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

Improve handling of definitions of enum classes
Author: xaizek
Author date (UTC): 2020-03-30 16:29
Committer name: xaizek
Committer date (UTC): 2020-03-30 16:46
Parent(s): 8faf636a5bcb3292c58c686aff74c248a5f33c17
Signing key: 99DC5E4DB05F6BE2
Tree: c9fd6c473e0c56427c1428298e6b63ffd303043b
File Lines added Lines deleted
src/srcml/cxx/SrcmlCxxLanguage.cpp 71 0
tests/srcml/cxx/srcml-cxx-parser.cpp 19 0
File src/srcml/cxx/SrcmlCxxLanguage.cpp changed (mode: 100644) (index b0384c3..408d866)
... ... static void postProcessIfStmt(PNode *node, TreeBuilder &tb,
36 36 const std::string &contents); const std::string &contents);
37 37 static void postProcessBlock(PNode *node, TreeBuilder &tb, static void postProcessBlock(PNode *node, TreeBuilder &tb,
38 38 const std::string &contents); const std::string &contents);
39 static void postProcessEnum(PNode *node, TreeBuilder &tb,
40 const std::string &contents);
41 static void postProcessEnumClass(PNode *node, TreeBuilder &tb,
42 const std::string &contents);
39 43 static void postProcessParameterList(PNode *node, TreeBuilder &tb, static void postProcessParameterList(PNode *node, TreeBuilder &tb,
40 44 const std::string &contents); const std::string &contents);
41 45 static bool breakLeaf(PNode *node, TreeBuilder &tb, static bool breakLeaf(PNode *node, TreeBuilder &tb,
 
... ... postProcessTree(PNode *node, TreeBuilder &tb, const std::string &contents)
217 221 postProcessBlock(node, tb, contents); postProcessBlock(node, tb, contents);
218 222 } }
219 223
224 if (node->stype == +SrcmlCxxSType::Enum) {
225 postProcessEnum(node, tb, contents);
226 postProcessEnumClass(node, tb, contents);
227 }
228
220 229 if (node->stype == +SrcmlCxxSType::ParameterList) { if (node->stype == +SrcmlCxxSType::ParameterList) {
221 230 postProcessParameterList(node, tb, contents); postProcessParameterList(node, tb, contents);
222 231 } }
 
... ... postProcessBlock(PNode *node, TreeBuilder &tb, const std::string &contents)
353 362 node->children.assign({ stmts }); node->children.assign({ stmts });
354 363 } }
355 364
365 // Rewrites enumeration nodes to be more diff-friendly. This turns ",\s*}" into
366 // two separate tokens.
367 static void
368 postProcessEnum(PNode *node, TreeBuilder &tb, const std::string &contents)
369 {
370 if (node->children.size() < 2) {
371 return;
372 }
373
374 PNode *block = node->children[node->children.size() - 2];
375 if (block->stype != +SrcmlCxxSType::Block) {
376 return;
377 }
378
379 if (block->children.empty()) {
380 return;
381 }
382
383 PNode *tail = block->children.back();
384 if (contents[tail->value.from] != ',' ||
385 contents[tail->value.from + tail->value.len - 1] != '}') {
386 return;
387 }
388
389 PNode *comma = tb.addNode();
390 comma->stype = +SrcmlCxxSType::Separator;
391
392 // Take "," part.
393 takeWord(comma, tail, 1);
394 // Drop "," prefix and whitespace that follows it.
395 skipWord(tail, tail, 1, contents);
396
397 block->children.insert(block->children.cend() - 1, comma);
398
399 comma->value.token = static_cast<int>(Type::Other);
400 tail->value.token = static_cast<int>(Type::RightBrackets);
401 }
402
403 // Rewrites enumeration class nodes to be more diff-friendly. This breaks
404 // "enum\s+class" into two separate keyword tokens.
405 static void
406 postProcessEnumClass(PNode *node, TreeBuilder &tb, const std::string &contents)
407 {
408 PNode *originalKw = node->children.front();
409 if (originalKw->value.len <= 4) {
410 return;
411 }
412
413 PNode *enumKw = tb.addNode();
414 enumKw->stype = +SrcmlCxxSType::Separator;
415
416 // Take "enum" part.
417 takeWord(enumKw, originalKw, 4);
418 // Drop "enum" prefix and whitespace that follows it.
419 skipWord(originalKw, originalKw, 4, contents);
420
421 node->children.insert(node->children.cbegin(), enumKw);
422
423 enumKw->value.token = static_cast<int>(Type::Keywords);
424 originalKw->value.token = static_cast<int>(Type::Keywords);
425 }
426
356 427 // Rewrites parameter list nodes to be more diff-friendly. // Rewrites parameter list nodes to be more diff-friendly.
357 428 static void static void
358 429 postProcessParameterList(PNode *node, TreeBuilder &tb, postProcessParameterList(PNode *node, TreeBuilder &tb,
File tests/srcml/cxx/srcml-cxx-parser.cpp changed (mode: 100644) (index a76f9b6..1b63674)
... ... TEST_CASE("EOL continuation is identified in C++",
397 397 REQUIRE(node != nullptr); REQUIRE(node != nullptr);
398 398 CHECK(tree.getLanguage()->isEolContinuation(node)); CHECK(tree.getLanguage()->isEolContinuation(node));
399 399 } }
400
401 TEST_CASE("Enum classes are properly handled", "[.srcml][srcml-cxx][parser]")
402 {
403 Tree tree = parseCxx(R"(
404 enum class C : int {
405 item,
406 };
407 )");
408 CHECK(findNode(tree, makePred(Type::Keywords, "enum")) != nullptr);
409 CHECK(findNode(tree, makePred(Type::Keywords, "class")) != nullptr);
410 CHECK(findNode(tree, makePred(Type::Identifiers, "C")) != nullptr);
411 CHECK(findNode(tree, makePred(Type::Other, ":")) != nullptr);
412 CHECK(findNode(tree, makePred(Type::Keywords, "int")) != nullptr);
413 CHECK(findNode(tree, makePred(Type::LeftBrackets, "{")) != nullptr);
414 CHECK(findNode(tree, makePred(Type::Identifiers, "item")) != nullptr);
415 CHECK(findNode(tree, makePred(Type::Other, ",")) != nullptr);
416 CHECK(findNode(tree, makePred(Type::RightBrackets, "}")) != nullptr);
417 CHECK(findNode(tree, makePred(Type::Other, ";")) != nullptr);
418 }
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