xaizek / zograscope (License: AGPLv3 only) (since 2018-12-07)
Mainly a syntax-aware diff that also provides a number of additional tools.
Commit a27ac9e01a29de610f54c1fea11ac5fb905173e1

Recognize recursive nature of block meta-type
They can be nested and all blocks should be found (not just top level
blocks).

Maybe there could be a syntax for searching that specifies whether to
recurse on nesting or not.
Author: xaizek
Author date (UTC): 2019-07-03 11:49
Committer name: xaizek
Committer date (UTC): 2019-07-03 11:49
Parent(s): 13bfb75a5bcedcacdd5582664f84074ca64d87c9
Signing key: 99DC5E4DB05F6BE2
Tree: f2f3c3f2fb73ce741ed369bb4af934d517137ed5
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 }
Hints

Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://code.reversed.top/user/xaizek/zograscope

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@code.reversed.top/user/xaizek/zograscope

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a pull request:
... clone the repository ...
... make some changes and some commits ...
git push origin master