From e8f38efd42519b098a54e16f038343eefb04466f Mon Sep 17 00:00:00 2001 From: Arnold Metselaar Date: Fri, 2 Jan 2015 16:12:29 +0100 Subject: [PATCH] Fix hashhash related parsing problem Let ## operator work on two tokens on the left when the token before the last non-whitespace token is not whitespace and has no trivia. Enable test cases. --- .../cxx/preprocessor/CxxPreprocessor.java | 16 +++++++++ .../parser/PreprocessorDirectivesTest.java | 34 ++++++++----------- 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/cxx-squid/src/main/java/org/sonar/cxx/preprocessor/CxxPreprocessor.java b/cxx-squid/src/main/java/org/sonar/cxx/preprocessor/CxxPreprocessor.java index d9d4a76ed9..ca978f2c71 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/preprocessor/CxxPreprocessor.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/preprocessor/CxxPreprocessor.java @@ -860,6 +860,22 @@ private Token predConcatToken(List tokens) { while (!tokens.isEmpty()) { Token last = tokens.remove(tokens.size() - 1); if (last.getType() != WS) { + if ( !tokens.isEmpty() ) { + Token pred = tokens.get(tokens.size() - 1); + if (pred.getType() != WS && !pred.hasTrivia()) { + // Needed to paste tokens 0 and x back together after #define N(hex) 0x ## hex + tokens.remove(tokens.size() - 1); + String replacement = pred.getValue() + last.getValue(); + last = Token.builder() + .setLine(pred.getLine()) + .setColumn(pred.getColumn()) + .setURI(pred.getURI()) + .setValueAndOriginalValue(replacement) + .setType(pred.getType()) + .setGeneratedCode(true) + .build(); + } + } return last; } } diff --git a/cxx-squid/src/test/java/org/sonar/cxx/parser/PreprocessorDirectivesTest.java b/cxx-squid/src/test/java/org/sonar/cxx/parser/PreprocessorDirectivesTest.java index eb96d4d535..098039ee18 100644 --- a/cxx-squid/src/test/java/org/sonar/cxx/parser/PreprocessorDirectivesTest.java +++ b/cxx-squid/src/test/java/org/sonar/cxx/parser/PreprocessorDirectivesTest.java @@ -61,19 +61,15 @@ public void preprocessorDirectives() { @Test public void hashhash_related_parsing_problem() { - // TODO: make it run. - // this reproduces a macros expansion problem where - // whitespace handling goes wrong - - // assertThat(p).matches( - // "#define CASES CASE(00)\n" - // + "#define CASE(n) case 0x##n:\n" - // + "void foo() {\n" - // + "switch (1) {\n" - // + "CASES\n" - // + "break;\n" - // + "}\n" - // + "}\n"); + assertThat(p).matches( + "#define CASES CASE(00)\n" + + "#define CASE(n) case 0x##n:\n" + + "void foo() {\n" + + "switch (1) {\n" + + "CASES\n" + + "break;\n" + + "}\n" + + "}\n"); } @Test @@ -261,13 +257,11 @@ public void concatenation() { + "macro_start")) .equals("int main ( void ) ; EOF")); - // FIXME: this failes due to a bug in production code - // which rips apart the number '0xcf' - // assert (serialize(p.parse( - // "#define A B(cf)\n" - // + "#define B(n) 0x##n\n" - // + "i = A;")) - // .equals("i = 0xcf ; EOF")); + assert (serialize(p.parse( + "#define A B(cf)\n" + + "#define B(n) 0x##n\n" + + "i = A;")) + .equals("i = 0xcf ; EOF")); } @Test