diff --git a/cxx-checks/src/main/java/org/sonar/cxx/checks/BooleanEqualityComparisonCheck.java b/cxx-checks/src/main/java/org/sonar/cxx/checks/BooleanEqualityComparisonCheck.java index add0ed8826..0f56889f0e 100644 --- a/cxx-checks/src/main/java/org/sonar/cxx/checks/BooleanEqualityComparisonCheck.java +++ b/cxx-checks/src/main/java/org/sonar/cxx/checks/BooleanEqualityComparisonCheck.java @@ -39,6 +39,11 @@ @SqaleConstantRemediation("5min") public class BooleanEqualityComparisonCheck extends SquidCheck { + private static boolean hasBooleanLiteralOperand(AstNode node) { + return node.hasDirectChildren(CxxGrammarImpl.LITERAL, CxxGrammarImpl.BOOL) + && node.hasDescendant(CxxKeyword.TRUE, CxxKeyword.FALSE); + } + @Override public void init() { subscribeTo(CxxGrammarImpl.equalityExpression); @@ -54,9 +59,4 @@ public void visitNode(AstNode node) { } } - private static boolean hasBooleanLiteralOperand(AstNode node) { - return node.hasDirectChildren(CxxGrammarImpl.LITERAL, CxxGrammarImpl.BOOL) - && node.hasDescendant(CxxKeyword.TRUE, CxxKeyword.FALSE); - } - } diff --git a/cxx-checks/src/main/java/org/sonar/cxx/checks/CollapsibleIfCandidateCheck.java b/cxx-checks/src/main/java/org/sonar/cxx/checks/CollapsibleIfCandidateCheck.java index b916631054..a0ebb3334e 100644 --- a/cxx-checks/src/main/java/org/sonar/cxx/checks/CollapsibleIfCandidateCheck.java +++ b/cxx-checks/src/main/java/org/sonar/cxx/checks/CollapsibleIfCandidateCheck.java @@ -41,22 +41,6 @@ @SqaleConstantRemediation("5min") public class CollapsibleIfCandidateCheck extends SquidCheck { - @Override - public void init() { - subscribeTo(CxxGrammarImpl.selectionStatement); - } - - @Override - public void visitNode(AstNode node) { - if (!hasElseClause(node) && !hasDeclaration(node)) { - AstNode enclosingIfStatement = getEnclosingIfStatement(node); - if (enclosingIfStatement != null && !hasElseClause(enclosingIfStatement) - && hasSingleTrueStatement(enclosingIfStatement) && !hasDeclaration(enclosingIfStatement)) { - getContext().createLineViolation(this, "Merge this if statement with the enclosing one.", node); - } - } - } - private static boolean hasElseClause(AstNode node) { return node.hasDirectChildren(CxxKeyword.ELSE); } @@ -95,4 +79,20 @@ private static boolean hasSingleTrueStatement(AstNode node) { .getChildren().size() == 1 : true; } + @Override + public void init() { + subscribeTo(CxxGrammarImpl.selectionStatement); + } + + @Override + public void visitNode(AstNode node) { + if (!hasElseClause(node) && !hasDeclaration(node)) { + AstNode enclosingIfStatement = getEnclosingIfStatement(node); + if (enclosingIfStatement != null && !hasElseClause(enclosingIfStatement) + && hasSingleTrueStatement(enclosingIfStatement) && !hasDeclaration(enclosingIfStatement)) { + getContext().createLineViolation(this, "Merge this if statement with the enclosing one.", node); + } + } + } + } diff --git a/cxx-checks/src/main/java/org/sonar/cxx/checks/CommentedCodeCheck.java b/cxx-checks/src/main/java/org/sonar/cxx/checks/CommentedCodeCheck.java index 6ab0989704..33d62699e2 100644 --- a/cxx-checks/src/main/java/org/sonar/cxx/checks/CommentedCodeCheck.java +++ b/cxx-checks/src/main/java/org/sonar/cxx/checks/CommentedCodeCheck.java @@ -54,25 +54,9 @@ public class CommentedCodeCheck extends SquidCheck implements AstAndTok private static final double THRESHOLD = 0.94; - private final CodeRecognizer codeRecognizer = new CodeRecognizer(THRESHOLD, new CxxRecognizer()); - private static final Pattern EOL_PATTERN = Pattern.compile("\\R"); - private static class CxxRecognizer implements LanguageFootprint { - - @Override - public Set getDetectors() { - Set detectors = new HashSet<>(); - - detectors.add(new EndWithDetector(0.95, '}', ';', '{')); - detectors.add(new KeywordsDetector(0.7, "||", "&&")); - detectors.add(new KeywordsDetector(0.3, CppKeyword.keywordValues())); - detectors.add(new ContainsDetector(0.95, "for(", "if(", "while(", "catch(", "switch(", "try{", "else{")); - - return detectors; - } - - } + private final CodeRecognizer codeRecognizer = new CodeRecognizer(THRESHOLD, new CxxRecognizer()); @Override public void visitToken(Token token) { @@ -98,4 +82,20 @@ public void visitToken(Token token) { } } + private static class CxxRecognizer implements LanguageFootprint { + + @Override + public Set getDetectors() { + Set detectors = new HashSet<>(); + + detectors.add(new EndWithDetector(0.95, '}', ';', '{')); + detectors.add(new KeywordsDetector(0.7, "||", "&&")); + detectors.add(new KeywordsDetector(0.3, CppKeyword.keywordValues())); + detectors.add(new ContainsDetector(0.95, "for(", "if(", "while(", "catch(", "switch(", "try{", "else{")); + + return detectors; + } + + } + } diff --git a/cxx-checks/src/main/java/org/sonar/cxx/checks/HardcodedAccountCheck.java b/cxx-checks/src/main/java/org/sonar/cxx/checks/HardcodedAccountCheck.java index 4cedd7dee4..9a99aa2ef5 100644 --- a/cxx-checks/src/main/java/org/sonar/cxx/checks/HardcodedAccountCheck.java +++ b/cxx-checks/src/main/java/org/sonar/cxx/checks/HardcodedAccountCheck.java @@ -25,7 +25,6 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; - import org.sonar.check.Priority; import org.sonar.check.Rule; import org.sonar.check.RuleProperty; diff --git a/cxx-checks/src/main/java/org/sonar/cxx/checks/HardcodedIpCheck.java b/cxx-checks/src/main/java/org/sonar/cxx/checks/HardcodedIpCheck.java index 3f72e916c2..d7c77599c6 100644 --- a/cxx-checks/src/main/java/org/sonar/cxx/checks/HardcodedIpCheck.java +++ b/cxx-checks/src/main/java/org/sonar/cxx/checks/HardcodedIpCheck.java @@ -25,7 +25,6 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; - import org.sonar.check.Priority; import org.sonar.check.Rule; import org.sonar.check.RuleProperty; diff --git a/cxx-checks/src/main/java/org/sonar/cxx/checks/MagicNumberCheck.java b/cxx-checks/src/main/java/org/sonar/cxx/checks/MagicNumberCheck.java index 3714bd1e43..cbd57f38ad 100755 --- a/cxx-checks/src/main/java/org/sonar/cxx/checks/MagicNumberCheck.java +++ b/cxx-checks/src/main/java/org/sonar/cxx/checks/MagicNumberCheck.java @@ -50,39 +50,6 @@ public class MagicNumberCheck extends SquidCheck { private static final String DEFAULT_EXCEPTIONS = "0,1,0x0,0x00,.0,.1,0.0,1.0,0u,1u,0ul,1ul,1.0f,0.0f,0LL,1LL,0ULL,1ULL"; - @RuleProperty( - key = "exceptions", - description = "Comma separated list of allowed values (excluding '-' and '+' signs)", - defaultValue = DEFAULT_EXCEPTIONS) - public String exceptions = DEFAULT_EXCEPTIONS; - - private final Set exceptionsSet = new HashSet<>(); - - @Override - public void init() { - subscribeTo(CxxTokenType.NUMBER); - for (String magicNumber : exceptions.split(",")) { - magicNumber = magicNumber.trim(); - if (!magicNumber.isEmpty()) { - exceptionsSet.add(magicNumber); - } - } - } - - @Override - public void visitNode(AstNode node) { - if (!isConstexpr(node) - && !isConst(node) - && !isExcluded(node) - && !isInEnum(node) - && !isArrayInitializer(node) - && !isGenerated(node) - && !isNullPtr(node)) { - getContext().createLineViolation(this, "Extract this magic number '" + node.getTokenOriginalValue() - + "' into a constant, variable declaration or an enum.", node); - } - } - private static boolean isConstexpr(AstNode node) { AstNode decl = null; @@ -116,10 +83,6 @@ private static boolean isConst(AstNode node) { return false; } - private boolean isExcluded(AstNode node) { - return exceptionsSet.contains(node.getTokenOriginalValue()); - } - private static boolean isInEnum(AstNode node) { return node.hasAncestor(CxxGrammarImpl.enumeratorList); } @@ -135,5 +98,40 @@ private static boolean isGenerated(AstNode node) { private static boolean isNullPtr(AstNode node) { return "nullptr".equals(node.getTokenValue()); } + @RuleProperty( + key = "exceptions", + description = "Comma separated list of allowed values (excluding '-' and '+' signs)", + defaultValue = DEFAULT_EXCEPTIONS) + public String exceptions = DEFAULT_EXCEPTIONS; + private final Set exceptionsSet = new HashSet<>(); + + @Override + public void init() { + subscribeTo(CxxTokenType.NUMBER); + for (String magicNumber : exceptions.split(",")) { + magicNumber = magicNumber.trim(); + if (!magicNumber.isEmpty()) { + exceptionsSet.add(magicNumber); + } + } + } + + @Override + public void visitNode(AstNode node) { + if (!isConstexpr(node) + && !isConst(node) + && !isExcluded(node) + && !isInEnum(node) + && !isArrayInitializer(node) + && !isGenerated(node) + && !isNullPtr(node)) { + getContext().createLineViolation(this, "Extract this magic number '" + node.getTokenOriginalValue() + + "' into a constant, variable declaration or an enum.", node); + } + } + + private boolean isExcluded(AstNode node) { + return exceptionsSet.contains(node.getTokenOriginalValue()); + } } diff --git a/cxx-checks/src/main/java/org/sonar/cxx/checks/MissingCurlyBracesCheck.java b/cxx-checks/src/main/java/org/sonar/cxx/checks/MissingCurlyBracesCheck.java index 4cc54dc5fd..73a01cf239 100644 --- a/cxx-checks/src/main/java/org/sonar/cxx/checks/MissingCurlyBracesCheck.java +++ b/cxx-checks/src/main/java/org/sonar/cxx/checks/MissingCurlyBracesCheck.java @@ -19,17 +19,17 @@ */ package org.sonar.cxx.checks; +import com.sonar.sslr.api.AstNode; +import com.sonar.sslr.api.Grammar; import org.sonar.check.Priority; import org.sonar.check.Rule; import org.sonar.cxx.api.CxxKeyword; -import org.sonar.cxx.parser.CxxGrammarImpl; -import org.sonar.squidbridge.checks.SquidCheck; -import com.sonar.sslr.api.AstNode; -import com.sonar.sslr.api.Grammar; import static org.sonar.cxx.checks.utils.CheckUtils.isIfStatement; +import org.sonar.cxx.parser.CxxGrammarImpl; +import org.sonar.cxx.tag.Tag; import org.sonar.squidbridge.annotations.ActivatedByDefault; import org.sonar.squidbridge.annotations.SqaleConstantRemediation; -import org.sonar.cxx.tag.Tag; +import org.sonar.squidbridge.checks.SquidCheck; @Rule( key = "MissingCurlyBraces", diff --git a/cxx-checks/src/main/java/org/sonar/cxx/checks/NestedStatementsCheck.java b/cxx-checks/src/main/java/org/sonar/cxx/checks/NestedStatementsCheck.java index deb46906b2..265dac1446 100644 --- a/cxx-checks/src/main/java/org/sonar/cxx/checks/NestedStatementsCheck.java +++ b/cxx-checks/src/main/java/org/sonar/cxx/checks/NestedStatementsCheck.java @@ -58,6 +58,13 @@ public class NestedStatementsCheck extends SquidCheck { private static final int DEFAULT_MAX = 3; + /** + * @return True if the given node is the 'if' in an 'else if' construct. + */ + private static boolean isElseIf(AstNode node) { + return isIfStatement(node) && node.getParent().getPreviousAstNode().getType().equals(CxxKeyword.ELSE); + } + /** * max */ @@ -113,10 +120,4 @@ private void visitChildren(List watchedDescendants) { } } - /** - * @return True if the given node is the 'if' in an 'else if' construct. - */ - private static boolean isElseIf(AstNode node) { - return isIfStatement(node) && node.getParent().getPreviousAstNode().getType().equals(CxxKeyword.ELSE); - } } diff --git a/cxx-checks/src/main/java/org/sonar/cxx/checks/ReservedNamesCheck.java b/cxx-checks/src/main/java/org/sonar/cxx/checks/ReservedNamesCheck.java index 48c4b625d5..95df48ca32 100644 --- a/cxx-checks/src/main/java/org/sonar/cxx/checks/ReservedNamesCheck.java +++ b/cxx-checks/src/main/java/org/sonar/cxx/checks/ReservedNamesCheck.java @@ -29,7 +29,6 @@ import java.util.Locale; import java.util.regex.Matcher; import java.util.regex.Pattern; - import org.sonar.check.Priority; import org.sonar.check.Rule; import org.sonar.cxx.api.CxxKeyword; @@ -53,9 +52,8 @@ public class ReservedNamesCheck extends SquidCheck implements CxxCharsetAwareVisitor { private static final String[] keywords = CxxKeyword.keywordValues(); - private Charset charset = StandardCharsets.UTF_8; private static final Pattern DEFINE_DECLARATION_PATTERN = Pattern.compile("^\\s*#define\\s+([^\\s(]+).*$"); - + private Charset charset = StandardCharsets.UTF_8; @Override public void visitFile(AstNode astNode) { diff --git a/cxx-checks/src/main/java/org/sonar/cxx/checks/SwitchLastCaseIsDefaultCheck.java b/cxx-checks/src/main/java/org/sonar/cxx/checks/SwitchLastCaseIsDefaultCheck.java index 31aa735c3d..dae57b4bce 100644 --- a/cxx-checks/src/main/java/org/sonar/cxx/checks/SwitchLastCaseIsDefaultCheck.java +++ b/cxx-checks/src/main/java/org/sonar/cxx/checks/SwitchLastCaseIsDefaultCheck.java @@ -50,6 +50,20 @@ public class SwitchLastCaseIsDefaultCheck extends SquidCheck { private static final String DEFAULT_CASE_IS_NOT_LAST_MESSAGE = "Move this default to the end of the switch."; private static final String DEFAULT_CASE_TOKENVALUE = "default"; + private static void getSwitchCases(List result, AstNode node) { + if (isSwitchStatement(node)) { + return; + } + if (node.is(CxxGrammarImpl.labeledStatement)) { + result.add(node); + } + if (node.hasChildren()) { + for (AstNode child : node.getChildren()) { + getSwitchCases(result, child); + } + } + } + @Override public void init() { subscribeTo(CHECKED_TYPES); @@ -87,18 +101,4 @@ private List getSwitchCases(AstNode node) { return cases; } - private static void getSwitchCases(List result, AstNode node) { - if (isSwitchStatement(node)) { - return; - } - if (node.is(CxxGrammarImpl.labeledStatement)) { - result.add(node); - } - if (node.hasChildren()) { - for (AstNode child : node.getChildren()) { - getSwitchCases(result, child); - } - } - } - } diff --git a/cxx-checks/src/main/java/org/sonar/cxx/checks/UnnamedNamespaceInHeaderCheck.java b/cxx-checks/src/main/java/org/sonar/cxx/checks/UnnamedNamespaceInHeaderCheck.java index 9516472870..ee725b8bd8 100644 --- a/cxx-checks/src/main/java/org/sonar/cxx/checks/UnnamedNamespaceInHeaderCheck.java +++ b/cxx-checks/src/main/java/org/sonar/cxx/checks/UnnamedNamespaceInHeaderCheck.java @@ -39,7 +39,16 @@ //similar Vera++ rule T017 public class UnnamedNamespaceInHeaderCheck extends SquidCheck { - private static final String[] DEFAULT_NAME_SUFFIX = new String[] { ".h", ".hh", ".hpp", ".H" }; + private static final String[] DEFAULT_NAME_SUFFIX = new String[]{".h", ".hh", ".hpp", ".H"}; + + private static boolean isHeader(String name) { + for (String suff : DEFAULT_NAME_SUFFIX) { + if (name.endsWith(suff)) { + return true; + } + } + return false; + } private Boolean isHeader = false; @Override @@ -61,12 +70,4 @@ public void visitNode(AstNode node) { } } - private static boolean isHeader(String name) { - for (String suff : DEFAULT_NAME_SUFFIX) { - if (name.endsWith(suff)) { - return true; - } - } - return false; - } } diff --git a/cxx-checks/src/main/java/org/sonar/cxx/checks/UsingNamespaceInHeaderCheck.java b/cxx-checks/src/main/java/org/sonar/cxx/checks/UsingNamespaceInHeaderCheck.java index f088279651..92fe5575a7 100644 --- a/cxx-checks/src/main/java/org/sonar/cxx/checks/UsingNamespaceInHeaderCheck.java +++ b/cxx-checks/src/main/java/org/sonar/cxx/checks/UsingNamespaceInHeaderCheck.java @@ -39,7 +39,16 @@ //similar Vera++ rule T018 public class UsingNamespaceInHeaderCheck extends SquidCheck { - private static final String[] DEFAULT_NAME_SUFFIX = new String[] { ".h", ".hh", ".hpp", ".H" }; + private static final String[] DEFAULT_NAME_SUFFIX = new String[]{".h", ".hh", ".hpp", ".H"}; + + private static boolean isHeader(String name) { + for (String suff : DEFAULT_NAME_SUFFIX) { + if (name.endsWith(suff)) { + return true; + } + } + return false; + } private Boolean isHeader = false; @Override @@ -60,12 +69,4 @@ public void visitNode(AstNode node) { } } - private static boolean isHeader(String name) { - for (String suff : DEFAULT_NAME_SUFFIX) { - if (name.endsWith(suff)) { - return true; - } - } - return false; - } } diff --git a/cxx-checks/src/main/java/org/sonar/cxx/checks/api/UndocumentedApiCheck.java b/cxx-checks/src/main/java/org/sonar/cxx/checks/api/UndocumentedApiCheck.java index fd33fb2f7b..5546b69a71 100644 --- a/cxx-checks/src/main/java/org/sonar/cxx/checks/api/UndocumentedApiCheck.java +++ b/cxx-checks/src/main/java/org/sonar/cxx/checks/api/UndocumentedApiCheck.java @@ -48,8 +48,8 @@ * *

* Public API items are considered documented if they have Doxygen comments.
- * Function arguments are not counted since they can be documented in function - * documentation and this visitor does not parse Doxygen comments.
+ * Function arguments are not counted since they can be documented in function documentation and this visitor does not + * parse Doxygen comments.
* This visitor should be applied only on header files.
* Currently, no filtering is applied using preprocessing directive.
*

diff --git a/cxx-checks/src/main/java/org/sonar/cxx/checks/error/MissingIncludeFileCheck.java b/cxx-checks/src/main/java/org/sonar/cxx/checks/error/MissingIncludeFileCheck.java index 34c68e6e1b..a623f85e89 100644 --- a/cxx-checks/src/main/java/org/sonar/cxx/checks/error/MissingIncludeFileCheck.java +++ b/cxx-checks/src/main/java/org/sonar/cxx/checks/error/MissingIncludeFileCheck.java @@ -19,6 +19,8 @@ */ package org.sonar.cxx.checks.error; +import com.sonar.sslr.api.AstNode; +import com.sonar.sslr.api.Grammar; import org.sonar.check.Priority; import org.sonar.check.Rule; import org.sonar.cxx.parser.CxxParser; @@ -28,9 +30,6 @@ import org.sonar.squidbridge.annotations.NoSqale; import org.sonar.squidbridge.checks.SquidCheck; -import com.sonar.sslr.api.AstNode; -import com.sonar.sslr.api.Grammar; - @Rule( key = "MissingIncludeFile", name = "C++ preprocessor unable to locate file referenced by #include directive", diff --git a/cxx-checks/src/main/java/org/sonar/cxx/checks/file/MissingNewLineAtEndOfFileCheck.java b/cxx-checks/src/main/java/org/sonar/cxx/checks/file/MissingNewLineAtEndOfFileCheck.java index a89d78f4a7..39886d5962 100644 --- a/cxx-checks/src/main/java/org/sonar/cxx/checks/file/MissingNewLineAtEndOfFileCheck.java +++ b/cxx-checks/src/main/java/org/sonar/cxx/checks/file/MissingNewLineAtEndOfFileCheck.java @@ -40,19 +40,6 @@ @SqaleConstantRemediation("1min") public class MissingNewLineAtEndOfFileCheck extends SquidCheck { - @Override - public void visitFile(AstNode astNode) { - try { - try (RandomAccessFile randomAccessFile = new RandomAccessFile(getContext().getFile(), "r")) { - if (!endsWithNewline(randomAccessFile)) { - getContext().createFileViolation(this, "Add a new line at the end of this file."); - } - } - } catch (IOException e) { - throw new IllegalStateException(e); - } - } - private static boolean endsWithNewline(RandomAccessFile randomAccessFile) throws IOException { if (randomAccessFile.length() < 1) { return false; @@ -66,4 +53,17 @@ private static boolean endsWithNewline(RandomAccessFile randomAccessFile) throws return "\n".equals(ch) || "\r".equals(ch); } + @Override + public void visitFile(AstNode astNode) { + try { + try (RandomAccessFile randomAccessFile = new RandomAccessFile(getContext().getFile(), "r")) { + if (!endsWithNewline(randomAccessFile)) { + getContext().createFileViolation(this, "Add a new line at the end of this file."); + } + } + } catch (IOException e) { + throw new IllegalStateException(e); + } + } + } diff --git a/cxx-checks/src/main/java/org/sonar/cxx/checks/metrics/ClassComplexityCheck.java b/cxx-checks/src/main/java/org/sonar/cxx/checks/metrics/ClassComplexityCheck.java index 9f168913a5..5197786f70 100644 --- a/cxx-checks/src/main/java/org/sonar/cxx/checks/metrics/ClassComplexityCheck.java +++ b/cxx-checks/src/main/java/org/sonar/cxx/checks/metrics/ClassComplexityCheck.java @@ -19,8 +19,9 @@ */ package org.sonar.cxx.checks.metrics; +import com.sonar.sslr.api.AstNodeType; +import com.sonar.sslr.api.Grammar; import java.util.Optional; - import org.sonar.check.Priority; import org.sonar.check.Rule; import org.sonar.check.RuleProperty; @@ -28,9 +29,6 @@ import org.sonar.cxx.tag.Tag; import org.sonar.squidbridge.annotations.SqaleLinearWithOffsetRemediation; -import com.sonar.sslr.api.AstNodeType; -import com.sonar.sslr.api.Grammar; - @Rule( key = "ClassComplexity", priority = Priority.MAJOR, diff --git a/cxx-checks/src/main/java/org/sonar/cxx/checks/metrics/FileComplexityCheck.java b/cxx-checks/src/main/java/org/sonar/cxx/checks/metrics/FileComplexityCheck.java index fedd895192..6dd63ef638 100644 --- a/cxx-checks/src/main/java/org/sonar/cxx/checks/metrics/FileComplexityCheck.java +++ b/cxx-checks/src/main/java/org/sonar/cxx/checks/metrics/FileComplexityCheck.java @@ -19,17 +19,15 @@ */ package org.sonar.cxx.checks.metrics; +import com.sonar.sslr.api.AstNodeType; +import com.sonar.sslr.api.Grammar; import java.util.Optional; - import org.sonar.check.Priority; import org.sonar.check.Rule; import org.sonar.check.RuleProperty; import org.sonar.cxx.tag.Tag; import org.sonar.squidbridge.annotations.SqaleLinearWithOffsetRemediation; -import com.sonar.sslr.api.AstNodeType; -import com.sonar.sslr.api.Grammar; - @Rule( key = "FileComplexity", name = "Files should not be too complex", diff --git a/cxx-checks/src/main/java/org/sonar/cxx/checks/metrics/FunctionCognitiveComplexityCheck.java b/cxx-checks/src/main/java/org/sonar/cxx/checks/metrics/FunctionCognitiveComplexityCheck.java index a258ff983f..46004f15bc 100644 --- a/cxx-checks/src/main/java/org/sonar/cxx/checks/metrics/FunctionCognitiveComplexityCheck.java +++ b/cxx-checks/src/main/java/org/sonar/cxx/checks/metrics/FunctionCognitiveComplexityCheck.java @@ -19,6 +19,7 @@ */ package org.sonar.cxx.checks.metrics; +import com.sonar.sslr.api.Grammar; import org.sonar.check.Priority; import org.sonar.check.Rule; import org.sonar.check.RuleProperty; @@ -30,8 +31,6 @@ import org.sonar.squidbridge.annotations.ActivatedByDefault; import org.sonar.squidbridge.annotations.SqaleLinearWithOffsetRemediation; -import com.sonar.sslr.api.Grammar; - @Rule( key = "FunctionCognitiveComplexity", name = "Cognitive Complexity of methods/functions should not be too high", @@ -57,7 +56,7 @@ protected void analyzeComplexity(CxxComplexityScope scope) { if (scope.getComplexity() > max) { final StringBuilder msg = new StringBuilder(); msg.append("The Cognitive Complexity of this function is ").append(scope.getComplexity()) - .append(" which is greater than ").append(max).append(" authorized."); + .append(" which is greater than ").append(max).append(" authorized."); final CxxReportIssue issue = new CxxReportIssue(getRuleKey(), null, scope.getStartingLine(), msg.toString()); for (CxxComplexitySource source : scope.getSources()) { diff --git a/cxx-checks/src/main/java/org/sonar/cxx/checks/metrics/FunctionComplexityCheck.java b/cxx-checks/src/main/java/org/sonar/cxx/checks/metrics/FunctionComplexityCheck.java index 2c7e310465..8d644d5ec3 100644 --- a/cxx-checks/src/main/java/org/sonar/cxx/checks/metrics/FunctionComplexityCheck.java +++ b/cxx-checks/src/main/java/org/sonar/cxx/checks/metrics/FunctionComplexityCheck.java @@ -19,8 +19,9 @@ */ package org.sonar.cxx.checks.metrics; +import com.sonar.sslr.api.AstNodeType; +import com.sonar.sslr.api.Grammar; import java.util.Optional; - import org.sonar.check.Priority; import org.sonar.check.Rule; import org.sonar.check.RuleProperty; @@ -29,9 +30,6 @@ import org.sonar.squidbridge.annotations.ActivatedByDefault; import org.sonar.squidbridge.annotations.SqaleLinearWithOffsetRemediation; -import com.sonar.sslr.api.AstNodeType; -import com.sonar.sslr.api.Grammar; - @Rule( key = "FunctionComplexity", name = "Functions should not be too complex", @@ -45,7 +43,6 @@ public class FunctionComplexityCheck extends CxxCyclomaticComplexityCheck { // TODO MultiLineSquidCheck - private static final int DEFAULT_MAX = 10; @RuleProperty( diff --git a/cxx-checks/src/main/java/org/sonar/cxx/checks/metrics/TooManyLinesOfCodeInFunctionCheck.java b/cxx-checks/src/main/java/org/sonar/cxx/checks/metrics/TooManyLinesOfCodeInFunctionCheck.java index 289dc97933..084bb38984 100644 --- a/cxx-checks/src/main/java/org/sonar/cxx/checks/metrics/TooManyLinesOfCodeInFunctionCheck.java +++ b/cxx-checks/src/main/java/org/sonar/cxx/checks/metrics/TooManyLinesOfCodeInFunctionCheck.java @@ -61,7 +61,7 @@ public void leaveNode(AstNode node) { if (lineCount > max) { getContext().createLineViolation(this, "The number of code lines in this function is {0,number,integer} which is greater than " - + "{1,number,integer} authorized.", + + "{1,number,integer} authorized.", node, lineCount, max); } } diff --git a/cxx-checks/src/main/java/org/sonar/cxx/checks/metrics/TooManyStatementsPerLineCheck.java b/cxx-checks/src/main/java/org/sonar/cxx/checks/metrics/TooManyStatementsPerLineCheck.java index 2f2d39e70e..7bda4a3fa6 100644 --- a/cxx-checks/src/main/java/org/sonar/cxx/checks/metrics/TooManyStatementsPerLineCheck.java +++ b/cxx-checks/src/main/java/org/sonar/cxx/checks/metrics/TooManyStatementsPerLineCheck.java @@ -47,8 +47,24 @@ public class TooManyStatementsPerLineCheck extends AbstractOneStatementPerLineCh private static final boolean DEFAULT_EXCLUDE_CASE_BREAK = false; /** - * excludeCaseBreak - Exclude 'break' statement if it is on the same line as - * the switch label (case: or default:) + * Exclude subsequent generated nodes, if they are consecutive and on the same line. + */ + private static boolean isGeneratedNodeExcluded(AstNode astNode) { + AstNode prev = astNode.getPreviousAstNode(); + return prev != null + && prev.getTokenLine() == astNode.getTokenLine() + && prev.isCopyBookOrGeneratedNode(); + } + + /** + * Exclude type alias definitions inside of blocks ( ... { using a = b; ... } ... ) + */ + private static boolean isTypeAlias(AstNode astNode) { + return astNode.getFirstDescendant(CxxGrammarImpl.aliasDeclaration) != null; + } + + /** + * excludeCaseBreak - Exclude 'break' statement if it is on the same line as the switch label (case: or default:) */ @RuleProperty( key = "excludeCaseBreak", @@ -66,17 +82,6 @@ public void init() { subscribeTo(CxxGrammarImpl.statement); } - /** - * Exclude subsequent generated nodes, if they are consecutive and on the same - * line. - */ - private static boolean isGeneratedNodeExcluded(AstNode astNode) { - AstNode prev = astNode.getPreviousAstNode(); - return prev != null - && prev.getTokenLine() == astNode.getTokenLine() - && prev.isCopyBookOrGeneratedNode(); - } - /** * Exclude 'break' statement if it is on the same line as the switch label */ @@ -99,14 +104,6 @@ private boolean isBreakStatementExcluded(AstNode astNode) { return exclude; } - /** - * Exclude type alias definitions inside of blocks ( ... { using a = b; ... } - * ... ) - */ - private static boolean isTypeAlias(AstNode astNode) { - return astNode.getFirstDescendant(CxxGrammarImpl.aliasDeclaration) != null; - } - /** * Exclude empty expression statement */ diff --git a/cxx-checks/src/main/java/org/sonar/cxx/checks/naming/FunctionNameCheck.java b/cxx-checks/src/main/java/org/sonar/cxx/checks/naming/FunctionNameCheck.java index 64a8bcfe36..72a2186bab 100644 --- a/cxx-checks/src/main/java/org/sonar/cxx/checks/naming/FunctionNameCheck.java +++ b/cxx-checks/src/main/java/org/sonar/cxx/checks/naming/FunctionNameCheck.java @@ -46,6 +46,17 @@ public class FunctionNameCheck extends SquidCheck { private static final String DEFAULT = "^[a-z_][a-z0-9_]{2,30}$"; + + private static boolean isFunctionDefinition(AstNode declId) { + boolean isFunction = false; + // not method inside of class + // not a nested name - not method outside of class + if ((declId.getFirstAncestor(CxxGrammarImpl.memberDeclaration) == null) + && (!declId.hasDirectChildren(CxxGrammarImpl.nestedNameSpecifier))) { + isFunction = true; + } + return isFunction; + } private Pattern pattern = null; /** @@ -77,15 +88,4 @@ public void visitNode(AstNode astNode) { } } - private static boolean isFunctionDefinition(AstNode declId) { - boolean isFunction = false; - // not method inside of class - // not a nested name - not method outside of class - if ((declId.getFirstAncestor(CxxGrammarImpl.memberDeclaration) == null) - && (!declId.hasDirectChildren(CxxGrammarImpl.nestedNameSpecifier))) { - isFunction = true; - } - return isFunction; - } - } diff --git a/cxx-checks/src/main/java/org/sonar/cxx/checks/naming/MethodNameCheck.java b/cxx-checks/src/main/java/org/sonar/cxx/checks/naming/MethodNameCheck.java index a2238a8528..acb494b376 100644 --- a/cxx-checks/src/main/java/org/sonar/cxx/checks/naming/MethodNameCheck.java +++ b/cxx-checks/src/main/java/org/sonar/cxx/checks/naming/MethodNameCheck.java @@ -19,11 +19,12 @@ */ package org.sonar.cxx.checks.naming; +import com.sonar.sslr.api.AstNode; +import com.sonar.sslr.api.GenericTokenType; +import com.sonar.sslr.api.Grammar; import java.util.Optional; import java.util.regex.Pattern; - import javax.annotation.Nullable; - import org.sonar.check.Priority; import org.sonar.check.Rule; import org.sonar.check.RuleProperty; @@ -33,10 +34,6 @@ import org.sonar.squidbridge.annotations.SqaleConstantRemediation; import org.sonar.squidbridge.checks.SquidCheck; -import com.sonar.sslr.api.AstNode; -import com.sonar.sslr.api.GenericTokenType; -import com.sonar.sslr.api.Grammar; - /** * MethodNameCheck * @@ -51,33 +48,6 @@ public class MethodNameCheck extends SquidCheck { private static final String DEFAULT = "^[A-Z][A-Za-z0-9]{2,30}$"; - private Pattern pattern = null; - - /** - * format - */ - @RuleProperty( - key = "format", - defaultValue = "" + DEFAULT) - public String format = DEFAULT; - - @Override - public void init() { - pattern = Pattern.compile(format); - subscribeTo(CxxGrammarImpl.functionDefinition); - } - - @Override - public void visitNode(AstNode astNode) { - AstNode idNode = getMethodName(astNode); - if (idNode != null) { - String identifier = idNode.getTokenValue(); - if (!pattern.matcher(identifier).matches()) { - getContext().createLineViolation(this, - "Rename method \"{0}\" to match the regular expression {1}.", idNode, identifier, format); - } - } - } private static @Nullable AstNode getMethodName(AstNode functionDefinition) { @@ -147,5 +117,31 @@ AstNode getOutsideMemberDeclaration(AstNode declId) { } return result; } + private Pattern pattern = null; + /** + * format + */ + @RuleProperty( + key = "format", + defaultValue = "" + DEFAULT) + public String format = DEFAULT; + + @Override + public void init() { + pattern = Pattern.compile(format); + subscribeTo(CxxGrammarImpl.functionDefinition); + } + + @Override + public void visitNode(AstNode astNode) { + AstNode idNode = getMethodName(astNode); + if (idNode != null) { + String identifier = idNode.getTokenValue(); + if (!pattern.matcher(identifier).matches()) { + getContext().createLineViolation(this, + "Rename method \"{0}\" to match the regular expression {1}.", idNode, identifier, format); + } + } + } } diff --git a/cxx-checks/src/main/java/org/sonar/cxx/checks/regex/CommentContainsPatternChecker.java b/cxx-checks/src/main/java/org/sonar/cxx/checks/regex/CommentContainsPatternChecker.java index 2f78ab41c7..9a8e3a29f1 100644 --- a/cxx-checks/src/main/java/org/sonar/cxx/checks/regex/CommentContainsPatternChecker.java +++ b/cxx-checks/src/main/java/org/sonar/cxx/checks/regex/CommentContainsPatternChecker.java @@ -41,6 +41,8 @@ @NoSqale public class CommentContainsPatternChecker { + private static final Pattern EOL_PATTERN = Pattern.compile("\\R"); + @RuleProperty( key = "check", description = "The Squid check") @@ -58,8 +60,6 @@ public class CommentContainsPatternChecker { private final Pattern p; - private static final Pattern EOL_PATTERN = Pattern.compile("\\R"); - /** * CommentContainsPatternChecker * diff --git a/cxx-checks/src/main/java/org/sonar/cxx/checks/regex/FileHeaderCheck.java b/cxx-checks/src/main/java/org/sonar/cxx/checks/regex/FileHeaderCheck.java index 8f4579395f..1326bfd3c8 100644 --- a/cxx-checks/src/main/java/org/sonar/cxx/checks/regex/FileHeaderCheck.java +++ b/cxx-checks/src/main/java/org/sonar/cxx/checks/regex/FileHeaderCheck.java @@ -54,6 +54,27 @@ public class FileHeaderCheck extends SquidCheck implements CxxCharsetAw private static final String DEFAULT_HEADER_FORMAT = ""; private static final String MESSAGE = "Add or update the header of this file."; + private static boolean matches(String[] expectedLines, List lines) { + boolean result; + + if (expectedLines.length <= lines.size()) { + result = true; + + Iterator it = lines.iterator(); + for (String expectedLine : expectedLines) { + String line = it.next(); + if (!line.equals(expectedLine)) { + result = false; + break; + } + } + } else { + result = false; + } + + return result; + } + /** * headerFormat */ @@ -130,24 +151,4 @@ private void checkRegularExpression(String fileContent) { } } - private static boolean matches(String[] expectedLines, List lines) { - boolean result; - - if (expectedLines.length <= lines.size()) { - result = true; - - Iterator it = lines.iterator(); - for (String expectedLine : expectedLines) { - String line = it.next(); - if (!line.equals(expectedLine)) { - result = false; - break; - } - } - } else { - result = false; - } - - return result; - } } diff --git a/cxx-checks/src/main/java/org/sonar/cxx/checks/regex/FileRegularExpressionCheck.java b/cxx-checks/src/main/java/org/sonar/cxx/checks/regex/FileRegularExpressionCheck.java index 81d735e751..7769e4e6eb 100644 --- a/cxx-checks/src/main/java/org/sonar/cxx/checks/regex/FileRegularExpressionCheck.java +++ b/cxx-checks/src/main/java/org/sonar/cxx/checks/regex/FileRegularExpressionCheck.java @@ -61,6 +61,10 @@ public class FileRegularExpressionCheck extends SquidCheck implements C private static final boolean DEFAULT_INVERT_REGULAR_EXPRESSION = false; private static final String DEFAULT_MESSAGE = "The regular expression matches this file"; + private static boolean compare(boolean invert, boolean condition) { + return invert ? !condition : condition; + } + private Charset charset = StandardCharsets.UTF_8; private CharsetDecoder decoder = null; private Pattern pattern = null; @@ -161,7 +165,4 @@ private CharSequence fromFile(File file) throws IOException { } } - private static boolean compare(boolean invert, boolean condition) { - return invert ? !condition : condition; - } } diff --git a/cxx-checks/src/main/java/org/sonar/cxx/checks/regex/LineRegularExpressionCheck.java b/cxx-checks/src/main/java/org/sonar/cxx/checks/regex/LineRegularExpressionCheck.java index 63e7fc99e1..bcb20bb30c 100644 --- a/cxx-checks/src/main/java/org/sonar/cxx/checks/regex/LineRegularExpressionCheck.java +++ b/cxx-checks/src/main/java/org/sonar/cxx/checks/regex/LineRegularExpressionCheck.java @@ -57,6 +57,10 @@ public class LineRegularExpressionCheck extends SquidCheck implements C private static final boolean DEFAULT_INVERT_REGULAR_EXPRESSION = false; private static final String DEFAULT_MESSAGE = "The regular expression matches this line"; + private static boolean compare(boolean invert, boolean condition) { + return invert ? !condition : condition; + } + private Charset charset = StandardCharsets.UTF_8; private Pattern pattern = null; @@ -146,7 +150,4 @@ private boolean matchFile() { return true; } - private static boolean compare(boolean invert, boolean condition) { - return invert ? !condition : condition; - } } diff --git a/cxx-checks/src/main/java/org/sonar/cxx/checks/regex/NoSonarCheck.java b/cxx-checks/src/main/java/org/sonar/cxx/checks/regex/NoSonarCheck.java index 95de16d01e..e4973ad9f9 100644 --- a/cxx-checks/src/main/java/org/sonar/cxx/checks/regex/NoSonarCheck.java +++ b/cxx-checks/src/main/java/org/sonar/cxx/checks/regex/NoSonarCheck.java @@ -23,9 +23,7 @@ import com.sonar.sslr.api.Grammar; import com.sonar.sslr.api.Token; import com.sonar.sslr.api.Trivia; - import java.util.regex.Pattern; - import org.sonar.check.Priority; import org.sonar.check.Rule; import org.sonar.squidbridge.annotations.ActivatedByDefault; diff --git a/cxx-checks/src/main/java/org/sonar/cxx/checks/utils/CheckUtils.java b/cxx-checks/src/main/java/org/sonar/cxx/checks/utils/CheckUtils.java index 4b0e297e3f..9cbc073dcb 100644 --- a/cxx-checks/src/main/java/org/sonar/cxx/checks/utils/CheckUtils.java +++ b/cxx-checks/src/main/java/org/sonar/cxx/checks/utils/CheckUtils.java @@ -27,9 +27,6 @@ public class CheckUtils { - private CheckUtils() { - } - public static boolean isIfStatement(AstNode node) { if (node.is(CxxGrammarImpl.selectionStatement)) { return node.getToken().getType().equals(CxxKeyword.IF); @@ -57,4 +54,7 @@ public static boolean isIdentifierLabel(AstNode node) { return false; } + private CheckUtils() { + } + } diff --git a/cxx-checks/src/main/java/org/sonar/cxx/checks/xpath/XPathCheck.java b/cxx-checks/src/main/java/org/sonar/cxx/checks/xpath/XPathCheck.java index 1ea975fb9d..67db0cfb37 100644 --- a/cxx-checks/src/main/java/org/sonar/cxx/checks/xpath/XPathCheck.java +++ b/cxx-checks/src/main/java/org/sonar/cxx/checks/xpath/XPathCheck.java @@ -43,6 +43,10 @@ public class XPathCheck extends AbstractXPathCheck { private static final String DEFAULT_XPATH_QUERY = ""; private static final String DEFAULT_MESSAGE = "The XPath expression matches this piece of code"; + private static boolean compare(boolean invert, boolean condition) { + return invert ? !condition : condition; + } + @RuleProperty( key = "matchFilePattern", description = "Ant-style matching patterns for path", @@ -90,7 +94,4 @@ public void visitFile(AstNode fileNode) { super.visitFile(fileNode); } - private static boolean compare(boolean invert, boolean condition) { - return invert ? !condition : condition; - } } diff --git a/cxx-checks/src/test/java/org/sonar/cxx/checks/BooleanEqualityComparisonCheckTest.java b/cxx-checks/src/test/java/org/sonar/cxx/checks/BooleanEqualityComparisonCheckTest.java index 0b89c87852..9738430375 100644 --- a/cxx-checks/src/test/java/org/sonar/cxx/checks/BooleanEqualityComparisonCheckTest.java +++ b/cxx-checks/src/test/java/org/sonar/cxx/checks/BooleanEqualityComparisonCheckTest.java @@ -21,7 +21,6 @@ import java.io.IOException; import java.io.UnsupportedEncodingException; - import org.junit.Rule; import org.junit.Test; import org.sonar.cxx.CxxAstScanner; diff --git a/cxx-checks/src/test/java/org/sonar/cxx/checks/CollapsibleIfCandidateCheckTest.java b/cxx-checks/src/test/java/org/sonar/cxx/checks/CollapsibleIfCandidateCheckTest.java index 337e6f30a1..eb322f97ed 100644 --- a/cxx-checks/src/test/java/org/sonar/cxx/checks/CollapsibleIfCandidateCheckTest.java +++ b/cxx-checks/src/test/java/org/sonar/cxx/checks/CollapsibleIfCandidateCheckTest.java @@ -21,7 +21,6 @@ import java.io.IOException; import java.io.UnsupportedEncodingException; - import org.junit.Rule; import org.junit.Test; import org.sonar.cxx.CxxAstScanner; diff --git a/cxx-checks/src/test/java/org/sonar/cxx/checks/CommentedCodeCheckTest.java b/cxx-checks/src/test/java/org/sonar/cxx/checks/CommentedCodeCheckTest.java index 9dfbf75a81..f0adac1a58 100644 --- a/cxx-checks/src/test/java/org/sonar/cxx/checks/CommentedCodeCheckTest.java +++ b/cxx-checks/src/test/java/org/sonar/cxx/checks/CommentedCodeCheckTest.java @@ -21,7 +21,6 @@ import java.io.IOException; import java.io.UnsupportedEncodingException; - import org.junit.Rule; import org.junit.Test; import org.sonar.cxx.CxxAstScanner; diff --git a/cxx-checks/src/test/java/org/sonar/cxx/checks/CxxFileTesterHelper.java b/cxx-checks/src/test/java/org/sonar/cxx/checks/CxxFileTesterHelper.java index d72332c016..74908dc639 100644 --- a/cxx-checks/src/test/java/org/sonar/cxx/checks/CxxFileTesterHelper.java +++ b/cxx-checks/src/test/java/org/sonar/cxx/checks/CxxFileTesterHelper.java @@ -24,10 +24,8 @@ import java.io.UnsupportedEncodingException; import java.nio.charset.Charset; import java.util.Optional; - import org.mockito.Mockito; import static org.mockito.Mockito.when; - import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.api.batch.sensor.internal.SensorContextTester; import org.sonar.cxx.CxxLanguage; @@ -66,7 +64,7 @@ public static CxxLanguage mockCxxLanguage() { when(language.IsRecoveryEnabled()).thenReturn(Optional.of(Boolean.TRUE)); when(language.getFileSuffixes()) .thenReturn(new String[]{".cpp", ".hpp", ".h", ".cxx", ".c", ".cc", ".hxx", ".hh"}); - when(language.getHeaderFileSuffixes()).thenReturn(new String[] { ".hpp", ".h", ".hxx", ".hh" }); + when(language.getHeaderFileSuffixes()).thenReturn(new String[]{".hpp", ".h", ".hxx", ".hh"}); return language; } diff --git a/cxx-checks/src/test/java/org/sonar/cxx/checks/HardcodedAccountCheckTest.java b/cxx-checks/src/test/java/org/sonar/cxx/checks/HardcodedAccountCheckTest.java index 603642353d..0b3277d13d 100644 --- a/cxx-checks/src/test/java/org/sonar/cxx/checks/HardcodedAccountCheckTest.java +++ b/cxx-checks/src/test/java/org/sonar/cxx/checks/HardcodedAccountCheckTest.java @@ -21,12 +21,9 @@ import java.io.IOException; import java.io.UnsupportedEncodingException; - -//import org.sonar.squid.api.CheckMessage; import org.junit.Rule; import org.junit.Test; import org.sonar.cxx.CxxAstScanner; -//import org.sonar.java.model.VisitorsBridge; import org.sonar.squidbridge.api.SourceFile; import org.sonar.squidbridge.checks.CheckMessagesVerifier; import org.sonar.squidbridge.checks.CheckMessagesVerifierRule; diff --git a/cxx-checks/src/test/java/org/sonar/cxx/checks/HardcodedIpCheckTest.java b/cxx-checks/src/test/java/org/sonar/cxx/checks/HardcodedIpCheckTest.java index 970f6ab1d9..20186be01b 100644 --- a/cxx-checks/src/test/java/org/sonar/cxx/checks/HardcodedIpCheckTest.java +++ b/cxx-checks/src/test/java/org/sonar/cxx/checks/HardcodedIpCheckTest.java @@ -21,12 +21,9 @@ import java.io.IOException; import java.io.UnsupportedEncodingException; - -//import org.sonar.squid.api.CheckMessage; import org.junit.Rule; import org.junit.Test; import org.sonar.cxx.CxxAstScanner; -//import org.sonar.java.model.VisitorsBridge; import org.sonar.squidbridge.api.SourceFile; import org.sonar.squidbridge.checks.CheckMessagesVerifier; import org.sonar.squidbridge.checks.CheckMessagesVerifierRule; diff --git a/cxx-checks/src/test/java/org/sonar/cxx/checks/MagicNumberCheckTest.java b/cxx-checks/src/test/java/org/sonar/cxx/checks/MagicNumberCheckTest.java index 31f134b557..87b2d752b0 100755 --- a/cxx-checks/src/test/java/org/sonar/cxx/checks/MagicNumberCheckTest.java +++ b/cxx-checks/src/test/java/org/sonar/cxx/checks/MagicNumberCheckTest.java @@ -21,7 +21,6 @@ import java.io.IOException; import java.io.UnsupportedEncodingException; - import org.junit.Rule; import org.junit.Test; import org.sonar.cxx.CxxAstScanner; diff --git a/cxx-checks/src/test/java/org/sonar/cxx/checks/MissingCurlyBracesCheckTest.java b/cxx-checks/src/test/java/org/sonar/cxx/checks/MissingCurlyBracesCheckTest.java index 43a4e2495b..8a37b77dc5 100644 --- a/cxx-checks/src/test/java/org/sonar/cxx/checks/MissingCurlyBracesCheckTest.java +++ b/cxx-checks/src/test/java/org/sonar/cxx/checks/MissingCurlyBracesCheckTest.java @@ -21,7 +21,6 @@ import java.io.IOException; import java.io.UnsupportedEncodingException; - import org.junit.Test; import org.sonar.cxx.CxxAstScanner; import org.sonar.squidbridge.api.SourceFile; diff --git a/cxx-checks/src/test/java/org/sonar/cxx/checks/NestedStatementsCheckTest.java b/cxx-checks/src/test/java/org/sonar/cxx/checks/NestedStatementsCheckTest.java index 56b8e256b5..0d00609721 100644 --- a/cxx-checks/src/test/java/org/sonar/cxx/checks/NestedStatementsCheckTest.java +++ b/cxx-checks/src/test/java/org/sonar/cxx/checks/NestedStatementsCheckTest.java @@ -19,13 +19,13 @@ */ package org.sonar.cxx.checks; +import java.io.IOException; +import java.io.UnsupportedEncodingException; import org.junit.Rule; import org.junit.Test; import org.sonar.cxx.CxxAstScanner; import org.sonar.squidbridge.api.SourceFile; import org.sonar.squidbridge.checks.CheckMessagesVerifierRule; -import java.io.IOException; -import java.io.UnsupportedEncodingException; public class NestedStatementsCheckTest { diff --git a/cxx-checks/src/test/java/org/sonar/cxx/checks/api/UndocumentedApiCheckTest.java b/cxx-checks/src/test/java/org/sonar/cxx/checks/api/UndocumentedApiCheckTest.java index cf60cee0ea..3ae0d044ac 100644 --- a/cxx-checks/src/test/java/org/sonar/cxx/checks/api/UndocumentedApiCheckTest.java +++ b/cxx-checks/src/test/java/org/sonar/cxx/checks/api/UndocumentedApiCheckTest.java @@ -19,10 +19,9 @@ */ package org.sonar.cxx.checks.api; -import static org.assertj.core.api.Assertions.assertThat; - import java.io.IOException; import java.io.UnsupportedEncodingException; +import static org.assertj.core.api.Assertions.assertThat; import org.junit.Rule; import org.junit.Test; import org.sonar.cxx.CxxAstScanner; diff --git a/cxx-checks/src/test/java/org/sonar/cxx/checks/error/ParsingErrorCheckTest.java b/cxx-checks/src/test/java/org/sonar/cxx/checks/error/ParsingErrorCheckTest.java index ff6d07ccce..59121f0ecf 100644 --- a/cxx-checks/src/test/java/org/sonar/cxx/checks/error/ParsingErrorCheckTest.java +++ b/cxx-checks/src/test/java/org/sonar/cxx/checks/error/ParsingErrorCheckTest.java @@ -19,10 +19,9 @@ */ package org.sonar.cxx.checks.error; -import static org.hamcrest.Matchers.containsString; - import java.io.IOException; import java.io.UnsupportedEncodingException; +import static org.hamcrest.Matchers.containsString; import org.junit.Test; import org.sonar.cxx.CxxAstScanner; import org.sonar.cxx.CxxConfiguration; diff --git a/cxx-checks/src/test/java/org/sonar/cxx/checks/file/FileEncodingCheckTest.java b/cxx-checks/src/test/java/org/sonar/cxx/checks/file/FileEncodingCheckTest.java index ed9a673426..8ea177aff7 100644 --- a/cxx-checks/src/test/java/org/sonar/cxx/checks/file/FileEncodingCheckTest.java +++ b/cxx-checks/src/test/java/org/sonar/cxx/checks/file/FileEncodingCheckTest.java @@ -23,7 +23,6 @@ import java.io.UnsupportedEncodingException; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; - import org.junit.Test; import org.sonar.cxx.CxxAstScanner; import org.sonar.cxx.CxxConfiguration; diff --git a/cxx-checks/src/test/java/org/sonar/cxx/checks/file/MissingNewLineAtEndOfFileCheckTest.java b/cxx-checks/src/test/java/org/sonar/cxx/checks/file/MissingNewLineAtEndOfFileCheckTest.java index 8c28ef67ff..3a8dd7b3cb 100644 --- a/cxx-checks/src/test/java/org/sonar/cxx/checks/file/MissingNewLineAtEndOfFileCheckTest.java +++ b/cxx-checks/src/test/java/org/sonar/cxx/checks/file/MissingNewLineAtEndOfFileCheckTest.java @@ -21,7 +21,6 @@ import java.io.IOException; import java.io.UnsupportedEncodingException; - import org.junit.Test; import org.sonar.cxx.CxxAstScanner; import org.sonar.cxx.checks.CxxFileTester; diff --git a/cxx-checks/src/test/java/org/sonar/cxx/checks/metrics/ClassComplexityCheckTest.java b/cxx-checks/src/test/java/org/sonar/cxx/checks/metrics/ClassComplexityCheckTest.java index 10c103a7c9..3bc49deea8 100644 --- a/cxx-checks/src/test/java/org/sonar/cxx/checks/metrics/ClassComplexityCheckTest.java +++ b/cxx-checks/src/test/java/org/sonar/cxx/checks/metrics/ClassComplexityCheckTest.java @@ -19,12 +19,10 @@ */ package org.sonar.cxx.checks.metrics; -import static org.assertj.core.api.Assertions.assertThat; - import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.Set; - +import static org.assertj.core.api.Assertions.assertThat; import org.assertj.core.api.SoftAssertions; import org.junit.Test; import org.sonar.cxx.CxxAstScanner; @@ -52,54 +50,54 @@ public void test() throws UnsupportedEncodingException, IOException { softly.assertThat(issues).allSatisfy(issue -> "ClassComplexity".equals(issue.getRuleId())); CxxReportIssue issue0 = issues.stream().filter(issue -> issue.getLocations().get(0).getLine().equals("9")) - .findFirst().orElseThrow(() -> new AssertionError("No issue at line 9")); + .findFirst().orElseThrow(() -> new AssertionError("No issue at line 9")); softly.assertThat(issue0.getLocations()).containsOnly( - new CxxReportLocation(null, "9", - "The Cyclomatic Complexity of this class is 12 which is greater than 5 authorized."), - new CxxReportLocation(null, "14", "+1: function definition"), - new CxxReportLocation(null, "16", "+1: function definition"), - new CxxReportLocation(null, "21", "+1: function definition"), - new CxxReportLocation(null, "22", "+1: function definition"), - new CxxReportLocation(null, "25", "+1: function definition"), - new CxxReportLocation(null, "26", "+1: if statement"), - new CxxReportLocation(null, "27", "+1: if statement"), - new CxxReportLocation(null, "28", "+1: conditional operator"), - new CxxReportLocation(null, "30", "+1: conditional operator"), - new CxxReportLocation(null, "33", "+1: if statement"), - new CxxReportLocation(null, "34", "+1: conditional operator"), - new CxxReportLocation(null, "36", "+1: conditional operator")); + new CxxReportLocation(null, "9", + "The Cyclomatic Complexity of this class is 12 which is greater than 5 authorized."), + new CxxReportLocation(null, "14", "+1: function definition"), + new CxxReportLocation(null, "16", "+1: function definition"), + new CxxReportLocation(null, "21", "+1: function definition"), + new CxxReportLocation(null, "22", "+1: function definition"), + new CxxReportLocation(null, "25", "+1: function definition"), + new CxxReportLocation(null, "26", "+1: if statement"), + new CxxReportLocation(null, "27", "+1: if statement"), + new CxxReportLocation(null, "28", "+1: conditional operator"), + new CxxReportLocation(null, "30", "+1: conditional operator"), + new CxxReportLocation(null, "33", "+1: if statement"), + new CxxReportLocation(null, "34", "+1: conditional operator"), + new CxxReportLocation(null, "36", "+1: conditional operator")); CxxReportIssue issue1 = issues.stream().filter(issue -> issue.getLocations().get(0).getLine().equals("42")) - .findFirst().orElseThrow(() -> new AssertionError("No issue at line 42")); + .findFirst().orElseThrow(() -> new AssertionError("No issue at line 42")); softly.assertThat(issue1.getLocations()).containsOnly( - new CxxReportLocation(null, "42", - "The Cyclomatic Complexity of this class is 10 which is greater than 5 authorized."), - new CxxReportLocation(null, "47", "+1: function definition"), - new CxxReportLocation(null, "49", "+1: function definition"), - new CxxReportLocation(null, "51", "+1: switch label"), - new CxxReportLocation(null, "53", "+1: switch label"), - new CxxReportLocation(null, "57", "+1: function definition"), - new CxxReportLocation(null, "58", "+1: for loop"), - new CxxReportLocation(null, "59", "+1: if statement"), - new CxxReportLocation(null, "59", "+1: logical operator"), - new CxxReportLocation(null, "59", "+1: logical operator"), - new CxxReportLocation(null, "65", "+1: function definition") + new CxxReportLocation(null, "42", + "The Cyclomatic Complexity of this class is 10 which is greater than 5 authorized."), + new CxxReportLocation(null, "47", "+1: function definition"), + new CxxReportLocation(null, "49", "+1: function definition"), + new CxxReportLocation(null, "51", "+1: switch label"), + new CxxReportLocation(null, "53", "+1: switch label"), + new CxxReportLocation(null, "57", "+1: function definition"), + new CxxReportLocation(null, "58", "+1: for loop"), + new CxxReportLocation(null, "59", "+1: if statement"), + new CxxReportLocation(null, "59", "+1: logical operator"), + new CxxReportLocation(null, "59", "+1: logical operator"), + new CxxReportLocation(null, "65", "+1: function definition") ); CxxReportIssue issue2 = issues.stream().filter(issue -> issue.getLocations().get(0).getLine().equals("45")) - .findFirst().orElseThrow(() -> new AssertionError("No issue at line 45")); + .findFirst().orElseThrow(() -> new AssertionError("No issue at line 45")); softly.assertThat(issue2.getLocations()).containsOnly( - new CxxReportLocation(null, "45", - "The Cyclomatic Complexity of this class is 9 which is greater than 5 authorized."), - new CxxReportLocation(null, "47", "+1: function definition"), - new CxxReportLocation(null, "49", "+1: function definition"), - new CxxReportLocation(null, "51", "+1: switch label"), - new CxxReportLocation(null, "53", "+1: switch label"), - new CxxReportLocation(null, "57", "+1: function definition"), - new CxxReportLocation(null, "58", "+1: for loop"), - new CxxReportLocation(null, "59", "+1: if statement"), - new CxxReportLocation(null, "59", "+1: logical operator"), - new CxxReportLocation(null, "59", "+1: logical operator")); + new CxxReportLocation(null, "45", + "The Cyclomatic Complexity of this class is 9 which is greater than 5 authorized."), + new CxxReportLocation(null, "47", "+1: function definition"), + new CxxReportLocation(null, "49", "+1: function definition"), + new CxxReportLocation(null, "51", "+1: switch label"), + new CxxReportLocation(null, "53", "+1: switch label"), + new CxxReportLocation(null, "57", "+1: function definition"), + new CxxReportLocation(null, "58", "+1: for loop"), + new CxxReportLocation(null, "59", "+1: if statement"), + new CxxReportLocation(null, "59", "+1: logical operator"), + new CxxReportLocation(null, "59", "+1: logical operator")); softly.assertAll(); diff --git a/cxx-checks/src/test/java/org/sonar/cxx/checks/metrics/FileComplexityCheckTest.java b/cxx-checks/src/test/java/org/sonar/cxx/checks/metrics/FileComplexityCheckTest.java index e9fa7cba7b..1deb455519 100644 --- a/cxx-checks/src/test/java/org/sonar/cxx/checks/metrics/FileComplexityCheckTest.java +++ b/cxx-checks/src/test/java/org/sonar/cxx/checks/metrics/FileComplexityCheckTest.java @@ -19,12 +19,10 @@ */ package org.sonar.cxx.checks.metrics; -import static org.assertj.core.api.Assertions.assertThat; - import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.Set; - +import static org.assertj.core.api.Assertions.assertThat; import org.assertj.core.api.SoftAssertions; import org.junit.Test; import org.sonar.cxx.CxxAstScanner; @@ -53,10 +51,10 @@ public void check() throws UnsupportedEncodingException, IOException { CxxReportIssue actualIssue = issues.iterator().next(); softly.assertThat(actualIssue.getRuleId()).isEqualTo("FileComplexity"); softly.assertThat(actualIssue.getLocations()).containsOnly( - new CxxReportLocation(null, "1", - "The Cyclomatic Complexity of this file is 2 which is greater than 1 authorized."), - new CxxReportLocation(null, "3", "+1: function definition"), - new CxxReportLocation(null, "5", "+1: function definition")); + new CxxReportLocation(null, "1", + "The Cyclomatic Complexity of this file is 2 which is greater than 1 authorized."), + new CxxReportLocation(null, "3", "+1: function definition"), + new CxxReportLocation(null, "5", "+1: function definition")); softly.assertAll(); } diff --git a/cxx-checks/src/test/java/org/sonar/cxx/checks/metrics/FunctionCognitiveComplexityCheckTest.java b/cxx-checks/src/test/java/org/sonar/cxx/checks/metrics/FunctionCognitiveComplexityCheckTest.java index 3bb4423644..873e4f92d4 100644 --- a/cxx-checks/src/test/java/org/sonar/cxx/checks/metrics/FunctionCognitiveComplexityCheckTest.java +++ b/cxx-checks/src/test/java/org/sonar/cxx/checks/metrics/FunctionCognitiveComplexityCheckTest.java @@ -19,12 +19,10 @@ */ package org.sonar.cxx.checks.metrics; -import static org.assertj.core.api.Assertions.assertThat; - import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.Set; - +import static org.assertj.core.api.Assertions.assertThat; import org.assertj.core.api.SoftAssertions; import org.junit.Test; import org.sonar.cxx.CxxAstScanner; @@ -51,83 +49,83 @@ public void check() throws UnsupportedEncodingException, IOException { softly.assertThat(issues).allSatisfy(issue -> "FunctionCognitiveComplexity".equals(issue.getRuleId())); CxxReportIssue issue0 = issues.stream().filter(issue -> issue.getLocations().get(0).getLine().equals("13")) - .findFirst().orElseThrow(() -> new AssertionError("No issue at line 13")); + .findFirst().orElseThrow(() -> new AssertionError("No issue at line 13")); softly.assertThat(issue0.getLocations()).containsOnly( - new CxxReportLocation(null, "13", "The Cognitive Complexity of this function is 20 which is greater than 5 authorized."), - new CxxReportLocation(null, "14", "+1: if statement"), - new CxxReportLocation(null, "15", "+2: if statement (incl 1 for nesting)"), - new CxxReportLocation(null, "16", "+3: conditional operator (incl 2 for nesting)"), - new CxxReportLocation(null, "17", "+1: else statement"), - new CxxReportLocation(null, "18", "+3: conditional operator (incl 2 for nesting)"), - new CxxReportLocation(null, "20", "+1: else statement"), - new CxxReportLocation(null, "21", "+2: if statement (incl 1 for nesting)"), - new CxxReportLocation(null, "22", "+3: conditional operator (incl 2 for nesting)"), - new CxxReportLocation(null, "23", "+1: else statement"), - new CxxReportLocation(null, "24", "+3: conditional operator (incl 2 for nesting)")); + new CxxReportLocation(null, "13", "The Cognitive Complexity of this function is 20 which is greater than 5 authorized."), + new CxxReportLocation(null, "14", "+1: if statement"), + new CxxReportLocation(null, "15", "+2: if statement (incl 1 for nesting)"), + new CxxReportLocation(null, "16", "+3: conditional operator (incl 2 for nesting)"), + new CxxReportLocation(null, "17", "+1: else statement"), + new CxxReportLocation(null, "18", "+3: conditional operator (incl 2 for nesting)"), + new CxxReportLocation(null, "20", "+1: else statement"), + new CxxReportLocation(null, "21", "+2: if statement (incl 1 for nesting)"), + new CxxReportLocation(null, "22", "+3: conditional operator (incl 2 for nesting)"), + new CxxReportLocation(null, "23", "+1: else statement"), + new CxxReportLocation(null, "24", "+3: conditional operator (incl 2 for nesting)")); CxxReportIssue issue1 = issues.stream().filter(issue -> issue.getLocations().get(0).getLine().equals("33")) - .findFirst().orElseThrow(() -> new AssertionError("No issue at line 33")); + .findFirst().orElseThrow(() -> new AssertionError("No issue at line 33")); softly.assertThat(issue1.getLocations()).containsOnly( - new CxxReportLocation(null, "33", "The Cognitive Complexity of this function is 20 which is greater than 5 authorized."), - new CxxReportLocation(null, "34", "+1: if statement"), - new CxxReportLocation(null, "35", "+2: if statement (incl 1 for nesting)"), - new CxxReportLocation(null, "36", "+3: conditional operator (incl 2 for nesting)"), - new CxxReportLocation(null, "37", "+1: else statement"), - new CxxReportLocation(null, "38", "+3: conditional operator (incl 2 for nesting)"), - new CxxReportLocation(null, "40", "+1: else statement"), - new CxxReportLocation(null, "41", "+2: if statement (incl 1 for nesting)"), - new CxxReportLocation(null, "42", "+3: conditional operator (incl 2 for nesting)"), - new CxxReportLocation(null, "43", "+1: else statement"), - new CxxReportLocation(null, "44", "+3: conditional operator (incl 2 for nesting)")); + new CxxReportLocation(null, "33", "The Cognitive Complexity of this function is 20 which is greater than 5 authorized."), + new CxxReportLocation(null, "34", "+1: if statement"), + new CxxReportLocation(null, "35", "+2: if statement (incl 1 for nesting)"), + new CxxReportLocation(null, "36", "+3: conditional operator (incl 2 for nesting)"), + new CxxReportLocation(null, "37", "+1: else statement"), + new CxxReportLocation(null, "38", "+3: conditional operator (incl 2 for nesting)"), + new CxxReportLocation(null, "40", "+1: else statement"), + new CxxReportLocation(null, "41", "+2: if statement (incl 1 for nesting)"), + new CxxReportLocation(null, "42", "+3: conditional operator (incl 2 for nesting)"), + new CxxReportLocation(null, "43", "+1: else statement"), + new CxxReportLocation(null, "44", "+3: conditional operator (incl 2 for nesting)")); CxxReportIssue issue2 = issues.stream().filter(issue -> issue.getLocations().get(0).getLine().equals("51")) - .findFirst().orElseThrow(() -> new AssertionError("No issue at line 51")); + .findFirst().orElseThrow(() -> new AssertionError("No issue at line 51")); softly.assertThat(issue2.getLocations()).containsOnly( - new CxxReportLocation(null, "51", "The Cognitive Complexity of this function is 20 which is greater than 5 authorized."), - new CxxReportLocation(null, "52", "+1: if statement"), - new CxxReportLocation(null, "53", "+2: if statement (incl 1 for nesting)"), - new CxxReportLocation(null, "54", "+3: conditional operator (incl 2 for nesting)"), - new CxxReportLocation(null, "55", "+1: else statement"), - new CxxReportLocation(null, "56", "+3: conditional operator (incl 2 for nesting)"), - new CxxReportLocation(null, "58", "+1: else statement"), - new CxxReportLocation(null, "59", "+2: if statement (incl 1 for nesting)"), - new CxxReportLocation(null, "60", "+3: conditional operator (incl 2 for nesting)"), - new CxxReportLocation(null, "61", "+1: else statement"), - new CxxReportLocation(null, "62", "+3: conditional operator (incl 2 for nesting)")); + new CxxReportLocation(null, "51", "The Cognitive Complexity of this function is 20 which is greater than 5 authorized."), + new CxxReportLocation(null, "52", "+1: if statement"), + new CxxReportLocation(null, "53", "+2: if statement (incl 1 for nesting)"), + new CxxReportLocation(null, "54", "+3: conditional operator (incl 2 for nesting)"), + new CxxReportLocation(null, "55", "+1: else statement"), + new CxxReportLocation(null, "56", "+3: conditional operator (incl 2 for nesting)"), + new CxxReportLocation(null, "58", "+1: else statement"), + new CxxReportLocation(null, "59", "+2: if statement (incl 1 for nesting)"), + new CxxReportLocation(null, "60", "+3: conditional operator (incl 2 for nesting)"), + new CxxReportLocation(null, "61", "+1: else statement"), + new CxxReportLocation(null, "62", "+3: conditional operator (incl 2 for nesting)")); CxxReportIssue issue3 = issues.stream().filter(issue -> issue.getLocations().get(0).getLine().equals("72")) - .findFirst().orElseThrow(() -> new AssertionError("No issue at line 72")); + .findFirst().orElseThrow(() -> new AssertionError("No issue at line 72")); softly.assertThat(issue3.getLocations()).containsOnly( - new CxxReportLocation(null, "72", "The Cognitive Complexity of this function is 20 which is greater than 5 authorized."), - new CxxReportLocation(null, "73", "+1: if statement"), - new CxxReportLocation(null, "74", "+2: if statement (incl 1 for nesting)"), - new CxxReportLocation(null, "75", "+3: conditional operator (incl 2 for nesting)"), - new CxxReportLocation(null, "76", "+1: else statement"), - new CxxReportLocation(null, "77", "+3: conditional operator (incl 2 for nesting)"), - new CxxReportLocation(null, "79", "+1: else statement"), - new CxxReportLocation(null, "80", "+2: if statement (incl 1 for nesting)"), - new CxxReportLocation(null, "81", "+3: conditional operator (incl 2 for nesting)"), - new CxxReportLocation(null, "82", "+1: else statement"), - new CxxReportLocation(null, "83", "+3: conditional operator (incl 2 for nesting)")); + new CxxReportLocation(null, "72", "The Cognitive Complexity of this function is 20 which is greater than 5 authorized."), + new CxxReportLocation(null, "73", "+1: if statement"), + new CxxReportLocation(null, "74", "+2: if statement (incl 1 for nesting)"), + new CxxReportLocation(null, "75", "+3: conditional operator (incl 2 for nesting)"), + new CxxReportLocation(null, "76", "+1: else statement"), + new CxxReportLocation(null, "77", "+3: conditional operator (incl 2 for nesting)"), + new CxxReportLocation(null, "79", "+1: else statement"), + new CxxReportLocation(null, "80", "+2: if statement (incl 1 for nesting)"), + new CxxReportLocation(null, "81", "+3: conditional operator (incl 2 for nesting)"), + new CxxReportLocation(null, "82", "+1: else statement"), + new CxxReportLocation(null, "83", "+3: conditional operator (incl 2 for nesting)")); CxxReportIssue issue4 = issues.stream().filter(issue -> issue.getLocations().get(0).getLine().equals("89")) - .findFirst().orElseThrow(() -> new AssertionError("No issue at line 89")); + .findFirst().orElseThrow(() -> new AssertionError("No issue at line 89")); softly.assertThat(issue4.getLocations()).containsOnly( - new CxxReportLocation(null, "89", "The Cognitive Complexity of this function is 18 which is greater than 5 authorized."), - new CxxReportLocation(null, "91", "+1: if statement"), - new CxxReportLocation(null, "91", "+1: logical operator"), - new CxxReportLocation(null, "91", "+1: logical operator"), - new CxxReportLocation(null, "94", "+1: catch-clause"), - new CxxReportLocation(null, "96", "+1: catch-clause"), - new CxxReportLocation(null, "98", "+1: catch-clause"), - new CxxReportLocation(null, "100", "+1: catch-clause"), - new CxxReportLocation(null, "102", "+1: catch-clause"), - new CxxReportLocation(null, "104", "+1: catch-clause"), - new CxxReportLocation(null, "106", "+1: catch-clause"), - new CxxReportLocation(null, "107", "+2: iteration statement (incl 1 for nesting)"), - new CxxReportLocation(null, "108", "+3: conditional operator (incl 2 for nesting)"), - new CxxReportLocation(null, "110", "+2: conditional operator (incl 1 for nesting)"), - new CxxReportLocation(null, "113", "+1: switch statement")); + new CxxReportLocation(null, "89", "The Cognitive Complexity of this function is 18 which is greater than 5 authorized."), + new CxxReportLocation(null, "91", "+1: if statement"), + new CxxReportLocation(null, "91", "+1: logical operator"), + new CxxReportLocation(null, "91", "+1: logical operator"), + new CxxReportLocation(null, "94", "+1: catch-clause"), + new CxxReportLocation(null, "96", "+1: catch-clause"), + new CxxReportLocation(null, "98", "+1: catch-clause"), + new CxxReportLocation(null, "100", "+1: catch-clause"), + new CxxReportLocation(null, "102", "+1: catch-clause"), + new CxxReportLocation(null, "104", "+1: catch-clause"), + new CxxReportLocation(null, "106", "+1: catch-clause"), + new CxxReportLocation(null, "107", "+2: iteration statement (incl 1 for nesting)"), + new CxxReportLocation(null, "108", "+3: conditional operator (incl 2 for nesting)"), + new CxxReportLocation(null, "110", "+2: conditional operator (incl 1 for nesting)"), + new CxxReportLocation(null, "113", "+1: switch statement")); softly.assertAll(); } diff --git a/cxx-checks/src/test/java/org/sonar/cxx/checks/metrics/FunctionComplexityCheckTest.java b/cxx-checks/src/test/java/org/sonar/cxx/checks/metrics/FunctionComplexityCheckTest.java index 541400b411..6ff0725c8a 100644 --- a/cxx-checks/src/test/java/org/sonar/cxx/checks/metrics/FunctionComplexityCheckTest.java +++ b/cxx-checks/src/test/java/org/sonar/cxx/checks/metrics/FunctionComplexityCheckTest.java @@ -19,12 +19,10 @@ */ package org.sonar.cxx.checks.metrics; -import static org.assertj.core.api.Assertions.assertThat; - import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.Set; - +import static org.assertj.core.api.Assertions.assertThat; import org.assertj.core.api.SoftAssertions; import org.junit.Test; import org.sonar.cxx.CxxAstScanner; @@ -51,80 +49,80 @@ public void check() throws UnsupportedEncodingException, IOException { softly.assertThat(issues).allSatisfy(issue -> "FunctionComplexity".equals(issue.getRuleId())); CxxReportIssue issue0 = issues.stream().filter(issue -> issue.getLocations().get(0).getLine().equals("13")) - .findFirst().orElseThrow(() -> new AssertionError("No issue at line 13")); + .findFirst().orElseThrow(() -> new AssertionError("No issue at line 13")); softly.assertThat(issue0.getLocations()).containsOnly( - new CxxReportLocation(null, "13", - "The Cyclomatic Complexity of this function is 8 which is greater than 5 authorized."), - new CxxReportLocation(null, "13", "+1: function definition"), - new CxxReportLocation(null, "14", "+1: if statement"), - new CxxReportLocation(null, "15", "+1: if statement"), - new CxxReportLocation(null, "16", "+1: conditional operator"), - new CxxReportLocation(null, "18", "+1: conditional operator"), - new CxxReportLocation(null, "21", "+1: if statement"), - new CxxReportLocation(null, "22", "+1: conditional operator"), - new CxxReportLocation(null, "24", "+1: conditional operator")); + new CxxReportLocation(null, "13", + "The Cyclomatic Complexity of this function is 8 which is greater than 5 authorized."), + new CxxReportLocation(null, "13", "+1: function definition"), + new CxxReportLocation(null, "14", "+1: if statement"), + new CxxReportLocation(null, "15", "+1: if statement"), + new CxxReportLocation(null, "16", "+1: conditional operator"), + new CxxReportLocation(null, "18", "+1: conditional operator"), + new CxxReportLocation(null, "21", "+1: if statement"), + new CxxReportLocation(null, "22", "+1: conditional operator"), + new CxxReportLocation(null, "24", "+1: conditional operator")); CxxReportIssue issue1 = issues.stream().filter(issue -> issue.getLocations().get(0).getLine().equals("33")) - .findFirst().orElseThrow(() -> new AssertionError("No issue at line 33")); + .findFirst().orElseThrow(() -> new AssertionError("No issue at line 33")); softly.assertThat(issue1.getLocations()).containsOnly( - new CxxReportLocation(null, "33", - "The Cyclomatic Complexity of this function is 8 which is greater than 5 authorized."), - new CxxReportLocation(null, "33", "+1: function definition"), - new CxxReportLocation(null, "34", "+1: if statement"), - new CxxReportLocation(null, "35", "+1: if statement"), - new CxxReportLocation(null, "36", "+1: conditional operator"), - new CxxReportLocation(null, "38", "+1: conditional operator"), - new CxxReportLocation(null, "41", "+1: if statement"), - new CxxReportLocation(null, "42", "+1: conditional operator"), - new CxxReportLocation(null, "44", "+1: conditional operator")); + new CxxReportLocation(null, "33", + "The Cyclomatic Complexity of this function is 8 which is greater than 5 authorized."), + new CxxReportLocation(null, "33", "+1: function definition"), + new CxxReportLocation(null, "34", "+1: if statement"), + new CxxReportLocation(null, "35", "+1: if statement"), + new CxxReportLocation(null, "36", "+1: conditional operator"), + new CxxReportLocation(null, "38", "+1: conditional operator"), + new CxxReportLocation(null, "41", "+1: if statement"), + new CxxReportLocation(null, "42", "+1: conditional operator"), + new CxxReportLocation(null, "44", "+1: conditional operator")); CxxReportIssue issue2 = issues.stream().filter(issue -> issue.getLocations().get(0).getLine().equals("51")) - .findFirst().orElseThrow(() -> new AssertionError("No issue at line 51")); + .findFirst().orElseThrow(() -> new AssertionError("No issue at line 51")); softly.assertThat(issue2.getLocations()).containsOnly( - new CxxReportLocation(null, "51", - "The Cyclomatic Complexity of this function is 8 which is greater than 5 authorized."), - new CxxReportLocation(null, "51", "+1: function definition"), - new CxxReportLocation(null, "52", "+1: if statement"), - new CxxReportLocation(null, "53", "+1: if statement"), - new CxxReportLocation(null, "54", "+1: conditional operator"), - new CxxReportLocation(null, "56", "+1: conditional operator"), - new CxxReportLocation(null, "59", "+1: if statement"), - new CxxReportLocation(null, "60", "+1: conditional operator"), - new CxxReportLocation(null, "62", "+1: conditional operator")); + new CxxReportLocation(null, "51", + "The Cyclomatic Complexity of this function is 8 which is greater than 5 authorized."), + new CxxReportLocation(null, "51", "+1: function definition"), + new CxxReportLocation(null, "52", "+1: if statement"), + new CxxReportLocation(null, "53", "+1: if statement"), + new CxxReportLocation(null, "54", "+1: conditional operator"), + new CxxReportLocation(null, "56", "+1: conditional operator"), + new CxxReportLocation(null, "59", "+1: if statement"), + new CxxReportLocation(null, "60", "+1: conditional operator"), + new CxxReportLocation(null, "62", "+1: conditional operator")); CxxReportIssue issue3 = issues.stream().filter(issue -> issue.getLocations().get(0).getLine().equals("72")) - .findFirst().orElseThrow(() -> new AssertionError("No issue at line 72")); + .findFirst().orElseThrow(() -> new AssertionError("No issue at line 72")); softly.assertThat(issue3.getLocations()).containsOnly( - new CxxReportLocation(null, "72", - "The Cyclomatic Complexity of this function is 8 which is greater than 5 authorized."), - new CxxReportLocation(null, "72", "+1: function definition"), - new CxxReportLocation(null, "73", "+1: if statement"), - new CxxReportLocation(null, "74", "+1: if statement"), - new CxxReportLocation(null, "75", "+1: conditional operator"), - new CxxReportLocation(null, "77", "+1: conditional operator"), - new CxxReportLocation(null, "80", "+1: if statement"), - new CxxReportLocation(null, "81", "+1: conditional operator"), - new CxxReportLocation(null, "83", "+1: conditional operator")); + new CxxReportLocation(null, "72", + "The Cyclomatic Complexity of this function is 8 which is greater than 5 authorized."), + new CxxReportLocation(null, "72", "+1: function definition"), + new CxxReportLocation(null, "73", "+1: if statement"), + new CxxReportLocation(null, "74", "+1: if statement"), + new CxxReportLocation(null, "75", "+1: conditional operator"), + new CxxReportLocation(null, "77", "+1: conditional operator"), + new CxxReportLocation(null, "80", "+1: if statement"), + new CxxReportLocation(null, "81", "+1: conditional operator"), + new CxxReportLocation(null, "83", "+1: conditional operator")); CxxReportIssue issue4 = issues.stream().filter(issue -> issue.getLocations().get(0).getLine().equals("89")) - .findFirst().orElseThrow(() -> new AssertionError("No issue at line 89")); + .findFirst().orElseThrow(() -> new AssertionError("No issue at line 89")); softly.assertThat(issue4.getLocations()).containsOnly( - new CxxReportLocation(null, "89", - "The Cyclomatic Complexity of this function is 14 which is greater than 5 authorized."), - new CxxReportLocation(null, "89", "+1: function definition"), - new CxxReportLocation(null, "91", "+1: if statement"), - new CxxReportLocation(null, "91", "+1: logical operator"), - new CxxReportLocation(null, "91", "+1: logical operator"), - new CxxReportLocation(null, "94", "+1: catch-clause"), - new CxxReportLocation(null, "96", "+1: catch-clause"), - new CxxReportLocation(null, "98", "+1: catch-clause"), - new CxxReportLocation(null, "100", "+1: catch-clause"), - new CxxReportLocation(null, "102", "+1: catch-clause"), - new CxxReportLocation(null, "104", "+1: catch-clause"), - new CxxReportLocation(null, "106", "+1: catch-clause"), - new CxxReportLocation(null, "107", "+1: while loop"), - new CxxReportLocation(null, "108", "+1: conditional operator"), - new CxxReportLocation(null, "110", "+1: conditional operator")); + new CxxReportLocation(null, "89", + "The Cyclomatic Complexity of this function is 14 which is greater than 5 authorized."), + new CxxReportLocation(null, "89", "+1: function definition"), + new CxxReportLocation(null, "91", "+1: if statement"), + new CxxReportLocation(null, "91", "+1: logical operator"), + new CxxReportLocation(null, "91", "+1: logical operator"), + new CxxReportLocation(null, "94", "+1: catch-clause"), + new CxxReportLocation(null, "96", "+1: catch-clause"), + new CxxReportLocation(null, "98", "+1: catch-clause"), + new CxxReportLocation(null, "100", "+1: catch-clause"), + new CxxReportLocation(null, "102", "+1: catch-clause"), + new CxxReportLocation(null, "104", "+1: catch-clause"), + new CxxReportLocation(null, "106", "+1: catch-clause"), + new CxxReportLocation(null, "107", "+1: while loop"), + new CxxReportLocation(null, "108", "+1: conditional operator"), + new CxxReportLocation(null, "110", "+1: conditional operator")); softly.assertAll(); } diff --git a/cxx-checks/src/test/java/org/sonar/cxx/checks/metrics/TooManyLinesOfCodeInFunctionCheckTest.java b/cxx-checks/src/test/java/org/sonar/cxx/checks/metrics/TooManyLinesOfCodeInFunctionCheckTest.java index 44551e10f9..54b91e1dd6 100644 --- a/cxx-checks/src/test/java/org/sonar/cxx/checks/metrics/TooManyLinesOfCodeInFunctionCheckTest.java +++ b/cxx-checks/src/test/java/org/sonar/cxx/checks/metrics/TooManyLinesOfCodeInFunctionCheckTest.java @@ -19,14 +19,14 @@ */ package org.sonar.cxx.checks.metrics; -import org.sonar.squidbridge.checks.CheckMessagesVerifier; +import java.io.IOException; +import java.io.UnsupportedEncodingException; import org.junit.Test; import org.sonar.cxx.CxxAstScanner; import org.sonar.cxx.checks.CxxFileTester; import org.sonar.cxx.checks.CxxFileTesterHelper; import org.sonar.squidbridge.api.SourceFile; -import java.io.IOException; -import java.io.UnsupportedEncodingException; +import org.sonar.squidbridge.checks.CheckMessagesVerifier; public class TooManyLinesOfCodeInFunctionCheckTest { diff --git a/cxx-checks/src/test/java/org/sonar/cxx/checks/metrics/TooManyParametersCheckTest.java b/cxx-checks/src/test/java/org/sonar/cxx/checks/metrics/TooManyParametersCheckTest.java index d3ac5afbda..0404182eb5 100644 --- a/cxx-checks/src/test/java/org/sonar/cxx/checks/metrics/TooManyParametersCheckTest.java +++ b/cxx-checks/src/test/java/org/sonar/cxx/checks/metrics/TooManyParametersCheckTest.java @@ -19,6 +19,8 @@ */ package org.sonar.cxx.checks.metrics; +import java.io.IOException; +import java.io.UnsupportedEncodingException; import org.junit.Test; import org.sonar.cxx.CxxAstScanner; import org.sonar.cxx.checks.CxxFileTester; @@ -26,9 +28,6 @@ import org.sonar.squidbridge.api.SourceFile; import org.sonar.squidbridge.checks.CheckMessagesVerifier; -import java.io.IOException; -import java.io.UnsupportedEncodingException; - public class TooManyParametersCheckTest { @Test diff --git a/cxx-checks/src/test/java/org/sonar/cxx/checks/metrics/TooManyStatementsPerLineCheckTest.java b/cxx-checks/src/test/java/org/sonar/cxx/checks/metrics/TooManyStatementsPerLineCheckTest.java index 73f4978328..a07fd5e52b 100644 --- a/cxx-checks/src/test/java/org/sonar/cxx/checks/metrics/TooManyStatementsPerLineCheckTest.java +++ b/cxx-checks/src/test/java/org/sonar/cxx/checks/metrics/TooManyStatementsPerLineCheckTest.java @@ -22,7 +22,6 @@ import java.io.IOException; import java.io.UnsupportedEncodingException; import static org.assertj.core.api.Assertions.assertThat; - import org.junit.Test; import org.sonar.cxx.CxxAstScanner; import org.sonar.cxx.checks.CxxFileTester; diff --git a/cxx-checks/src/test/java/org/sonar/cxx/checks/naming/ClassNameCheckTest.java b/cxx-checks/src/test/java/org/sonar/cxx/checks/naming/ClassNameCheckTest.java index 023d18563b..4578388cf5 100644 --- a/cxx-checks/src/test/java/org/sonar/cxx/checks/naming/ClassNameCheckTest.java +++ b/cxx-checks/src/test/java/org/sonar/cxx/checks/naming/ClassNameCheckTest.java @@ -20,12 +20,11 @@ package org.sonar.cxx.checks.naming; import org.junit.Test; -import org.sonar.squidbridge.api.SourceFile; -import org.sonar.squidbridge.checks.CheckMessagesVerifier; import org.sonar.cxx.CxxAstScanner; - import org.sonar.cxx.checks.CxxFileTester; import org.sonar.cxx.checks.CxxFileTesterHelper; +import org.sonar.squidbridge.api.SourceFile; +import org.sonar.squidbridge.checks.CheckMessagesVerifier; public class ClassNameCheckTest { diff --git a/cxx-checks/src/test/java/org/sonar/cxx/checks/naming/FileNameCheckTest.java b/cxx-checks/src/test/java/org/sonar/cxx/checks/naming/FileNameCheckTest.java index 98918ff122..7a63acc021 100644 --- a/cxx-checks/src/test/java/org/sonar/cxx/checks/naming/FileNameCheckTest.java +++ b/cxx-checks/src/test/java/org/sonar/cxx/checks/naming/FileNameCheckTest.java @@ -19,16 +19,15 @@ */ package org.sonar.cxx.checks.naming; +import java.io.IOException; +import java.io.UnsupportedEncodingException; import org.junit.Rule; import org.junit.Test; -import org.sonar.squidbridge.api.SourceFile; -import org.sonar.squidbridge.checks.CheckMessagesVerifierRule; import org.sonar.cxx.CxxAstScanner; - -import java.io.IOException; -import java.io.UnsupportedEncodingException; import org.sonar.cxx.checks.CxxFileTester; import org.sonar.cxx.checks.CxxFileTesterHelper; +import org.sonar.squidbridge.api.SourceFile; +import org.sonar.squidbridge.checks.CheckMessagesVerifierRule; public class FileNameCheckTest { diff --git a/cxx-checks/src/test/java/org/sonar/cxx/checks/naming/FunctionNameCheckTest.java b/cxx-checks/src/test/java/org/sonar/cxx/checks/naming/FunctionNameCheckTest.java index 5ed73a76d9..ba587fc3cf 100644 --- a/cxx-checks/src/test/java/org/sonar/cxx/checks/naming/FunctionNameCheckTest.java +++ b/cxx-checks/src/test/java/org/sonar/cxx/checks/naming/FunctionNameCheckTest.java @@ -20,12 +20,11 @@ package org.sonar.cxx.checks.naming; import org.junit.Test; -import org.sonar.squidbridge.api.SourceFile; -import org.sonar.squidbridge.checks.CheckMessagesVerifier; import org.sonar.cxx.CxxAstScanner; - import org.sonar.cxx.checks.CxxFileTester; import org.sonar.cxx.checks.CxxFileTesterHelper; +import org.sonar.squidbridge.api.SourceFile; +import org.sonar.squidbridge.checks.CheckMessagesVerifier; public class FunctionNameCheckTest { diff --git a/cxx-checks/src/test/java/org/sonar/cxx/checks/naming/MethodNameCheckTest.java b/cxx-checks/src/test/java/org/sonar/cxx/checks/naming/MethodNameCheckTest.java index 41c86a5af1..fad016fc04 100644 --- a/cxx-checks/src/test/java/org/sonar/cxx/checks/naming/MethodNameCheckTest.java +++ b/cxx-checks/src/test/java/org/sonar/cxx/checks/naming/MethodNameCheckTest.java @@ -20,12 +20,11 @@ package org.sonar.cxx.checks.naming; import org.junit.Test; -import org.sonar.squidbridge.api.SourceFile; -import org.sonar.squidbridge.checks.CheckMessagesVerifier; import org.sonar.cxx.CxxAstScanner; - import org.sonar.cxx.checks.CxxFileTester; import org.sonar.cxx.checks.CxxFileTesterHelper; +import org.sonar.squidbridge.api.SourceFile; +import org.sonar.squidbridge.checks.CheckMessagesVerifier; public class MethodNameCheckTest { diff --git a/cxx-checks/src/test/java/org/sonar/cxx/checks/regex/CommentRegularExpressionCheckTest.java b/cxx-checks/src/test/java/org/sonar/cxx/checks/regex/CommentRegularExpressionCheckTest.java index 4de8ada7c8..e478a165c1 100644 --- a/cxx-checks/src/test/java/org/sonar/cxx/checks/regex/CommentRegularExpressionCheckTest.java +++ b/cxx-checks/src/test/java/org/sonar/cxx/checks/regex/CommentRegularExpressionCheckTest.java @@ -21,7 +21,6 @@ import java.io.IOException; import java.io.UnsupportedEncodingException; - import org.junit.Test; import org.sonar.cxx.CxxAstScanner; import org.sonar.cxx.checks.CxxFileTester; diff --git a/cxx-checks/src/test/java/org/sonar/cxx/checks/regex/FileHeaderCheckTest.java b/cxx-checks/src/test/java/org/sonar/cxx/checks/regex/FileHeaderCheckTest.java index 56bfcc6c9d..5d9ade2ae7 100644 --- a/cxx-checks/src/test/java/org/sonar/cxx/checks/regex/FileHeaderCheckTest.java +++ b/cxx-checks/src/test/java/org/sonar/cxx/checks/regex/FileHeaderCheckTest.java @@ -21,7 +21,6 @@ import java.io.IOException; import java.io.UnsupportedEncodingException; - import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; diff --git a/cxx-checks/src/test/java/org/sonar/cxx/checks/regex/FileRegularExpressionCheckTest.java b/cxx-checks/src/test/java/org/sonar/cxx/checks/regex/FileRegularExpressionCheckTest.java index d92d202901..2679bb0a5f 100644 --- a/cxx-checks/src/test/java/org/sonar/cxx/checks/regex/FileRegularExpressionCheckTest.java +++ b/cxx-checks/src/test/java/org/sonar/cxx/checks/regex/FileRegularExpressionCheckTest.java @@ -23,7 +23,6 @@ import java.io.UnsupportedEncodingException; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; - import org.junit.Test; import org.sonar.cxx.CxxAstScanner; import org.sonar.cxx.CxxConfiguration; diff --git a/cxx-checks/src/test/java/org/sonar/cxx/checks/regex/FixmeTagPresenceCheckTest.java b/cxx-checks/src/test/java/org/sonar/cxx/checks/regex/FixmeTagPresenceCheckTest.java index edc489fe32..36da46c1f4 100644 --- a/cxx-checks/src/test/java/org/sonar/cxx/checks/regex/FixmeTagPresenceCheckTest.java +++ b/cxx-checks/src/test/java/org/sonar/cxx/checks/regex/FixmeTagPresenceCheckTest.java @@ -21,7 +21,6 @@ import java.io.IOException; import java.io.UnsupportedEncodingException; - import org.junit.Rule; import org.junit.Test; import org.sonar.cxx.CxxAstScanner; diff --git a/cxx-checks/src/test/java/org/sonar/cxx/checks/regex/LineRegularExpressionCheckTest.java b/cxx-checks/src/test/java/org/sonar/cxx/checks/regex/LineRegularExpressionCheckTest.java index ab84fd2077..1a7ce529f6 100644 --- a/cxx-checks/src/test/java/org/sonar/cxx/checks/regex/LineRegularExpressionCheckTest.java +++ b/cxx-checks/src/test/java/org/sonar/cxx/checks/regex/LineRegularExpressionCheckTest.java @@ -21,7 +21,6 @@ import java.io.IOException; import java.io.UnsupportedEncodingException; - import org.junit.Test; import org.sonar.cxx.CxxAstScanner; import org.sonar.cxx.checks.CxxFileTester; diff --git a/cxx-checks/src/test/java/org/sonar/cxx/checks/regex/NoSonarCheckTest.java b/cxx-checks/src/test/java/org/sonar/cxx/checks/regex/NoSonarCheckTest.java index bcd9c3e076..176b4676c9 100644 --- a/cxx-checks/src/test/java/org/sonar/cxx/checks/regex/NoSonarCheckTest.java +++ b/cxx-checks/src/test/java/org/sonar/cxx/checks/regex/NoSonarCheckTest.java @@ -21,7 +21,6 @@ import java.io.IOException; import java.io.UnsupportedEncodingException; - import org.junit.Test; import org.sonar.cxx.CxxAstScanner; import org.sonar.cxx.checks.CxxFileTester; diff --git a/cxx-checks/src/test/java/org/sonar/cxx/checks/xpath/XPathCheckTest.java b/cxx-checks/src/test/java/org/sonar/cxx/checks/xpath/XPathCheckTest.java index 12a23b56d4..86d740e212 100644 --- a/cxx-checks/src/test/java/org/sonar/cxx/checks/xpath/XPathCheckTest.java +++ b/cxx-checks/src/test/java/org/sonar/cxx/checks/xpath/XPathCheckTest.java @@ -21,7 +21,6 @@ import java.io.IOException; import java.io.UnsupportedEncodingException; - import org.junit.Test; import org.sonar.cxx.CxxAstScanner; import org.sonar.cxx.checks.CxxFileTester; diff --git a/cxx-checks/src/test/java/org/sonar/cxx/tag/TagTest.java b/cxx-checks/src/test/java/org/sonar/cxx/tag/TagTest.java index f8b0407c51..32816fcbc1 100644 --- a/cxx-checks/src/test/java/org/sonar/cxx/tag/TagTest.java +++ b/cxx-checks/src/test/java/org/sonar/cxx/tag/TagTest.java @@ -19,11 +19,9 @@ */ package org.sonar.cxx.tag; -import org.junit.Test; - import java.lang.reflect.Constructor; - import static org.assertj.core.api.Assertions.assertThat; +import org.junit.Test; public class TagTest { diff --git a/cxx-lint/src/main/java/org/sonar/cxx/cxxlint/CxxCheckList.java b/cxx-lint/src/main/java/org/sonar/cxx/cxxlint/CxxCheckList.java index 797f821962..2cbe46e030 100644 --- a/cxx-lint/src/main/java/org/sonar/cxx/cxxlint/CxxCheckList.java +++ b/cxx-lint/src/main/java/org/sonar/cxx/cxxlint/CxxCheckList.java @@ -29,9 +29,6 @@ public final class CxxCheckList { public static final String DEFAULT_PROFILE = "Sonar way"; - private CxxCheckList() { - } - public static List getChecks() { return new ArrayList<>(Arrays.asList( org.sonar.cxx.checks.BooleanEqualityComparisonCheck.class, @@ -82,4 +79,7 @@ public static List getChecks() { )); } + private CxxCheckList() { + } + } diff --git a/cxx-lint/src/main/java/org/sonar/cxx/cxxlint/CxxLint.java b/cxx-lint/src/main/java/org/sonar/cxx/cxxlint/CxxLint.java index c0e96d7da9..fddac8bdc1 100644 --- a/cxx-lint/src/main/java/org/sonar/cxx/cxxlint/CxxLint.java +++ b/cxx-lint/src/main/java/org/sonar/cxx/cxxlint/CxxLint.java @@ -26,7 +26,6 @@ import java.beans.Statement; import java.io.File; import java.io.IOException; -import java.io.UnsupportedEncodingException; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.lang.reflect.Proxy; @@ -43,7 +42,6 @@ import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; - import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.DefaultParser; @@ -138,7 +136,6 @@ public static void main(String[] args) { return; } - try { File parent = targetFile.getParentFile(); SensorContextTester sensorContext = SensorContextTester.create(parent.toPath()); @@ -236,7 +233,7 @@ public static void main(String[] args) { LOG.info("LOC: {}", file.getInt(CxxMetric.LINES_OF_CODE)); LOG.info("COMPLEXITY: {}", file.getInt(CxxMetric.COMPLEXITY)); - } catch (InstantiationException | IllegalAccessException |NullPointerException ex) { + } catch (InstantiationException | IllegalAccessException | NullPointerException ex) { LOG.error("{}", ex); } diff --git a/cxx-lint/src/main/java/org/sonar/cxx/cxxlint/package-info.java b/cxx-lint/src/main/java/org/sonar/cxx/cxxlint/package-info.java index 28d7e275f9..0a03ab25d7 100644 --- a/cxx-lint/src/main/java/org/sonar/cxx/cxxlint/package-info.java +++ b/cxx-lint/src/main/java/org/sonar/cxx/cxxlint/package-info.java @@ -17,7 +17,6 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - /** * Package with sensor to evaluate Cppcheck specific report files. */ diff --git a/cxx-lint/src/test/java/org/codehaus/sonarplugins/cxx/cxxlint/CxxLintTest.java b/cxx-lint/src/test/java/org/codehaus/sonarplugins/cxx/cxxlint/CxxLintTest.java index f2d8f0d555..859bc1fb59 100644 --- a/cxx-lint/src/test/java/org/codehaus/sonarplugins/cxx/cxxlint/CxxLintTest.java +++ b/cxx-lint/src/test/java/org/codehaus/sonarplugins/cxx/cxxlint/CxxLintTest.java @@ -21,7 +21,6 @@ import java.io.File; import static org.assertj.core.api.Assertions.assertThatCode; - import org.junit.Test; import org.sonar.cxx.cxxlint.CxxLint; diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/clangsa/CxxClangSARuleRepository.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/clangsa/CxxClangSARuleRepository.java index 0f8e1eb48c..06bdcc825d 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/clangsa/CxxClangSARuleRepository.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/clangsa/CxxClangSARuleRepository.java @@ -33,6 +33,10 @@ public class CxxClangSARuleRepository extends CxxAbstractRuleRepository { public static final String CUSTOM_RULES_KEY = "clangsa.customRules"; private static final String NAME = "Clang-SA"; + public static String getRepositoryKey(CxxLanguage lang) { + return CxxAbstractRuleRepository.getRepositoryKey(KEY, lang); + } + /** * {@inheritDoc} */ @@ -41,10 +45,6 @@ public CxxClangSARuleRepository(ServerFileSystem fileSystem, RulesDefinitionXmlL super(fileSystem, xmlRuleLoader, KEY, NAME, CUSTOM_RULES_KEY, language); } - public static String getRepositoryKey(CxxLanguage lang) { - return CxxAbstractRuleRepository.getRepositoryKey(KEY, lang); - } - @Override protected String fileName() { return "/clangsa.xml"; diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/clangsa/CxxClangSASensor.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/clangsa/CxxClangSASensor.java index ad9014c26f..2d64b47bd2 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/clangsa/CxxClangSASensor.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/clangsa/CxxClangSASensor.java @@ -19,10 +19,14 @@ */ package org.sonar.cxx.sensors.clangsa; +import com.dd.plist.NSArray; +import com.dd.plist.NSDictionary; +import com.dd.plist.NSNumber; +import com.dd.plist.NSObject; +import com.dd.plist.NSString; +import com.dd.plist.PropertyListParser; import java.io.File; - import javax.annotation.Nullable; - import org.sonar.api.batch.sensor.SensorContext; import org.sonar.api.batch.sensor.SensorDescriptor; import org.sonar.api.utils.log.Logger; @@ -32,13 +36,6 @@ import org.sonar.cxx.sensors.utils.CxxIssuesReportSensor; import org.sonar.cxx.utils.CxxReportIssue; -import com.dd.plist.NSArray; -import com.dd.plist.NSDictionary; -import com.dd.plist.NSNumber; -import com.dd.plist.NSObject; -import com.dd.plist.NSString; -import com.dd.plist.PropertyListParser; - /** * Sensor for Clang Static Analyzer. * @@ -48,6 +45,13 @@ public class CxxClangSASensor extends CxxIssuesReportSensor { private static final Logger LOG = Loggers.get(CxxClangSASensor.class); public static final String REPORT_PATH_KEY = "clangsa.reportPath"; + private static NSObject require(@Nullable NSObject object, String errorMsg) { + if (object == null) { + throw new IllegalArgumentException(errorMsg); + } + return object; + } + /** * CxxClangSASensor for Clang Static Analyzer Sensor * @@ -66,13 +70,6 @@ public void describe(SensorDescriptor descriptor) { .onlyWhenConfiguration(conf -> conf.hasKey(getReportPathKey())); } - private static NSObject require(@Nullable NSObject object, String errorMsg) { - if (object == null) { - throw new IllegalArgumentException(errorMsg); - } - return object; - } - @Override protected void processReport(final SensorContext context, File report) throws javax.xml.stream.XMLStreamException { diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/clangsa/package-info.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/clangsa/package-info.java index fbc62a7881..dc767ef279 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/clangsa/package-info.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/clangsa/package-info.java @@ -17,7 +17,6 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - /** * Package with sensor to evaluate Cppcheck specific report files. */ diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/clangtidy/CxxClangTidyRuleRepository.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/clangtidy/CxxClangTidyRuleRepository.java index 2d407b25c5..2b25e6aff1 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/clangtidy/CxxClangTidyRuleRepository.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/clangtidy/CxxClangTidyRuleRepository.java @@ -33,6 +33,10 @@ public class CxxClangTidyRuleRepository extends CxxAbstractRuleRepository { public static final String CUSTOM_RULES_KEY = "clangtidy.customRules"; private static final String NAME = "Clang-Tidy"; + public static String getRepositoryKey(CxxLanguage lang) { + return CxxAbstractRuleRepository.getRepositoryKey(KEY, lang); + } + /** * {@inheritDoc} */ @@ -41,10 +45,6 @@ public CxxClangTidyRuleRepository(ServerFileSystem fileSystem, RulesDefinitionXm super(fileSystem, xmlRuleLoader, KEY, NAME, CUSTOM_RULES_KEY, language); } - public static String getRepositoryKey(CxxLanguage lang) { - return CxxAbstractRuleRepository.getRepositoryKey(KEY, lang); - } - @Override protected String fileName() { return "/clangtidy.xml"; diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/clangtidy/CxxClangTidySensor.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/clangtidy/CxxClangTidySensor.java index 853b1613b4..d6f3f69cde 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/clangtidy/CxxClangTidySensor.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/clangtidy/CxxClangTidySensor.java @@ -24,7 +24,6 @@ import java.util.regex.MatchResult; import java.util.regex.Matcher; import java.util.regex.Pattern; - import org.sonar.api.batch.sensor.SensorContext; import org.sonar.api.batch.sensor.SensorDescriptor; import org.sonar.api.utils.log.Logger; @@ -65,7 +64,7 @@ public void describe(SensorDescriptor descriptor) { @Override protected void processReport(final SensorContext context, File report) { final String reportCharset = getContextStringProperty(context, - getLanguage().getPluginProperty(REPORT_CHARSET_DEF), DEFAULT_CHARSET_DEF); + getLanguage().getPluginProperty(REPORT_CHARSET_DEF), DEFAULT_CHARSET_DEF); LOG.debug("Parsing 'clang-tidy' report, CharSet= '{}'", reportCharset); try (Scanner scanner = new Scanner(report, reportCharset)) { diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/compiler/gcc/CxxCompilerGccRuleRepository.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/compiler/gcc/CxxCompilerGccRuleRepository.java index a56ac9895b..48a8e9a397 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/compiler/gcc/CxxCompilerGccRuleRepository.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/compiler/gcc/CxxCompilerGccRuleRepository.java @@ -33,18 +33,18 @@ public class CxxCompilerGccRuleRepository extends CxxAbstractRuleRepository { public static final String CUSTOM_RULES_KEY = "compiler-gcc.customRules"; private static final String NAME = "Compiler-GCC"; + public static String getRepositoryKey(CxxLanguage lang) { + return CxxAbstractRuleRepository.getRepositoryKey(KEY, lang); + } + /** * {@inheritDoc} */ public CxxCompilerGccRuleRepository(ServerFileSystem fileSystem, RulesDefinitionXmlLoader xmlRuleLoader, - CxxLanguage language) { + CxxLanguage language) { super(fileSystem, xmlRuleLoader, KEY, NAME, CUSTOM_RULES_KEY, language); } - public static String getRepositoryKey(CxxLanguage lang) { - return CxxAbstractRuleRepository.getRepositoryKey(KEY, lang); - } - @Override protected String fileName() { return "/compiler-gcc.xml"; diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/compiler/gcc/package-info.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/compiler/gcc/package-info.java index 87263aca18..521964ab66 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/compiler/gcc/package-info.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/compiler/gcc/package-info.java @@ -17,7 +17,6 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - /** * Package with sensor to evaluate GCC compiler specific report files. */ diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/compiler/package-info.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/compiler/package-info.java index 2e0954d895..18bfa1a05f 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/compiler/package-info.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/compiler/package-info.java @@ -17,7 +17,6 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - /** * Package with base class for sensors to evaluate compiler specific report files. */ diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/compiler/vc/CxxCompilerVcRuleRepository.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/compiler/vc/CxxCompilerVcRuleRepository.java index 2d8de1b4b1..8f6d9558b5 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/compiler/vc/CxxCompilerVcRuleRepository.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/compiler/vc/CxxCompilerVcRuleRepository.java @@ -33,6 +33,10 @@ public class CxxCompilerVcRuleRepository extends CxxAbstractRuleRepository { public static final String CUSTOM_RULES_KEY = "compiler-vc.customRules"; private static final String NAME = "Compiler-VC"; + public static String getRepositoryKey(CxxLanguage lang) { + return CxxAbstractRuleRepository.getRepositoryKey(KEY, lang); + } + /** * {@inheritDoc} */ @@ -41,10 +45,6 @@ public CxxCompilerVcRuleRepository(ServerFileSystem fileSystem, RulesDefinitionX super(fileSystem, xmlRuleLoader, KEY, NAME, CUSTOM_RULES_KEY, language); } - public static String getRepositoryKey(CxxLanguage lang) { - return CxxAbstractRuleRepository.getRepositoryKey(KEY, lang); - } - @Override protected String fileName() { return "/compiler-vc.xml"; diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/compiler/vc/package-info.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/compiler/vc/package-info.java index 49cf0d33c0..90e7df1ef4 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/compiler/vc/package-info.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/compiler/vc/package-info.java @@ -17,7 +17,6 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - /** * Package with sensor to evaluate Microsoft Visual Studio compiler specific report files. */ diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/coverage/BullseyeParser.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/coverage/BullseyeParser.java index df9b4dd157..3f8c0d8647 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/coverage/BullseyeParser.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/coverage/BullseyeParser.java @@ -39,6 +39,29 @@ public class BullseyeParser extends CxxCoverageParser { private static final Logger LOG = Loggers.get(BullseyeParser.class); + + private static String ensureRefPathIsCorrect(@Nullable String refPath) { + if (refPath == null || refPath.isEmpty()) { + return refPath; + } + if (refPath.endsWith("\\") || refPath.endsWith("/")) { + return refPath.replace('\\', '/'); + } + return refPath.replace('\\', '/') + "/"; + } + + /** + * @param path + * @param correctPath + * @return + */ + private static String buildPath(List path, String correctPath) { + String fileName = String.join(File.separator, path); + if (!(new File(fileName)).isAbsolute()) { + fileName = correctPath + fileName; + } + return PathUtils.sanitize(fileName); + } private String prevLine; private int totalconditions; private int totalcoveredconditions; @@ -229,27 +252,4 @@ public String toString() { return getClass().getSimpleName(); } - private static String ensureRefPathIsCorrect(@Nullable String refPath) { - if (refPath == null || refPath.isEmpty()) { - return refPath; - } - if (refPath.endsWith("\\") || refPath.endsWith("/")) { - return refPath.replace('\\', '/'); - } - return refPath.replace('\\', '/') + "/"; - } - - /** - * @param path - * @param correctPath - * @return - */ - private static String buildPath(List path, String correctPath) { - String fileName = String.join(File.separator, path); - if (!(new File(fileName)).isAbsolute()) { - fileName = correctPath + fileName; - } - return PathUtils.sanitize(fileName); - } - } diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/coverage/CoberturaParser.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/coverage/CoberturaParser.java index b29829fc2a..5a36fd9fad 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/coverage/CoberturaParser.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/coverage/CoberturaParser.java @@ -39,9 +39,34 @@ public class CoberturaParser extends CxxCoverageParser { private static final Logger LOG = Loggers.get(CoberturaParser.class); - private Optional baseDir; private static final Pattern CONDITION_PATTERN = Pattern.compile("\\((.*?)\\)"); + private static void collectFileData(SMInputCursor clazz, CoverageMeasures builder) throws XMLStreamException { + SMInputCursor line = clazz.childElementCursor("lines").advance().childElementCursor("line"); + + while (line.getNext() != null) { + int lineId = Integer.parseInt(line.getAttrValue("number")); + long noHits = Long.parseLong(line.getAttrValue("hits")); + if (noHits > Integer.MAX_VALUE) { + LOG.warn("Truncating the actual number of hits ({}) to the maximum number supported by Sonar ({})", + noHits, Integer.MAX_VALUE); + noHits = Integer.MAX_VALUE; + } + builder.setHits(lineId, (int) noHits); + + String isBranch = line.getAttrValue("branch"); + String text = line.getAttrValue("condition-coverage"); + if (text != null && "true".equals(isBranch) && !text.trim().isEmpty()) { + Matcher m = CONDITION_PATTERN.matcher(text); + if (m.find()) { + String[] conditions = m.group(1).split("/"); + builder.setConditions(lineId, Integer.parseInt(conditions[1]), Integer.parseInt(conditions[0])); + } + } + } + } + private Optional baseDir; + public CoberturaParser() { // no operation but necessary for list of coverage parsers } @@ -79,7 +104,7 @@ private void readBaseDir(SMInputCursor source) throws XMLStreamException { } private void collectPackageMeasures(SMInputCursor pack, Map coverageData) - throws XMLStreamException { + throws XMLStreamException { while (pack.getNext() != null) { collectFileMeasures(pack.descendantElementCursor("class"), coverageData); } @@ -94,7 +119,7 @@ private String buildPath(String filename) { } private void collectFileMeasures(SMInputCursor clazz, Map coverageData) - throws XMLStreamException { + throws XMLStreamException { while (clazz.getNext() != null) { String normalPath = buildPath(clazz.getAttrValue("filename")); CoverageMeasures builder = coverageData.get(normalPath); @@ -106,31 +131,6 @@ private void collectFileMeasures(SMInputCursor clazz, Map Integer.MAX_VALUE) { - LOG.warn("Truncating the actual number of hits ({}) to the maximum number supported by Sonar ({})", - noHits, Integer.MAX_VALUE); - noHits = Integer.MAX_VALUE; - } - builder.setHits(lineId, (int) noHits); - - String isBranch = line.getAttrValue("branch"); - String text = line.getAttrValue("condition-coverage"); - if (text != null && "true".equals(isBranch) && !text.trim().isEmpty()) { - Matcher m = CONDITION_PATTERN.matcher(text); - if (m.find()) { - String[] conditions = m.group(1).split("/"); - builder.setConditions(lineId, Integer.parseInt(conditions[1]), Integer.parseInt(conditions[0])); - } - } - } - } - @Override public String toString() { return getClass().getSimpleName(); diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/coverage/CoverageMeasures.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/coverage/CoverageMeasures.java index f5b59af332..38151e592c 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/coverage/CoverageMeasures.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/coverage/CoverageMeasures.java @@ -31,16 +31,16 @@ * @author jocs */ public final class CoverageMeasures { + + static CoverageMeasures create() { + return new CoverageMeasures(); + } private final Map lineMeasures = new HashMap<>(); private CoverageMeasures() { // empty } - static CoverageMeasures create() { - return new CoverageMeasures(); - } - void setHits(int lineId, int hits) { lineMeasures.computeIfAbsent(lineId, v -> new CoverageMeasure(lineId)); CoverageMeasure coverageMeasure = lineMeasures.get(lineId); diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/coverage/CoverageParser.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/coverage/CoverageParser.java index c91a640060..b0f3cddb27 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/coverage/CoverageParser.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/coverage/CoverageParser.java @@ -21,33 +21,25 @@ import java.io.File; import java.util.Map; - import javax.xml.stream.XMLStreamException; /** - * The interface a coverage report parser has to implement in order to be used - * by CxxCoverageSensor + * The interface a coverage report parser has to implement in order to be used by CxxCoverageSensor */ public interface CoverageParser { /** * Parses the given report and stores the results in the according builder * - * @param context - * of sensor - * @param report - * with coverage data - * @param coverageData - * A Map mapping source file names to coverage measures. Has to be - * used to store the results into. Source file names might be - * relative. In such case they will be resolved against the base - * directory of SonarQube module/project.
+ * @param context of sensor + * @param report with coverage data + * @param coverageData A Map mapping source file names to coverage measures. Has to be used to store the results into. + * Source file names might be relative. In such case they will be resolved against the base directory of SonarQube + * module/project.
* - * ATTENTION! This map is shared between modules in - * multi-module projects. Don't try to resolve paths against some - * specific module! - * @throws XMLStreamException - * javax.xml.stream.XMLStreamException + * ATTENTION! This map is shared between modules in multi-module projects. Don't try to resolve paths against + * some specific module! + * @throws XMLStreamException javax.xml.stream.XMLStreamException */ void processReport(File report, Map coverageData) throws XMLStreamException; } diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/coverage/CxxCoverageSensor.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/coverage/CxxCoverageSensor.java index 4dac6c5f17..ce1e49eec0 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/coverage/CxxCoverageSensor.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/coverage/CxxCoverageSensor.java @@ -26,9 +26,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; - import javax.xml.stream.XMLStreamException; - import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.sensor.SensorContext; import org.sonar.api.batch.sensor.SensorDescriptor; @@ -52,6 +50,30 @@ public class CxxCoverageSensor extends CxxReportSensor { // Configuration properties before SQ 6.2 public static final String REPORT_PATH_KEY = "coverage.reportPath"; + /** + * @param parser + * @param context + * @param report + * @param measuresTotal + * @return true if report was parsed and results are available otherwise false + */ + private static void parseCoverageReport(CoverageParser parser, File report, + Map measuresTotal) { + Map measuresForReport = new HashMap<>(); + try { + parser.processReport(report, measuresForReport); + } catch (XMLStreamException e) { + throw new EmptyReportException("Coverage report" + report + "cannot be parsed by" + parser, e); + } + + if (measuresForReport.isEmpty()) { + throw new EmptyReportException("Coverage report " + report + " result is empty (parsed by " + parser + ")"); + } + + measuresTotal.putAll(measuresForReport); + LOG.info("Added coverage report '{}' (parsed by: {})", report, parser); + } + private final List parsers = new LinkedList<>(); private final CxxCoverageCache cache; @@ -103,7 +125,7 @@ public void execute(SensorContext context) { } private Map processReports(List reports, - Map> cacheCov) { + Map> cacheCov) { Map measuresTotal = new HashMap<>(); for (File report : reports) { @@ -135,30 +157,6 @@ private Map processReports(List reports, return measuresTotal; } - /** - * @param parser - * @param context - * @param report - * @param measuresTotal - * @return true if report was parsed and results are available otherwise false - */ - private static void parseCoverageReport(CoverageParser parser, File report, - Map measuresTotal) { - Map measuresForReport = new HashMap<>(); - try { - parser.processReport(report, measuresForReport); - } catch (XMLStreamException e) { - throw new EmptyReportException("Coverage report" + report + "cannot be parsed by" + parser, e); - } - - if (measuresForReport.isEmpty()) { - throw new EmptyReportException("Coverage report " + report + " result is empty (parsed by " + parser + ")"); - } - - measuresTotal.putAll(measuresForReport); - LOG.info("Added coverage report '{}' (parsed by: {})", report, parser); - } - private void saveMeasures(SensorContext context, Map coverageMeasures) { for (Map.Entry entry : coverageMeasures.entrySet()) { @@ -210,8 +208,8 @@ private void checkCoverage(NewCoverage newCoverage, CoverageMeasure measure) { newCoverage.lineHits(measure.getLine(), measure.getHits()); newCoverage.conditions(measure.getLine(), measure.getConditions(), measure.getCoveredConditions()); if (LOG.isDebugEnabled()) { - LOG.debug("line '{}' Hits '{}' Conditions '{}:{}'",measure.getLine(), measure.getHits(), - measure.getConditions(), measure.getCoveredConditions() ); + LOG.debug("line '{}' Hits '{}' Conditions '{}:{}'", measure.getLine(), measure.getHits(), + measure.getConditions(), measure.getCoveredConditions()); } } catch (RuntimeException ex) { LOG.error("Cannot save Conditions Hits for Line '{}' , ignoring measure. ", diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/coverage/TestwellCtcTxtParser.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/coverage/TestwellCtcTxtParser.java index 320e83fb45..8a9d1e0257 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/coverage/TestwellCtcTxtParser.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/coverage/TestwellCtcTxtParser.java @@ -24,19 +24,14 @@ import java.io.File; import java.io.FileNotFoundException; - -import java.util.NoSuchElementException; +import java.math.BigDecimal; import java.util.Map; +import java.util.NoSuchElementException; import java.util.Scanner; import java.util.regex.Matcher; - -import java.math.BigDecimal; - import org.apache.commons.io.FilenameUtils; - import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; - import static org.sonar.cxx.sensors.coverage.TestwellCtcTxtResult.FILE_HEADER; import static org.sonar.cxx.sensors.coverage.TestwellCtcTxtResult.FILE_RESULT; import static org.sonar.cxx.sensors.coverage.TestwellCtcTxtResult.LINE_RESULT; @@ -49,12 +44,11 @@ public class TestwellCtcTxtParser extends CxxCoverageParser { private static final Logger LOG = Loggers.get(TestwellCtcTxtParser.class); - private Scanner scanner; - private static final int FROM_START = 0; private static final int CONDS_FALSE = 1; private static final int CONDS_TRUE = 2; private static final int LINE_NR_GROUP = 3; + private Scanner scanner; public TestwellCtcTxtParser() { // no operation but necessary for list of coverage parsers diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/coverage/VisualStudioParser.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/coverage/VisualStudioParser.java index 4863d15f09..3404a28fcd 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/coverage/VisualStudioParser.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/coverage/VisualStudioParser.java @@ -35,24 +35,6 @@ public class VisualStudioParser extends CxxCoverageParser { private static final Logger LOG = Loggers.get(VisualStudioParser.class); - public VisualStudioParser() { - // no operation but necessary for list of coverage parsers - } - - /** - * {@inheritDoc} - */ - @Override - public void processReport(File report, final Map coverageData) - throws XMLStreamException { - LOG.debug("Parsing 'Visual Studio' format"); - StaxParser parser = new StaxParser((SMHierarchicCursor rootCursor) -> { - rootCursor.advance(); - collectModuleMeasures(rootCursor.descendantElementCursor("module"), coverageData); - }); - parser.parse(report); - } - private static void collectModuleMeasures(SMInputCursor module, Map coverageData) throws XMLStreamException { while (module.getNext() != null) { @@ -122,6 +104,24 @@ private static void collectRangeMeasures(SMInputCursor function, Map coverageData) + throws XMLStreamException { + LOG.debug("Parsing 'Visual Studio' format"); + StaxParser parser = new StaxParser((SMHierarchicCursor rootCursor) -> { + rootCursor.advance(); + collectModuleMeasures(rootCursor.descendantElementCursor("module"), coverageData); + }); + parser.parse(report); + } + @Override public String toString() { return getClass().getSimpleName(); diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/coverage/package-info.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/coverage/package-info.java index 87c1af50a1..e83240227f 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/coverage/package-info.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/coverage/package-info.java @@ -17,7 +17,6 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - /** * Package with sensor to evaluate coverage tool specific report files. */ diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/cppcheck/CppcheckParserV2.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/cppcheck/CppcheckParserV2.java index 3189e465c2..66255bedb5 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/cppcheck/CppcheckParserV2.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/cppcheck/CppcheckParserV2.java @@ -21,10 +21,8 @@ import java.io.File; import java.nio.file.Paths; - import javax.annotation.Nullable; import javax.xml.stream.XMLStreamException; - import org.codehaus.staxmate.in.SMHierarchicCursor; import org.codehaus.staxmate.in.SMInputCursor; import org.sonar.api.batch.sensor.SensorContext; @@ -41,11 +39,6 @@ public class CppcheckParserV2 implements CppcheckParser { private static final Logger LOG = Loggers.get(CppcheckParserV2.class); - private final CxxCppCheckSensor sensor; - - public CppcheckParserV2(CxxCppCheckSensor sensor) { - this.sensor = sensor; - } private static String requireAttributeSet(@Nullable String attributeValue, String errorMsg) { if (attributeValue == null || attributeValue.isEmpty()) { @@ -60,6 +53,11 @@ private static String createIssueText(String msg, boolean isInconclusive) { } return msg; } + private final CxxCppCheckSensor sensor; + + public CppcheckParserV2(CxxCppCheckSensor sensor) { + this.sensor = sensor; + } /** * {@inheritDoc} @@ -106,9 +104,9 @@ public void stream(SMHierarchicCursor rootCursor) throws XMLStreamException { private void processErrorTag(final SensorContext context, SMInputCursor errorCursor) throws XMLStreamException { String id = requireAttributeSet(errorCursor.getAttrValue("id"), - "Missing mandatory attribute /results/errors/error[@id]"); + "Missing mandatory attribute /results/errors/error[@id]"); String msg = requireAttributeSet(errorCursor.getAttrValue("msg"), - "Missing mandatory attribute /results/errors/error[@msg]"); + "Missing mandatory attribute /results/errors/error[@msg]"); boolean isInconclusive = "true".equals(errorCursor.getAttrValue("inconclusive")); String issueText = createIssueText(msg, isInconclusive); CxxReportIssue issue = null; @@ -161,7 +159,7 @@ private void processErrorTag(final SensorContext context, SMInputCursor errorCur StringBuilder extendedInfo = new StringBuilder(); extendedInfo.append(makeRelativePath(file, primaryFile)).append(":").append(line).append(" ") - .append(info); + .append(info); issue.addLocation(primaryFile, primaryLine, extendedInfo.toString()); } } diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/cppcheck/CxxCppCheckRuleRepository.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/cppcheck/CxxCppCheckRuleRepository.java index 134e00f8dc..e2c29dcff3 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/cppcheck/CxxCppCheckRuleRepository.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/cppcheck/CxxCppCheckRuleRepository.java @@ -33,18 +33,18 @@ public class CxxCppCheckRuleRepository extends CxxAbstractRuleRepository { public static final String CUSTOM_RULES_KEY = "cppcheck.customRules"; private static final String NAME = "Cppcheck"; + public static String getRepositoryKey(CxxLanguage lang) { + return CxxAbstractRuleRepository.getRepositoryKey(KEY, lang); + } + /** * {@inheritDoc} */ public CxxCppCheckRuleRepository(ServerFileSystem fileSystem, RulesDefinitionXmlLoader xmlRuleLoader, - CxxLanguage language) { + CxxLanguage language) { super(fileSystem, xmlRuleLoader, KEY, NAME, CUSTOM_RULES_KEY, language); } - public static String getRepositoryKey(CxxLanguage lang) { - return CxxAbstractRuleRepository.getRepositoryKey(KEY, lang); - } - @Override protected String fileName() { return "/cppcheck.xml"; diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/cppcheck/CxxCppCheckSensor.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/cppcheck/CxxCppCheckSensor.java index ce5854d9ca..c83eaf5dc5 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/cppcheck/CxxCppCheckSensor.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/cppcheck/CxxCppCheckSensor.java @@ -22,9 +22,7 @@ import java.io.File; import java.util.LinkedList; import java.util.List; - import javax.xml.stream.XMLStreamException; - import org.sonar.api.batch.sensor.SensorContext; import org.sonar.api.batch.sensor.SensorDescriptor; import org.sonar.api.utils.log.Logger; diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/cppcheck/package-info.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/cppcheck/package-info.java index d5bc2ac576..a51e34c837 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/cppcheck/package-info.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/cppcheck/package-info.java @@ -17,7 +17,6 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - /** * Package with sensor to evaluate Cppcheck specific report files. */ diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/drmemory/CxxDrMemoryRuleRepository.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/drmemory/CxxDrMemoryRuleRepository.java index a797a44ebc..84a5605ea7 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/drmemory/CxxDrMemoryRuleRepository.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/drmemory/CxxDrMemoryRuleRepository.java @@ -33,18 +33,18 @@ public class CxxDrMemoryRuleRepository extends CxxAbstractRuleRepository { public static final String CUSTOM_RULES_KEY = "drmemory.customRules"; private static final String NAME = "Dr Memory"; + public static String getRepositoryKey(CxxLanguage lang) { + return CxxAbstractRuleRepository.getRepositoryKey(KEY, lang); + } + /** * {@inheritDoc} */ public CxxDrMemoryRuleRepository(ServerFileSystem fileSystem, RulesDefinitionXmlLoader xmlRuleLoader, - CxxLanguage language) { + CxxLanguage language) { super(fileSystem, xmlRuleLoader, KEY, NAME, CUSTOM_RULES_KEY, language); } - public static String getRepositoryKey(CxxLanguage lang) { - return CxxAbstractRuleRepository.getRepositoryKey(KEY, lang); - } - @Override protected String fileName() { return "/drmemory.xml"; diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/drmemory/CxxDrMemorySensor.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/drmemory/CxxDrMemorySensor.java index e8befe6e00..21a857046b 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/drmemory/CxxDrMemorySensor.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/drmemory/CxxDrMemorySensor.java @@ -21,7 +21,6 @@ import java.io.File; import java.nio.charset.StandardCharsets; - import org.sonar.api.batch.sensor.SensorContext; import org.sonar.api.batch.sensor.SensorDescriptor; import org.sonar.api.utils.log.Logger; @@ -47,6 +46,12 @@ public class CxxDrMemorySensor extends CxxIssuesReportSensor { public static final String REPORT_PATH_KEY = "drmemory.reportPath"; private static final String DEFAULT_CHARSET_DEF = StandardCharsets.UTF_8.name(); + private static String getFrameText(Location frame, int frameNr) { + StringBuilder sb = new StringBuilder(); + sb.append("#").append(frameNr).append(" ").append(frame.getFile()).append(":").append(frame.getLine()); + return sb.toString(); + } + /** * CxxDrMemorySensor for Doctor Memory Sensor * @@ -78,12 +83,6 @@ private Location getLastOwnFrame(SensorContext context, DrMemoryError error) { return null; } - private static String getFrameText(Location frame, int frameNr) { - StringBuilder sb = new StringBuilder(); - sb.append("#").append(frameNr).append(" ").append(frame.getFile()).append(":").append(frame.getLine()); - return sb.toString(); - } - @Override protected void processReport(final SensorContext context, File report) { LOG.debug("Parsing 'Dr Memory' format"); @@ -91,7 +90,7 @@ protected void processReport(final SensorContext context, File report) { for (DrMemoryError error : DrMemoryParser.parse(report, DEFAULT_CHARSET_DEF)) { if (error.getStackTrace().isEmpty()) { CxxReportIssue moduleIssue = new CxxReportIssue(error.getType().getId(), null, - null, error.getMessage()); + null, error.getMessage()); saveUniqueViolation(context, moduleIssue); } else { Location lastOwnFrame = getLastOwnFrame(context, error); @@ -100,7 +99,7 @@ protected void processReport(final SensorContext context, File report) { continue; } CxxReportIssue fileIssue = new CxxReportIssue(error.getType().getId(), - lastOwnFrame.getFile(), lastOwnFrame.getLine().toString(), error.getMessage()); + lastOwnFrame.getFile(), lastOwnFrame.getLine().toString(), error.getMessage()); // add all frames as secondary locations int frameNr = 0; diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/drmemory/DrMemoryParser.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/drmemory/DrMemoryParser.java index 85150dc9f1..374d95031d 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/drmemory/DrMemoryParser.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/drmemory/DrMemoryParser.java @@ -41,100 +41,6 @@ public final class DrMemoryParser { public static final Pattern RX_FILE_FINDER = Pattern.compile("^.*\\[(.*):(\\d+)\\]$"); public static final int TOP_COUNT = 4; - /** - * DrMemory supported error types - * - */ - public enum DrMemoryErrorType { - UNADRESSABLE_ACCESS("UnadressableAccess", "UNADDRESSABLE ACCESS"), - UNINITIALIZE_READ("UninitializedRead", "UNINITIALIZED READ"), - INVALID_HEAP_ARGUMENT("InvalidHeapArgument", "INVALID HEAP ARGUMENT"), - GDI_USAGE_ERROR("GdiUsageError", "GDI Usage Error"), - HANDLE_LEAK("HandleLeak", "HANDLE LEAK"), - WARNING("DrMemoryWarning", "WARNING"), - POSSIBLE_LEAK("PossibleMemoryLeak", "POSSIBLE LEAK"), - LEAK("MemoryLeak", "LEAK"), - UNRECOGNIZED("Dr Memory unrecognized error", ""); - - private final String id; - private final String title; - - DrMemoryErrorType(String id, String title) { - this.id = id; - this.title = title; - } - - public String getId() { - return id; - } - - public String getTitle() { - return title; - } - } - - public static class DrMemoryError { - - public static class Location { - - private String file = ""; - private Integer line = 0; - - public String getFile() { - return file; - } - - public void setFile(String file) { - this.file = file; - } - - public Integer getLine() { - return line; - } - - public void setLine(Integer line) { - this.line = line; - } - - @Override - public String toString() { - return "Location [file=" + file + ", line=" + line + "]"; - } - } - - private DrMemoryErrorType type = DrMemoryErrorType.UNRECOGNIZED; - private final List stackTrace = new ArrayList<>(); - private String message = ""; - - public DrMemoryErrorType getType() { - return type; - } - - public void setType(DrMemoryErrorType type) { - this.type = type; - } - - public List getStackTrace() { - return Collections.unmodifiableList(stackTrace); - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - @Override - public String toString() { - return "DrMemoryError [type=" + type + ", stackTrace=" + stackTrace + ", message=" + message + "]"; - } - } - - private DrMemoryParser() { - } - /** * DrMemory parser * @@ -230,4 +136,98 @@ public static List getElements(File file, String charset) { } return list; } + + private DrMemoryParser() { + } + + public static class DrMemoryError { + + public static class Location { + + private String file = ""; + private Integer line = 0; + + public String getFile() { + return file; + } + + public void setFile(String file) { + this.file = file; + } + + public Integer getLine() { + return line; + } + + public void setLine(Integer line) { + this.line = line; + } + + @Override + public String toString() { + return "Location [file=" + file + ", line=" + line + "]"; + } + } + + private DrMemoryErrorType type = DrMemoryErrorType.UNRECOGNIZED; + private final List stackTrace = new ArrayList<>(); + private String message = ""; + + public DrMemoryErrorType getType() { + return type; + } + + public void setType(DrMemoryErrorType type) { + this.type = type; + } + + public List getStackTrace() { + return Collections.unmodifiableList(stackTrace); + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + @Override + public String toString() { + return "DrMemoryError [type=" + type + ", stackTrace=" + stackTrace + ", message=" + message + "]"; + } + } + + /** + * DrMemory supported error types + * + */ + public enum DrMemoryErrorType { + UNADRESSABLE_ACCESS("UnadressableAccess", "UNADDRESSABLE ACCESS"), + UNINITIALIZE_READ("UninitializedRead", "UNINITIALIZED READ"), + INVALID_HEAP_ARGUMENT("InvalidHeapArgument", "INVALID HEAP ARGUMENT"), + GDI_USAGE_ERROR("GdiUsageError", "GDI Usage Error"), + HANDLE_LEAK("HandleLeak", "HANDLE LEAK"), + WARNING("DrMemoryWarning", "WARNING"), + POSSIBLE_LEAK("PossibleMemoryLeak", "POSSIBLE LEAK"), + LEAK("MemoryLeak", "LEAK"), + UNRECOGNIZED("Dr Memory unrecognized error", ""); + + private final String id; + private final String title; + + DrMemoryErrorType(String id, String title) { + this.id = id; + this.title = title; + } + + public String getId() { + return id; + } + + public String getTitle() { + return title; + } + } } diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/drmemory/package-info.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/drmemory/package-info.java index 630a4c7e95..72b414d2ab 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/drmemory/package-info.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/drmemory/package-info.java @@ -17,7 +17,6 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - /** * Package with sensor to evaluate Dr Memrory specific results files. */ diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/other/CxxOtherRepository.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/other/CxxOtherRepository.java index e011a15d91..2d8c5c9213 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/other/CxxOtherRepository.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/other/CxxOtherRepository.java @@ -35,12 +35,17 @@ public class CxxOtherRepository implements RulesDefinition { private static final Logger LOG = Loggers.get(CxxOtherRepository.class); private static final String KEY = "other"; public static final String RULES_KEY = "other.rules"; - private final RulesDefinitionXmlLoader xmlRuleLoader; private static final String NAME = "Other"; + + public static String getRepositoryKey(CxxLanguage lang) { + return CxxAbstractRuleRepository.getRepositoryKey(KEY, lang); + } + private final RulesDefinitionXmlLoader xmlRuleLoader; private final CxxLanguage language; /** * CxxOtherRepository + * * @param xmlRuleLoader to load rules from XML file * @param language for C or C++ */ @@ -49,14 +54,10 @@ public CxxOtherRepository(RulesDefinitionXmlLoader xmlRuleLoader, CxxLanguage la this.language = language; } - public static String getRepositoryKey(CxxLanguage lang) { - return CxxAbstractRuleRepository.getRepositoryKey(KEY, lang); - } - @Override public void define(Context context) { NewRepository repository = context.createRepository(getRepositoryKey(language), this.language.getKey()) - .setName(NAME); + .setName(NAME); xmlRuleLoader.load(repository, getClass().getResourceAsStream("/external-rule.xml"), "UTF-8"); for (String ruleDefs : this.language.getStringArrayOption(RULES_KEY)) { diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/other/CxxOtherSensor.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/other/CxxOtherSensor.java index 245de524c5..b354de685e 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/other/CxxOtherSensor.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/other/CxxOtherSensor.java @@ -25,12 +25,10 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; - import javax.annotation.Nullable; import javax.xml.stream.XMLStreamException; import javax.xml.transform.TransformerException; import javax.xml.transform.stream.StreamSource; - import org.codehaus.staxmate.in.SMHierarchicCursor; import org.codehaus.staxmate.in.SMInputCursor; import org.sonar.api.batch.sensor.SensorContext; @@ -59,6 +57,59 @@ public class CxxOtherSensor extends CxxIssuesReportSensor { public static final String INPUT_KEY = ".inputs"; public static final String OUTPUT_KEY = ".outputs"; + private static boolean checkInput(String inputKey, String outputKey, @Nullable List inputs, + @Nullable List outputs) { + return isValidInput(inputKey, inputs) && isValidOutput(outputKey, outputs) && hasCorrectSize(inputs, outputs); + } + + /** + * @param inputs + * @param outputs + * @return + */ + private static boolean hasCorrectSize(List inputs, List outputs) { + if (inputs.size() != outputs.size()) { + LOG.error("Number of source XML files is not equal to the the number of output files."); + return false; + } + return true; + } + + /** + * @param outputKey + * @param outputs + * @return + */ + private static boolean isValidOutput(@Nullable String outputKey, @Nullable List outputs) { + if ((outputKey == null) || (outputs == null) || (outputs.isEmpty())) { + if (outputKey != null) { + LOG.error(outputKey + " file is not defined."); + } else { + LOG.error("outputKey is not defined."); + } + return false; + } + return true; + } + + /** + * @param inputKey + * @param inputs + */ + private static boolean isValidInput(@Nullable String inputKey, @Nullable List inputs) { + + if ((inputKey == null) || (inputs == null) || (inputs.isEmpty())) { + if (inputKey != null) { + LOG.error(inputKey + " file is not defined."); + } else { + LOG.error("inputKey is not defined."); + } + return false; + } + + return true; + } + /** * CxxOtherSensor for Other Sensor * @@ -147,59 +198,6 @@ public void transformFiles(final File baseDir, SensorContext context) { } } - private static boolean checkInput(String inputKey, String outputKey, @Nullable List inputs, - @Nullable List outputs) { - return isValidInput(inputKey, inputs) && isValidOutput(outputKey, outputs) && hasCorrectSize(inputs, outputs); - } - - /** - * @param inputs - * @param outputs - * @return - */ - private static boolean hasCorrectSize(List inputs, List outputs) { - if (inputs.size() != outputs.size()) { - LOG.error("Number of source XML files is not equal to the the number of output files."); - return false; - } - return true; - } - - /** - * @param outputKey - * @param outputs - * @return - */ - private static boolean isValidOutput(@Nullable String outputKey, @Nullable List outputs) { - if ((outputKey == null) || (outputs == null) || (outputs.isEmpty())) { - if (outputKey != null) { - LOG.error(outputKey + " file is not defined."); - } else { - LOG.error("outputKey is not defined."); - } - return false; - } - return true; - } - - /** - * @param inputKey - * @param inputs - */ - private static boolean isValidInput(@Nullable String inputKey, @Nullable List inputs) { - - if ((inputKey == null) || (inputs == null) || (inputs.isEmpty())) { - if (inputKey != null) { - LOG.error(inputKey + " file is not defined."); - } else { - LOG.error("inputKey is not defined."); - } - return false; - } - - return true; - } - private void transformFileList(final String baseDir, String stylesheet, List inputs, List outputs) { for (int j = 0; j < inputs.size(); j++) { try { diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/other/package-info.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/other/package-info.java index 3a44f726ea..a3540075e7 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/other/package-info.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/other/package-info.java @@ -17,7 +17,6 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - /** * Package with sensor to evaluate XML report files (other). */ diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/pclint/CxxPCLintRuleRepository.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/pclint/CxxPCLintRuleRepository.java index a3e368154f..7a9a564c6e 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/pclint/CxxPCLintRuleRepository.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/pclint/CxxPCLintRuleRepository.java @@ -33,18 +33,18 @@ public class CxxPCLintRuleRepository extends CxxAbstractRuleRepository { public static final String CUSTOM_RULES_KEY = "pclint.customRules"; private static final String NAME = "PC-lint"; + public static String getRepositoryKey(CxxLanguage lang) { + return CxxAbstractRuleRepository.getRepositoryKey(KEY, lang); + } + /** * {@inheritDoc} */ public CxxPCLintRuleRepository(ServerFileSystem fileSystem, RulesDefinitionXmlLoader xmlRuleLoader, - CxxLanguage language) { + CxxLanguage language) { super(fileSystem, xmlRuleLoader, KEY, NAME, CUSTOM_RULES_KEY, language); } - public static String getRepositoryKey(CxxLanguage lang) { - return CxxAbstractRuleRepository.getRepositoryKey(KEY, lang); - } - @Override protected String fileName() { return "/pclint.xml"; diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/pclint/CxxPCLintSensor.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/pclint/CxxPCLintSensor.java index 5a97149ea2..76311d6c35 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/pclint/CxxPCLintSensor.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/pclint/CxxPCLintSensor.java @@ -22,10 +22,8 @@ import java.io.File; import java.util.regex.Matcher; import java.util.regex.Pattern; - import javax.annotation.Nullable; import javax.xml.stream.XMLStreamException; - import org.codehaus.staxmate.in.SMHierarchicCursor; import org.codehaus.staxmate.in.SMInputCursor; import org.sonar.api.batch.sensor.SensorContext; @@ -52,8 +50,8 @@ public class CxxPCLintSensor extends CxxIssuesReportSensor { private static final Logger LOG = Loggers.get(CxxPCLintSensor.class); public static final String REPORT_PATH_KEY = "pclint.reportPath"; public static final Pattern MISRA_RULE_PATTERN = Pattern.compile( - // Rule nn.nn -or- Rule nn-nn-nn - "Rule\\x20(\\d{1,2}.\\d{1,2}|\\d{1,2}-\\d{1,2}-\\d{1,2})(,|\\])"); + // Rule nn.nn -or- Rule nn-nn-nn + "Rule\\x20(\\d{1,2}.\\d{1,2}|\\d{1,2}-\\d{1,2}-\\d{1,2})(,|\\])"); /** * CxxPCLintSensor for PC-lint Sensor diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/pclint/package-info.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/pclint/package-info.java index 1e9a1642ec..6c0711c247 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/pclint/package-info.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/pclint/package-info.java @@ -17,7 +17,6 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - /** * Package with sensor to evaluate PC-Lint specific report files. */ diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/rats/CxxRatsRuleRepository.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/rats/CxxRatsRuleRepository.java index 55dbcc0b55..a4339e84b8 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/rats/CxxRatsRuleRepository.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/rats/CxxRatsRuleRepository.java @@ -33,18 +33,18 @@ public class CxxRatsRuleRepository extends CxxAbstractRuleRepository { public static final String CUSTOM_RULES_KEY = "rats.customRules"; private static final String NAME = "RATS"; + public static String getRepositoryKey(CxxLanguage lang) { + return CxxAbstractRuleRepository.getRepositoryKey(KEY, lang); + } + /** * {@inheritDoc} */ public CxxRatsRuleRepository(ServerFileSystem fileSystem, RulesDefinitionXmlLoader xmlRuleLoader, - CxxLanguage language) { + CxxLanguage language) { super(fileSystem, xmlRuleLoader, KEY, NAME, CUSTOM_RULES_KEY, language); } - public static String getRepositoryKey(CxxLanguage lang) { - return CxxAbstractRuleRepository.getRepositoryKey(KEY, lang); - } - @Override protected String fileName() { return "/rats.xml"; diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/rats/CxxRatsSensor.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/rats/CxxRatsSensor.java index a3744d8044..e3186d60ab 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/rats/CxxRatsSensor.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/rats/CxxRatsSensor.java @@ -21,9 +21,7 @@ import java.io.File; import java.util.List; - import javax.annotation.Nullable; - import org.jdom2.Element; import org.jdom2.input.SAXBuilder; import org.jdom2.input.sax.XMLReaders; @@ -46,6 +44,13 @@ public class CxxRatsSensor extends CxxIssuesReportSensor { private static final String MISSING_RATS_TYPE = "fixed size global buffer"; public static final String REPORT_PATH_KEY = "rats.reportPath"; + private static String getVulnerabilityType(@Nullable Element child) { + if (child != null) { + return child.getTextTrim(); + } + return MISSING_RATS_TYPE; + } + /** * CxxRatsSensor for RATS Sensor * @@ -97,13 +102,6 @@ protected void processReport(final SensorContext context, File report) } } - private static String getVulnerabilityType(@Nullable Element child) { - if (child != null) { - return child.getTextTrim(); - } - return MISSING_RATS_TYPE; - } - @Override protected CxxMetricsFactory.Key getMetricKey() { return CxxMetricsFactory.Key.RATS_SENSOR_ISSUES_KEY; diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/rats/package-info.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/rats/package-info.java index 186dda88bb..257d8e9a2d 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/rats/package-info.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/rats/package-info.java @@ -17,7 +17,6 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - /** * Package with sensor to evaluate RATS specific report files. */ diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/squid/CxxChecks.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/squid/CxxChecks.java index a01f49ae0c..402d79ae43 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/squid/CxxChecks.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/squid/CxxChecks.java @@ -34,6 +34,10 @@ public final class CxxChecks { + public static CxxChecks createCxxCheck(CheckFactory checkFactory) { + return new CxxChecks(checkFactory); + } + private final CheckFactory checkFactory; private final Set>> checksByRepository = new HashSet<>(); @@ -41,10 +45,6 @@ private CxxChecks(CheckFactory checkFactory) { this.checkFactory = checkFactory; } - public static CxxChecks createCxxCheck(CheckFactory checkFactory) { - return new CxxChecks(checkFactory); - } - @SuppressWarnings("rawtypes") public CxxChecks addChecks(String repositoryKey, Iterable checkClass) { checksByRepository.add(checkFactory diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/squid/package-info.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/squid/package-info.java index 4f35e732b9..1b34090fbe 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/squid/package-info.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/squid/package-info.java @@ -17,7 +17,6 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - /** * Package with Squid sensor and Squid based functionality. */ diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/CxxUnitTestResultsAggregator.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/CxxUnitTestResultsAggregator.java index 9e0ebd596c..a77d6788f4 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/CxxUnitTestResultsAggregator.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/CxxUnitTestResultsAggregator.java @@ -23,9 +23,7 @@ // SonarQube .NET Tests Library // Copyright (C) 2014-2017 SonarSource SA // mailto:info AT sonarsource DOT com - import java.io.File; - import org.sonar.api.batch.ScannerSide; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; @@ -37,12 +35,25 @@ public class CxxUnitTestResultsAggregator { private static final Logger LOG = Loggers.get(CxxUnitTestResultsAggregator.class); + + private static void aggregate(WildcardPatternFileProvider wildcardPatternFileProvider, String[] reportPaths, + UnitTestResultsParser parser, UnitTestResults unitTestResults) { + for (String reportPathPattern : reportPaths) { + LOG.info("Report path pattern: '{}'", reportPathPattern); + if (!reportPathPattern.isEmpty()) { + for (File reportFile : wildcardPatternFileProvider.listFiles(reportPathPattern)) { + parser.accept(reportFile, unitTestResults); + } + } + } + } private final VisualStudioTestResultsFileParser visualStudioTestResultsFileParser; private final XUnitTestResultsFileParser xunitTestResultsFileParser; private final NUnitTestResultsFileParser nunitTestResultsFileParser; /** * CxxUnitTestResultsAggregator + * * @param language C or C++ * @param settings SQ Configuration */ @@ -51,41 +62,30 @@ public CxxUnitTestResultsAggregator() { } CxxUnitTestResultsAggregator(VisualStudioTestResultsFileParser visualStudioTestResultsFileParser, - XUnitTestResultsFileParser xunitTestResultsFileParser, NUnitTestResultsFileParser nunitTestResultsFileParser) { + XUnitTestResultsFileParser xunitTestResultsFileParser, NUnitTestResultsFileParser nunitTestResultsFileParser) { this.visualStudioTestResultsFileParser = visualStudioTestResultsFileParser; this.xunitTestResultsFileParser = xunitTestResultsFileParser; this.nunitTestResultsFileParser = nunitTestResultsFileParser; } UnitTestResults aggregate(WildcardPatternFileProvider wildcardPatternFileProvider, UnitTestResults unitTestResults, - UnitTestConfiguration unitTestConf) { + UnitTestConfiguration unitTestConf) { if (unitTestConf.hasVisualStudioTestResultsFile()) { aggregate(wildcardPatternFileProvider, unitTestConf.getVisualStudioTestResultsFiles(), - visualStudioTestResultsFileParser, unitTestResults); + visualStudioTestResultsFileParser, unitTestResults); } if (unitTestConf.hasXUnitTestResultsFile()) { aggregate(wildcardPatternFileProvider, unitTestConf.getXUnitTestResultsFiles(), xunitTestResultsFileParser, - unitTestResults); + unitTestResults); } if (unitTestConf.hasNUnitTestResultsFile()) { aggregate(wildcardPatternFileProvider, unitTestConf.getNUnitTestResultsFiles(), nunitTestResultsFileParser, - unitTestResults); + unitTestResults); } return unitTestResults; } - private static void aggregate(WildcardPatternFileProvider wildcardPatternFileProvider, String[] reportPaths, - UnitTestResultsParser parser, UnitTestResults unitTestResults) { - for (String reportPathPattern : reportPaths) { - LOG.info("Report path pattern: '{}'", reportPathPattern); - if (!reportPathPattern.isEmpty()) { - for (File reportFile : wildcardPatternFileProvider.listFiles(reportPathPattern)) { - parser.accept(reportFile, unitTestResults); - } - } - } - } } diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/CxxUnitTestResultsImportSensor.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/CxxUnitTestResultsImportSensor.java index 6067c71369..9971cd684a 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/CxxUnitTestResultsImportSensor.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/CxxUnitTestResultsImportSensor.java @@ -23,9 +23,7 @@ // SonarQube .NET Tests Library // Copyright (C) 2014-2017 SonarSource SA // mailto:info AT sonarsource DOT com - import java.io.File; - import org.sonar.api.batch.sensor.Sensor; import org.sonar.api.batch.sensor.SensorContext; import org.sonar.api.batch.sensor.SensorDescriptor; @@ -61,7 +59,7 @@ public void execute(SensorContext context) { void analyze(SensorContext context, UnitTestResults unitTestResults, UnitTestConfiguration unitTestConf) { UnitTestResults aggregatedResults = unitTestResultsAggregator.aggregate(wildcardPatternFileProvider, - unitTestResults, unitTestConf); + unitTestResults, unitTestConf); context.newMeasure() .forMetric(CoreMetrics.TESTS) diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/NUnitTestResultsFileParser.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/NUnitTestResultsFileParser.java index 87b355579e..88ea0a08f2 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/NUnitTestResultsFileParser.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/NUnitTestResultsFileParser.java @@ -41,6 +41,41 @@ public void accept(File file, UnitTestResults unitTestResults) { private static class Parser { + private static boolean checkRootTag(XmlParserHelper xmlParserHelper) { + try { + xmlParserHelper.checkRootTag("test-results"); + return true; + } catch (ParseErrorException e) { + LOG.warn("One of the assemblies contains no test result, please make sure this is expected."); + return false; + } + } + + @CheckForNull + private static Double readExecutionTimeFromDirectlyNestedTestSuiteTags(XmlParserHelper xmlParserHelper) { + Double executionTime = null; + + String tag; + int level = 0; + while ((tag = xmlParserHelper.nextStartOrEndTag()) != null) { + if ("".equals(tag)) { + level++; + Double time = xmlParserHelper.getDoubleAttribute("time"); + + if (level == 1 && time != null) { + if (executionTime == null) { + executionTime = 0D; + } + executionTime += time * 1000; + } + } else if ("".equals(tag)) { + level--; + } + } + + return executionTime; + } + private final File file; private final UnitTestResults unitTestResults; @@ -59,16 +94,6 @@ public void parse() { } } - private static boolean checkRootTag(XmlParserHelper xmlParserHelper) { - try { - xmlParserHelper.checkRootTag("test-results"); - return true; - } catch (ParseErrorException e) { - LOG.warn("One of the assemblies contains no test result, please make sure this is expected."); - return false; - } - } - private void handleTestResultsTag(XmlParserHelper xmlParserHelper) { int total = xmlParserHelper.getRequiredIntAttribute("total"); int errors = xmlParserHelper.getRequiredIntAttribute("errors"); @@ -86,30 +111,6 @@ private void handleTestResultsTag(XmlParserHelper xmlParserHelper) { executionTime != null ? (long) executionTime.doubleValue() : null); } - @CheckForNull - private static Double readExecutionTimeFromDirectlyNestedTestSuiteTags(XmlParserHelper xmlParserHelper) { - Double executionTime = null; - - String tag; - int level = 0; - while ((tag = xmlParserHelper.nextStartOrEndTag()) != null) { - if ("".equals(tag)) { - level++; - Double time = xmlParserHelper.getDoubleAttribute("time"); - - if (level == 1 && time != null) { - if (executionTime == null) { - executionTime = 0D; - } - executionTime += time * 1000; - } - } else if ("".equals(tag)) { - level--; - } - } - - return executionTime; - } } } diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/ParseErrorException.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/ParseErrorException.java index 1ef558e0f6..31b28be6d1 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/ParseErrorException.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/ParseErrorException.java @@ -23,7 +23,6 @@ // SonarQube .NET Tests Library // Copyright (C) 2014-2017 SonarSource SA // mailto:info AT sonarsource DOT com - public class ParseErrorException extends RuntimeException { private static final long serialVersionUID = 1L; diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/UnitTestConfiguration.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/UnitTestConfiguration.java index 15d1060a59..233524bc0c 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/UnitTestConfiguration.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/UnitTestConfiguration.java @@ -22,12 +22,6 @@ import org.sonar.api.config.Configuration; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; - -// origin https://github.com/SonarSource/sonar-dotnet-tests-library/ -// SonarQube .NET Tests Library -// Copyright (C) 2014-2017 SonarSource SA -// mailto:info AT sonarsource DOT com - import org.sonar.cxx.CxxLanguage; public class UnitTestConfiguration { diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/UnitTestResults.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/UnitTestResults.java index bf9f5db694..e66104fc4e 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/UnitTestResults.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/UnitTestResults.java @@ -23,7 +23,6 @@ // SonarQube .NET Tests Library // Copyright (C) 2014-2017 SonarSource SA // mailto:info AT sonarsource DOT com - import javax.annotation.CheckForNull; import javax.annotation.Nullable; diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/UnitTestResultsParser.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/UnitTestResultsParser.java index 40eba9a8e4..c03674b04c 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/UnitTestResultsParser.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/UnitTestResultsParser.java @@ -23,7 +23,6 @@ // SonarQube .NET Tests Library // Copyright (C) 2014-2017 SonarSource SA // mailto:info AT sonarsource DOT com - import java.io.File; import java.util.function.BiConsumer; diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/VisualStudioTestResultsFileParser.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/VisualStudioTestResultsFileParser.java index 138ea5a69f..39663c97e9 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/VisualStudioTestResultsFileParser.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/VisualStudioTestResultsFileParser.java @@ -23,7 +23,6 @@ // SonarQube .NET Tests Library // Copyright (C) 2014-2017 SonarSource SA // mailto:info AT sonarsource DOT com - import java.io.File; import java.io.IOException; import java.text.DateFormat; @@ -47,6 +46,10 @@ public void accept(File file, UnitTestResults unitTestResults) { private static class Parser { + private static void checkRootTag(XmlParserHelper xmlParserHelper) { + xmlParserHelper.checkRootTag("TestRun"); + } + private final File file; private final UnitTestResults unitTestResults; private final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"); @@ -137,10 +140,6 @@ private String keepOnlyMilliseconds(String value) { return sb.toString(); } - private static void checkRootTag(XmlParserHelper xmlParserHelper) { - xmlParserHelper.checkRootTag("TestRun"); - } - } } diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/WildcardPatternFileProvider.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/WildcardPatternFileProvider.java index 25b7ab5f99..b75fe739a2 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/WildcardPatternFileProvider.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/WildcardPatternFileProvider.java @@ -23,7 +23,6 @@ // SonarQube .NET Tests Library // Copyright (C) 2014-2017 SonarSource SA // mailto:info AT sonarsource DOT com - import java.io.File; import java.util.ArrayList; import java.util.Arrays; @@ -44,49 +43,6 @@ public class WildcardPatternFileProvider { private static final String ZERO_OR_MORE_PATTERN = "*"; private static final String ANY_PATTERN = "?"; - private final File baseDir; - private final String directorySeparator; - - public WildcardPatternFileProvider(File baseDir, String directorySeparator) { - this.baseDir = baseDir; - this.directorySeparator = directorySeparator; - } - - Set listFiles(String pattern) { - List elements = Arrays.asList(pattern.split(Pattern.quote(directorySeparator))); - - List elementsTillFirstWildcard = elementsTillFirstWildcard(elements); - String pathTillFirstWildcardElement = toPath(elementsTillFirstWildcard); - File fileTillFirstWildcardElement = new File(pathTillFirstWildcardElement); - - File absoluteFileTillFirstWildcardElement = fileTillFirstWildcardElement.isAbsolute() - ? fileTillFirstWildcardElement : new File(baseDir, pathTillFirstWildcardElement); - - List wildcardElements = elements.subList(elementsTillFirstWildcard.size(), elements.size()); - if (wildcardElements.isEmpty()) { - return absoluteFileTillFirstWildcardElement.exists() - ? new HashSet<>(Arrays.asList(absoluteFileTillFirstWildcardElement)) : Collections.emptySet(); - } - checkNoCurrentOrParentFolderAccess(wildcardElements); - - WildcardPattern wildcardPattern = WildcardPattern.create(toPath(wildcardElements), directorySeparator); - - Set result = new HashSet<>(); - for (File file : listFiles(absoluteFileTillFirstWildcardElement)) { - String relativePath = relativize(absoluteFileTillFirstWildcardElement, file); - - if (wildcardPattern.match(relativePath)) { - result.add(file); - } - } - - return result; - } - - private String toPath(List elements) { - return elements.stream().collect(Collectors.joining(directorySeparator)); - } - private static List elementsTillFirstWildcard(List elements) { List result = new ArrayList<>(); for (String element : elements) { @@ -140,5 +96,47 @@ private static void listFiles(Set result, File dir) { private static String relativize(File parent, File file) { return file.getAbsolutePath().substring(parent.getAbsolutePath().length() + 1); } + private final File baseDir; + private final String directorySeparator; + + public WildcardPatternFileProvider(File baseDir, String directorySeparator) { + this.baseDir = baseDir; + this.directorySeparator = directorySeparator; + } + + Set listFiles(String pattern) { + List elements = Arrays.asList(pattern.split(Pattern.quote(directorySeparator))); + + List elementsTillFirstWildcard = elementsTillFirstWildcard(elements); + String pathTillFirstWildcardElement = toPath(elementsTillFirstWildcard); + File fileTillFirstWildcardElement = new File(pathTillFirstWildcardElement); + + File absoluteFileTillFirstWildcardElement = fileTillFirstWildcardElement.isAbsolute() + ? fileTillFirstWildcardElement : new File(baseDir, pathTillFirstWildcardElement); + + List wildcardElements = elements.subList(elementsTillFirstWildcard.size(), elements.size()); + if (wildcardElements.isEmpty()) { + return absoluteFileTillFirstWildcardElement.exists() + ? new HashSet<>(Arrays.asList(absoluteFileTillFirstWildcardElement)) : Collections.emptySet(); + } + checkNoCurrentOrParentFolderAccess(wildcardElements); + + WildcardPattern wildcardPattern = WildcardPattern.create(toPath(wildcardElements), directorySeparator); + + Set result = new HashSet<>(); + for (File file : listFiles(absoluteFileTillFirstWildcardElement)) { + String relativePath = relativize(absoluteFileTillFirstWildcardElement, file); + + if (wildcardPattern.match(relativePath)) { + result.add(file); + } + } + + return result; + } + + private String toPath(List elements) { + return elements.stream().collect(Collectors.joining(directorySeparator)); + } } diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/XUnitTestResultsFileParser.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/XUnitTestResultsFileParser.java index 62369d494f..43bf423c3c 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/XUnitTestResultsFileParser.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/XUnitTestResultsFileParser.java @@ -23,7 +23,6 @@ // SonarQube .NET Tests Library // Copyright (C) 2014-2017 SonarSource SA // mailto:info AT sonarsource DOT com - import java.io.File; import java.io.IOException; import org.sonar.api.utils.log.Logger; diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/XmlParserHelper.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/XmlParserHelper.java index cb01156131..e31cd8bbab 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/XmlParserHelper.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/XmlParserHelper.java @@ -23,7 +23,6 @@ // SonarQube .NET Tests Library // Copyright (C) 2014-2017 SonarSource SA // mailto:info AT sonarsource DOT com - import java.io.File; import java.io.IOException; import java.io.InputStreamReader; diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/package-info.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/package-info.java index dd3e4c09ff..30fe42c6ba 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/package-info.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/package-info.java @@ -17,7 +17,6 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - /** * Package with sensor to evaluate Unit Test specific report files. */ diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/xunit/CxxXunitSensor.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/xunit/CxxXunitSensor.java index a9da93e69b..c568004c36 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/xunit/CxxXunitSensor.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/xunit/CxxXunitSensor.java @@ -24,12 +24,10 @@ import java.io.InputStream; import java.net.URL; import java.util.List; - import javax.xml.stream.XMLStreamException; import javax.xml.transform.Source; import javax.xml.transform.TransformerException; import javax.xml.transform.stream.StreamSource; - import org.sonar.api.batch.sensor.SensorContext; import org.sonar.api.batch.sensor.SensorDescriptor; import org.sonar.api.measures.CoreMetrics; @@ -56,6 +54,7 @@ public class CxxXunitSensor extends CxxReportSensor { /** * CxxXunitSensor + * * @param language for C or C++ */ public CxxXunitSensor(CxxLanguage language) { diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/xunit/TestCase.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/xunit/TestCase.java index d8440ec951..ca519b8437 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/xunit/TestCase.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/xunit/TestCase.java @@ -22,8 +22,8 @@ import org.apache.commons.lang.StringEscapeUtils; /** - * Represents a unit test case. Has a couple of data items like name, status, - * time etc. associated. Reports testcase details in sonar-conform XML + * Represents a unit test case. Has a couple of data items like name, status, time etc. associated. Reports testcase + * details in sonar-conform XML */ public class TestCase { @@ -48,15 +48,12 @@ public class TestCase { * @params name The name of this testcase * @params time The execution time in milliseconds * @params status The execution status of the testcase - * @params stack The stack trace occurred while executing of this testcase; - * pass "" if the testcase passed/skipped. - * @params msg The error message accosiated with this testcase of the - * execution was errouneous; pass "" if not. + * @params stack The stack trace occurred while executing of this testcase; pass "" if the testcase passed/skipped. + * @params msg The error message accosiated with this testcase of the execution was errouneous; pass "" if not. * @params classname The name of the class this testcase is implemented by * @params tcFilename The path of the file which implements the testcase * @params tsName The name of the testssuite this testcase is in. - * @params tsFilename The path of the file which implements the testssuite - * this testcase is in. + * @params tsFilename The path of the file which implements the testssuite this testcase is in. */ public TestCase(String name, int time, String status, String stack, String msg, String classname, String tcFilename, String tsName, String tsFilename) { diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/xunit/TestFile.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/xunit/TestFile.java index 730f24a125..b59661cab0 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/xunit/TestFile.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/xunit/TestFile.java @@ -24,9 +24,8 @@ import org.sonar.api.batch.fs.InputFile; /** - * Represents a test file in Sonar, i.e. a source code file which implements - * tests. Holds all test cases along with all measures collected from the - * reports. + * Represents a test file in Sonar, i.e. a source code file which implements tests. Holds all test cases along with all + * measures collected from the reports. */ public class TestFile { @@ -39,8 +38,7 @@ public class TestFile { private final InputFile inputFile; /** - * Creates a test file instance which corresponds and represents the passed - * InputFile instance + * Creates a test file instance which corresponds and represents the passed InputFile instance * * @param inputFile The InputFile in SQ which this TestFile proxies */ @@ -74,8 +72,7 @@ public int getFailures() { } /** - * Adds the given test case to this test file maintaining the internal - * statistics + * Adds the given test case to this test file maintaining the internal statistics * * @param tc the test case to add */ diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/xunit/XunitReportParser.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/xunit/XunitReportParser.java index 8f091cc26c..72fa5d0ea1 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/xunit/XunitReportParser.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/xunit/XunitReportParser.java @@ -36,46 +36,6 @@ */ public class XunitReportParser implements XmlStreamHandler { - private final List testCases = new LinkedList<>(); - - /** - * Returns successfully parsed testcases. - */ - public List getTestCases() { - return new LinkedList<>(testCases); - } - - /** - * {@inheritDoc} - */ - @Override - public void stream(SMHierarchicCursor rootCursor) throws XMLStreamException { - SMInputCursor testSuiteCursor = rootCursor.constructDescendantCursor(new ElementFilter("testsuite")); - try { - while (testSuiteCursor.getNext() != null) { - parseTestSuiteTag(testSuiteCursor); - } - } catch (com.ctc.wstx.exc.WstxEOFException eofExc) { - throw new EmptyReportException("Cannot read Xunit report", eofExc); - } - } - - public void parseTestSuiteTag(SMInputCursor testSuiteCursor) - throws XMLStreamException { - String testSuiteName = testSuiteCursor.getAttrValue("name"); - String testSuiteFName = testSuiteCursor.getAttrValue("filename"); - - SMInputCursor childCursor = testSuiteCursor.childElementCursor(); - while (childCursor.getNext() != null) { - String elementName = childCursor.getLocalName(); - if ("testsuite".equals(elementName)) { - parseTestSuiteTag(childCursor); - } else if ("testcase".equals(elementName)) { - testCases.add(parseTestCaseTag(childCursor, testSuiteName, testSuiteFName)); - } - } - } - private static TestCase parseTestCaseTag(SMInputCursor testCaseCursor, String tsName, String tsFilename) throws XMLStreamException { String classname = testCaseCursor.getAttrValue("classname"); @@ -138,4 +98,45 @@ private static String parseTestCaseName(SMInputCursor testCaseCursor) throws XML } return name; } + + private final List testCases = new LinkedList<>(); + + /** + * Returns successfully parsed testcases. + */ + public List getTestCases() { + return new LinkedList<>(testCases); + } + + /** + * {@inheritDoc} + */ + @Override + public void stream(SMHierarchicCursor rootCursor) throws XMLStreamException { + SMInputCursor testSuiteCursor = rootCursor.constructDescendantCursor(new ElementFilter("testsuite")); + try { + while (testSuiteCursor.getNext() != null) { + parseTestSuiteTag(testSuiteCursor); + } + } catch (com.ctc.wstx.exc.WstxEOFException eofExc) { + throw new EmptyReportException("Cannot read Xunit report", eofExc); + } + } + + public void parseTestSuiteTag(SMInputCursor testSuiteCursor) + throws XMLStreamException { + String testSuiteName = testSuiteCursor.getAttrValue("name"); + String testSuiteFName = testSuiteCursor.getAttrValue("filename"); + + SMInputCursor childCursor = testSuiteCursor.childElementCursor(); + while (childCursor.getNext() != null) { + String elementName = childCursor.getLocalName(); + if ("testsuite".equals(elementName)) { + parseTestSuiteTag(childCursor); + } else if ("testcase".equals(elementName)) { + testCases.add(parseTestCaseTag(childCursor, testSuiteName, testSuiteFName)); + } + } + } + } diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/xunit/package-info.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/xunit/package-info.java index 0604255e5e..bd009a5592 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/xunit/package-info.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/xunit/package-info.java @@ -17,7 +17,6 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - /** * Package with sensor to evaluate Unit Test specific report files. */ diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/utils/CxxAbstractRuleRepository.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/utils/CxxAbstractRuleRepository.java index 3cc5368bed..3c5edd1bf0 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/utils/CxxAbstractRuleRepository.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/utils/CxxAbstractRuleRepository.java @@ -43,6 +43,10 @@ public abstract class CxxAbstractRuleRepository implements RulesDefinition { private static final Logger LOG = Loggers.get(CxxAbstractRuleRepository.class); + public static String getRepositoryKey(String key, CxxLanguage lang) { + return key + lang.getRepositorySuffix(); + } + private final ServerFileSystem fileSystem; private final RulesDefinitionXmlLoader xmlRuleLoader; protected final String repositoryKey; @@ -68,10 +72,6 @@ public CxxAbstractRuleRepository( this.language = language; } - public static String getRepositoryKey(String key, CxxLanguage lang) { - return key + lang.getRepositorySuffix(); - } - @Override public void define(Context context) { Charset charset = StandardCharsets.UTF_8; diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/utils/CxxIssuesReportSensor.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/utils/CxxIssuesReportSensor.java index 7111289248..9187b7b7ec 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/utils/CxxIssuesReportSensor.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/utils/CxxIssuesReportSensor.java @@ -26,9 +26,7 @@ import java.util.List; import java.util.Map; import java.util.Set; - import javax.annotation.Nullable; - import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.sensor.SensorContext; import org.sonar.api.batch.sensor.issue.NewIssue; @@ -49,6 +47,11 @@ public abstract class CxxIssuesReportSensor extends CxxReportSensor { private static final Logger LOG = Loggers.get(CxxIssuesReportSensor.class); + + private static NewIssueLocation createNewIssueLocationModule(SensorContext sensorContext, NewIssue newIssue, + CxxReportLocation location) { + return newIssue.newLocation().on(sensorContext.module()).message(location.getInfo()); + } private final Set notFoundFiles = new HashSet<>(); private final Set uniqueIssues = new HashSet<>(); private final Map violationsPerFileCount = new HashMap<>(); @@ -186,11 +189,6 @@ private NewIssueLocation createNewIssueLocationFile(SensorContext sensorContext, } } - private static NewIssueLocation createNewIssueLocationModule(SensorContext sensorContext, NewIssue newIssue, - CxxReportLocation location) { - return newIssue.newLocation().on(sensorContext.module()).message(location.getInfo()); - } - /** * Saves a code violation which is detected in the given file/line and has given ruleId and message. Saves it to the * given project and context. Project or file-level violations can be saved by passing null for the according diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/utils/CxxReportSensor.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/utils/CxxReportSensor.java index 4084643efa..5d5536a535 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/utils/CxxReportSensor.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/utils/CxxReportSensor.java @@ -19,15 +19,15 @@ */ package org.sonar.cxx.sensors.utils; +import com.google.common.base.Splitter; +import com.google.common.collect.Iterables; import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; - import javax.annotation.Nullable; - import org.apache.commons.io.FilenameUtils; import org.apache.tools.ant.DirectoryScanner; import org.sonar.api.batch.sensor.Sensor; @@ -37,35 +37,12 @@ import org.sonar.api.utils.log.Loggers; import org.sonar.cxx.CxxLanguage; -import com.google.common.base.Splitter; -import com.google.common.collect.Iterables; - /** - * This class is used as base for all sensors which import reports. It hosts - * common logic such as finding the reports. + * This class is used as base for all sensors which import reports. It hosts common logic such as finding the reports. */ public abstract class CxxReportSensor implements Sensor { private static final Logger LOG = Loggers.get(CxxReportSensor.class); - private final CxxLanguage language; - private final String propertiesKeyPathToReports; - - /** - * {@inheritDoc} - */ - protected CxxReportSensor(CxxLanguage language, String propertiesKeyPathToReports) { - this.language = language; - this.propertiesKeyPathToReports = language.getPluginProperty(propertiesKeyPathToReports); - } - - public CxxLanguage getLanguage() { - return language; - } - - public String getReportPathKey() - { - return propertiesKeyPathToReports; - } /** * Get string property from configuration. If the string is not set or empty, return the default value. @@ -83,11 +60,6 @@ public static String getContextStringProperty(SensorContext context, String name return s; } - @Override - public String toString() { - return getClass().getSimpleName(); - } - /** * resolveFilename normalizes the report full path * @@ -116,18 +88,13 @@ public static String resolveFilename(final String baseDir, @Nullable final Strin } /** - * Use the given {@link Configuration} object in order to get a list of Ant - * patterns referenced by key reportPathKey. Apply - * moduleBaseDir in order to make relative Ant patterns to - * absolute ones. Resolve Ant patterns and returns the list of existing files. + * Use the given {@link Configuration} object in order to get a list of Ant patterns referenced by key + * reportPathKey. Apply moduleBaseDir in order to make relative Ant patterns to absolute + * ones. Resolve Ant patterns and returns the list of existing files. * - * @param settings - * project (module) configuration - * @param moduleBaseDir - * project (module) base directory - * @param reportPathKey - * configuration key for the external reports (CSV list of Ant - * patterns) + * @param settings project (module) configuration + * @param moduleBaseDir project (module) base directory + * @param reportPathKey configuration key for the external reports (CSV list of Ant patterns) * @return List list of report paths */ public static List getReports(Configuration settings, final File moduleBaseDir, String reportPathKey) { @@ -149,7 +116,7 @@ public static List getReports(Configuration settings, final File moduleBas if (existingReportPaths.length == 0) { LOG.warn("Property '{}': cannot find any files matching the Ant pattern(s) '{}'", reportPathKey, - String.join(", ", normalizedReportPaths)); + String.join(", ", normalizedReportPaths)); return Collections.emptyList(); } @@ -189,5 +156,28 @@ private static List normalizeReportPaths(final File moduleBaseDir, Strin public static String[] splitProperty(String property) { return Iterables.toArray(Splitter.on(',').split(property), String.class); } + private final CxxLanguage language; + private final String propertiesKeyPathToReports; + + /** + * {@inheritDoc} + */ + protected CxxReportSensor(CxxLanguage language, String propertiesKeyPathToReports) { + this.language = language; + this.propertiesKeyPathToReports = language.getPluginProperty(propertiesKeyPathToReports); + } + + public CxxLanguage getLanguage() { + return language; + } + + public String getReportPathKey() { + return propertiesKeyPathToReports; + } + + @Override + public String toString() { + return getClass().getSimpleName(); + } } diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/utils/CxxUtils.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/utils/CxxUtils.java index 95c10f5054..3b3ecef688 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/utils/CxxUtils.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/utils/CxxUtils.java @@ -23,7 +23,6 @@ import java.util.Optional; import java.util.regex.Pattern; import javax.xml.XMLConstants; - import javax.xml.transform.OutputKeys; import javax.xml.transform.Source; import javax.xml.transform.Transformer; @@ -45,10 +44,6 @@ public final class CxxUtils { public static final Pattern EOL_PATTERN = Pattern.compile("\\R"); private static final Logger LOG = Loggers.get(CxxUtils.class); - private CxxUtils() { - // only static methods - } - /** * transformFile * @@ -90,4 +85,8 @@ public static void validateRecovery(Exception ex, CxxLanguage language) { LOG.info("Recovery is disabled, failing analysis : '{}'", ex.toString()); throw new IllegalStateException(ex.getMessage(), ex.getCause()); } + + private CxxUtils() { + // only static methods + } } diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/utils/JsonCompilationDatabase.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/utils/JsonCompilationDatabase.java index bdb92e70eb..f9c58a8e25 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/utils/JsonCompilationDatabase.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/utils/JsonCompilationDatabase.java @@ -40,8 +40,6 @@ public class JsonCompilationDatabase { private static final Logger LOG = Loggers.get(JsonCompilationDatabase.class); - private JsonCompilationDatabase() { /* utility class is not meant to be instantiated */ } - /** * Set up the given CxxConfiguration from the JSON compilation database * @@ -192,4 +190,7 @@ private static String[] tokenizeCommandLine(String cmdLine) { return args.toArray(new String[0]); } + + private JsonCompilationDatabase() { + /* utility class is not meant to be instantiated */ } } diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/utils/StaxParser.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/utils/StaxParser.java index be76980fd6..7073b65ffd 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/utils/StaxParser.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/utils/StaxParser.java @@ -154,20 +154,6 @@ public Object resolveEntity(String arg0, String arg1, String fileName, String un } } - /** - * XmlStreamHandler: Simple interface for handling XML stream to parse - */ - public interface XmlStreamHandler { - - /** - * stream: - * - * @param rootCursor - org.codehaus.staxmate.i.SMHierarchicCursor - * @exception XMLStreamException javax.xml.stream.XMLStreamException - */ - void stream(SMHierarchicCursor rootCursor) throws XMLStreamException; - } - private static class ISOControlCharAwareInputStream extends InputStream { private final InputStream inputToCheck; @@ -236,4 +222,18 @@ private static void checkBufferForISOControlChars(byte[] buffer, int off, int le } } } + + /** + * XmlStreamHandler: Simple interface for handling XML stream to parse + */ + public interface XmlStreamHandler { + + /** + * stream: + * + * @param rootCursor - org.codehaus.staxmate.i.SMHierarchicCursor + * @exception XMLStreamException javax.xml.stream.XMLStreamException + */ + void stream(SMHierarchicCursor rootCursor) throws XMLStreamException; + } } diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/utils/package-info.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/utils/package-info.java index 4972890e8b..e2014bf3ff 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/utils/package-info.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/utils/package-info.java @@ -17,7 +17,6 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - /** * Package with helpers and base classes for sensors and plug-in. */ diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/valgrind/CxxValgrindRuleRepository.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/valgrind/CxxValgrindRuleRepository.java index 49ff803607..dc990dcbdf 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/valgrind/CxxValgrindRuleRepository.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/valgrind/CxxValgrindRuleRepository.java @@ -33,18 +33,18 @@ public class CxxValgrindRuleRepository extends CxxAbstractRuleRepository { public static final String CUSTOM_RULES_KEY = "valgrind.customRules"; private static final String NAME = "Valgrind"; + public static String getRepositoryKey(CxxLanguage lang) { + return CxxAbstractRuleRepository.getRepositoryKey(KEY, lang); + } + /** * {@inheritDoc} */ public CxxValgrindRuleRepository(ServerFileSystem fileSystem, RulesDefinitionXmlLoader xmlRuleLoader, - CxxLanguage language) { + CxxLanguage language) { super(fileSystem, xmlRuleLoader, KEY, NAME, CUSTOM_RULES_KEY, language); } - public static String getRepositoryKey(CxxLanguage lang) { - return CxxAbstractRuleRepository.getRepositoryKey(KEY, lang); - } - @Override protected String fileName() { return "/valgrind.xml"; diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/valgrind/CxxValgrindSensor.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/valgrind/CxxValgrindSensor.java index a6c6e63458..ddefe61d64 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/valgrind/CxxValgrindSensor.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/valgrind/CxxValgrindSensor.java @@ -21,7 +21,6 @@ import java.io.File; import java.util.Set; - import org.sonar.api.batch.sensor.SensorContext; import org.sonar.api.batch.sensor.SensorDescriptor; import org.sonar.api.utils.log.Logger; @@ -39,6 +38,16 @@ public class CxxValgrindSensor extends CxxIssuesReportSensor { private static final Logger LOG = Loggers.get(CxxValgrindSensor.class); public static final String REPORT_PATH_KEY = "valgrind.reportPath"; + private static String createErrorMsg(ValgrindError error, ValgrindStack stack, int stackNr) { + StringBuilder errorMsg = new StringBuilder(); + errorMsg.append(error.getText()); + if (error.getStacks().size() > 1) { + errorMsg.append(" (Stack ").append(stackNr).append(")"); + } + errorMsg.append("\n\n").append(stack); + return errorMsg.toString(); + } + /** * CxxValgrindSensor for Valgrind Sensor * @@ -65,16 +74,6 @@ protected void processReport(final SensorContext context, File report) saveErrors(context, parser.processReport(report)); } - private static String createErrorMsg(ValgrindError error, ValgrindStack stack, int stackNr) { - StringBuilder errorMsg = new StringBuilder(); - errorMsg.append(error.getText()); - if (error.getStacks().size() > 1) { - errorMsg.append(" (Stack ").append(stackNr).append(")"); - } - errorMsg.append("\n\n").append(stack); - return errorMsg.toString(); - } - private Boolean frameIsInProject(SensorContext context, ValgrindFrame frame) { return frame.isLocationKnown() && (getInputFileIfInProject(context, frame.getPath()) != null); } diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/valgrind/ValgrindError.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/valgrind/ValgrindError.java index 843a72cc3c..bd5cf41ef4 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/valgrind/ValgrindError.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/valgrind/ValgrindError.java @@ -21,7 +21,6 @@ import java.util.Collections; import java.util.List; - import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/valgrind/ValgrindFrame.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/valgrind/ValgrindFrame.java index 32c40c3bba..fd584212d1 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/valgrind/ValgrindFrame.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/valgrind/ValgrindFrame.java @@ -26,8 +26,8 @@ import org.apache.commons.lang.builder.HashCodeBuilder; /** - * Represents a stack frame. Overwrites equality. Has a string serialization - * that resembles the valgrind output in textual mode. + * Represents a stack frame. Overwrites equality. Has a string serialization that resembles the valgrind output in + * textual mode. */ class ValgrindFrame { @@ -39,8 +39,8 @@ class ValgrindFrame { private final String line; /** - * Constructs a stack frame with given attributes. Its perfectly valid if some - * of them are empty or don't carry meaningful information. + * Constructs a stack frame with given attributes. Its perfectly valid if some of them are empty or don't carry + * meaningful information. */ public ValgrindFrame(@Nullable String ip, @Nullable String obj, @Nullable String fn, @Nullable String dir, @Nullable String file, @Nullable String line) { @@ -77,25 +77,25 @@ public boolean equals(Object o) { } ValgrindFrame other = (ValgrindFrame) o; return new EqualsBuilder() - .append(ip, other.ip) - .append(obj, other.obj) - .append(fn, other.fn) - .append(dir, other.dir) - .append(file, other.file) - .append(line, other.line) - .isEquals(); + .append(ip, other.ip) + .append(obj, other.obj) + .append(fn, other.fn) + .append(dir, other.dir) + .append(file, other.file) + .append(line, other.line) + .isEquals(); } @Override public int hashCode() { return new HashCodeBuilder() - .append(ip) - .append(obj) - .append(fn) - .append(dir) - .append(file) - .append(line) - .toHashCode(); + .append(ip) + .append(obj) + .append(fn) + .append(dir) + .append(file) + .append(line) + .toHashCode(); } String getPath() { diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/valgrind/ValgrindReportParser.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/valgrind/ValgrindReportParser.java index f04299c4a3..bffc8ef241 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/valgrind/ValgrindReportParser.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/valgrind/ValgrindReportParser.java @@ -24,7 +24,6 @@ import java.util.HashSet; import java.util.List; import java.util.Set; - import javax.xml.stream.XMLStreamException; import org.codehaus.staxmate.in.SMHierarchicCursor; import org.codehaus.staxmate.in.SMInputCursor; @@ -52,8 +51,6 @@ public Set processReport(File report) throws XMLStreamException { private static class ValgrindReportStreamHandler implements StaxParser.XmlStreamHandler { - private final Set valgrindErrors = new HashSet<>(); - private static ValgrindStack parseStackTag(SMInputCursor child) throws XMLStreamException { ValgrindStack stack = new ValgrindStack(); SMInputCursor frameCursor = child.childElementCursor("frame"); @@ -124,6 +121,7 @@ private static ValgrindError parseErrorTag(SMInputCursor error) throws XMLStream return new ValgrindError(kind, text, stacks); } + private final Set valgrindErrors = new HashSet<>(); /** * {@inheritDoc} diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/valgrind/ValgrindStack.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/valgrind/ValgrindStack.java index 6d0f2cb976..8760180755 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/valgrind/ValgrindStack.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/valgrind/ValgrindStack.java @@ -32,6 +32,10 @@ */ class ValgrindStack { + private static boolean isInside(String path, String folder) { + return (path == null || "".equals(path)) ? false : path.startsWith(folder); + } + private final List frames = new ArrayList<>(); /** @@ -60,8 +64,8 @@ public String toString() { @Override public int hashCode() { return new HashCodeBuilder() - .append(frames) - .toHashCode(); + .append(frames) + .toHashCode(); } @Override @@ -77,13 +81,12 @@ public boolean equals(Object obj) { } ValgrindStack other = (ValgrindStack) obj; return new EqualsBuilder() - .append(frames, other.frames) - .isEquals(); + .append(frames, other.frames) + .isEquals(); } /** - * Returns the last frame (counted from the bottom of the stack) of a function - * which is in 'our' code + * Returns the last frame (counted from the bottom of the stack) of a function which is in 'our' code * * @param basedir * @return ValgrindFrame frame or null @@ -99,8 +102,4 @@ public ValgrindFrame getLastOwnFrame(String basedir) { return null; } - private static boolean isInside(String path, String folder) { - return (path == null || "".equals(path)) ? false : path.startsWith(folder); - } - } diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/valgrind/package-info.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/valgrind/package-info.java index 20e92944e8..fd3f090cf1 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/valgrind/package-info.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/valgrind/package-info.java @@ -17,7 +17,6 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - /** * Package with sensor to evaluate Valgrind specific report files. */ diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/veraxx/CxxVeraxxRuleRepository.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/veraxx/CxxVeraxxRuleRepository.java index 9fb9269da8..11cca36f71 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/veraxx/CxxVeraxxRuleRepository.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/veraxx/CxxVeraxxRuleRepository.java @@ -33,18 +33,18 @@ public class CxxVeraxxRuleRepository extends CxxAbstractRuleRepository { public static final String CUSTOM_RULES_KEY = "vera++.customRules"; private static final String NAME = "Vera++"; + public static String getRepositoryKey(CxxLanguage lang) { + return CxxAbstractRuleRepository.getRepositoryKey(KEY, lang); + } + /** * {@inheritDoc} */ public CxxVeraxxRuleRepository(ServerFileSystem fileSystem, RulesDefinitionXmlLoader xmlRuleLoader, - CxxLanguage language) { + CxxLanguage language) { super(fileSystem, xmlRuleLoader, KEY, NAME, CUSTOM_RULES_KEY, language); } - public static String getRepositoryKey(CxxLanguage lang) { - return CxxAbstractRuleRepository.getRepositoryKey(KEY, lang); - } - @Override protected String fileName() { return "/vera++.xml"; diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/veraxx/CxxVeraxxSensor.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/veraxx/CxxVeraxxSensor.java index 37eb64495b..159f0a98c3 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/veraxx/CxxVeraxxSensor.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/veraxx/CxxVeraxxSensor.java @@ -20,7 +20,6 @@ package org.sonar.cxx.sensors.veraxx; import java.io.File; - import org.codehaus.staxmate.in.SMHierarchicCursor; import org.codehaus.staxmate.in.SMInputCursor; import org.sonar.api.batch.sensor.SensorContext; diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/veraxx/package-info.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/veraxx/package-info.java index b4384006f2..bc6c22152e 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/veraxx/package-info.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/veraxx/package-info.java @@ -17,7 +17,6 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - /** * Package with sensor to evaluate Veraxx specific report files. */ diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/visitors/CxxFileLinesVisitor.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/visitors/CxxFileLinesVisitor.java index 82bff1b684..9cf2c7dce1 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/visitors/CxxFileLinesVisitor.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/visitors/CxxFileLinesVisitor.java @@ -19,9 +19,16 @@ */ package org.sonar.cxx.sensors.visitors; +import com.google.common.collect.Sets; +import com.sonar.sslr.api.AstAndTokenVisitor; +import com.sonar.sslr.api.AstNode; +import com.sonar.sslr.api.GenericTokenType; +import com.sonar.sslr.api.Grammar; +import com.sonar.sslr.api.Token; +import com.sonar.sslr.api.TokenType; +import com.sonar.sslr.api.Trivia; import java.util.ArrayList; import java.util.List; - import org.sonar.api.batch.fs.FileSystem; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.sensor.SensorContext; @@ -37,15 +44,6 @@ import org.sonar.cxx.sensors.utils.CxxUtils; import org.sonar.squidbridge.SquidAstVisitor; -import com.google.common.collect.Sets; -import com.sonar.sslr.api.AstAndTokenVisitor; -import com.sonar.sslr.api.AstNode; -import com.sonar.sslr.api.GenericTokenType; -import com.sonar.sslr.api.Grammar; -import com.sonar.sslr.api.Token; -import com.sonar.sslr.api.TokenType; -import com.sonar.sslr.api.Trivia; - /** * Visitor that computes {@link CoreMetrics#NCLOC_DATA_KEY} and {@link CoreMetrics#COMMENT_LINES_DATA_KEY} metrics used * by the DevCockpit. @@ -54,39 +52,6 @@ public class CxxFileLinesVisitor extends SquidAstVisitor implements Ast private static final Logger LOG = Loggers.get(CxxFileLinesVisitor.class); - private final CxxLanguage language; - private final FileLinesContextFactory fileLinesContextFactory; - private final FileSystem fileSystem; - private List linesOfCode; - private List linesOfComments; - private List executableLines; - private int isWithinFunctionDefinition; - - /** - * CxxFileLinesVisitor generates sets for linesOfCode, linesOfComments, executableLines - * - * @param context for coverage analysis - * @param fileLinesContextFactory container for linesOfCode, linesOfComments, executableLines - * @param language properties - */ - public CxxFileLinesVisitor(CxxLanguage language, FileLinesContextFactory fileLinesContextFactory, - SensorContext context) { - this.language = language; - this.fileLinesContextFactory = fileLinesContextFactory; - this.fileSystem = context.fileSystem(); - } - - @Override - public void init() { - subscribeTo(CxxGrammarImpl.functionDefinition, - CxxGrammarImpl.labeledStatement, - CxxGrammarImpl.expressionStatement, - CxxGrammarImpl.iterationStatement, - CxxGrammarImpl.jumpStatement, - CxxGrammarImpl.assignmentExpression, - CxxGrammarImpl.lambdaExpression); - } - static boolean isCodeToken(Token token) { final TokenType type = token.getType(); if (!(type instanceof CxxPunctuator)) { @@ -94,17 +59,17 @@ static boolean isCodeToken(Token token) { } switch ((CxxPunctuator) type) { - case SEMICOLON: - case BR_LEFT: - case BR_RIGHT: - case CURLBR_LEFT: - case CURLBR_RIGHT: - case SQBR_LEFT: - case SQBR_RIGHT: - return false; + case SEMICOLON: + case BR_LEFT: + case BR_RIGHT: + case CURLBR_LEFT: + case CURLBR_RIGHT: + case SQBR_LEFT: + case SQBR_RIGHT: + return false; - default: - return true; + default: + return true; } } @@ -129,6 +94,57 @@ static void addLineNumber(List collection, int lineNr) { } } + private static boolean isDefaultOrDeleteFunctionBody(AstNode astNode) { + AstNode node = astNode.getFirstChild(CxxGrammarImpl.functionBody); + if ((node != null)) { + List functionBody = node.getChildren(); + + // look for exact sub AST + if ((functionBody.size() == 3) && functionBody.get(0).is(CxxPunctuator.ASSIGN) + && functionBody.get(2).is(CxxPunctuator.SEMICOLON)) { + AstNode bodyType = functionBody.get(1); + if (bodyType.is(CxxKeyword.DELETE) + || bodyType.is(CxxKeyword.DEFAULT)) { + return true; + } + } + } + return false; + } + + private final CxxLanguage language; + private final FileLinesContextFactory fileLinesContextFactory; + private final FileSystem fileSystem; + private List linesOfCode; + private List linesOfComments; + private List executableLines; + private int isWithinFunctionDefinition; + + /** + * CxxFileLinesVisitor generates sets for linesOfCode, linesOfComments, executableLines + * + * @param context for coverage analysis + * @param fileLinesContextFactory container for linesOfCode, linesOfComments, executableLines + * @param language properties + */ + public CxxFileLinesVisitor(CxxLanguage language, FileLinesContextFactory fileLinesContextFactory, + SensorContext context) { + this.language = language; + this.fileLinesContextFactory = fileLinesContextFactory; + this.fileSystem = context.fileSystem(); + } + + @Override + public void init() { + subscribeTo(CxxGrammarImpl.functionDefinition, + CxxGrammarImpl.labeledStatement, + CxxGrammarImpl.expressionStatement, + CxxGrammarImpl.iterationStatement, + CxxGrammarImpl.jumpStatement, + CxxGrammarImpl.assignmentExpression, + CxxGrammarImpl.lambdaExpression); + } + @Override public void visitToken(Token token) { if (token.getType().equals(GenericTokenType.EOF)) { @@ -196,24 +212,6 @@ private void decreaseFunctionDefinitions() { isWithinFunctionDefinition--; } - private static boolean isDefaultOrDeleteFunctionBody(AstNode astNode) { - AstNode node = astNode.getFirstChild(CxxGrammarImpl.functionBody); - if ((node != null)) { - List functionBody = node.getChildren(); - - // look for exact sub AST - if ((functionBody.size() == 3) && functionBody.get(0).is(CxxPunctuator.ASSIGN) - && functionBody.get(2).is(CxxPunctuator.SEMICOLON)) { - AstNode bodyType = functionBody.get(1); - if (bodyType.is(CxxKeyword.DELETE) - || bodyType.is(CxxKeyword.DEFAULT)) { - return true; - } - } - } - return false; - } - @Override public void visitFile(AstNode astNode) { linesOfCode = new ArrayList<>(); diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/visitors/CxxHighlighterVisitor.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/visitors/CxxHighlighterVisitor.java index 8abf1f4b31..0724078352 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/visitors/CxxHighlighterVisitor.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/visitors/CxxHighlighterVisitor.java @@ -24,7 +24,6 @@ import com.sonar.sslr.api.Grammar; import com.sonar.sslr.api.Token; import com.sonar.sslr.api.Trivia; - import java.util.Optional; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -47,77 +46,6 @@ public class CxxHighlighterVisitor extends SquidAstVisitor implements A private NewHighlighting newHighlighting; private final SensorContext context; - private static class TokenLocation { - - protected int startLine; - protected int startLineOffset; - protected int endLine; - protected int endLineOffset; - - public TokenLocation(Token token) { - startLine = token.getLine(); - startLineOffset = token.getColumn(); - endLine = this.startLine; - endLineOffset = startLineOffset + token.getValue().length(); - } - - public int startLine() { - return startLine; - } - - public int startLineOffset() { - return startLineOffset; - } - - public int endLine() { - return endLine; - } - - public int endLineOffset() { - return endLineOffset; - } - - public boolean overlaps(@Nullable TokenLocation other) { - if (other != null) { - return !(startLineOffset() > other.endLineOffset() - || other.startLineOffset() > endLineOffset() - || startLine() > other.endLine() - || other.startLine() > endLine()); - } - return false; - } - - } - - private static class CommentLocation extends TokenLocation { - - public CommentLocation(Token token) { - super(token); - String value = token.getValue(); - String[] lines = CxxUtils.EOL_PATTERN.split(value, -1); - - if (lines.length > 1) { - endLine = token.getLine() + lines.length - 1; - endLineOffset = lines[lines.length - 1].length(); - } - } - } - - private static class PreprocessorDirectiveLocation extends TokenLocation { - - public static final Pattern PREPROCESSOR_PATTERN = Pattern.compile("^[ \t]*#[ \t]*\\w+"); - - PreprocessorDirectiveLocation(Token token) { - super(token); - Matcher m = PREPROCESSOR_PATTERN.matcher(token.getValue()); - if (m.find()) { - endLineOffset = startLineOffset + (m.end() - m.start()); - } else { - endLineOffset = startLineOffset; - } - } - } - public CxxHighlighterVisitor(SensorContext context) { this.context = context; } @@ -196,4 +124,75 @@ private TokenLocation highlight(TokenLocation last, TokenLocation current, TypeO return current; } + private static class TokenLocation { + + protected int startLine; + protected int startLineOffset; + protected int endLine; + protected int endLineOffset; + + public TokenLocation(Token token) { + startLine = token.getLine(); + startLineOffset = token.getColumn(); + endLine = this.startLine; + endLineOffset = startLineOffset + token.getValue().length(); + } + + public int startLine() { + return startLine; + } + + public int startLineOffset() { + return startLineOffset; + } + + public int endLine() { + return endLine; + } + + public int endLineOffset() { + return endLineOffset; + } + + public boolean overlaps(@Nullable TokenLocation other) { + if (other != null) { + return !(startLineOffset() > other.endLineOffset() + || other.startLineOffset() > endLineOffset() + || startLine() > other.endLine() + || other.startLine() > endLine()); + } + return false; + } + + } + + private static class CommentLocation extends TokenLocation { + + public CommentLocation(Token token) { + super(token); + String value = token.getValue(); + String[] lines = CxxUtils.EOL_PATTERN.split(value, -1); + + if (lines.length > 1) { + endLine = token.getLine() + lines.length - 1; + endLineOffset = lines[lines.length - 1].length(); + } + } + } + + private static class PreprocessorDirectiveLocation extends TokenLocation { + + public static final Pattern PREPROCESSOR_PATTERN = Pattern.compile("^[ \t]*#[ \t]*\\w+"); + + PreprocessorDirectiveLocation(Token token) { + super(token); + Matcher m = PREPROCESSOR_PATTERN.matcher(token.getValue()); + if (m.find()) { + endLineOffset = startLineOffset + (m.end() - m.start()); + } else { + endLineOffset = startLineOffset; + } + } + } + } diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/visitors/package-info.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/visitors/package-info.java index a6a0e93f8b..8eaf153a69 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/visitors/package-info.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/visitors/package-info.java @@ -17,7 +17,6 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - /** * Package with visitor to define tokens used by CPD algorithm on files. */ diff --git a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/clangsa/CxxClangSASensorTest.java b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/clangsa/CxxClangSASensorTest.java index 0e27ab23e2..504feed087 100644 --- a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/clangsa/CxxClangSASensorTest.java +++ b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/clangsa/CxxClangSASensorTest.java @@ -21,7 +21,6 @@ import java.util.Optional; import static org.assertj.core.api.Assertions.assertThat; - import org.assertj.core.api.SoftAssertions; import org.junit.Before; import org.junit.Test; @@ -74,12 +73,12 @@ public void shouldReportCorrectViolations() { * 2 issues */ DefaultInputFile testFile0 = TestInputFileBuilder.create("ProjectKey", "src/lib/component0.cc").setLanguage("cpp") - .initMetadata(new String("asd\nasdas\nasda\n")).build(); + .initMetadata(new String("asd\nasdas\nasda\n")).build(); /* * 1 issue */ DefaultInputFile testFile1 = TestInputFileBuilder.create("ProjectKey", "src/lib/component1.cc").setLanguage("cpp") - .initMetadata(new String("asd\nasdas\nasda\n")).build(); + .initMetadata(new String("asd\nasdas\nasda\n")).build(); context.fileSystem().add(testFile0); context.fileSystem().add(testFile1); @@ -100,12 +99,12 @@ public void shouldReportCorrectMetrics() { * 2 issues */ DefaultInputFile testFile0 = TestInputFileBuilder.create("ProjectKey", "src/lib/component0.cc").setLanguage("cpp") - .initMetadata(new String("asd\nasdas\nasda\n")).build(); + .initMetadata(new String("asd\nasdas\nasda\n")).build(); /* * 1 issue */ DefaultInputFile testFile1 = TestInputFileBuilder.create("ProjectKey", "src/lib/component1.cc").setLanguage("cpp") - .initMetadata(new String("asd\nasdas\nasda\n")).build(); + .initMetadata(new String("asd\nasdas\nasda\n")).build(); context.fileSystem().add(testFile0); context.fileSystem().add(testFile1); @@ -117,16 +116,16 @@ public void shouldReportCorrectMetrics() { // number of ClangSA issues SoftAssertions softly = new SoftAssertions(); Measure nrOfIssuesFile0 = context.measure(testFile0.key(), - language.getMetric(CxxMetricsFactory.Key.CLANG_SA_SENSOR_ISSUES_KEY)); + language.getMetric(CxxMetricsFactory.Key.CLANG_SA_SENSOR_ISSUES_KEY)); softly.assertThat(nrOfIssuesFile0.value()).isEqualTo(2); Measure nrOfIssuesFile1 = context.measure(testFile1.key(), - language.getMetric(CxxMetricsFactory.Key.CLANG_SA_SENSOR_ISSUES_KEY)); + language.getMetric(CxxMetricsFactory.Key.CLANG_SA_SENSOR_ISSUES_KEY)); softly.assertThat(nrOfIssuesFile1.value()).isEqualTo(1); // assert that the module is annotated with the total sum of ClangSA issues Measure nrOfIssuesModule = context.measure(context.module().key(), - language.getMetric(CxxMetricsFactory.Key.CLANG_SA_SENSOR_ISSUES_KEY)); + language.getMetric(CxxMetricsFactory.Key.CLANG_SA_SENSOR_ISSUES_KEY)); softly.assertThat(nrOfIssuesModule.value()).isEqualTo(3); softly.assertAll(); } diff --git a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/clangtidy/CxxClangTidySensorTest.java b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/clangtidy/CxxClangTidySensorTest.java index 898f7a7740..0c3a809bcd 100644 --- a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/clangtidy/CxxClangTidySensorTest.java +++ b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/clangtidy/CxxClangTidySensorTest.java @@ -21,7 +21,6 @@ import java.util.Optional; import static org.assertj.core.api.Assertions.assertThat; - import org.assertj.core.api.SoftAssertions; import org.junit.Before; import org.junit.Test; diff --git a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/compiler/CxxCompilerSensorTest.java b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/compiler/CxxCompilerSensorTest.java index 6960f72586..2cd9deaa2d 100644 --- a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/compiler/CxxCompilerSensorTest.java +++ b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/compiler/CxxCompilerSensorTest.java @@ -44,6 +44,40 @@ public class CxxCompilerSensorTest { @Rule public LogTester logTester = new LogTester(); + @Before + public void setUp() { + fs = TestUtils.mockFileSystem(); + language = TestUtils.mockCxxLanguage(); + context = SensorContextTester.create(fs.baseDir()); + sensor = new CxxCompilerSensorMock(language); + } + + @Test + public void testFileNotFound() throws XMLStreamException { + File report = new File(""); + sensor.testProcessReport(context, report); + String log = logTester.logs().toString(); + assertThat(log.contains("FileNotFoundException")).isTrue(); + } + + @Test + public void testRegexInvalid() throws XMLStreamException { + File report = new File(fs.baseDir(), "compiler-reports/VC-report.vclog"); + sensor.setRegex("*"); + sensor.testProcessReport(context, report); + String log = logTester.logs().toString(); + assertThat(log.contains("PatternSyntaxException")).isTrue(); + } + + @Test + public void testRegexNamedGroupMissing() throws XMLStreamException { + File report = new File(fs.baseDir(), "compiler-reports/VC-report.vclog"); + sensor.setRegex(".*"); + sensor.testProcessReport(context, report); + String log = logTester.logs().toString(); + assertThat(log.contains("No group with name")).isTrue(); + } + private class CxxCompilerSensorMock extends CxxCompilerSensor { private String regex = ""; @@ -85,38 +119,4 @@ public void setRegex(String regex) { } } - @Before - public void setUp() { - fs = TestUtils.mockFileSystem(); - language = TestUtils.mockCxxLanguage(); - context = SensorContextTester.create(fs.baseDir()); - sensor = new CxxCompilerSensorMock(language); - } - - @Test - public void testFileNotFound() throws XMLStreamException { - File report = new File(""); - sensor.testProcessReport(context, report); - String log = logTester.logs().toString(); - assertThat(log.contains("FileNotFoundException")).isTrue(); - } - - @Test - public void testRegexInvalid() throws XMLStreamException { - File report = new File(fs.baseDir(), "compiler-reports/VC-report.vclog"); - sensor.setRegex("*"); - sensor.testProcessReport(context, report); - String log = logTester.logs().toString(); - assertThat(log.contains("PatternSyntaxException")).isTrue(); - } - - @Test - public void testRegexNamedGroupMissing() throws XMLStreamException { - File report = new File(fs.baseDir(), "compiler-reports/VC-report.vclog"); - sensor.setRegex(".*"); - sensor.testProcessReport(context, report); - String log = logTester.logs().toString(); - assertThat(log.contains("No group with name")).isTrue(); - } - } diff --git a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/coverage/CxxCoberturaSensorTest.java b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/coverage/CxxCoberturaSensorTest.java index 086f255221..0babd32dc6 100644 --- a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/coverage/CxxCoberturaSensorTest.java +++ b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/coverage/CxxCoberturaSensorTest.java @@ -25,7 +25,6 @@ import java.util.Map; import java.util.Set; import static org.assertj.core.api.Assertions.assertThat; - import org.junit.Before; import org.junit.Test; import static org.mockito.Mockito.when; @@ -124,7 +123,7 @@ public void shouldReportNoCoverageSaved() { List log = logTester.logs(); assertThat(log).contains("Property 'sonar.cxx.coverage.reportPath': cannot find any files matching the Ant pattern(s) '" - + new File(fs.baseDir(), reportPathValue).getAbsolutePath() + "'"); + + new File(fs.baseDir(), reportPathValue).getAbsolutePath() + "'"); } @Test diff --git a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/coverage/CxxMSCoverageSensorTest.java b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/coverage/CxxMSCoverageSensorTest.java index 0c4f358414..0818264ff1 100644 --- a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/coverage/CxxMSCoverageSensorTest.java +++ b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/coverage/CxxMSCoverageSensorTest.java @@ -20,11 +20,10 @@ package org.sonar.cxx.sensors.coverage; import static org.assertj.core.api.Assertions.assertThat; +import org.assertj.core.api.SoftAssertions; import org.junit.Before; import org.junit.Test; import static org.mockito.Mockito.when; - -import org.assertj.core.api.SoftAssertions; import org.sonar.api.batch.fs.internal.DefaultFileSystem; import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor; @@ -90,7 +89,7 @@ public void shouldConsumeEmptyReport() { assertThat(context.lineHits("ProjectKey:source/motorcontroller/motorcontroller.cpp", 1)).isNull(); } - + @Test public void sensorDescriptor() { DefaultSensorDescriptor descriptor = new DefaultSensorDescriptor(); @@ -98,10 +97,10 @@ public void sensorDescriptor() { sensor = new CxxCoverageSensor(new CxxCoverageCache(), language, context); sensor.describe(descriptor); - SoftAssertions softly = new SoftAssertions(); + SoftAssertions softly = new SoftAssertions(); softly.assertThat(descriptor.name()).isEqualTo(language.getName() + " CoverageSensor"); softly.assertThat(descriptor.languages()).containsOnly(language.getKey()); softly.assertAll(); } - + } diff --git a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/coverage/CxxTestwellCtcTxtParserTest.java b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/coverage/CxxTestwellCtcTxtParserTest.java index c8a79742c7..976de7aba8 100644 --- a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/coverage/CxxTestwellCtcTxtParserTest.java +++ b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/coverage/CxxTestwellCtcTxtParserTest.java @@ -23,7 +23,6 @@ import org.junit.Before; import org.junit.Test; import static org.mockito.Mockito.when; - import org.sonar.api.batch.fs.internal.DefaultFileSystem; import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.api.batch.sensor.internal.SensorContextTester; @@ -56,10 +55,10 @@ public void shouldReportCoveredLines() { .setLanguage("cpp").initMetadata("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n").build()); sensor = new CxxCoverageSensor(new CxxCoverageCache(), language, context); sensor.execute(context); - + softly.assertThat(context.lineHits("ProjectKey:HGBuildNumberLookup.cpp", 42)).isEqualTo(10); softly.assertAll(); - + } @Test @@ -72,10 +71,10 @@ public void shouldReportCoveredConditionsOne() { .setLanguage("cpp").initMetadata("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n").build()); sensor = new CxxCoverageSensor(new CxxCoverageCache(), language, context); sensor.execute(context); - + softly.assertThat(context.coveredConditions("ProjectKey:HGBuildNumberLookup.cpp", 50)).isEqualTo(1); softly.assertAll(); - + } @Test @@ -88,10 +87,10 @@ public void shouldReportCoveredConditionsTwo() { .setLanguage("cpp").initMetadata("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n").build()); sensor = new CxxCoverageSensor(new CxxCoverageCache(), language, context); sensor.execute(context); - + softly.assertThat(context.coveredConditions("ProjectKey:HGBuildNumberLookup.cpp", 56)).isEqualTo(2); softly.assertAll(); - + } @Test @@ -106,7 +105,7 @@ public void shouldConsumeLargeReportCoveredLines() { .setLanguage("cpp").initMetadata("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n").build()); sensor = new CxxCoverageSensor(new CxxCoverageCache(), language, context); sensor.execute(context); - + softly.assertThat(context.lineHits("ProjectKey:test-wildmatch.c", 3)).isEqualTo(209); softly.assertAll(); @@ -124,7 +123,7 @@ public void shouldConsumeLargeReportCoveredConditions() { .setLanguage("cpp").initMetadata("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n").build()); sensor = new CxxCoverageSensor(new CxxCoverageCache(), language, context); sensor.execute(context); - + softly.assertThat(context.coveredConditions("ProjectKey:test-wildmatch.c", 6)).isEqualTo(2); softly.assertAll(); @@ -142,7 +141,7 @@ public void shouldConsumeLargeReportConditions() { .setLanguage("cpp").initMetadata("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n").build()); sensor = new CxxCoverageSensor(new CxxCoverageCache(), language, context); sensor.execute(context); - + softly.assertThat(context.conditions("ProjectKey:credential-store.c", 78)).isEqualTo(8); softly.assertAll(); @@ -158,7 +157,7 @@ public void shouldConsumeEmptyReport() { .setLanguage("cpp").initMetadata("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n").build()); sensor = new CxxCoverageSensor(new CxxCoverageCache(), language, context); sensor.execute(context); - + softly.assertThat(context.lineHits("ProjectKey:test-wildmatch.c", 3)).isNull(); softly.assertAll(); diff --git a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/cppcheck/CxxCppCheckSensorTest.java b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/cppcheck/CxxCppCheckSensorTest.java index d6d4b08440..2022957578 100644 --- a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/cppcheck/CxxCppCheckSensorTest.java +++ b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/cppcheck/CxxCppCheckSensorTest.java @@ -21,7 +21,6 @@ import java.util.Optional; import static org.assertj.core.api.Assertions.assertThat; - import org.assertj.core.api.SoftAssertions; import org.junit.Before; import org.junit.Test; @@ -93,8 +92,7 @@ public void shouldReportProjectLevelViolationsV2() { // assert that all all issues were filed on on the module final String moduleKey = context.module().key(); - for ( Issue issue : context.allIssues() ) - { + for (Issue issue : context.allIssues()) { softly.assertThat(issue.primaryLocation().inputComponent().key()).isEqualTo(moduleKey); } softly.assertAll(); @@ -114,7 +112,7 @@ public void shouldReportProjectLevelMetricsV2() { // the total number of cppcheck issues final String moduleKey = context.module().key(); Measure nrOfIssuesMetric = context.measure(moduleKey, - language.getMetric(CxxMetricsFactory.Key.CPPCHECK_SENSOR_ISSUES_KEY)); + language.getMetric(CxxMetricsFactory.Key.CPPCHECK_SENSOR_ISSUES_KEY)); assertThat(nrOfIssuesMetric.value()).isEqualTo(3); } diff --git a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/drmemory/CxxDrMemorySensorTest.java b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/drmemory/CxxDrMemorySensorTest.java index 09434b075d..202c1bcb7b 100644 --- a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/drmemory/CxxDrMemorySensorTest.java +++ b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/drmemory/CxxDrMemorySensorTest.java @@ -19,11 +19,8 @@ */ package org.sonar.cxx.sensors.drmemory; -import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; - import static org.assertj.core.api.Assertions.assertThat; - import org.assertj.core.api.SoftAssertions; import org.junit.Before; import org.junit.Test; diff --git a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/other/CxxOtherSensorTest.java b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/other/CxxOtherSensorTest.java index dde0d62bcb..1c17a4cf4d 100644 --- a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/other/CxxOtherSensorTest.java +++ b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/other/CxxOtherSensorTest.java @@ -21,7 +21,6 @@ import java.util.Optional; import static org.assertj.core.api.Assertions.assertThat; - import org.assertj.core.api.SoftAssertions; import org.junit.Before; import org.junit.Rule; diff --git a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/pclint/CxxPCLintSensorTest.java b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/pclint/CxxPCLintSensorTest.java index b58f50cee5..27df8ca615 100644 --- a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/pclint/CxxPCLintSensorTest.java +++ b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/pclint/CxxPCLintSensorTest.java @@ -22,7 +22,6 @@ import java.util.ArrayList; import java.util.Optional; import static org.assertj.core.api.Assertions.assertThat; - import org.assertj.core.api.SoftAssertions; import org.junit.Before; import org.junit.Test; diff --git a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/rats/CxxRatsSensorTest.java b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/rats/CxxRatsSensorTest.java index b2b405148d..ac0d488e98 100644 --- a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/rats/CxxRatsSensorTest.java +++ b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/rats/CxxRatsSensorTest.java @@ -20,11 +20,10 @@ package org.sonar.cxx.sensors.rats; import static org.assertj.core.api.Assertions.assertThat; +import org.assertj.core.api.SoftAssertions; import org.junit.Before; import org.junit.Test; import static org.mockito.Mockito.when; - -import org.assertj.core.api.SoftAssertions; import org.sonar.api.batch.fs.internal.DefaultFileSystem; import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor; diff --git a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/tests/dotnet/CxxUnitTestResultsAggregatorTest.java b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/tests/dotnet/CxxUnitTestResultsAggregatorTest.java index a856ccb6e9..d2c87e5d4f 100644 --- a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/tests/dotnet/CxxUnitTestResultsAggregatorTest.java +++ b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/tests/dotnet/CxxUnitTestResultsAggregatorTest.java @@ -23,7 +23,6 @@ // SonarQube .NET Tests Library // Copyright (C) 2014-2017 SonarSource SA // mailto:info AT sonarsource DOT com - import java.io.File; import static java.util.Arrays.asList; import java.util.Collections; @@ -106,8 +105,8 @@ public void aggregate() { NUnitTestResultsFileParser nunitTestResultsFileParser = mock(NUnitTestResultsFileParser.class); UnitTestResults results = mock(UnitTestResults.class); new CxxUnitTestResultsAggregator(visualStudioTestResultsFileParser, xunitTestResultsFileParser, - nunitTestResultsFileParser).aggregate(wildcardPatternFileProvider, results, - new UnitTestConfiguration(language, settings.asConfig())); + nunitTestResultsFileParser).aggregate(wildcardPatternFileProvider, results, + new UnitTestConfiguration(language, settings.asConfig())); verify(visualStudioTestResultsFileParser).accept(new File("foo.trx"), results); // XUnit test results only @@ -119,8 +118,8 @@ public void aggregate() { nunitTestResultsFileParser = mock(NUnitTestResultsFileParser.class); results = mock(UnitTestResults.class); new CxxUnitTestResultsAggregator(visualStudioTestResultsFileParser, xunitTestResultsFileParser, - nunitTestResultsFileParser).aggregate(wildcardPatternFileProvider, results, - new UnitTestConfiguration(language, settings.asConfig())); + nunitTestResultsFileParser).aggregate(wildcardPatternFileProvider, results, + new UnitTestConfiguration(language, settings.asConfig())); verify(visualStudioTestResultsFileParser, Mockito.never()).accept(Mockito.any(File.class), Mockito.any(UnitTestResults.class)); verify(xunitTestResultsFileParser).accept(new File("foo.xml"), results); verify(nunitTestResultsFileParser, Mockito.never()).accept(Mockito.any(File.class), Mockito.any(UnitTestResults.class)); @@ -138,8 +137,8 @@ public void aggregate() { nunitTestResultsFileParser = mock(NUnitTestResultsFileParser.class); results = mock(UnitTestResults.class); new CxxUnitTestResultsAggregator(visualStudioTestResultsFileParser, xunitTestResultsFileParser, - nunitTestResultsFileParser).aggregate(wildcardPatternFileProvider, results, - new UnitTestConfiguration(language, settings.asConfig())); + nunitTestResultsFileParser).aggregate(wildcardPatternFileProvider, results, + new UnitTestConfiguration(language, settings.asConfig())); verify(visualStudioTestResultsFileParser).accept(new File("foo.trx"), results); verify(xunitTestResultsFileParser).accept(new File("foo.xml"), results); verify(nunitTestResultsFileParser).accept(new File("foo1.xml"), results); @@ -151,8 +150,8 @@ public void aggregate() { nunitTestResultsFileParser = mock(NUnitTestResultsFileParser.class); results = mock(UnitTestResults.class); new CxxUnitTestResultsAggregator(visualStudioTestResultsFileParser, xunitTestResultsFileParser, - nunitTestResultsFileParser).aggregate(wildcardPatternFileProvider, results, - new UnitTestConfiguration(language, settings.asConfig())); + nunitTestResultsFileParser).aggregate(wildcardPatternFileProvider, results, + new UnitTestConfiguration(language, settings.asConfig())); verify(visualStudioTestResultsFileParser, Mockito.never()).accept(Mockito.any(File.class), Mockito.any(UnitTestResults.class)); verify(xunitTestResultsFileParser, Mockito.never()).accept(Mockito.any(File.class), Mockito.any(UnitTestResults.class)); verify(nunitTestResultsFileParser, Mockito.never()).accept(Mockito.any(File.class), Mockito.any(UnitTestResults.class)); @@ -175,8 +174,8 @@ public void aggregate() { results = mock(UnitTestResults.class); new CxxUnitTestResultsAggregator(visualStudioTestResultsFileParser, xunitTestResultsFileParser, - nunitTestResultsFileParser).aggregate(wildcardPatternFileProvider, results, - new UnitTestConfiguration(language, settings.asConfig())); + nunitTestResultsFileParser).aggregate(wildcardPatternFileProvider, results, + new UnitTestConfiguration(language, settings.asConfig())); verify(wildcardPatternFileProvider).listFiles("*.trx"); verify(wildcardPatternFileProvider).listFiles("bar.trx"); diff --git a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/tests/dotnet/CxxUnitTestResultsImportSensorTest.java b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/tests/dotnet/CxxUnitTestResultsImportSensorTest.java index 3cdf078de1..1b57e3e17f 100644 --- a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/tests/dotnet/CxxUnitTestResultsImportSensorTest.java +++ b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/tests/dotnet/CxxUnitTestResultsImportSensorTest.java @@ -23,22 +23,19 @@ // SonarQube .NET Tests Library // Copyright (C) 2014-2017 SonarSource SA // mailto:info AT sonarsource DOT com - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.groups.Tuple.tuple; -import static org.mockito.ArgumentMatchers.same; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - import java.util.Optional; - +import static org.assertj.core.api.Assertions.assertThat; import org.assertj.core.api.SoftAssertions; +import static org.assertj.core.groups.Tuple.tuple; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; +import static org.mockito.ArgumentMatchers.same; import org.mockito.Mockito; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor; import org.sonar.api.batch.sensor.internal.SensorContextTester; import org.sonar.api.measures.CoreMetrics; @@ -88,13 +85,13 @@ public void analyze() throws Exception { UnitTestConfiguration unitTestConf = mock(UnitTestConfiguration.class); when(unitTestResultsAggregator.aggregate(Mockito.any(WildcardPatternFileProvider.class), - Mockito.any(UnitTestResults.class), same(unitTestConf))).thenReturn(results); + Mockito.any(UnitTestResults.class), same(unitTestConf))).thenReturn(results); new CxxUnitTestResultsImportSensor(unitTestResultsAggregator, language) .analyze(context, results, unitTestConf); verify(unitTestResultsAggregator).aggregate(Mockito.any(WildcardPatternFileProvider.class), Mockito.eq(results), - same(unitTestConf)); + same(unitTestConf)); assertThat(context.measures("projectKey")) .extracting("metric.key", "value") @@ -119,13 +116,13 @@ public void should_not_save_metrics_with_empty_results() throws Exception { when(results.errors()).thenReturn(3); when(results.executionTime()).thenReturn(null); when(unitTestResultsAggregator.aggregate(Mockito.any(WildcardPatternFileProvider.class), - Mockito.any(UnitTestResults.class), same(unitTestConf))).thenReturn(results); + Mockito.any(UnitTestResults.class), same(unitTestConf))).thenReturn(results); new CxxUnitTestResultsImportSensor(unitTestResultsAggregator, language) .analyze(context, results, unitTestConf); verify(unitTestResultsAggregator).aggregate(Mockito.any(WildcardPatternFileProvider.class), Mockito.eq(results), - same(unitTestConf)); + same(unitTestConf)); assertThat(context.measures("projectKey")) .extracting("metric.key", "value") diff --git a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/tests/dotnet/NUnitTestResultsFileParserTest.java b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/tests/dotnet/NUnitTestResultsFileParserTest.java index 32a4f5e354..c23625132e 100644 --- a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/tests/dotnet/NUnitTestResultsFileParserTest.java +++ b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/tests/dotnet/NUnitTestResultsFileParserTest.java @@ -24,22 +24,20 @@ // Copyright (C) 2014-2017 SonarSource SA // mailto:info AT sonarsource DOT com import java.io.File; +import static org.assertj.core.api.Assertions.assertThat; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; - -import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import org.sonar.api.utils.log.LogTester; import org.sonar.api.utils.log.LoggerLevel; public class NUnitTestResultsFileParserTest { + private static final String REPORT_PATH = "src/test/resources/org/sonar/cxx/sensors/reports-project/xunit-reports/nunit/"; @Rule public ExpectedException thrown = ExpectedException.none(); - private static final String REPORT_PATH = "src/test/resources/org/sonar/cxx/sensors/reports-project/xunit-reports/nunit/"; - @Rule public LogTester logTester = new LogTester(); diff --git a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/tests/dotnet/VisualStudioTestResultsFileParserTest.java b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/tests/dotnet/VisualStudioTestResultsFileParserTest.java index 1d73d7b27d..1a45e18378 100644 --- a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/tests/dotnet/VisualStudioTestResultsFileParserTest.java +++ b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/tests/dotnet/VisualStudioTestResultsFileParserTest.java @@ -23,7 +23,6 @@ // SonarQube .NET Tests Library // Copyright (C) 2014-2017 SonarSource SA // mailto:info AT sonarsource DOT com - import java.io.File; import static org.assertj.core.api.Assertions.assertThat; import org.junit.Rule; diff --git a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/tests/dotnet/WildcardPatternFileProviderTest.java b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/tests/dotnet/WildcardPatternFileProviderTest.java index 9f7f047276..a124ec3cff 100644 --- a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/tests/dotnet/WildcardPatternFileProviderTest.java +++ b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/tests/dotnet/WildcardPatternFileProviderTest.java @@ -23,7 +23,6 @@ // SonarQube .NET Tests Library // Copyright (C) 2014-2017 SonarSource SA // mailto:info AT sonarsource DOT com - import com.google.common.base.Joiner; import java.io.File; import java.util.Set; @@ -36,6 +35,18 @@ public class WildcardPatternFileProviderTest { + private static String path(String... elements) { + return Joiner.on(File.separator).join(elements); + } + + private static Set listFiles(String pattern) { + return listFiles(pattern, null); + } + + private static Set listFiles(String pattern, File baseDir) { + return new WildcardPatternFileProvider(baseDir, File.separator).listFiles(pattern); + } + @Rule public TemporaryFolder tmp = new TemporaryFolder(); @@ -184,16 +195,4 @@ public void should_fail_with_parent_folder_access_after_wildcard() { listFiles(path("*", "..", "foo.txt"), tmp.getRoot()); } - private static String path(String... elements) { - return Joiner.on(File.separator).join(elements); - } - - private static Set listFiles(String pattern) { - return listFiles(pattern, null); - } - - private static Set listFiles(String pattern, File baseDir) { - return new WildcardPatternFileProvider(baseDir, File.separator).listFiles(pattern); - } - } diff --git a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/tests/dotnet/XUnitTestResultsFileParserTest.java b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/tests/dotnet/XUnitTestResultsFileParserTest.java index bbcd35c5cf..8be40e6370 100644 --- a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/tests/dotnet/XUnitTestResultsFileParserTest.java +++ b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/tests/dotnet/XUnitTestResultsFileParserTest.java @@ -23,7 +23,6 @@ // SonarQube .NET Tests Library // Copyright (C) 2014-2017 SonarSource SA // mailto:info AT sonarsource DOT com - import java.io.File; import static org.assertj.core.api.Assertions.assertThat; import org.junit.Rule; @@ -35,11 +34,10 @@ public class XUnitTestResultsFileParserTest { + private static final String REPORT_PATH = "src/test/resources/org/sonar/cxx/sensors/reports-project/xunit-reports/xunit/"; @Rule public ExpectedException thrown = ExpectedException.none(); - private static final String REPORT_PATH = "src/test/resources/org/sonar/cxx/sensors/reports-project/xunit-reports/xunit/"; - @Rule public LogTester logTester = new LogTester(); diff --git a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/tests/dotnet/XmlParserHelperTest.java b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/tests/dotnet/XmlParserHelperTest.java index aea3927cfb..93ef2c89be 100644 --- a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/tests/dotnet/XmlParserHelperTest.java +++ b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/tests/dotnet/XmlParserHelperTest.java @@ -23,7 +23,6 @@ // SonarQube .NET Tests Library // Copyright (C) 2014-2017 SonarSource SA // mailto:info AT sonarsource DOT com - import java.io.File; import java.io.IOException; import static org.assertj.core.api.Assertions.assertThat; diff --git a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/utils/CxxMetricsTest.java b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/utils/CxxMetricsTest.java index f85ed56855..6c49b66597 100644 --- a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/utils/CxxMetricsTest.java +++ b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/utils/CxxMetricsTest.java @@ -22,7 +22,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; - import static org.assertj.core.api.Assertions.assertThat; import org.junit.Before; import org.junit.Test; @@ -36,6 +35,32 @@ public class CxxMetricsTest { private CxxLanguage language; + @Before + public void setUp() { + language = new CxxLanguageImpl(new MapSettings().asConfig()); + } + + @Test + public void getMetricsTest() { + List list = CxxMetricsFactory.generateList(language.getKey(), language.getPropertiesKey()); + assertThat(list.size()).isEqualTo(24); + + Map> map = CxxMetricsFactory.generateMap(language.getKey(), language.getPropertiesKey()); + assertThat(map.size()).isEqualTo(24); + } + + @Test + public void getMetricTest() { + Metric metric0 = language.getMetric(CxxMetricsFactory.Key.PUBLIC_API_KEY); + assertThat(metric0).isNotNull(); + + Metric metric1 = language.getMetric(CxxMetricsFactory.Key.PUBLIC_UNDOCUMENTED_API_KEY); + assertThat(metric1).isNotNull(); + + Metric metric2 = language.getMetric(CxxMetricsFactory.Key.PUBLIC_DOCUMENTED_API_DENSITY_KEY); + assertThat(metric2).isNotNull(); + } + public class CxxLanguageImpl extends CxxLanguage { public CxxLanguageImpl(Configuration settings) { @@ -68,30 +93,4 @@ public String getRepositoryKey() { } } - - @Before - public void setUp() { - language = new CxxLanguageImpl(new MapSettings().asConfig()); - } - - @Test - public void getMetricsTest() { - List list = CxxMetricsFactory.generateList(language.getKey(), language.getPropertiesKey()); - assertThat(list.size()).isEqualTo(24); - - Map> map = CxxMetricsFactory.generateMap(language.getKey(), language.getPropertiesKey()); - assertThat(map.size()).isEqualTo(24); - } - - @Test - public void getMetricTest() { - Metric metric0 = language.getMetric(CxxMetricsFactory.Key.PUBLIC_API_KEY); - assertThat(metric0).isNotNull(); - - Metric metric1 = language.getMetric(CxxMetricsFactory.Key.PUBLIC_UNDOCUMENTED_API_KEY); - assertThat(metric1).isNotNull(); - - Metric metric2 = language.getMetric(CxxMetricsFactory.Key.PUBLIC_DOCUMENTED_API_DENSITY_KEY); - assertThat(metric2).isNotNull(); - } } diff --git a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/utils/CxxReportSensorTest.java b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/utils/CxxReportSensorTest.java index 6eb7b511bf..efb62f2120 100644 --- a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/utils/CxxReportSensorTest.java +++ b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/utils/CxxReportSensorTest.java @@ -19,11 +19,9 @@ */ package org.sonar.cxx.sensors.utils; -import static org.assertj.core.api.Assertions.assertThat; - import java.io.File; import java.util.List; - +import static org.assertj.core.api.Assertions.assertThat; import org.junit.Before; import org.junit.Test; import org.sonar.api.batch.sensor.SensorContext; @@ -41,22 +39,6 @@ public class CxxReportSensorTest { private File baseDir; private final MapSettings settings = new MapSettings(); - private class CxxReportSensorImpl extends CxxReportSensor { - - public CxxReportSensorImpl(CxxLanguage language, MapSettings settings) { - super(language, "test.report"); - } - - @Override - public void execute(SensorContext sc) { - } - - @Override - public void describe(SensorDescriptor descriptor) { - descriptor.onlyOnLanguage("c++").name("CxxReportSensorTest"); - } - }; - @Before public void init() { TestUtils.mockFileSystem(); @@ -122,4 +104,20 @@ public void getReports_shouldFindSomethingList() { assertThat(reports.size() == 5).isTrue(); } + private class CxxReportSensorImpl extends CxxReportSensor { + + public CxxReportSensorImpl(CxxLanguage language, MapSettings settings) { + super(language, "test.report"); + } + + @Override + public void execute(SensorContext sc) { + } + + @Override + public void describe(SensorDescriptor descriptor) { + descriptor.onlyOnLanguage("c++").name("CxxReportSensorTest"); + } + } + } diff --git a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/utils/CxxReportSensor_getReports_Test.java b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/utils/CxxReportSensor_getReports_Test.java index 33062984a2..ec423aff06 100644 --- a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/utils/CxxReportSensor_getReports_Test.java +++ b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/utils/CxxReportSensor_getReports_Test.java @@ -19,7 +19,6 @@ */ package org.sonar.cxx.sensors.utils; - import java.io.File; import java.io.IOException; import java.util.List; diff --git a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/utils/TestUtils.java b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/utils/TestUtils.java index 0fdd84211c..9928fa81b7 100644 --- a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/utils/TestUtils.java +++ b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/utils/TestUtils.java @@ -23,7 +23,6 @@ import java.io.Serializable; import java.net.URISyntaxException; import java.net.URL; -import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.List; @@ -31,9 +30,9 @@ import java.util.Optional; import javax.annotation.CheckForNull; import org.apache.tools.ant.DirectoryScanner; +import static org.mockito.ArgumentMatchers.same; import org.mockito.Mockito; import static org.mockito.Mockito.when; -import static org.mockito.Mockito.same; import org.sonar.api.batch.fs.InputFile.Type; import org.sonar.api.batch.fs.internal.DefaultFileSystem; import org.sonar.api.batch.fs.internal.TestInputFileBuilder; @@ -78,8 +77,8 @@ public static DefaultFileSystem mockFileSystem() { } /** - * Mocks the filesystem given the root directory and lists of source and tests - * directories. The latter are given just as in sonar-project.properties + * Mocks the filesystem given the root directory and lists of source and tests directories. The latter are given just + * as in sonar-project.properties * * @param baseDir project root directory * @param sourceDirs List of source directories, relative to baseDir. @@ -106,7 +105,7 @@ public static CxxLanguage mockCxxLanguage() { when(language.IsRecoveryEnabled()).thenReturn(Optional.of(Boolean.TRUE)); when(language.getFileSuffixes()) .thenReturn(new String[]{".cpp", ".hpp", ".h", ".cxx", ".c", ".cc", ".hxx", ".hh"}); - when(language.getHeaderFileSuffixes()).thenReturn(new String[] { ".hpp", ".h", ".hxx", ".hh" }); + when(language.getHeaderFileSuffixes()).thenReturn(new String[]{".hpp", ".h", ".hxx", ".hh"}); Map> metrics = CxxMetricsFactory.generateMap("cxx", "cxx"); metrics.forEach((key, value) -> when(language.getMetric(same(key))).thenReturn((Metric) value)); @@ -143,8 +142,7 @@ private static void scanDirs(DefaultFileSystem fs, List dirs, Type ftype) } /** - * Search for a test resource in the classpath. For example - * getResource("org/sonar/MyClass/foo.txt"); + * Search for a test resource in the classpath. For example getResource("org/sonar/MyClass/foo.txt"); * * @param path the starting slash is optional * @return the resource. Null if resource not found diff --git a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/valgrind/CxxValgrindSensorTest.java b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/valgrind/CxxValgrindSensorTest.java index b097ff1e89..21f0b92136 100644 --- a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/valgrind/CxxValgrindSensorTest.java +++ b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/valgrind/CxxValgrindSensorTest.java @@ -23,7 +23,6 @@ import java.util.HashSet; import java.util.Set; import static org.assertj.core.api.Assertions.assertThat; - import org.assertj.core.api.SoftAssertions; import org.junit.Before; import org.junit.Test; diff --git a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/veraxx/CxxVeraxxSensorTest.java b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/veraxx/CxxVeraxxSensorTest.java index 85a63c5775..9b9198aaa6 100644 --- a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/veraxx/CxxVeraxxSensorTest.java +++ b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/veraxx/CxxVeraxxSensorTest.java @@ -21,7 +21,6 @@ import java.util.Optional; import static org.assertj.core.api.Assertions.assertThat; - import org.assertj.core.api.SoftAssertions; import org.junit.Before; import org.junit.Test; diff --git a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/visitors/CxxCpdVisitorTest.java b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/visitors/CxxCpdVisitorTest.java index dc057bb8fa..c0b095eba0 100644 --- a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/visitors/CxxCpdVisitorTest.java +++ b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/visitors/CxxCpdVisitorTest.java @@ -22,7 +22,6 @@ import java.io.File; import java.io.IOException; import java.io.UnsupportedEncodingException; -import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.util.List; diff --git a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/visitors/CxxFileLinesVisitorTest.java b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/visitors/CxxFileLinesVisitorTest.java index 907f9f9fa2..c31dd39d7e 100644 --- a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/visitors/CxxFileLinesVisitorTest.java +++ b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/visitors/CxxFileLinesVisitorTest.java @@ -22,7 +22,6 @@ import java.io.File; import java.io.IOException; import java.io.UnsupportedEncodingException; -import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.util.HashSet; @@ -30,14 +29,12 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; - import org.assertj.core.api.SoftAssertions; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; - import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.fs.internal.TestInputFileBuilder; @@ -54,52 +51,6 @@ public class CxxFileLinesVisitorTest { private CxxLanguage language; private FileLinesContextFactory fileLinesContextFactory; - private class FileLinesContextForTesting implements FileLinesContext - { - public final Set executableLines = new HashSet<>(); - public final Set linesOfCode = new HashSet<>(); - public final Set linesOfComments = new HashSet<>(); - - @Override - public void setIntValue(String metricKey, int line, int value) { - Assert.assertEquals(1, value); - - switch (metricKey) { - case CoreMetrics.NCLOC_DATA_KEY: - linesOfCode.add(line); - break; - case CoreMetrics.COMMENT_LINES_DATA_KEY: - linesOfComments.add(line); - break; - case CoreMetrics.EXECUTABLE_LINES_DATA_KEY: - executableLines.add(line); - break; - default: - Assert.fail("Unsupported metric key " + metricKey); - } - } - - @Override - public Integer getIntValue(String metricKey, int line) { - Assert.fail("unexpected method called: getIntValue()"); - return null; - } - - @Override - public void setStringValue(String metricKey, int line, String value) { - Assert.fail("unexpected method called: setStringValue()"); - } - - @Override - public String getStringValue(String metricKey, int line) { - Assert.fail("unexpected method called: getStringValue()"); - return null; - } - - @Override - public void save() { - } - } private FileLinesContextForTesting fileLinesContext; private File baseDir; @@ -118,9 +69,9 @@ public void setUp() { target = new File(baseDir, "ncloc.cc"); testLines = Stream.of(8, 10, 14, 16, 17, 21, 22, 23, 26, 31, 34, 35, 42, 44, 45, 49, 51, 53, 55, 56, - 58, 59, 63, 65, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 79, 82, 84, 86, 87, 89, - 90, 95, 98, 99, 100, 102, 107, 108, 109, 110, 111, 113, 115, 118, 119, 124, 126) - .collect(Collectors.toCollection(HashSet::new)); + 58, 59, 63, 65, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 79, 82, 84, 86, 87, 89, + 90, 95, 98, 99, 100, 102, 107, 108, 109, 110, 111, 113, 115, 118, 119, 124, 126) + .collect(Collectors.toCollection(HashSet::new)); } @Test @@ -183,4 +134,51 @@ public void TestExecutableLinesOfCode() throws UnsupportedEncodingException, IOE assertThat(fileLinesContext.executableLines).containsExactlyInAnyOrder(10, 26, 34, 35, 56, 59, 69, 70, 72, 73, 75, 76, 79, 87, 90, 98, 102, 118, 119, 126); } + + private class FileLinesContextForTesting implements FileLinesContext { + + public final Set executableLines = new HashSet<>(); + public final Set linesOfCode = new HashSet<>(); + public final Set linesOfComments = new HashSet<>(); + + @Override + public void setIntValue(String metricKey, int line, int value) { + Assert.assertEquals(1, value); + + switch (metricKey) { + case CoreMetrics.NCLOC_DATA_KEY: + linesOfCode.add(line); + break; + case CoreMetrics.COMMENT_LINES_DATA_KEY: + linesOfComments.add(line); + break; + case CoreMetrics.EXECUTABLE_LINES_DATA_KEY: + executableLines.add(line); + break; + default: + Assert.fail("Unsupported metric key " + metricKey); + } + } + + @Override + public Integer getIntValue(String metricKey, int line) { + Assert.fail("unexpected method called: getIntValue()"); + return null; + } + + @Override + public void setStringValue(String metricKey, int line, String value) { + Assert.fail("unexpected method called: setStringValue()"); + } + + @Override + public String getStringValue(String metricKey, int line) { + Assert.fail("unexpected method called: getStringValue()"); + return null; + } + + @Override + public void save() { + } + } } diff --git a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/visitors/CxxHighlighterTest.java b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/visitors/CxxHighlighterTest.java index 8abea1faf1..3a9f8851de 100644 --- a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/visitors/CxxHighlighterTest.java +++ b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/visitors/CxxHighlighterTest.java @@ -21,7 +21,6 @@ import java.io.File; import java.io.IOException; -import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.util.List; diff --git a/cxx-sensors/src/test/java/org/sonar/plugins/cxx/squid/CustomCxxRulesDefinitionTest.java b/cxx-sensors/src/test/java/org/sonar/plugins/cxx/squid/CustomCxxRulesDefinitionTest.java index a6372f0f77..76034c8f43 100644 --- a/cxx-sensors/src/test/java/org/sonar/plugins/cxx/squid/CustomCxxRulesDefinitionTest.java +++ b/cxx-sensors/src/test/java/org/sonar/plugins/cxx/squid/CustomCxxRulesDefinitionTest.java @@ -63,20 +63,6 @@ public void test() { } } - @Rule( - key = RULE_KEY, - name = RULE_NAME, - description = "desc", - tags = {Tag.BUG}) - public class MyCustomRule extends SquidCheck { - - @RuleProperty( - key = "customParam", - description = "Custom parameter", - defaultValue = "value") - public String customParam = "value"; - } - public static class MyCustomPlSqlRulesDefinition extends CustomCxxRulesDefinition { @Override @@ -102,4 +88,18 @@ public CxxLanguage getLanguage() { } } + @Rule( + key = RULE_KEY, + name = RULE_NAME, + description = "desc", + tags = {Tag.BUG}) + public class MyCustomRule extends SquidCheck { + + @RuleProperty( + key = "customParam", + description = "Custom parameter", + defaultValue = "value") + public String customParam = "value"; + } + } diff --git a/cxx-sensors/src/test/java/org/sonar/plugins/cxx/squid/CxxSquidSensorTest.java b/cxx-sensors/src/test/java/org/sonar/plugins/cxx/squid/CxxSquidSensorTest.java index dbb17fa3ce..40416207a4 100644 --- a/cxx-sensors/src/test/java/org/sonar/plugins/cxx/squid/CxxSquidSensorTest.java +++ b/cxx-sensors/src/test/java/org/sonar/plugins/cxx/squid/CxxSquidSensorTest.java @@ -21,16 +21,14 @@ import java.io.File; import java.io.IOException; -import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.util.Optional; - import static org.assertj.core.api.Assertions.assertThat; - import org.assertj.core.api.SoftAssertions; import org.junit.Before; import org.junit.Test; +import static org.mockito.ArgumentMatchers.same; import org.mockito.Mockito; import static org.mockito.Mockito.*; import org.sonar.api.batch.fs.InputFile; @@ -74,8 +72,7 @@ public void setUp() { null); } - private DefaultInputFile buildTestInputFile(File baseDir, String fileName) throws IOException - { + private DefaultInputFile buildTestInputFile(File baseDir, String fileName) throws IOException { File target = new File(baseDir, fileName); String content = new String(Files.readAllBytes(target.toPath()), "UTF-8"); DefaultInputFile inputFile = TestInputFileBuilder.create("ProjectKey", baseDir, target).setContents(content) @@ -160,9 +157,9 @@ public void testDocumentationSquidMetrics() throws IOException { final Metric API = language.getMetric(CxxMetricsFactory.Key.PUBLIC_API_KEY); final Metric UNDOCUMENTED_API = language - .getMetric(CxxMetricsFactory.Key.PUBLIC_UNDOCUMENTED_API_KEY); + .getMetric(CxxMetricsFactory.Key.PUBLIC_UNDOCUMENTED_API_KEY); final Metric DOCUMENTED_API_DENSITY = language - .getMetric(CxxMetricsFactory.Key.PUBLIC_DOCUMENTED_API_DENSITY_KEY); + .getMetric(CxxMetricsFactory.Key.PUBLIC_DOCUMENTED_API_DENSITY_KEY); SoftAssertions softly = new SoftAssertions(); softly.assertThat(context.measure(inputFile.key(), API).value()).isEqualTo(8); diff --git a/cxx-squid/src/main/java/org/sonar/cxx/AggregateMeasureComputer.java b/cxx-squid/src/main/java/org/sonar/cxx/AggregateMeasureComputer.java index df88a76729..f04211f2d5 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/AggregateMeasureComputer.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/AggregateMeasureComputer.java @@ -20,7 +20,6 @@ package org.sonar.cxx; import java.util.Map; - import org.sonar.api.ce.measure.Component; import org.sonar.api.ce.measure.Measure; import org.sonar.api.ce.measure.MeasureComputer; @@ -29,18 +28,16 @@ import org.sonar.api.utils.log.Loggers; /** - * SonarQube supports hierarchical multi-module projects. It is not enough to - * calculate a metric M for the file and/or for the corresponding module. The - * same metric has to be calculated/propagated/aggregated for all parent modules - * and the root project. + * SonarQube supports hierarchical multi-module projects. It is not enough to calculate a metric M for the file and/or + * for the corresponding module. The same metric has to be calculated/propagated/aggregated for all parent modules and + * the root project. * - * This {@link MeasureComputer} is executed on Compute Engine (server-side). For - * each metric M in the given set of metrics the sum on the hierarchy level L is - * calculated. The sum is persisted as aggregated metric M on the level (L-1). + * This {@link MeasureComputer} is executed on Compute Engine (server-side). For each metric M in the given set of + * metrics the sum on the hierarchy level L is calculated. The sum is persisted as aggregated metric M on the level + * (L-1). * - * Some CXX sensors (see CxxReportSensor) can create issues on the whole module. - * Such sensors have to aggregate the corresponding module Metric by themselves. - * {@link AggregateMeasureComputer} doesn't recalculate already aggregated + * Some CXX sensors (see CxxReportSensor) can create issues on the whole module. Such sensors have to aggregate the + * corresponding module Metric by themselves. {@link AggregateMeasureComputer} doesn't recalculate already aggregated * metrics. * */ @@ -48,43 +45,6 @@ public class AggregateMeasureComputer implements MeasureComputer { private static final Logger LOG = Loggers.get(AggregateMeasureComputer.class); - private final String[] metricKeys; - - public AggregateMeasureComputer(String languageKey, String languagePropsKey) { - final Map> metrics = CxxMetricsFactory.generateMap(languageKey, languagePropsKey); - - metricKeys = new String[] { - // public API - metrics.get(CxxMetricsFactory.Key.PUBLIC_API_KEY).key(), - metrics.get(CxxMetricsFactory.Key.PUBLIC_UNDOCUMENTED_API_KEY).key(), - - // sensors - metrics.get(CxxMetricsFactory.Key.CLANG_SA_SENSOR_ISSUES_KEY).key(), - metrics.get(CxxMetricsFactory.Key.CLANG_TIDY_SENSOR_ISSUES_KEY).key(), - metrics.get(CxxMetricsFactory.Key.VC_SENSOR_ISSUES_KEY).key(), - metrics.get(CxxMetricsFactory.Key.GCC_SENSOR_ISSUES_KEY).key(), - metrics.get(CxxMetricsFactory.Key.CPPCHECK_SENSOR_ISSUES_KEY).key(), - metrics.get(CxxMetricsFactory.Key.DRMEMORY_SENSOR_ISSUES_KEY).key(), - metrics.get(CxxMetricsFactory.Key.OTHER_SENSOR_ISSUES_KEY).key(), - metrics.get(CxxMetricsFactory.Key.PCLINT_SENSOR_ISSUES_KEY).key(), - metrics.get(CxxMetricsFactory.Key.RATS_SENSOR_ISSUES_KEY).key(), - metrics.get(CxxMetricsFactory.Key.SQUID_SENSOR_ISSUES_KEY).key(), - metrics.get(CxxMetricsFactory.Key.VALGRIND_SENSOR_KEY).key(), - metrics.get(CxxMetricsFactory.Key.VERAXX_SENSOR_KEY).key(), - - // complexity - metrics.get(CxxMetricsFactory.Key.COMPLEX_FUNCTIONS_KEY).key(), - metrics.get(CxxMetricsFactory.Key.COMPLEX_FUNCTIONS_LOC_KEY).key(), - - metrics.get(CxxMetricsFactory.Key.BIG_FUNCTIONS_KEY).key(), - metrics.get(CxxMetricsFactory.Key.BIG_FUNCTIONS_LOC_KEY).key(), - metrics.get(CxxMetricsFactory.Key.LOC_IN_FUNCTIONS_KEY).key(), }; - } - - public String[] getAggregatedMetrics() { - return metricKeys.clone(); - } - private static void compute(MeasureComputerContext context, String metricKey) { final Component component = context.getComponent(); if (component.getType() == Component.Type.FILE) { @@ -94,7 +54,7 @@ private static void compute(MeasureComputerContext context, String metricKey) { final Measure existingMeasure = context.getMeasure(metricKey); if (existingMeasure != null) { LOG.debug("Component {}: measure {} already calculated, value = {}", component.getKey(), metricKey, - existingMeasure.getIntValue()); + existingMeasure.getIntValue()); return; } Iterable childrenMeasures = context.getChildrenMeasures(metricKey); @@ -112,6 +72,40 @@ private static void compute(MeasureComputerContext context, String metricKey) { context.addMeasure(metricKey, aggregation); } + private final String[] metricKeys; + + public AggregateMeasureComputer(String languageKey, String languagePropsKey) { + final Map> metrics = CxxMetricsFactory.generateMap(languageKey, languagePropsKey); + + metricKeys = new String[]{ + // public API + metrics.get(CxxMetricsFactory.Key.PUBLIC_API_KEY).key(), + metrics.get(CxxMetricsFactory.Key.PUBLIC_UNDOCUMENTED_API_KEY).key(), + // sensors + metrics.get(CxxMetricsFactory.Key.CLANG_SA_SENSOR_ISSUES_KEY).key(), + metrics.get(CxxMetricsFactory.Key.CLANG_TIDY_SENSOR_ISSUES_KEY).key(), + metrics.get(CxxMetricsFactory.Key.VC_SENSOR_ISSUES_KEY).key(), + metrics.get(CxxMetricsFactory.Key.GCC_SENSOR_ISSUES_KEY).key(), + metrics.get(CxxMetricsFactory.Key.CPPCHECK_SENSOR_ISSUES_KEY).key(), + metrics.get(CxxMetricsFactory.Key.DRMEMORY_SENSOR_ISSUES_KEY).key(), + metrics.get(CxxMetricsFactory.Key.OTHER_SENSOR_ISSUES_KEY).key(), + metrics.get(CxxMetricsFactory.Key.PCLINT_SENSOR_ISSUES_KEY).key(), + metrics.get(CxxMetricsFactory.Key.RATS_SENSOR_ISSUES_KEY).key(), + metrics.get(CxxMetricsFactory.Key.SQUID_SENSOR_ISSUES_KEY).key(), + metrics.get(CxxMetricsFactory.Key.VALGRIND_SENSOR_KEY).key(), + metrics.get(CxxMetricsFactory.Key.VERAXX_SENSOR_KEY).key(), + // complexity + metrics.get(CxxMetricsFactory.Key.COMPLEX_FUNCTIONS_KEY).key(), + metrics.get(CxxMetricsFactory.Key.COMPLEX_FUNCTIONS_LOC_KEY).key(), + metrics.get(CxxMetricsFactory.Key.BIG_FUNCTIONS_KEY).key(), + metrics.get(CxxMetricsFactory.Key.BIG_FUNCTIONS_LOC_KEY).key(), + metrics.get(CxxMetricsFactory.Key.LOC_IN_FUNCTIONS_KEY).key(),}; + } + + public String[] getAggregatedMetrics() { + return metricKeys.clone(); + } + @Override public MeasureComputerDefinition define(MeasureComputerDefinitionContext defContext) { return defContext.newDefinitionBuilder().setInputMetrics(metricKeys).setOutputMetrics(metricKeys).build(); diff --git a/cxx-squid/src/main/java/org/sonar/cxx/CxxAstScanner.java b/cxx-squid/src/main/java/org/sonar/cxx/CxxAstScanner.java index e1a3e8e4b8..249f16243c 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/CxxAstScanner.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/CxxAstScanner.java @@ -43,7 +43,6 @@ import org.sonar.cxx.visitors.CxxPublicApiVisitor; import org.sonar.squidbridge.AstScanner; import org.sonar.squidbridge.CommentAnalyser; -import org.sonar.squidbridge.SourceCodeBuilderCallback; import org.sonar.squidbridge.SourceCodeBuilderVisitor; import org.sonar.squidbridge.SquidAstVisitor; import org.sonar.squidbridge.SquidAstVisitorContextImpl; @@ -60,9 +59,6 @@ public final class CxxAstScanner { - private CxxAstScanner() { - } - /** * Helper method for testing checks without having to deploy them on a Sonar instance. * @@ -254,5 +250,7 @@ public static String intersectingConcatenate(String a, String b) { // Didn't find any intersection. Fall back to straight concatenation. return a + b; } -} + private CxxAstScanner() { + } +} diff --git a/cxx-squid/src/main/java/org/sonar/cxx/CxxComplexityConstants.java b/cxx-squid/src/main/java/org/sonar/cxx/CxxComplexityConstants.java index d93fa2526f..c2c895dfd1 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/CxxComplexityConstants.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/CxxComplexityConstants.java @@ -49,7 +49,7 @@ public final class CxxComplexityConstants { CxxPunctuator.QUEST }; - public static final AstNodeType[] getCyclomaticComplexityTypes() { + public static AstNodeType[] getCyclomaticComplexityTypes() { return CYCLOMATIC_COMPLEXITY_TYPES; } diff --git a/cxx-squid/src/main/java/org/sonar/cxx/CxxLanguage.java b/cxx-squid/src/main/java/org/sonar/cxx/CxxLanguage.java index 02fd0aeaac..961cc49afa 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/CxxLanguage.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/CxxLanguage.java @@ -20,27 +20,25 @@ package org.sonar.cxx; import java.io.Serializable; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.regex.Pattern; - import org.sonar.api.config.Configuration; import org.sonar.api.measures.Metric; import org.sonar.api.resources.AbstractLanguage; -import java.util.Collections; - /** * {@inheritDoc} */ public abstract class CxxLanguage extends AbstractLanguage { public static final String ERROR_RECOVERY_KEY = "errorRecoveryEnabled"; + public static final Pattern EOL_PATTERN = Pattern.compile("\\R"); private final String propertiesKey; private final Configuration settings; private final Map> langSpecificMetrics; - public static final Pattern EOL_PATTERN = Pattern.compile("\\R"); public CxxLanguage(String key, String propertiesKey, Configuration settings) { super(key); diff --git a/cxx-squid/src/main/java/org/sonar/cxx/CxxMetricsFactory.java b/cxx-squid/src/main/java/org/sonar/cxx/CxxMetricsFactory.java index bed753f21f..46b1f3a2d1 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/CxxMetricsFactory.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/CxxMetricsFactory.java @@ -24,7 +24,6 @@ import java.util.List; import java.util.Locale; import java.util.Map; - import org.sonar.api.measures.CoreMetrics; import org.sonar.api.measures.Metric; @@ -38,56 +37,6 @@ */ public class CxxMetricsFactory { - private CxxMetricsFactory() { - } - - public enum Key { - // Introduce own documentation metrics, after they has been removed from SQ core - // see https://jira.sonarsource.com/browse/SONAR-8328 - PUBLIC_API_KEY("public_api"), - PUBLIC_UNDOCUMENTED_API_KEY("public_undocumented_api"), - PUBLIC_DOCUMENTED_API_DENSITY_KEY("public_documented_api_density"), - // Introduce metric keys for sensors - number of issues per file / per module - CLANG_SA_SENSOR_ISSUES_KEY("ClangSA"), - CLANG_TIDY_SENSOR_ISSUES_KEY("Clang-Tidy"), - VC_SENSOR_ISSUES_KEY("Compiler-VC"), - GCC_SENSOR_ISSUES_KEY("Compiler-GCC"), - CPPCHECK_SENSOR_ISSUES_KEY("CppCheck"), - DRMEMORY_SENSOR_ISSUES_KEY("DrMemory"), - OTHER_SENSOR_ISSUES_KEY("other"), - PCLINT_SENSOR_ISSUES_KEY("PC-Lint"), - RATS_SENSOR_ISSUES_KEY("Rats"), - SQUID_SENSOR_ISSUES_KEY("Squid"), - VALGRIND_SENSOR_KEY("Valgrind"), - VERAXX_SENSOR_KEY("Vera++"), - // Introduce additional complexity metrics - COMPLEX_FUNCTIONS_KEY("complex_functions"), - COMPLEX_FUNCTIONS_PERC_KEY("perc_complex_functions"), - COMPLEX_FUNCTIONS_LOC_KEY("loc_in_complex_functions"), - COMPLEX_FUNCTIONS_LOC_PERC_KEY("perc_loc_in_complex_functions"), - BIG_FUNCTIONS_KEY("big_functions"), - BIG_FUNCTIONS_LOC_KEY("loc_in_big_functions"), - BIG_FUNCTIONS_PERC_KEY("perc_big_functions"), - BIG_FUNCTIONS_LOC_PERC_KEY("perc_loc_in_big_functions"), - LOC_IN_FUNCTIONS_KEY("loc_in_functions"); - - private final String key; - - Key(final String key) { - this.key = key.toUpperCase(Locale.ENGLISH); - } - - String getLanguageSpecificKey(String langPropertiesKey) { - return langPropertiesKey.toUpperCase(Locale.ENGLISH) + "-" + key; - } - - @Override - public String toString() { - return key; - } - - } - /** * Generate a map { language independent metric key : language dependent Metric object } */ @@ -265,4 +214,54 @@ private static void addSensorMetric(Key metricKey, String description, String do .create(); metrics.put(metricKey, metric); } + + private CxxMetricsFactory() { + } + + public enum Key { + // Introduce own documentation metrics, after they has been removed from SQ core + // see https://jira.sonarsource.com/browse/SONAR-8328 + PUBLIC_API_KEY("public_api"), + PUBLIC_UNDOCUMENTED_API_KEY("public_undocumented_api"), + PUBLIC_DOCUMENTED_API_DENSITY_KEY("public_documented_api_density"), + // Introduce metric keys for sensors - number of issues per file / per module + CLANG_SA_SENSOR_ISSUES_KEY("ClangSA"), + CLANG_TIDY_SENSOR_ISSUES_KEY("Clang-Tidy"), + VC_SENSOR_ISSUES_KEY("Compiler-VC"), + GCC_SENSOR_ISSUES_KEY("Compiler-GCC"), + CPPCHECK_SENSOR_ISSUES_KEY("CppCheck"), + DRMEMORY_SENSOR_ISSUES_KEY("DrMemory"), + OTHER_SENSOR_ISSUES_KEY("other"), + PCLINT_SENSOR_ISSUES_KEY("PC-Lint"), + RATS_SENSOR_ISSUES_KEY("Rats"), + SQUID_SENSOR_ISSUES_KEY("Squid"), + VALGRIND_SENSOR_KEY("Valgrind"), + VERAXX_SENSOR_KEY("Vera++"), + // Introduce additional complexity metrics + COMPLEX_FUNCTIONS_KEY("complex_functions"), + COMPLEX_FUNCTIONS_PERC_KEY("perc_complex_functions"), + COMPLEX_FUNCTIONS_LOC_KEY("loc_in_complex_functions"), + COMPLEX_FUNCTIONS_LOC_PERC_KEY("perc_loc_in_complex_functions"), + BIG_FUNCTIONS_KEY("big_functions"), + BIG_FUNCTIONS_LOC_KEY("loc_in_big_functions"), + BIG_FUNCTIONS_PERC_KEY("perc_big_functions"), + BIG_FUNCTIONS_LOC_PERC_KEY("perc_loc_in_big_functions"), + LOC_IN_FUNCTIONS_KEY("loc_in_functions"); + + private final String key; + + Key(final String key) { + this.key = key.toUpperCase(Locale.ENGLISH); + } + + String getLanguageSpecificKey(String langPropertiesKey) { + return langPropertiesKey.toUpperCase(Locale.ENGLISH) + "-" + key; + } + + @Override + public String toString() { + return key; + } + + } } diff --git a/cxx-squid/src/main/java/org/sonar/cxx/CxxVCppBuildLogParser.java b/cxx-squid/src/main/java/org/sonar/cxx/CxxVCppBuildLogParser.java index b4e1def5ae..360d405030 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/CxxVCppBuildLogParser.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/CxxVCppBuildLogParser.java @@ -48,11 +48,6 @@ public class CxxVCppBuildLogParser { private static final Logger LOG = Loggers.get(CxxVCppBuildLogParser.class); - private final Map> uniqueIncludes; - private final Map> uniqueDefines; - - private String platformToolset = "V120"; - private String platform = "Win32"; private static final String CPPWINRTVERSION = "__cplusplus_winrt=201009"; private static final String CPPVERSION = "__cplusplus=199711L"; @@ -65,6 +60,19 @@ public class CxxVCppBuildLogParser { private static final Pattern toolsetV141Pattern = Pattern .compile("^.*VC\\\\Tools\\\\MSVC\\\\14\\.1\\d\\.\\d+\\\\bin\\\\HostX(86|64)\\\\x(86|64)\\\\CL.exe.*$"); + private static List getMatches(Pattern pattern, String text) { + List matches = new ArrayList<>(); + Matcher m = pattern.matcher(text); + while (m.find()) { + matches.add(m.group(1)); + } + return matches; + } + private final Map> uniqueIncludes; + private final Map> uniqueDefines; + private String platformToolset = "V120"; + private String platform = "Win32"; + /** * CxxVCppBuildLogParser (ctor) * @@ -276,15 +284,6 @@ private void parseVCppCompilerCLLine(String line, String projectPath, String fil } } - private static List getMatches(Pattern pattern, String text) { - List matches = new ArrayList<>(); - Matcher m = pattern.matcher(text); - while (m.find()) { - matches.add(m.group(1)); - } - return matches; - } - private void parseInclude(String element, String project, String fileElement) { List includesPerUnit = uniqueIncludes.get(fileElement); diff --git a/cxx-squid/src/main/java/org/sonar/cxx/DensityMeasureComputer.java b/cxx-squid/src/main/java/org/sonar/cxx/DensityMeasureComputer.java index 6185d643f8..0e82bd364d 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/DensityMeasureComputer.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/DensityMeasureComputer.java @@ -20,7 +20,6 @@ package org.sonar.cxx; import java.util.Map; - import org.sonar.api.ce.measure.Component; import org.sonar.api.ce.measure.Measure; import org.sonar.api.ce.measure.MeasureComputer; @@ -30,19 +29,16 @@ import org.sonar.api.utils.log.Loggers; /** - * SonarQube supports hierarchical multi-module projects. It is not enough to - * calculate a metric M for the file and/or for the corresponding module. The - * same metric has to be calculated/propagated/aggregated for all parent modules - * and the root project. + * SonarQube supports hierarchical multi-module projects. It is not enough to calculate a metric M for the file and/or + * for the corresponding module. The same metric has to be calculated/propagated/aggregated for all parent modules and + * the root project. * - * This {@link MeasureComputer} is executed on Compute Engine (server-side). For - * a pair of existing metrics VALUE_METRIC_KEY and TOTAL_METRIC_KEY it - * calculates the PERCENT_OF_VALUE_IN_TOTAL_METRIC. This calculation takes place - * on each hierarchy level of SonarQube project. + * This {@link MeasureComputer} is executed on Compute Engine (server-side). For a pair of existing metrics + * VALUE_METRIC_KEY and TOTAL_METRIC_KEY it calculates the PERCENT_OF_VALUE_IN_TOTAL_METRIC. This calculation takes + * place on each hierarchy level of SonarQube project. * - * REQUIREMENT: input metrics VALUE_METRIC_KEY and TOTAL_METRIC_KEY must be - * already calculated and propagated/aggregated on each level. - * AggregateMeasureComputer must have already run. + * REQUIREMENT: input metrics VALUE_METRIC_KEY and TOTAL_METRIC_KEY must be already calculated and propagated/aggregated + * on each level. AggregateMeasureComputer must have already run. * * See also {@link AggregateMeasureComputer} */ @@ -50,6 +46,38 @@ public class DensityMeasureComputer implements MeasureComputer { private static final Logger LOG = Loggers.get(DensityMeasureComputer.class); + private static void compute(MeasureComputerContext context, String valueKey, String totalKey, String densityKey, + boolean calculateReminingPercent) { + final Component component = context.getComponent(); + + final Measure valueMeasure = context.getMeasure(valueKey); + final Measure totalMeasure = context.getMeasure(totalKey); + if (valueMeasure == null || totalMeasure == null) { + LOG.error("Component {}: not enough data to calcualte measure {}", context.getComponent().getKey(), densityKey); + return; + } + final Measure existingMeasure = context.getMeasure(densityKey); + if (existingMeasure != null) { + LOG.error("Component {}: measure {} already calculated, value = {}", component.getKey(), densityKey, + existingMeasure.getDoubleValue()); + return; + } + + int value = valueMeasure.getIntValue(); + final int total = totalMeasure.getIntValue(); + if (calculateReminingPercent) { + value = Integer.max(total - value, 0); + } + + double density = 0.0; + if (total >= value && total != 0) { + density = (double) value / (double) total * 100.0; + } + + LOG.info("Component {}: add measure {}, value {}", component.getKey(), densityKey, density); + context.addMeasure(densityKey, density); + } + private final String publicAPIKey; private final String publicUndocumentedAPIKey; private final String publicDocumentedAPIDensityKey; @@ -88,10 +116,10 @@ public DensityMeasureComputer(String languageKey, String languagePropsKey) { locInFunctionsKey = metrics.get(CxxMetricsFactory.Key.LOC_IN_FUNCTIONS_KEY).key(); - inputMetrics = new String[] { publicAPIKey, publicUndocumentedAPIKey, CoreMetrics.FUNCTIONS_KEY, locInFunctionsKey, - complexFunctionsKey, complexFunctionsLocKey, bigFunctionsKey, bigFunctionsLocKey }; - outputMetrics = new String[] { publicDocumentedAPIDensityKey, complexFunctionsPercKey, complexFunctionsLocPercKey, - bigFunctionsPercKey, bigFunctionsLocPercKey }; + inputMetrics = new String[]{publicAPIKey, publicUndocumentedAPIKey, CoreMetrics.FUNCTIONS_KEY, locInFunctionsKey, + complexFunctionsKey, complexFunctionsLocKey, bigFunctionsKey, bigFunctionsLocKey}; + outputMetrics = new String[]{publicDocumentedAPIDensityKey, complexFunctionsPercKey, complexFunctionsLocPercKey, + bigFunctionsPercKey, bigFunctionsLocPercKey}; } public String[] getInputMetrics() { @@ -116,36 +144,4 @@ public void compute(MeasureComputerContext context) { compute(context, bigFunctionsLocKey, locInFunctionsKey, bigFunctionsLocPercKey, false); } - private static void compute(MeasureComputerContext context, String valueKey, String totalKey, String densityKey, - boolean calculateReminingPercent) { - final Component component = context.getComponent(); - - final Measure valueMeasure = context.getMeasure(valueKey); - final Measure totalMeasure = context.getMeasure(totalKey); - if (valueMeasure == null || totalMeasure == null) { - LOG.error("Component {}: not enough data to calcualte measure {}", context.getComponent().getKey(), densityKey); - return; - } - final Measure existingMeasure = context.getMeasure(densityKey); - if (existingMeasure != null) { - LOG.error("Component {}: measure {} already calculated, value = {}", component.getKey(), densityKey, - existingMeasure.getDoubleValue()); - return; - } - - int value = valueMeasure.getIntValue(); - final int total = totalMeasure.getIntValue(); - if (calculateReminingPercent) { - value = Integer.max(total - value, 0); - } - - double density = 0.0; - if (total >= value && total != 0) { - density = (double) value / (double) total * 100.0; - } - - LOG.info("Component {}: add measure {}, value {}", component.getKey(), densityKey, density); - context.addMeasure(densityKey, density); - } - } diff --git a/cxx-squid/src/main/java/org/sonar/cxx/api/CxxMetric.java b/cxx-squid/src/main/java/org/sonar/cxx/api/CxxMetric.java index a87e9974be..327e3f08e2 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/api/CxxMetric.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/api/CxxMetric.java @@ -34,13 +34,10 @@ public enum CxxMetric implements MetricDef { COMPLEXITY, COGNITIVE_COMPLEXITY, COMMENT_LINES, - PUBLIC_API, PUBLIC_UNDOCUMENTED_API, - COMPLEX_FUNCTIONS, COMPLEX_FUNCTIONS_LOC, - LOC_IN_FUNCTIONS, BIG_FUNCTIONS, BIG_FUNCTIONS_LOC; diff --git a/cxx-squid/src/main/java/org/sonar/cxx/channels/PreprocessorChannel.java b/cxx-squid/src/main/java/org/sonar/cxx/channels/PreprocessorChannel.java index c65663ecb5..612e48ccf1 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/channels/PreprocessorChannel.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/channels/PreprocessorChannel.java @@ -29,28 +29,6 @@ public class PreprocessorChannel extends Channel { private static final char EOF = (char) -1; - @Override - public boolean consume(CodeReader code, Lexer output) { - int line = code.getLinePosition(); - int column = code.getColumnPosition(); - - char ch = code.charAt(0); - if ((ch != '#')) { - return false; - } - - String tokenValue = read(code); - output.addToken(Token.builder() - .setLine(line) - .setColumn(column) - .setURI(output.getURI()) - .setValueAndOriginalValue(tokenValue) - .setType(CxxTokenType.PREPROCESSOR) - .build()); - - return true; - } - private static String read(CodeReader code) { StringBuilder sb = new StringBuilder(); char ch; @@ -104,4 +82,26 @@ private static void consumeComment(CodeReader code) { private static boolean isNewline(char ch) { return (ch == '\n') || (ch == '\r'); } + + @Override + public boolean consume(CodeReader code, Lexer output) { + int line = code.getLinePosition(); + int column = code.getColumnPosition(); + + char ch = code.charAt(0); + if ((ch != '#')) { + return false; + } + + String tokenValue = read(code); + output.addToken(Token.builder() + .setLine(line) + .setColumn(column) + .setURI(output.getURI()) + .setValueAndOriginalValue(tokenValue) + .setType(CxxTokenType.PREPROCESSOR) + .build()); + + return true; + } } diff --git a/cxx-squid/src/main/java/org/sonar/cxx/lexer/BackslashChannel.java b/cxx-squid/src/main/java/org/sonar/cxx/lexer/BackslashChannel.java index 77c840172d..8bb4003a37 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/lexer/BackslashChannel.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/lexer/BackslashChannel.java @@ -25,6 +25,10 @@ public class BackslashChannel extends Channel { + private static boolean isNewLine(char ch) { + return (ch == '\n') || (ch == '\r'); + } + @Override public boolean consume(CodeReader code, Lexer output) { char ch = (char) code.peek(); @@ -38,8 +42,4 @@ public boolean consume(CodeReader code, Lexer output) { return false; } - private static boolean isNewLine(char ch) { - return (ch == '\n') || (ch == '\r'); - } - } diff --git a/cxx-squid/src/main/java/org/sonar/cxx/lexer/CxxLexer.java b/cxx-squid/src/main/java/org/sonar/cxx/lexer/CxxLexer.java index 103d5c6a2b..3bbbf12f4a 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/lexer/CxxLexer.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/lexer/CxxLexer.java @@ -50,9 +50,6 @@ public final class CxxLexer { private static final String UD_SUFFIX = "([_a-zA-Z]([_a-zA-Z0-9]*+))"; private static final String HEXDIGIT_SEQUENCE = "([0-9a-fA-F]([']?+[0-9a-fA-F]++)*+)"; - private CxxLexer() { - } - public static Lexer create(Preprocessor... preprocessors) { return create(new CxxConfiguration(), preprocessors); } @@ -112,4 +109,7 @@ public static Lexer create(CxxConfiguration conf, Preprocessor... preprocessors) return builder.build(); } + + private CxxLexer() { + } } diff --git a/cxx-squid/src/main/java/org/sonar/cxx/parser/CxxGrammarImpl.java b/cxx-squid/src/main/java/org/sonar/cxx/parser/CxxGrammarImpl.java index a85e1f1d95..f8923420d9 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/parser/CxxGrammarImpl.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/parser/CxxGrammarImpl.java @@ -31,19 +31,15 @@ import org.sonar.sslr.grammar.LexerfulGrammarBuilder; /** - * Parsing expression grammar - * (PEG)[https://en.wikipedia.org/wiki/Parsing_expression_grammar] + * Parsing expression grammar (PEG)[https://en.wikipedia.org/wiki/Parsing_expression_grammar] * - * The fundamental difference between context-free grammars and parsing - * expression grammars is that the PEG's choice operator is ordered. If the - * first alternative succeeds, the second alternative is ignored. The - * consequence is that if a CFG is transliterated directly to a PEG, any - * ambiguity in the former is resolved by deterministically picking one parse - * tree from the possible parses. + * The fundamental difference between context-free grammars and parsing expression grammars is that the PEG's choice + * operator is ordered. If the first alternative succeeds, the second alternative is ignored. The consequence is that if + * a CFG is transliterated directly to a PEG, any ambiguity in the former is resolved by deterministically picking one + * parse tree from the possible parses. * - * By carefully choosing the order in which the grammar alternatives are - * specified, a programmer has a great deal of control over which parse tree is - * selected. + * By carefully choosing the order in which the grammar alternatives are specified, a programmer has a great deal of + * control over which parse tree is selected. * */ /** @@ -56,10 +52,8 @@ public enum CxxGrammarImpl implements GrammarRuleKey { BOOL, NULLPTR, LITERAL, - // Top level components translationUnit, - // Expressions primaryExpression, idExpression, @@ -108,7 +102,6 @@ public enum CxxGrammarImpl implements GrammarRuleKey { assignmentOperator, expression, constantExpression, - // Statements statement, emptyStatement, @@ -124,7 +117,6 @@ public enum CxxGrammarImpl implements GrammarRuleKey { forRangeInitializer, jumpStatement, declarationStatement, - // Declarations declarationSeq, declaration, @@ -194,7 +186,6 @@ public enum CxxGrammarImpl implements GrammarRuleKey { attributeArgumentClause, balancedTokenSeq, balancedToken, - // Declarators initDeclaratorList, initDeclarator, @@ -227,7 +218,6 @@ public enum CxxGrammarImpl implements GrammarRuleKey { initializerList, bracedInitList, exprOrBracedInitList, - // Classes className, classSpecifier, @@ -242,7 +232,6 @@ public enum CxxGrammarImpl implements GrammarRuleKey { virtSpecifierSeq, virtSpecifier, pureSpecifier, - // Derived classes baseClause, baseSpecifierList, @@ -250,7 +239,6 @@ public enum CxxGrammarImpl implements GrammarRuleKey { classOrDecltype, baseTypeSpecifier, accessSpecifier, - // Special member functions conversionFunctionId, conversionTypeId, @@ -259,12 +247,10 @@ public enum CxxGrammarImpl implements GrammarRuleKey { memInitializerList, memInitializer, memInitializerId, - // Overloading operatorFunctionId, overloadableOperator, literalOperatorId, - // Templates templateDeclaration, templateParameterList, @@ -288,7 +274,6 @@ public enum CxxGrammarImpl implements GrammarRuleKey { explicitInstantiation, explicitSpecialization, deductionGuide, - // Exception handling tryBlock, functionTryBlock, @@ -298,7 +283,6 @@ public enum CxxGrammarImpl implements GrammarRuleKey { throwExpression, typeIdList, noexceptSpecifier, - // Microsoft Extension: C++/CLI cliTopLevelVisibility, cliFinallyClause, @@ -342,11 +326,9 @@ public enum CxxGrammarImpl implements GrammarRuleKey { cliPositionArgument, cliNamedArgument, cliAttributeArgumentExpression, - // Microsoft Extension: Attributed ATL vcAtlDeclaration, vcAtlAttribute, - // CUDA extension cudaKernel; @@ -1758,7 +1740,7 @@ private static void overloading(LexerfulGrammarBuilder b) { b.sequence("(", ")"), b.sequence("[", "]") ) - // c++ todo missing optional < template-argument-list > ? + // c++ todo missing optional < template-argument-list > ? ); b.rule(literalOperatorId).is( diff --git a/cxx-squid/src/main/java/org/sonar/cxx/parser/CxxParser.java b/cxx-squid/src/main/java/org/sonar/cxx/parser/CxxParser.java index a496d579d0..1c2587d2ab 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/parser/CxxParser.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/parser/CxxParser.java @@ -36,9 +36,6 @@ public final class CxxParser { private static CxxPreprocessor cxxpp; - private CxxParser() { - } - public static void finishedParsing(File path) { cxxpp.finishedPreprocessing(path); } @@ -67,4 +64,7 @@ public static Parser create(SquidAstVisitorContext context, Cx .withLexer(CxxLexer.create(conf, cxxpp, new JoinStringsPreprocessor())) .build(); } + + private CxxParser() { + } } diff --git a/cxx-squid/src/main/java/org/sonar/cxx/preprocessor/CppLexer.java b/cxx-squid/src/main/java/org/sonar/cxx/preprocessor/CppLexer.java index 36c1ed188e..289336e2e1 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/preprocessor/CppLexer.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/preprocessor/CppLexer.java @@ -47,9 +47,6 @@ public final class CppLexer { private static final String UD_SUFFIX = "([_a-zA-Z]([_a-zA-Z0-9]*+))"; private static final String HEXDIGIT_SEQUENCE = "([0-9a-fA-F]([']?+[0-9a-fA-F]++)*+)"; - private CppLexer() { - } - public static Lexer create() { return create(new CxxConfiguration()); } @@ -68,16 +65,16 @@ public static Lexer create(CxxConfiguration conf) { .withChannel(new CharacterLiteralsChannel()) .withChannel(new StringLiteralsChannel()) // C++ Standard, Section 2.14.4 "Floating literals" - .withChannel(regexp(CxxTokenType.NUMBER, "[0-9]([']?+[0-9]++)*+\\.([0-9]([']?+[0-9]++)*+)*+" + .withChannel(regexp(CxxTokenType.NUMBER, "[0-9]([']?+[0-9]++)*+\\.([0-9]([']?+[0-9]++)*+)*+" + opt(EXPONENT) + opt(UD_SUFFIX))) - .withChannel(regexp(CxxTokenType.NUMBER, "\\.[0-9]([']?+[0-9]++)*+" + .withChannel(regexp(CxxTokenType.NUMBER, "\\.[0-9]([']?+[0-9]++)*+" + opt(EXPONENT) + opt(UD_SUFFIX))) .withChannel(regexp(CxxTokenType.NUMBER, "[0-9]([']?+[0-9]++)*+" + EXPONENT + opt(UD_SUFFIX))) - .withChannel(regexp(CxxTokenType.NUMBER, HEX_PREFIX + HEXDIGIT_SEQUENCE + .withChannel(regexp(CxxTokenType.NUMBER, HEX_PREFIX + HEXDIGIT_SEQUENCE + BINARY_EXPONENT + opt(UD_SUFFIX))) // since C++17 - .withChannel(regexp(CxxTokenType.NUMBER, HEX_PREFIX + HEXDIGIT_SEQUENCE + "." + .withChannel(regexp(CxxTokenType.NUMBER, HEX_PREFIX + HEXDIGIT_SEQUENCE + "." + BINARY_EXPONENT + opt(UD_SUFFIX))) // since C++17 - .withChannel(regexp(CxxTokenType.NUMBER, HEX_PREFIX + opt(HEXDIGIT_SEQUENCE) + "." + HEXDIGIT_SEQUENCE + .withChannel(regexp(CxxTokenType.NUMBER, HEX_PREFIX + opt(HEXDIGIT_SEQUENCE) + "." + HEXDIGIT_SEQUENCE + BINARY_EXPONENT + opt(UD_SUFFIX))) // since C++17 // C++ Standard, Section 2.14.2 "Integer literals" .withChannel(regexp(CxxTokenType.NUMBER, "[1-9]([']?+[0-9]++)*+" + opt(UD_SUFFIX))) // Decimal literals @@ -93,4 +90,7 @@ public static Lexer create(CxxConfiguration conf) { return builder.build(); } + + private CppLexer() { + } } diff --git a/cxx-squid/src/main/java/org/sonar/cxx/preprocessor/CppParser.java b/cxx-squid/src/main/java/org/sonar/cxx/preprocessor/CppParser.java index 16e937978d..3f61cd1ace 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/preprocessor/CppParser.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/preprocessor/CppParser.java @@ -25,9 +25,6 @@ public final class CppParser { - private CppParser() { - } - public static Parser create(CxxConfiguration conf) { return Parser.builder(CppGrammar.create()) .withLexer(CppLexer.create(conf)) @@ -42,4 +39,7 @@ public static Parser createConstantExpressionParser(CxxConfiguration co parser.setRootRule(grammar.rule(CppGrammar.constantExpression)); return parser; } + + private CppParser() { + } } 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 807a8000af..5f56baa541 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 @@ -89,152 +89,315 @@ public class CxxPreprocessor extends Preprocessor { = "Preprocessor: {} include directive error(s). This is only relevant if parser creates syntax errors." + " The preprocessor searches for include files in the with 'sonar.cxx.includeDirectories'" + " defined directories and order."; - private final CxxLanguage language; - private File currentContextFile; - private String rootFilePath; - - private static class State { - - private boolean skipPreprocessorDirectives; - private boolean conditionWasTrue; - private int conditionalInclusionCounter; - private File includeUnderAnalysis; + private static final Logger LOG = Loggers.get(CxxPreprocessor.class); + private static final String VARIADICPARAMETER = "__VA_ARGS__"; + private static int missingIncludeFilesCounter = 0; - public State(@Nullable File includeUnderAnalysis) { - this.skipPreprocessorDirectives = false; - this.conditionWasTrue = false; - this.conditionalInclusionCounter = 0; - this.includeUnderAnalysis = includeUnderAnalysis; + public static void finalReport() { + if (missingIncludeFilesCounter != 0) { + LOG.warn(MISSING_INCLUDE_MSG, missingIncludeFilesCounter); } + } - /** - * reset preprocessor state - */ - public final void reset() { - skipPreprocessorDirectives = false; - conditionWasTrue = false; - conditionalInclusionCounter = 0; - includeUnderAnalysis = null; - } + @VisibleForTesting + public static void resetReport() { + missingIncludeFilesCounter = 0; } - static class MismatchException extends Exception { + private static List stripEOF(List tokens) { + if (tokens.get(tokens.size() - 1).getType().equals(EOF)) { + return tokens.subList(0, tokens.size() - 1); + } else { + return tokens; + } + } - private static final long serialVersionUID = 1960113363232807009L; + private static String serialize(List tokens) { + return serialize(tokens, " "); + } - MismatchException(String message) { - super(message); + private static String serialize(List tokens, String spacer) { + StringJoiner js = new StringJoiner(spacer); + for (Token t : tokens) { + js.add(t.getValue()); } + return js.toString(); + } - MismatchException(Throwable cause) { - super(cause); + private static int matchArguments(List tokens, List arguments) { + List rest = new ArrayList<>(tokens); + try { + rest = match(rest, "("); + } catch (MismatchException me) { + return 0; } - MismatchException(String message, Throwable cause) { - super(message, cause); + try { + do { + rest = matchArgument(rest, arguments); + try { + rest = match(rest, ","); + } catch (MismatchException me) { + break; + } + } while (true); + } catch (MismatchException me) { + } + try { + rest = match(rest, ")"); + } catch (MismatchException me) { + LOG.error("MismatchException : '{}' rest: '{}'", me.getMessage(), rest); + return 0; } + return tokens.size() - rest.size(); + } - MismatchException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { - super(message, cause, enableSuppression, writableStackTrace); + private static List match(List tokens, String str) throws MismatchException { + if (!tokens.get(0).getValue().equals(str)) { + throw new MismatchException("Mismatch: expected '" + str + "' got: '" + + tokens.get(0).getValue() + "'" + " [" + tokens.get(0).getURI() + "(" + + tokens.get(0).getLine() + "," + tokens.get(0).getColumn() + ")]"); } + return tokens.subList(1, tokens.size()); } - static final class Macro { + private static List matchArgument(List tokens, List arguments) throws MismatchException { + int nestingLevel = 0; + int tokensConsumed = 0; + int noTokens = tokens.size(); + Token firstToken = tokens.get(0); + Token currToken = firstToken; + String curr = currToken.getValue(); + List matchedTokens = new LinkedList<>(); - private final String name; - private final List params; - private final List body; - private final boolean isVariadic; + while (true) { + if (nestingLevel == 0 && (",".equals(curr) || ")".equals(curr))) { + if (tokensConsumed > 0) { + arguments.add(Token.builder() + .setLine(firstToken.getLine()) + .setColumn(firstToken.getColumn()) + .setURI(firstToken.getURI()) + .setValueAndOriginalValue(serialize(matchedTokens).trim()) + .setType(STRING) + .build()); + } + return tokens.subList(tokensConsumed, noTokens); + } - public Macro(String name, @Nullable List params, @Nullable List body, boolean variadic) { - this.name = name; - if (params == null) { - this.params = null; - } else { - this.params = params.stream().collect(Collectors.toList()); + if ("(".equals(curr)) { + nestingLevel++; + } else if (")".equals(curr)) { + nestingLevel--; } - if (body == null) { - this.body = null; - } else { - this.body = body.stream().collect(Collectors.toList()); + + tokensConsumed++; + if (tokensConsumed == noTokens) { + throw new MismatchException("reached the end of the stream while matching a macro argument"); } - this.isVariadic = variadic; + + matchedTokens.add(currToken); + currToken = tokens.get(tokensConsumed); + curr = currToken.getValue(); } + } - @Override - public String toString() { - return name - + (params == null ? "" : "(" + serialize(params, ", ") + (isVariadic ? "..." : "") + ")") - + " -> '" + serialize(body) + "'"; + private static List evaluateHashhashOperators(List tokens) { + List newTokens = new ArrayList<>(); + + Iterator it = tokens.iterator(); + while (it.hasNext()) { + Token curr = it.next(); + if ("##".equals(curr.getValue())) { + Token pred = predConcatToken(newTokens); + Token succ = succConcatToken(it); + if (pred != null && succ != null) { + newTokens.add(Token.builder() + .setLine(pred.getLine()) + .setColumn(pred.getColumn()) + .setURI(pred.getURI()) + .setValueAndOriginalValue(pred.getValue() + succ.getValue()) + .setType(pred.getType()) + .setGeneratedCode(true) + .build()); + } else { + LOG.error("Missing data : succ ='{}' or pred = '{}'", succ, pred); + } + } else { + newTokens.add(curr); + } } - public boolean checkArgumentsCount(int count) { - return isVariadic - ? count >= params.size() - 1 - : count == params.size(); + return newTokens; + } + + @Nullable + private static Token predConcatToken(List tokens) { + while (!tokens.isEmpty()) { + Token last = tokens.remove(tokens.size() - 1); + if (!last.getType().equals(WS)) { + if (!tokens.isEmpty()) { + Token pred = tokens.get(tokens.size() - 1); + if (!pred.getType().equals(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; + } } + return null; } - private static final Logger LOG = Loggers.get(CxxPreprocessor.class); - private Parser pplineParser; - private final MapChain fixedMacros = new MapChain<>(); - private MapChain unitMacros; - private final Set analysedFiles = new HashSet<>(); - private SourceCodeProvider codeProvider = new SourceCodeProvider(); - private SourceCodeProvider unitCodeProvider; - private SquidAstVisitorContext context; - private List cFilesPatterns; - private CxxConfiguration conf; - private CxxCompilationUnitSettings compilationUnitSettings; - private static final String VARIADICPARAMETER = "__VA_ARGS__"; + @Nullable + private static Token succConcatToken(Iterator it) { + Token succ = null; + while (it.hasNext()) { + succ = it.next(); + if (!"##".equals(succ.getValue()) && !succ.getType().equals(WS)) { + break; + } + } + return succ; + } - public static class Include { + private static String quote(String str) { + StringBuilder result = new StringBuilder(2 * str.length()); + boolean addBlank = false; + boolean ignoreNextBlank = false; + for (int i = 0; i < str.length(); i++) { + char c = str.charAt(i); + if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_') { // token + if (addBlank) { + result.append(' '); + addBlank = false; + } + result.append(c); + } else { // special characters + switch (c) { + case ' ': + if (ignoreNextBlank) { + ignoreNextBlank = false; + } else { + addBlank = true; + } + break; + case '\"': + if (addBlank) { + result.append(' '); + addBlank = false; + } + result.append("\\\""); + break; + case '\\': + result.append("\\\\"); + addBlank = false; + ignoreNextBlank = true; + break; + default: // operator + result.append(c); + addBlank = false; + ignoreNextBlank = true; + break; + } + } + } + return result.toString(); + } - private final int line; - private final String path; + private static String encloseWithQuotes(String str) { + return "\"" + str + "\""; + } - Include(int line, String path) { - this.line = line; - this.path = path; + private static List reallocate(List tokens, Token token) { + List reallocated = new LinkedList<>(); + int currColumn = token.getColumn(); + for (Token t : tokens) { + reallocated.add(Token.builder() + .setLine(token.getLine()) + .setColumn(currColumn) + .setURI(token.getURI()) + .setValueAndOriginalValue(t.getValue()) + .setType(t.getType()) + .setGeneratedCode(true) + .build()); + currColumn += t.getValue().length() + 1; } - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } + return reallocated; + } - Include that = (Include) o; + private static Macro parseMacroDefinition(AstNode defineLineAst) { + AstNode ast = defineLineAst.getFirstChild(); + AstNode nameNode = ast.getFirstDescendant(CppGrammar.ppToken); + String macroName = nameNode.getTokenValue(); - if (line != that.line) { - return false; - } - if (path != null ? !path.equals(that.path) : that.path != null) { - return false; - } + AstNode paramList = ast.getFirstDescendant(CppGrammar.parameterList); + List macroParams = paramList == null + ? "objectlikeMacroDefinition".equals(ast.getName()) ? null : new LinkedList<>() : getParams(paramList); - return true; + AstNode vaargs = ast.getFirstDescendant(CppGrammar.variadicparameter); + if ((vaargs != null) && (macroParams != null)) { + AstNode identifier = vaargs.getFirstChild(IDENTIFIER); + macroParams.add(identifier == null + ? Token.builder() + .setLine(vaargs.getToken().getLine()) + .setColumn(vaargs.getToken().getColumn()) + .setURI(vaargs.getToken().getURI()) + .setValueAndOriginalValue(VARIADICPARAMETER) + .setType(IDENTIFIER) + .setGeneratedCode(true) + .build() + : identifier.getToken()); } - @Override - public int hashCode() { - return 31 * line + (path != null ? path.hashCode() : 0); - } + AstNode replList = ast.getFirstDescendant(CppGrammar.replacementList); + List macroBody = replList == null + ? new LinkedList<>() : replList.getTokens().subList(0, replList.getTokens().size() - 1); - public String getPath() { - return path; - } + return new Macro(macroName, macroParams, macroBody, vaargs != null); + } - public int getLine() { - return line; + private static List getParams(AstNode identListAst) { + List params = new ArrayList<>(); + for (AstNode node : identListAst.getChildren(IDENTIFIER)) { + params.add(node.getToken()); } + + return params; + } + + private static String getMacroName(AstNode ast) { + return ast.getFirstDescendant(IDENTIFIER).getTokenValue(); + } + + private static String stripQuotes(String str) { + return str.substring(1, str.length() - 1); } + private final CxxLanguage language; + private File currentContextFile; + private String rootFilePath; + + private Parser pplineParser; + private final MapChain fixedMacros = new MapChain<>(); + private MapChain unitMacros; + private final Set analysedFiles = new HashSet<>(); + private SourceCodeProvider codeProvider = new SourceCodeProvider(); + private SourceCodeProvider unitCodeProvider; + private SquidAstVisitorContext context; + private List cFilesPatterns; + private CxxConfiguration conf; + private CxxCompilationUnitSettings compilationUnitSettings; private final Multimap includedFiles = HashMultimap.create(); private final Multimap missingIncludeFiles = HashMultimap.create(); - private static int missingIncludeFilesCounter = 0; private State currentFileState = new State(null); private final Deque globalStateStack = new LinkedList<>(); @@ -290,17 +453,6 @@ public CxxPreprocessor(SquidAstVisitorContext context, } } - public static void finalReport() { - if (missingIncludeFilesCounter != 0) { - LOG.warn(MISSING_INCLUDE_MSG, missingIncludeFilesCounter); - } - } - - @VisibleForTesting - public static void resetReport() { - missingIncludeFilesCounter = 0; - } - private void registerMacros(Map standardMacros) { for (Map.Entry entry : standardMacros.entrySet()) { Token bodyToken; @@ -533,7 +685,7 @@ PreprocessorAction handleIfLine(AstNode ast, Token token, String filename) { try { currentFileState.skipPreprocessorDirectives = false; currentFileState.skipPreprocessorDirectives = !ExpressionEvaluator.eval(conf, this, - ast.getFirstDescendant(CppGrammar.constantExpression)); + ast.getFirstDescendant(CppGrammar.constantExpression)); } catch (EvaluationException e) { LOG.error("[{}:{}]: error evaluating the expression {} assume 'true' ...", filename, token.getLine(), token.getValue()); @@ -568,7 +720,7 @@ PreprocessorAction handleElIfLine(AstNode ast, Token token, String filename) { } currentFileState.skipPreprocessorDirectives = false; currentFileState.skipPreprocessorDirectives = !ExpressionEvaluator.eval(conf, this, - ast.getFirstDescendant(CppGrammar.constantExpression)); + ast.getFirstDescendant(CppGrammar.constantExpression)); } catch (EvaluationException e) { LOG.error("[{}:{}]: error evaluating the expression {} assume 'true' ...", filename, token.getLine(), token.getValue()); @@ -864,103 +1016,6 @@ private List expandMacro(String macroName, String macroExpression) { return tokens; } - private static List stripEOF(List tokens) { - if (tokens.get(tokens.size() - 1).getType().equals(EOF)) { - return tokens.subList(0, tokens.size() - 1); - } else { - return tokens; - } - } - - private static String serialize(List tokens) { - return serialize(tokens, " "); - } - - private static String serialize(List tokens, String spacer) { - StringJoiner js = new StringJoiner(spacer); - for (Token t : tokens) { - js.add(t.getValue()); - } - return js.toString(); - } - - private static int matchArguments(List tokens, List arguments) { - List rest = new ArrayList<>(tokens); - try { - rest = match(rest, "("); - } catch (MismatchException me) { - return 0; - } - - try { - do { - rest = matchArgument(rest, arguments); - try { - rest = match(rest, ","); - } catch (MismatchException me) { - break; - } - } while (true); - } catch (MismatchException me) { - } - try { - rest = match(rest, ")"); - } catch (MismatchException me) { - LOG.error("MismatchException : '{}' rest: '{}'", me.getMessage(), rest); - return 0; - } - return tokens.size() - rest.size(); - } - - private static List match(List tokens, String str) throws MismatchException { - if (!tokens.get(0).getValue().equals(str)) { - throw new MismatchException("Mismatch: expected '" + str + "' got: '" - + tokens.get(0).getValue() + "'" + " [" + tokens.get(0).getURI() + "(" - + tokens.get(0).getLine() + "," + tokens.get(0).getColumn() + ")]"); - } - return tokens.subList(1, tokens.size()); - } - - private static List matchArgument(List tokens, List arguments) throws MismatchException { - int nestingLevel = 0; - int tokensConsumed = 0; - int noTokens = tokens.size(); - Token firstToken = tokens.get(0); - Token currToken = firstToken; - String curr = currToken.getValue(); - List matchedTokens = new LinkedList<>(); - - while (true) { - if (nestingLevel == 0 && (",".equals(curr) || ")".equals(curr))) { - if (tokensConsumed > 0) { - arguments.add(Token.builder() - .setLine(firstToken.getLine()) - .setColumn(firstToken.getColumn()) - .setURI(firstToken.getURI()) - .setValueAndOriginalValue(serialize(matchedTokens).trim()) - .setType(STRING) - .build()); - } - return tokens.subList(tokensConsumed, noTokens); - } - - if ("(".equals(curr)) { - nestingLevel++; - } else if (")".equals(curr)) { - nestingLevel--; - } - - tokensConsumed++; - if (tokensConsumed == noTokens) { - throw new MismatchException("reached the end of the stream while matching a macro argument"); - } - - matchedTokens.add(currToken); - currToken = tokens.get(tokensConsumed); - curr = currToken.getValue(); - } - } - private List replaceParams(List body, List parameters, List arguments) { // Replace all parameters by according arguments // "Stringify" the argument if the according parameter is preceded by an # @@ -1027,190 +1082,56 @@ private List replaceParams(List body, List parameters, List } else { if (i > 0 && "#".equals(body.get(i - 1).getValue())) { // If the token is a macro, the macro is not expanded - the macro - // name is converted into a string. - newTokens.remove(newTokens.size() - 1); - newValue = encloseWithQuotes(quote(replacement.getValue())); - } else { - // otherwise the arguments have to be fully expanded before - // expanding the body of the macro - newValue = serialize(expandMacro("", replacement.getValue())); - } - } - - if (newValue.isEmpty() && VARIADICPARAMETER.equals(curr.getValue())) { - // the Visual C++ implementation will suppress a trailing comma - // if no arguments are passed to the ellipsis - for (int n = newTokens.size() - 1; n != 0; n = newTokens.size() - 1) { - if (newTokens.get(n).getType().equals(WS)) { - newTokens.remove(n); - } else if (newTokens.get(n).getType().equals(COMMA)) { - newTokens.remove(n); - break; - } else { - break; - } - } - } else { - newTokens.add(Token.builder().setLine(replacement.getLine()).setColumn(replacement.getColumn()) - .setURI(replacement.getURI()).setValueAndOriginalValue(newValue).setType(replacement.getType()) - .setGeneratedCode(true).build()); - } - } - } - } - - // replace # with "" if sequence HASH BR occurs for body HASH __VA_ARGS__ - if (newTokens.size() > 3 && newTokens.get(newTokens.size() - 2).getType().equals(HASH) - && newTokens.get(newTokens.size() - 1).getType().equals(BR_RIGHT)) { - for (int n = newTokens.size() - 2; n != 0; n--) { - if (newTokens.get(n).getType().equals(WS)) { - newTokens.remove(n); - } else if (newTokens.get(n).getType().equals(HASH)) { - newTokens.remove(n); - newTokens.add(n, Token.builder().setLine(newTokens.get(n).getLine()).setColumn(newTokens.get(n).getColumn()) - .setURI(newTokens.get(n).getURI()).setValueAndOriginalValue("\"\"").setType(STRING) - .setGeneratedCode(true).build()); - break; - } else { - break; - } - } - } - return newTokens; - } - - private static List evaluateHashhashOperators(List tokens) { - List newTokens = new ArrayList<>(); - - Iterator it = tokens.iterator(); - while (it.hasNext()) { - Token curr = it.next(); - if ("##".equals(curr.getValue())) { - Token pred = predConcatToken(newTokens); - Token succ = succConcatToken(it); - if (pred != null && succ != null) { - newTokens.add(Token.builder() - .setLine(pred.getLine()) - .setColumn(pred.getColumn()) - .setURI(pred.getURI()) - .setValueAndOriginalValue(pred.getValue() + succ.getValue()) - .setType(pred.getType()) - .setGeneratedCode(true) - .build()); - } else { - LOG.error("Missing data : succ ='{}' or pred = '{}'", succ, pred); - } - } else { - newTokens.add(curr); - } - } - - return newTokens; - } - - @Nullable - private static Token predConcatToken(List tokens) { - while (!tokens.isEmpty()) { - Token last = tokens.remove(tokens.size() - 1); - if (!last.getType().equals(WS)) { - if (!tokens.isEmpty()) { - Token pred = tokens.get(tokens.size() - 1); - if (!pred.getType().equals(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; - } - } - return null; - } - - @Nullable - private static Token succConcatToken(Iterator it) { - Token succ = null; - while (it.hasNext()) { - succ = it.next(); - if (!"##".equals(succ.getValue()) && !succ.getType().equals(WS)) { - break; - } - } - return succ; - } - - private static String quote(String str) { - StringBuilder result = new StringBuilder(2 * str.length()); - boolean addBlank = false; - boolean ignoreNextBlank = false; - for (int i = 0; i < str.length(); i++) { - char c = str.charAt(i); - if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_') { // token - if (addBlank) { - result.append(' '); - addBlank = false; - } - result.append(c); - } else { // special characters - switch (c) { - case ' ': - if (ignoreNextBlank) { - ignoreNextBlank = false; + // name is converted into a string. + newTokens.remove(newTokens.size() - 1); + newValue = encloseWithQuotes(quote(replacement.getValue())); } else { - addBlank = true; + // otherwise the arguments have to be fully expanded before + // expanding the body of the macro + newValue = serialize(expandMacro("", replacement.getValue())); } - break; - case '\"': - if (addBlank) { - result.append(' '); - addBlank = false; + } + + if (newValue.isEmpty() && VARIADICPARAMETER.equals(curr.getValue())) { + // the Visual C++ implementation will suppress a trailing comma + // if no arguments are passed to the ellipsis + for (int n = newTokens.size() - 1; n != 0; n = newTokens.size() - 1) { + if (newTokens.get(n).getType().equals(WS)) { + newTokens.remove(n); + } else if (newTokens.get(n).getType().equals(COMMA)) { + newTokens.remove(n); + break; + } else { + break; + } } - result.append("\\\""); - break; - case '\\': - result.append("\\\\"); - addBlank = false; - ignoreNextBlank = true; - break; - default: // operator - result.append(c); - addBlank = false; - ignoreNextBlank = true; - break; + } else { + newTokens.add(Token.builder().setLine(replacement.getLine()).setColumn(replacement.getColumn()) + .setURI(replacement.getURI()).setValueAndOriginalValue(newValue).setType(replacement.getType()) + .setGeneratedCode(true).build()); + } } } } - return result.toString(); - } - - private static String encloseWithQuotes(String str) { - return "\"" + str + "\""; - } - private static List reallocate(List tokens, Token token) { - List reallocated = new LinkedList<>(); - int currColumn = token.getColumn(); - for (Token t : tokens) { - reallocated.add(Token.builder() - .setLine(token.getLine()) - .setColumn(currColumn) - .setURI(token.getURI()) - .setValueAndOriginalValue(t.getValue()) - .setType(t.getType()) - .setGeneratedCode(true) - .build()); - currColumn += t.getValue().length() + 1; + // replace # with "" if sequence HASH BR occurs for body HASH __VA_ARGS__ + if (newTokens.size() > 3 && newTokens.get(newTokens.size() - 2).getType().equals(HASH) + && newTokens.get(newTokens.size() - 1).getType().equals(BR_RIGHT)) { + for (int n = newTokens.size() - 2; n != 0; n--) { + if (newTokens.get(n).getType().equals(WS)) { + newTokens.remove(n); + } else if (newTokens.get(n).getType().equals(HASH)) { + newTokens.remove(n); + newTokens.add(n, Token.builder().setLine(newTokens.get(n).getLine()).setColumn(newTokens.get(n).getColumn()) + .setURI(newTokens.get(n).getURI()).setValueAndOriginalValue("\"\"").setType(STRING) + .setGeneratedCode(true).build()); + break; + } else { + break; + } + } } - - return reallocated; + return newTokens; } private Macro parseMacroDefinition(String macroDef) { @@ -1218,46 +1139,6 @@ private Macro parseMacroDefinition(String macroDef) { .getFirstDescendant(CppGrammar.defineLine)); } - private static Macro parseMacroDefinition(AstNode defineLineAst) { - AstNode ast = defineLineAst.getFirstChild(); - AstNode nameNode = ast.getFirstDescendant(CppGrammar.ppToken); - String macroName = nameNode.getTokenValue(); - - AstNode paramList = ast.getFirstDescendant(CppGrammar.parameterList); - List macroParams = paramList == null - ? "objectlikeMacroDefinition".equals(ast.getName()) ? null : new LinkedList<>() : getParams(paramList); - - AstNode vaargs = ast.getFirstDescendant(CppGrammar.variadicparameter); - if ((vaargs != null) && (macroParams != null)) { - AstNode identifier = vaargs.getFirstChild(IDENTIFIER); - macroParams.add(identifier == null - ? Token.builder() - .setLine(vaargs.getToken().getLine()) - .setColumn(vaargs.getToken().getColumn()) - .setURI(vaargs.getToken().getURI()) - .setValueAndOriginalValue(VARIADICPARAMETER) - .setType(IDENTIFIER) - .setGeneratedCode(true) - .build() - : identifier.getToken()); - } - - AstNode replList = ast.getFirstDescendant(CppGrammar.replacementList); - List macroBody = replList == null - ? new LinkedList<>() : replList.getTokens().subList(0, replList.getTokens().size() - 1); - - return new Macro(macroName, macroParams, macroBody, vaargs != null); - } - - private static List getParams(AstNode identListAst) { - List params = new ArrayList<>(); - for (AstNode node : identListAst.getChildren(IDENTIFIER)) { - params.add(node.getToken()); - } - - return params; - } - private File findIncludedFile(AstNode ast, Token token, String currFileName) { String includedFileName = null; File includedFile = null; @@ -1328,14 +1209,6 @@ private File findIncludedFile(AstNode ast, Token token, String currFileName) { return includedFile; } - private static String getMacroName(AstNode ast) { - return ast.getFirstDescendant(IDENTIFIER).getTokenValue(); - } - - private static String stripQuotes(String str) { - return str.substring(1, str.length() - 1); - } - private File getFileUnderAnalysis() { if (currentFileState.includeUnderAnalysis == null) { return context.getFile(); @@ -1343,6 +1216,133 @@ private File getFileUnderAnalysis() { return currentFileState.includeUnderAnalysis; } + private static class State { + + private boolean skipPreprocessorDirectives; + private boolean conditionWasTrue; + private int conditionalInclusionCounter; + private File includeUnderAnalysis; + + public State(@Nullable File includeUnderAnalysis) { + this.skipPreprocessorDirectives = false; + this.conditionWasTrue = false; + this.conditionalInclusionCounter = 0; + this.includeUnderAnalysis = includeUnderAnalysis; + } + + /** + * reset preprocessor state + */ + public final void reset() { + skipPreprocessorDirectives = false; + conditionWasTrue = false; + conditionalInclusionCounter = 0; + includeUnderAnalysis = null; + } + } + + static class MismatchException extends Exception { + + private static final long serialVersionUID = 1960113363232807009L; + + MismatchException(String message) { + super(message); + } + + MismatchException(Throwable cause) { + super(cause); + } + + MismatchException(String message, Throwable cause) { + super(message, cause); + } + + MismatchException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + } + + static final class Macro { + + private final String name; + private final List params; + private final List body; + private final boolean isVariadic; + + public Macro(String name, @Nullable List params, @Nullable List body, boolean variadic) { + this.name = name; + if (params == null) { + this.params = null; + } else { + this.params = params.stream().collect(Collectors.toList()); + } + if (body == null) { + this.body = null; + } else { + this.body = body.stream().collect(Collectors.toList()); + } + this.isVariadic = variadic; + } + + @Override + public String toString() { + return name + + (params == null ? "" : "(" + serialize(params, ", ") + (isVariadic ? "..." : "") + ")") + + " -> '" + serialize(body) + "'"; + } + + public boolean checkArgumentsCount(int count) { + return isVariadic + ? count >= params.size() - 1 + : count == params.size(); + } + } + + public static class Include { + + private final int line; + private final String path; + + Include(int line, String path) { + this.line = line; + this.path = path; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + Include that = (Include) o; + + if (line != that.line) { + return false; + } + if (path != null ? !path.equals(that.path) : that.path != null) { + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 31 * line + (path != null ? path.hashCode() : 0); + } + + public String getPath() { + return path; + } + + public int getLine() { + return line; + } + } + static class PreprocessorRuntimeException extends RuntimeException { /** diff --git a/cxx-squid/src/main/java/org/sonar/cxx/preprocessor/EvaluationException.java b/cxx-squid/src/main/java/org/sonar/cxx/preprocessor/EvaluationException.java index b248cdc9be..081bbf0f4f 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/preprocessor/EvaluationException.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/preprocessor/EvaluationException.java @@ -20,6 +20,7 @@ package org.sonar.cxx.preprocessor; public class EvaluationException extends RuntimeException { + private static final long serialVersionUID = 336015352128912495L; public EvaluationException(String message) { diff --git a/cxx-squid/src/main/java/org/sonar/cxx/preprocessor/ExpressionEvaluator.java b/cxx-squid/src/main/java/org/sonar/cxx/preprocessor/ExpressionEvaluator.java index 8e5371305d..ac677b4010 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/preprocessor/ExpressionEvaluator.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/preprocessor/ExpressionEvaluator.java @@ -29,9 +29,7 @@ import java.util.Deque; import java.util.LinkedList; import java.util.List; - import javax.annotation.Nullable; - import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.cxx.CxxConfiguration; @@ -43,6 +41,118 @@ public final class ExpressionEvaluator { private static final BigInteger UINT64_MAX = new BigInteger("FFFFFFFFFFFFFFFF", 16); private static final Logger LOG = Loggers.get(ExpressionEvaluator.class); + public static boolean eval(CxxConfiguration conf, CxxPreprocessor preprocessor, String constExpr) { + return new ExpressionEvaluator(conf, preprocessor).evalToBoolean(constExpr, null); + } + + public static boolean eval(CxxConfiguration conf, CxxPreprocessor preprocessor, AstNode constExpr) { + return new ExpressionEvaluator(conf, preprocessor).evalToBoolean(constExpr); + } + + // ///////////////// Primitives ////////////////////// + private static BigInteger evalBool(String boolValue) { + return "true".equalsIgnoreCase(boolValue) ? BigInteger.ONE : BigInteger.ZERO; + } + + private static BigInteger evalNumber(String intValue) { + // the if expressions aren't allowed to contain floats + BigInteger number; + try { + number = decode(intValue); + } catch (java.lang.NumberFormatException nfe) { + LOG.warn("Cannot decode the number '{}' falling back to value '{}' instead", intValue, BigInteger.ONE); + number = BigInteger.ONE; + } + + return number; + } + + private static BigInteger evalCharacter(String charValue) { + // TODO: replace this simplification by something more sane + return "'\0'".equals(charValue) ? BigInteger.ZERO : BigInteger.ONE; + } + + private static AstNode getNextOperand(@Nullable AstNode node) { + AstNode sibling = node; + if (sibling != null) { + sibling = sibling.getNextSibling(); + if (sibling != null) { + sibling = sibling.getNextSibling(); + } + } + return sibling; + } + + public static BigInteger decode(String number) { + + // This function is only responsible for providing a string and a radix to BigInteger. + // The lexer ensures that the number has a valid format. + int radix = 10; + int begin = 0; + if (number.length() > 2) { + if (number.charAt(0) == '0') { + switch (number.charAt(1)) { + case 'x': + case 'X': + radix = 16; // 0x... + begin = 2; + break; + case 'b': + case 'B': + radix = 2; // 0b... + begin = 2; + break; + default: + radix = 8; // 0... + break; + } + } + } + + StringBuilder sb = new StringBuilder(number.length()); + boolean suffix = false; + for (int index = begin; index < number.length() && !suffix; index++) { + char c = number.charAt(index); + switch (c) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + sb.append(c); + break; + + case '\'': // ignore digit separator + break; + + default: // suffix + suffix = true; + break; + } + } + + return new BigInteger(sb.toString(), radix); + } + private final Parser parser; private final CxxPreprocessor preprocessor; private final Deque macroEvaluationStack; @@ -54,14 +164,6 @@ private ExpressionEvaluator(CxxConfiguration conf, CxxPreprocessor preprocessor) macroEvaluationStack = new LinkedList<>(); } - public static boolean eval(CxxConfiguration conf, CxxPreprocessor preprocessor, String constExpr) { - return new ExpressionEvaluator(conf, preprocessor).evalToBoolean(constExpr, null); - } - - public static boolean eval(CxxConfiguration conf, CxxPreprocessor preprocessor, AstNode constExpr) { - return new ExpressionEvaluator(conf, preprocessor).evalToBoolean(constExpr); - } - private BigInteger evalToInt(String constExpr, @Nullable AstNode exprAst) { AstNode constExprAst = null; try { @@ -188,40 +290,6 @@ private BigInteger evalComplexAst(AstNode exprAst) { } } - // ///////////////// Primitives ////////////////////// - private static BigInteger evalBool(String boolValue) { - return "true".equalsIgnoreCase(boolValue) ? BigInteger.ONE : BigInteger.ZERO; - } - - private static BigInteger evalNumber(String intValue) { - // the if expressions aren't allowed to contain floats - BigInteger number; - try { - number = decode(intValue); - } catch (java.lang.NumberFormatException nfe) { - LOG.warn("Cannot decode the number '{}' falling back to value '{}' instead", intValue, BigInteger.ONE); - number = BigInteger.ONE; - } - - return number; - } - - private static BigInteger evalCharacter(String charValue) { - // TODO: replace this simplification by something more sane - return "'\0'".equals(charValue) ? BigInteger.ZERO : BigInteger.ONE; - } - - private static AstNode getNextOperand(@Nullable AstNode node) { - AstNode sibling = node; - if (sibling != null) { - sibling = sibling.getNextSibling(); - if (sibling != null) { - sibling = sibling.getNextSibling(); - } - } - return sibling; - } - // ////////////// logical expressions /////////////////////////// private BigInteger evalLogicalOrExpression(AstNode exprAst) { AstNode operand = exprAst.getFirstChild(); @@ -497,73 +565,4 @@ private BigInteger evalHasIncludeExpression(AstNode exprAst) { return preprocessor.expandHasIncludeExpression(exprAst) ? BigInteger.ONE : BigInteger.ZERO; } - public static BigInteger decode(String number) { - - // This function is only responsible for providing a string and a radix to BigInteger. - // The lexer ensures that the number has a valid format. - int radix = 10; - int begin = 0; - if (number.length() > 2) { - if (number.charAt(0) == '0') { - switch (number.charAt(1)) { - case 'x': - case 'X': - radix = 16; // 0x... - begin = 2; - break; - case 'b': - case 'B': - radix = 2; // 0b... - begin = 2; - break; - default: - radix = 8; // 0... - break; - } - } - } - - StringBuilder sb = new StringBuilder(number.length()); - boolean suffix = false; - for (int index = begin; index < number.length() && !suffix; index++) { - char c = number.charAt(index); - switch (c) { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - - case 'a': - case 'b': - case 'c': - case 'd': - case 'e': - case 'f': - - case 'A': - case 'B': - case 'C': - case 'D': - case 'E': - case 'F': - sb.append(c); - break; - - case '\'': // ignore digit separator - break; - - default: // suffix - suffix = true; - break; - } - } - - return new BigInteger(sb.toString(), radix); - } } diff --git a/cxx-squid/src/main/java/org/sonar/cxx/preprocessor/IncludeLexer.java b/cxx-squid/src/main/java/org/sonar/cxx/preprocessor/IncludeLexer.java index 0b62ce1cf3..c58c11a9a1 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/preprocessor/IncludeLexer.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/preprocessor/IncludeLexer.java @@ -29,9 +29,6 @@ public final class IncludeLexer { - private IncludeLexer() { - } - public static Lexer create(Preprocessor... preprocessors) { return create(new CxxConfiguration(), preprocessors); } @@ -51,4 +48,7 @@ public static Lexer create(CxxConfiguration conf, Preprocessor... preprocessors) return builder.build(); } + + private IncludeLexer() { + } } diff --git a/cxx-squid/src/main/java/org/sonar/cxx/preprocessor/JoinStringsPreprocessor.java b/cxx-squid/src/main/java/org/sonar/cxx/preprocessor/JoinStringsPreprocessor.java index 1f11c7d8a1..848d3d169b 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/preprocessor/JoinStringsPreprocessor.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/preprocessor/JoinStringsPreprocessor.java @@ -19,19 +19,31 @@ */ package org.sonar.cxx.preprocessor; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.sonar.cxx.api.CxxTokenType; - import com.sonar.sslr.api.Preprocessor; import com.sonar.sslr.api.PreprocessorAction; import com.sonar.sslr.api.Token; import com.sonar.sslr.api.Trivia; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.sonar.cxx.api.CxxTokenType; public class JoinStringsPreprocessor extends Preprocessor { + private static String stripQuotes(String str) { + return str.substring(str.indexOf('"') + 1, str.lastIndexOf('"')); + } + + private static String concatenateStringLiterals(List concatenatedTokens) { + StringBuilder sb = new StringBuilder(); + sb.append("\""); + for (Token t : concatenatedTokens) { + sb.append(stripQuotes(t.getValue())); + } + sb.append("\""); + return sb.toString(); + } + @Override public PreprocessorAction process(List tokens) { @@ -56,24 +68,10 @@ public PreprocessorAction process(List tokens) { Trivia trivia = Trivia.createSkippedText(concatenatedTokens); Token firstToken = tokens.get(0); Token tokenToInject = Token.builder().setLine(firstToken.getLine()).setColumn(firstToken.getColumn()) - .setURI(firstToken.getURI()).setType(CxxTokenType.STRING).setValueAndOriginalValue(concatenatedLiteral) - .setGeneratedCode(isGenerated).build(); + .setURI(firstToken.getURI()).setType(CxxTokenType.STRING).setValueAndOriginalValue(concatenatedLiteral) + .setGeneratedCode(isGenerated).build(); return new PreprocessorAction(nrOfAdjacentStringLiterals, Collections.singletonList(trivia), - Collections.singletonList(tokenToInject)); - } - - private static String stripQuotes(String str) { - return str.substring(str.indexOf('"') + 1, str.lastIndexOf('"')); - } - - private static String concatenateStringLiterals(List concatenatedTokens) { - StringBuilder sb = new StringBuilder(); - sb.append("\""); - for (Token t : concatenatedTokens) { - sb.append(stripQuotes(t.getValue())); - } - sb.append("\""); - return sb.toString(); + Collections.singletonList(tokenToInject)); } } diff --git a/cxx-squid/src/main/java/org/sonar/cxx/preprocessor/SourceCodeProvider.java b/cxx-squid/src/main/java/org/sonar/cxx/preprocessor/SourceCodeProvider.java index c76e893178..2a28afa1d3 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/preprocessor/SourceCodeProvider.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/preprocessor/SourceCodeProvider.java @@ -36,8 +36,8 @@ */ public class SourceCodeProvider { - private final List includeRoots = new LinkedList<>(); private static final Logger LOG = Loggers.get(SourceCodeProvider.class); + private final List includeRoots = new LinkedList<>(); public void setIncludeRoots(List includeRoots, String baseDir) { for (String tmp : includeRoots) { diff --git a/cxx-squid/src/main/java/org/sonar/cxx/preprocessor/StandardDefinitions.java b/cxx-squid/src/main/java/org/sonar/cxx/preprocessor/StandardDefinitions.java index 0a09d7f1e6..3875829112 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/preprocessor/StandardDefinitions.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/preprocessor/StandardDefinitions.java @@ -28,9 +28,6 @@ */ public final class StandardDefinitions { - private StandardDefinitions() { - } - /** * macros * @@ -98,4 +95,7 @@ public static Map compatibilityMacros() { source.put("virtual", "__virtual"); return source; } + + private StandardDefinitions() { + } } diff --git a/cxx-squid/src/main/java/org/sonar/cxx/utils/CxxReportIssue.java b/cxx-squid/src/main/java/org/sonar/cxx/utils/CxxReportIssue.java index c091a240d2..1e8ae58453 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/utils/CxxReportIssue.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/utils/CxxReportIssue.java @@ -30,6 +30,7 @@ * Issue with one or multiple locations */ public class CxxReportIssue { + private final String ruleId; private final List locations; diff --git a/cxx-squid/src/main/java/org/sonar/cxx/utils/CxxReportLocation.java b/cxx-squid/src/main/java/org/sonar/cxx/utils/CxxReportLocation.java index 0c30a66662..db9bb33761 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/utils/CxxReportLocation.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/utils/CxxReportLocation.java @@ -23,10 +23,10 @@ import javax.annotation.Nullable; /** - * Each issues in SonarQube might have multiple locations; Encapsulate its - * properties in this structure + * Each issues in SonarQube might have multiple locations; Encapsulate its properties in this structure */ public class CxxReportLocation { + private final String file; private final String line; private final String info; diff --git a/cxx-squid/src/main/java/org/sonar/cxx/visitors/AbstractCxxPublicApiVisitor.java b/cxx-squid/src/main/java/org/sonar/cxx/visitors/AbstractCxxPublicApiVisitor.java index bc6b2dfe79..52c834c303 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/visitors/AbstractCxxPublicApiVisitor.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/visitors/AbstractCxxPublicApiVisitor.java @@ -80,6 +80,294 @@ public abstract class AbstractCxxPublicApiVisitor extends Squ private static final String TOKEN_OVERRIDE = "override"; + private static boolean isTypedef(AstNode declaratorList) { + AstNode simpleDeclSpezifierSeq = declaratorList.getPreviousSibling(); + if (simpleDeclSpezifierSeq != null) { + AstNode firstDeclSpecifier = simpleDeclSpezifierSeq.getFirstChild(CxxGrammarImpl.declSpecifier); + if (firstDeclSpecifier != null && firstDeclSpecifier.getToken().getType().equals(CxxKeyword.TYPEDEF)) { + AstNode classSpefifier = firstDeclSpecifier.getNextSibling(); + if (classSpefifier != null) { + TokenType type = classSpefifier.getToken().getType(); + if (type.equals(CxxKeyword.STRUCT) + || type.equals(CxxKeyword.CLASS) + || type.equals(CxxKeyword.UNION) + || type.equals(CxxKeyword.ENUM)) { + return true; + } + } + } + } + return false; + } + + private static boolean isFriendDeclarationList(AstNode declaratorList) { + AstNode simpleDeclNode = declaratorList + .getFirstAncestor(CxxGrammarImpl.simpleDeclaration); + + if (simpleDeclNode == null) { + LOG.warn("No simple declaration found for declarator list at {}", + declaratorList.getTokenLine()); + return false; + } + + AstNode declSpecifierSeq = simpleDeclNode + .getFirstChild(CxxGrammarImpl.declSpecifierSeq); + + if (declSpecifierSeq == null) { + return false; + } + + List declSpecifiers = declSpecifierSeq + .getChildren(CxxGrammarImpl.declSpecifier); + + for (AstNode declSpecifier : declSpecifiers) { + AstNode friendNode = declSpecifier.getFirstChild(CxxKeyword.FRIEND); + if (friendNode != null) { + return true; + } + } + + return false; + } + + private static AstNode getTypedefNode(AstNode classSpecifier) { + AstNode declSpecifier = classSpecifier.getFirstAncestor(CxxGrammarImpl.declSpecifier); + if (declSpecifier != null) { + declSpecifier = declSpecifier.getPreviousSibling(); + if (declSpecifier != null) { + AstNode typedef = declSpecifier.getFirstChild(); + if (typedef != null && typedef.getToken().getType().equals(CxxKeyword.TYPEDEF)) { + return typedef; + } + } + } + return null; + } + + private static boolean isFriendMemberDeclaration(AstNode memberDeclaration) { + AstNode simpleDeclNode = memberDeclaration + .getFirstDescendant(CxxGrammarImpl.simpleDeclaration); + + if (simpleDeclNode == null) { + LOG.warn("No simple declaration found for declarator list at {}", + memberDeclaration.getTokenLine()); + return false; + } + + AstNode declSpecifierSeq = simpleDeclNode + .getFirstChild(CxxGrammarImpl.declSpecifierSeq); + + if (declSpecifierSeq != null) { + List declSpecifiers = declSpecifierSeq + .getChildren(CxxGrammarImpl.declSpecifier); + + for (AstNode declSpecifier : declSpecifiers) { + AstNode friendNode = declSpecifier.getFirstChild(CxxKeyword.FRIEND); + if (friendNode != null) { + return true; + } + } + } + return false; + } + + private static boolean isDefaultOrDeleteFunctionBody(AstNode functionBodyNode) { + boolean defaultOrDelete = false; + List functionBody = functionBodyNode.getChildren(); + + // look for exact sub AST + if ((functionBody.size() == 3) + && functionBody.get(0).is(CxxPunctuator.ASSIGN) + && functionBody.get(2).is(CxxPunctuator.SEMICOLON)) { + + AstNode bodyType = functionBody.get(1); + + if (bodyType.is(CxxKeyword.DELETE) + || bodyType.is(CxxKeyword.DEFAULT)) { + defaultOrDelete = true; + } + } + return defaultOrDelete; + } + + private static boolean isOverriddenMethod(AstNode memberDeclarator) { + List modifiers = memberDeclarator.getDescendants(CxxGrammarImpl.virtSpecifier); + + for (AstNode modifier : modifiers) { + AstNode modifierId = modifier.getFirstChild(); + + if (TOKEN_OVERRIDE.equals(modifierId.getTokenValue())) { + return true; + } + } + + return false; + } + + // XXX may go to a utility class + private static String getOperatorId(AstNode operatorFunctionId) { + + StringBuilder builder = new StringBuilder( + operatorFunctionId.getTokenValue()); + AstNode operator = operatorFunctionId + .getFirstDescendant(CxxGrammarImpl.overloadableOperator); + + if (operator != null) { + + AstNode opNode = operator.getFirstChild(); + while (opNode != null) { + builder.append(opNode.getTokenValue()); + opNode = opNode.getNextSibling(); + } + } + + return builder.toString(); + } + + private static List getDeclaratorInlineComment(AstNode declarator) { + List comments; + + // inline comments are attached to the next AST node (not sibling, + // because the last attribute inline comment is attached to the next + // node of the parent) + AstNode next = declarator.getNextAstNode(); + + // inline documentation may be on the next definition token + // or next curly brace + if (next != null) { + // discard COMMA and SEMICOLON + if (next.getToken().getType().equals(CxxPunctuator.COMMA) + || next.getToken().getType().equals(CxxPunctuator.SEMICOLON)) { + next = next.getNextAstNode(); + } + + comments = getInlineDocumentation(next.getToken(), + declarator.getTokenLine()); + } else { + // could happen on parse error ? + comments = new ArrayList<>(); + } + + return comments; + } + + private static boolean isPublicApiMember(AstNode node) { + AstNode access = node; + + // retrieve the accessSpecifier + do { + access = access.getPreviousAstNode(); + } while (access != null + && !access.getType().equals(CxxGrammarImpl.accessSpecifier)); + + if (access != null) { + return access.getToken().getType().equals(CxxKeyword.PUBLIC) + || access.getToken().getType().equals(CxxKeyword.PROTECTED); + } else { + AstNode classSpecifier = node + .getFirstAncestor(CxxGrammarImpl.classSpecifier); + + if (classSpecifier != null) { + + AstNode enclosingSpecifierNode = classSpecifier + .getFirstDescendant(CxxKeyword.STRUCT, CxxKeyword.CLASS, + CxxKeyword.ENUM, CxxKeyword.UNION); + + if (enclosingSpecifierNode != null) { + TokenType type = enclosingSpecifierNode.getToken().getType(); + if (type.equals(CxxKeyword.STRUCT) || type.equals(CxxKeyword.UNION)) { + // struct and union members have public access, thus access level + // is the access level of the enclosing classSpecifier + return isPublicApiMember(classSpecifier); + + } else if (type.equals(CxxKeyword.CLASS)) { + // default access in classes is private + return false; + + } else { + LOG.error("isPublicApiMember unhandled case: {} at {}", enclosingSpecifierNode.getType(), + enclosingSpecifierNode.getTokenLine()); + return false; + } + } else { + LOG.error("isPublicApiMember: failed to get enclosing classSpecifier for node at {}", node.getTokenLine()); + return false; + } + } + + if (node.is(CxxGrammarImpl.functionDefinition)) { + // filter out function definitions with nested name specifier: should be documented inside of class + AstNode declarator = node.getFirstChild(CxxGrammarImpl.declarator); + if ((declarator != null) && declarator.hasDescendant(CxxGrammarImpl.nestedNameSpecifier)) { + return false; + } + } + + return true; + } + } + + /** + * Check if inline Doxygen documentation is attached to the given token at specified line + * + * @param token the token to inspect + * @param line line of the inlined documentation + * @return true if documentation is found for specified line, false otherwise + */ + private static List getInlineDocumentation(Token token, int line) { + List comments = new ArrayList<>(); + + for (Trivia trivia : token.getTrivia()) { + if (trivia.isComment()) { + Token triviaToken = trivia.getToken(); + if ((triviaToken != null) + && (triviaToken.getLine() == line) + && (isDoxygenInlineComment(triviaToken.getValue()))) { + comments.add(triviaToken); + if (LOG.isTraceEnabled()) { + LOG.trace("Inline doc: " + triviaToken.getValue()); + } + } + } + } + return comments; + } + + private static List getBlockDocumentation(AstNode node) { + List commentTokens = new ArrayList<>(); + + Token token = node.getToken(); + for (Trivia trivia : token.getTrivia()) { + if (trivia.isComment()) { + Token triviaToken = trivia.getToken(); + if (triviaToken != null) { + String comment = triviaToken.getValue(); + if (LOG.isTraceEnabled()) { + LOG.trace("Doc: {}\n", comment); + } + if (isDoxygenCommentBlock(comment) + && !isDoxygenInlineComment(comment)) { + commentTokens.add(triviaToken); + } + } + } + } + + return commentTokens; + } + + private static boolean isDoxygenInlineComment(String comment) { + + return comment.startsWith("/*!<") || comment.startsWith("/**<") + || comment.startsWith("//!<") || comment.startsWith("///<"); + } + + private static boolean isDoxygenCommentBlock(String comment) { + + return comment.startsWith("/**") || comment.startsWith("/*!") + || comment.startsWith("///") || comment.startsWith("//!"); + } + private List headerFileSuffixes; private boolean skipFile = true; @@ -206,71 +494,21 @@ private void visitDeclaratorList(AstNode declaratorList) { AstNode declaration = declaratorList .getFirstAncestor(CxxGrammarImpl.declaration); - List declarators = declaratorList - .getChildren(CxxGrammarImpl.initDeclarator); - - if (declarators.size() == 1) { - // a special handling is needed in case of single declarator - // because documentation may be located on different places - // depending on the declaration - visitSingleDeclarator(declaration, declarators.get(0)); - } else { - // with several declarators, documentation should be located - // on each declarator - for (AstNode declarator : declarators) { - visitDeclarator(declarator, declarator); - } - } - } - - private static boolean isTypedef(AstNode declaratorList) { - AstNode simpleDeclSpezifierSeq = declaratorList.getPreviousSibling(); - if (simpleDeclSpezifierSeq != null) { - AstNode firstDeclSpecifier = simpleDeclSpezifierSeq.getFirstChild(CxxGrammarImpl.declSpecifier); - if (firstDeclSpecifier != null && firstDeclSpecifier.getToken().getType().equals(CxxKeyword.TYPEDEF)) { - AstNode classSpefifier = firstDeclSpecifier.getNextSibling(); - if (classSpefifier != null) { - TokenType type = classSpefifier.getToken().getType(); - if (type.equals(CxxKeyword.STRUCT) - || type.equals(CxxKeyword.CLASS) - || type.equals(CxxKeyword.UNION) - || type.equals(CxxKeyword.ENUM)) { - return true; - } - } - } - } - return false; - } - - private static boolean isFriendDeclarationList(AstNode declaratorList) { - AstNode simpleDeclNode = declaratorList - .getFirstAncestor(CxxGrammarImpl.simpleDeclaration); - - if (simpleDeclNode == null) { - LOG.warn("No simple declaration found for declarator list at {}", - declaratorList.getTokenLine()); - return false; - } - - AstNode declSpecifierSeq = simpleDeclNode - .getFirstChild(CxxGrammarImpl.declSpecifierSeq); - - if (declSpecifierSeq == null) { - return false; - } - - List declSpecifiers = declSpecifierSeq - .getChildren(CxxGrammarImpl.declSpecifier); + List declarators = declaratorList + .getChildren(CxxGrammarImpl.initDeclarator); - for (AstNode declSpecifier : declSpecifiers) { - AstNode friendNode = declSpecifier.getFirstChild(CxxKeyword.FRIEND); - if (friendNode != null) { - return true; + if (declarators.size() == 1) { + // a special handling is needed in case of single declarator + // because documentation may be located on different places + // depending on the declaration + visitSingleDeclarator(declaration, declarators.get(0)); + } else { + // with several declarators, documentation should be located + // on each declarator + for (AstNode declarator : declarators) { + visitDeclarator(declarator, declarator); } } - - return false; } private void visitSingleDeclarator(AstNode declaration, @@ -334,20 +572,6 @@ private void visitDeclarator(AstNode declarator, AstNode docNode) { } } - private static AstNode getTypedefNode(AstNode classSpecifier) { - AstNode declSpecifier = classSpecifier.getFirstAncestor(CxxGrammarImpl.declSpecifier); - if (declSpecifier != null) { - declSpecifier = declSpecifier.getPreviousSibling(); - if (declSpecifier != null) { - AstNode typedef = declSpecifier.getFirstChild(); - if (typedef != null && typedef.getToken().getType().equals(CxxKeyword.TYPEDEF)) { - return typedef; - } - } - } - return null; - } - private void visitClassSpecifier(AstNode classSpecifier) { // check if this is a template specification to adjust documentation node @@ -444,33 +668,6 @@ private void visitMemberDeclaration(AstNode memberDeclaration) { } } - private static boolean isFriendMemberDeclaration(AstNode memberDeclaration) { - AstNode simpleDeclNode = memberDeclaration - .getFirstDescendant(CxxGrammarImpl.simpleDeclaration); - - if (simpleDeclNode == null) { - LOG.warn("No simple declaration found for declarator list at {}", - memberDeclaration.getTokenLine()); - return false; - } - - AstNode declSpecifierSeq = simpleDeclNode - .getFirstChild(CxxGrammarImpl.declSpecifierSeq); - - if (declSpecifierSeq != null) { - List declSpecifiers = declSpecifierSeq - .getChildren(CxxGrammarImpl.declSpecifier); - - for (AstNode declSpecifier : declSpecifiers) { - AstNode friendNode = declSpecifier.getFirstChild(CxxKeyword.FRIEND); - if (friendNode != null) { - return true; - } - } - } - return false; - } - private void visitTemplateDeclaration(AstNode templateDeclaration) { if (isFriendMemberDeclaration(templateDeclaration.getParent())) { @@ -514,39 +711,6 @@ private void visitFunctionDefinition(AstNode functionDef) { } } - private static boolean isDefaultOrDeleteFunctionBody(AstNode functionBodyNode) { - boolean defaultOrDelete = false; - List functionBody = functionBodyNode.getChildren(); - - // look for exact sub AST - if ((functionBody.size() == 3) - && functionBody.get(0).is(CxxPunctuator.ASSIGN) - && functionBody.get(2).is(CxxPunctuator.SEMICOLON)) { - - AstNode bodyType = functionBody.get(1); - - if (bodyType.is(CxxKeyword.DELETE) - || bodyType.is(CxxKeyword.DEFAULT)) { - defaultOrDelete = true; - } - } - return defaultOrDelete; - } - - private static boolean isOverriddenMethod(AstNode memberDeclarator) { - List modifiers = memberDeclarator.getDescendants(CxxGrammarImpl.virtSpecifier); - - for (AstNode modifier : modifiers) { - AstNode modifierId = modifier.getFirstChild(); - - if (TOKEN_OVERRIDE.equals(modifierId.getTokenValue())) { - return true; - } - } - - return false; - } - /** * Find documentation node, associated documentation, identifier of a * public member declarator and visit it as a public API. @@ -726,170 +890,6 @@ private void visitEnumSpecifier(AstNode enumSpecifierNode) { } } - // XXX may go to a utility class - private static String getOperatorId(AstNode operatorFunctionId) { - - StringBuilder builder = new StringBuilder( - operatorFunctionId.getTokenValue()); - AstNode operator = operatorFunctionId - .getFirstDescendant(CxxGrammarImpl.overloadableOperator); - - if (operator != null) { - - AstNode opNode = operator.getFirstChild(); - while (opNode != null) { - builder.append(opNode.getTokenValue()); - opNode = opNode.getNextSibling(); - } - } - - return builder.toString(); - } - - private static List getDeclaratorInlineComment(AstNode declarator) { - List comments; - - // inline comments are attached to the next AST node (not sibling, - // because the last attribute inline comment is attached to the next - // node of the parent) - AstNode next = declarator.getNextAstNode(); - - // inline documentation may be on the next definition token - // or next curly brace - if (next != null) { - // discard COMMA and SEMICOLON - if (next.getToken().getType().equals(CxxPunctuator.COMMA) - || next.getToken().getType().equals(CxxPunctuator.SEMICOLON)) { - next = next.getNextAstNode(); - } - - comments = getInlineDocumentation(next.getToken(), - declarator.getTokenLine()); - } else { - // could happen on parse error ? - comments = new ArrayList<>(); - } - - return comments; - } - - private static boolean isPublicApiMember(AstNode node) { - AstNode access = node; - - // retrieve the accessSpecifier - do { - access = access.getPreviousAstNode(); - } while (access != null - && !access.getType().equals(CxxGrammarImpl.accessSpecifier)); - - if (access != null) { - return access.getToken().getType().equals(CxxKeyword.PUBLIC) - || access.getToken().getType().equals(CxxKeyword.PROTECTED); - } else { - AstNode classSpecifier = node - .getFirstAncestor(CxxGrammarImpl.classSpecifier); - - if (classSpecifier != null) { - - AstNode enclosingSpecifierNode = classSpecifier - .getFirstDescendant(CxxKeyword.STRUCT, CxxKeyword.CLASS, - CxxKeyword.ENUM, CxxKeyword.UNION); - - if (enclosingSpecifierNode != null) { - TokenType type = enclosingSpecifierNode.getToken().getType(); - if (type.equals(CxxKeyword.STRUCT) || type.equals(CxxKeyword.UNION)) { - // struct and union members have public access, thus access level - // is the access level of the enclosing classSpecifier - return isPublicApiMember(classSpecifier); - - } else if (type.equals(CxxKeyword.CLASS)) { - // default access in classes is private - return false; - - } else { - LOG.error("isPublicApiMember unhandled case: {} at {}", enclosingSpecifierNode.getType(), - enclosingSpecifierNode.getTokenLine()); - return false; - } - } else { - LOG.error("isPublicApiMember: failed to get enclosing classSpecifier for node at {}", node.getTokenLine()); - return false; - } - } - - if (node.is(CxxGrammarImpl.functionDefinition)) { - // filter out function definitions with nested name specifier: should be documented inside of class - AstNode declarator = node.getFirstChild(CxxGrammarImpl.declarator); - if ((declarator != null) && declarator.hasDescendant(CxxGrammarImpl.nestedNameSpecifier)) { - return false; - } - } - - return true; - } - } - - /** - * Check if inline Doxygen documentation is attached to the given token at specified line - * - * @param token the token to inspect - * @param line line of the inlined documentation - * @return true if documentation is found for specified line, false otherwise - */ - private static List getInlineDocumentation(Token token, int line) { - List comments = new ArrayList<>(); - - for (Trivia trivia : token.getTrivia()) { - if (trivia.isComment()) { - Token triviaToken = trivia.getToken(); - if ((triviaToken != null) - && (triviaToken.getLine() == line) - && (isDoxygenInlineComment(triviaToken.getValue()))) { - comments.add(triviaToken); - if (LOG.isTraceEnabled()) { - LOG.trace("Inline doc: " + triviaToken.getValue()); - } - } - } - } - return comments; - } - - private static List getBlockDocumentation(AstNode node) { - List commentTokens = new ArrayList<>(); - - Token token = node.getToken(); - for (Trivia trivia : token.getTrivia()) { - if (trivia.isComment()) { - Token triviaToken = trivia.getToken(); - if (triviaToken != null) { - String comment = triviaToken.getValue(); - if (LOG.isTraceEnabled()) { - LOG.trace("Doc: {}\n", comment); - } - if (isDoxygenCommentBlock(comment) - && !isDoxygenInlineComment(comment)) { - commentTokens.add(triviaToken); - } - } - } - } - - return commentTokens; - } - - private static boolean isDoxygenInlineComment(String comment) { - - return comment.startsWith("/*!<") || comment.startsWith("/**<") - || comment.startsWith("//!<") || comment.startsWith("///<"); - } - - private static boolean isDoxygenCommentBlock(String comment) { - - return comment.startsWith("/**") || comment.startsWith("/*!") - || comment.startsWith("///") || comment.startsWith("//!"); - } - public final AbstractCxxPublicApiVisitor withHeaderFileSuffixes(List headerFileSuffixes) { this.headerFileSuffixes = new ArrayList<>(headerFileSuffixes); return this; diff --git a/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxCognitiveComplexityVisitor.java b/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxCognitiveComplexityVisitor.java index 72653f0718..c16592b91e 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxCognitiveComplexityVisitor.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxCognitiveComplexityVisitor.java @@ -19,24 +19,21 @@ */ package org.sonar.cxx.visitors; +import com.sonar.sslr.api.AstNode; +import com.sonar.sslr.api.AstNodeType; import static com.sonar.sslr.api.GenericTokenType.IDENTIFIER; - +import com.sonar.sslr.api.Grammar; import java.util.Arrays; import java.util.Deque; import java.util.HashSet; import java.util.LinkedList; import java.util.Set; - import org.sonar.cxx.api.CxxKeyword; import org.sonar.cxx.api.CxxMetric; import org.sonar.cxx.api.CxxPunctuator; import org.sonar.cxx.parser.CxxGrammarImpl; import org.sonar.squidbridge.api.SourceCode; -import com.sonar.sslr.api.AstNode; -import com.sonar.sslr.api.AstNodeType; -import com.sonar.sslr.api.Grammar; - public class CxxCognitiveComplexityVisitor extends MultiLocatitionSquidCheck { private static final AstNodeType[] DESCENDANT_TYPES = new AstNodeType[]{ @@ -74,8 +71,6 @@ public class CxxCognitiveComplexityVisitor extends MultiLocat CxxGrammarImpl.selectionStatement, CxxPunctuator.QUEST}; - private Deque complexityScopes = null; - private static final Set SUBSCRIPTION_NODES = new HashSet<>(); static { @@ -86,6 +81,12 @@ public class CxxCognitiveComplexityVisitor extends MultiLocat SUBSCRIPTION_NODES.addAll(Arrays.asList(NESTING_INCREMENTS_TYPES)); } + private static boolean isElseIf(AstNode node) { + return node.is(CxxGrammarImpl.selectionStatement) && node.getToken().getType().equals(CxxKeyword.IF) + && node.getParent().getPreviousAstNode().getType().equals(CxxKeyword.ELSE); + } + private Deque complexityScopes = null; + protected void analyzeComplexity(CxxComplexityScope scope) { SourceCode code = getContext().peekSourceCode(); code.setMeasure(CxxMetric.COGNITIVE_COMPLEXITY, scope.getComplexity()); @@ -147,8 +148,4 @@ public void leaveNode(AstNode node) { } } - private static boolean isElseIf(AstNode node) { - return node.is(CxxGrammarImpl.selectionStatement) && node.getToken().getType().equals(CxxKeyword.IF) - && node.getParent().getPreviousAstNode().getType().equals(CxxKeyword.ELSE); - } } diff --git a/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxComplexityScope.java b/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxComplexityScope.java index 1dd398c8f9..7b5bab9c10 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxComplexityScope.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxComplexityScope.java @@ -19,12 +19,11 @@ */ package org.sonar.cxx.visitors; +import com.sonar.sslr.api.AstNode; import java.util.Collections; import java.util.LinkedList; import java.util.List; -import com.sonar.sslr.api.AstNode; - /** * Describe a code scope (function definition, class definition, entire file etc) in terms of complexity sources */ diff --git a/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxComplexitySource.java b/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxComplexitySource.java index 4c0b0afac3..287d26e268 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxComplexitySource.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxComplexitySource.java @@ -19,13 +19,12 @@ */ package org.sonar.cxx.visitors; +import com.sonar.sslr.api.AstNodeType; +import com.sonar.sslr.api.TokenType; import org.sonar.cxx.api.CxxKeyword; import org.sonar.cxx.api.CxxPunctuator; import org.sonar.cxx.parser.CxxGrammarImpl; -import com.sonar.sslr.api.AstNodeType; -import com.sonar.sslr.api.TokenType; - /** * Structure, that tracks all nodes, which increase the code complexity */ diff --git a/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxCyclomaticComplexityVisitor.java b/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxCyclomaticComplexityVisitor.java index 52f93d7609..2a8812cb83 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxCyclomaticComplexityVisitor.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxCyclomaticComplexityVisitor.java @@ -19,25 +19,22 @@ */ package org.sonar.cxx.visitors; +import com.sonar.sslr.api.AstNode; +import com.sonar.sslr.api.AstNodeType; +import com.sonar.sslr.api.Grammar; +import com.sonar.sslr.api.Token; import java.util.List; - import javax.annotation.Nullable; - import org.sonar.squidbridge.SquidAstVisitor; import org.sonar.squidbridge.SquidAstVisitorContext; import org.sonar.squidbridge.metrics.ComplexityVisitor; -import com.sonar.sslr.api.AstNode; -import com.sonar.sslr.api.AstNodeType; -import com.sonar.sslr.api.Grammar; -import com.sonar.sslr.api.Token; - /** - * Decorator for {@link org.sonar.squidbridge.metrics.ComplexityVisitor} in - * order to prevent visiting of generated {@link com.sonar.sslr.api.AstNode}s + * Decorator for {@link org.sonar.squidbridge.metrics.ComplexityVisitor} in order to prevent visiting of generated + * {@link com.sonar.sslr.api.AstNode}s * - * Inheritance is not possible, since the class - * {@link org.sonar.squidbridge.metrics.ComplexityVisitor} is marked as final + * Inheritance is not possible, since the class {@link org.sonar.squidbridge.metrics.ComplexityVisitor} is marked as + * final * * @param */ diff --git a/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxFileVisitor.java b/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxFileVisitor.java index d075b27b2e..1274725a55 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxFileVisitor.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxFileVisitor.java @@ -27,7 +27,7 @@ import org.sonar.squidbridge.SquidAstVisitorContext; public class CxxFileVisitor extends SquidAstVisitor - implements AstVisitor { + implements AstVisitor { private final SquidAstVisitorContext context; diff --git a/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxFunctionComplexityVisitor.java b/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxFunctionComplexityVisitor.java index 0ee215a6e3..96ce55b9a1 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxFunctionComplexityVisitor.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxFunctionComplexityVisitor.java @@ -19,6 +19,8 @@ */ package org.sonar.cxx.visitors; +import com.sonar.sslr.api.AstNode; +import com.sonar.sslr.api.Grammar; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.cxx.CxxLanguage; @@ -29,9 +31,6 @@ import org.sonar.squidbridge.api.SourceFunction; import org.sonar.squidbridge.checks.ChecksHelper; -import com.sonar.sslr.api.AstNode; -import com.sonar.sslr.api.Grammar; - public class CxxFunctionComplexityVisitor extends SquidAstVisitor { private static final Logger LOG = Loggers.get(CxxFunctionComplexityVisitor.class); diff --git a/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxFunctionSizeVisitor.java b/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxFunctionSizeVisitor.java index 1200dca7fe..dcc39c8a69 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxFunctionSizeVisitor.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxFunctionSizeVisitor.java @@ -19,6 +19,8 @@ */ package org.sonar.cxx.visitors; +import com.sonar.sslr.api.AstNode; +import com.sonar.sslr.api.Grammar; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.cxx.CxxLanguage; @@ -28,9 +30,6 @@ import org.sonar.squidbridge.api.SourceFile; import org.sonar.squidbridge.api.SourceFunction; -import com.sonar.sslr.api.AstNode; -import com.sonar.sslr.api.Grammar; - public class CxxFunctionSizeVisitor extends SquidAstVisitor { private static final Logger LOG = Loggers.get(CxxFunctionSizeVisitor.class); diff --git a/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxLinesOfCodeInFunctionBodyVisitor.java b/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxLinesOfCodeInFunctionBodyVisitor.java index 2f965e4858..482fe3c01f 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxLinesOfCodeInFunctionBodyVisitor.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxLinesOfCodeInFunctionBodyVisitor.java @@ -19,24 +19,22 @@ */ package org.sonar.cxx.visitors; +import com.sonar.sslr.api.AstNode; +import com.sonar.sslr.api.AstVisitor; +import com.sonar.sslr.api.Grammar; import java.util.List; - import org.sonar.cxx.api.CppPunctuator; import org.sonar.cxx.api.CxxMetric; import org.sonar.cxx.parser.CxxGrammarImpl; import org.sonar.squidbridge.SquidAstVisitor; -import com.sonar.sslr.api.AstNode; -import com.sonar.sslr.api.AstVisitor; -import com.sonar.sslr.api.Grammar; - /** * Visitor that computes the NCLOCs in function body, leading and trailing {} do not count * * @param */ public class CxxLinesOfCodeInFunctionBodyVisitor extends SquidAstVisitor - implements AstVisitor { + implements AstVisitor { @Override public void init() { @@ -46,7 +44,7 @@ public void init() { @Override public void visitNode(AstNode node) { List allChilds = node.getDescendants(CxxGrammarImpl.statement, CppPunctuator.CURLBR_LEFT, - CppPunctuator.CURLBR_RIGHT); + CppPunctuator.CURLBR_RIGHT); int lines = 1; int firstLine = node.getTokenLine(); if (allChilds != null && !allChilds.isEmpty()) { diff --git a/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxLinesOfCodeVisitor.java b/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxLinesOfCodeVisitor.java index db718992d0..0d62131d90 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxLinesOfCodeVisitor.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxLinesOfCodeVisitor.java @@ -22,11 +22,9 @@ import com.sonar.sslr.api.AstAndTokenVisitor; import com.sonar.sslr.api.AstNode; import static com.sonar.sslr.api.GenericTokenType.EOF; - -import java.util.regex.Pattern; - import com.sonar.sslr.api.Grammar; import com.sonar.sslr.api.Token; +import java.util.regex.Pattern; import org.sonar.squidbridge.SquidAstVisitor; import org.sonar.squidbridge.measures.MetricDef; @@ -38,9 +36,10 @@ public class CxxLinesOfCodeVisitor extends SquidAstVisitor implements AstAndTokenVisitor { + public static final Pattern EOL_PATTERN = Pattern.compile("\\R"); + private final MetricDef metric; private int lastTokenLine; - public static final Pattern EOL_PATTERN = Pattern.compile("\\R"); public CxxLinesOfCodeVisitor(MetricDef metric) { this.metric = metric; diff --git a/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxParseErrorLoggerVisitor.java b/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxParseErrorLoggerVisitor.java index 459fdeacaa..43b6bf2bd6 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxParseErrorLoggerVisitor.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxParseErrorLoggerVisitor.java @@ -40,13 +40,8 @@ public class CxxParseErrorLoggerVisitor = "Source code parser: {} syntax error(s) detected. Syntax errors could cause invalid software metric values." + " Root cause are typically missing includes, missing macros or compiler specific extensions."; private static final Logger LOG = Loggers.get(CxxParseErrorLoggerVisitor.class); - private final SquidAstVisitorContext context; private static int errors = 0; - public CxxParseErrorLoggerVisitor(SquidAstVisitorContext context) { - this.context = context; - } - public static void finalReport() { if (errors != 0) { LOG.warn(SYNTAX_ERROR_MSG, errors); @@ -57,6 +52,11 @@ public static void finalReport() { public static void resetReport() { errors = 0; } + private final SquidAstVisitorContext context; + + public CxxParseErrorLoggerVisitor(SquidAstVisitorContext context) { + this.context = context; + } @Override public void init() { diff --git a/cxx-squid/src/main/java/org/sonar/cxx/visitors/MultiLocatitionSquidCheck.java b/cxx-squid/src/main/java/org/sonar/cxx/visitors/MultiLocatitionSquidCheck.java index 4b1ca902f2..24fb9a7fdb 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/visitors/MultiLocatitionSquidCheck.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/visitors/MultiLocatitionSquidCheck.java @@ -19,9 +19,9 @@ */ package org.sonar.cxx.visitors; +import com.sonar.sslr.api.Grammar; import java.util.HashSet; import java.util.Set; - import org.sonar.api.utils.AnnotationUtils; import org.sonar.cxx.utils.CxxReportIssue; import org.sonar.squidbridge.SquidAstVisitorContext; @@ -30,11 +30,9 @@ import org.sonar.squidbridge.measures.CalculatedMetricFormula; import org.sonar.squidbridge.measures.MetricDef; -import com.sonar.sslr.api.Grammar; - /** - * Derivation of {@link SquidCheck}, which can create issues with multiple - * locations (1 primary location, arbitrary number of secondary locations + * Derivation of {@link SquidCheck}, which can create issues with multiple locations (1 primary location, arbitrary + * number of secondary locations * * See also org.sonar.squidbridge.SquidAstVisitorContext.createLineViolation * @@ -42,33 +40,30 @@ */ public class MultiLocatitionSquidCheck extends SquidCheck { - private static enum DataKey implements MetricDef { - FILE_VIOLATIONS_WITH_MULTIPLE_LOCATIONS; - - @Override - public String getName() { - return FILE_VIOLATIONS_WITH_MULTIPLE_LOCATIONS.getName(); - } - - @Override - public boolean isCalculatedMetric() { - return false; - } + /** + * @return set of multi-location issues, raised on the given file; might be null + * @see SourceFile.getCheckMessages() for simple violations + */ + @SuppressWarnings("unchecked") + public static Set getMultiLocationCheckMessages(SourceFile sourceFile) { + return (Set) sourceFile.getData(DataKey.FILE_VIOLATIONS_WITH_MULTIPLE_LOCATIONS); + } - @Override - public boolean aggregateIfThereIsAlreadyAValue() { - return false; - } + /** + * @return true if the given file has mult-location issues + * @see SourceFile.hasCheckMessages() for simple violations + */ + public static boolean hasMultiLocationCheckMessages(SourceFile sourceFile) { + Set issues = getMultiLocationCheckMessages(sourceFile); + return issues != null && !issues.isEmpty(); + } - @Override - public boolean isThereAggregationFormula() { - return false; - } + private static void setMultiLocationViolation(SourceFile sourceFile, Set messages) { + sourceFile.addData(DataKey.FILE_VIOLATIONS_WITH_MULTIPLE_LOCATIONS, messages); + } - @Override - public CalculatedMetricFormula getCalculatedMetricFormula() { - return null; - } + public static void eraseMultilineCheckMessages(SourceFile sourceFile) { + setMultiLocationViolation(sourceFile, null); } /** @@ -91,12 +86,13 @@ private SourceFile getSourceFile() { return c.peekSourceCode().getParent(SourceFile.class); } else { throw new IllegalStateException("Unable to get SourceFile on source code '" - + (c.peekSourceCode() == null ? "[NULL]" : c.peekSourceCode().getKey()) + "'"); + + (c.peekSourceCode() == null ? "[NULL]" : c.peekSourceCode().getKey()) + "'"); } } /** * Add the given message to the current SourceFile object + * * @see SquidAstVisitorContext.createLineViolation() for simple violations */ protected void createMultiLocationViolation(CxxReportIssue message) { @@ -109,30 +105,32 @@ protected void createMultiLocationViolation(CxxReportIssue message) { setMultiLocationViolation(sourceFile, messages); } - /** - * @return set of multi-location issues, raised on the given file; might be - * null - * @see SourceFile.getCheckMessages() for simple violations - */ - @SuppressWarnings("unchecked") - public static Set getMultiLocationCheckMessages(SourceFile sourceFile) { - return (Set) sourceFile.getData(DataKey.FILE_VIOLATIONS_WITH_MULTIPLE_LOCATIONS); - } + private static enum DataKey implements MetricDef { + FILE_VIOLATIONS_WITH_MULTIPLE_LOCATIONS; - /** - * @return true if the given file has mult-location issues - * @see SourceFile.hasCheckMessages() for simple violations - */ - public static boolean hasMultiLocationCheckMessages(SourceFile sourceFile) { - Set issues = getMultiLocationCheckMessages(sourceFile); - return issues != null && !issues.isEmpty(); - } + @Override + public String getName() { + return FILE_VIOLATIONS_WITH_MULTIPLE_LOCATIONS.getName(); + } - private static void setMultiLocationViolation(SourceFile sourceFile, Set messages) { - sourceFile.addData(DataKey.FILE_VIOLATIONS_WITH_MULTIPLE_LOCATIONS, messages); - } + @Override + public boolean isCalculatedMetric() { + return false; + } - public static void eraseMultilineCheckMessages(SourceFile sourceFile) { - setMultiLocationViolation(sourceFile, null); + @Override + public boolean aggregateIfThereIsAlreadyAValue() { + return false; + } + + @Override + public boolean isThereAggregationFormula() { + return false; + } + + @Override + public CalculatedMetricFormula getCalculatedMetricFormula() { + return null; + } } } diff --git a/cxx-squid/src/test/java/org/sonar/cxx/AggregateMeasureComputerTest.java b/cxx-squid/src/test/java/org/sonar/cxx/AggregateMeasureComputerTest.java index 4b44f80059..cb631d1141 100644 --- a/cxx-squid/src/test/java/org/sonar/cxx/AggregateMeasureComputerTest.java +++ b/cxx-squid/src/test/java/org/sonar/cxx/AggregateMeasureComputerTest.java @@ -19,10 +19,8 @@ */ package org.sonar.cxx; -import static org.assertj.core.api.Assertions.assertThat; - import java.util.Map; - +import static org.assertj.core.api.Assertions.assertThat; import org.junit.Test; import org.sonar.api.ce.measure.Component; import org.sonar.api.ce.measure.Component.Type; @@ -40,8 +38,8 @@ public class AggregateMeasureComputerTest { private static TestMeasureComputerContext createContext(AggregateMeasureComputer aggregator, Component component) { return new TestMeasureComputerContext(component, new TestSettings(), - new MeasureComputerDefinitionBuilderImpl().setInputMetrics(aggregator.getAggregatedMetrics()) - .setOutputMetrics(aggregator.getAggregatedMetrics()).build()); + new MeasureComputerDefinitionBuilderImpl().setInputMetrics(aggregator.getAggregatedMetrics()) + .setOutputMetrics(aggregator.getAggregatedMetrics()).build()); } @Test diff --git a/cxx-squid/src/test/java/org/sonar/cxx/CxxAstScannerTest.java b/cxx-squid/src/test/java/org/sonar/cxx/CxxAstScannerTest.java index 9505ca1ea4..9d109c6eba 100644 --- a/cxx-squid/src/test/java/org/sonar/cxx/CxxAstScannerTest.java +++ b/cxx-squid/src/test/java/org/sonar/cxx/CxxAstScannerTest.java @@ -26,7 +26,6 @@ import java.util.ArrayList; import java.util.Arrays; import static org.assertj.core.api.Assertions.assertThat; - import org.assertj.core.api.SoftAssertions; import org.junit.Test; import org.sonar.cxx.api.CxxMetric; diff --git a/cxx-squid/src/test/java/org/sonar/cxx/CxxConfigurationTest.java b/cxx-squid/src/test/java/org/sonar/cxx/CxxConfigurationTest.java index ee7c891294..c55e4e210f 100644 --- a/cxx-squid/src/test/java/org/sonar/cxx/CxxConfigurationTest.java +++ b/cxx-squid/src/test/java/org/sonar/cxx/CxxConfigurationTest.java @@ -23,7 +23,6 @@ import java.util.ArrayList; import java.util.List; import static org.assertj.core.api.Assertions.assertThat; - import org.assertj.core.api.SoftAssertions; import org.fest.assertions.Assertions; import org.junit.Test; @@ -210,7 +209,7 @@ public void shouldHandleSpecificV120OptionsCorrectly() { softly.assertThat(defines.contains("_MSC_FULL_VER 180031101")).isTrue(); softly.assertThat(defines.contains("_ATL_VER 0x0C00")).isTrue(); softly.assertAll(); - } + } @Test public void shouldHandleSpecificV140OptionsCorrectly() { diff --git a/cxx-squid/src/test/java/org/sonar/cxx/CxxFileTesterHelper.java b/cxx-squid/src/test/java/org/sonar/cxx/CxxFileTesterHelper.java index 571d5c9a5f..8dc6649106 100644 --- a/cxx-squid/src/test/java/org/sonar/cxx/CxxFileTesterHelper.java +++ b/cxx-squid/src/test/java/org/sonar/cxx/CxxFileTesterHelper.java @@ -58,7 +58,7 @@ public static CxxLanguage mockCxxLanguage() { when(language.IsRecoveryEnabled()).thenReturn(Optional.of(Boolean.TRUE)); when(language.getFileSuffixes()) .thenReturn(new String[]{".cpp", ".hpp", ".h", ".cxx", ".c", ".cc", ".hxx", ".hh"}); - when(language.getHeaderFileSuffixes()).thenReturn(new String[] { ".hpp", ".h", ".hxx", ".hh" }); + when(language.getHeaderFileSuffixes()).thenReturn(new String[]{".hpp", ".h", ".hxx", ".hh"}); return language; } diff --git a/cxx-squid/src/test/java/org/sonar/cxx/CxxLanguageTest.java b/cxx-squid/src/test/java/org/sonar/cxx/CxxLanguageTest.java index e7582a4dd4..7171e529cb 100644 --- a/cxx-squid/src/test/java/org/sonar/cxx/CxxLanguageTest.java +++ b/cxx-squid/src/test/java/org/sonar/cxx/CxxLanguageTest.java @@ -30,8 +30,6 @@ public class CxxLanguageTest { - private MapSettings settings; - private static final String KEY = "c++"; private static final String NAME = "c++"; private static final String PLUGIN_ID = "cxx"; @@ -42,67 +40,13 @@ public class CxxLanguageTest { * Default cxx header files suffixes */ public static final String DEFAULT_HEADER_SUFFIXES = ".hxx,.hpp,.hh,.h"; + private MapSettings settings; @Before public void setUp() { settings = new MapSettings(); } - private class CppLanguage extends CxxLanguage { - - private final String[] sourceSuffixes; - private final String[] headerSuffixes; - private final String[] fileSuffixes; - - public CppLanguage(Configuration settings) { - super(KEY, NAME, PLUGIN_ID, settings); - - sourceSuffixes = createStringArray(settings.getStringArray("sonar.cxx.suffixes.sources"), SOURCE_SUFFIXES); - headerSuffixes = createStringArray(settings.getStringArray("sonar.cxx.suffixes.headers"), HEADER_SUFFIXES); - fileSuffixes = mergeArrays(sourceSuffixes, headerSuffixes); - } - - @Override - public String[] getFileSuffixes() { - return fileSuffixes.clone(); - } - - @Override - public String[] getSourceFileSuffixes() { - return sourceSuffixes.clone(); - } - - @Override - public String[] getHeaderFileSuffixes() { - return headerSuffixes.clone(); - } - - @Override - public List getChecks() { - return new ArrayList<>(); - } - - private String[] createStringArray(String[] values, String defaultValues) { - if (values.length == 0) { - return defaultValues.split(","); - } - return values; - } - - private String[] mergeArrays(String[] array1, String[] array2) { - String[] result = new String[array1.length + array2.length]; - System.arraycopy(sourceSuffixes, 0, result, 0, array1.length); - System.arraycopy(headerSuffixes, 0, result, array1.length, array2.length); - return result; - } - - @Override - public String getRepositoryKey() { - return PLUGIN_ID; - - } - } - @Test public void testCxxLanguageStringConfiguration() throws Exception { CppLanguage language = new CppLanguage(settings.asConfig()); @@ -163,4 +107,59 @@ public void testHasKey() throws Exception { assertThat(language.hasKey("sonar.cxx.errorRecoveryEnabled")).isEqualTo(Boolean.FALSE); } + private class CppLanguage extends CxxLanguage { + + private final String[] sourceSuffixes; + private final String[] headerSuffixes; + private final String[] fileSuffixes; + + public CppLanguage(Configuration settings) { + super(KEY, NAME, PLUGIN_ID, settings); + + sourceSuffixes = createStringArray(settings.getStringArray("sonar.cxx.suffixes.sources"), SOURCE_SUFFIXES); + headerSuffixes = createStringArray(settings.getStringArray("sonar.cxx.suffixes.headers"), HEADER_SUFFIXES); + fileSuffixes = mergeArrays(sourceSuffixes, headerSuffixes); + } + + @Override + public String[] getFileSuffixes() { + return fileSuffixes.clone(); + } + + @Override + public String[] getSourceFileSuffixes() { + return sourceSuffixes.clone(); + } + + @Override + public String[] getHeaderFileSuffixes() { + return headerSuffixes.clone(); + } + + @Override + public List getChecks() { + return new ArrayList<>(); + } + + private String[] createStringArray(String[] values, String defaultValues) { + if (values.length == 0) { + return defaultValues.split(","); + } + return values; + } + + private String[] mergeArrays(String[] array1, String[] array2) { + String[] result = new String[array1.length + array2.length]; + System.arraycopy(sourceSuffixes, 0, result, 0, array1.length); + System.arraycopy(headerSuffixes, 0, result, array1.length, array2.length); + return result; + } + + @Override + public String getRepositoryKey() { + return PLUGIN_ID; + + } + } + } diff --git a/cxx-squid/src/test/java/org/sonar/cxx/DensityMeasureComputerTest.java b/cxx-squid/src/test/java/org/sonar/cxx/DensityMeasureComputerTest.java index 7c3fdf8777..ebe5e67c9f 100644 --- a/cxx-squid/src/test/java/org/sonar/cxx/DensityMeasureComputerTest.java +++ b/cxx-squid/src/test/java/org/sonar/cxx/DensityMeasureComputerTest.java @@ -19,10 +19,8 @@ */ package org.sonar.cxx; -import static org.assertj.core.api.Assertions.assertThat; - import java.util.Map; - +import static org.assertj.core.api.Assertions.assertThat; import org.junit.Test; import org.sonar.api.ce.measure.Component.Type; import org.sonar.api.ce.measure.test.TestComponent; @@ -49,7 +47,7 @@ public class DensityMeasureComputerTest { private static TestMeasureComputerContext createContext(DensityMeasureComputer computer) { final TestComponent component = new TestComponent("file", Type.FILE, new FileAttributesImpl("c++", false)); return new TestMeasureComputerContext(component, new TestSettings(), new MeasureComputerDefinitionBuilderImpl() - .setInputMetrics(computer.getInputMetrics()).setOutputMetrics(computer.getOutputMetrics()).build()); + .setInputMetrics(computer.getInputMetrics()).setOutputMetrics(computer.getOutputMetrics()).build()); } @Test diff --git a/cxx-squid/src/test/java/org/sonar/cxx/api/CppPunctuatorTest.java b/cxx-squid/src/test/java/org/sonar/cxx/api/CppPunctuatorTest.java index d6db763025..6bff60868a 100644 --- a/cxx-squid/src/test/java/org/sonar/cxx/api/CppPunctuatorTest.java +++ b/cxx-squid/src/test/java/org/sonar/cxx/api/CppPunctuatorTest.java @@ -21,11 +21,10 @@ import com.sonar.sslr.api.AstNode; import static org.assertj.core.api.Assertions.assertThat; +import org.assertj.core.api.SoftAssertions; import org.junit.Test; import static org.mockito.Mockito.mock; -import org.assertj.core.api.SoftAssertions; - public class CppPunctuatorTest { @Test diff --git a/cxx-squid/src/test/java/org/sonar/cxx/api/CxxPunctuatorTest.java b/cxx-squid/src/test/java/org/sonar/cxx/api/CxxPunctuatorTest.java index ff10fbc708..8e063adad7 100644 --- a/cxx-squid/src/test/java/org/sonar/cxx/api/CxxPunctuatorTest.java +++ b/cxx-squid/src/test/java/org/sonar/cxx/api/CxxPunctuatorTest.java @@ -20,9 +20,9 @@ package org.sonar.cxx.api; import com.sonar.sslr.api.AstNode; +import org.assertj.core.api.SoftAssertions; import org.junit.Test; import static org.mockito.Mockito.mock; -import org.assertj.core.api.SoftAssertions; public class CxxPunctuatorTest { diff --git a/cxx-squid/src/test/java/org/sonar/cxx/lexer/CxxLexerTest.java b/cxx-squid/src/test/java/org/sonar/cxx/lexer/CxxLexerTest.java index ab22894ef4..90d8acb779 100644 --- a/cxx-squid/src/test/java/org/sonar/cxx/lexer/CxxLexerTest.java +++ b/cxx-squid/src/test/java/org/sonar/cxx/lexer/CxxLexerTest.java @@ -21,27 +21,24 @@ import com.sonar.sslr.api.GenericTokenType; import com.sonar.sslr.impl.Lexer; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import static org.assertj.core.api.Assertions.assertThat; - import org.assertj.core.api.SoftAssertions; import org.junit.BeforeClass; import org.junit.Test; import static org.mockito.Mockito.mock; - -import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - import org.sonar.cxx.CxxFileTesterHelper; import org.sonar.cxx.CxxLanguage; import org.sonar.cxx.api.CxxKeyword; import org.sonar.cxx.api.CxxPunctuator; import org.sonar.cxx.api.CxxTokenType; +import static org.sonar.cxx.lexer.LexerAssert.assertThat; import org.sonar.cxx.preprocessor.CxxPreprocessor; import org.sonar.cxx.preprocessor.JoinStringsPreprocessor; import org.sonar.squidbridge.SquidAstVisitorContext; -import static org.sonar.cxx.lexer.LexerAssert.assertThat; public class CxxLexerTest { @@ -56,21 +53,22 @@ public static void init() { /** * C++ Standard, Section 2.8 "Comments" - * @throws URISyntaxException + * + * @throws URISyntaxException */ @Test public void comments_cxx() { SoftAssertions softly = new SoftAssertions(); - softly.assertThat(lexer.lex("//\n new line")).as("comment c++: empty").anySatisfy(token -> - assertThat(token).isValue("new").hasTrivia().isTrivia("//").isComment().isTriviaLine(1)); - softly.assertThat(lexer.lex("// My comment \\n new line")).as("\"comment c++: simple\"").anySatisfy(token -> - assertThat(token).isValue("EOF").hasTrivia().isTrivia("// My comment \\n new line").isComment().isTriviaLine(1)); - softly.assertThat(lexer.lex("// // \n new line")).as("comment c++: nested").anySatisfy(token -> - assertThat(token).isValue("new").hasTrivia().isTrivia("// // ").isComment().isTriviaLine(1)); - softly.assertThat(lexer.lex("// /**/ \n new line")).as("comment c++: nested2").anySatisfy(token -> - assertThat(token).isValue("new").hasTrivia().isTrivia("// /**/ ").isComment().isTriviaLine(1)); + softly.assertThat(lexer.lex("//\n new line")).as("comment c++: empty").anySatisfy(token + -> assertThat(token).isValue("new").hasTrivia().isTrivia("//").isComment().isTriviaLine(1)); + softly.assertThat(lexer.lex("// My comment \\n new line")).as("\"comment c++: simple\"").anySatisfy(token + -> assertThat(token).isValue("EOF").hasTrivia().isTrivia("// My comment \\n new line").isComment().isTriviaLine(1)); + softly.assertThat(lexer.lex("// // \n new line")).as("comment c++: nested").anySatisfy(token + -> assertThat(token).isValue("new").hasTrivia().isTrivia("// // ").isComment().isTriviaLine(1)); + softly.assertThat(lexer.lex("// /**/ \n new line")).as("comment c++: nested2").anySatisfy(token + -> assertThat(token).isValue("new").hasTrivia().isTrivia("// /**/ ").isComment().isTriviaLine(1)); softly.assertAll(); - } + } /** * C++ Standard, Section 2.8 "Comments" @@ -78,116 +76,113 @@ public void comments_cxx() { @Test public void comments_c() { SoftAssertions softly = new SoftAssertions(); - softly.assertThat(lexer.lex("/**/")).as("comment c: empty").anySatisfy(token -> - assertThat(token).isValue("EOF").hasTrivia().isTrivia("/**/").isComment().isTriviaLine(1)); - softly.assertThat(lexer.lex("/* My comment */")).as("comment c: simple").anySatisfy(token -> - assertThat(token).isValue("EOF").hasTrivia().isTrivia("/* My comment */").isComment().isTriviaLine(1)); - softly.assertThat(lexer.lex("/*\\\n*/")).as("comment c: with newline").anySatisfy(token -> - assertThat(token).isValue("EOF").hasTrivia().isTrivia("/*\\\n*/").isComment().isTriviaLine(1)); - softly.assertThat(lexer.lex("/*//*/")).as("comment c: nested").anySatisfy(token -> - assertThat(token).isValue("EOF").hasTrivia().isTrivia("/*//*/").isComment().isTriviaLine(1)); - softly.assertThat(lexer.lex("/* /* */")).as("comment c: nested2").anySatisfy(token -> - assertThat(token).isValue("EOF").hasTrivia().isTrivia("/* /* */").isComment().isTriviaLine(1)); + softly.assertThat(lexer.lex("/**/")).as("comment c: empty").anySatisfy(token + -> assertThat(token).isValue("EOF").hasTrivia().isTrivia("/**/").isComment().isTriviaLine(1)); + softly.assertThat(lexer.lex("/* My comment */")).as("comment c: simple").anySatisfy(token + -> assertThat(token).isValue("EOF").hasTrivia().isTrivia("/* My comment */").isComment().isTriviaLine(1)); + softly.assertThat(lexer.lex("/*\\\n*/")).as("comment c: with newline").anySatisfy(token + -> assertThat(token).isValue("EOF").hasTrivia().isTrivia("/*\\\n*/").isComment().isTriviaLine(1)); + softly.assertThat(lexer.lex("/*//*/")).as("comment c: nested").anySatisfy(token + -> assertThat(token).isValue("EOF").hasTrivia().isTrivia("/*//*/").isComment().isTriviaLine(1)); + softly.assertThat(lexer.lex("/* /* */")).as("comment c: nested2").anySatisfy(token + -> assertThat(token).isValue("EOF").hasTrivia().isTrivia("/* /* */").isComment().isTriviaLine(1)); softly.assertAll(); } - /** * C++ Standard, Section 2.14.2 "Integer literals" */ @Test public void decimal_integer_literals() { - final List values = - new ArrayList<>(Arrays.asList( - LiteralValuesBuilder.builder("0").tokenValue("0").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("7").tokenValue("7").tokenType(CxxTokenType.NUMBER).build(), - // With "UnsignedSuffix - LiteralValuesBuilder.builder("7u").tokenValue("7u").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("7U").tokenValue("7U").tokenType(CxxTokenType.NUMBER).build(), - // With "UnsignedSuffix LongSuffix" - LiteralValuesBuilder.builder("7ul").tokenValue("7ul").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("7uL").tokenValue("7uL").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("7Ul").tokenValue("7Ul").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("7UL").tokenValue("7UL").tokenType(CxxTokenType.NUMBER).build(), - // With "UnsignedSuffix LongLongSuffix" - LiteralValuesBuilder.builder("7ull").tokenValue("7ull").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("7uLL").tokenValue("7uLL").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("7Ull").tokenValue("7Ull").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("7ULL").tokenValue("7ULL").tokenType(CxxTokenType.NUMBER).build(), - // With "LongSuffix" - LiteralValuesBuilder.builder("7l").tokenValue("7l").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("7L").tokenValue("7L").tokenType(CxxTokenType.NUMBER).build(), - // With "LongSuffix UnsignedSuffix" - LiteralValuesBuilder.builder("7lu").tokenValue("7lu").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("7lU").tokenValue("7lU").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("7Lu").tokenValue("7Lu").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("7LU").tokenValue("7LU").tokenType(CxxTokenType.NUMBER).build(), - // With "LongLongSuffix" - LiteralValuesBuilder.builder("7ll").tokenValue("7ll").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("7LL").tokenValue("7LL").tokenType(CxxTokenType.NUMBER).build(), - // With "LongLongSuffix UnsignedSuffix" - LiteralValuesBuilder.builder("7llu").tokenValue("7llu").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("7llU").tokenValue("7llU").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("7LLu").tokenValue("7LLu").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("7LLU").tokenValue("7LLU").tokenType(CxxTokenType.NUMBER).build(), - // With Microsoft specific 64-bit integer-suffix: i64 - LiteralValuesBuilder.builder("7i64").tokenValue("7i64").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("7ui64").tokenValue("7ui64").tokenType(CxxTokenType.NUMBER).build() + final List values + = new ArrayList<>(Arrays.asList( + LiteralValuesBuilder.builder("0").tokenValue("0").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("7").tokenValue("7").tokenType(CxxTokenType.NUMBER).build(), + // With "UnsignedSuffix + LiteralValuesBuilder.builder("7u").tokenValue("7u").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("7U").tokenValue("7U").tokenType(CxxTokenType.NUMBER).build(), + // With "UnsignedSuffix LongSuffix" + LiteralValuesBuilder.builder("7ul").tokenValue("7ul").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("7uL").tokenValue("7uL").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("7Ul").tokenValue("7Ul").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("7UL").tokenValue("7UL").tokenType(CxxTokenType.NUMBER).build(), + // With "UnsignedSuffix LongLongSuffix" + LiteralValuesBuilder.builder("7ull").tokenValue("7ull").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("7uLL").tokenValue("7uLL").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("7Ull").tokenValue("7Ull").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("7ULL").tokenValue("7ULL").tokenType(CxxTokenType.NUMBER).build(), + // With "LongSuffix" + LiteralValuesBuilder.builder("7l").tokenValue("7l").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("7L").tokenValue("7L").tokenType(CxxTokenType.NUMBER).build(), + // With "LongSuffix UnsignedSuffix" + LiteralValuesBuilder.builder("7lu").tokenValue("7lu").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("7lU").tokenValue("7lU").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("7Lu").tokenValue("7Lu").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("7LU").tokenValue("7LU").tokenType(CxxTokenType.NUMBER).build(), + // With "LongLongSuffix" + LiteralValuesBuilder.builder("7ll").tokenValue("7ll").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("7LL").tokenValue("7LL").tokenType(CxxTokenType.NUMBER).build(), + // With "LongLongSuffix UnsignedSuffix" + LiteralValuesBuilder.builder("7llu").tokenValue("7llu").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("7llU").tokenValue("7llU").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("7LLu").tokenValue("7LLu").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("7LLU").tokenValue("7LLU").tokenType(CxxTokenType.NUMBER).build(), + // With Microsoft specific 64-bit integer-suffix: i64 + LiteralValuesBuilder.builder("7i64").tokenValue("7i64").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("7ui64").tokenValue("7ui64").tokenType(CxxTokenType.NUMBER).build() )); - values.forEach(value -> - assertThat(lexer.lex(value.lexerValue)).as("Literal %s", value.lexerValue).anySatisfy(token -> - assertThat(token).isValue(value.tokenValue).hasType(value.tokenType))); - } - - + values.forEach(value + -> assertThat(lexer.lex(value.lexerValue)).as("Literal %s", value.lexerValue).anySatisfy(token + -> assertThat(token).isValue(value.tokenValue).hasType(value.tokenType))); + } /** * C++ Standard, Section 2.14.2 "Integer literals" */ @Test public void octal_integer_literals() { - final List values = - new ArrayList<>(Arrays.asList( - // Octal integer - LiteralValuesBuilder.builder("07").tokenValue("07").tokenType(CxxTokenType.NUMBER).build(), - // With "UnsignedSuffix - LiteralValuesBuilder.builder("07u").tokenValue("07u").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("07U").tokenValue("07U").tokenType(CxxTokenType.NUMBER).build(), - // With "UnsignedSuffix LongSuffix" - LiteralValuesBuilder.builder("07ul").tokenValue("07ul").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("07uL").tokenValue("07uL").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("07Ul").tokenValue("07Ul").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("07UL").tokenValue("07UL").tokenType(CxxTokenType.NUMBER).build(), - // With "UnsignedSuffix LongLongSuffix" - LiteralValuesBuilder.builder("07ull").tokenValue("07ull").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("07uLL").tokenValue("07uLL").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("07Ull").tokenValue("07Ull").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("07ULL").tokenValue("07ULL").tokenType(CxxTokenType.NUMBER).build(), - // With "LongSuffix" - LiteralValuesBuilder.builder("07l").tokenValue("07l").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("07L").tokenValue("07L").tokenType(CxxTokenType.NUMBER).build(), - // With "LongSuffix UnsignedSuffix" - LiteralValuesBuilder.builder("07lu").tokenValue("07lu").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("07lU").tokenValue("07lU").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("07Lu").tokenValue("07Lu").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("07LU").tokenValue("07LU").tokenType(CxxTokenType.NUMBER).build(), - // With "LongLongSuffix" - LiteralValuesBuilder.builder("07ll").tokenValue("07ll").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("07LL").tokenValue("07LL").tokenType(CxxTokenType.NUMBER).build(), - // With "LongLongSuffix UnsignedSuffix" - LiteralValuesBuilder.builder("07llu").tokenValue("07llu").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("07llU").tokenValue("07llU").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("07LLu").tokenValue("07LLu").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("07LLU").tokenValue("07LLU").tokenType(CxxTokenType.NUMBER).build(), - // With Microsoft specific 64-bit integer-suffix: i64 - LiteralValuesBuilder.builder("07i64").tokenValue("07i64").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("07ui64").tokenValue("07ui64").tokenType(CxxTokenType.NUMBER).build() + final List values + = new ArrayList<>(Arrays.asList( + // Octal integer + LiteralValuesBuilder.builder("07").tokenValue("07").tokenType(CxxTokenType.NUMBER).build(), + // With "UnsignedSuffix + LiteralValuesBuilder.builder("07u").tokenValue("07u").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("07U").tokenValue("07U").tokenType(CxxTokenType.NUMBER).build(), + // With "UnsignedSuffix LongSuffix" + LiteralValuesBuilder.builder("07ul").tokenValue("07ul").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("07uL").tokenValue("07uL").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("07Ul").tokenValue("07Ul").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("07UL").tokenValue("07UL").tokenType(CxxTokenType.NUMBER).build(), + // With "UnsignedSuffix LongLongSuffix" + LiteralValuesBuilder.builder("07ull").tokenValue("07ull").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("07uLL").tokenValue("07uLL").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("07Ull").tokenValue("07Ull").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("07ULL").tokenValue("07ULL").tokenType(CxxTokenType.NUMBER).build(), + // With "LongSuffix" + LiteralValuesBuilder.builder("07l").tokenValue("07l").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("07L").tokenValue("07L").tokenType(CxxTokenType.NUMBER).build(), + // With "LongSuffix UnsignedSuffix" + LiteralValuesBuilder.builder("07lu").tokenValue("07lu").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("07lU").tokenValue("07lU").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("07Lu").tokenValue("07Lu").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("07LU").tokenValue("07LU").tokenType(CxxTokenType.NUMBER).build(), + // With "LongLongSuffix" + LiteralValuesBuilder.builder("07ll").tokenValue("07ll").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("07LL").tokenValue("07LL").tokenType(CxxTokenType.NUMBER).build(), + // With "LongLongSuffix UnsignedSuffix" + LiteralValuesBuilder.builder("07llu").tokenValue("07llu").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("07llU").tokenValue("07llU").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("07LLu").tokenValue("07LLu").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("07LLU").tokenValue("07LLU").tokenType(CxxTokenType.NUMBER).build(), + // With Microsoft specific 64-bit integer-suffix: i64 + LiteralValuesBuilder.builder("07i64").tokenValue("07i64").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("07ui64").tokenValue("07ui64").tokenType(CxxTokenType.NUMBER).build() )); - values.forEach(value -> - assertThat(lexer.lex(value.lexerValue)).as("Literal %s", value.lexerValue).anySatisfy(token -> - assertThat(token).isValue(value.tokenValue).hasType(value.tokenType))); + values.forEach(value + -> assertThat(lexer.lex(value.lexerValue)).as("Literal %s", value.lexerValue).anySatisfy(token + -> assertThat(token).isValue(value.tokenValue).hasType(value.tokenType))); } /** @@ -195,47 +190,47 @@ public void octal_integer_literals() { */ @Test public void hex_integer_literals() { - final List values = - new ArrayList<>(Arrays.asList( - // Hex integer - LiteralValuesBuilder.builder("0x7").tokenValue("0x7").tokenType(CxxTokenType.NUMBER).build(), - // With "UnsignedSuffix - LiteralValuesBuilder.builder("0x7u").tokenValue("0x7u").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0x7U").tokenValue("0x7U").tokenType(CxxTokenType.NUMBER).build(), - // With "UnsignedSuffix LongSuffix" - LiteralValuesBuilder.builder("0x7ul").tokenValue("0x7ul").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0x7uL").tokenValue("0x7uL").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0x7Ul").tokenValue("0x7Ul").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0x7UL").tokenValue("0x7UL").tokenType(CxxTokenType.NUMBER).build(), - // With "UnsignedSuffix LongLongSuffix" - LiteralValuesBuilder.builder("0x7ull").tokenValue("0x7ull").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0x7uLL").tokenValue("0x7uLL").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0x7Ull").tokenValue("0x7Ull").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0x7ULL").tokenValue("0x7ULL").tokenType(CxxTokenType.NUMBER).build(), - // With "LongSuffix" - LiteralValuesBuilder.builder("0x7l").tokenValue("0x7l").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0x7L").tokenValue("0x7L").tokenType(CxxTokenType.NUMBER).build(), - // With "LongSuffix UnsignedSuffix" - LiteralValuesBuilder.builder("0x7lu").tokenValue("0x7lu").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0x7lU").tokenValue("0x7lU").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0x7Lu").tokenValue("0x7Lu").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0x7LU").tokenValue("0x7LU").tokenType(CxxTokenType.NUMBER).build(), - // With "LongLongSuffix" - LiteralValuesBuilder.builder("0x7ll").tokenValue("0x7ll").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0x7LL").tokenValue("0x7LL").tokenType(CxxTokenType.NUMBER).build(), - // With "LongLongSuffix UnsignedSuffix" - LiteralValuesBuilder.builder("0x7llu").tokenValue("0x7llu").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0x7llU").tokenValue("0x7llU").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0x7LLu").tokenValue("0x7LLu").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0x7LLU").tokenValue("0x7LLU").tokenType(CxxTokenType.NUMBER).build(), - // With Microsoft specific 64-bit integer-suffix: i64 - LiteralValuesBuilder.builder("0x7i64").tokenValue("0x7i64").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0x7ui64").tokenValue("0x7ui64").tokenType(CxxTokenType.NUMBER).build() + final List values + = new ArrayList<>(Arrays.asList( + // Hex integer + LiteralValuesBuilder.builder("0x7").tokenValue("0x7").tokenType(CxxTokenType.NUMBER).build(), + // With "UnsignedSuffix + LiteralValuesBuilder.builder("0x7u").tokenValue("0x7u").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0x7U").tokenValue("0x7U").tokenType(CxxTokenType.NUMBER).build(), + // With "UnsignedSuffix LongSuffix" + LiteralValuesBuilder.builder("0x7ul").tokenValue("0x7ul").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0x7uL").tokenValue("0x7uL").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0x7Ul").tokenValue("0x7Ul").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0x7UL").tokenValue("0x7UL").tokenType(CxxTokenType.NUMBER).build(), + // With "UnsignedSuffix LongLongSuffix" + LiteralValuesBuilder.builder("0x7ull").tokenValue("0x7ull").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0x7uLL").tokenValue("0x7uLL").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0x7Ull").tokenValue("0x7Ull").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0x7ULL").tokenValue("0x7ULL").tokenType(CxxTokenType.NUMBER).build(), + // With "LongSuffix" + LiteralValuesBuilder.builder("0x7l").tokenValue("0x7l").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0x7L").tokenValue("0x7L").tokenType(CxxTokenType.NUMBER).build(), + // With "LongSuffix UnsignedSuffix" + LiteralValuesBuilder.builder("0x7lu").tokenValue("0x7lu").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0x7lU").tokenValue("0x7lU").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0x7Lu").tokenValue("0x7Lu").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0x7LU").tokenValue("0x7LU").tokenType(CxxTokenType.NUMBER).build(), + // With "LongLongSuffix" + LiteralValuesBuilder.builder("0x7ll").tokenValue("0x7ll").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0x7LL").tokenValue("0x7LL").tokenType(CxxTokenType.NUMBER).build(), + // With "LongLongSuffix UnsignedSuffix" + LiteralValuesBuilder.builder("0x7llu").tokenValue("0x7llu").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0x7llU").tokenValue("0x7llU").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0x7LLu").tokenValue("0x7LLu").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0x7LLU").tokenValue("0x7LLU").tokenType(CxxTokenType.NUMBER).build(), + // With Microsoft specific 64-bit integer-suffix: i64 + LiteralValuesBuilder.builder("0x7i64").tokenValue("0x7i64").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0x7ui64").tokenValue("0x7ui64").tokenType(CxxTokenType.NUMBER).build() )); - values.forEach(value -> - assertThat(lexer.lex(value.lexerValue)).as("Literal %s", value.lexerValue).anySatisfy(token -> - assertThat(token).isValue(value.tokenValue).hasType(value.tokenType))); + values.forEach(value + -> assertThat(lexer.lex(value.lexerValue)).as("Literal %s", value.lexerValue).anySatisfy(token + -> assertThat(token).isValue(value.tokenValue).hasType(value.tokenType))); } /** @@ -243,17 +238,17 @@ public void hex_integer_literals() { */ @Test public void bin_integer_literals() { - final List values = - new ArrayList<>(Arrays.asList( - // bin integer - LiteralValuesBuilder.builder("0b0").tokenValue("0b0").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0B1").tokenValue("0B1").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0b10101001").tokenValue("0b10101001").tokenType(CxxTokenType.NUMBER).build() - )); - - values.forEach(value -> - assertThat(lexer.lex(value.lexerValue)).as("Literal %s", value.lexerValue).anySatisfy(token -> - assertThat(token).isValue(value.tokenValue).hasType(value.tokenType))); + final List values + = new ArrayList<>(Arrays.asList( + // bin integer + LiteralValuesBuilder.builder("0b0").tokenValue("0b0").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0B1").tokenValue("0B1").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0b10101001").tokenValue("0b10101001").tokenType(CxxTokenType.NUMBER).build() + )); + + values.forEach(value + -> assertThat(lexer.lex(value.lexerValue)).as("Literal %s", value.lexerValue).anySatisfy(token + -> assertThat(token).isValue(value.tokenValue).hasType(value.tokenType))); } /** @@ -261,47 +256,47 @@ public void bin_integer_literals() { */ @Test public void hex_integer_literals_bigX() { - final List values = - new ArrayList<>(Arrays.asList( - // Hex integer (big X) - LiteralValuesBuilder.builder("0X7").tokenValue("0X7").tokenType(CxxTokenType.NUMBER).build(), - // With "UnsignedSuffix - LiteralValuesBuilder.builder("0X7u").tokenValue("0X7u").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0X7U").tokenValue("0X7U").tokenType(CxxTokenType.NUMBER).build(), - // With "UnsignedSuffix LongSuffix" - LiteralValuesBuilder.builder("0X7ul").tokenValue("0X7ul").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0X7uL").tokenValue("0X7uL").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0X7Ul").tokenValue("0X7Ul").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0X7UL").tokenValue("0X7UL").tokenType(CxxTokenType.NUMBER).build(), - // With "UnsignedSuffix LongLongSuffix" - LiteralValuesBuilder.builder("0X7ull").tokenValue("0X7ull").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0X7uLL").tokenValue("0X7uLL").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0X7Ull").tokenValue("0X7Ull").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0X7ULL").tokenValue("0X7ULL").tokenType(CxxTokenType.NUMBER).build(), - // With "LongSuffix" - LiteralValuesBuilder.builder("0X7l").tokenValue("0X7l").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0X7L").tokenValue("0X7L").tokenType(CxxTokenType.NUMBER).build(), - // With "LongSuffix UnsignedSuffix" - LiteralValuesBuilder.builder("0X7lu").tokenValue("0X7lu").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0X7lU").tokenValue("0X7lU").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0X7Lu").tokenValue("0X7Lu").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0X7LU").tokenValue("0X7LU").tokenType(CxxTokenType.NUMBER).build(), - // With "LongLongSuffix" - LiteralValuesBuilder.builder("0X7ll").tokenValue("0X7ll").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0X7LL").tokenValue("0X7LL").tokenType(CxxTokenType.NUMBER).build(), - // With "LongLongSuffix UnsignedSuffix" - LiteralValuesBuilder.builder("0X7llu").tokenValue("0X7llu").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0X7llU").tokenValue("0X7llU").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0X7LLu").tokenValue("0X7LLu").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0X7LLU").tokenValue("0X7LLU").tokenType(CxxTokenType.NUMBER).build(), - // With Microsoft specific 64-bit integer-suffix: i64 - LiteralValuesBuilder.builder("0X7i64").tokenValue("0X7i64").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0X7ui64").tokenValue("0X7ui64").tokenType(CxxTokenType.NUMBER).build() + final List values + = new ArrayList<>(Arrays.asList( + // Hex integer (big X) + LiteralValuesBuilder.builder("0X7").tokenValue("0X7").tokenType(CxxTokenType.NUMBER).build(), + // With "UnsignedSuffix + LiteralValuesBuilder.builder("0X7u").tokenValue("0X7u").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0X7U").tokenValue("0X7U").tokenType(CxxTokenType.NUMBER).build(), + // With "UnsignedSuffix LongSuffix" + LiteralValuesBuilder.builder("0X7ul").tokenValue("0X7ul").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0X7uL").tokenValue("0X7uL").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0X7Ul").tokenValue("0X7Ul").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0X7UL").tokenValue("0X7UL").tokenType(CxxTokenType.NUMBER).build(), + // With "UnsignedSuffix LongLongSuffix" + LiteralValuesBuilder.builder("0X7ull").tokenValue("0X7ull").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0X7uLL").tokenValue("0X7uLL").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0X7Ull").tokenValue("0X7Ull").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0X7ULL").tokenValue("0X7ULL").tokenType(CxxTokenType.NUMBER).build(), + // With "LongSuffix" + LiteralValuesBuilder.builder("0X7l").tokenValue("0X7l").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0X7L").tokenValue("0X7L").tokenType(CxxTokenType.NUMBER).build(), + // With "LongSuffix UnsignedSuffix" + LiteralValuesBuilder.builder("0X7lu").tokenValue("0X7lu").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0X7lU").tokenValue("0X7lU").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0X7Lu").tokenValue("0X7Lu").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0X7LU").tokenValue("0X7LU").tokenType(CxxTokenType.NUMBER).build(), + // With "LongLongSuffix" + LiteralValuesBuilder.builder("0X7ll").tokenValue("0X7ll").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0X7LL").tokenValue("0X7LL").tokenType(CxxTokenType.NUMBER).build(), + // With "LongLongSuffix UnsignedSuffix" + LiteralValuesBuilder.builder("0X7llu").tokenValue("0X7llu").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0X7llU").tokenValue("0X7llU").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0X7LLu").tokenValue("0X7LLu").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0X7LLU").tokenValue("0X7LLU").tokenType(CxxTokenType.NUMBER).build(), + // With Microsoft specific 64-bit integer-suffix: i64 + LiteralValuesBuilder.builder("0X7i64").tokenValue("0X7i64").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0X7ui64").tokenValue("0X7ui64").tokenType(CxxTokenType.NUMBER).build() )); - values.forEach(value -> - assertThat(lexer.lex(value.lexerValue)).as("Literal %s", value.lexerValue).anySatisfy(token -> - assertThat(token).isValue(value.tokenValue).hasType(value.tokenType))); + values.forEach(value + -> assertThat(lexer.lex(value.lexerValue)).as("Literal %s", value.lexerValue).anySatisfy(token + -> assertThat(token).isValue(value.tokenValue).hasType(value.tokenType))); } /** @@ -309,47 +304,47 @@ public void hex_integer_literals_bigX() { */ @Test public void bin_integer_literals_bigB() { - final List values = - new ArrayList<>(Arrays.asList( - // Binary literal (big B) - LiteralValuesBuilder.builder("0B1").tokenValue("0B1").tokenType(CxxTokenType.NUMBER).build(), - // With "UnsignedSuffix - LiteralValuesBuilder.builder("0B1u").tokenValue("0B1u").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0B1U").tokenValue("0B1U").tokenType(CxxTokenType.NUMBER).build(), - // With "UnsignedSuffix LongSuffix" - LiteralValuesBuilder.builder("0B1ul").tokenValue("0B1ul").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0B1uL").tokenValue("0B1uL").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0B1Ul").tokenValue("0B1Ul").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0B1UL").tokenValue("0B1UL").tokenType(CxxTokenType.NUMBER).build(), - // With "UnsignedSuffix LongLongSuffix" - LiteralValuesBuilder.builder("0B1ull").tokenValue("0B1ull").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0B1uLL").tokenValue("0B1uLL").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0B1Ull").tokenValue("0B1Ull").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0B1ULL").tokenValue("0B1ULL").tokenType(CxxTokenType.NUMBER).build(), - // With "LongSuffix" - LiteralValuesBuilder.builder("0B1l").tokenValue("0B1l").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0B1L").tokenValue("0B1L").tokenType(CxxTokenType.NUMBER).build(), - // With "LongSuffix UnsignedSuffix" - LiteralValuesBuilder.builder("0B1lu").tokenValue("0B1lu").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0B1lU").tokenValue("0B1lU").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0B1Lu").tokenValue("0B1Lu").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0B1LU").tokenValue("0B1LU").tokenType(CxxTokenType.NUMBER).build(), - // With "LongLongSuffix" - LiteralValuesBuilder.builder("0B1ll").tokenValue("0B1ll").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0B1LL").tokenValue("0B1LL").tokenType(CxxTokenType.NUMBER).build(), - // With "LongLongSuffix UnsignedSuffix" - LiteralValuesBuilder.builder("0B1llu").tokenValue("0B1llu").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0B1llU").tokenValue("0B1llU").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0B1LLu").tokenValue("0B1LLu").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0B1LLU").tokenValue("0B1LLU").tokenType(CxxTokenType.NUMBER).build(), - // With Microsoft specific 64-bit integer-suffix: i64 - LiteralValuesBuilder.builder("0B1i64").tokenValue("0B1i64").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0B1ui64").tokenValue("0B1ui64").tokenType(CxxTokenType.NUMBER).build() + final List values + = new ArrayList<>(Arrays.asList( + // Binary literal (big B) + LiteralValuesBuilder.builder("0B1").tokenValue("0B1").tokenType(CxxTokenType.NUMBER).build(), + // With "UnsignedSuffix + LiteralValuesBuilder.builder("0B1u").tokenValue("0B1u").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0B1U").tokenValue("0B1U").tokenType(CxxTokenType.NUMBER).build(), + // With "UnsignedSuffix LongSuffix" + LiteralValuesBuilder.builder("0B1ul").tokenValue("0B1ul").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0B1uL").tokenValue("0B1uL").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0B1Ul").tokenValue("0B1Ul").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0B1UL").tokenValue("0B1UL").tokenType(CxxTokenType.NUMBER).build(), + // With "UnsignedSuffix LongLongSuffix" + LiteralValuesBuilder.builder("0B1ull").tokenValue("0B1ull").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0B1uLL").tokenValue("0B1uLL").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0B1Ull").tokenValue("0B1Ull").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0B1ULL").tokenValue("0B1ULL").tokenType(CxxTokenType.NUMBER).build(), + // With "LongSuffix" + LiteralValuesBuilder.builder("0B1l").tokenValue("0B1l").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0B1L").tokenValue("0B1L").tokenType(CxxTokenType.NUMBER).build(), + // With "LongSuffix UnsignedSuffix" + LiteralValuesBuilder.builder("0B1lu").tokenValue("0B1lu").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0B1lU").tokenValue("0B1lU").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0B1Lu").tokenValue("0B1Lu").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0B1LU").tokenValue("0B1LU").tokenType(CxxTokenType.NUMBER).build(), + // With "LongLongSuffix" + LiteralValuesBuilder.builder("0B1ll").tokenValue("0B1ll").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0B1LL").tokenValue("0B1LL").tokenType(CxxTokenType.NUMBER).build(), + // With "LongLongSuffix UnsignedSuffix" + LiteralValuesBuilder.builder("0B1llu").tokenValue("0B1llu").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0B1llU").tokenValue("0B1llU").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0B1LLu").tokenValue("0B1LLu").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0B1LLU").tokenValue("0B1LLU").tokenType(CxxTokenType.NUMBER).build(), + // With Microsoft specific 64-bit integer-suffix: i64 + LiteralValuesBuilder.builder("0B1i64").tokenValue("0B1i64").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0B1ui64").tokenValue("0B1ui64").tokenType(CxxTokenType.NUMBER).build() )); - values.forEach(value -> - assertThat(lexer.lex(value.lexerValue)).as("Literal %s", value.lexerValue).anySatisfy(token -> - assertThat(token).isValue(value.tokenValue).hasType(value.tokenType))); + values.forEach(value + -> assertThat(lexer.lex(value.lexerValue)).as("Literal %s", value.lexerValue).anySatisfy(token + -> assertThat(token).isValue(value.tokenValue).hasType(value.tokenType))); } /** @@ -357,59 +352,55 @@ public void bin_integer_literals_bigB() { */ @Test public void floating_point_literals() { - final List values = - new ArrayList<>(Arrays.asList( - LiteralValuesBuilder.builder("3.14").tokenValue("3.14").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("10.").tokenValue("10.").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder(".001").tokenValue(".001").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("1e100").tokenValue("1e100").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("3.14e-10").tokenValue("3.14e-10").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("3.14E-10").tokenValue("3.14E-10").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0e0").tokenValue("0e0").tokenType(CxxTokenType.NUMBER).build(), - - LiteralValuesBuilder.builder("3.14f").tokenValue("3.14f").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("10.f").tokenValue("10.f").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder(".001f").tokenValue(".001f").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("1e100f").tokenValue("1e100f").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("3.14e-10f").tokenValue("3.14e-10f").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("3.14E-10f").tokenValue("3.14E-10f").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0e0f").tokenValue("0e0f").tokenType(CxxTokenType.NUMBER).build(), - - LiteralValuesBuilder.builder("3.14F").tokenValue("3.14F").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("10.F").tokenValue("10.F").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder(".001F").tokenValue(".001F").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("1e100F").tokenValue("1e100F").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("3.14e-10F").tokenValue("3.14e-10F").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("3.14E-10F").tokenValue("3.14E-10F").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0e0F").tokenValue("0e0F").tokenType(CxxTokenType.NUMBER).build(), - - LiteralValuesBuilder.builder("3.14l").tokenValue("3.14l").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("10.l").tokenValue("10.l").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder(".001l").tokenValue(".001l").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("1e100l").tokenValue("1e100l").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("3.14e-10l").tokenValue("3.14e-10l").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("3.14E-10l").tokenValue("3.14E-10l").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0e0l").tokenValue("0e0l").tokenType(CxxTokenType.NUMBER).build(), - - LiteralValuesBuilder.builder("3.14L").tokenValue("3.14L").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("10.L").tokenValue("10.L").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder(".001L").tokenValue(".001L").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("1e100L").tokenValue("1e100L").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("3.14e-10L").tokenValue("3.14e-10L").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("3.14E-10L").tokenValue("3.14E-10L").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0e0L").tokenValue("0e0L").tokenType(CxxTokenType.NUMBER).build(), - // c++17: hexadecimal floating literals - LiteralValuesBuilder.builder("0x1ffp10").tokenValue("0x1ffp10").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0X0p-1").tokenValue("0X0p-1").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0x1.p0").tokenValue("0x1.p0").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0xf.p-1").tokenValue("0xf.p-1").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0x0.123p-1").tokenValue("0x0.123p-1").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0xa.bp10l").tokenValue("0xa.bp10l").tokenType(CxxTokenType.NUMBER).build() + final List values + = new ArrayList<>(Arrays.asList( + LiteralValuesBuilder.builder("3.14").tokenValue("3.14").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("10.").tokenValue("10.").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder(".001").tokenValue(".001").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("1e100").tokenValue("1e100").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("3.14e-10").tokenValue("3.14e-10").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("3.14E-10").tokenValue("3.14E-10").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0e0").tokenValue("0e0").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("3.14f").tokenValue("3.14f").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("10.f").tokenValue("10.f").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder(".001f").tokenValue(".001f").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("1e100f").tokenValue("1e100f").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("3.14e-10f").tokenValue("3.14e-10f").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("3.14E-10f").tokenValue("3.14E-10f").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0e0f").tokenValue("0e0f").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("3.14F").tokenValue("3.14F").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("10.F").tokenValue("10.F").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder(".001F").tokenValue(".001F").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("1e100F").tokenValue("1e100F").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("3.14e-10F").tokenValue("3.14e-10F").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("3.14E-10F").tokenValue("3.14E-10F").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0e0F").tokenValue("0e0F").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("3.14l").tokenValue("3.14l").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("10.l").tokenValue("10.l").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder(".001l").tokenValue(".001l").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("1e100l").tokenValue("1e100l").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("3.14e-10l").tokenValue("3.14e-10l").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("3.14E-10l").tokenValue("3.14E-10l").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0e0l").tokenValue("0e0l").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("3.14L").tokenValue("3.14L").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("10.L").tokenValue("10.L").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder(".001L").tokenValue(".001L").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("1e100L").tokenValue("1e100L").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("3.14e-10L").tokenValue("3.14e-10L").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("3.14E-10L").tokenValue("3.14E-10L").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0e0L").tokenValue("0e0L").tokenType(CxxTokenType.NUMBER).build(), + // c++17: hexadecimal floating literals + LiteralValuesBuilder.builder("0x1ffp10").tokenValue("0x1ffp10").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0X0p-1").tokenValue("0X0p-1").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0x1.p0").tokenValue("0x1.p0").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0xf.p-1").tokenValue("0xf.p-1").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0x0.123p-1").tokenValue("0x0.123p-1").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0xa.bp10l").tokenValue("0xa.bp10l").tokenType(CxxTokenType.NUMBER).build() )); - values.forEach(value -> - assertThat(lexer.lex(value.lexerValue)).as("Literal %s", value.lexerValue).anySatisfy(token -> - assertThat(token).isValue(value.tokenValue).hasType(value.tokenType))); + values.forEach(value + -> assertThat(lexer.lex(value.lexerValue)).as("Literal %s", value.lexerValue).anySatisfy(token + -> assertThat(token).isValue(value.tokenValue).hasType(value.tokenType))); } /** @@ -417,19 +408,19 @@ public void floating_point_literals() { */ @Test public void user_defined_literals() { - final List values = - new ArrayList<>(Arrays.asList( - LiteralValuesBuilder.builder("12_w").tokenValue("12_w").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("1.2_w").tokenValue("1.2_w").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0x123ABC_print").tokenValue("0x123ABC_print").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0b101010_print").tokenValue("0b101010_print").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("\"two\"_w").tokenValue("\"two\"_w").tokenType(CxxTokenType.STRING).build(), - LiteralValuesBuilder.builder("'X'_w").tokenValue("'X'_w").tokenType(CxxTokenType.CHARACTER).build() - )); - - values.forEach(value -> - assertThat(lexer.lex(value.lexerValue)).as("Literal %s", value.lexerValue).anySatisfy(token -> - assertThat(token).isValue(value.tokenValue).hasType(value.tokenType))); + final List values + = new ArrayList<>(Arrays.asList( + LiteralValuesBuilder.builder("12_w").tokenValue("12_w").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("1.2_w").tokenValue("1.2_w").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0x123ABC_print").tokenValue("0x123ABC_print").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0b101010_print").tokenValue("0b101010_print").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("\"two\"_w").tokenValue("\"two\"_w").tokenType(CxxTokenType.STRING).build(), + LiteralValuesBuilder.builder("'X'_w").tokenValue("'X'_w").tokenType(CxxTokenType.CHARACTER).build() + )); + + values.forEach(value + -> assertThat(lexer.lex(value.lexerValue)).as("Literal %s", value.lexerValue).anySatisfy(token + -> assertThat(token).isValue(value.tokenValue).hasType(value.tokenType))); } /** @@ -437,22 +428,22 @@ public void user_defined_literals() { */ @Test public void digit_separators() { - final List values = - new ArrayList<>(Arrays.asList( - LiteralValuesBuilder.builder("1'000'000").tokenValue("1'000'000").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0b0100'1100'0110").tokenValue("0b0100'1100'0110").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("00'04'00'00'00").tokenValue("00'04'00'00'00").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("0x10'0000").tokenValue("0x10'0000").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("1'000.000'015'3").tokenValue("1'000.000'015'3").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("1'000.").tokenValue("1'000.").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder(".000'015'3").tokenValue(".000'015'3").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("1'000e-10").tokenValue("1'000e-10").tokenType(CxxTokenType.NUMBER).build(), - LiteralValuesBuilder.builder("1'000e-1'000").tokenValue("1'000e-1'000").tokenType(CxxTokenType.NUMBER).build() - )); - - values.forEach(value -> - assertThat(lexer.lex(value.lexerValue)).as("Literal %s", value.lexerValue).anySatisfy(token -> - assertThat(token).isValue(value.tokenValue).hasType(value.tokenType))); + final List values + = new ArrayList<>(Arrays.asList( + LiteralValuesBuilder.builder("1'000'000").tokenValue("1'000'000").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0b0100'1100'0110").tokenValue("0b0100'1100'0110").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("00'04'00'00'00").tokenValue("00'04'00'00'00").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("0x10'0000").tokenValue("0x10'0000").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("1'000.000'015'3").tokenValue("1'000.000'015'3").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("1'000.").tokenValue("1'000.").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder(".000'015'3").tokenValue(".000'015'3").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("1'000e-10").tokenValue("1'000e-10").tokenType(CxxTokenType.NUMBER).build(), + LiteralValuesBuilder.builder("1'000e-1'000").tokenValue("1'000e-1'000").tokenType(CxxTokenType.NUMBER).build() + )); + + values.forEach(value + -> assertThat(lexer.lex(value.lexerValue)).as("Literal %s", value.lexerValue).anySatisfy(token + -> assertThat(token).isValue(value.tokenValue).hasType(value.tokenType))); } /** @@ -460,15 +451,15 @@ public void digit_separators() { */ @Test public void boolean_literals() { - final List values = - new ArrayList<>(Arrays.asList( - LiteralValuesBuilder.builder("true").tokenValue("true").tokenType(CxxKeyword.TRUE).build(), - LiteralValuesBuilder.builder("false").tokenValue("false").tokenType(CxxKeyword.FALSE).build() - )); - - values.forEach(value -> - assertThat(lexer.lex(value.lexerValue)).as("Literal %s", value.lexerValue).anySatisfy(token -> - assertThat(token).isValue(value.tokenValue).hasType(value.tokenType))); + final List values + = new ArrayList<>(Arrays.asList( + LiteralValuesBuilder.builder("true").tokenValue("true").tokenType(CxxKeyword.TRUE).build(), + LiteralValuesBuilder.builder("false").tokenValue("false").tokenType(CxxKeyword.FALSE).build() + )); + + values.forEach(value + -> assertThat(lexer.lex(value.lexerValue)).as("Literal %s", value.lexerValue).anySatisfy(token + -> assertThat(token).isValue(value.tokenValue).hasType(value.tokenType))); } /** @@ -476,14 +467,14 @@ public void boolean_literals() { */ @Test public void pointer_literals() { - final List values = - new ArrayList<>(Arrays.asList( - LiteralValuesBuilder.builder("nullptr").tokenValue("nullptr").tokenType(CxxTokenType.NUMBER).build() - )); - - values.forEach(value -> - assertThat(lexer.lex(value.lexerValue)).as("Literal %s", value.lexerValue).anySatisfy(token -> - assertThat(token).isValue(value.tokenValue).hasType(value.tokenType))); + final List values + = new ArrayList<>(Arrays.asList( + LiteralValuesBuilder.builder("nullptr").tokenValue("nullptr").tokenType(CxxTokenType.NUMBER).build() + )); + + values.forEach(value + -> assertThat(lexer.lex(value.lexerValue)).as("Literal %s", value.lexerValue).anySatisfy(token + -> assertThat(token).isValue(value.tokenValue).hasType(value.tokenType))); } /** @@ -491,26 +482,26 @@ public void pointer_literals() { */ @Test public void character_literals() { - final List values = - new ArrayList<>(Arrays.asList( - LiteralValuesBuilder.builder("''").tokenValue("''").tokenType(CxxTokenType.CHARACTER).build(), // char: empty - LiteralValuesBuilder.builder("u''").tokenValue("u''").tokenType(CxxTokenType.CHARACTER).build(), // char: prefix u - LiteralValuesBuilder.builder("U''").tokenValue("U''").tokenType(CxxTokenType.CHARACTER).build(), // char: prefix U - LiteralValuesBuilder.builder("L''").tokenValue("L''").tokenType(CxxTokenType.CHARACTER).build(), // char: prefix L - - LiteralValuesBuilder.builder("'a'").tokenValue("'a'").tokenType(CxxTokenType.CHARACTER).build(), // char: trivial - LiteralValuesBuilder.builder("'ab'").tokenValue("'ab'").tokenType(CxxTokenType.CHARACTER).build(), //char: more than one - - LiteralValuesBuilder.builder("'\\''").tokenValue("'\\''").tokenType(CxxTokenType.CHARACTER).build(), // char: escaped quote - LiteralValuesBuilder.builder("'\\\\'").tokenValue("'\\\\'").tokenType(CxxTokenType.CHARACTER).build(), // char: escaped backslash - - LiteralValuesBuilder.builder("'").tokenValue("'").tokenType(GenericTokenType.UNKNOWN_CHAR).build(), - LiteralValuesBuilder.builder("'\\'").tokenValue("'").tokenType(GenericTokenType.UNKNOWN_CHAR).build() // This are 3 Tokens of UNKNOWN_CHAR - )); - - values.forEach(value -> - assertThat(lexer.lex(value.lexerValue)).as("Literal %s", value.lexerValue).anySatisfy(token -> - assertThat(token).isValue(value.tokenValue).hasType(value.tokenType))); + final List values + = new ArrayList<>(Arrays.asList( + LiteralValuesBuilder.builder("''").tokenValue("''").tokenType(CxxTokenType.CHARACTER).build(), // char: empty + LiteralValuesBuilder.builder("u''").tokenValue("u''").tokenType(CxxTokenType.CHARACTER).build(), // char: prefix u + LiteralValuesBuilder.builder("U''").tokenValue("U''").tokenType(CxxTokenType.CHARACTER).build(), // char: prefix U + LiteralValuesBuilder.builder("L''").tokenValue("L''").tokenType(CxxTokenType.CHARACTER).build(), // char: prefix L + + LiteralValuesBuilder.builder("'a'").tokenValue("'a'").tokenType(CxxTokenType.CHARACTER).build(), // char: trivial + LiteralValuesBuilder.builder("'ab'").tokenValue("'ab'").tokenType(CxxTokenType.CHARACTER).build(), //char: more than one + + LiteralValuesBuilder.builder("'\\''").tokenValue("'\\''").tokenType(CxxTokenType.CHARACTER).build(), // char: escaped quote + LiteralValuesBuilder.builder("'\\\\'").tokenValue("'\\\\'").tokenType(CxxTokenType.CHARACTER).build(), // char: escaped backslash + + LiteralValuesBuilder.builder("'").tokenValue("'").tokenType(GenericTokenType.UNKNOWN_CHAR).build(), + LiteralValuesBuilder.builder("'\\'").tokenValue("'").tokenType(GenericTokenType.UNKNOWN_CHAR).build() // This are 3 Tokens of UNKNOWN_CHAR + )); + + values.forEach(value + -> assertThat(lexer.lex(value.lexerValue)).as("Literal %s", value.lexerValue).anySatisfy(token + -> assertThat(token).isValue(value.tokenValue).hasType(value.tokenType))); } /** @@ -518,90 +509,90 @@ public void character_literals() { */ @Test public void string_literals() { - final List values = - new ArrayList<>(Arrays.asList( - LiteralValuesBuilder.builder("\"\"").tokenValue("\"\"").tokenType(CxxTokenType.STRING).build(), // string: empty - LiteralValuesBuilder.builder("u\"\"").tokenValue("u\"\"").tokenType(CxxTokenType.STRING).build(), // string: prefix u - LiteralValuesBuilder.builder("u8\"\"").tokenValue("u8\"\"").tokenType(CxxTokenType.STRING).build(), // string: prefix U - LiteralValuesBuilder.builder("U\"\"").tokenValue("U\"\"").tokenType(CxxTokenType.STRING).build(), // string: prefix L + final List values + = new ArrayList<>(Arrays.asList( + LiteralValuesBuilder.builder("\"\"").tokenValue("\"\"").tokenType(CxxTokenType.STRING).build(), // string: empty + LiteralValuesBuilder.builder("u\"\"").tokenValue("u\"\"").tokenType(CxxTokenType.STRING).build(), // string: prefix u + LiteralValuesBuilder.builder("u8\"\"").tokenValue("u8\"\"").tokenType(CxxTokenType.STRING).build(), // string: prefix U + LiteralValuesBuilder.builder("U\"\"").tokenValue("U\"\"").tokenType(CxxTokenType.STRING).build(), // string: prefix L - LiteralValuesBuilder.builder("\"a\"").tokenValue("\"a\"").tokenType(CxxTokenType.STRING).build(), // string: trivial + LiteralValuesBuilder.builder("\"a\"").tokenValue("\"a\"").tokenType(CxxTokenType.STRING).build(), // string: trivial - LiteralValuesBuilder.builder("\" \\\\ \"").tokenValue("\" \\\\ \"").tokenType(CxxTokenType.STRING).build(), // string: escaped quote - LiteralValuesBuilder.builder("\" \\\" \"").tokenValue("\" \\\" \"").tokenType(CxxTokenType.STRING).build(), // string: escaped backslash + LiteralValuesBuilder.builder("\" \\\\ \"").tokenValue("\" \\\\ \"").tokenType(CxxTokenType.STRING).build(), // string: escaped quote + LiteralValuesBuilder.builder("\" \\\" \"").tokenValue("\" \\\" \"").tokenType(CxxTokenType.STRING).build(), // string: escaped backslash - LiteralValuesBuilder.builder("\"").tokenValue("\"").tokenType(GenericTokenType.UNKNOWN_CHAR).build(), // string: unterminated - LiteralValuesBuilder.builder("\"\\\"").tokenValue("\\").tokenType(GenericTokenType.UNKNOWN_CHAR).build() // string: unescaped backslash - )); + LiteralValuesBuilder.builder("\"").tokenValue("\"").tokenType(GenericTokenType.UNKNOWN_CHAR).build(), // string: unterminated + LiteralValuesBuilder.builder("\"\\\"").tokenValue("\\").tokenType(GenericTokenType.UNKNOWN_CHAR).build() // string: unescaped backslash + )); - values.forEach(value -> - assertThat(lexer.lex(value.lexerValue)).as("Literal %s", value.lexerValue).anySatisfy(token -> - assertThat(token).isValue(value.tokenValue).hasType(value.tokenType))); + values.forEach(value + -> assertThat(lexer.lex(value.lexerValue)).as("Literal %s", value.lexerValue).anySatisfy(token + -> assertThat(token).isValue(value.tokenValue).hasType(value.tokenType))); } @Test public void rawstring_literals() { - final List values = - new ArrayList<>(Arrays.asList( - LiteralValuesBuilder.builder("R\"(...)\"").tokenValue("R\"(...)\"").tokenType(CxxTokenType.STRING).build(), // raw string: empty - LiteralValuesBuilder.builder("uR\"(...)\"").tokenValue("uR\"(...)\"").tokenType(CxxTokenType.STRING).build(), // raw string: prefix u - LiteralValuesBuilder.builder("u8R\"(...)\"").tokenValue("u8R\"(...)\"").tokenType(CxxTokenType.STRING).build(), // raw string: prefix u8R - LiteralValuesBuilder.builder("UR\"(...)\"").tokenValue("UR\"(...)\"").tokenType(CxxTokenType.STRING).build(), // raw string: prefix UR - LiteralValuesBuilder.builder("LR\"(...)\"").tokenValue("LR\"(...)\"").tokenType(CxxTokenType.STRING).build(), // raw string: prefix LR - // examples from the standard - LiteralValuesBuilder.builder("R\"(...)\"").tokenValue("R\"(...)\"").tokenType(CxxTokenType.STRING).build(), // raw string: std example 1 - LiteralValuesBuilder.builder("u8R\"**(...)**\"").tokenValue("u8R\"**(...)**\"").tokenType(CxxTokenType.STRING).build(), // raw string: std example 2 - LiteralValuesBuilder.builder("uR\"*∼(...)*∼\"").tokenValue("uR\"*∼(...)*∼\"").tokenType(CxxTokenType.STRING).build(), // raw string: std example 3 - LiteralValuesBuilder.builder("UR\"zzz(...)zzz\"").tokenValue("UR\"zzz(...)zzz\"").tokenType(CxxTokenType.STRING).build(), // raw string: std example 4 - LiteralValuesBuilder.builder("LR\"(...)\"").tokenValue("LR\"(...)\"").tokenType(CxxTokenType.STRING).build(), // raw string: std example 5 - - LiteralValuesBuilder.builder("R\"(An unescaped \\ character)\"").tokenValue("R\"(An unescaped \\ character)\"") - .tokenType(CxxTokenType.STRING).build(), // raw string: an unescaped \\ character - LiteralValuesBuilder.builder("R\"(An unescaped \" character)\"").tokenValue("R\"(An unescaped \" character)\"") - .tokenType(CxxTokenType.STRING).build(), // raw string: an unescaped \" character - LiteralValuesBuilder.builder("R\"xyz()\")xyz\"").tokenValue("R\"xyz()\")xyz\"") - .tokenType(CxxTokenType.STRING).build(), // raw string: represent the string: )\" - LiteralValuesBuilder.builder("R\"X*X(A C++11 raw string literal can be specified like this: R\"(This is my raw string)\" )X*X\"") - .tokenValue("R\"X*X(A C++11 raw string literal can be specified like this: R\"(This is my raw string)\" )X*X\"") - .tokenType(CxxTokenType.STRING).build(), // raw string: complex example - LiteralValuesBuilder.builder("R\"([.^$|()\\[\\]{}*+?\\\\])\"").tokenValue("R\"([.^$|()\\[\\]{}*+?\\\\])\"") - .tokenType(CxxTokenType.STRING).build() // raw string: regex sample - )); - - values.forEach(value -> - assertThat(lexer.lex(value.lexerValue)).as("Literal %s", value.lexerValue).anySatisfy(token -> - assertThat(token).isValue(value.tokenValue).hasType(value.tokenType))); + final List values + = new ArrayList<>(Arrays.asList( + LiteralValuesBuilder.builder("R\"(...)\"").tokenValue("R\"(...)\"").tokenType(CxxTokenType.STRING).build(), // raw string: empty + LiteralValuesBuilder.builder("uR\"(...)\"").tokenValue("uR\"(...)\"").tokenType(CxxTokenType.STRING).build(), // raw string: prefix u + LiteralValuesBuilder.builder("u8R\"(...)\"").tokenValue("u8R\"(...)\"").tokenType(CxxTokenType.STRING).build(), // raw string: prefix u8R + LiteralValuesBuilder.builder("UR\"(...)\"").tokenValue("UR\"(...)\"").tokenType(CxxTokenType.STRING).build(), // raw string: prefix UR + LiteralValuesBuilder.builder("LR\"(...)\"").tokenValue("LR\"(...)\"").tokenType(CxxTokenType.STRING).build(), // raw string: prefix LR + // examples from the standard + LiteralValuesBuilder.builder("R\"(...)\"").tokenValue("R\"(...)\"").tokenType(CxxTokenType.STRING).build(), // raw string: std example 1 + LiteralValuesBuilder.builder("u8R\"**(...)**\"").tokenValue("u8R\"**(...)**\"").tokenType(CxxTokenType.STRING).build(), // raw string: std example 2 + LiteralValuesBuilder.builder("uR\"*∼(...)*∼\"").tokenValue("uR\"*∼(...)*∼\"").tokenType(CxxTokenType.STRING).build(), // raw string: std example 3 + LiteralValuesBuilder.builder("UR\"zzz(...)zzz\"").tokenValue("UR\"zzz(...)zzz\"").tokenType(CxxTokenType.STRING).build(), // raw string: std example 4 + LiteralValuesBuilder.builder("LR\"(...)\"").tokenValue("LR\"(...)\"").tokenType(CxxTokenType.STRING).build(), // raw string: std example 5 + + LiteralValuesBuilder.builder("R\"(An unescaped \\ character)\"").tokenValue("R\"(An unescaped \\ character)\"") + .tokenType(CxxTokenType.STRING).build(), // raw string: an unescaped \\ character + LiteralValuesBuilder.builder("R\"(An unescaped \" character)\"").tokenValue("R\"(An unescaped \" character)\"") + .tokenType(CxxTokenType.STRING).build(), // raw string: an unescaped \" character + LiteralValuesBuilder.builder("R\"xyz()\")xyz\"").tokenValue("R\"xyz()\")xyz\"") + .tokenType(CxxTokenType.STRING).build(), // raw string: represent the string: )\" + LiteralValuesBuilder.builder("R\"X*X(A C++11 raw string literal can be specified like this: R\"(This is my raw string)\" )X*X\"") + .tokenValue("R\"X*X(A C++11 raw string literal can be specified like this: R\"(This is my raw string)\" )X*X\"") + .tokenType(CxxTokenType.STRING).build(), // raw string: complex example + LiteralValuesBuilder.builder("R\"([.^$|()\\[\\]{}*+?\\\\])\"").tokenValue("R\"([.^$|()\\[\\]{}*+?\\\\])\"") + .tokenType(CxxTokenType.STRING).build() // raw string: regex sample + )); + + values.forEach(value + -> assertThat(lexer.lex(value.lexerValue)).as("Literal %s", value.lexerValue).anySatisfy(token + -> assertThat(token).isValue(value.tokenValue).hasType(value.tokenType))); } @Test public void operators_and_delimiters() { - final List values = - new ArrayList<>(Arrays.asList( - LiteralValuesBuilder.builder(":").tokenValue(":").tokenType(CxxPunctuator.COLON).build(), - LiteralValuesBuilder.builder("=").tokenValue("=").tokenType(CxxPunctuator.ASSIGN).build(), - LiteralValuesBuilder.builder("~").tokenValue("~").tokenType(CxxPunctuator.BW_NOT).build() - )); - - values.forEach(value -> - assertThat(lexer.lex(value.lexerValue)).as("Operator|Delimiter %s", value.lexerValue).anySatisfy(token -> - assertThat(token).isValue(value.tokenValue).hasType(value.tokenType))); + final List values + = new ArrayList<>(Arrays.asList( + LiteralValuesBuilder.builder(":").tokenValue(":").tokenType(CxxPunctuator.COLON).build(), + LiteralValuesBuilder.builder("=").tokenValue("=").tokenType(CxxPunctuator.ASSIGN).build(), + LiteralValuesBuilder.builder("~").tokenValue("~").tokenType(CxxPunctuator.BW_NOT).build() + )); + + values.forEach(value + -> assertThat(lexer.lex(value.lexerValue)).as("Operator|Delimiter %s", value.lexerValue).anySatisfy(token + -> assertThat(token).isValue(value.tokenValue).hasType(value.tokenType))); } @Test public void keywords_and_identifiers() { - final List values = - new ArrayList<>(Arrays.asList( - LiteralValuesBuilder.builder("return").tokenValue("return").tokenType(CxxKeyword.RETURN).build(), - LiteralValuesBuilder.builder("identifier").tokenValue("identifier").tokenType(GenericTokenType.IDENTIFIER).build(), - LiteralValuesBuilder.builder("a1").tokenValue("a1").tokenType(GenericTokenType.IDENTIFIER).build(), - LiteralValuesBuilder.builder("A1").tokenValue("A1").tokenType(GenericTokenType.IDENTIFIER).build(), - LiteralValuesBuilder.builder("A_a_A_1").tokenValue("A_a_A_1").tokenType(GenericTokenType.IDENTIFIER).build(), - LiteralValuesBuilder.builder("truetype").tokenValue("truetype").tokenType(GenericTokenType.IDENTIFIER).build() //identifier: containing boolean constant - )); - - values.forEach(value -> - assertThat(lexer.lex(value.lexerValue)).as("Keyword|Identifier %s", value.lexerValue).anySatisfy(token -> - assertThat(token).isValue(value.tokenValue).hasType(value.tokenType))); + final List values + = new ArrayList<>(Arrays.asList( + LiteralValuesBuilder.builder("return").tokenValue("return").tokenType(CxxKeyword.RETURN).build(), + LiteralValuesBuilder.builder("identifier").tokenValue("identifier").tokenType(GenericTokenType.IDENTIFIER).build(), + LiteralValuesBuilder.builder("a1").tokenValue("a1").tokenType(GenericTokenType.IDENTIFIER).build(), + LiteralValuesBuilder.builder("A1").tokenValue("A1").tokenType(GenericTokenType.IDENTIFIER).build(), + LiteralValuesBuilder.builder("A_a_A_1").tokenValue("A_a_A_1").tokenType(GenericTokenType.IDENTIFIER).build(), + LiteralValuesBuilder.builder("truetype").tokenValue("truetype").tokenType(GenericTokenType.IDENTIFIER).build() //identifier: containing boolean constant + )); + + values.forEach(value + -> assertThat(lexer.lex(value.lexerValue)).as("Keyword|Identifier %s", value.lexerValue).anySatisfy(token + -> assertThat(token).isValue(value.tokenValue).hasType(value.tokenType))); } @Test diff --git a/cxx-squid/src/test/java/org/sonar/cxx/lexer/CxxLexerWithPreprocessingTest.java b/cxx-squid/src/test/java/org/sonar/cxx/lexer/CxxLexerWithPreprocessingTest.java index c1400987f1..9f443ba004 100644 --- a/cxx-squid/src/test/java/org/sonar/cxx/lexer/CxxLexerWithPreprocessingTest.java +++ b/cxx-squid/src/test/java/org/sonar/cxx/lexer/CxxLexerWithPreprocessingTest.java @@ -42,11 +42,11 @@ import org.sonar.cxx.api.CxxKeyword; import org.sonar.cxx.api.CxxPunctuator; import org.sonar.cxx.api.CxxTokenType; +import static org.sonar.cxx.lexer.LexerAssert.assertThat; import org.sonar.cxx.preprocessor.CxxPreprocessor; import org.sonar.cxx.preprocessor.JoinStringsPreprocessor; import org.sonar.cxx.preprocessor.SourceCodeProvider; import org.sonar.squidbridge.SquidAstVisitorContext; -import static org.sonar.cxx.lexer.LexerAssert.assertThat; public class CxxLexerWithPreprocessingTest { @@ -62,12 +62,12 @@ public CxxLexerWithPreprocessingTest() { @Test public void escaping_newline() { SoftAssertions softly = new SoftAssertions(); - softly.assertThat(lexer.lex("line\\\r\nline")).as("dos style").noneMatch(token -> - token.getValue().contentEquals("\\") && token.getType().equals(GenericTokenType.UNKNOWN_CHAR)); - softly.assertThat(lexer.lex("line\\\rline")).as("mac(old) style").noneMatch(token -> - token.getValue().contentEquals("\\") && token.getType().equals(GenericTokenType.UNKNOWN_CHAR)); - softly.assertThat(lexer.lex("line\\\nline")).as("unix style").noneMatch(token -> - token.getValue().contentEquals("\\") && token.getType().equals(GenericTokenType.UNKNOWN_CHAR)); + softly.assertThat(lexer.lex("line\\\r\nline")).as("dos style").noneMatch(token + -> token.getValue().contentEquals("\\") && token.getType().equals(GenericTokenType.UNKNOWN_CHAR)); + softly.assertThat(lexer.lex("line\\\rline")).as("mac(old) style").noneMatch(token + -> token.getValue().contentEquals("\\") && token.getType().equals(GenericTokenType.UNKNOWN_CHAR)); + softly.assertThat(lexer.lex("line\\\nline")).as("unix style").noneMatch(token + -> token.getValue().contentEquals("\\") && token.getType().equals(GenericTokenType.UNKNOWN_CHAR)); softly.assertThat(lexer.lex("line\\\n line")).hasSize(3); softly.assertAll(); } @@ -75,12 +75,12 @@ public void escaping_newline() { @Test public void joining_strings() { SoftAssertions softly = new SoftAssertions(); - softly.assertThat(lexer.lex("\"string\"")).anySatisfy(token -> - assertThat(token).isValue("\"string\"").hasType(CxxTokenType.STRING)); - softly.assertThat(lexer.lex("\"string\"\"string\"")).anySatisfy(token -> - assertThat(token).isValue("\"stringstring\"").hasType(CxxTokenType.STRING)); - softly.assertThat(lexer.lex("\"string\"\n\"string\"")).anySatisfy(token -> - assertThat(token).isValue("\"stringstring\"").hasType(CxxTokenType.STRING)); + softly.assertThat(lexer.lex("\"string\"")).anySatisfy(token + -> assertThat(token).isValue("\"string\"").hasType(CxxTokenType.STRING)); + softly.assertThat(lexer.lex("\"string\"\"string\"")).anySatisfy(token + -> assertThat(token).isValue("\"stringstring\"").hasType(CxxTokenType.STRING)); + softly.assertThat(lexer.lex("\"string\"\n\"string\"")).anySatisfy(token + -> assertThat(token).isValue("\"stringstring\"").hasType(CxxTokenType.STRING)); softly.assertThat(lexer.lex("\"string\"\"string\"")).hasSize(2); // string + EOF softly.assertAll(); } @@ -90,7 +90,7 @@ public void expanding_objectlike_macros() { List tokens = lexer.lex("#define lala \"haha\"\nlala"); SoftAssertions softly = new SoftAssertions(); softly.assertThat(tokens).hasSize(2); - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("\"haha\"").hasType(CxxTokenType.STRING)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("\"haha\"").hasType(CxxTokenType.STRING)); softly.assertAll(); } @@ -99,7 +99,7 @@ public void expanding_functionlike_macros() { List tokens = lexer.lex("#define plus(a, b) a + b\n plus(1, 2)"); SoftAssertions softly = new SoftAssertions(); softly.assertThat(tokens).hasSize(4); - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("1").hasType(CxxTokenType.NUMBER)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("1").hasType(CxxTokenType.NUMBER)); softly.assertAll(); } @@ -108,8 +108,8 @@ public void expanding_functionlike_macros_withvarargs() { List tokens = lexer.lex("#define wrapper(...) __VA_ARGS__\n wrapper(1, 2)"); SoftAssertions softly = new SoftAssertions(); softly.assertThat(tokens).hasSize(4); - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("1").hasType(CxxTokenType.NUMBER)); - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("2").hasType(CxxTokenType.NUMBER)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("1").hasType(CxxTokenType.NUMBER)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("2").hasType(CxxTokenType.NUMBER)); softly.assertAll(); } @@ -118,8 +118,8 @@ public void expanding_functionlike_macros_withnamedvarargs() { List tokens = lexer.lex("#define wrapper(args...) args\n wrapper(1, 2)"); SoftAssertions softly = new SoftAssertions(); softly.assertThat(tokens).hasSize(4); - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("1").hasType(CxxTokenType.NUMBER)); - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("2").hasType(CxxTokenType.NUMBER)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("1").hasType(CxxTokenType.NUMBER)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("2").hasType(CxxTokenType.NUMBER)); softly.assertAll(); } @@ -128,8 +128,8 @@ public void expanding_functionlike_macros_withemptyvarargs() { List tokens = lexer.lex("#define wrapper(...) (__VA_ARGS__)\n wrapper()"); SoftAssertions softly = new SoftAssertions(); softly.assertThat(tokens).hasSize(3); - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("(").hasType(CxxPunctuator.BR_LEFT)); - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue(")").hasType(CxxPunctuator.BR_RIGHT)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("(").hasType(CxxPunctuator.BR_LEFT)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue(")").hasType(CxxPunctuator.BR_RIGHT)); softly.assertAll(); } @@ -138,7 +138,7 @@ public void expanding_macro_with_empty_parameterlist() { List tokens = lexer.lex("#define M() 0\n M()"); SoftAssertions softly = new SoftAssertions(); softly.assertThat(tokens).hasSize(2); - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("0").hasType(CxxTokenType.NUMBER)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("0").hasType(CxxTokenType.NUMBER)); softly.assertAll(); } @@ -147,7 +147,7 @@ public void expanding_functionlike_macros_withextraparantheses() { List tokens = lexer.lex("#define neg(a) -a\n neg((1))"); SoftAssertions softly = new SoftAssertions(); softly.assertThat(tokens).hasSize(5); - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("(").hasType(CxxPunctuator.BR_LEFT)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("(").hasType(CxxPunctuator.BR_LEFT)); softly.assertAll(); } @@ -156,7 +156,7 @@ public void expanding_hashoperator() { List tokens = lexer.lex("#define str(a) # a\n str(x)"); SoftAssertions softly = new SoftAssertions(); softly.assertThat(tokens).hasSize(2); - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("\"x\"").hasType(CxxTokenType.STRING)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("\"x\"").hasType(CxxTokenType.STRING)); softly.assertAll(); } @@ -165,7 +165,7 @@ public void expanding_hashhash_operator() { List tokens = lexer.lex("#define concat(a,b) a ## b\n concat(x,y)"); SoftAssertions softly = new SoftAssertions(); softly.assertThat(tokens).hasSize(2); // xy + EOF - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("xy").hasType(GenericTokenType.IDENTIFIER)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("xy").hasType(GenericTokenType.IDENTIFIER)); softly.assertAll(); } @@ -174,7 +174,7 @@ public void expanding_hashhash_operator_withoutparams() { List tokens = lexer.lex("#define hashhash c ## c\n hashhash"); SoftAssertions softly = new SoftAssertions(); softly.assertThat(tokens).hasSize(2); // cc + EOF - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("cc").hasType(GenericTokenType.IDENTIFIER)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("cc").hasType(GenericTokenType.IDENTIFIER)); softly.assertAll(); } @@ -183,7 +183,7 @@ public void expanding_sequenceof_hashhash_operators() { List tokens = lexer.lex("#define concat(a,b) a ## ## ## b\n concat(x,y)"); SoftAssertions softly = new SoftAssertions(); softly.assertThat(tokens).hasSize(2); // xy + EOF - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("xy").hasType(GenericTokenType.IDENTIFIER)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("xy").hasType(GenericTokenType.IDENTIFIER)); softly.assertAll(); } @@ -192,7 +192,7 @@ public void expanding_many_hashhash_operators() { List tokens = lexer.lex("#define concat(a,b) c ## c ## c ## c\n concat(x,y)"); SoftAssertions softly = new SoftAssertions(); softly.assertThat(tokens).hasSize(2); // cccc + EOF - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("cccc").hasType(GenericTokenType.IDENTIFIER)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("cccc").hasType(GenericTokenType.IDENTIFIER)); softly.assertAll(); } @@ -211,27 +211,27 @@ public void hashhash_arguments_with_whitespace_before_comma() { SoftAssertions softly = new SoftAssertions(); softly.assertThat(tokens).hasSize(2); // yes + EOF - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("yes").hasType(GenericTokenType.IDENTIFIER)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("yes").hasType(GenericTokenType.IDENTIFIER)); softly.assertAll(); } - @Test + @Test public void expanding_hashhash_operator_sampleFromCPPStandard() { // TODO: think about implementing this behavior. This is a sample from the standard, which is // not working yet. Because the current implementation throws away all 'irrelevant' // preprocessor directives too early, I guess. - List tokens = lexer.lex("#define hash_hash(x) # ## #\n" - + "#define mkstr(a) # a\n" - + "#define in_between(a) mkstr(a)\n" - + "#define join(c, d) in_between(c hash_hash(x) d)\n" - + "join(x,y)"); - - SoftAssertions softly = new SoftAssertions(); - softly.assertThat(tokens).hasSize(2); //"x ## y" + EOF + List tokens = lexer.lex("#define hash_hash(x) # ## #\n" + + "#define mkstr(a) # a\n" + + "#define in_between(a) mkstr(a)\n" + + "#define join(c, d) in_between(c hash_hash(x) d)\n" + + "join(x,y)"); + + SoftAssertions softly = new SoftAssertions(); + softly.assertThat(tokens).hasSize(2); //"x ## y" + EOF // softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("\"x ## y\"").hasType(CxxTokenType.STRING)); - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("\"x y\"").hasType(CxxTokenType.STRING)); - softly.assertAll(); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("\"x y\"").hasType(CxxTokenType.STRING)); + softly.assertAll(); } @Test @@ -239,7 +239,7 @@ public void expanding_hashoperator_quoting1() { List tokens = lexer.lex("#define str(a) # a\n str(\"x\")"); SoftAssertions softly = new SoftAssertions(); softly.assertThat(tokens).hasSize(2); - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("\"\\\"x\\\"\"").hasType(CxxTokenType.STRING)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("\"\\\"x\\\"\"").hasType(CxxTokenType.STRING)); softly.assertAll(); } @@ -250,7 +250,7 @@ public void expanding_chained_macros() { + "M2"); SoftAssertions softly = new SoftAssertions(); softly.assertThat(tokens).hasSize(2); - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("\"a\"").hasType(CxxTokenType.STRING)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("\"a\"").hasType(CxxTokenType.STRING)); softly.assertAll(); } @@ -261,8 +261,8 @@ public void expanding_chained_macros2() { + "M2"); SoftAssertions softly = new SoftAssertions(); softly.assertThat(tokens).hasSize(5); - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("\"a\"").hasType(CxxTokenType.STRING)); - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("foo").hasType(GenericTokenType.IDENTIFIER)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("\"a\"").hasType(CxxTokenType.STRING)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("foo").hasType(GenericTokenType.IDENTIFIER)); softly.assertAll(); } @@ -273,8 +273,8 @@ public void expanding_chained_macros3() { + "M2"); SoftAssertions softly = new SoftAssertions(); softly.assertThat(tokens).hasSize(5); - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("M1").hasType(GenericTokenType.IDENTIFIER)); - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("foo").hasType(GenericTokenType.IDENTIFIER)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("M1").hasType(GenericTokenType.IDENTIFIER)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("foo").hasType(GenericTokenType.IDENTIFIER)); softly.assertAll(); } @@ -285,7 +285,7 @@ public void joining_strings_after_macro_expansion() { + "X"); SoftAssertions softly = new SoftAssertions(); softly.assertThat(tokens).hasSize(2); // string + EOF - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("\"hello, world\"").hasType(CxxTokenType.STRING)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("\"hello, world\"").hasType(CxxTokenType.STRING)); softly.assertAll(); } @@ -296,7 +296,7 @@ public void joining_strings_after_macro_expansion2() { + "N"); SoftAssertions softly = new SoftAssertions(); softly.assertThat(tokens).hasSize(2); // string + EOF - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("\"ABC\"").hasType(CxxTokenType.STRING)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("\"ABC\"").hasType(CxxTokenType.STRING)); softly.assertAll(); } @@ -306,7 +306,7 @@ public void joining_strings_after_macro_expansion3() { + "\"A\" M"); SoftAssertions softly = new SoftAssertions(); softly.assertThat(tokens).hasSize(2); // string + EOF - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("\"AB\"").hasType(CxxTokenType.STRING)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("\"AB\"").hasType(CxxTokenType.STRING)); softly.assertAll(); } @@ -316,15 +316,15 @@ public void preserving_whitespace() { + "CODE(new B())"); SoftAssertions softly = new SoftAssertions(); softly.assertThat(tokens).hasSize(5); - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("new").hasType(CxxKeyword.NEW)); - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("B").hasType(GenericTokenType.IDENTIFIER)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("new").hasType(CxxKeyword.NEW)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("B").hasType(GenericTokenType.IDENTIFIER)); softly.assertAll(); } @Test public void bodyless_defines() { - assertThat(lexer.lex("#define M\n" + "M")).noneMatch(token ->token.getValue().contentEquals("M")) - .noneMatch(token ->token.getType().equals(GenericTokenType.IDENTIFIER)); + assertThat(lexer.lex("#define M\n" + "M")).noneMatch(token -> token.getValue().contentEquals("M")) + .noneMatch(token -> token.getType().equals(GenericTokenType.IDENTIFIER)); } @Test @@ -337,7 +337,7 @@ public void external_define() { List tokens = lexer.lex("M"); SoftAssertions softly = new SoftAssertions(); softly.assertThat(tokens).hasSize(2); - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("body").hasType(GenericTokenType.IDENTIFIER)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("body").hasType(GenericTokenType.IDENTIFIER)); softly.assertAll(); } @@ -351,7 +351,7 @@ public void external_defines_with_params() { List tokens = lexer.lex("minus(1, 2)"); SoftAssertions softly = new SoftAssertions(); softly.assertThat(tokens).hasSize(4); - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("1").hasType(CxxTokenType.NUMBER)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("1").hasType(CxxTokenType.NUMBER)); softly.assertAll(); } @@ -361,7 +361,7 @@ public void using_keyword_as_macro_name() { + "new"); SoftAssertions softly = new SoftAssertions(); softly.assertThat(tokens).hasSize(2); // identifier + EOF - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("new_debug").hasType(GenericTokenType.IDENTIFIER)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("new_debug").hasType(GenericTokenType.IDENTIFIER)); softly.assertAll(); } @@ -371,7 +371,7 @@ public void using_keyword_as_macro_parameter() { + "macro(a)"); SoftAssertions softly = new SoftAssertions(); softly.assertThat(tokens).hasSize(2); // identifier + EOF - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("a").hasType(GenericTokenType.IDENTIFIER)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("a").hasType(GenericTokenType.IDENTIFIER)); softly.assertAll(); } @@ -381,8 +381,8 @@ public void using_macro_name_as_macro_identifier() { + "X(new)"); SoftAssertions softly = new SoftAssertions(); softly.assertThat(tokens).hasSize(6); // new + X + ( + new + ) + EOF - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("new").hasType(CxxKeyword.NEW)); - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("X").hasType(GenericTokenType.IDENTIFIER)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("new").hasType(CxxKeyword.NEW)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("X").hasType(GenericTokenType.IDENTIFIER)); softly.assertAll(); } @@ -392,7 +392,7 @@ public void using_keyword_as_macro_argument() { + "X(new)"); SoftAssertions softly = new SoftAssertions(); softly.assertThat(tokens).hasSize(2); // kw + EOF - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("new").hasType(CxxKeyword.NEW)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("new").hasType(CxxKeyword.NEW)); softly.assertAll(); } @@ -412,7 +412,7 @@ public void includes_are_working() throws IOException { + "A"); SoftAssertions softly = new SoftAssertions(); softly.assertThat(tokens).hasSize(2); // B + EOF - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("B").hasType(GenericTokenType.IDENTIFIER)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("B").hasType(GenericTokenType.IDENTIFIER)); softly.assertAll(); } @@ -432,8 +432,8 @@ public void conditional_compilation_ifdef_undefined() { + "#endif\n"); SoftAssertions softly = new SoftAssertions(); - softly.assertThat(tokens).noneMatch(token ->token.getValue().contentEquals("111") && token.getType().equals(CxxTokenType.NUMBER)); - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("222").hasType(CxxTokenType.NUMBER)); + softly.assertThat(tokens).noneMatch(token -> token.getValue().contentEquals("111") && token.getType().equals(CxxTokenType.NUMBER)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("222").hasType(CxxTokenType.NUMBER)); softly.assertAll(); } @@ -447,8 +447,8 @@ public void conditional_compilation_ifdef_defined() { + "#endif\n"); SoftAssertions softly = new SoftAssertions(); - softly.assertThat(tokens).noneMatch(token ->token.getValue().contentEquals("222") && token.getType().equals(CxxTokenType.NUMBER)); - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("111").hasType(CxxTokenType.NUMBER)); + softly.assertThat(tokens).noneMatch(token -> token.getValue().contentEquals("222") && token.getType().equals(CxxTokenType.NUMBER)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("111").hasType(CxxTokenType.NUMBER)); softly.assertAll(); } @@ -462,7 +462,7 @@ public void conditional_compilation_ifndef_undefined() { SoftAssertions softly = new SoftAssertions(); softly.assertThat(tokens).hasSize(2); // 111 + EOF - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("111").hasType(CxxTokenType.NUMBER)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("111").hasType(CxxTokenType.NUMBER)); softly.assertAll(); } @@ -477,7 +477,7 @@ public void conditional_compilation_ifndef_defined() { SoftAssertions softly = new SoftAssertions(); softly.assertThat(tokens).hasSize(2); // 222 + EOF - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("222").hasType(CxxTokenType.NUMBER)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("222").hasType(CxxTokenType.NUMBER)); softly.assertAll(); } @@ -498,7 +498,7 @@ public void conditional_compilation_ifdef_nested() { SoftAssertions softly = new SoftAssertions(); softly.assertThat(tokens).hasSize(2); // nota + EOF - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("nota").hasType(GenericTokenType.IDENTIFIER)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("nota").hasType(GenericTokenType.IDENTIFIER)); softly.assertAll(); } @@ -512,7 +512,7 @@ public void conditional_compilation_if_false() { SoftAssertions softly = new SoftAssertions(); softly.assertThat(tokens).hasSize(2); // nota + EOF - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("nota").hasType(GenericTokenType.IDENTIFIER)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("nota").hasType(GenericTokenType.IDENTIFIER)); softly.assertAll(); } @@ -526,7 +526,7 @@ public void conditional_compilation_if_true() { SoftAssertions softly = new SoftAssertions(); softly.assertThat(tokens).hasSize(2); // a + EOF - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("a").hasType(GenericTokenType.IDENTIFIER)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("a").hasType(GenericTokenType.IDENTIFIER)); softly.assertAll(); } @@ -541,7 +541,7 @@ public void conditional_compilation_if_identifier_true() { SoftAssertions softly = new SoftAssertions(); softly.assertThat(tokens).hasSize(2); // a + EOF - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("a").hasType(GenericTokenType.IDENTIFIER)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("a").hasType(GenericTokenType.IDENTIFIER)); softly.assertAll(); } @@ -555,7 +555,7 @@ public void conditional_compilation_if_identifier_false() { SoftAssertions softly = new SoftAssertions(); assertThat(tokens).hasSize(2); // nota + EOF - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("nota").hasType(GenericTokenType.IDENTIFIER)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("nota").hasType(GenericTokenType.IDENTIFIER)); softly.assertAll(); } @@ -573,7 +573,7 @@ public void nested_ifs() { SoftAssertions softly = new SoftAssertions(); assertThat(tokens).hasSize(2); // nota + EOF - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("nota").hasType(GenericTokenType.IDENTIFIER)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("nota").hasType(GenericTokenType.IDENTIFIER)); softly.assertAll(); } @@ -586,7 +586,7 @@ public void macro_expanding_to_parantheses() { // belong to the replacement string List tokens = lexer.lex("#define macro ()\n" + "macro\n"); - assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("(").hasType(CxxPunctuator.BR_LEFT)); + assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("(").hasType(CxxPunctuator.BR_LEFT)); } @Test @@ -598,7 +598,7 @@ public void assume_true_if_cannot_evaluate_if_expression() { + "#endif\n"); SoftAssertions softly = new SoftAssertions(); softly.assertThat(tokens).hasSize(2); // a + EOF - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("a").hasType(GenericTokenType.IDENTIFIER)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("a").hasType(GenericTokenType.IDENTIFIER)); softly.assertAll(); } @@ -620,7 +620,7 @@ public void externalMacrosCannotBeOverriden() { SoftAssertions softly = new SoftAssertions(); softly.assertThat(tokens).hasSize(2); // goodvalue + EOF - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("goodvalue").hasType(GenericTokenType.IDENTIFIER)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("goodvalue").hasType(GenericTokenType.IDENTIFIER)); softly.assertAll(); } @@ -634,7 +634,7 @@ public void elif_expression() { SoftAssertions softly = new SoftAssertions(); softly.assertThat(tokens).hasSize(2); // elif + EOF - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("elif").hasType(GenericTokenType.IDENTIFIER)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("elif").hasType(GenericTokenType.IDENTIFIER)); softly.assertAll(); } @@ -646,7 +646,7 @@ public void continued_preprocessor_directive() { + "external"); SoftAssertions softly = new SoftAssertions(); softly.assertThat(tokens).hasSize(2); // external + EOF - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("external").hasType(GenericTokenType.IDENTIFIER)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("external").hasType(GenericTokenType.IDENTIFIER)); softly.assertAll(); } @@ -669,7 +669,7 @@ public void undef_works() { + "a\n"); SoftAssertions softly = new SoftAssertions(); softly.assertThat(tokens).hasSize(2); // a + EOF - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("a").hasType(GenericTokenType.IDENTIFIER)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("a").hasType(GenericTokenType.IDENTIFIER)); softly.assertAll(); } @@ -684,7 +684,7 @@ public void function_like_macros_in_if_expressions() { + "#endif"); SoftAssertions softly = new SoftAssertions(); softly.assertThat(tokens).hasSize(2); // falsecase + EOF - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("falsecase").hasType(GenericTokenType.IDENTIFIER)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("falsecase").hasType(GenericTokenType.IDENTIFIER)); softly.assertAll(); } @@ -698,7 +698,7 @@ public void proper_expansion_of_function_like_macros_in_if_expressions() { + "#endif"); SoftAssertions softly = new SoftAssertions(); softly.assertThat(tokens).hasSize(2); // falsecase + EOF - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("truecase").hasType(GenericTokenType.IDENTIFIER)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("truecase").hasType(GenericTokenType.IDENTIFIER)); softly.assertAll(); } @@ -712,7 +712,7 @@ public void problem_with_chained_defined_expressions() { + "#endif"); SoftAssertions softly = new SoftAssertions(); softly.assertThat(tokens).hasSize(2); // falsecase + EOF - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("falsecase").hasType(GenericTokenType.IDENTIFIER)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("falsecase").hasType(GenericTokenType.IDENTIFIER)); softly.assertAll(); } @@ -728,7 +728,7 @@ public void problem_evaluating_elif_expressions() { + "endif\n"); SoftAssertions softly = new SoftAssertions(); softly.assertThat(tokens).hasSize(2); // truecase + EOF - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("truecase").hasType(GenericTokenType.IDENTIFIER)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("truecase").hasType(GenericTokenType.IDENTIFIER)); softly.assertAll(); } @@ -737,7 +737,7 @@ public void built_in_macros() { List tokens = lexer.lex("__DATE__"); SoftAssertions softly = new SoftAssertions(); softly.assertThat(tokens).hasSize(2); // date + EOF - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).hasType(CxxTokenType.STRING)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).hasType(CxxTokenType.STRING)); softly.assertAll(); } @@ -753,7 +753,7 @@ public void dont_look_at_subsequent_clauses_if_elif() { + "#endif"); SoftAssertions softly = new SoftAssertions(); softly.assertThat(tokens).hasSize(2); // ifbody + EOF - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("ifbody").hasType(GenericTokenType.IDENTIFIER)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("ifbody").hasType(GenericTokenType.IDENTIFIER)); softly.assertAll(); } @@ -771,7 +771,7 @@ public void dont_look_at_subsequent_clauses_elif_elif() { + "#endif\n"); SoftAssertions softly = new SoftAssertions(); softly.assertThat(tokens).hasSize(2); // case2 + EOF - softly.assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("case2").hasType(GenericTokenType.IDENTIFIER)); + softly.assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("case2").hasType(GenericTokenType.IDENTIFIER)); softly.assertAll(); } @@ -785,6 +785,6 @@ public void hashhash_operator_problem() { List tokens = lexer.lex("#define A B(cf)\n" + "#define B(n) 0x##n\n" + "A"); - assertThat(tokens).anySatisfy(token ->assertThat(token).isValue("0xcf").hasType(CxxKeyword.INT)); + assertThat(tokens).anySatisfy(token -> assertThat(token).isValue("0xcf").hasType(CxxKeyword.INT)); } } diff --git a/cxx-squid/src/test/java/org/sonar/cxx/lexer/CxxLexer_PreprocessorDisabled_Test.java b/cxx-squid/src/test/java/org/sonar/cxx/lexer/CxxLexer_PreprocessorDisabled_Test.java index e311e6b475..710bc499e3 100644 --- a/cxx-squid/src/test/java/org/sonar/cxx/lexer/CxxLexer_PreprocessorDisabled_Test.java +++ b/cxx-squid/src/test/java/org/sonar/cxx/lexer/CxxLexer_PreprocessorDisabled_Test.java @@ -21,12 +21,11 @@ import com.sonar.sslr.impl.Lexer; import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.cxx.lexer.LexerAssert.assertThat; - import org.assertj.core.api.SoftAssertions; import org.junit.BeforeClass; import org.junit.Test; import org.sonar.cxx.api.CxxTokenType; +import static org.sonar.cxx.lexer.LexerAssert.assertThat; public class CxxLexer_PreprocessorDisabled_Test { @@ -40,32 +39,32 @@ public static void init() { @Test public void preprocessor_directives() { SoftAssertions softly = new SoftAssertions(); - softly.assertThat(lexer.lex("#include ")).anySatisfy(token ->assertThat(token).isValue("#include ").hasType(CxxTokenType.PREPROCESSOR)); - softly.assertThat(lexer.lex("# include ")).anySatisfy(token ->assertThat(token).isValue("# include ").hasType(CxxTokenType.PREPROCESSOR)); - softly.assertThat(lexer.lex(" # include ")).anySatisfy(token ->assertThat(token).isValue("# include ").hasType(CxxTokenType.PREPROCESSOR)); - softly.assertThat(lexer.lex("#define lala")).anySatisfy(token ->assertThat(token).isValue("#define lala").hasType(CxxTokenType.PREPROCESSOR)); - softly.assertThat(lexer.lex("# define lala")).anySatisfy(token ->assertThat(token).isValue("# define lala").hasType(CxxTokenType.PREPROCESSOR)); - softly.assertThat(lexer.lex(" # define lala")).anySatisfy(token ->assertThat(token).isValue("# define lala").hasType(CxxTokenType.PREPROCESSOR)); + softly.assertThat(lexer.lex("#include ")).anySatisfy(token -> assertThat(token).isValue("#include ").hasType(CxxTokenType.PREPROCESSOR)); + softly.assertThat(lexer.lex("# include ")).anySatisfy(token -> assertThat(token).isValue("# include ").hasType(CxxTokenType.PREPROCESSOR)); + softly.assertThat(lexer.lex(" # include ")).anySatisfy(token -> assertThat(token).isValue("# include ").hasType(CxxTokenType.PREPROCESSOR)); + softly.assertThat(lexer.lex("#define lala")).anySatisfy(token -> assertThat(token).isValue("#define lala").hasType(CxxTokenType.PREPROCESSOR)); + softly.assertThat(lexer.lex("# define lala")).anySatisfy(token -> assertThat(token).isValue("# define lala").hasType(CxxTokenType.PREPROCESSOR)); + softly.assertThat(lexer.lex(" # define lala")).anySatisfy(token -> assertThat(token).isValue("# define lala").hasType(CxxTokenType.PREPROCESSOR)); softly.assertThat(lexer.lex("#include ")).hasSize(2); softly.assertThat(lexer.lex("#define\\\ncontinued line")).hasSize(2); - softly.assertThat(lexer.lex("#include \n1")).anySatisfy(token ->assertThat(token).isValue("1").hasType(CxxTokenType.NUMBER)); + softly.assertThat(lexer.lex("#include \n1")).anySatisfy(token -> assertThat(token).isValue("1").hasType(CxxTokenType.NUMBER)); softly.assertAll(); } @Test public void preprocessor_continued_define() { assertThat(lexer.lex("#define M\\\n" - + "0")).anySatisfy(token ->assertThat(token).isValue("#define M 0").hasType(CxxTokenType.PREPROCESSOR)); + + "0")).anySatisfy(token -> assertThat(token).isValue("#define M 0").hasType(CxxTokenType.PREPROCESSOR)); } @Test public void preprocessor_directive_with_multiline_comment() { SoftAssertions softly = new SoftAssertions(); - softly.assertThat(lexer.lex("#define A B/*CCC*/\n")).anySatisfy(token ->assertThat(token).isValue("#define A B").hasType(CxxTokenType.PREPROCESSOR)); - softly.assertThat(lexer.lex("#define A B/**/C\n")).anySatisfy(token ->assertThat(token).isValue("#define A BC").hasType(CxxTokenType.PREPROCESSOR)); - softly.assertThat(lexer.lex("#define A B/*C\n\n\nC*/\n")).anySatisfy(token ->assertThat(token).isValue("#define A B").hasType(CxxTokenType.PREPROCESSOR)); - softly.assertThat(lexer.lex("#define A B*/\n")).anySatisfy(token ->assertThat(token).isValue("#define A B*/").hasType(CxxTokenType.PREPROCESSOR)); + softly.assertThat(lexer.lex("#define A B/*CCC*/\n")).anySatisfy(token -> assertThat(token).isValue("#define A B").hasType(CxxTokenType.PREPROCESSOR)); + softly.assertThat(lexer.lex("#define A B/**/C\n")).anySatisfy(token -> assertThat(token).isValue("#define A BC").hasType(CxxTokenType.PREPROCESSOR)); + softly.assertThat(lexer.lex("#define A B/*C\n\n\nC*/\n")).anySatisfy(token -> assertThat(token).isValue("#define A B").hasType(CxxTokenType.PREPROCESSOR)); + softly.assertThat(lexer.lex("#define A B*/\n")).anySatisfy(token -> assertThat(token).isValue("#define A B*/").hasType(CxxTokenType.PREPROCESSOR)); softly.assertAll(); } } diff --git a/cxx-squid/src/test/java/org/sonar/cxx/lexer/LexerAssert.java b/cxx-squid/src/test/java/org/sonar/cxx/lexer/LexerAssert.java index aefb11835b..0d93963fb7 100644 --- a/cxx-squid/src/test/java/org/sonar/cxx/lexer/LexerAssert.java +++ b/cxx-squid/src/test/java/org/sonar/cxx/lexer/LexerAssert.java @@ -19,21 +19,21 @@ */ package org.sonar.cxx.lexer; -import org.assertj.core.api.AbstractAssert; import com.sonar.sslr.api.Token; import com.sonar.sslr.api.TokenType; +import org.assertj.core.api.AbstractAssert; public class LexerAssert extends AbstractAssert { + public static LexerAssert assertThat(Token actual) { + return new LexerAssert(actual); + } + public LexerAssert(Token actual) { super(actual, LexerAssert.class); } - public static LexerAssert assertThat(Token actual) { - return new LexerAssert(actual); - } - public LexerAssert hasType(TokenType type) { isNotNull(); if (actual.getType() != type) { @@ -88,12 +88,12 @@ public LexerAssert isTriviaLine(int line) { return this; } - public LexerAssert isComment() { - isNotNull(); - Boolean exists = actual.getTrivia().get(0).isComment(); - if (!exists) { - failWithMessage("Expected the Token isComment but was <%s>", exists); - } + public LexerAssert isComment() { + isNotNull(); + Boolean exists = actual.getTrivia().get(0).isComment(); + if (!exists) { + failWithMessage("Expected the Token isComment but was <%s>", exists); + } return this; } diff --git a/cxx-squid/src/test/java/org/sonar/cxx/lexer/LiteralValuesBuilder.java b/cxx-squid/src/test/java/org/sonar/cxx/lexer/LiteralValuesBuilder.java index 2791354446..42ceffa658 100644 --- a/cxx-squid/src/test/java/org/sonar/cxx/lexer/LiteralValuesBuilder.java +++ b/cxx-squid/src/test/java/org/sonar/cxx/lexer/LiteralValuesBuilder.java @@ -19,29 +19,28 @@ */ package org.sonar.cxx.lexer; -import org.sonar.cxx.api.CxxTokenType; - import com.sonar.sslr.api.TokenType; - +import org.sonar.cxx.api.CxxTokenType; public final class LiteralValuesBuilder { + + public static Builder builder(String key) { + return new Builder(key); + } String lexerValue; String tokenValue; TokenType tokenType; - LiteralValuesBuilder (Builder builder) { + LiteralValuesBuilder(Builder builder) { this.lexerValue = builder.lexerValue; this.tokenValue = builder.tokenValue; - this.tokenType = builder .tokenType; - } - - public static Builder builder(String key) { - return new Builder(key); + this.tokenType = builder.tokenType; } public static class Builder { + private final String lexerValue; - private String tokenValue =""; + private String tokenValue = ""; private TokenType tokenType = CxxTokenType.NUMBER; private Builder(String lexerValue) { diff --git a/cxx-squid/src/test/java/org/sonar/cxx/parser/CxxParserTest.java b/cxx-squid/src/test/java/org/sonar/cxx/parser/CxxParserTest.java index ee5a0cc29d..6fef447022 100644 --- a/cxx-squid/src/test/java/org/sonar/cxx/parser/CxxParserTest.java +++ b/cxx-squid/src/test/java/org/sonar/cxx/parser/CxxParserTest.java @@ -28,16 +28,14 @@ import java.util.HashMap; import java.util.List; import org.apache.commons.io.FileUtils; - +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import org.junit.Test; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; - import org.sonar.cxx.CxxConfiguration; import org.sonar.cxx.CxxFileTesterHelper; import org.sonar.squidbridge.SquidAstVisitorContext; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; public class CxxParserTest extends ParserBaseTestHelper { @@ -59,30 +57,32 @@ public CxxParserTest() { @Test public void testParsingOnDiverseSourceFiles() { Collection files = listFiles(goodFiles, new String[]{"cc", "cpp", "hpp"}); - HashMap map = new HashMap() { + HashMap map = new HashMap() { private static final long serialVersionUID = 6029310517902718597L; + { - put("ignore.hpp", 2); - put("ignore1.cpp", 2); - put("ignoreparam.hpp", 4); - put("ignoreparam1.cpp", 2); - put("inbuf1.cpp", 2); - put("io1.cpp", 3); - put("outbuf1.cpp", 2); - put("outbuf1.hpp", 2); - put("outbuf1x.cpp", 2); - put("outbuf1x.hpp", 4); - put("outbuf2.cpp", 2); - put("outbuf2.hpp", 3); - put("outbuf3.cpp", 2); - put("outbuf3.hpp", 2); - put("outbuf2.cpp", 2); - }}; + put("ignore.hpp", 2); + put("ignore1.cpp", 2); + put("ignoreparam.hpp", 4); + put("ignoreparam1.cpp", 2); + put("inbuf1.cpp", 2); + put("io1.cpp", 3); + put("outbuf1.cpp", 2); + put("outbuf1.hpp", 2); + put("outbuf1x.cpp", 2); + put("outbuf1x.hpp", 4); + put("outbuf2.cpp", 2); + put("outbuf2.hpp", 3); + put("outbuf3.cpp", 2); + put("outbuf3.hpp", 2); + put("outbuf2.cpp", 2); + } + }; for (File file : files) { AstNode root = p.parse(file); CxxParser.finishedParsing(file); if (map.containsKey(file.getName())) { - assertThat(root.getNumberOfChildren()).as("check number of nodes for file %s",file.getName()).isEqualTo(map.get(file.getName())); + assertThat(root.getNumberOfChildren()).as("check number of nodes for file %s", file.getName()).isEqualTo(map.get(file.getName())); } else { assertThat(root.hasChildren()).isTrue(); } @@ -109,14 +109,16 @@ public void testPreproccessorParsingOnDiverseSourceFiles() { "resources\\parser\\preprocessor") ); - HashMap map = new HashMap() { + HashMap map = new HashMap() { private static final long serialVersionUID = 1433381506274827684L; + { put("variadic_macros.cpp", 2); put("apply_wrap.hpp", 1); put("boost_macros_short.hpp", 1); put("boost_macros.hpp", 1); - }}; + } + }; p = CxxParser.create(mock(SquidAstVisitorContext.class), conf, CxxFileTesterHelper.mockCxxLanguage()); Collection files = listFiles(preprocessorFiles, new String[]{"cc", "cpp", "hpp", "h"}); @@ -124,7 +126,7 @@ public void testPreproccessorParsingOnDiverseSourceFiles() { AstNode root = p.parse(file); CxxParser.finishedParsing(file); if (map.containsKey(file.getName())) { - assertThat(root.getNumberOfChildren()).as("check number of nodes for file %s",file.getName()).isEqualTo(map.get(file.getName())); + assertThat(root.getNumberOfChildren()).as("check number of nodes for file %s", file.getName()).isEqualTo(map.get(file.getName())); } else { assertThat(root.hasChildren()).isTrue(); } @@ -155,14 +157,16 @@ public void testParsingInCCompatMode() { //ToDo: Fix this compatibility test - c conf.setCFilesPatterns(new String[]{"*.c"}); p = CxxParser.create(context, conf, CxxFileTesterHelper.mockCxxLanguage()); AstNode root = p.parse(cfile); - assertThat(root.getNumberOfChildren()).isEqualTo(2); + assertThat(root.getNumberOfChildren()).isEqualTo(2); } @Test public void testParseErrorRecoveryDisabled() { // The error recovery works, if: // - a syntacticly incorrect file causes a parse error when recovery is disabled - assertThatThrownBy(() -> {p.parse(erroneousSources);}).isInstanceOf(com.sonar.sslr.api.RecognitionException.class); + assertThatThrownBy(() -> { + p.parse(erroneousSources); + }).isInstanceOf(com.sonar.sslr.api.RecognitionException.class); } @SuppressWarnings("unchecked") diff --git a/cxx-squid/src/test/java/org/sonar/cxx/parser/ExpressionTest.java b/cxx-squid/src/test/java/org/sonar/cxx/parser/ExpressionTest.java index 56ae3f04a2..c88cf246ea 100644 --- a/cxx-squid/src/test/java/org/sonar/cxx/parser/ExpressionTest.java +++ b/cxx-squid/src/test/java/org/sonar/cxx/parser/ExpressionTest.java @@ -153,7 +153,7 @@ public void nestedNameSpecifier() { assertThat(p).matches("typeName :: template simpleTemplateId ::"); assertThat(p).matches("namespaceName :: template simpleTemplateId ::"); assertThat(p).matches("decltypeSpecifier :: template simpleTemplateId ::"); - + // some deeper nested tests assertThat(p).matches(":: foo1 :: foo2 :: foo3 :: foo4 ::"); assertThat(p).matches("typeName :: foo2 :: foo3 :: foo4 ::"); @@ -162,7 +162,7 @@ public void nestedNameSpecifier() { assertThat(p).matches(":: foo1 :: simpleTemplateId :: foo2 :: simpleTemplateId ::"); assertThat(p).matches(":: foo1 :: template simpleTemplateId :: foo2 :: template simpleTemplateId ::"); } - + @Test public void postfixExpression() { p.setRootRule(g.rule(CxxGrammarImpl.postfixExpression)); diff --git a/cxx-squid/src/test/java/org/sonar/cxx/preprocessor/ExpressionEvaluatorTest.java b/cxx-squid/src/test/java/org/sonar/cxx/preprocessor/ExpressionEvaluatorTest.java index 2265ac5ab9..8d424c8c70 100644 --- a/cxx-squid/src/test/java/org/sonar/cxx/preprocessor/ExpressionEvaluatorTest.java +++ b/cxx-squid/src/test/java/org/sonar/cxx/preprocessor/ExpressionEvaluatorTest.java @@ -19,18 +19,16 @@ */ package org.sonar.cxx.preprocessor; +import java.math.BigInteger; +import org.assertj.core.api.SoftAssertions; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import org.junit.Test; import static org.mockito.ArgumentMatchers.anyList; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; - -import java.math.BigInteger; - -import org.assertj.core.api.SoftAssertions; -import org.junit.Test; import org.sonar.cxx.CxxConfiguration; import org.sonar.cxx.CxxFileTesterHelper; import org.sonar.squidbridge.SquidAstVisitorContext; @@ -311,7 +309,6 @@ public void self_referential_identifier4() { softly.assertAll(); } - @Test public void identifier_undefined() { assertFalse(eval("LALA")); diff --git a/cxx-squid/src/test/java/org/sonar/cxx/utils/CxxReportIssueTest.java b/cxx-squid/src/test/java/org/sonar/cxx/utils/CxxReportIssueTest.java index 9fd20cefc7..b0d1d3cd44 100644 --- a/cxx-squid/src/test/java/org/sonar/cxx/utils/CxxReportIssueTest.java +++ b/cxx-squid/src/test/java/org/sonar/cxx/utils/CxxReportIssueTest.java @@ -21,7 +21,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; - import org.junit.Test; public class CxxReportIssueTest { diff --git a/cxx-squid/src/test/java/org/sonar/cxx/visitors/CxxCognitiveComplexityVisitorTest.java b/cxx-squid/src/test/java/org/sonar/cxx/visitors/CxxCognitiveComplexityVisitorTest.java index c050cbf8ed..1a56a7fcfd 100644 --- a/cxx-squid/src/test/java/org/sonar/cxx/visitors/CxxCognitiveComplexityVisitorTest.java +++ b/cxx-squid/src/test/java/org/sonar/cxx/visitors/CxxCognitiveComplexityVisitorTest.java @@ -19,11 +19,9 @@ */ package org.sonar.cxx.visitors; -import static org.assertj.core.api.Assertions.assertThat; - import java.io.IOException; import java.io.UnsupportedEncodingException; - +import static org.assertj.core.api.Assertions.assertThat; import org.junit.Test; import org.sonar.cxx.CxxAstScanner; import org.sonar.cxx.CxxFileTester; diff --git a/cxx-squid/src/test/java/org/sonar/cxx/visitors/CxxFunctionComplexityVisitorTest.java b/cxx-squid/src/test/java/org/sonar/cxx/visitors/CxxFunctionComplexityVisitorTest.java index 1fd12de50c..55fd109797 100644 --- a/cxx-squid/src/test/java/org/sonar/cxx/visitors/CxxFunctionComplexityVisitorTest.java +++ b/cxx-squid/src/test/java/org/sonar/cxx/visitors/CxxFunctionComplexityVisitorTest.java @@ -19,13 +19,11 @@ */ package org.sonar.cxx.visitors; -import static org.mockito.Mockito.when; - import java.io.IOException; import java.util.Optional; - import org.assertj.core.api.SoftAssertions; import org.junit.Test; +import static org.mockito.Mockito.when; import org.sonar.cxx.CxxAstScanner; import org.sonar.cxx.CxxFileTester; import org.sonar.cxx.CxxFileTesterHelper; @@ -33,7 +31,6 @@ import org.sonar.cxx.api.CxxMetric; import org.sonar.squidbridge.api.SourceFile; - public class CxxFunctionComplexityVisitorTest { @Test @@ -41,10 +38,10 @@ public void testPublishMeasuresForFile() throws IOException { CxxLanguage language = CxxFileTesterHelper.mockCxxLanguage(); when(language.getIntegerOption(CxxFunctionComplexityVisitor.FUNCTION_COMPLEXITY_THRESHOLD_KEY)) - .thenReturn(Optional.of(5)); + .thenReturn(Optional.of(5)); CxxFileTester tester = CxxFileTesterHelper.CreateCxxFileTester("src/test/resources/metrics/FunctionComplexity.cc", - ".", ""); + ".", ""); SourceFile file = CxxAstScanner.scanSingleFile(tester.cxxFile, tester.sensorContext, language); SoftAssertions softly = new SoftAssertions(); diff --git a/cxx-squid/src/test/java/org/sonar/cxx/visitors/CxxFunctionSizeVisitorTest.java b/cxx-squid/src/test/java/org/sonar/cxx/visitors/CxxFunctionSizeVisitorTest.java index 04ac5f9b05..5929a8e07d 100644 --- a/cxx-squid/src/test/java/org/sonar/cxx/visitors/CxxFunctionSizeVisitorTest.java +++ b/cxx-squid/src/test/java/org/sonar/cxx/visitors/CxxFunctionSizeVisitorTest.java @@ -19,13 +19,11 @@ */ package org.sonar.cxx.visitors; -import static org.mockito.Mockito.when; - import java.io.IOException; import java.util.Optional; - import org.assertj.core.api.SoftAssertions; import org.junit.Test; +import static org.mockito.Mockito.when; import org.sonar.cxx.CxxAstScanner; import org.sonar.cxx.CxxFileTester; import org.sonar.cxx.CxxFileTesterHelper; @@ -33,7 +31,6 @@ import org.sonar.cxx.api.CxxMetric; import org.sonar.squidbridge.api.SourceFile; - public class CxxFunctionSizeVisitorTest { @Test @@ -43,7 +40,7 @@ public void testPublishMeasuresForFile() throws IOException { when(language.getIntegerOption(CxxFunctionSizeVisitor.FUNCTION_SIZE_THRESHOLD_KEY)).thenReturn(Optional.of(5)); CxxFileTester tester = CxxFileTesterHelper.CreateCxxFileTester("src/test/resources/metrics/FunctionComplexity.cc", - ".", ""); + ".", ""); SourceFile file = CxxAstScanner.scanSingleFile(tester.cxxFile, tester.sensorContext, language); SoftAssertions softly = new SoftAssertions(); diff --git a/cxx-squid/src/test/java/org/sonar/cxx/visitors/CxxPublicApiVisitorTest.java b/cxx-squid/src/test/java/org/sonar/cxx/visitors/CxxPublicApiVisitorTest.java index 3b85b2d743..3198959125 100644 --- a/cxx-squid/src/test/java/org/sonar/cxx/visitors/CxxPublicApiVisitorTest.java +++ b/cxx-squid/src/test/java/org/sonar/cxx/visitors/CxxPublicApiVisitorTest.java @@ -56,24 +56,6 @@ private static String getFileExtension(String fileName) { return fileName.substring(lastIndexOf); } - private class TestPublicApiVisitor extends AbstractCxxPublicApiVisitor { - - final Map> idCommentMap = new HashMap<>(); - boolean checkDoubleIDs = false; - - TestPublicApiVisitor(boolean checkDoubleIDs) { - this.checkDoubleIDs = checkDoubleIDs; - } - - @Override - protected void onPublicApi(AstNode node, String id, List comments) { - if (checkDoubleIDs && idCommentMap.containsKey(id)) { - Fail.fail("DOUBLE ID: " + id); - } - idCommentMap.put(id, comments); - } - } - /** * Check that CxxPublicApiVisitor correctly counts API for given file. * @@ -248,4 +230,22 @@ public void public_api() throws UnsupportedEncodingException, IOException { assertThat(file.getInt(CxxMetric.PUBLIC_UNDOCUMENTED_API)).isEqualTo(0); } + private class TestPublicApiVisitor extends AbstractCxxPublicApiVisitor { + + final Map> idCommentMap = new HashMap<>(); + boolean checkDoubleIDs = false; + + TestPublicApiVisitor(boolean checkDoubleIDs) { + this.checkDoubleIDs = checkDoubleIDs; + } + + @Override + protected void onPublicApi(AstNode node, String id, List comments) { + if (checkDoubleIDs && idCommentMap.containsKey(id)) { + Fail.fail("DOUBLE ID: " + id); + } + idCommentMap.put(id, comments); + } + } + } diff --git a/sonar-c-plugin/src/main/java/org/sonar/plugins/c/CDefaultProfile.java b/sonar-c-plugin/src/main/java/org/sonar/plugins/c/CDefaultProfile.java index bd8b664bd0..b92170ca7f 100644 --- a/sonar-c-plugin/src/main/java/org/sonar/plugins/c/CDefaultProfile.java +++ b/sonar-c-plugin/src/main/java/org/sonar/plugins/c/CDefaultProfile.java @@ -32,9 +32,10 @@ */ public class CDefaultProfile extends ProfileDefinition { + private static final String NAME = "Sonar way"; + private final XMLProfileParser xmlProfileParser; private final AnnotationProfileParser annotationProfileParser; - private static final String NAME = "Sonar way"; private final CxxLanguage language; /** diff --git a/sonar-c-plugin/src/main/java/org/sonar/plugins/c/CLanguage.java b/sonar-c-plugin/src/main/java/org/sonar/plugins/c/CLanguage.java index dd743844c6..b33d352944 100644 --- a/sonar-c-plugin/src/main/java/org/sonar/plugins/c/CLanguage.java +++ b/sonar-c-plugin/src/main/java/org/sonar/plugins/c/CLanguage.java @@ -63,6 +63,13 @@ public class CLanguage extends CxxLanguage { public static final String REPOSITORY_KEY = "c"; public static final String DEFAULT_PROFILE = "Sonar way"; + private static String[] createStringArray(String[] values, String defaultValues) { + if (values.length == 0) { + return defaultValues.split(","); + } + return values; + } + private final String[] sourceSuffixes; private final String[] headerSuffixes; private final String[] fileSuffixes; @@ -97,13 +104,6 @@ public String[] getHeaderFileSuffixes() { return headerSuffixes.clone(); } - private static String[] createStringArray(String[] values, String defaultValues) { - if (values.length == 0) { - return defaultValues.split(","); - } - return values; - } - private String[] mergeArrays(String[] array1, String[] array2) { String[] result = new String[array1.length + array2.length]; System.arraycopy(sourceSuffixes, 0, result, 0, array1.length); diff --git a/sonar-c-plugin/src/main/java/org/sonar/plugins/c/CPlugin.java b/sonar-c-plugin/src/main/java/org/sonar/plugins/c/CPlugin.java index 4557a31509..d945928309 100644 --- a/sonar-c-plugin/src/main/java/org/sonar/plugins/c/CPlugin.java +++ b/sonar-c-plugin/src/main/java/org/sonar/plugins/c/CPlugin.java @@ -564,6 +564,11 @@ public List getSensorsImpl() { return l; } + @Override + public String toString() { + return getClass().getSimpleName(); + } + public static class CxxMetricsImp implements Metrics { private static final List METRICS = CxxMetricsFactory.generateList(CLanguage.KEY, CLanguage.PROPSKEY); @@ -793,8 +798,4 @@ public CxxCoverageAggregator() { } } - @Override - public String toString() { - return getClass().getSimpleName(); - } } diff --git a/sonar-c-plugin/src/main/java/org/sonar/plugins/c/package-info.java b/sonar-c-plugin/src/main/java/org/sonar/plugins/c/package-info.java index 56fa47baef..ca5ba23985 100644 --- a/sonar-c-plugin/src/main/java/org/sonar/plugins/c/package-info.java +++ b/sonar-c-plugin/src/main/java/org/sonar/plugins/c/package-info.java @@ -17,7 +17,6 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - /** * Package with cxx community plug-in for SonarQube. */ diff --git a/sonar-cxx-plugin/src/main/java/org/sonar/plugins/cxx/CppLanguage.java b/sonar-cxx-plugin/src/main/java/org/sonar/plugins/cxx/CppLanguage.java index fc95a9158b..746e8bcb80 100644 --- a/sonar-cxx-plugin/src/main/java/org/sonar/plugins/cxx/CppLanguage.java +++ b/sonar-cxx-plugin/src/main/java/org/sonar/plugins/cxx/CppLanguage.java @@ -64,6 +64,13 @@ public class CppLanguage extends CxxLanguage { public static final String REPOSITORY_KEY = "cxx"; public static final String DEFAULT_PROFILE = "Sonar way"; + private static String[] createStringArray(String[] values, String defaultValues) { + if (values.length == 0) { + return defaultValues.split(","); + } + return values; + } + private final String[] sourceSuffixes; private final String[] headerSuffixes; private final String[] fileSuffixes; @@ -144,7 +151,7 @@ public List getChecks() { org.sonar.cxx.checks.regex.NoSonarCheck.class, org.sonar.cxx.checks.regex.TodoTagPresenceCheck.class, org.sonar.cxx.checks.xpath.XPathCheck.class - )); + )); } @Override @@ -152,13 +159,6 @@ public String getRepositoryKey() { return REPOSITORY_KEY; } - private static String[] createStringArray(String[] values, String defaultValues) { - if (values.length == 0) { - return defaultValues.split(","); - } - return values; - } - private String[] mergeArrays(String[] array1, String[] array2) { String[] result = new String[array1.length + array2.length]; System.arraycopy(sourceSuffixes, 0, result, 0, array1.length); diff --git a/sonar-cxx-plugin/src/main/java/org/sonar/plugins/cxx/CxxDefaultProfile.java b/sonar-cxx-plugin/src/main/java/org/sonar/plugins/cxx/CxxDefaultProfile.java index 3e8518fbf8..c3de8b08da 100644 --- a/sonar-cxx-plugin/src/main/java/org/sonar/plugins/cxx/CxxDefaultProfile.java +++ b/sonar-cxx-plugin/src/main/java/org/sonar/plugins/cxx/CxxDefaultProfile.java @@ -32,9 +32,10 @@ */ public class CxxDefaultProfile extends ProfileDefinition { + private static final String NAME = "Sonar way"; + private final XMLProfileParser xmlProfileParser; private final AnnotationProfileParser annotationProfileParser; - private static final String NAME = "Sonar way"; private final CxxLanguage lang; /** diff --git a/sonar-cxx-plugin/src/main/java/org/sonar/plugins/cxx/CxxPlugin.java b/sonar-cxx-plugin/src/main/java/org/sonar/plugins/cxx/CxxPlugin.java index 459075f8dc..eebeda7c6b 100644 --- a/sonar-cxx-plugin/src/main/java/org/sonar/plugins/cxx/CxxPlugin.java +++ b/sonar-cxx-plugin/src/main/java/org/sonar/plugins/cxx/CxxPlugin.java @@ -622,6 +622,11 @@ public List getSensorsImpl() { return l; } + @Override + public String toString() { + return getClass().getSimpleName(); + } + public static class CxxMetricsImp implements Metrics { private static final List METRICS = CxxMetricsFactory.generateList(CppLanguage.KEY, CppLanguage.PROPSKEY); @@ -858,8 +863,4 @@ public CxxCoverageAggregator() { } } - @Override - public String toString() { - return getClass().getSimpleName(); - } } diff --git a/sonar-cxx-plugin/src/main/java/org/sonar/plugins/cxx/package-info.java b/sonar-cxx-plugin/src/main/java/org/sonar/plugins/cxx/package-info.java index 9913b18cb5..2d3aaf546e 100644 --- a/sonar-cxx-plugin/src/main/java/org/sonar/plugins/cxx/package-info.java +++ b/sonar-cxx-plugin/src/main/java/org/sonar/plugins/cxx/package-info.java @@ -17,7 +17,6 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - /** * Package with cxx community plug-in for SonarQube. */ diff --git a/sslr-cxx-toolkit/src/main/java/org/sonar/cxx/toolkit/CxxConfigurationModel.java b/sslr-cxx-toolkit/src/main/java/org/sonar/cxx/toolkit/CxxConfigurationModel.java index 76c3ab4672..12b0f3e63e 100644 --- a/sslr-cxx-toolkit/src/main/java/org/sonar/cxx/toolkit/CxxConfigurationModel.java +++ b/sslr-cxx-toolkit/src/main/java/org/sonar/cxx/toolkit/CxxConfigurationModel.java @@ -55,6 +55,38 @@ public class CxxConfigurationModel extends AbstractConfigurationModel { private static final String DEFINES_PROPERTY_KEY = "sonar.cxx.defines"; private static final String INCLUDE_DIRECTORIES_PROPERTY_KEY = "sonar.cxx.includeDirectories"; private static final String FORCE_INCLUDES_PROPERTY_KEY = "sonar.cxx.forceIncludes"; + + @VisibleForTesting + static String getPropertyOrDefaultValue(String propertyKey, String defaultValue) { + String propertyValue = System.getProperty(propertyKey); + + if (propertyValue == null) { + LOG.info("The property '{}' is not set, using the default value '{}'.", propertyKey, defaultValue); + return defaultValue; + } else { + LOG.info("The property '{}' is set, using its value '{}'.", propertyKey, defaultValue); + return propertyValue; + } + } + + static String[] getStringLines(@Nullable String value) { + if (value == null || value.isEmpty()) { + return new String[0]; + } + return value.split("\\\\n\\\\", -1); + } + + static String[] getStringArray(@Nullable String value) { + if (value != null) { + String[] strings = value.split(","); + String[] result = new String[strings.length]; + for (int index = 0; index < strings.length; index++) { + result[index] = strings[index].trim(); + } + return result; + } + return new String[0]; + } private final MapSettings settings = new MapSettings(); @VisibleForTesting @@ -121,36 +153,4 @@ CxxConfiguration getConfiguration(CxxLanguage language) { return config; } - @VisibleForTesting - static String getPropertyOrDefaultValue(String propertyKey, String defaultValue) { - String propertyValue = System.getProperty(propertyKey); - - if (propertyValue == null) { - LOG.info("The property '{}' is not set, using the default value '{}'.", propertyKey, defaultValue); - return defaultValue; - } else { - LOG.info("The property '{}' is set, using its value '{}'.", propertyKey, defaultValue); - return propertyValue; - } - } - - static String[] getStringLines(@Nullable String value) { - if (value == null || value.isEmpty()) { - return new String[0]; - } - return value.split("\\\\n\\\\", -1); - } - - static String[] getStringArray(@Nullable String value) { - if (value != null) { - String[] strings = value.split(","); - String[] result = new String[strings.length]; - for (int index = 0; index < strings.length; index++) { - result[index] = strings[index].trim(); - } - return result; - } - return new String[0]; - } - } diff --git a/sslr-cxx-toolkit/src/main/java/org/sonar/cxx/toolkit/CxxToolkit.java b/sslr-cxx-toolkit/src/main/java/org/sonar/cxx/toolkit/CxxToolkit.java index 685008e1e8..8efbfac860 100644 --- a/sslr-cxx-toolkit/src/main/java/org/sonar/cxx/toolkit/CxxToolkit.java +++ b/sslr-cxx-toolkit/src/main/java/org/sonar/cxx/toolkit/CxxToolkit.java @@ -23,12 +23,12 @@ public final class CxxToolkit { - private CxxToolkit() { - } - public static void main(String[] args) { Toolkit toolkit = new Toolkit("SSLR :: Cxx :: Toolkit", new CxxConfigurationModel()); toolkit.run(); } + private CxxToolkit() { + } + }