File | Lines added | Lines deleted |
---|---|---|
src/mtypes.cpp | 20 | 0 |
src/mtypes.hpp | 3 | 0 |
src/tooling/Matcher.hpp | 5 | 2 |
tests/tooling/Matcher.cpp | 22 | 0 |
File src/mtypes.cpp changed (mode: 100644) (index 1f192bd..b027f17) | |||
... | ... | operator<<(std::ostream &os, MType mtype) | |
38 | 38 | assert(false && "Unhandled enumeration item"); | assert(false && "Unhandled enumeration item"); |
39 | 39 | return (os << "<UNKNOWN:" << static_cast<int>(mtype) << '>'); | return (os << "<UNKNOWN:" << static_cast<int>(mtype) << '>'); |
40 | 40 | } | } |
41 | |||
42 | bool | ||
43 | canNest(MType mtype) | ||
44 | { | ||
45 | switch (mtype) { | ||
46 | case MType::Block: | ||
47 | return true; | ||
48 | case MType::Other: | ||
49 | case MType::Declaration: | ||
50 | case MType::Statement: | ||
51 | case MType::Function: | ||
52 | case MType::Parameter: | ||
53 | case MType::Comment: | ||
54 | case MType::Directive: | ||
55 | return false; | ||
56 | } | ||
57 | |||
58 | assert(false && "Unhandled enumeration item"); | ||
59 | return false; | ||
60 | } |
File src/mtypes.hpp changed (mode: 100644) (index 3c9ee52..3fff56c) | |||
... | ... | enum class MType : std::uint8_t | |
38 | 38 | // Prints mtype as a string. | // Prints mtype as a string. |
39 | 39 | std::ostream & operator<<(std::ostream &os, MType mtype); | std::ostream & operator<<(std::ostream &os, MType mtype); |
40 | 40 | ||
41 | // Checks whether nodes of the meta-type can nest. | ||
42 | bool canNest(MType mtype); | ||
43 | |||
41 | 44 | #endif // ZOGRASCOPE__MTYPES_HPP__ | #endif // ZOGRASCOPE__MTYPES_HPP__ |
File src/tooling/Matcher.hpp changed (mode: 100644) (index 803b29b..4cdf502) | |||
23 | 23 | #include <utility> | #include <utility> |
24 | 24 | ||
25 | 25 | #include "Language.hpp" | #include "Language.hpp" |
26 | #include "mtypes.hpp" | ||
26 | 27 | #include "tree.hpp" | #include "tree.hpp" |
27 | 28 | ||
28 | enum class MType : std::uint8_t; | ||
29 | |||
30 | 29 | // Finds a node of specified type that matches another matcher. | // Finds a node of specified type that matches another matcher. |
31 | 30 | class Matcher | class Matcher |
32 | 31 | { | { |
... | ... | Matcher::match(const Node *node, Language &lang, F &&handler) | |
88 | 87 | if (nested == nullptr) { | if (nested == nullptr) { |
89 | 88 | handler(child); | handler(child); |
90 | 89 | } | } |
90 | |||
91 | if (canNest(mtype)) { | ||
92 | match(child, lang, std::forward<F>(handler)); | ||
93 | } | ||
91 | 94 | } | } |
92 | 95 | } | } |
93 | 96 | return foundMatch; | return foundMatch; |
File tests/tooling/Matcher.cpp changed (mode: 100644) (index 01f02bb..cf428f4) | |||
... | ... | TEST_CASE("Statement matcher works", "[tooling][matcher][.srcml]") | |
98 | 98 | CHECK(nMatches == 3); | CHECK(nMatches == 3); |
99 | 99 | } | } |
100 | 100 | } | } |
101 | |||
102 | TEST_CASE("Block matcher works", "[tooling][matcher][.srcml]") | ||
103 | { | ||
104 | Matcher matcher(MType::Block, nullptr); | ||
105 | |||
106 | int nMatches = 0; | ||
107 | |||
108 | auto matchHandler = [&](Node */*node*/) { | ||
109 | ++nMatches; | ||
110 | }; | ||
111 | |||
112 | SECTION("In C") { | ||
113 | Tree tree = parseC("void f() { { } { { } } }", true); | ||
114 | CHECK(matcher.match(tree.getRoot(), *tree.getLanguage(), matchHandler)); | ||
115 | CHECK(nMatches == 4); | ||
116 | } | ||
117 | SECTION("In C++") { | ||
118 | Tree tree = parseCxx("void f() { { } { { } } }"); | ||
119 | CHECK(matcher.match(tree.getRoot(), *tree.getLanguage(), matchHandler)); | ||
120 | CHECK(nMatches == 4); | ||
121 | } | ||
122 | } |