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