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

Account for new SrcML nodes added in v1.0.0
Author: xaizek
Author date (UTC): 2020-03-29 22:34
Committer name: xaizek
Committer date (UTC): 2020-03-29 22:34
Parent(s): 07f2c2f5216cb13ebfe0b9e47e0467050da05aa3
Signing key: 99DC5E4DB05F6BE2
Tree: 912fff529cb93928fc6387fb76d83c4a037eaac2
File Lines added Lines deleted
src/srcml/cxx/SrcmlCxxLanguage.cpp 79 2
File src/srcml/cxx/SrcmlCxxLanguage.cpp changed (mode: 100644) (index 6fe4915..54f3afb)
... ... static void postProcessTree(PNode *node, TreeBuilder &tb,
32 32 static bool isConditional(SType stype); static bool isConditional(SType stype);
33 33 static void postProcessIf(PNode *node, TreeBuilder &tb, static void postProcessIf(PNode *node, TreeBuilder &tb,
34 34 const std::string &contents); const std::string &contents);
35 static void postProcessIfStmt(PNode *node, TreeBuilder &tb,
36 const std::string &contents);
35 37 static void postProcessBlock(PNode *node, TreeBuilder &tb, static void postProcessBlock(PNode *node, TreeBuilder &tb,
36 38 const std::string &contents); const std::string &contents);
37 39 static void postProcessParameterList(PNode *node, TreeBuilder &tb, static void postProcessParameterList(PNode *node, TreeBuilder &tb,
 
... ... postProcessTree(PNode *node, TreeBuilder &tb, const std::string &contents)
204 206 postProcessIf(node, tb, contents); postProcessIf(node, tb, contents);
205 207 } }
206 208
209 if (node->stype == +SrcmlCxxSType::IfStmt) {
210 postProcessIfStmt(node, tb, contents);
211 }
212
207 213 if (node->stype == +SrcmlCxxSType::Block) { if (node->stype == +SrcmlCxxSType::Block) {
208 214 postProcessBlock(node, tb, contents); postProcessBlock(node, tb, contents);
209 215 } }
 
... ... postProcessIf(PNode *node, TreeBuilder &/*tb*/, const std::string &/*contents*/)
251 257 } }
252 258 } }
253 259
260 // Rewrites if statement nodes to be more diff-friendly.
261 static void
262 postProcessIfStmt(PNode *node, TreeBuilder &tb, const std::string &contents)
263 {
264 // Move else or else-if nodes to respective if-statement splitting "else-if"
265 // into else and if parts.
266 while (node->children.size() > 1) {
267 auto n = node->children.size();
268 PNode *prev = node->children[n - 2U];
269 PNode *tailNode = node->children[n - 1U];
270 node->children.pop_back();
271
272 if (tailNode->stype == +SrcmlCxxSType::Else) {
273 // Else nodes just need to be moved.
274 prev->children.push_back(tailNode);
275 continue;
276 }
277
278 PNode *elseIfKw = tailNode->children[0];
279
280 PNode *elseKw = tb.addNode();
281 elseKw->stype = +SrcmlCxxSType::Separator;
282 elseKw->value.token = static_cast<int>(Type::Keywords);
283 // Take "else" part.
284 elseKw->value.from = elseIfKw->value.from;
285 elseKw->value.len = 4;
286 elseKw->line = elseIfKw->line;
287 elseKw->col = elseIfKw->col;
288
289 // Drop "else" prefix and whitespace that follows it.
290 elseIfKw->value.token = static_cast<int>(Type::Keywords);
291 elseIfKw->value.from += 4;
292 elseIfKw->value.len -= 4;
293 elseIfKw->col += 4;
294 dropLeadingWS(elseIfKw, contents);
295
296 PNode *newNode = tb.addNode();
297 newNode->stype = +SrcmlCxxSType::Elseif;
298 newNode->children = { elseKw, tailNode };
299 prev->children.push_back(newNode);
300 }
301
302 // Replace if-statement node with the if node.
303 PNode *ifNode = node->children[0];
304 node->children.erase(node->children.cbegin());
305 node->children.insert(node->children.cbegin(),
306 ifNode->children.cbegin(), ifNode->children.cend());
307 node->stype = ifNode->stype;
308 }
309
254 310 // Rewrites block nodes to be more diff-friendly. // Rewrites block nodes to be more diff-friendly.
255 311 static void static void
256 312 postProcessBlock(PNode *node, TreeBuilder &tb, const std::string &contents) postProcessBlock(PNode *node, TreeBuilder &tb, const std::string &contents)
257 313 { {
258 // Children: `{` statement* `}`.
314 // Children: `{` block-content `}`
315 if (node->children.size() == 3 &&
316 node->children[1]->stype == +SrcmlCxxSType::BlockContent) {
317 PNode *content = node->children[1];
318
319 // Empty block-content gets replaces with empty statements node.
320 if (content->children.empty()) {
321 node->children[1] = tb.addNode();
322 node->children[1]->stype = +SrcmlCxxSType::Statements;
323 return;
324 }
325
326 // Splice children of block-content in its place.
327 node->children.erase(++node->children.cbegin());
328 node->children.insert(++node->children.cbegin(),
329 content->children.cbegin(),
330 content->children.cend());
331 }
332
333 // Children: `{` statement+ `}`.
259 334 if (node->children.size() > 2) { if (node->children.size() > 2) {
260 335 PNode *stmts = tb.addNode(); PNode *stmts = tb.addNode();
261 336 stmts->stype = +SrcmlCxxSType::Statements; stmts->stype = +SrcmlCxxSType::Statements;
 
... ... SrcmlCxxLanguage::shouldSplice(SType parent, const Node *childNode) const
474 549 -parent == SrcmlCxxSType::Class || -parent == SrcmlCxxSType::Class ||
475 550 -parent == SrcmlCxxSType::Union || -parent == SrcmlCxxSType::Union ||
476 551 -parent == SrcmlCxxSType::Enum || -parent == SrcmlCxxSType::Enum ||
552 -parent == SrcmlCxxSType::If ||
477 553 -parent == SrcmlCxxSType::Then || -parent == SrcmlCxxSType::Then ||
478 554 -parent == SrcmlCxxSType::Else || -parent == SrcmlCxxSType::Else ||
479 555 -parent == SrcmlCxxSType::For || -parent == SrcmlCxxSType::For ||
 
... ... SrcmlCxxLanguage::shouldSplice(SType parent, const Node *childNode) const
490 566 child == SrcmlCxxSType::ArgumentList) { child == SrcmlCxxSType::ArgumentList) {
491 567 return true; return true;
492 568 } }
493 if (child == SrcmlCxxSType::ParameterList) {
569 if (child == SrcmlCxxSType::ParameterList ||
570 child == SrcmlCxxSType::BlockContent) {
494 571 return true; return true;
495 572 } }
496 573 return false; return false;
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