| 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 | } | ||