Skip to content

Commit 0175410

Browse files
authored
Merge pull request #2202 from guwirth/identifiers-with-special-meaning
fix highlighting error for identifiers with special meaning
2 parents 87104dd + 6bf0302 commit 0175410

File tree

3 files changed

+78
-67
lines changed

3 files changed

+78
-67
lines changed

cxx-squid/src/main/java/org/sonar/cxx/preprocessor/CxxPreprocessor.java

Lines changed: 48 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@
7575
* **A.12 Preprocessing directives [gram.cpp]**
7676
*
7777
* preprocessing-file:
78-
* groupopt
78+
* groupopt
7979
* module-file
8080
*
8181
* module-file:
@@ -187,7 +187,7 @@ public void init() {
187187
globalMacros = new MapChain<>();
188188
globalMacros.putAll(unitMacros);
189189

190-
if(LOG.isDebugEnabled()) {
190+
if (LOG.isDebugEnabled()) {
191191
LOG.debug("global include directories: {}", unitCodeProvider.getIncludeRoots());
192192
LOG.debug("global macros: {}", globalMacros);
193193
}
@@ -197,7 +197,7 @@ public void init() {
197197

198198
// add unit specific stuff
199199
boolean changes = addUnitIncludeDirectories(path);
200-
if (changes && LOG.isDebugEnabled() ) {
200+
if (changes && LOG.isDebugEnabled()) {
201201
LOG.debug("unit include directories: {}", unitCodeProvider.getIncludeRoots());
202202
}
203203
changes = addUnitMacros(path);
@@ -282,7 +282,7 @@ private PreprocessorAction handlePreprocessorDirective(Token token, String rootF
282282
// ignore all other preprocessor directives (which are not handled explicitly) and strip them from the stream
283283
return oneConsumedToken(token);
284284
}
285-
}
285+
}
286286

287287
public static void finalReport() {
288288
if (missingIncludeFilesCounter != 0) {
@@ -541,13 +541,13 @@ private static Macro parseMacroDefinition(AstNode defineLineAst) {
541541
var identifier = vaargs.getFirstChild(IDENTIFIER);
542542
macroParams.add(identifier == null
543543
? Token.builder()
544-
.setLine(vaargs.getToken().getLine())
545-
.setColumn(vaargs.getToken().getColumn())
546-
.setURI(vaargs.getToken().getURI())
547-
.setValueAndOriginalValue("__VA_ARGS__")
548-
.setType(IDENTIFIER)
549-
.setGeneratedCode(true)
550-
.build()
544+
.setLine(vaargs.getToken().getLine())
545+
.setColumn(vaargs.getToken().getColumn())
546+
.setURI(vaargs.getToken().getURI())
547+
.setValueAndOriginalValue("__VA_ARGS__")
548+
.setType(IDENTIFIER)
549+
.setGeneratedCode(true)
550+
.build()
551551
: identifier.getToken());
552552
}
553553

@@ -658,15 +658,16 @@ private boolean addUnitMacros(String level) {
658658
}
659659

660660
private void addGlobalIncludeDirectories() {
661-
globalIncludeDirectories = squidConfig.getValues(CxxSquidConfiguration.GLOBAL, CxxSquidConfiguration.INCLUDE_DIRECTORIES);
662-
unitCodeProvider.setIncludeRoots(globalIncludeDirectories,squidConfig.getBaseDir());
661+
globalIncludeDirectories = squidConfig.getValues(CxxSquidConfiguration.GLOBAL,
662+
CxxSquidConfiguration.INCLUDE_DIRECTORIES);
663+
unitCodeProvider.setIncludeRoots(globalIncludeDirectories, squidConfig.getBaseDir());
663664
}
664665

665666
private boolean addUnitIncludeDirectories(String level) {
666667
List<String> unitIncludeDirectories = squidConfig.getLevelValues(level, CxxSquidConfiguration.INCLUDE_DIRECTORIES);
667668
boolean hasUnitIncludes = !unitIncludeDirectories.isEmpty();
668669
unitIncludeDirectories.addAll(globalIncludeDirectories);
669-
unitCodeProvider.setIncludeRoots(unitIncludeDirectories,squidConfig.getBaseDir());
670+
unitCodeProvider.setIncludeRoots(unitIncludeDirectories, squidConfig.getBaseDir());
670671
return hasUnitIncludes;
671672
}
672673

@@ -799,7 +800,7 @@ private static void expandVaOpt(List<Token> tokens, boolean keep) {
799800
if (firstIndex > 0 && lastIndex < tokens.size()) {
800801
if (keep) {
801802
// keep pp-tokensopt, remove ) and __VA_OPT__ (
802-
tokens.subList(lastIndex, lastIndex+1).clear();
803+
tokens.subList(lastIndex, lastIndex + 1).clear();
803804
tokens.subList(0, firstIndex).clear();
804805
} else {
805806
// remove from body: __VA_OPT__ ( pp-tokensopt )
@@ -819,8 +820,8 @@ private List<Token> replaceParams(List<Token> body, List<Token> parameters, List
819820

820821
// container to search parameter by name
821822
var paramterIndex = new HashMap<String, Integer>();
822-
for(var index=0; index<parameters.size(); index++) {
823-
paramterIndex.put(parameters.get(index).getValue(),index);
823+
for (var index = 0; index < parameters.size(); index++) {
824+
paramterIndex.put(parameters.get(index).getValue(), index);
824825
}
825826

826827
for (var i = 0; i < body.size(); ++i) {
@@ -1017,18 +1018,18 @@ private File findIncludedFile(AstNode ast, Token token, String currFileName) {
10171018
return null;
10181019
}
10191020

1020-
void handleConstantExpression(AstNode ast,Token token, String filename){
1021+
void handleConstantExpression(AstNode ast, Token token, String filename) {
10211022
try {
10221023
unitCodeProvider.skipBlock(false);
10231024
boolean result = ExpressionEvaluator.eval(this, ast.getFirstDescendant(CppGrammarImpl.constantExpression));
10241025
unitCodeProvider.expressionWas(result);
10251026
unitCodeProvider.skipBlock(!result);
1026-
} catch (EvaluationException e) {
1027-
LOG.error("[{}:{}]: error evaluating the expression {} assume 'true' ...",
1028-
filename, token.getLine(), token.getValue());
1029-
unitCodeProvider.expressionWas(true);
1030-
unitCodeProvider.skipBlock(false);
1031-
}
1027+
} catch (EvaluationException e) {
1028+
LOG.error("[{}:{}]: error evaluating the expression {} assume 'true' ...",
1029+
filename, token.getLine(), token.getValue());
1030+
unitCodeProvider.expressionWas(true);
1031+
unitCodeProvider.skipBlock(false);
1032+
}
10321033
}
10331034

10341035
PreprocessorAction handleIfLine(AstNode ast, Token token, String filename) {
@@ -1105,7 +1106,8 @@ PreprocessorAction handleIncludeLine(AstNode ast, Token token, String filename,
11051106
File includedFile = findIncludedFile(ast, token, filename);
11061107
if (includedFile == null) {
11071108
missingIncludeFilesCounter++;
1108-
LOG.debug("[" + filename + ":" + token.getLine() + "]: preprocessor cannot find include file '" + token.getValue() + "'");
1109+
LOG.debug("[" + filename + ":" + token.getLine()
1110+
+ "]: preprocessor cannot find include file '" + token.getValue() + "'");
11091111
} else if (analysedFiles.add(includedFile.getAbsoluteFile())) {
11101112
unitCodeProvider.pushFileState(includedFile);
11111113
try {
@@ -1122,63 +1124,45 @@ PreprocessorAction handleIncludeLine(AstNode ast, Token token, String filename,
11221124
}
11231125

11241126
PreprocessorAction handleImportLine(AstNode ast, Token token, String filename, Charset charset) {
1125-
if (ast.getFirstDescendant(CppGrammarImpl.expandedIncludeBody) != null) {
1127+
if (ast.getFirstDescendant(CppGrammarImpl.expandedIncludeBody) != null) {
11261128
// import <file>
11271129
return handleIncludeLine(ast, token, filename, charset);
11281130
}
11291131

11301132
// forward to parser: ... import ...
1131-
return mapModuleTokens(ast, token);
1133+
return mapFromCppToCxx(ast, token);
11321134
}
11331135

11341136
PreprocessorAction handleModuleLine(AstNode ast, Token token) {
11351137
// forward to parser: ... module ...
1136-
return mapModuleTokens(ast, token);
1138+
return mapFromCppToCxx(ast, token);
11371139
}
11381140

1139-
PreprocessorAction mapModuleTokens(AstNode ast, Token token) {
1141+
PreprocessorAction mapFromCppToCxx(AstNode ast, Token token) {
11401142
List<Token> replTokens = new ArrayList<>();
11411143
for (Token ppToken : stripEOF(serialize(ast))) {
11421144
String value = ppToken.getValue();
1143-
var type = ppToken.getType();
1144-
var newToken = ppToken;
1145-
var convert = true;
1146-
1147-
// identifier with special meaning?
1148-
// if (type.equals(IDENTIFIER)) {
1149-
// if (value.equals(CppSpecialIdentifier.MODULE.getValue())) {
1150-
// type = CppSpecialIdentifier.MODULE;
1151-
// convert = false;
1152-
// } else if (value.equals(CppSpecialIdentifier.IMPORT.getValue())) {
1153-
// type = CppSpecialIdentifier.IMPORT;
1154-
// convert = false;
1155-
// } else if (value.equals(CppSpecialIdentifier.EXPORT.getValue())) {
1156-
// type = CppSpecialIdentifier.EXPORT;
1157-
// convert = false;
1158-
// }
1159-
// }
1160-
1161-
// convert pp token to cxx token
1162-
if (convert) {
1145+
if (!value.isBlank()) {
1146+
// call CXX lexer to create a CXX token
11631147
List<Token> cxxTokens = CxxLexer.create().lex(value);
1164-
newToken = cxxTokens.get(0);
1165-
type = newToken.getType();
1166-
}
1167-
1168-
if (!type.equals(EOF)) {
1169-
newToken = Token.builder()
1170-
.setLine(token.getLine())
1171-
.setColumn(ppToken.getColumn())
1172-
.setURI(ppToken.getURI())
1173-
.setValueAndOriginalValue(ppToken.getValue())
1174-
.setType(type)
1175-
.build();
1176-
1177-
replTokens.add(newToken);
1148+
var cxxToken = cxxTokens.get(0);
1149+
var cxxType = cxxToken.getType();
1150+
1151+
if (!cxxType.equals(EOF)) {
1152+
cxxToken = Token.builder()
1153+
.setLine(token.getLine() + ppToken.getLine() - 1)
1154+
.setColumn(token.getColumn() + ppToken.getColumn())
1155+
.setURI(ppToken.getURI())
1156+
.setValueAndOriginalValue(ppToken.getValue())
1157+
.setType(cxxType)
1158+
.build();
1159+
1160+
replTokens.add(cxxToken);
1161+
}
11781162
}
11791163
}
11801164

1181-
return new PreprocessorAction(1, Collections.singletonList(Trivia.createSkippedText(token)),replTokens);
1165+
return new PreprocessorAction(1, Collections.singletonList(Trivia.createPreprocessingToken(token)), replTokens);
11821166
}
11831167

11841168
PreprocessorAction handleUndefLine(AstNode ast, Token token) {

sonar-cxx-plugin/src/test/java/org/sonar/plugins/cxx/CxxHighlighterTest.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,16 @@ public void preprocessDirective() {
187187
checkOnRange(20, 0, 7, TypeOfText.PREPROCESS_DIRECTIVE); // #define
188188
}
189189

190+
@Test
191+
@SuppressWarnings("squid:S2699") // ... checkOnRange contains the assertion
192+
public void identifiersWithSpecialMeaning() {
193+
// identifier with special meaning => no highlighting
194+
checkOnRange(112, 11, 6, null); // import
195+
checkOnRange(119, 10, 6, null); // module
196+
checkOnRange(120, 12, 6, null); // module
197+
checkOnRange(122, 13, 6, null); // module
198+
}
199+
190200
/**
191201
* Checks the highlighting of a range of columns. The first column of a line has index 0. The range is the columns of
192202
* the token.

sonar-cxx-plugin/src/test/resources/org/sonar/plugins/cxx/highlighter.cc

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,11 @@ void test2(const char* sourceFilename)
8181
void test3()
8282
{
8383
const char *t1 = "..."; // UTF-8 encoded
84-
const char *t2 = u8"..."; // UTF-8 encoded
84+
const char *t2 = u8"..."; // UTF-8 encoded
8585
const wchar_t *t3 = L"..."; // Wide string
8686
const char16_t *t4 = u"..."; // UTF-16 encoded
8787
const char32_t *t5 = U"..."; // UTF-32 encoded
88-
88+
8989
const char *t6 = "hello" " world";
9090
const wchar_t *t7 = u"" "hello world";
9191
const wchar_t *t8 = /*comment1*/ u"" /*comment2*/ "hello world" /*comment3*/; // issue #996
@@ -102,7 +102,24 @@ void test4()
102102
{
103103
auto txt = R"(
104104
Hello World!
105-
)";
105+
)";
106+
}
107+
108+
// issue #2197
109+
namespace Test {
110+
class Test {
111+
private:
112+
bool import = false;
113+
}
114+
}
115+
116+
// issue #2192
117+
void test5()
118+
{
119+
assert(module != nullptr);
120+
for (int module=0; module<10; module++) {}
121+
char modules[]= {}
122+
for (auto module : modules) {}
106123
}
107124

108125
/* EOF */

0 commit comments

Comments
 (0)