From 6ae6ca93c8a7d5ff0d432bf06bf7f11aafa712f8 Mon Sep 17 00:00:00 2001 From: Bert Date: Tue, 18 Apr 2017 17:26:36 +0200 Subject: [PATCH 1/6] fix sonarlint issues and reduce false positives --- .../checks/CommentContainsPatternChecker.java | 2 +- .../sonar/cxx/checks/CommentedCodeCheck.java | 13 +++-- .../sonar/cxx/checks/FileEncodingCheck.java | 4 +- .../org/sonar/cxx/checks/FileHeaderCheck.java | 4 +- .../checks/FileRegularExpressionCheck.java | 31 +++++------- .../cxx/checks/HardcodedAccountCheck.java | 2 +- .../sonar/cxx/checks/HardcodedIpCheck.java | 5 +- .../checks/LineRegularExpressionCheck.java | 4 +- .../sonar/cxx/checks/MagicNumberCheck.java | 2 +- .../MissingNewLineAtEndOfFileCheck.java | 4 +- .../cxx/checks/NestedStatementsCheck.java | 8 ++-- .../sonar/cxx/checks/ParsingErrorCheck.java | 2 + .../cxx/checks/ParsingErrorRecoveryCheck.java | 2 + .../sonar/cxx/checks/ReservedNamesCheck.java | 4 +- .../org/sonar/cxx/checks/SafetyTagCheck.java | 2 +- .../checks/SwitchLastCaseIsDefaultCheck.java | 2 +- .../sonar/cxx/checks/TabCharacterCheck.java | 2 +- .../sonar/cxx/checks/TooLongLineCheck.java | 2 +- .../TooManyLinesOfCodeInFunctionCheck.java | 5 +- .../checks/TooManyStatementsPerLineCheck.java | 4 +- .../cxx/checks/UseCorrectIncludeCheck.java | 2 +- .../sonar/cxx/checks/UseCorrectTypeCheck.java | 2 +- .../checks/UsingNamespaceInHeaderCheck.java | 2 +- .../java/org/sonar/cxx/checks/XPathCheck.java | 4 +- .../cxx/checks/naming/ClassNameCheck.java | 2 +- .../cxx/checks/naming/FileNameCheck.java | 2 +- .../cxx/checks/naming/FunctionNameCheck.java | 14 ++---- .../cxx/checks/naming/MethodNameCheck.java | 2 +- .../sonar/cxx/checks/utils/CheckUtils.java | 22 ++++----- .../java/org/sonar/cxx/cxxlint/CxxLint.java | 47 ++++++++++--------- .../src/test/resources/compiler/vc++13.txt | 4 +- 31 files changed, 98 insertions(+), 109 deletions(-) diff --git a/cxx-checks/src/main/java/org/sonar/cxx/checks/CommentContainsPatternChecker.java b/cxx-checks/src/main/java/org/sonar/cxx/checks/CommentContainsPatternChecker.java index 336a4c5f99..71dde5e8cc 100644 --- a/cxx-checks/src/main/java/org/sonar/cxx/checks/CommentContainsPatternChecker.java +++ b/cxx-checks/src/main/java/org/sonar/cxx/checks/CommentContainsPatternChecker.java @@ -72,7 +72,7 @@ public void visitToken(Token token) { for (int i = 0; i < lines.length; i++) { int start = indexOfIgnoreCase(lines[i]); if (start != -1 && !isLetterAround(lines[i], start)) { - check.getContext().createLineViolation(check, message, trivia.getToken().getLine() + i); + check.getContext().createLineViolation(check, message, trivia.getToken().getLine() + i); //NOSONAR } } } 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 ed7f823f27..021996dcc7 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 @@ -44,8 +44,8 @@ @Rule( key = "CommentedCode", name = "Sections of code should not be 'commented out'", - tags = {Tag.UNUSED}, - priority = Priority.BLOCKER) + tags = {Tag.BAD_PRACTICE}, + priority = Priority.CRITICAL) @ActivatedByDefault @SqaleConstantRemediation("5min") public class CommentedCodeCheck extends SquidCheck implements AstAndTokenVisitor { @@ -74,15 +74,14 @@ public Set getDetectors() { @Override public void visitToken(Token token) { for (Trivia trivia : token.getTrivia()) { - if (trivia.isComment() + if (trivia.isComment() //NOSONAR && !trivia.getToken().getOriginalValue().startsWith("///") && !trivia.getToken().getOriginalValue().startsWith("//!") - && !trivia.getToken().getOriginalValue().startsWith("/**") + && !trivia.getToken().getOriginalValue().startsWith("/**") //NOSONAR && !trivia.getToken().getOriginalValue().startsWith("/*!") - && !trivia.getToken().getOriginalValue().startsWith("/*@") + && !trivia.getToken().getOriginalValue().startsWith("/*@") //NOSONAR && !trivia.getToken().getOriginalValue().startsWith("//@")) { - String lines[] = regexpToDivideStringByLine.split(getContext().getCommentAnalyser().getContents( - trivia.getToken().getOriginalValue())); + String lines[] = regexpToDivideStringByLine.split(getContext().getCommentAnalyser().getContents(trivia.getToken().getOriginalValue())); //NOSONAR for (int lineOffset = 0; lineOffset < lines.length; lineOffset++) { if (codeRecognizer.isLineOfCode(lines[lineOffset])) { diff --git a/cxx-checks/src/main/java/org/sonar/cxx/checks/FileEncodingCheck.java b/cxx-checks/src/main/java/org/sonar/cxx/checks/FileEncodingCheck.java index c5f10c80a6..17b5b63e7c 100644 --- a/cxx-checks/src/main/java/org/sonar/cxx/checks/FileEncodingCheck.java +++ b/cxx-checks/src/main/java/org/sonar/cxx/checks/FileEncodingCheck.java @@ -37,7 +37,7 @@ priority = Priority.MINOR) @ActivatedByDefault @NoSqale -public class FileEncodingCheck extends SquidCheck implements CxxCharsetAwareVisitor { +public class FileEncodingCheck extends SquidCheck implements CxxCharsetAwareVisitor { //NOSONAR private Charset charset; @@ -50,7 +50,7 @@ public void setCharset(Charset charset) { public void visitFile(AstNode astNode) { try { Files.readAllLines(getContext().getFile().toPath(), charset); - } catch (IOException e) { + } catch (IOException e) { //NOSONAR getContext().createFileViolation(this, "Not all characters of the file can be encoded with the predefined charset " + charset.name() + "."); } } diff --git a/cxx-checks/src/main/java/org/sonar/cxx/checks/FileHeaderCheck.java b/cxx-checks/src/main/java/org/sonar/cxx/checks/FileHeaderCheck.java index 4994fc8a6a..017ad33b8a 100644 --- a/cxx-checks/src/main/java/org/sonar/cxx/checks/FileHeaderCheck.java +++ b/cxx-checks/src/main/java/org/sonar/cxx/checks/FileHeaderCheck.java @@ -49,7 +49,7 @@ @ActivatedByDefault @SqaleConstantRemediation("5min") //similar Vera++ rule T013 "No copyright notice found" -public class FileHeaderCheck extends SquidCheck implements CxxCharsetAwareVisitor { +public class FileHeaderCheck extends SquidCheck implements CxxCharsetAwareVisitor { //NOSONAR private static final String DEFAULT_HEADER_FORMAT = ""; private static final String MESSAGE = "Add or update the header of this file."; @@ -105,7 +105,7 @@ public void visitFile(AstNode astNode) { List lines; try { lines = Files.readLines(getContext().getFile(), charset); - } catch (IOException e) { + } catch (IOException e) { //NOSONAR throw new IllegalStateException(e); } diff --git a/cxx-checks/src/main/java/org/sonar/cxx/checks/FileRegularExpressionCheck.java b/cxx-checks/src/main/java/org/sonar/cxx/checks/FileRegularExpressionCheck.java index 563958c97b..944a3caaad 100644 --- a/cxx-checks/src/main/java/org/sonar/cxx/checks/FileRegularExpressionCheck.java +++ b/cxx-checks/src/main/java/org/sonar/cxx/checks/FileRegularExpressionCheck.java @@ -28,14 +28,16 @@ import org.sonar.squidbridge.checks.SquidCheck; import java.io.File; import java.io.FileInputStream; +import java.io.IOException; import java.nio.ByteBuffer; -import java.nio.CharBuffer; import java.nio.channels.FileChannel; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.nio.charset.CodingErrorAction; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; + import org.sonar.api.utils.PathUtils; import org.sonar.api.utils.WildcardPattern; import org.sonar.squidbridge.annotations.NoSqale; @@ -47,7 +49,7 @@ priority = Priority.MAJOR) @RuleTemplate @NoSqale -public class FileRegularExpressionCheck extends SquidCheck implements CxxCharsetAwareVisitor { +public class FileRegularExpressionCheck extends SquidCheck implements CxxCharsetAwareVisitor { //NOSONAR private static final String DEFAULT_MATCH_FILE_PATTERN = ""; private static final boolean DEFAULT_INVERT_FILE_PATTERN = false; @@ -96,8 +98,10 @@ public void init() { decoder = charset.newDecoder(); decoder.onMalformedInput(CodingErrorAction.REPLACE); decoder.onUnmappableCharacter(CodingErrorAction.REPLACE); - } catch (Exception e) { - throw new IllegalStateException(e); + } catch (PatternSyntaxException ex) { + throw new IllegalStateException(ex); + } catch (IllegalArgumentException ex2) { + throw new IllegalStateException(ex2); } } @@ -108,7 +112,6 @@ public void setCharset(Charset charset) { @Override public void visitFile(AstNode fileNode) { - if (fileNode != null) { try { if (!compare(invertFilePattern, matchFile())) { return; @@ -117,11 +120,10 @@ public void visitFile(AstNode fileNode) { if (compare(invertRegularExpression, matcher.find())) { getContext().createFileViolation(this, message); } - } catch (Exception e) { - throw new IllegalStateException(e); + } catch (Exception e) { //NOSONAR + throw new IllegalStateException(e); } } - } private boolean matchFile() { if (!matchFilePattern.isEmpty()) { @@ -132,18 +134,11 @@ private boolean matchFile() { return true; } - private CharSequence fromFile(File file) throws Exception { - FileInputStream input = null; - try { - input = new FileInputStream(file); + private CharSequence fromFile(File file) throws IOException { + try (FileInputStream input = new FileInputStream(file)) { FileChannel channel = input.getChannel(); ByteBuffer bbuf = channel.map(FileChannel.MapMode.READ_ONLY, 0, (int) channel.size()); - CharBuffer cbuf = decoder.decode(bbuf); - return cbuf; - } finally { - if (input != null) { - input.close(); - } + return decoder.decode(bbuf); } } 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 5bcbffd803..c47bbd2925 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 @@ -53,7 +53,7 @@ public class HardcodedAccountCheck extends SquidCheck { * */ private static final String DEFAULT_REGULAR_EXPRESSION = "\\bDSN\\b.*=.*;\\b(UID|PWD)\\b=.*;"; - private static Matcher reg; + private static volatile Matcher reg = null; @RuleProperty( key = "regularExpression", 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 c17dc2c6e1..049b20cdaf 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 @@ -30,10 +30,8 @@ import org.sonar.squidbridge.checks.SquidCheck; import com.sonar.sslr.api.AstNode; import com.sonar.sslr.api.Grammar; -import org.sonar.api.server.rule.RulesDefinition; import org.sonar.squidbridge.annotations.ActivatedByDefault; import org.sonar.squidbridge.annotations.SqaleConstantRemediation; -import org.sonar.squidbridge.annotations.SqaleSubCharacteristic; import org.sonar.cxx.tag.Tag; @Rule( @@ -42,7 +40,6 @@ tags = {Tag.CERT, Tag.SECURITY}, priority = Priority.CRITICAL) @ActivatedByDefault -@SqaleSubCharacteristic(RulesDefinition.SubCharacteristics.ARCHITECTURE_CHANGEABILITY) @SqaleConstantRemediation("30min") public class HardcodedIpCheck extends SquidCheck { @@ -53,7 +50,7 @@ public class HardcodedIpCheck extends SquidCheck { // IPv4 with port number // (?:^|\s)([a-z]{3,6}(?=://))?(://)?((?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.(?:25[0-5]|2[0-4]\d|[01]?\d\d?))(?::(\d{2,5}))?(?:\s|$) private static final String DEFAULT_REGULAR_EXPRESSION = "^.*((? implements CxxCharsetAwareVisitor { +public class LineRegularExpressionCheck extends SquidCheck implements CxxCharsetAwareVisitor { //NOSONAR private static final String DEFAULT_MATCH_FILE_PATTERN = ""; private static final boolean DEFAULT_INVERT_FILE_PATTERN = false; @@ -104,7 +104,6 @@ public void setCharset(Charset charset) { @Override public void visitFile(AstNode fileNode) { - if (fileNode != null) { if (compare(invertFilePattern, matchFile())) { List lines; try { @@ -120,7 +119,6 @@ public void visitFile(AstNode fileNode) { } } } - } private boolean matchFile() { if (!matchFilePattern.isEmpty()) { 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 43625e6fe0..0eb756ae92 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 @@ -104,7 +104,7 @@ private boolean isConst(AstNode node) { } if (decl != null) { for (AstNode qualifier : decl.getDescendants(CxxGrammarImpl.cvQualifier)) { - if (qualifier.getToken().getType() == CxxKeyword.CONST) { + if (qualifier.getToken().getType().equals(CxxKeyword.CONST)) { return true; } } diff --git a/cxx-checks/src/main/java/org/sonar/cxx/checks/MissingNewLineAtEndOfFileCheck.java b/cxx-checks/src/main/java/org/sonar/cxx/checks/MissingNewLineAtEndOfFileCheck.java index 2ca69e02ab..188938dd05 100644 --- a/cxx-checks/src/main/java/org/sonar/cxx/checks/MissingNewLineAtEndOfFileCheck.java +++ b/cxx-checks/src/main/java/org/sonar/cxx/checks/MissingNewLineAtEndOfFileCheck.java @@ -21,6 +21,8 @@ import java.io.IOException; import java.io.RandomAccessFile; +import java.nio.charset.StandardCharsets; + import org.sonar.check.Priority; import org.sonar.check.Rule; import org.sonar.squidbridge.checks.SquidCheck; @@ -61,7 +63,7 @@ private boolean endsWithNewline(RandomAccessFile randomAccessFile) throws IOExce if (randomAccessFile.read(chars) < 1) { return false; } - String ch = new String(chars); + String ch = new String(chars, StandardCharsets.UTF_8); return "\n".equals(ch) || "\r".equals(ch); } 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 c7a55527b6..50847dad70 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 @@ -45,7 +45,7 @@ ) @ActivatedByDefault @SqaleConstantRemediation("10min") -public class NestedStatementsCheck extends SquidCheck { +public class NestedStatementsCheck extends SquidCheck { //NOSONAR private static final AstNodeType[] CHECKED_TYPES = new AstNodeType[]{ CxxGrammarImpl.selectionStatement, @@ -55,8 +55,6 @@ public class NestedStatementsCheck extends SquidCheck { private static final int DEFAULT_MAX = 3; - private static final String ELSE_TOKEN = "ELSE"; - @RuleProperty( key = "max", description = "Maximum allowed control flow statement nesting depth.", @@ -99,7 +97,7 @@ public void visitNode(AstNode node) { nestingLevel--; } - // Prevent re-checking of descendent nodes + // Prevent re-checking of descendant nodes checkedNodes.addAll(watchedDescendants); } @@ -113,6 +111,6 @@ private void visitChildren(List watchedDescendants) { * @return True if the given node is the 'if' in an 'else if' construct. */ private boolean isElseIf(AstNode node) { - return isIfStatement(node) && node.getParent().getPreviousAstNode().getType()==CxxKeyword.ELSE; + return isIfStatement(node) && node.getParent().getPreviousAstNode().getType().equals(CxxKeyword.ELSE); } } diff --git a/cxx-checks/src/main/java/org/sonar/cxx/checks/ParsingErrorCheck.java b/cxx-checks/src/main/java/org/sonar/cxx/checks/ParsingErrorCheck.java index 78f1e70fe4..210d98d095 100644 --- a/cxx-checks/src/main/java/org/sonar/cxx/checks/ParsingErrorCheck.java +++ b/cxx-checks/src/main/java/org/sonar/cxx/checks/ParsingErrorCheck.java @@ -23,6 +23,7 @@ import java.io.StringWriter; import org.sonar.check.Priority; import org.sonar.check.Rule; +import org.sonar.cxx.tag.Tag; import org.sonar.squidbridge.AstScannerExceptionHandler; import org.sonar.squidbridge.checks.SquidCheck; import com.sonar.sslr.api.Grammar; @@ -33,6 +34,7 @@ @Rule( key = "ParsingError", name = "C++ parser failure", + tags = {Tag.TOOL_ERROR}, priority = Priority.MAJOR) @ActivatedByDefault @NoSqale diff --git a/cxx-checks/src/main/java/org/sonar/cxx/checks/ParsingErrorRecoveryCheck.java b/cxx-checks/src/main/java/org/sonar/cxx/checks/ParsingErrorRecoveryCheck.java index 870c6a2126..b68d1d6776 100644 --- a/cxx-checks/src/main/java/org/sonar/cxx/checks/ParsingErrorRecoveryCheck.java +++ b/cxx-checks/src/main/java/org/sonar/cxx/checks/ParsingErrorRecoveryCheck.java @@ -22,6 +22,7 @@ import org.sonar.check.Priority; import org.sonar.check.Rule; import org.sonar.cxx.parser.CxxGrammarImpl; +import org.sonar.cxx.tag.Tag; import org.sonar.squidbridge.checks.SquidCheck; import com.sonar.sslr.api.AstNode; import com.sonar.sslr.api.Grammar; @@ -31,6 +32,7 @@ @Rule( key = "ParsingErrorRecovery", name = "C++ skip parser error", + tags = {Tag.TOOL_ERROR}, priority = Priority.INFO) @ActivatedByDefault @NoSqale 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 ec0af46142..57e44f6c14 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 @@ -46,9 +46,9 @@ @ActivatedByDefault @SqaleConstantRemediation("5min") //similar Vera++ rule T002 -public class ReservedNamesCheck extends SquidCheck implements CxxCharsetAwareVisitor { +public class ReservedNamesCheck extends SquidCheck implements CxxCharsetAwareVisitor { //NOSONAR - private static String[] keywords; + private static volatile String[] keywords = null; private Charset charset; @Override diff --git a/cxx-checks/src/main/java/org/sonar/cxx/checks/SafetyTagCheck.java b/cxx-checks/src/main/java/org/sonar/cxx/checks/SafetyTagCheck.java index b547b6242c..1afa6cb20e 100644 --- a/cxx-checks/src/main/java/org/sonar/cxx/checks/SafetyTagCheck.java +++ b/cxx-checks/src/main/java/org/sonar/cxx/checks/SafetyTagCheck.java @@ -42,7 +42,7 @@ tags = {Tag.CONVENTION}) @ActivatedByDefault @SqaleConstantRemediation("5min") -public class SafetyTagCheck extends SquidCheck implements AstAndTokenVisitor { +public class SafetyTagCheck extends SquidCheck implements AstAndTokenVisitor { //NOSONAR private static final String DEFAULT_REGULAR_EXPRESSION = ".*"; private static final String DEFAULT_MESSAGE = "Source files implementing risk mitigations shall use special name suffix"; 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 521c08c4aa..a1fb58f42c 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 @@ -38,7 +38,7 @@ key = "SwitchLastCaseIsDefault", name = "Switch statements should end with a default case", priority = Priority.MAJOR, - tags = {Tag.PITFALL}) + tags = {Tag.BAD_PRACTICE, Tag.PITFALL}) @ActivatedByDefault @SqaleConstantRemediation("5min") public class SwitchLastCaseIsDefaultCheck extends SquidCheck { diff --git a/cxx-checks/src/main/java/org/sonar/cxx/checks/TabCharacterCheck.java b/cxx-checks/src/main/java/org/sonar/cxx/checks/TabCharacterCheck.java index 90070f43fc..424372c343 100644 --- a/cxx-checks/src/main/java/org/sonar/cxx/checks/TabCharacterCheck.java +++ b/cxx-checks/src/main/java/org/sonar/cxx/checks/TabCharacterCheck.java @@ -45,7 +45,7 @@ @ActivatedByDefault @SqaleConstantRemediation("5min") //similar Vera++ rule L002 "Don't use tab characters" -public class TabCharacterCheck extends SquidCheck implements CxxCharsetAwareVisitor { +public class TabCharacterCheck extends SquidCheck implements CxxCharsetAwareVisitor { //NOSONAR private static final boolean DEFAULT_CREATE_LINE_VIOLATION = false; diff --git a/cxx-checks/src/main/java/org/sonar/cxx/checks/TooLongLineCheck.java b/cxx-checks/src/main/java/org/sonar/cxx/checks/TooLongLineCheck.java index 655572d46d..70615bd534 100644 --- a/cxx-checks/src/main/java/org/sonar/cxx/checks/TooLongLineCheck.java +++ b/cxx-checks/src/main/java/org/sonar/cxx/checks/TooLongLineCheck.java @@ -45,7 +45,7 @@ @ActivatedByDefault @SqaleConstantRemediation("5min") //similar Vera++ rule L004 "Line too long" -public class TooLongLineCheck extends SquidCheck implements CxxCharsetAwareVisitor { +public class TooLongLineCheck extends SquidCheck implements CxxCharsetAwareVisitor { //NOSONAR private static final int DEFAULT_MAXIMUM_LINE_LENHGTH = 160; private static final int DEFAULT_TAB_WIDTH = 8; diff --git a/cxx-checks/src/main/java/org/sonar/cxx/checks/TooManyLinesOfCodeInFunctionCheck.java b/cxx-checks/src/main/java/org/sonar/cxx/checks/TooManyLinesOfCodeInFunctionCheck.java index 796d0d65f5..2e2c78c779 100644 --- a/cxx-checks/src/main/java/org/sonar/cxx/checks/TooManyLinesOfCodeInFunctionCheck.java +++ b/cxx-checks/src/main/java/org/sonar/cxx/checks/TooManyLinesOfCodeInFunctionCheck.java @@ -21,7 +21,6 @@ import java.util.List; -import org.sonar.api.server.rule.RulesDefinition; import org.sonar.check.Priority; import org.sonar.check.Rule; import org.sonar.check.RuleProperty; @@ -30,7 +29,6 @@ import org.sonar.cxx.tag.Tag; import org.sonar.squidbridge.annotations.ActivatedByDefault; import org.sonar.squidbridge.annotations.SqaleConstantRemediation; -import org.sonar.squidbridge.annotations.SqaleSubCharacteristic; import com.sonar.sslr.api.AstNode; import com.sonar.sslr.api.Grammar; import org.sonar.squidbridge.checks.SquidCheck; @@ -40,9 +38,8 @@ priority = Priority.MAJOR, tags = {Tag.BRAIN_OVERLOAD}) @ActivatedByDefault -@SqaleSubCharacteristic(RulesDefinition.SubCharacteristics.READABILITY) @SqaleConstantRemediation("1h") -public class TooManyLinesOfCodeInFunctionCheck extends SquidCheck { +public class TooManyLinesOfCodeInFunctionCheck extends SquidCheck { //NOSONAR private static final int DEFAULT_MAXIMUM = 200; @RuleProperty( diff --git a/cxx-checks/src/main/java/org/sonar/cxx/checks/TooManyStatementsPerLineCheck.java b/cxx-checks/src/main/java/org/sonar/cxx/checks/TooManyStatementsPerLineCheck.java index 3b42dd72d3..76bef65ddb 100644 --- a/cxx-checks/src/main/java/org/sonar/cxx/checks/TooManyStatementsPerLineCheck.java +++ b/cxx-checks/src/main/java/org/sonar/cxx/checks/TooManyStatementsPerLineCheck.java @@ -75,7 +75,7 @@ private boolean isGeneratedNodeExcluded(AstNode astNode) { */ private boolean isBreakStatementExcluded(AstNode astNode) { boolean exclude = false; - if (excludeCaseBreak && astNode.getToken().getType() == CxxKeyword.BREAK) { + if (excludeCaseBreak && astNode.getToken().getType().equals(CxxKeyword.BREAK)) { for (AstNode statement = astNode.getFirstAncestor(CxxGrammarImpl.statement); statement != null; statement = statement.getPreviousSibling()) { @@ -83,7 +83,7 @@ private boolean isBreakStatementExcluded(AstNode astNode) { break; } TokenType type = statement.getToken().getType(); - if (type == CxxKeyword.CASE || type == CxxKeyword.DEFAULT) { + if (type.equals(CxxKeyword.CASE) || type.equals(CxxKeyword.DEFAULT)) { exclude = true; break; } diff --git a/cxx-checks/src/main/java/org/sonar/cxx/checks/UseCorrectIncludeCheck.java b/cxx-checks/src/main/java/org/sonar/cxx/checks/UseCorrectIncludeCheck.java index aa48529221..4fbb58ecbe 100644 --- a/cxx-checks/src/main/java/org/sonar/cxx/checks/UseCorrectIncludeCheck.java +++ b/cxx-checks/src/main/java/org/sonar/cxx/checks/UseCorrectIncludeCheck.java @@ -43,7 +43,7 @@ priority = Priority.BLOCKER) @ActivatedByDefault @SqaleConstantRemediation("5min") -public class UseCorrectIncludeCheck extends SquidCheck implements CxxCharsetAwareVisitor { +public class UseCorrectIncludeCheck extends SquidCheck implements CxxCharsetAwareVisitor { //NOSONAR private static final String DEFAULT_REGULAR_EXPRESSION = "#include\\s+(?>\"|\\<)[\\\\/\\.]+"; private static final String DEFAULT_MESSAGE = "Use correct #include directives"; diff --git a/cxx-checks/src/main/java/org/sonar/cxx/checks/UseCorrectTypeCheck.java b/cxx-checks/src/main/java/org/sonar/cxx/checks/UseCorrectTypeCheck.java index b143a1472a..da124525f2 100644 --- a/cxx-checks/src/main/java/org/sonar/cxx/checks/UseCorrectTypeCheck.java +++ b/cxx-checks/src/main/java/org/sonar/cxx/checks/UseCorrectTypeCheck.java @@ -41,7 +41,7 @@ priority = Priority.MINOR) @RuleTemplate @NoSqale -public class UseCorrectTypeCheck extends SquidCheck { +public class UseCorrectTypeCheck extends SquidCheck { //NOSONAR private static final AstNodeType[] CHECKED_TYPES = new AstNodeType[]{ CxxGrammarImpl.typeName, 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 e394b167a9..7ef740af3b 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 @@ -51,7 +51,7 @@ public void init() { @Override public void visitNode(AstNode node) { if (isHeader(getContext().getFile().getName()) - && node.getTokenValue().equals("using") && node.getFirstChild().getChildren().toString().contains("namespace")) { + && "using".equals(node.getTokenValue()) && node.getFirstChild().getChildren().toString().contains("namespace")) { getContext().createLineViolation(this, "Using namespace are not allowed in header files.", node); } } diff --git a/cxx-checks/src/main/java/org/sonar/cxx/checks/XPathCheck.java b/cxx-checks/src/main/java/org/sonar/cxx/checks/XPathCheck.java index da4cbd05dc..d3c8aa9deb 100644 --- a/cxx-checks/src/main/java/org/sonar/cxx/checks/XPathCheck.java +++ b/cxx-checks/src/main/java/org/sonar/cxx/checks/XPathCheck.java @@ -36,7 +36,7 @@ priority = Priority.MAJOR) @RuleTemplate @NoSqale -public class XPathCheck extends AbstractXPathCheck { +public class XPathCheck extends AbstractXPathCheck { //NOSONAR private static final String DEFAULT_MATCH_FILE_PATTERN = ""; private static final boolean DEFAULT_INVERT_FILE_PATTERN = false; @@ -80,7 +80,6 @@ public String getMessage() { @Override public void visitFile(AstNode fileNode) { - if (fileNode != null) { if (!matchFilePattern.isEmpty()) { WildcardPattern pattern = WildcardPattern.create(matchFilePattern); String path = PathUtils.sanitize(getContext().getFile().getPath()); @@ -89,7 +88,6 @@ public void visitFile(AstNode fileNode) { } } super.visitFile(fileNode); - } } private boolean compare(boolean invert, boolean condition) { diff --git a/cxx-checks/src/main/java/org/sonar/cxx/checks/naming/ClassNameCheck.java b/cxx-checks/src/main/java/org/sonar/cxx/checks/naming/ClassNameCheck.java index e16c8329ff..c5b1d29906 100644 --- a/cxx-checks/src/main/java/org/sonar/cxx/checks/naming/ClassNameCheck.java +++ b/cxx-checks/src/main/java/org/sonar/cxx/checks/naming/ClassNameCheck.java @@ -39,7 +39,7 @@ tags = {Tag.CONVENTION}) @SqaleConstantRemediation("5min") @ActivatedByDefault -public class ClassNameCheck extends SquidCheck { +public class ClassNameCheck extends SquidCheck { //NOSONAR private static final String DEFAULT = "^[A-Z_][a-zA-Z0-9]+$"; diff --git a/cxx-checks/src/main/java/org/sonar/cxx/checks/naming/FileNameCheck.java b/cxx-checks/src/main/java/org/sonar/cxx/checks/naming/FileNameCheck.java index 57e2a19303..4bc952d7ef 100644 --- a/cxx-checks/src/main/java/org/sonar/cxx/checks/naming/FileNameCheck.java +++ b/cxx-checks/src/main/java/org/sonar/cxx/checks/naming/FileNameCheck.java @@ -37,7 +37,7 @@ name = "File names should comply with a naming convention", tags = {Tag.CONVENTION}) @SqaleConstantRemediation("10min") -public class FileNameCheck extends SquidCheck { +public class FileNameCheck extends SquidCheck { //NOSONAR private static final String DEFAULT = "(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$"; private static final String MESSAGE = "Rename this file to match this regular expression: \"%s\"."; 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 96552e1afe..e57afc4ba3 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 @@ -39,7 +39,7 @@ ) @SqaleConstantRemediation("10min") @ActivatedByDefault -public class FunctionNameCheck extends SquidCheck { +public class FunctionNameCheck extends SquidCheck { //NOSONAR private static final String DEFAULT = "^[a-z_][a-z0-9_]{2,30}$"; @@ -72,14 +72,10 @@ public void visitNode(AstNode astNode) { private boolean isFunctionDefinition(AstNode declId) { boolean isFunction = false; - if (declId != null) { - // not method inside of class - if (declId.getFirstAncestor(CxxGrammarImpl.memberDeclaration) == null) { - // not a nested name - not method outside of class - if (!declId.hasDirectChildren(CxxGrammarImpl.nestedNameSpecifier)) { - isFunction = true; - } - } + // 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 65373fe6c7..015e75647c 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 @@ -39,7 +39,7 @@ tags = {Tag.CONVENTION}) @SqaleConstantRemediation("10min") @ActivatedByDefault -public class MethodNameCheck extends SquidCheck { +public class MethodNameCheck extends SquidCheck { //NOSONAR private static final String DEFAULT = "^[A-Z][A-Za-z0-9]{2,30}$"; 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 a8006a40cb..7e0833dfc1 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 @@ -31,33 +31,33 @@ private CheckUtils() { } public static boolean isIfStatement(AstNode node) { - if (node != null && node.is(CxxGrammarImpl.selectionStatement)) { - return node.getToken().getType() == CxxKeyword.IF; + if (node.is(CxxGrammarImpl.selectionStatement)) { + return node.getToken().getType().equals(CxxKeyword.IF); } return false; } public static boolean isSwitchStatement(AstNode node) { - if (node != null && node.is(CxxGrammarImpl.selectionStatement)) { - return node.getToken().getType() == CxxKeyword.SWITCH; + if (node.is(CxxGrammarImpl.selectionStatement)) { + return node.getToken().getType().equals(CxxKeyword.SWITCH); } return false; } public static boolean isParenthesisedExpression(AstNode node) { - if (node != null && node.is(CxxGrammarImpl.primaryExpression)) { - if (node.getFirstChild().is(CxxPunctuator.BR_LEFT) && node.getLastChild().is(CxxPunctuator.BR_RIGHT)) { - if (node.getParent().is(CxxGrammarImpl.expression) && !node.isCopyBookOrGeneratedNode()) { + if (node.is(CxxGrammarImpl.primaryExpression) //NOSONAR + && node.getFirstChild().is(CxxPunctuator.BR_LEFT) + && node.getLastChild().is(CxxPunctuator.BR_RIGHT) + && node.getParent().is(CxxGrammarImpl.expression) + && !node.isCopyBookOrGeneratedNode()) { return true; } - } - } return false; } public static boolean isIdentifierLabel(AstNode node) { - if (node != null && node.is(CxxGrammarImpl.labeledStatement)) { - return node.getToken().getType() == GenericTokenType.IDENTIFIER; + if (node.is(CxxGrammarImpl.labeledStatement)) { + return node.getToken().getType().equals(GenericTokenType.IDENTIFIER); } return false; } 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 6090a30020..2033ad1871 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 @@ -25,9 +25,13 @@ import com.google.gson.JsonSyntaxException; import com.sonar.sslr.api.Grammar; import java.beans.Statement; +import java.io.BufferedReader; import java.io.File; -import java.io.FileReader; +import java.io.FileInputStream; +import java.io.InputStream; +import java.io.InputStreamReader; import java.io.IOException; +import java.io.Reader; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.lang.reflect.Proxy; @@ -74,15 +78,16 @@ private static Options CreateCommandLineOptions() { return options; } - public static String readFile(String filename) throws IOException { + public static String readFile(String filename, Charset charset) throws IOException { String content = null; File file = new File(filename); //for ex foo.txt - try (FileReader reader = new FileReader(file)) { + try (FileInputStream input = new FileInputStream(file)) { + BufferedReader reader = new BufferedReader(new InputStreamReader(input, charset)); char[] chars = new char[(int) file.length()]; reader.read(chars); content = new String(chars); reader.close(); - } catch (IOException e) { + } catch (IOException e) { //NOSONAR } return content; } @@ -93,8 +98,8 @@ public static String readFile(String filename) throws IOException { * @throws java.lang.IllegalAccessException * @throws java.io.IOException */ - public static void main(String[] args) - throws InstantiationException, IllegalAccessException, IOException, Exception { + public static void main(String[] args) + throws InstantiationException, IllegalAccessException, IOException, Exception { //NOSONAR CommandLineParser commandlineParser = new DefaultParser(); Options options = CreateCommandLineOptions(); @@ -142,10 +147,10 @@ public static void main(String[] args) sensorContext.fileSystem().add(new DefaultInputFile("myProjectKey", fileName).initMetadata(content)); InputFile cxxFile = sensorContext.fileSystem().inputFile(sensorContext.fileSystem().predicates().hasPath(fileName)); - List rulesData = new ArrayList(); + List rulesData = new ArrayList<>(); if (!"".equals(settingsFile)) { JsonParser parser = new JsonParser(); - String fileContent = readFile(settingsFile); + String fileContent = readFile(settingsFile, Charset.forName(encodingOfFile)); // get basic information String platformToolset = GetJsonStringValue(parser, fileContent, "platformToolset"); @@ -162,7 +167,7 @@ public static void main(String[] args) try { templateKey = data.get("templateKeyId").getAsString(); - } catch(Exception ex) { + } catch(Exception ex) { //NOSONAR } String enabled = data.get("status").getAsString(); @@ -171,7 +176,7 @@ public static void main(String[] args) check.id = ruleId; check.templateId = templateKey; - check.enabled = enabled.equals("Enabled"); + check.enabled = "Enabled".equals(enabled); JsonElement region = data.get("properties"); if (region != null) { for (Entry parameter : region.getAsJsonObject().entrySet()) { @@ -199,10 +204,11 @@ public static void main(String[] args) } JsonElement additionalOptions = parser.parse(fileContent).getAsJsonObject().get("additionalOptions"); - String elementsOfAdditionalOptions = ""; + StringBuilder elementsOfAdditionalOptions = new StringBuilder(); if (additionalOptions != null) { for (JsonElement option : additionalOptions.getAsJsonArray()) { - elementsOfAdditionalOptions = elementsOfAdditionalOptions + " " + option.getAsString(); + elementsOfAdditionalOptions.append(' '); + elementsOfAdditionalOptions.append(option.getAsString()); } } @@ -236,7 +242,7 @@ public static void main(String[] args) changeAnnotationValue(a, "key", checkDefined.id); break; } - } catch (Exception ex) { + } catch (IllegalStateException ex) { //NOSONAR break; } } @@ -244,8 +250,8 @@ public static void main(String[] args) for (Field f : check.getDeclaredFields()) { for (Annotation a : f.getAnnotations()) { RuleProperty ruleProp = (RuleProperty) a; - if (ruleProp != null) { - if (checkDefined.parameterData.containsKey(ruleProp.key())) { + if ((ruleProp != null) + && (checkDefined.parameterData.containsKey(ruleProp.key()))) { if (f.getType().equals(int.class)) { String cleanData = checkDefined.parameterData.get(ruleProp.key()); int value = Integer.parseInt(cleanData); @@ -272,7 +278,6 @@ public static void main(String[] args) } } } - } visitors.add(element); } } @@ -296,7 +301,7 @@ public static void main(String[] args) key = rule.key(); break; } - } catch(Exception ex) { + } catch(Exception ex) { //NOSONAR } } @@ -346,10 +351,10 @@ private static String GetJsonStringValue(JsonParser parser, String fileContent, } private static void HandleVCppAdditionalOptions(String platformToolset, String platform, String elementsOfAdditionalOptions, String project, String fileToAnalyse, CxxConfiguration configuration) { - if(platformToolset.equals("V100") || - platformToolset.equals("V110") || - platformToolset.equals("V120") || - platformToolset.equals("V140")) { + if("V100".equals(platformToolset) + || "V110".equals(platformToolset) + || "V120".equals(platformToolset) + || "V140".equals(platformToolset)) { HashMap> uniqueIncludes = new HashMap<>(); HashMap> uniqueDefines = new HashMap<>(); diff --git a/cxx-squid/src/test/resources/compiler/vc++13.txt b/cxx-squid/src/test/resources/compiler/vc++13.txt index 8fff9307b3..bacefb6341 100644 --- a/cxx-squid/src/test/resources/compiler/vc++13.txt +++ b/cxx-squid/src/test/resources/compiler/vc++13.txt @@ -906,9 +906,9 @@ Task "CL" skipped, due to false condition; ('%(ClCompile.PrecompiledHeader)' == Using "CL" task from assembly "C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.Build.CppTasks.Common.dll". Task "CL" Forcing rebuild of all source files due to missing command TLog "C:\prod\SonarQube\cxx\sonar-cxx\integration-tests\testdata\googletest_bullseye_vs_project\ObjDrop\pathhandling\v120\Debug\Win32\v120\PathHandling.Test\PathHand.6C9EC6AA.tlog\cl.command.1.tlog". - C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\CL.exe /c /ID:/prod/SonarQube/cxx/packages/gtestmock.1.7.2/build/native/../..//build/native/include/ /ID:/prod/SonarQube/cxx/packages/gtestmock.1.7.2/build/native/../..///build/native/include//googletest /I.. /Z7 /nologo /W1 /WX- /Od /Oy- /D NT /D OS_NT /D WIN32 /D _MBCS /D ANSI_HEADER /D GTEST_LINKED_AS_SHARED_LIBRARY=0 /Gm- /EHsc /MD /GS /fp:precise /Zc:wchar_t /Zc:forScope /GR /Fo"C:\prod\SonarQube\cxx\sonar-cxx\integration-tests\testdata\googletest_bullseye_vs_project\ObjDrop\pathhandling\v120\Debug\Win32\v120\PathHandling.Test\\" /Fd"C:\prod\SonarQube\cxx\sonar-cxx\integration-tests\testdata\googletest_bullseye_vs_project\ObjDrop\pathhandling\v120\Debug\Win32\v120\PathHandling.Test\vc120.pdb" /Gd /TP /analyze- /errorReport:queue -D_ITERATOR_DEBUG_LEVEL=0 main.cpp PathHandlingTest.cpp + C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\CL.exe /c /IC:/prod/SonarQube/cxx/packages/gtestmock.1.7.2/build/native/../..//build/native/include/ /IC:/prod/SonarQube/cxx/packages/gtestmock.1.7.2/build/native/../..///build/native/include//googletest /I.. /Z7 /nologo /W1 /WX- /Od /Oy- /D NT /D OS_NT /D WIN32 /D _MBCS /D ANSI_HEADER /D GTEST_LINKED_AS_SHARED_LIBRARY=0 /Gm- /EHsc /MD /GS /fp:precise /Zc:wchar_t /Zc:forScope /GR /Fo"C:\prod\SonarQube\cxx\sonar-cxx\integration-tests\testdata\googletest_bullseye_vs_project\ObjDrop\pathhandling\v120\Debug\Win32\v120\PathHandling.Test\\" /Fd"C:\prod\SonarQube\cxx\sonar-cxx\integration-tests\testdata\googletest_bullseye_vs_project\ObjDrop\pathhandling\v120\Debug\Win32\v120\PathHandling.Test\vc120.pdb" /Gd /TP /analyze- /errorReport:queue -D_ITERATOR_DEBUG_LEVEL=0 main.cpp PathHandlingTest.cpp Tracking command: - C:\Program Files (x86)\MSBuild\12.0\bin\Tracker.exe /d "C:\Program Files (x86)\MSBuild\12.0\bin\FileTracker.dll" /i C:\prod\SonarQube\cxx\sonar-cxx\integration-tests\testdata\googletest_bullseye_vs_project\ObjDrop\pathhandling\v120\Debug\Win32\v120\PathHandling.Test\PathHand.6C9EC6AA.tlog /r "C:\DEVELOPMENT\SONARQUBE\CXX\SONAR-CXX\INTEGRATION-TESTS\TESTDATA\GOOGLETEST_BULLSEYE_VS_PROJECT\PATHHANDLING.TEST\MAIN.CPP|C:\DEVELOPMENT\SONARQUBE\CXX\SONAR-CXX\INTEGRATION-TESTS\TESTDATA\GOOGLETEST_BULLSEYE_VS_PROJECT\PATHHANDLING.TEST\PATHHANDLINGTEST.CPP" /b MSBuildConsole_CancelEventf43bad95b923410bb5a2af0cbdc1b945 /c "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\CL.exe" /c /ID:/prod/SonarQube/cxx/packages/gtestmock.1.7.2/build/native/../..//build/native/include/ /ID:/prod/SonarQube/cxx/packages/gtestmock.1.7.2/build/native/../..///build/native/include//googletest /I.. /Z7 /nologo /W1 /WX- /Od /Oy- /D NT /D OS_NT /D WIN32 /D _MBCS /D ANSI_HEADER /D GTEST_LINKED_AS_SHARED_LIBRARY=0 /Gm- /EHsc /MD /GS /fp:precise /Zc:wchar_t /Zc:forScope /GR /Fo"C:\prod\SonarQube\cxx\sonar-cxx\integration-tests\testdata\googletest_bullseye_vs_project\ObjDrop\pathhandling\v120\Debug\Win32\v120\PathHandling.Test\\" /Fd"C:\prod\SonarQube\cxx\sonar-cxx\integration-tests\testdata\googletest_bullseye_vs_project\ObjDrop\pathhandling\v120\Debug\Win32\v120\PathHandling.Test\vc120.pdb" /Gd /TP /analyze- /errorReport:queue -D_ITERATOR_DEBUG_LEVEL=0 main.cpp PathHandlingTest.cpp + C:\Program Files (x86)\MSBuild\12.0\bin\Tracker.exe /d "C:\Program Files (x86)\MSBuild\12.0\bin\FileTracker.dll" /i C:\prod\SonarQube\cxx\sonar-cxx\integration-tests\testdata\googletest_bullseye_vs_project\ObjDrop\pathhandling\v120\Debug\Win32\v120\PathHandling.Test\PathHand.6C9EC6AA.tlog /r "C:\DEVELOPMENT\SONARQUBE\CXX\SONAR-CXX\INTEGRATION-TESTS\TESTDATA\GOOGLETEST_BULLSEYE_VS_PROJECT\PATHHANDLING.TEST\MAIN.CPP|C:\DEVELOPMENT\SONARQUBE\CXX\SONAR-CXX\INTEGRATION-TESTS\TESTDATA\GOOGLETEST_BULLSEYE_VS_PROJECT\PATHHANDLING.TEST\PATHHANDLINGTEST.CPP" /b MSBuildConsole_CancelEventf43bad95b923410bb5a2af0cbdc1b945 /c "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\CL.exe" /c /IC:/prod/SonarQube/cxx/packages/gtestmock.1.7.2/build/native/../..//build/native/include/ /IC:/prod/SonarQube/cxx/packages/gtestmock.1.7.2/build/native/../..///build/native/include//googletest /I.. /Z7 /nologo /W1 /WX- /Od /Oy- /D NT /D OS_NT /D WIN32 /D _MBCS /D ANSI_HEADER /D GTEST_LINKED_AS_SHARED_LIBRARY=0 /Gm- /EHsc /MD /GS /fp:precise /Zc:wchar_t /Zc:forScope /GR /Fo"C:\prod\SonarQube\cxx\sonar-cxx\integration-tests\testdata\googletest_bullseye_vs_project\ObjDrop\pathhandling\v120\Debug\Win32\v120\PathHandling.Test\\" /Fd"C:\prod\SonarQube\cxx\sonar-cxx\integration-tests\testdata\googletest_bullseye_vs_project\ObjDrop\pathhandling\v120\Debug\Win32\v120\PathHandling.Test\vc120.pdb" /Gd /TP /analyze- /errorReport:queue -D_ITERATOR_DEBUG_LEVEL=0 main.cpp PathHandlingTest.cpp main.cpp PathHandlingTest.cpp Generating Code... From ee1c31d4144264ab8faa92e5d8669fa8d1bad3b5 Mon Sep 17 00:00:00 2001 From: Bert Date: Tue, 18 Apr 2017 17:58:05 +0200 Subject: [PATCH 2/6] fix more sonarlint issues - reduce noise --- .../java/org/sonar/cxx/CxxConfiguration.java | 36 ++++-- .../main/java/org/sonar/cxx/CxxLanguage.java | 34 +++++- .../org/sonar/cxx/CxxVCppBuildLogParser.java | 60 +++++---- .../channels/CharacterLiteralsChannel.java | 4 +- .../cxx/channels/StringLiteralsChannel.java | 2 +- .../java/org/sonar/cxx/parser/CxxParser.java | 2 +- .../cxx/preprocessor/CxxPreprocessor.java | 115 +++++++++--------- .../cxx/preprocessor/ExpressionEvaluator.java | 94 +++++++------- .../preprocessor/JoinStringsPreprocessor.java | 8 +- .../org/sonar/cxx/preprocessor/MapChain.java | 2 +- .../visitors/AbstractCxxPublicApiVisitor.java | 69 +++++------ .../cxx/visitors/CxxCommentLinesVisitor.java | 2 +- .../cxx/visitors/CxxLinesOfCodeVisitor.java | 7 +- .../visitors/CxxParseErrorLoggerVisitor.java | 9 +- .../cxx/visitors/CxxPublicApiVisitor.java | 2 +- .../org/sonar/plugins/c/package-info.java | 2 +- 16 files changed, 253 insertions(+), 195 deletions(-) diff --git a/cxx-squid/src/main/java/org/sonar/cxx/CxxConfiguration.java b/cxx-squid/src/main/java/org/sonar/cxx/CxxConfiguration.java index 10e9dc8399..4f21f6f979 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/CxxConfiguration.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/CxxConfiguration.java @@ -29,7 +29,10 @@ import java.util.List; import java.util.Set; +import javax.annotation.Nullable; + import org.sonar.api.utils.log.Logger; +import org.sonar.api.utils.log.LoggerLevel; import org.sonar.api.utils.log.Loggers; import org.sonar.api.batch.fs.FileSystem; import org.sonar.squidbridge.api.SquidConfiguration; @@ -89,7 +92,7 @@ public boolean getIgnoreHeaderComments() { } public void setDefines(String[] defines) { - if (defines == null) { + if (defines == null) { //NOSONAR return; } @@ -140,7 +143,7 @@ public void addOverallIncludeDirectory(String includeDirectory) { } } - public void setIncludeDirectories(String[] includeDirectories) { + public void setIncludeDirectories(@Nullable String[] includeDirectories) { if (includeDirectories != null) { setIncludeDirectories(Arrays.asList(includeDirectories)); } @@ -164,7 +167,7 @@ public void setForceIncludeFiles(List forceIncludeFiles) { this.forceIncludeFiles = forceIncludeFiles; } - public void setForceIncludeFiles(String[] forceIncludeFiles) { + public void setForceIncludeFiles(@Nullable String[] forceIncludeFiles) { if (forceIncludeFiles != null) { setForceIncludeFiles(Arrays.asList(forceIncludeFiles)); } @@ -194,7 +197,7 @@ public List getCFilesPatterns() { return cFilesPatterns; } - public void setCFilesPatterns(String[] cFilesPatterns) { + public void setCFilesPatterns(@Nullable String[] cFilesPatterns) { if (cFilesPatterns != null) { this.cFilesPatterns = Arrays.asList(cFilesPatterns); } @@ -204,7 +207,7 @@ public void setHeaderFileSuffixes(List headerFileSuffixes) { this.headerFileSuffixes = headerFileSuffixes; } - public void setHeaderFileSuffixes(String[] headerFileSuffixes) { + public void setHeaderFileSuffixes(@Nullable String[] headerFileSuffixes) { if (headerFileSuffixes != null) { setHeaderFileSuffixes(Arrays.asList(headerFileSuffixes)); } @@ -255,7 +258,7 @@ public void addCompilationUnitSettings(String filename, CxxCompilationUnitSettin } public List getCompilationUnitSourceFiles() { - List files = new ArrayList(); + List files = new ArrayList<>(); for (Iterator iter = compilationUnitSettings.keySet().iterator(); iter.hasNext(); ) { String item = iter.next(); @@ -280,17 +283,32 @@ public void setCompilationPropertiesWithBuildLog(List reports, } if ("Visual C++".equals(fileFormat)) { cxxVCppParser.parseVCppLog(buildLog, baseDir, charsetName); - LOG.info("Parse build log '"+ buildLog.getAbsolutePath() +"' added includes: '"+ uniqueIncludes.size() +"', added defines: '" + uniqueDefines.size() + "'"); + LOG.info("Parse build log '"+ buildLog.getAbsolutePath() + +"' added includes: '" + uniqueIncludes.size() + +"', added defines: '" + uniqueDefines.size() + "'"); + } + if(LOG.isDebugEnabled()) { + LOG.debug("Parse build log OK"); + for (List allIncludes : uniqueIncludes.values()) { + if (!allIncludes.isEmpty()) { + LOG.debug("Includes folders ({})='{}'", allIncludes.size(), allIncludes); + } + } + for (Set allDefines : uniqueDefines.values()) { + if (!allDefines.isEmpty()) { + LOG.debug("Defines ({})='{}'", allDefines.size(), allDefines); + } + } } - - LOG.debug("Parse build log OK: includes: '{}' defines: '{}'", uniqueIncludes.size(), uniqueDefines.size()); } else { LOG.error("Compilation log not found: '{}'", buildLog.getAbsolutePath()); } } + } public Charset getEncoding() { return super.getCharset(); } } + 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 74ffc9b32a..2c18dd579a 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/CxxLanguage.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/CxxLanguage.java @@ -26,6 +26,7 @@ import org.sonar.api.measures.Metric; import org.sonar.api.resources.AbstractLanguage; import org.sonar.api.config.Settings; +import org.sonar.api.internal.apachecommons.lang.builder.HashCodeBuilder; /** * {@inheritDoc} @@ -47,11 +48,36 @@ public CxxLanguage(String key, String name, Settings settings) { this.MetricsCache = new HashMap<>(); } + @Override + public int hashCode() { + return new HashCodeBuilder(17, 31). // two randomly chosen prime numbers + appendSuper(super.hashCode()). + append(getKey()). + toHashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + + if (obj == null) { + return false; + } + + if (this.getClass() == obj.getClass()) { + return getKey().equals(((AbstractLanguage) obj).getKey()); + } else { + return false; + } + } + /** * {@inheritDoc} */ - @Override - public abstract String[] getFileSuffixes(); +// @Override +// public abstract String[] getFileSuffixes(); public abstract String[] getSourceFileSuffixes(); @@ -61,9 +87,9 @@ public CxxLanguage(String key, String name, Settings settings) { public abstract List getChecks(); public abstract String getRepositoryKey(); - + public String getRepositorySuffix() { - return ""; + return ""; //NOSONAR } public String getPluginProperty(String 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 ed1d65708e..cf38005050 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/CxxVCppBuildLogParser.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/CxxVCppBuildLogParser.java @@ -23,6 +23,7 @@ import java.io.File; import java.io.FileInputStream; import java.io.IOException; +import java.io.InputStream; import java.io.InputStreamReader; import java.nio.file.InvalidPathException; import java.nio.file.Path; @@ -31,10 +32,12 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.sonar.api.utils.log.Logger; +import org.sonar.api.utils.log.LoggerLevel; import org.sonar.api.utils.log.Loggers; public class CxxVCppBuildLogParser { @@ -49,8 +52,8 @@ public class CxxVCppBuildLogParser { private static final String CPPWINRTVERSION = "__cplusplus_winrt=201009"; private static final String CPPVERSION = "__cplusplus=199711L"; - public CxxVCppBuildLogParser(HashMap> uniqueIncludesIn, - HashMap> uniqueDefinesIn) { + public CxxVCppBuildLogParser(HashMap> uniqueIncludesIn, //NOSONAR + HashMap> uniqueDefinesIn) { //NOSONAR uniqueIncludes = uniqueIncludesIn; uniqueDefines = uniqueDefinesIn; } @@ -79,9 +82,8 @@ public void parseVCppLine(String line, String projectPath, String compilationFil } public void parseVCppLog(File buildLog, String baseDir, String charsetName) { - - try { - BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(buildLog), charsetName)); + try (FileInputStream input = new FileInputStream(buildLog)) { + BufferedReader br = new BufferedReader(new InputStreamReader(input, charsetName)); String line; LOG.debug("build log parser baseDir='{}'", baseDir); Path currentProjectPath = Paths.get(baseDir); @@ -137,24 +139,7 @@ public void parseVCppLog(File buildLog, String baseDir, String charsetName) { if (line.matches("^.*\\\\bin\\\\.*CL.exe\\x20.*$")) { String[] allElems = line.split("\\s+"); String data = allElems[allElems.length - 1]; - try { - String fileElement = Paths.get(currentProjectPath.toAbsolutePath().toString(), data).toAbsolutePath().toString(); - - if (!uniqueDefines.containsKey(fileElement)) { - uniqueDefines.put(fileElement, new HashSet()); - } - - if (!uniqueIncludes.containsKey(fileElement)) { - uniqueIncludes.put(fileElement, new ArrayList()); - } - - parseVCppCompilerCLLine(line, currentProjectPath.toAbsolutePath().toString(), fileElement); - } catch (InvalidPathException ex) { - LOG.warn("Cannot extract information from current element: " + data + " : " + ex.getMessage()); - } catch (NullPointerException ex) { - LOG.error("Bug in parser, please report: '{}' - '{}'", ex.getMessage(), data + " @ " + currentProjectPath); - LOG.error("StackTrace: '{}'", ex.getStackTrace()); - } + parseCLParameters(line, currentProjectPath, data); } } br.close(); @@ -163,6 +148,33 @@ public void parseVCppLog(File buildLog, String baseDir, String charsetName) { } } + /** + * @param line + * @param currentProjectPath + * @param data + */ + private void parseCLParameters(String line, Path currentProjectPath, String data) { + try { + String fileElement = Paths.get(currentProjectPath.toAbsolutePath().toString(), data).toAbsolutePath().toString(); + + if (!uniqueDefines.containsKey(fileElement)) { + uniqueDefines.put(fileElement, new HashSet()); + } + + if (!uniqueIncludes.containsKey(fileElement)) { + uniqueIncludes.put(fileElement, new ArrayList()); + } + + parseVCppCompilerCLLine(line, currentProjectPath.toAbsolutePath().toString(), fileElement); + } catch (InvalidPathException ex) { + LOG.warn("Cannot extract information from current element: " + data + " : " + ex.getMessage()); + LOG.error("StackTrace: '{}'", ex); + } catch (NullPointerException ex2) { + LOG.error("Bug in parser, please report: '{}' - '{}'", ex2.getMessage(), data + " @ " + currentProjectPath); + LOG.error("StackTrace: '{}'", ex2); + } + } + private void parseVCppCompilerCLLine(String line, String projectPath, String fileElement) { for (String includeElem : getMatches(Pattern.compile("/I\"(.*?)\""), line)) { @@ -230,7 +242,7 @@ private void parseInclude(String element, String project, String fileElement) { if (!includesPerUnit.contains(includePath)) { includesPerUnit.add(includePath); } - } catch (java.io.IOException io) { + } catch (java.io.IOException io) { //NOSONAR LOG.error("Cannot parse include path using element '{}' : '{}'", element, io.getMessage()); } diff --git a/cxx-squid/src/main/java/org/sonar/cxx/channels/CharacterLiteralsChannel.java b/cxx-squid/src/main/java/org/sonar/cxx/channels/CharacterLiteralsChannel.java index fa705da2fd..4191d29ca6 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/channels/CharacterLiteralsChannel.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/channels/CharacterLiteralsChannel.java @@ -26,7 +26,7 @@ import com.sonar.sslr.api.Token; import com.sonar.sslr.impl.Lexer; -public class CharacterLiteralsChannel extends Channel { +public class CharacterLiteralsChannel extends Channel { //NOSONAR private static final char EOF = (char) -1; @@ -41,7 +41,7 @@ public boolean consume(CodeReader code, Lexer output) { int column = code.getColumnPosition(); index = 0; readPrefix(code); - if ((ch != '\'')) { + if (ch != '\'') { return false; } if (!read(code)) { diff --git a/cxx-squid/src/main/java/org/sonar/cxx/channels/StringLiteralsChannel.java b/cxx-squid/src/main/java/org/sonar/cxx/channels/StringLiteralsChannel.java index 073a954b70..e3a53934f9 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/channels/StringLiteralsChannel.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/channels/StringLiteralsChannel.java @@ -28,7 +28,7 @@ /** */ -public class StringLiteralsChannel extends Channel { +public class StringLiteralsChannel extends Channel { //NOSONAR private static final char EOF = (char) -1; 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 6e6eb75c29..ac6d8f084f 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,7 +36,7 @@ public final class CxxParser { - private static CxxPreprocessor cxxpp; + private static volatile CxxPreprocessor cxxpp = null; private CxxParser() { } 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 38632ddd4c..f9a630a08a 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 @@ -35,6 +35,8 @@ import java.util.Set; import java.util.StringJoiner; +import javax.annotation.Nullable; + import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; @@ -86,7 +88,7 @@ public class CxxPreprocessor extends Preprocessor { private final CxxLanguage language; //@todo: deprecated Preprocessor - private class State { + static private class State { public boolean skipPreprocessorDirectives; public boolean conditionWasTrue; @@ -121,7 +123,7 @@ static class MismatchException extends Exception { super(message, cause); } MismatchException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { - super(message, cause, enableSuppression, writableStackTrace);; + super(message, cause, enableSuppression, writableStackTrace); } } @@ -131,7 +133,7 @@ class Macro { public List body; public boolean isVariadic; - public Macro(String name, List params, List body, boolean variadic) { + public Macro(String name, @Nullable List params, @Nullable List body, boolean variadic) { this.name = name; this.params = params; this.body = body; @@ -270,7 +272,7 @@ public CxxPreprocessor(SquidAstVisitorContext context, Macro macro = parseMacroDefinition("#define " + define); if (macro != null) { LOG.debug("storing external macro: '{}'", macro); - getMacros().put(macro.name, macro); + getMacros().put(macro.name, macro); //NOSONAR } } } @@ -351,7 +353,7 @@ public PreprocessorAction process(List tokens) { //@todo: deprecated Prep Macro macro = parseMacroDefinition("#define " + define); if (macro != null) { LOG.debug("storing external macro to unit: '{}'", macro); - getMacros().put(macro.name, macro); + getMacros().put(macro.name, macro); //NOSONAR } } } @@ -397,27 +399,28 @@ public PreprocessorAction process(List tokens) { //@todo: deprecated Prep } } - if (ttype == PREPROCESSOR) { + if (ttype.equals(PREPROCESSOR)) { AstNode lineAst; try { lineAst = pplineParser.parse(token.getValue()).getFirstChild(); } catch (com.sonar.sslr.api.RecognitionException re) { LOG.warn("Cannot parse '{}', ignoring...", token.getValue()); + LOG.debug("Parser exception: '{}'", re); return new PreprocessorAction(1, Collections.singletonList(Trivia.createSkippedText(token)), new ArrayList()); //@todo: deprecated PreprocessorAction } AstNodeType lineKind = lineAst.getType(); - if (lineKind == ifdefLine) { + if (lineKind.equals(ifdefLine)) { return handleIfdefLine(lineAst, token, filePath); - } else if (lineKind == ifLine) { + } else if (lineKind.equals(ifLine)) { return handleIfLine(lineAst, token, filePath); - } else if (lineKind == endifLine) { - return handleEndifLine(lineAst, token, filePath); - } else if (lineKind == elseLine) { - return handleElseLine(lineAst, token, filePath); - } else if (lineKind == elifLine) { + } else if (lineKind.equals(endifLine)) { + return handleEndifLine(token, filePath); + } else if (lineKind.equals(elseLine)) { + return handleElseLine(token, filePath); + } else if (lineKind.equals(elifLine)) { return handleElIfLine(lineAst, token, filePath); } @@ -425,12 +428,12 @@ public PreprocessorAction process(List tokens) { //@todo: deprecated Prep return new PreprocessorAction(1, Collections.singletonList(Trivia.createSkippedText(token)), new ArrayList()); //@todo: deprecated PreprocessorAction } - if (lineKind == defineLine) { + if (lineKind.equals(defineLine)) { return handleDefineLine(lineAst, token, filePath); - } else if (lineKind == includeLine) { + } else if (lineKind.equals(includeLine)) { return handleIncludeLine(lineAst, token, filePath, conf.getCharset()); - } else if (lineKind == undefLine) { - return handleUndefLine(lineAst, token, filePath); + } else if (lineKind.equals(undefLine)) { + return handleUndefLine(lineAst, token); } // Ignore all other preprocessor directives (which are not handled explicitly) @@ -438,12 +441,12 @@ public PreprocessorAction process(List tokens) { //@todo: deprecated Prep return new PreprocessorAction(1, Collections.singletonList(Trivia.createSkippedText(token)), new ArrayList()); //@todo: deprecated PreprocessorAction } - if (ttype != EOF) { + if (!ttype.equals(EOF)) { if (currentFileState.skipPreprocessorDirectives) { return new PreprocessorAction(1, Collections.singletonList(Trivia.createSkippedText(token)), new ArrayList()); //@todo: deprecated PreprocessorAction } - if (ttype != STRING && ttype != NUMBER) { + if (!ttype.equals(STRING) && !ttype.equals(NUMBER)) { return handleIdentifiersAndKeywords(tokens, token, filePath); } } @@ -472,11 +475,11 @@ public SourceCodeProvider getCodeProvider() { return unitCodeProvider != null ? unitCodeProvider : codeProvider; } - public MapChain getMacros() { + public final MapChain getMacros() { return unitMacros != null ? unitMacros : fixedMacros; } - public Macro getMacro(String macroname) { + public final Macro getMacro(String macroname) { return getMacros().get(macroname); } @@ -562,7 +565,7 @@ private PreprocessorAction handleIfdefLine(AstNode ast, Token token, String file if (!currentFileState.skipPreprocessorDirectives) { Macro macro = getMacro(getMacroName(ast)); TokenType tokType = ast.getToken().getType(); - if ((tokType == IFDEF && macro == null) || (tokType == IFNDEF && macro != null)) { + if ((tokType.equals(IFDEF) && macro == null) || (tokType.equals(IFNDEF) && macro != null)) { if (LOG.isTraceEnabled()) { LOG.trace("[{}:{}]: '{}' evaluated to false, skipping tokens that follow", new Object[]{filename, token.getLine(), token.getValue()}); @@ -579,7 +582,7 @@ private PreprocessorAction handleIfdefLine(AstNode ast, Token token, String file return new PreprocessorAction(1, Collections.singletonList(Trivia.createSkippedText(token)), new ArrayList()); //@todo: deprecated PreprocessorAction } - PreprocessorAction handleElseLine(AstNode ast, Token token, String filename) { //@todo: deprecated PreprocessorAction + PreprocessorAction handleElseLine(Token token, String filename) { //@todo: deprecated PreprocessorAction if (currentFileState.conditionalInclusionCounter == 0) { if (currentFileState.skipPreprocessorDirectives && !currentFileState.conditionWasTrue) { if (LOG.isTraceEnabled()) { @@ -598,7 +601,7 @@ PreprocessorAction handleElseLine(AstNode ast, Token token, String filename) { / return new PreprocessorAction(1, Collections.singletonList(Trivia.createSkippedText(token)), new ArrayList()); //@todo: deprecated PreprocessorAction } - PreprocessorAction handleEndifLine(AstNode ast, Token token, String filename) { //@todo: deprecated PreprocessorAction + PreprocessorAction handleEndifLine(Token token, String filename) { //@todo: deprecated PreprocessorAction if (currentFileState.conditionalInclusionCounter > 0) { currentFileState.conditionalInclusionCounter--; } else { @@ -670,7 +673,7 @@ PreprocessorAction handleIncludeLine(AstNode ast, Token token, String filename, try { IncludeLexer.create(this.language, this).lex(getCodeProvider().getSourceCode(includedFile, charset)); } catch (IOException ex) { - LOG.error("[{}: Cannot read file]: {}", includedFile.getAbsoluteFile(), ex.getMessage()); + LOG.error("[{}: Cannot read file]: {}", includedFile.getAbsoluteFile(), ex); } finally { currentFileState = globalStateStack.pop(); } @@ -682,7 +685,7 @@ PreprocessorAction handleIncludeLine(AstNode ast, Token token, String filename, return new PreprocessorAction(1, Collections.singletonList(Trivia.createSkippedText(token)), new ArrayList()); //@todo: deprecated PreprocessorAction } - PreprocessorAction handleUndefLine(AstNode ast, Token token, String filename) { //@todo: deprecated PreprocessorAction + PreprocessorAction handleUndefLine(AstNode ast, Token token) { //@todo: deprecated PreprocessorAction String macroName = ast.getFirstDescendant(IDENTIFIER).getTokenValue(); getMacros().removeLowPrio(macroName); return new PreprocessorAction(1, Collections.singletonList(Trivia.createSkippedText(token)), new ArrayList()); //@todo: deprecated PreprocessorAction @@ -721,12 +724,12 @@ PreprocessorAction handleIdentifiersAndKeywords(List tokens, Token curr, while (!replTokens.isEmpty()) { Token c = replTokens.get(0); PreprocessorAction action = PreprocessorAction.NO_OPERATION; //@todo: deprecated PreprocessorAction - if (c.getType() == IDENTIFIER) { + if (c.getType().equals(IDENTIFIER)) { List rest = new ArrayList(replTokens); rest.addAll(tokens.subList(tokensConsumed, tokens.size())); action = handleIdentifiersAndKeywords(rest, c, filename); } - if (action == PreprocessorAction.NO_OPERATION) { //@todo: deprecated PreprocessorAction + if (action.equals(PreprocessorAction.NO_OPERATION)) { //@todo: deprecated PreprocessorAction replTokens.remove(0); outTokens.add(c); } else { @@ -809,7 +812,7 @@ private List expandMacro(String macroName, String macroExpression) { } private List stripEOF(List tokens) { - if (tokens.get(tokens.size() - 1).getType() == EOF) { + if (tokens.get(tokens.size() - 1).getType().equals(EOF)) { return tokens.subList(0, tokens.size() - 1); } else { return tokens; @@ -832,23 +835,23 @@ private int matchArguments(List tokens, List arguments) { List rest = tokens; try { rest = match(rest, "("); - } catch (MismatchException me) { + } catch (MismatchException me) { //NOSONAR return 0; } try { do { rest = matchArgument(rest, arguments); - try { + try { //NOSONAR rest = match(rest, ","); - } catch (MismatchException me) { + } catch (MismatchException me) { //NOSONAR break; } } while (true); - } catch (MismatchException me) {} + } catch (MismatchException me) {} //NOSONAR try { rest = match(rest, ")"); - } catch (MismatchException me) { + } catch (MismatchException me) { //NOSONAR LOG.error("MismatchException : '{}' rest: '{}'", me.getMessage(), rest); return 0; } @@ -922,7 +925,7 @@ private List replaceParams(List body, List parameters, List Token curr = body.get(i); int index = defParamValues.indexOf(curr.getValue()); if (index == -1) { - if (tokenPastingRightOp && curr.getType() != WS && curr.getType() != HASHHASH) { + if (tokenPastingRightOp && !curr.getType().equals(WS) && !curr.getType().equals(HASHHASH)) { tokenPastingRightOp = false; } newTokens.add(curr); @@ -931,14 +934,14 @@ private List replaceParams(List body, List parameters, List // If variable argument is left out then the comma before the paste // operator will be deleted int j = i; - while (j > 0 && body.get(j - 1).getType() == WS) { + while (j > 0 && body.get(j - 1).getType().equals(WS)) { j--; } if (j == 0 || !"##".equals(body.get(--j).getValue())) { continue; } int k = j; - while (j > 0 && body.get(j - 1).getType() == WS) { + while (j > 0 && body.get(j - 1).getType().equals(WS)) { j--; } if (j > 0 && ",".equals(body.get(j - 1).getValue())) { @@ -949,7 +952,7 @@ private List replaceParams(List body, List parameters, List } else if (index < arguments.size()) { // token pasting operator? int j = i + 1; - while (j < body.size() && body.get(j).getType() == WS) { + while (j < body.size() && body.get(j).getType().equals(WS)) { j++; } if (j < body.size() && "##".equals(body.get(j).getValue())) { @@ -983,9 +986,9 @@ private List replaceParams(List body, List parameters, List // 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() == WS) { + if (newTokens.get(n).getType().equals(WS)) { newTokens.remove(n); - } else if (newTokens.get(n).getType() == COMMA) { + } else if (newTokens.get(n).getType().equals(COMMA)) { newTokens.remove(n); break; } else { @@ -1002,11 +1005,11 @@ private List replaceParams(List body, List parameters, List } // replace # with "" if sequence HASH BR occurs for body HASH __VA_ARGS__ - if (newTokens.size() > 3 && newTokens.get(newTokens.size() - 2).getType() == HASH && newTokens.get(newTokens.size() - 1).getType() == BR_RIGHT) { + 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() == WS) { + if (newTokens.get(n).getType().equals(WS)) { newTokens.remove(n); - } else if (newTokens.get(n).getType() == HASH) { + } 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) @@ -1018,11 +1021,11 @@ private List replaceParams(List body, List parameters, List } } // drop COMMA from sequence COMMA "," BR ")" - if (newTokens.size() > 2 && newTokens.get(newTokens.size() - 1).getType() == BR_RIGHT) { + if (newTokens.size() > 2 && newTokens.get(newTokens.size() - 1).getType().equals(BR_RIGHT)) { for (int n = newTokens.size() - 2; n != 0; n--) { - if (newTokens.get(n).getType() == WS) { + if (newTokens.get(n).getType().equals(WS)) { newTokens.remove(n); - } else if (newTokens.get(n).getType() == COMMA) { + } else if (newTokens.get(n).getType().equals(COMMA)) { newTokens.remove(n); break; } else { @@ -1039,9 +1042,10 @@ private List evaluateHashhashOperators(List tokens) { Iterator it = tokens.iterator(); while (it.hasNext()) { Token curr = it.next(); - if (curr.getValue() == "##") { + if ("##".equals(curr.getValue())) { Token pred = predConcatToken(newTokens); Token succ = succConcatToken(it); + try { newTokens.add(Token.builder() .setLine(pred.getLine()) .setColumn(pred.getColumn()) @@ -1050,6 +1054,9 @@ private List evaluateHashhashOperators(List tokens) { .setType(pred.getType()) .setGeneratedCode(true) .build()); + } catch (NullPointerException ex) { + LOG.error ("Missing data : '{}'", ex); + } } else { newTokens.add(curr); } @@ -1061,10 +1068,10 @@ private List evaluateHashhashOperators(List tokens) { private Token predConcatToken(List tokens) { while (!tokens.isEmpty()) { Token last = tokens.remove(tokens.size() - 1); - if (last.getType() != WS) { + if (!last.getType().equals(WS)) { if (!tokens.isEmpty()) { Token pred = tokens.get(tokens.size() - 1); - if (pred.getType() != WS && !pred.hasTrivia()) { + 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(); @@ -1088,7 +1095,7 @@ private Token succConcatToken(Iterator it) { Token succ = null; while (it.hasNext()) { succ = it.next(); - if (!"##".equals(succ.getValue()) && succ.getType() != WS) { + if (!"##".equals(succ.getValue()) && !succ.getType().equals(WS)) { break; } } @@ -1173,8 +1180,7 @@ private Macro parseMacroDefinition(AstNode defineLineAst) { AstNode paramList = ast.getFirstDescendant(CppGrammar.parameterList); List macroParams = paramList == null - ? "objectlikeMacroDefinition".equals(ast.getName()) ? null : new LinkedList() - : getParams(paramList); + ? "objectlikeMacroDefinition".equals(ast.getName()) ? null : new LinkedList<>() : getParams(paramList); AstNode vaargs = ast.getFirstDescendant(CppGrammar.variadicparameter); if (vaargs != null) { @@ -1193,8 +1199,7 @@ private Macro parseMacroDefinition(AstNode defineLineAst) { AstNode replList = ast.getFirstDescendant(CppGrammar.replacementList); List macroBody = replList == null - ? new LinkedList() - : replList.getTokens().subList(0, replList.getTokens().size() - 1); + ? new LinkedList<>() : replList.getTokens().subList(0, replList.getTokens().size() - 1); return new Macro(macroName, macroParams, macroBody, vaargs != null); } @@ -1244,7 +1249,7 @@ private File findIncludedFile(AstNode ast, Token token, String currFileName) { AstNode includeBodyAst = null; try { includeBodyAst = pplineParser.parse("#include " + expandedIncludeBody); - } catch (com.sonar.sslr.api.RecognitionException re) { + } catch (com.sonar.sslr.api.RecognitionException re) { //NOSONAR parseError = true; } 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 e5d9ba0f39..96dfda4195 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 @@ -61,7 +61,7 @@ private BigInteger evalToInt(String constExpr, AstNode exprAst) { AstNode constExprAst = null; try { constExprAst = parser.parse(constExpr); - } catch (com.sonar.sslr.api.RecognitionException re) { + } catch (com.sonar.sslr.api.RecognitionException re) { //NOSONAR if (exprAst != null) { LOG.warn("Error evaluating expression '{}' for AstExp '{}', assuming 0", constExpr, exprAst.getToken()); } else { @@ -92,11 +92,11 @@ private BigInteger evalLeaf(AstNode exprAst) { // AstNodeType nodeType = exprAst.getType(); - if (CxxTokenType.NUMBER == nodeType) { + if (nodeType.equals(CxxTokenType.NUMBER)) { return evalNumber(exprAst.getTokenValue()); - } else if (CxxTokenType.CHARACTER == nodeType) { + } else if (nodeType.equals(CxxTokenType.CHARACTER)) { return evalCharacter(exprAst.getTokenValue()); - } else if (GenericTokenType.IDENTIFIER == nodeType) { + } else if (nodeType.equals(GenericTokenType.IDENTIFIER)) { String value = preprocessor.valueOf(exprAst.getTokenValue()); return value == null ? BigInteger.ZERO : evalToInt(value, exprAst); } else { @@ -108,7 +108,7 @@ private BigInteger evalOneChildAst(AstNode exprAst) { // Evaluation of booleans and 'pass-through's // AstNodeType nodeType = exprAst.getType(); - if (CppGrammar.bool == nodeType) { + if (nodeType.equals(CppGrammar.bool)) { return evalBool(exprAst.getTokenValue()); } return evalToInt(exprAst.getFirstChild()); @@ -119,35 +119,35 @@ private BigInteger evalComplexAst(AstNode exprAst) { // More complex expressions with more than one child // AstNodeType nodeType = exprAst.getType(); - if (CppGrammar.unaryExpression == nodeType) { + if (nodeType.equals(CppGrammar.unaryExpression)) { return evalUnaryExpression(exprAst); - } else if (CppGrammar.conditionalExpression == nodeType) { + } else if (nodeType.equals(CppGrammar.conditionalExpression)) { return evalConditionalExpression(exprAst); - } else if (CppGrammar.logicalOrExpression == nodeType) { + } else if (nodeType.equals(CppGrammar.logicalOrExpression)) { return evalLogicalOrExpression(exprAst); - } else if (CppGrammar.logicalAndExpression == nodeType) { + } else if (nodeType.equals(CppGrammar.logicalAndExpression)) { return evalLogicalAndExpression(exprAst); - } else if (CppGrammar.inclusiveOrExpression == nodeType) { + } else if (nodeType.equals(CppGrammar.inclusiveOrExpression)) { return evalInclusiveOrExpression(exprAst); - } else if (CppGrammar.exclusiveOrExpression == nodeType) { + } else if (nodeType.equals(CppGrammar.exclusiveOrExpression)) { return evalExclusiveOrExpression(exprAst); - } else if (CppGrammar.andExpression == nodeType) { + } else if (nodeType.equals(CppGrammar.andExpression)) { return evalAndExpression(exprAst); - } else if (CppGrammar.equalityExpression == nodeType) { + } else if (nodeType.equals(CppGrammar.equalityExpression)) { return evalEqualityExpression(exprAst); - } else if (CppGrammar.relationalExpression == nodeType) { + } else if (nodeType.equals(CppGrammar.relationalExpression)) { return evalRelationalExpression(exprAst); - } else if (CppGrammar.shiftExpression == nodeType) { + } else if (nodeType.equals(CppGrammar.shiftExpression)) { return evalShiftExpression(exprAst); - } else if (CppGrammar.additiveExpression == nodeType) { + } else if (nodeType.equals(CppGrammar.additiveExpression)) { return evalAdditiveExpression(exprAst); - } else if (CppGrammar.multiplicativeExpression == nodeType) { + } else if (nodeType.equals(CppGrammar.multiplicativeExpression)) { return evalMultiplicativeExpression(exprAst); - } else if (CppGrammar.primaryExpression == nodeType) { + } else if (nodeType.equals(CppGrammar.primaryExpression)) { return evalPrimaryExpression(exprAst); - } else if (CppGrammar.definedExpression == nodeType) { + } else if (nodeType.equals(CppGrammar.definedExpression)) { return evalDefinedExpression(exprAst); - } else if (CppGrammar.functionlikeMacro == nodeType) { + } else if (nodeType.equals(CppGrammar.functionlikeMacro)) { return evalFunctionlikeMacro(exprAst); } else { LOG.error("'evalComplexAst' Unknown expression type '" + nodeType + "' for AstExt '" + exprAst.getToken() + "', assuming 0"); @@ -194,6 +194,7 @@ private BigInteger evalLogicalOrExpression(AstNode exprAst) { boolean result = eval(operand); while ((result != true) && ((operand = getNextOperand(operand)) != null)) { + // Todo fix this statement - it is always false ?!? result = result || eval(operand); } @@ -205,6 +206,7 @@ private BigInteger evalLogicalAndExpression(AstNode exprAst) { boolean result = eval(operand); while ((result != false) && ((operand = getNextOperand(operand)) != null)) { + // Todo fix this statement - it is always false ?!? result = result && eval(operand); } @@ -218,23 +220,23 @@ private BigInteger evalEqualityExpression(AstNode exprAst) { AstNodeType operatorType = operator.getType(); boolean result; - if (CppPunctuator.EQ == operatorType) { + if (operatorType.equals(CppPunctuator.EQ)) { result = evalToInt(lhs).compareTo(evalToInt(rhs)) == 0; - } else if (CppPunctuator.NOT_EQ == operatorType) { + } else if (operatorType.equals(CppPunctuator.NOT_EQ)) { result = evalToInt(lhs).compareTo(evalToInt(rhs)) != 0; } else { - throw new EvaluationException("Unknown equality operator '" + operatorType.toString() + "'"); + throw new EvaluationException("Unknown equality operator '" + operatorType + "'"); } while ((operator = rhs.getNextSibling()) != null) { operatorType = operator.getType(); rhs = operator.getNextSibling(); - if (CppPunctuator.EQ == operatorType) { + if (operatorType.equals(CppPunctuator.EQ)) { result = result == eval(rhs); - } else if (CppPunctuator.NOT_EQ == operatorType) { + } else if (operatorType.equals(CppPunctuator.NOT_EQ)) { result = result != eval(rhs); } else { - throw new EvaluationException("Unknown equality operator '" + operatorType.toString() + "'"); + throw new EvaluationException("Unknown equality operator '" + operatorType + "'"); } } @@ -248,16 +250,16 @@ private BigInteger evalRelationalExpression(AstNode exprAst) { AstNodeType operatorType = operator.getType(); boolean result; - if (CppPunctuator.LT == operatorType) { + if (operatorType.equals(CppPunctuator.LT)) { result = evalToInt(lhs).compareTo(evalToInt(rhs)) < 0; - } else if (CppPunctuator.GT == operatorType) { + } else if (operatorType.equals(CppPunctuator.GT)) { result = evalToInt(lhs).compareTo(evalToInt(rhs)) > 0; - } else if (CppPunctuator.LT_EQ == operatorType) { + } else if (operatorType.equals(CppPunctuator.LT_EQ)) { result = evalToInt(lhs).compareTo(evalToInt(rhs)) <= 0; - } else if (CppPunctuator.GT_EQ == operatorType) { + } else if (operatorType.equals(CppPunctuator.GT_EQ)) { result = evalToInt(lhs).compareTo(evalToInt(rhs)) >= 0; } else { - throw new EvaluationException("Unknown relational operator '" + operatorType.toString() + "'"); + throw new EvaluationException("Unknown relational operator '" + operatorType + "'"); } BigInteger resultAsInt; @@ -266,13 +268,13 @@ private BigInteger evalRelationalExpression(AstNode exprAst) { rhs = operator.getNextSibling(); resultAsInt = result ? BigInteger.ONE : BigInteger.ZERO; - if (CppPunctuator.LT == operatorType) { + if (operatorType.equals(CppPunctuator.LT)) { result = resultAsInt.compareTo(evalToInt(rhs)) < 0; - } else if (CppPunctuator.GT == operatorType) { + } else if (operatorType.equals(CppPunctuator.GT)) { result = resultAsInt.compareTo(evalToInt(rhs)) > 0; - } else if (CppPunctuator.LT_EQ == operatorType) { + } else if (operatorType.equals(CppPunctuator.LT_EQ)) { result = resultAsInt.compareTo(evalToInt(rhs)) <= 0; - } else if (CppPunctuator.GT_EQ == operatorType) { + } else if (operatorType.equals(CppPunctuator.GT_EQ)) { result = resultAsInt.compareTo(evalToInt(rhs)) >= 0; } else { throw new EvaluationException("Unknown relational operator '" + operatorType + "'"); @@ -324,14 +326,14 @@ private BigInteger evalUnaryExpression(AstNode exprAst) { AstNode operand = operator.getNextSibling(); AstNodeType operatorType = operator.getFirstChild().getType(); - if (CppPunctuator.PLUS == operatorType) { + if (operatorType.equals(CppPunctuator.PLUS)) { return evalToInt(operand); - } else if (CppPunctuator.MINUS == operatorType) { + } else if (operatorType.equals(CppPunctuator.MINUS)) { return evalToInt(operand).negate(); - } else if (CppPunctuator.NOT == operatorType) { + } else if (operatorType.equals(CppPunctuator.NOT)) { boolean result = !eval(operand); return result ? BigInteger.ONE : BigInteger.ZERO; - } else if (CppPunctuator.BW_NOT == operatorType) { + } else if (operatorType.equals(CppPunctuator.BW_NOT)) { //todo: need more information (signed/unsigned, data type length) to invert bits in all cases correct return evalToInt(operand).not().and(UINT64_MAX); } else { @@ -348,9 +350,9 @@ private BigInteger evalShiftExpression(AstNode exprAst) { AstNodeType operatorType = operator.getType(); rhs = operator.getNextSibling(); - if (CppPunctuator.BW_LSHIFT == operatorType) { + if (operatorType.equals(CppPunctuator.BW_LSHIFT)) { result = result.shiftLeft(evalToInt(rhs).intValue()).and(UINT64_MAX); - } else if (CppPunctuator.BW_RSHIFT == operatorType) { + } else if (operatorType.equals(CppPunctuator.BW_RSHIFT)) { result = result.shiftRight(evalToInt(rhs).intValue()); } else { throw new EvaluationException("Unknown shift operator '" + operatorType + "'"); @@ -369,9 +371,9 @@ private BigInteger evalAdditiveExpression(AstNode exprAst) { AstNodeType operatorType = operator.getType(); rhs = operator.getNextSibling(); - if (CppPunctuator.PLUS == operatorType) { + if (operatorType.equals(CppPunctuator.PLUS)) { result = result.add(evalToInt(rhs)); - } else if (CppPunctuator.MINUS == operatorType) { + } else if (operatorType.equals(CppPunctuator.MINUS)) { result = result.subtract(evalToInt(rhs)); } else { throw new EvaluationException("Unknown additive operator '" + operatorType + "'"); @@ -390,11 +392,11 @@ private BigInteger evalMultiplicativeExpression(AstNode exprAst) { AstNodeType operatorType = operator.getType(); rhs = operator.getNextSibling(); - if (CppPunctuator.MUL == operatorType) { + if (operatorType.equals(CppPunctuator.MUL)) { result = result.multiply(evalToInt(rhs)); - } else if (CppPunctuator.DIV == operatorType) { + } else if (operatorType.equals(CppPunctuator.DIV)) { result = result.divide(evalToInt(rhs)); - } else if (CppPunctuator.MODULO == operatorType) { + } else if (operatorType.equals(CppPunctuator.MODULO)) { result = result.mod(evalToInt(rhs)); } else { throw new EvaluationException("Unknown multiplicative operator '" + operatorType + "'"); 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 b9e2532aaf..259bc89c42 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 @@ -35,7 +35,7 @@ public class JoinStringsPreprocessor extends Preprocessor { //@todo deprecated P public PreprocessorAction process(List tokens) { //@todo deprecated PreprocessorAction Token token = tokens.get(0); - if (token.getType() == CxxTokenType.STRING) { + if (token.getType().equals(CxxTokenType.STRING)) { // Joining string literals (C++ Standard, "2.2 Phases of translation, Phase 6") StringBuilder newStr = null; @@ -43,15 +43,15 @@ public PreprocessorAction process(List tokens) { //@todo deprecated Prepr for (;;) { Token nextToken = tokens.get(numberOfStrings); - if (nextToken.getType() != CxxTokenType.STRING) { + if (!nextToken.getType().equals(CxxTokenType.STRING)) { if (newStr != null) { - newStr.append("\""); + newStr.append('\"'); } break; } if (newStr == null) { newStr = new StringBuilder(); - newStr.append("\""); + newStr.append('\"'); newStr.append(stripQuotes(token.getValue())); } newStr.append(stripQuotes(nextToken.getValue())); diff --git a/cxx-squid/src/main/java/org/sonar/cxx/preprocessor/MapChain.java b/cxx-squid/src/main/java/org/sonar/cxx/preprocessor/MapChain.java index 2a8fd91ba3..c6a61e0a68 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/preprocessor/MapChain.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/preprocessor/MapChain.java @@ -22,7 +22,7 @@ import java.util.HashMap; import java.util.Map; -public class MapChain { +public class MapChain { //NOSONAR private final Map highPrioMap = new HashMap<>(); private final Map lowPrioMap = new HashMap<>(); 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 e593b503e7..4a7f71e9b6 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 @@ -94,7 +94,7 @@ abstract protected void onPublicApi(AstNode node, String id, public interface PublicApiHandler { void onPublicApi(AstNode node, String id, List comments); - }; + } private List headerFileSuffixes; @@ -239,14 +239,14 @@ private boolean isTypedef(AstNode declaratorList) { AstNode simpleDeclSpezifierSeq = declaratorList.getPreviousSibling(); if (simpleDeclSpezifierSeq != null) { AstNode firstDeclSpecifier = simpleDeclSpezifierSeq.getFirstChild(CxxGrammarImpl.declSpecifier); - if (firstDeclSpecifier != null && firstDeclSpecifier.getToken().getType() == CxxKeyword.TYPEDEF) { + if (firstDeclSpecifier != null && firstDeclSpecifier.getToken().getType().equals(CxxKeyword.TYPEDEF)) { AstNode classSpefifier = firstDeclSpecifier.getNextSibling(); if (classSpefifier != null) { TokenType type = classSpefifier.getToken().getType(); - if (type == CxxKeyword.STRUCT - || type == CxxKeyword.CLASS - || type == CxxKeyword.UNION - || type == CxxKeyword.ENUM) { + if (type.equals(CxxKeyword.STRUCT) + || type.equals(CxxKeyword.CLASS) + || type.equals(CxxKeyword.UNION) + || type.equals(CxxKeyword.ENUM)) { return true; } } @@ -352,7 +352,7 @@ private AstNode getTypedefNode(AstNode classSpecifier) { declSpecifier = declSpecifier.getPreviousSibling(); if (declSpecifier != null) { AstNode typedef = declSpecifier.getFirstChild(); - if (typedef != null && typedef.getToken().getType() == CxxKeyword.TYPEDEF) { + if (typedef != null && typedef.getToken().getType().equals(CxxKeyword.TYPEDEF)) { return typedef; } } @@ -517,11 +517,9 @@ private void visitFunctionDefinition(AstNode functionDef) { AstNode functionBodyNode = functionDef .getFirstChild(CxxGrammarImpl.functionBody); - if (functionBodyNode != null) { - if (isDefaultOrDeleteFunctionBody(functionBodyNode)) { - return; - } - } + if ((functionBodyNode != null) && (isDefaultOrDeleteFunctionBody(functionBodyNode))){ + return; + } visitMemberDeclarator(functionDef); } @@ -532,19 +530,17 @@ private boolean isDefaultOrDeleteFunctionBody(AstNode functionBodyNode) { List functionBody = functionBodyNode.getChildren(); // look for exact sub AST - if (functionBody.size() == 3) { - if (functionBody.get(0).is(CxxPunctuator.ASSIGN) + if ((functionBody.size() == 3) + && functionBody.get(0).is(CxxPunctuator.ASSIGN) && functionBody.get(2).is(CxxPunctuator.SEMICOLON)) { - AstNode bodyType = functionBody.get(1); + AstNode bodyType = functionBody.get(1); - if (bodyType.is(CxxKeyword.DELETE) - || bodyType.is(CxxKeyword.DEFAULT)) { - defaultOrDelete = true; - } + if (bodyType.is(CxxKeyword.DELETE) + || bodyType.is(CxxKeyword.DEFAULT)) { + defaultOrDelete = true; } } - return defaultOrDelete; } @@ -583,7 +579,7 @@ private void visitMemberDeclarator(AstNode node) { AstNode docNode = node; List comments; - if (container == null || container.getType() == CxxGrammarImpl.classSpecifier) { + if (container == null || container.getType().equals(CxxGrammarImpl.classSpecifier)) { comments = getBlockDocumentation(docNode); } else { // template do { @@ -602,10 +598,9 @@ private void visitMemberDeclarator(AstNode node) { // find the identifier to present to concrete visitors String id = null; - AstNode idNode = null; // first look for an operator function id - idNode = node.getFirstDescendant(CxxGrammarImpl.operatorFunctionId); + AstNode idNode = node.getFirstDescendant(CxxGrammarImpl.operatorFunctionId); if (idNode != null) { id = getOperatorId(idNode); @@ -638,7 +633,7 @@ private void visitAliasDeclaration(AstNode aliasDeclNode) { CxxGrammarImpl.classSpecifier); // An alias declaration inside a function is not part of the public API - if (parent != null && parent.getType() == CxxGrammarImpl.functionDefinition) { + if (parent != null && parent.getType().equals(CxxGrammarImpl.functionDefinition)) { return; } @@ -659,7 +654,7 @@ private void visitAliasDeclaration(AstNode aliasDeclNode) { AstNode docNode; if (container == null - || container.getType() == CxxGrammarImpl.classSpecifier) { + || container.getType().equals(CxxGrammarImpl.classSpecifier)) { docNode = aliasDeclNode; } else { docNode = container; @@ -720,7 +715,7 @@ private void visitEnumSpecifier(AstNode enumSpecifierNode) { // or next curly brace if (next != null) { // discard COMMA - if (next.getToken().getType() == CxxPunctuator.COMMA) { + if (next.getToken().getType().equals( CxxPunctuator.COMMA)) { next = next.getNextAstNode(); } @@ -770,8 +765,8 @@ private static List getDeclaratorInlineComment(AstNode declarator) { // or next curly brace if (next != null) { // discard COMMA and SEMICOLON - if (next.getToken().getType() == CxxPunctuator.COMMA - || next.getToken().getType() == CxxPunctuator.SEMICOLON) { + if (next.getToken().getType().equals(CxxPunctuator.COMMA) + || next.getToken().getType().equals(CxxPunctuator.SEMICOLON)) { next = next.getNextAstNode(); } @@ -792,11 +787,11 @@ private static boolean isPublicApiMember(AstNode node) { do { access = access.getPreviousAstNode(); } while (access != null - && access.getType() != CxxGrammarImpl.accessSpecifier); + && !access.getType().equals(CxxGrammarImpl.accessSpecifier)); if (access != null) { - return access.getToken().getType() == CxxKeyword.PUBLIC - || access.getToken().getType() == CxxKeyword.PROTECTED; + return access.getToken().getType().equals(CxxKeyword.PUBLIC) + || access.getToken().getType().equals( CxxKeyword.PROTECTED); } else { AstNode classSpecifier = node .getFirstAncestor(CxxGrammarImpl.classSpecifier); @@ -809,12 +804,12 @@ private static boolean isPublicApiMember(AstNode node) { if (enclosingSpecifierNode != null) { TokenType type = enclosingSpecifierNode.getToken().getType(); - if (type == CxxKeyword.STRUCT || type == CxxKeyword.UNION) { + 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 == CxxKeyword.CLASS) { + } else if (type.equals(CxxKeyword.CLASS)) { // default access in classes is private return false; @@ -847,15 +842,13 @@ private static List getInlineDocumentation(Token token, int line) { for (Trivia trivia : token.getTrivia()) { if (trivia.isComment()) { Token triviaToken = trivia.getToken(); - if (triviaToken != null) { - if (triviaToken.getLine() == line) { - if (isDoxygenInlineComment(triviaToken.getValue())) { + if ((triviaToken != null) + && (triviaToken.getLine() == line) + && (isDoxygenInlineComment(triviaToken.getValue()))) { comments.add(triviaToken); LOG.trace("Inline doc: " + triviaToken.getValue()); } } - } - } } return comments; } diff --git a/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxCommentLinesVisitor.java b/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxCommentLinesVisitor.java index 52ac44eacc..69154f277a 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxCommentLinesVisitor.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxCommentLinesVisitor.java @@ -33,7 +33,7 @@ import com.sonar.sslr.api.Token; import com.sonar.sslr.api.Trivia; -public class CxxCommentLinesVisitor extends SquidAstVisitor implements AstAndTokenVisitor { +public class CxxCommentLinesVisitor extends SquidAstVisitor implements AstAndTokenVisitor { //NOSONAR private final Set comments = new HashSet<>(); private boolean seenFirstToken; 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 0432828612..bd70ed08ec 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 @@ -33,7 +33,8 @@ * Visitor that computes the number of lines of code of a file. * @param */ -public class CxxLinesOfCodeVisitor extends SquidAstVisitor implements AstAndTokenVisitor { +public class CxxLinesOfCodeVisitor + extends SquidAstVisitor implements AstAndTokenVisitor { private final MetricDef metric; private int lastTokenLine; @@ -55,12 +56,12 @@ public void visitFile(AstNode node) { */ @Override public void visitToken(Token token) { - if (token.getType() != EOF) { + if (!token.getType().equals(EOF)) { /* Handle all the lines of the token */ String[] tokenLines = token.getValue().split("\n", -1); int firstLineAlreadyCounted = lastTokenLine == token.getLine() ? 1 : 0; - getContext().peekSourceCode().add(metric, tokenLines.length - firstLineAlreadyCounted); + getContext().peekSourceCode().add(metric, (double) tokenLines.length - firstLineAlreadyCounted); lastTokenLine = token.getLine() + tokenLines.length - 1; } 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 3a0c571abe..6785cb1446 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 @@ -32,7 +32,8 @@ import java.util.List; import org.sonar.cxx.api.CxxPunctuator; -public class CxxParseErrorLoggerVisitor extends SquidAstVisitor implements AstAndTokenVisitor { +public class CxxParseErrorLoggerVisitor + extends SquidAstVisitor implements AstAndTokenVisitor { private final SquidAstVisitorContext context; @@ -55,11 +56,11 @@ public void visitNode(AstNode node) { sb.append(child.getTokenValue()); TokenType type = child.getToken().getType(); - if (type == GenericTokenType.IDENTIFIER) { + if (type.equals(GenericTokenType.IDENTIFIER)) { // save position of last identifier for message identifierLine = child.getTokenLine(); sb.append(' '); - } else if (type == CxxPunctuator.CURLBR_LEFT) { + } else if (type.equals(CxxPunctuator.CURLBR_LEFT)) { // part with CURLBR_LEFT is typically an ignored declaration if (identifierLine != -1) { CxxGrammarImpl.LOG.warn("[{}:{}]: skip declarartion: {}", @@ -67,7 +68,7 @@ public void visitNode(AstNode node) { sb.setLength(0); identifierLine = -1; } - } else if (type == CxxPunctuator.CURLBR_RIGHT) { + } else if (type.equals(CxxPunctuator.CURLBR_RIGHT)) { sb.setLength(0); identifierLine = -1; } else { diff --git a/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxPublicApiVisitor.java b/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxPublicApiVisitor.java index 0adb76f222..cb3aa021ed 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxPublicApiVisitor.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/visitors/CxxPublicApiVisitor.java @@ -73,7 +73,7 @@ public class CxxPublicApiVisitor extends public interface PublicApiHandler { void onPublicApi(AstNode node, String id, List comments); - }; + } private PublicApiHandler handler; 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 c17fc1981d..80ef9b2a5f 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 @@ -22,6 +22,6 @@ * Package with cxx community plug-in for SonarQube. */ @ParametersAreNonnullByDefault -package org.sonar.plugins.cxx; +package org.sonar.plugins.c; import javax.annotation.ParametersAreNonnullByDefault; From 08748aaa493e407525e86594a3127063884c8bfd Mon Sep 17 00:00:00 2001 From: Bert Date: Tue, 18 Apr 2017 18:30:49 +0200 Subject: [PATCH 3/6] more fixes --- .../java/org/sonar/cxx/CxxConfiguration.java | 5 +- .../java/org/sonar/plugins/c/CPlugin.java | 62 +++++++------------ .../java/org/sonar/plugins/cxx/CxxPlugin.java | 59 +++++++----------- 3 files changed, 47 insertions(+), 79 deletions(-) diff --git a/cxx-squid/src/main/java/org/sonar/cxx/CxxConfiguration.java b/cxx-squid/src/main/java/org/sonar/cxx/CxxConfiguration.java index 4f21f6f979..15b946d4ab 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/CxxConfiguration.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/CxxConfiguration.java @@ -32,7 +32,6 @@ import javax.annotation.Nullable; import org.sonar.api.utils.log.Logger; -import org.sonar.api.utils.log.LoggerLevel; import org.sonar.api.utils.log.Loggers; import org.sonar.api.batch.fs.FileSystem; import org.sonar.squidbridge.api.SquidConfiguration; @@ -91,8 +90,8 @@ public boolean getIgnoreHeaderComments() { return ignoreHeaderComments; } - public void setDefines(String[] defines) { - if (defines == null) { //NOSONAR + public void setDefines(@Nullable String[] defines) { + if (defines == null) { return; } 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 8e60abd8a4..c39c115716 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 @@ -70,6 +70,8 @@ * {@inheritDoc} */ public final class CPlugin implements Plugin { + private static final String EXTENDING_THE_CODE_ANALYSIS = " The used format is described here."; + private static final String USE_ANT_STYLE_WILDCARDS = " Use Ant-style wildcards if neccessary."; public static final String LANG_PROP_PREFIX = "sonar.c."; public static final String SOURCE_FILE_SUFFIXES_KEY = LANG_PROP_PREFIX + "suffixes.sources"; public static final String HEADER_FILE_SUFFIXES_KEY = LANG_PROP_PREFIX + "suffixes.headers"; @@ -83,6 +85,7 @@ public final class CPlugin implements Plugin { public static final String SCAN_ONLY_SPECIFIED_SOURCES_KEY = LANG_PROP_PREFIX + "scanOnlySpecifiedSources"; public static final String CPD_IGNORE_LITERALS_KEY = LANG_PROP_PREFIX + "cpd.ignoreLiterals"; public static final String CPD_IGNORE_IDENTIFIERS_KEY = LANG_PROP_PREFIX + "cpd.ignoreIdentifiers"; + private static List generalProperties() { String subcateg = "(1) General"; @@ -186,88 +189,77 @@ private static List codeAnalysisProperties() { .build(), PropertyDefinition.builder(LANG_PROP_PREFIX + CxxCppCheckRuleRepository.CUSTOM_RULES_KEY) .name("Cppcheck custom rules") - .description("XML definitions of custom Cppcheck rules, which are'nt builtin into the plugin." - + " The used format is described here.") + .description("XML definitions of custom Cppcheck rules, which are'nt builtin into the plugin." + EXTENDING_THE_CODE_ANALYSIS) .type(PropertyType.TEXT) .subCategory(subcateg) .index(2) .build(), PropertyDefinition.builder(LANG_PROP_PREFIX + CxxValgrindSensor.REPORT_PATH_KEY) .name("Valgrind report(s)") - .description("Path to Valgrind report(s), relative to projects root." - + " Use Ant-style wildcards if neccessary.") + .description("Path to Valgrind report(s), relative to projects root." + USE_ANT_STYLE_WILDCARDS) .subCategory(subcateg) .onQualifiers(Qualifiers.PROJECT, Qualifiers.MODULE) .index(3) .build(), PropertyDefinition.builder(LANG_PROP_PREFIX + CxxValgrindRuleRepository.CUSTOM_RULES_KEY) .name("Valgrind custom rules") - .description("XML definitions of custom Valgrind rules, which are'nt builtin into the plugin." - + " The used format is described here.") + .description("XML definitions of custom Valgrind rules, which are'nt builtin into the plugin." + EXTENDING_THE_CODE_ANALYSIS) .type(PropertyType.TEXT) .subCategory(subcateg) .index(4) .build(), PropertyDefinition.builder(LANG_PROP_PREFIX + CxxDrMemorySensor.REPORT_PATH_KEY) .name("Dr Memory report(s)") - .description("Path to Dr. Memory reports(s), relative to projects root." - + " Use Ant-style wildcards if neccessary.") + .description("Path to Dr. Memory reports(s), relative to projects root." + USE_ANT_STYLE_WILDCARDS) .subCategory(subcateg) .onQualifiers(Qualifiers.PROJECT, Qualifiers.MODULE) .index(5) .build(), PropertyDefinition.builder(LANG_PROP_PREFIX + CxxPCLintSensor.REPORT_PATH_KEY) .name("PC-lint report(s)") - .description("Path to PC-lint reports(s), relative to projects root." - + " Use Ant-style wildcards if neccessary.") + .description("Path to PC-lint reports(s), relative to projects root." + USE_ANT_STYLE_WILDCARDS) .subCategory(subcateg) .onQualifiers(Qualifiers.PROJECT, Qualifiers.MODULE) .index(5) .build(), PropertyDefinition.builder(LANG_PROP_PREFIX + CxxPCLintRuleRepository.CUSTOM_RULES_KEY) .name("PC-lint custom rules") - .description("XML definitions of custom PC-lint rules, which are'nt builtin into the plugin." - + " The used format is described here.") + .description("XML definitions of custom PC-lint rules, which are'nt builtin into the plugin." + EXTENDING_THE_CODE_ANALYSIS) .type(PropertyType.TEXT) .subCategory(subcateg) .index(6) .build(), PropertyDefinition.builder(LANG_PROP_PREFIX + CxxRatsSensor.REPORT_PATH_KEY) .name("RATS report(s)") - .description("Path to RATS reports(s), relative to projects root." - + " Use Ant-style wildcards if neccessary.") + .description("Path to RATS reports(s), relative to projects root." + USE_ANT_STYLE_WILDCARDS) .subCategory(subcateg) .onQualifiers(Qualifiers.PROJECT, Qualifiers.MODULE) .index(7) .build(), PropertyDefinition.builder(LANG_PROP_PREFIX + CxxRatsRuleRepository.CUSTOM_RULES_KEY) .name("RATS custom rules") - .description("XML definitions of custom RATS rules, which are'nt builtin into the plugin." - + " The used format is described here.") + .description("XML definitions of custom RATS rules, which are'nt builtin into the plugin." + EXTENDING_THE_CODE_ANALYSIS) .type(PropertyType.TEXT) .subCategory(subcateg) .index(8) .build(), PropertyDefinition.builder(LANG_PROP_PREFIX + CxxVeraxxSensor.REPORT_PATH_KEY) .name("Vera++ report(s)") - .description("Path to Vera++ reports(s), relative to projects root." - + " Use Ant-style wildcards if neccessary.") + .description("Path to Vera++ reports(s), relative to projects root." + USE_ANT_STYLE_WILDCARDS) .subCategory(subcateg) .onQualifiers(Qualifiers.PROJECT, Qualifiers.MODULE) .index(9) .build(), PropertyDefinition.builder(LANG_PROP_PREFIX + CxxVeraxxRuleRepository.CUSTOM_RULES_KEY) .name("Vera++ custom rules") - .description("XML definitions of custom Vera++ rules, which are'nt builtin into the plugin." - + " The used format is described here.") + .description("XML definitions of custom Vera++ rules, which are'nt builtin into the plugin." + EXTENDING_THE_CODE_ANALYSIS) .type(PropertyType.TEXT) .subCategory(subcateg) .index(10) .build(), PropertyDefinition.builder(LANG_PROP_PREFIX + CxxOtherSensor.REPORT_PATH_KEY) .name("External checkers report(s)") - .description("Path to a code analysis report, which is generated by some unsupported code analyser, relative to projects root." - + " Use Ant-style wildcards if neccessary." + .description("Path to a code analysis report, which is generated by some unsupported code analyser, relative to projects root." + USE_ANT_STYLE_WILDCARDS + " See here for details.") .subCategory(subcateg) .onQualifiers(Qualifiers.PROJECT, Qualifiers.MODULE) @@ -292,8 +284,7 @@ private static List codeAnalysisProperties() { .build(), PropertyDefinition.builder(LANG_PROP_PREFIX + CxxClangTidyRuleRepository.CUSTOM_RULES_KEY) .name("Clang-Tidy custom rules") - .description("XML definitions of custom Clang-Tidy rules, which aren't builtin into the plugin." - + " The used format is described here.") + .description("XML definitions of custom Clang-Tidy rules, which aren't builtin into the plugin." + EXTENDING_THE_CODE_ANALYSIS) .type(PropertyType.TEXT) .subCategory(subcateg) .index(14) @@ -306,8 +297,7 @@ private static List compilerWarningsProperties() { return new ArrayList<>(Arrays.asList( PropertyDefinition.builder(LANG_PROP_PREFIX + CxxCompilerSensor.REPORT_PATH_KEY) .name("Compiler report(s)") - .description("Path to compilers output (i.e. file(s) containg compiler warnings), relative to projects root." - + " Use Ant-style wildcards if neccessary.") + .description("Path to compilers output (i.e. file(s) containg compiler warnings), relative to projects root." + USE_ANT_STYLE_WILDCARDS) .subCategory(subcateg) .onQualifiers(Qualifiers.PROJECT, Qualifiers.MODULE) .index(1) @@ -316,7 +306,7 @@ private static List compilerWarningsProperties() { .defaultValue(CxxCompilerSensor.DEFAULT_PARSER_DEF) .name("Format") .type(PropertyType.SINGLE_SELECT_LIST) - .options(LANG_PROP_PREFIX + CxxCompilerVcParser.KEY, LANG_PROP_PREFIX + CxxCompilerGccParser.KEY) + .options(LANG_PROP_PREFIX + CxxCompilerVcParser.COMPILER_KEY, LANG_PROP_PREFIX + CxxCompilerGccParser.COMPILER_KEY) .description("The format of the warnings file. Currently supported are Visual C++ and GCC.") .subCategory(subcateg) .onQualifiers(Qualifiers.PROJECT, Qualifiers.MODULE) @@ -340,16 +330,14 @@ private static List compilerWarningsProperties() { .build(), PropertyDefinition.builder(LANG_PROP_PREFIX + CxxCompilerVcRuleRepository.CUSTOM_RULES_KEY) .name("Custom rules for Visual C++ warnings") - .description("XML definitions of custom rules for Visual C++ warnings, which are'nt builtin into the plugin." - + " The used format is described here.") + .description("XML definitions of custom rules for Visual C++ warnings, which are'nt builtin into the plugin." + EXTENDING_THE_CODE_ANALYSIS) .type(PropertyType.TEXT) .subCategory(subcateg) .index(5) .build(), PropertyDefinition.builder(LANG_PROP_PREFIX + CxxCompilerGccRuleRepository.CUSTOM_RULES_KEY) .name("Custom rules for GCC warnings") - .description("XML definitions of custom rules for GCC's warnings, which are'nt builtin into the plugin." - + " The used format is described here.") + .description("XML definitions of custom rules for GCC's warnings, which are'nt builtin into the plugin." + EXTENDING_THE_CODE_ANALYSIS) .type(PropertyType.TEXT) .subCategory(subcateg) .index(6) @@ -363,8 +351,7 @@ private static List testingAndCoverageProperties() { PropertyDefinition.builder(LANG_PROP_PREFIX + CxxCoverageSensor.REPORT_PATH_KEY) .name("Unit test coverage report(s)") .description("Path to a report containing unit test coverage data, relative to projects root." - + " See here for supported formats." - + " Use Ant-style wildcards if neccessary.") + + " See here for supported formats." + USE_ANT_STYLE_WILDCARDS) .subCategory(subcateg) .onQualifiers(Qualifiers.PROJECT, Qualifiers.MODULE) .index(1) @@ -372,8 +359,7 @@ private static List testingAndCoverageProperties() { PropertyDefinition.builder(LANG_PROP_PREFIX + CxxCoverageSensor.IT_REPORT_PATH_KEY) .name("Integration test coverage report(s)") .description("Path to a report containing integration test coverage data, relative to projects root." - + " See here for supported formats." - + " Use Ant-style wildcards if neccessary.") + + " See here for supported formats." + USE_ANT_STYLE_WILDCARDS) .subCategory(subcateg) .onQualifiers(Qualifiers.PROJECT, Qualifiers.MODULE) .index(2) @@ -381,8 +367,7 @@ private static List testingAndCoverageProperties() { PropertyDefinition.builder(LANG_PROP_PREFIX + CxxCoverageSensor.OVERALL_REPORT_PATH_KEY) .name("Overall test coverage report(s)") .description("Path to a report containing overall test coverage data (i.e. test coverage gained by all tests of all kinds), relative to projects root." - + " See here for supported formats." - + " Use Ant-style wildcards if neccessary.") + + " See here for supported formats." + USE_ANT_STYLE_WILDCARDS) .subCategory(subcateg) .onQualifiers(Qualifiers.PROJECT, Qualifiers.MODULE) .index(3) @@ -399,8 +384,7 @@ private static List testingAndCoverageProperties() { PropertyDefinition.builder(LANG_PROP_PREFIX + CxxXunitSensor.REPORT_PATH_KEY) .name("Unit test execution report(s)") .description("Path to unit test execution report(s), relative to projects root." - + " See here for supported formats." - + " Use Ant-style wildcards if neccessary.") + + " See here for supported formats." + USE_ANT_STYLE_WILDCARDS) .subCategory(subcateg) .onQualifiers(Qualifiers.PROJECT, Qualifiers.MODULE) .index(6) 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 a110e19241..b013d462cc 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 @@ -70,6 +70,8 @@ * {@inheritDoc} */ public final class CxxPlugin implements Plugin { + private static final String USE_ANT_STYLE_WILDCARDS = " Use Ant-style wildcards if neccessary."; + private static final String EXTENDING_THE_CODE_ANALYSIS = " The used format is described here."; public static final String LANG_PROP_PREFIX = "sonar.cxx."; public static final String SOURCE_FILE_SUFFIXES_KEY = LANG_PROP_PREFIX + "suffixes.sources"; public static final String HEADER_FILE_SUFFIXES_KEY = LANG_PROP_PREFIX + "suffixes.headers"; @@ -186,88 +188,77 @@ private static List codeAnalysisProperties() { .build(), PropertyDefinition.builder(LANG_PROP_PREFIX + CxxCppCheckRuleRepository.CUSTOM_RULES_KEY) .name("Cppcheck custom rules") - .description("XML definitions of custom Cppcheck rules, which are'nt builtin into the plugin." - + " The used format is described here.") + .description("XML definitions of custom Cppcheck rules, which are'nt builtin into the plugin." + EXTENDING_THE_CODE_ANALYSIS) .type(PropertyType.TEXT) .subCategory(subcateg) .index(2) .build(), PropertyDefinition.builder(LANG_PROP_PREFIX + CxxValgrindSensor.REPORT_PATH_KEY) .name("Valgrind report(s)") - .description("Path to Valgrind report(s), relative to projects root." - + " Use Ant-style wildcards if neccessary.") + .description("Path to Valgrind report(s), relative to projects root." + USE_ANT_STYLE_WILDCARDS) .subCategory(subcateg) .onQualifiers(Qualifiers.PROJECT, Qualifiers.MODULE) .index(3) .build(), PropertyDefinition.builder(LANG_PROP_PREFIX + CxxValgrindRuleRepository.CUSTOM_RULES_KEY) .name("Valgrind custom rules") - .description("XML definitions of custom Valgrind rules, which are'nt builtin into the plugin." - + " The used format is described here.") + .description("XML definitions of custom Valgrind rules, which are'nt builtin into the plugin." + EXTENDING_THE_CODE_ANALYSIS) .type(PropertyType.TEXT) .subCategory(subcateg) .index(4) .build(), PropertyDefinition.builder(LANG_PROP_PREFIX + CxxDrMemorySensor.REPORT_PATH_KEY) .name("Dr Memory report(s)") - .description("Path to Dr. Memory reports(s), relative to projects root." - + " Use Ant-style wildcards if neccessary.") + .description("Path to Dr. Memory reports(s), relative to projects root." + USE_ANT_STYLE_WILDCARDS) .subCategory(subcateg) .onQualifiers(Qualifiers.PROJECT, Qualifiers.MODULE) .index(5) .build(), PropertyDefinition.builder(LANG_PROP_PREFIX + CxxPCLintSensor.REPORT_PATH_KEY) .name("PC-lint report(s)") - .description("Path to PC-lint reports(s), relative to projects root." - + " Use Ant-style wildcards if neccessary.") + .description("Path to PC-lint reports(s), relative to projects root." + USE_ANT_STYLE_WILDCARDS) .subCategory(subcateg) .onQualifiers(Qualifiers.PROJECT, Qualifiers.MODULE) .index(5) .build(), PropertyDefinition.builder(LANG_PROP_PREFIX + CxxPCLintRuleRepository.CUSTOM_RULES_KEY) .name("PC-lint custom rules") - .description("XML definitions of custom PC-lint rules, which are'nt builtin into the plugin." - + " The used format is described here.") + .description("XML definitions of custom PC-lint rules, which are'nt builtin into the plugin." + EXTENDING_THE_CODE_ANALYSIS) .type(PropertyType.TEXT) .subCategory(subcateg) .index(6) .build(), PropertyDefinition.builder(LANG_PROP_PREFIX + CxxRatsSensor.REPORT_PATH_KEY) .name("RATS report(s)") - .description("Path to RATS reports(s), relative to projects root." - + " Use Ant-style wildcards if neccessary.") + .description("Path to RATS reports(s), relative to projects root." + USE_ANT_STYLE_WILDCARDS) .subCategory(subcateg) .onQualifiers(Qualifiers.PROJECT, Qualifiers.MODULE) .index(7) .build(), PropertyDefinition.builder(LANG_PROP_PREFIX + CxxRatsRuleRepository.CUSTOM_RULES_KEY) .name("RATS custom rules") - .description("XML definitions of custom RATS rules, which are'nt builtin into the plugin." - + " The used format is described here.") + .description("XML definitions of custom RATS rules, which are'nt builtin into the plugin." + EXTENDING_THE_CODE_ANALYSIS) .type(PropertyType.TEXT) .subCategory(subcateg) .index(8) .build(), PropertyDefinition.builder(LANG_PROP_PREFIX + CxxVeraxxSensor.REPORT_PATH_KEY) .name("Vera++ report(s)") - .description("Path to Vera++ reports(s), relative to projects root." - + " Use Ant-style wildcards if neccessary.") + .description("Path to Vera++ reports(s), relative to projects root." + USE_ANT_STYLE_WILDCARDS) .subCategory(subcateg) .onQualifiers(Qualifiers.PROJECT, Qualifiers.MODULE) .index(9) .build(), PropertyDefinition.builder(LANG_PROP_PREFIX + CxxVeraxxRuleRepository.CUSTOM_RULES_KEY) .name("Vera++ custom rules") - .description("XML definitions of custom Vera++ rules, which are'nt builtin into the plugin." - + " The used format is described here.") + .description("XML definitions of custom Vera++ rules, which are'nt builtin into the plugin." + EXTENDING_THE_CODE_ANALYSIS) .type(PropertyType.TEXT) .subCategory(subcateg) .index(10) .build(), PropertyDefinition.builder(LANG_PROP_PREFIX + CxxOtherSensor.REPORT_PATH_KEY) .name("External checkers report(s)") - .description("Path to a code analysis report, which is generated by some unsupported code analyser, relative to projects root." - + " Use Ant-style wildcards if neccessary." + .description("Path to a code analysis report, which is generated by some unsupported code analyser, relative to projects root." + USE_ANT_STYLE_WILDCARDS + " See here for details.") .subCategory(subcateg) .onQualifiers(Qualifiers.PROJECT, Qualifiers.MODULE) @@ -293,7 +284,7 @@ private static List codeAnalysisProperties() { PropertyDefinition.builder(LANG_PROP_PREFIX + CxxClangTidyRuleRepository.CUSTOM_RULES_KEY) .name("Clang-Tidy custom rules") .description("XML definitions of custom Clang-Tidy rules, which aren't builtin into the plugin." - + " The used format is described here.") + + EXTENDING_THE_CODE_ANALYSIS) .type(PropertyType.TEXT) .subCategory(subcateg) .index(14) @@ -306,8 +297,7 @@ private static List compilerWarningsProperties() { return new ArrayList<>(Arrays.asList( PropertyDefinition.builder(LANG_PROP_PREFIX + CxxCompilerSensor.REPORT_PATH_KEY) .name("Compiler report(s)") - .description("Path to compilers output (i.e. file(s) containg compiler warnings), relative to projects root." - + " Use Ant-style wildcards if neccessary.") + .description("Path to compilers output (i.e. file(s) containg compiler warnings), relative to projects root." + USE_ANT_STYLE_WILDCARDS) .subCategory(subcateg) .onQualifiers(Qualifiers.PROJECT, Qualifiers.MODULE) .index(1) @@ -316,7 +306,7 @@ private static List compilerWarningsProperties() { .defaultValue(CxxCompilerSensor.DEFAULT_PARSER_DEF) .name("Format") .type(PropertyType.SINGLE_SELECT_LIST) - .options(LANG_PROP_PREFIX + CxxCompilerVcParser.KEY, LANG_PROP_PREFIX + CxxCompilerGccParser.KEY) + .options(LANG_PROP_PREFIX + CxxCompilerVcParser.COMPILER_KEY, LANG_PROP_PREFIX + CxxCompilerGccParser.COMPILER_KEY) .description("The format of the warnings file. Currently supported are Visual C++ and GCC.") .subCategory(subcateg) .onQualifiers(Qualifiers.PROJECT, Qualifiers.MODULE) @@ -340,16 +330,14 @@ private static List compilerWarningsProperties() { .build(), PropertyDefinition.builder(LANG_PROP_PREFIX + CxxCompilerVcRuleRepository.CUSTOM_RULES_KEY) .name("Custom rules for Visual C++ warnings") - .description("XML definitions of custom rules for Visual C++ warnings, which are'nt builtin into the plugin." - + " The used format is described here.") + .description("XML definitions of custom rules for Visual C++ warnings, which are'nt builtin into the plugin." + EXTENDING_THE_CODE_ANALYSIS) .type(PropertyType.TEXT) .subCategory(subcateg) .index(5) .build(), PropertyDefinition.builder(LANG_PROP_PREFIX + CxxCompilerGccRuleRepository.CUSTOM_RULES_KEY) .name("Custom rules for GCC warnings") - .description("XML definitions of custom rules for GCC's warnings, which are'nt builtin into the plugin." - + " The used format is described here.") + .description("XML definitions of custom rules for GCC's warnings, which are'nt builtin into the plugin." + EXTENDING_THE_CODE_ANALYSIS) .type(PropertyType.TEXT) .subCategory(subcateg) .index(6) @@ -364,7 +352,7 @@ private static List testingAndCoverageProperties() { .name("Unit test coverage report(s)") .description("Path to a report containing unit test coverage data, relative to projects root." + " See here for supported formats." - + " Use Ant-style wildcards if neccessary.") + + USE_ANT_STYLE_WILDCARDS) .subCategory(subcateg) .onQualifiers(Qualifiers.PROJECT, Qualifiers.MODULE) .index(1) @@ -372,8 +360,7 @@ private static List testingAndCoverageProperties() { PropertyDefinition.builder(LANG_PROP_PREFIX + CxxCoverageSensor.IT_REPORT_PATH_KEY) .name("Integration test coverage report(s)") .description("Path to a report containing integration test coverage data, relative to projects root." - + " See here for supported formats." - + " Use Ant-style wildcards if neccessary.") + + " See here for supported formats." + USE_ANT_STYLE_WILDCARDS) .subCategory(subcateg) .onQualifiers(Qualifiers.PROJECT, Qualifiers.MODULE) .index(2) @@ -381,8 +368,7 @@ private static List testingAndCoverageProperties() { PropertyDefinition.builder(LANG_PROP_PREFIX + CxxCoverageSensor.OVERALL_REPORT_PATH_KEY) .name("Overall test coverage report(s)") .description("Path to a report containing overall test coverage data (i.e. test coverage gained by all tests of all kinds), relative to projects root." - + " See here for supported formats." - + " Use Ant-style wildcards if neccessary.") + + " See here for supported formats." + USE_ANT_STYLE_WILDCARDS) .subCategory(subcateg) .onQualifiers(Qualifiers.PROJECT, Qualifiers.MODULE) .index(3) @@ -399,8 +385,7 @@ private static List testingAndCoverageProperties() { PropertyDefinition.builder(LANG_PROP_PREFIX + CxxXunitSensor.REPORT_PATH_KEY) .name("Unit test execution report(s)") .description("Path to unit test execution report(s), relative to projects root." - + " See here for supported formats." - + " Use Ant-style wildcards if neccessary.") + + " See here for supported formats." + USE_ANT_STYLE_WILDCARDS) .subCategory(subcateg) .onQualifiers(Qualifiers.PROJECT, Qualifiers.MODULE) .index(6) From 7554bf9e26487091438610d36f3c5a8066fa4f58 Mon Sep 17 00:00:00 2001 From: Bert Date: Tue, 18 Apr 2017 19:10:51 +0200 Subject: [PATCH 4/6] add missed files --- .../org/sonar/cxx/sensors/compiler/CompilerParser.java | 6 +++++- .../sonar/cxx/sensors/compiler/CxxCompilerGccParser.java | 8 ++++---- .../org/sonar/cxx/sensors/compiler/CxxCompilerSensor.java | 8 ++++---- .../sonar/cxx/sensors/compiler/CxxCompilerVcParser.java | 6 +++--- .../main/java/org/sonar/cxx/sensors/utils/CxxMetrics.java | 7 ++++--- .../sonar/cxx/sensors/compiler/CxxCompilerSensorTest.java | 6 +++--- 6 files changed, 23 insertions(+), 18 deletions(-) diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/compiler/CompilerParser.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/compiler/CompilerParser.java index b5b8e4df95..1767c0b43a 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/compiler/CompilerParser.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/compiler/CompilerParser.java @@ -90,7 +90,11 @@ public boolean equals(Object other) { return true; } - if ( !(other instanceof Warning) ) { + if (other == null) { + return false; + } + + if ( this.getClass() != other.getClass() ) { return false; } diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/compiler/CxxCompilerGccParser.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/compiler/CxxCompilerGccParser.java index 9b8a9d89e6..dac117bcf3 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/compiler/CxxCompilerGccParser.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/compiler/CxxCompilerGccParser.java @@ -33,7 +33,7 @@ */ public class CxxCompilerGccParser implements CompilerParser { public static final Logger LOG = Loggers.get(CxxCompilerGccParser.class); - public static final String KEY = "GCC"; + public static final String COMPILER_KEY = "GCC"; // search for single line with compiler warning message - order for groups: 1 = file, 2 = line, 3 = message, 4=id public static final String DEFAULT_REGEX_DEF = "^(.*):([0-9]+):[0-9]+: warning: (.*)\\[(.*)\\]$"; // ToDo: as long as java 7 API is not used the support of named groups for regular expression is not possible @@ -46,7 +46,7 @@ public class CxxCompilerGccParser implements CompilerParser { */ @Override public String key() { - return KEY; + return COMPILER_KEY; } /** @@ -78,12 +78,12 @@ public String defaultCharset() { */ @Override public void processReport(final SensorContext context, File report, String charset, String reportRegEx, List warnings) throws java.io.FileNotFoundException { - LOG.info("Parsing '{}' format", KEY); + LOG.info("Parsing '{}' format", COMPILER_KEY); Scanner scanner = new Scanner(report, charset); Pattern p = Pattern.compile(reportRegEx, Pattern.MULTILINE); LOG.debug("Using pattern : '{}'", p); - MatchResult matchres = null; + MatchResult matchres; while (scanner.findWithinHorizon(p, 0) != null) { matchres = scanner.match(); String filename = matchres.group(1).trim(); diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/compiler/CxxCompilerSensor.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/compiler/CxxCompilerSensor.java index 6c5f026d20..5fd8994038 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/compiler/CxxCompilerSensor.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/compiler/CxxCompilerSensor.java @@ -34,7 +34,7 @@ /** * compiler for C++ with advanced analysis features (e.g. for VC 2008 team - * edition or 2010/2012/2013 premium edition) + * edition or 2010/2012/2013/2015/2017 premium edition) * * @author Bert */ @@ -44,9 +44,9 @@ public class CxxCompilerSensor extends CxxReportSensor { public static final String REPORT_REGEX_DEF = "compiler.regex"; public static final String REPORT_CHARSET_DEF = "compiler.charset"; public static final String PARSER_KEY_DEF = "compiler.parser"; - public static final String DEFAULT_PARSER_DEF = CxxCompilerVcParser.KEY; + public static final String DEFAULT_PARSER_DEF = CxxCompilerVcParser.COMPILER_KEY; public static final String DEFAULT_CHARSET_DEF = "UTF-8"; - public static final String KEY = "Compiler"; + public static final String COMPILER_KEY = "Compiler"; private final Map parsers = new HashMap<>(); @@ -137,6 +137,6 @@ private boolean isInputValid(CompilerParser.Warning warning) { @Override protected String getSensorKey() { - return KEY; + return COMPILER_KEY; } } diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/compiler/CxxCompilerVcParser.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/compiler/CxxCompilerVcParser.java index 12705cec22..64cd9bc058 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/compiler/CxxCompilerVcParser.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/compiler/CxxCompilerVcParser.java @@ -34,7 +34,7 @@ */ public class CxxCompilerVcParser implements CompilerParser { public static final Logger LOG = Loggers.get(CxxCompilerVcParser.class); - public static final String KEY = "Visual C++"; + public static final String COMPILER_KEY = "Visual C++"; // search for single line with compiler warning message VS2008 - order for groups: 1 = file, 2 = line, 3 = ID, 4=message public static final String DEFAULT_REGEX_DEF = "^.*[\\\\,/](.*)\\((\\d+)\\)\\x20:\\x20warning\\x20(C\\d+):(.*)$"; // ToDo: as long as java 7 API is not used the support of named groups for regular expression is not possible @@ -47,7 +47,7 @@ public class CxxCompilerVcParser implements CompilerParser { */ @Override public String key() { - return KEY; + return COMPILER_KEY; } /** @@ -84,7 +84,7 @@ public void processReport(final SensorContext context, File report, String chars Scanner scanner = new Scanner(report, charset); Pattern p = Pattern.compile(reportRegEx, Pattern.MULTILINE); LOG.info("Using pattern : '{}'", p); - MatchResult matchres = null; + MatchResult matchres; while (scanner.findWithinHorizon(p, 0) != null) { matchres = scanner.match(); String filename = matchres.group(1).trim(); diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/utils/CxxMetrics.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/utils/CxxMetrics.java index 66fab0d971..5c01caa6c8 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/utils/CxxMetrics.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/utils/CxxMetrics.java @@ -21,6 +21,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Locale; import org.sonar.api.measures.Metric; import org.sonar.api.measures.Metrics; @@ -42,13 +43,13 @@ public class CxxMetrics implements Metrics { private final CxxLanguage language; public static String GetKey(String key, CxxLanguage language) { - return language.getPropertiesKey().toUpperCase() + "-" + key.toUpperCase(); + return language.getPropertiesKey().toUpperCase(Locale.ENGLISH) + "-" + key.toUpperCase(Locale.ENGLISH); } public CxxMetrics(CxxLanguage language) { this.language = language; - this.BuildMetric(CxxCompilerSensor.KEY, "Compiler issues", language); + this.BuildMetric(CxxCompilerSensor.COMPILER_KEY, "Compiler issues", language); this.BuildMetric(CxxCppCheckSensor.KEY, "CppCheck issues", language); this.BuildMetric(CxxOtherSensor.KEY, "Other tools issues", language); this.BuildMetric(CxxPCLintSensor.KEY, "PC-Lint issues", language); @@ -69,7 +70,7 @@ private void BuildMetric(String key, String description, CxxLanguage language) { Metric metric = new Metric.Builder(effectiveKey, description, Metric.ValueType.INT) .setDirection(Metric.DIRECTION_WORST) .setQualitative(Boolean.TRUE) - .setDomain(language.getKey().toUpperCase()) + .setDomain(language.getKey().toUpperCase(Locale.ENGLISH)) .create(); language.SaveMetric(metric, key); 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 b7bd422b68..119f3fd6e0 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 @@ -57,7 +57,7 @@ public void setUp() { // @Test @todo parsing for htm not working public void shouldReportACorrectVcViolations() { CxxLanguage language = TestUtils.mockCxxLanguage(); - when(language.getStringOption(CxxCompilerSensor.PARSER_KEY_DEF)).thenReturn(CxxCompilerVcParser.KEY); + when(language.getStringOption(CxxCompilerSensor.PARSER_KEY_DEF)).thenReturn(CxxCompilerVcParser.COMPILER_KEY); when(language.getStringArrayOption(CxxCompilerSensor.REPORT_PATH_KEY)) .thenReturn(new String [] { fs.baseDir().getAbsolutePath() + "/compiler-reports/BuildLog.htm"}); when(language.getStringOption(CxxCompilerSensor.REPORT_CHARSET_DEF)).thenReturn("UTF-16"); @@ -78,7 +78,7 @@ public void shouldReportCorrectGccViolations() { .setLanguage("cpp").initMetadata("asd\nasdas\nasda\n")); CxxLanguage language = TestUtils.mockCxxLanguage(); - when(language.getStringOption(CxxCompilerSensor.PARSER_KEY_DEF)).thenReturn(CxxCompilerGccParser.KEY); + when(language.getStringOption(CxxCompilerSensor.PARSER_KEY_DEF)).thenReturn(CxxCompilerGccParser.COMPILER_KEY); when(language.getStringArrayOption(CxxCompilerSensor.REPORT_PATH_KEY)) .thenReturn(new String [] {fs.baseDir().getAbsolutePath() + "/compiler-reports/build.log"}); when(language.getStringOption(CxxCompilerSensor.REPORT_CHARSET_DEF)).thenReturn("UTF-8"); @@ -92,7 +92,7 @@ public void shouldReportCorrectGccViolations() { public void shouldReportBCorrectVcViolations() { CxxLanguage language = TestUtils.mockCxxLanguage(); - when(language.getStringOption(CxxCompilerSensor.PARSER_KEY_DEF)).thenReturn(CxxCompilerVcParser.KEY); + when(language.getStringOption(CxxCompilerSensor.PARSER_KEY_DEF)).thenReturn(CxxCompilerVcParser.COMPILER_KEY); when(language.getStringArrayOption(CxxCompilerSensor.REPORT_PATH_KEY)) .thenReturn(new String [] {fs.baseDir().getAbsolutePath() + "/compiler-reports/VC-report.log"}); when(language.getStringOption(CxxCompilerSensor.REPORT_CHARSET_DEF)).thenReturn("UTF-8"); From 655ad7ad5fa4cade613e86c19880ffea2a45cac3 Mon Sep 17 00:00:00 2001 From: Bert Date: Wed, 19 Apr 2017 19:28:47 +0200 Subject: [PATCH 5/6] add fixes for sensors --- .../sensors/clangtidy/CxxClangTidySensor.java | 8 ++- .../sensors/coverage/CxxCoverageSensor.java | 18 +++--- .../sensors/cppcheck/CppcheckParserV1.java | 11 ++-- .../sensors/drmemory/CxxDrMemorySensor.java | 23 +++---- .../cxx/sensors/drmemory/DrMemoryParser.java | 37 +++++------ .../cxx/sensors/other/CxxOtherRepository.java | 2 +- .../cxx/sensors/other/CxxOtherSensor.java | 2 +- .../cxx/sensors/pclint/CxxPCLintSensor.java | 6 +- .../sensors/rats/CxxRatsRuleRepository.java | 2 +- .../sonar/cxx/sensors/rats/CxxRatsSensor.java | 4 +- .../dotnet/CxxUnitTestResultsProvider.java | 2 +- .../sensors/tests/xunit/CxxXunitSensor.java | 64 +++++++++++-------- .../tests/xunit/XunitReportParser.java | 11 ++-- .../utils/CxxAbstractRuleRepository.java | 18 ++++-- .../cxx/sensors/utils/CxxReportSensor.java | 6 +- .../org/sonar/cxx/sensors/utils/CxxUtils.java | 2 +- .../utils/JsonCompilationDatabase.java | 31 ++++----- .../cxx/sensors/veraxx/CxxVeraxxSensor.java | 6 +- .../cxx/sensors/visitors/CxxCpdVisitor.java | 2 +- .../visitors/CxxHighlighterVisitor.java | 19 +++--- .../sensors/drmemory/DrMemoryParserTest.java | 3 +- 21 files changed, 148 insertions(+), 129 deletions(-) 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 41b5648119..b02e2fc302 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 @@ -20,6 +20,7 @@ package org.sonar.cxx.sensors.clangtidy; import java.io.File; +import java.nio.charset.StandardCharsets; import java.util.Scanner; import java.util.regex.MatchResult; import java.util.regex.Matcher; @@ -61,7 +62,7 @@ public void describe(SensorDescriptor descriptor) { protected void processReport(final SensorContext context, File report) { LOG.debug("Parsing clang-tidy report"); - try (Scanner scanner = new Scanner(report, "UTF-8")) { + try (Scanner scanner = new Scanner(report, StandardCharsets.UTF_8.name())) { // E:\Development\SonarQube\cxx\sonar-cxx\sonar-cxx-plugin\src\test\resources\org\sonar\plugins\cxx\reports-project\clang-tidy-reports\..\..\cpd.cc:76:20: warning: ISO C++11 does not allow conversion from string literal to 'char *' [clang-diagnostic-writable-strings] // ::: : [] // relative paths @@ -85,7 +86,10 @@ protected void processReport(final SensorContext context, File report) { message); } } - } catch (final Exception e) { + } catch (final java.io.FileNotFoundException + |java.lang.IllegalArgumentException + |java.lang.IllegalStateException + |java.util.InputMismatchException e) { LOG.error("Failed to parse clang-tidy report: {}", e); } } 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 c4b6cefb72..e64321a7ee 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 @@ -113,9 +113,9 @@ public void execute(SensorContext context, Map> linesOfC private void zeroMeasuresWithoutReports( SensorContext context, - Map coverageMeasures, - Map itCoverageMeasures, - Map overallCoverageMeasures, + @Nullable Map coverageMeasures, + @Nullable Map itCoverageMeasures, + @Nullable Map overallCoverageMeasures, Map> linesOfCode ) { FileSystem fileSystem = context.fileSystem(); @@ -152,7 +152,7 @@ private void saveZeroValueForResource(InputFile inputFile, SensorContext context try { newCoverage.lineHits(line, 0); } catch (Exception ex) { - LOG.error("Cannot save Line Hits for Line '{}' '{}' : '{}', ignoring measure", inputFile.relativePath(), line, ex.getMessage()); + LOG.error("Cannot save Line Hits for Line '{}' '{}' : '{}', ignoring measure", inputFile.relativePath(), line, ex); CxxUtils.validateRecovery(ex, this.language); } } @@ -160,7 +160,7 @@ private void saveZeroValueForResource(InputFile inputFile, SensorContext context try { newCoverage.save(); } catch (Exception ex) { - LOG.error("Cannot save measure '{}' : '{}', ignoring measure", inputFile.relativePath(), ex.getMessage()); + LOG.error("Cannot save measure '{}' : '{}', ignoring measure", inputFile.relativePath(), ex); CxxUtils.validateRecovery(ex, this.language); } } @@ -184,7 +184,7 @@ private Map processReports(final SensorContext context LOG.info("Added report '{}' (parsed by: {}) to the coverage data", report, parser); break; } - } catch (XMLStreamException e) { + } catch (XMLStreamException e) { //NOSONAR LOG.trace("Report {} cannot be parsed by {}", report, parser); } } @@ -224,7 +224,7 @@ private void saveMeasures(SensorContext context, { newCoverage.lineHits(measure.getLine(), measure.getHits()); } catch(Exception ex) { - LOG.error("Cannot save Line Hits for Line '{}' '{}' : '{}', ignoring measure", filePath, measure.getLine(), ex.getMessage()); + LOG.error("Cannot save Line Hits for Line '{}' '{}' : '{}', ignoring measure", filePath, measure.getLine(), ex); CxxUtils.validateRecovery(ex, this.language); } } @@ -234,7 +234,7 @@ private void saveMeasures(SensorContext context, { newCoverage.conditions(measure.getLine(), measure.getConditions(), measure.getCoveredConditions()); } catch(Exception ex) { - LOG.error("Cannot save Conditions Hits for Line '{}' '{}' : '{}', ignoring measure", filePath, measure.getLine(), ex.getMessage()); + LOG.error("Cannot save Conditions Hits for Line '{}' '{}' : '{}', ignoring measure", filePath, measure.getLine(), ex); CxxUtils.validateRecovery(ex, this.language); } } @@ -244,7 +244,7 @@ private void saveMeasures(SensorContext context, { newCoverage.save(); } catch(Exception ex) { - LOG.error("Cannot save measure '{}' : '{}', ignoring measure", filePath, ex.getMessage()); + LOG.error("Cannot save measure '{}' : '{}', ignoring measure", filePath, ex); CxxUtils.validateRecovery(ex, this.language); } } else { diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/cppcheck/CppcheckParserV1.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/cppcheck/CppcheckParserV1.java index f164ba734c..0d159a8edc 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/cppcheck/CppcheckParserV1.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/cppcheck/CppcheckParserV1.java @@ -45,8 +45,7 @@ public CppcheckParserV1(CxxCppCheckSensor sensor) { * {@inheritDoc} */ @Override - public void processReport(final SensorContext context, File report) - throws javax.xml.stream.XMLStreamException { + public void processReport(final SensorContext context, File report) throws XMLStreamException { LOG.debug("Parsing 'Cppcheck V1' format"); StaxParser parser = new StaxParser(new StaxParser.XmlStreamHandler() { /** @@ -57,8 +56,8 @@ public void stream(SMHierarchicCursor rootCursor) throws XMLStreamException { try { rootCursor.advance(); // results - } catch (com.ctc.wstx.exc.WstxEOFException eofExc) { - throw new EmptyReportException(); + } catch (com.ctc.wstx.exc.WstxEOFException eofExc) { //NOSONAR + throw new EmptyReportException(); //NOSONAR } try { @@ -84,8 +83,8 @@ public void stream(SMHierarchicCursor rootCursor) throws XMLStreamException { LOG.warn("Skipping invalid violation: '{}'", msg); } } - } catch (RuntimeException e) { - throw new XMLStreamException(); + } catch (RuntimeException e) { //NOSONAR + throw new XMLStreamException(e.getMessage()); //NOSONAR } } 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 4b9ce7e399..8ac3390d94 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,6 +21,8 @@ import java.io.File; import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import org.sonar.api.batch.sensor.SensorContext; import org.sonar.api.batch.fs.InputFile; @@ -36,7 +38,7 @@ /** * Dr. Memory is a memory monitoring tool capable of identifying memory-related * programming errors such as accesses of uninitialized memory, accesses to - * unaddressable memory (including outside of allocated heap units and heap + * un-addressable memory (including outside of allocated heap units and heap * underflow and overflow), accesses to freed memory, double frees, memory * leaks, and (on Windows) handle leaks, GDI API usage errors, and accesses to * un-reserved thread local storage slots. See also: http://drmemory.org @@ -46,7 +48,8 @@ public class CxxDrMemorySensor extends CxxReportSensor { public static final Logger LOG = Loggers.get(CxxDrMemorySensor.class); public static final String REPORT_PATH_KEY = "drmemory.reportPath"; - public static String KEY = "DrMemory"; + public static final String KEY = "DrMemory"; + public static final String DEFAULT_CHARSET_DEF = StandardCharsets.UTF_8.name(); /** * {@inheritDoc} @@ -55,6 +58,10 @@ public CxxDrMemorySensor(CxxLanguage language) { super(language); } + public String defaultCharset() { + return DEFAULT_CHARSET_DEF; + } + @Override public void describe(SensorDescriptor descriptor) { descriptor.onlyOnLanguage(this.language.getKey()).name(language.getName() + " DrMemorySensor"); @@ -69,8 +76,7 @@ protected String reportPathKey() { protected void processReport(final SensorContext context, File report) { LOG.debug("Parsing 'Dr Memory' format"); - try { - for (DrMemoryError error : DrMemoryParser.parse(report)) { + for (DrMemoryError error : DrMemoryParser.parse(report, defaultCharset())) { if (error.stackTrace.isEmpty()) { saveUniqueViolation(context, CxxDrMemoryRuleRepository.KEY, null, null, @@ -85,15 +91,6 @@ protected void processReport(final SensorContext context, File report) { } } } - } catch (IOException e) { - String msg = new StringBuilder() - .append("Cannot feed the data into sonar, details: '") - .append(e) - .append("'") - .toString(); - LOG.error(msg); - CxxUtils.validateRecovery(e, this.language); - } } private boolean isFileInAnalysis(SensorContext context, Location errorLocation) { 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 d821867c9d..86082d4838 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 @@ -21,8 +21,11 @@ import java.io.BufferedReader; import java.io.File; +import java.io.FileInputStream; import java.io.FileReader; import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.Charset; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; @@ -32,7 +35,7 @@ public class DrMemoryParser { - public static enum DrMemoryErrorType { + public enum DrMemoryErrorType { UNADRESSABLE_ACCESS("UnadressableAccess", "UNADDRESSABLE ACCESS"), UNINITIALIZE_READ("UninitializedRead", "UNINITIALIZED READ"), INVALID_HEAP_ARGUMENT("InvalidHeapArgument", "INVALID HEAP ARGUMENT"), @@ -60,8 +63,6 @@ public String getTitle() { } } - - public static class DrMemoryError { public static class Location { @@ -70,11 +71,10 @@ public static class Location { } public DrMemoryErrorType type = DrMemoryErrorType.UNRECOGNIZED; - public List stackTrace = new ArrayList(); + public List stackTrace = new ArrayList<>(); public String message = ""; } - private DrMemoryParser() { } @@ -83,11 +83,11 @@ private DrMemoryParser() { public static final int __TOP_COUNT = 4; - public static List parse( File file ) throws IOException { + public static List parse(File file, String charset) { - List result = new ArrayList(); + List result = new ArrayList<>(); - List elements = getElements(file); + List elements = getElements(file, charset); for (String element : elements) { Matcher m = rx_message_finder.matcher( element ); @@ -95,7 +95,7 @@ public static List parse( File file ) throws IOException { if( m.find() ) { DrMemoryError error = new DrMemoryError(); error.type = extractErrorType(m.group(1)); - String elementSplitted[] = element.split("\\r?\\n"); + String[] elementSplitted = element.split("\\r?\\n"); error.message = elementSplitted[0]; for (String elementPart : elementSplitted) { Matcher locationMatcher = rx_file_finder.matcher( elementPart ); @@ -130,26 +130,25 @@ private static String clean(String title) { return title.trim(); } + public static List getElements(File file, String charset){ - public static List getElements( File file ) throws IOException { - FileReader fr = new FileReader( file ); - BufferedReader br = new BufferedReader( fr ); - List list = new ArrayList(); + List list = new ArrayList<>(); + try (FileInputStream input = new FileInputStream(file)) { + BufferedReader br = new BufferedReader(new InputStreamReader(input, charset)); StringBuilder sb = new StringBuilder(); String line; int cnt = 0; + while( ( line = br.readLine() ) != null ) { if( cnt > ( __TOP_COUNT ) ) { - if( line.matches( "^\\s*$" ) ) { list.add( sb.toString() ); sb.setLength( 0 ); - } else { - sb.append( line + '\n' ); + sb.append(line); + sb.append('\n'); } } - cnt++; } @@ -158,7 +157,9 @@ public static List getElements( File file ) throws IOException { } br.close(); - + input.close(); + } catch (IOException e) { //NOSONAR + } return list; } } 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 91ae3142c5..20e842166b 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 @@ -52,7 +52,7 @@ public void define(Context context) { if (ruleDefs != null && !ruleDefs.trim().isEmpty()) { try { xmlRuleLoader.load(repository, new StringReader(ruleDefs)); - } catch (Exception ex) { + } catch (Exception ex) { //NOSONAR LOG.info("Cannot load rules XML '{}'", ex); } } 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 a755bab51a..1119fd2bf1 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 @@ -40,7 +40,7 @@ public class CxxOtherSensor extends CxxReportSensor { public static final Logger LOG = Loggers.get(CxxOtherSensor.class); public static final String REPORT_PATH_KEY = "other.reportPath"; - public static String KEY = "Other"; + public static final String KEY = "Other"; /** * {@inheritDoc} 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 1cb2b1f169..efc5bb8feb 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 @@ -48,7 +48,7 @@ public class CxxPCLintSensor extends CxxReportSensor { public static final Logger LOG = Loggers.get(CxxPCLintSensor.class); public static final String REPORT_PATH_KEY = "pclint.reportPath"; - public static String KEY = "PC-Lint"; + public static final String KEY = "PC-Lint"; /** * {@inheritDoc} @@ -80,8 +80,8 @@ protected void processReport(final SensorContext context, File report) public void stream(SMHierarchicCursor rootCursor) throws XMLStreamException { try { rootCursor.advance(); - } catch (com.ctc.wstx.exc.WstxEOFException eofExc) { - throw new EmptyReportException(); + } catch (com.ctc.wstx.exc.WstxEOFException eofExc) { //NOSONAR + throw new EmptyReportException(); //NOSONAR } SMInputCursor errorCursor = rootCursor.childElementCursor("issue"); 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 337cfd5148..5365571a78 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 @@ -29,7 +29,7 @@ */ public class CxxRatsRuleRepository extends CxxAbstractRuleRepository { - public static final String KEY = "rats"; + public static String KEY = "rats"; public static final String CUSTOM_RULES_KEY = "rats.customRules"; private static final String NAME = "RATS"; 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 331aa5bb41..64fbefc741 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 @@ -22,6 +22,8 @@ import java.io.File; import java.util.List; +import javax.annotation.Nullable; + import org.jdom.Element; import org.jdom.input.SAXBuilder; import org.sonar.api.batch.sensor.SensorContext; @@ -93,7 +95,7 @@ protected void processReport(final SensorContext context, File report) } } - private String getVulnerabilityType(Element child) { + private String getVulnerabilityType(@Nullable Element child) { if (child != null) { return child.getTextTrim(); } diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/CxxUnitTestResultsProvider.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/CxxUnitTestResultsProvider.java index 3622531900..ed2d5806f4 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/CxxUnitTestResultsProvider.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/tests/dotnet/CxxUnitTestResultsProvider.java @@ -65,7 +65,7 @@ public CxxUnitTestResultsImportSensor(CxxUnitTestResultsAggregator unitTestResul public void execute(SensorContext context) { try { super.execute(context); - } catch (Exception e) { + } catch (Exception e) { //NOSONAR String msg = new StringBuilder() .append("Cannot feed the data into SonarQube, details: '") .append(e) 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 795103dfee..78aa09da2b 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 @@ -97,16 +97,7 @@ public void execute(SensorContext context) { try { List reports = getReports(this.language, context.fileSystem().baseDir(), REPORT_PATH_KEY); if (!reports.isEmpty()) { - XunitReportParser parserHandler = new XunitReportParser(); - StaxParser parser = new StaxParser(parserHandler, false); - for (File report : reports) { - LOG.info("Processing report '{}'", report); - try { - parser.parse(transformReport(report)); - } catch (EmptyReportException e) { - LOG.warn("The report '{}' seems to be empty, ignoring.", report); - } - } + XunitReportParser parserHandler = parseReport(reports); List testcases = parserHandler.getTestCases(); LOG.info("Parsing 'xUnit' format"); @@ -125,10 +116,29 @@ public void execute(SensorContext context) { } } - private void simpleMode(final SensorContext context, List testcases) - throws javax.xml.stream.XMLStreamException, - java.io.IOException, - javax.xml.transform.TransformerException { + /** + * @param reports + * @return + * @throws XMLStreamException + * @throws IOException + * @throws TransformerException + */ + private XunitReportParser parseReport(List reports) + throws XMLStreamException, IOException, TransformerException { + XunitReportParser parserHandler = new XunitReportParser(); + StaxParser parser = new StaxParser(parserHandler, false); + for (File report : reports) { + LOG.info("Processing report '{}'", report); + try { + parser.parse(transformReport(report)); + } catch (EmptyReportException e) { //NOSONAR + LOG.warn("The report '{}' seems to be empty, ignoring.", report); + } + } + return parserHandler; + } + + private void simpleMode(final SensorContext context, List testcases) { int testsCount = 0; int testsSkipped = 0; @@ -149,7 +159,7 @@ private void simpleMode(final SensorContext context, List testcases) testsCount -= testsSkipped; if (testsCount > 0) { - double testsPassed = testsCount - testsErrors - testsFailures; + double testsPassed = (double) testsCount - testsErrors - testsFailures; double successDensity = testsPassed * PERCENT_BASE / testsCount; try @@ -159,8 +169,8 @@ private void simpleMode(final SensorContext context, List testcases) .on(context.module()) .withValue(testsCount) .save(); - } catch(Exception ex) { - LOG.error("Cannot save measure TESTS : '{}', ignoring measure", ex.getMessage()); + } catch(Exception ex) { //NOSONAR + LOG.error("Cannot save measure TESTS : '{}', ignoring measure", ex); CxxUtils.validateRecovery(ex, this.language); } @@ -171,8 +181,8 @@ private void simpleMode(final SensorContext context, List testcases) .on(context.module()) .withValue(testsErrors) .save(); - } catch(Exception ex) { - LOG.error("Cannot save measure TEST_ERRORS : '{}', ignoring measure", ex.getMessage()); + } catch(Exception ex) { //NOSONAR + LOG.error("Cannot save measure TEST_ERRORS : '{}', ignoring measure", ex); CxxUtils.validateRecovery(ex, this.language); } @@ -183,8 +193,8 @@ private void simpleMode(final SensorContext context, List testcases) .on(context.module()) .withValue(testsFailures) .save(); - } catch(Exception ex) { - LOG.error("Cannot save measure TEST_FAILURES : '{}', ignoring measure", ex.getMessage()); + } catch(Exception ex) { //NOSONAR + LOG.error("Cannot save measure TEST_FAILURES : '{}', ignoring measure", ex); CxxUtils.validateRecovery(ex, this.language); } @@ -195,8 +205,8 @@ private void simpleMode(final SensorContext context, List testcases) .on(context.module()) .withValue(testsSkipped) .save(); - } catch(Exception ex) { - LOG.error("Cannot save measure SKIPPED_TESTS : '{}', ignoring measure", ex.getMessage()); + } catch(Exception ex) { //NOSONAR + LOG.error("Cannot save measure SKIPPED_TESTS : '{}', ignoring measure", ex); CxxUtils.validateRecovery(ex, this.language); } @@ -207,8 +217,8 @@ private void simpleMode(final SensorContext context, List testcases) .on(context.module()) .withValue(ParsingUtils.scaleValue(successDensity)) .save(); - } catch(Exception ex) { - LOG.error("Cannot save measure TEST_SUCCESS_DENSITY : '{}', ignoring measure", ex.getMessage()); + } catch(Exception ex) { //NOSONAR + LOG.error("Cannot save measure TEST_SUCCESS_DENSITY : '{}', ignoring measure", ex); CxxUtils.validateRecovery(ex, this.language); } @@ -219,8 +229,8 @@ private void simpleMode(final SensorContext context, List testcases) .on(context.module()) .withValue(testsTime) .save(); - } catch(Exception ex) { - LOG.error("Cannot save measure TEST_EXECUTION_TIME : '{}', ignoring measure", ex.getMessage()); + } catch(Exception ex) { //NOSONAR + LOG.error("Cannot save measure TEST_EXECUTION_TIME : '{}', ignoring measure", ex); CxxUtils.validateRecovery(ex, this.language); } } else { 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 61c9bd55a5..a468d0e275 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 @@ -55,8 +55,8 @@ public void stream(SMHierarchicCursor rootCursor) throws XMLStreamException { SMInputCursor testSuiteCursor = rootCursor.constructDescendantCursor(new ElementFilter("testsuite")); try { testSuiteCursor.getNext(); - } catch (com.ctc.wstx.exc.WstxEOFException eofExc) { - throw new EmptyReportException(); + } catch (com.ctc.wstx.exc.WstxEOFException eofExc) { //NOSONAR + throw new EmptyReportException(); //NOSONAR } do { @@ -89,17 +89,18 @@ private TestCase parseTestCaseTag(SMInputCursor testCaseCursor, String tsName, S String status = "ok"; String stack = ""; String msg = ""; + final String SKIPPED_STATUS = "skipped"; // Googletest-reports mark the skipped tests with status="notrun" String statusattr = testCaseCursor.getAttrValue("status"); if ("notrun".equals(statusattr)) { - status = "skipped"; + status = SKIPPED_STATUS; } else { SMInputCursor childCursor = testCaseCursor.childElementCursor(); if (childCursor.getNext() != null) { String elementName = childCursor.getLocalName(); - if ("skipped".equals(elementName)) { - status = "skipped"; + if (SKIPPED_STATUS.equals(elementName)) { + status = SKIPPED_STATUS; } else if ("failure".equals(elementName)) { status = "failure"; msg = childCursor.getAttrValue("message"); 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 c5bc3eab7d..50d4b486b6 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 @@ -19,10 +19,14 @@ */ package org.sonar.cxx.sensors.utils; +import java.io.BufferedReader; import java.io.File; -import java.io.FileReader; +import java.io.FileInputStream; import java.io.InputStream; +import java.io.InputStreamReader; import java.io.StringReader; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; import org.apache.commons.io.FileUtils; @@ -39,7 +43,7 @@ */ public abstract class CxxAbstractRuleRepository implements RulesDefinition { - public static final Logger LOG = Loggers.get(CxxAbstractRuleRepository.class); + private static final Logger LOG = Loggers.get(CxxAbstractRuleRepository.class); private final ServerFileSystem fileSystem; private final RulesDefinitionXmlLoader xmlRuleLoader; @@ -68,18 +72,20 @@ public CxxAbstractRuleRepository( @Override public void define(Context context) { + Charset charset = StandardCharsets.UTF_8; NewRepository repository = context.createRepository(repositoryKey, this.language.getKey()).setName(repositoryName); RulesDefinitionXmlLoader xmlLoader = new RulesDefinitionXmlLoader(); if (!"".equals(fileName())) { InputStream xmlStream = getClass().getResourceAsStream(fileName()); - xmlLoader.load(repository, xmlStream, "UTF-8"); + xmlLoader.load(repository, xmlStream, charset); for (File userExtensionXml : getExtensions(repositoryKey, "xml")) { - try { - FileReader reader = new FileReader(userExtensionXml); + try (FileInputStream input = new FileInputStream(userExtensionXml)) { + + BufferedReader reader = new BufferedReader(new InputStreamReader(input, charset)); xmlRuleLoader.load(repository, reader); - } catch (Exception ex) { + } catch (Exception ex) { //NOSONAR LOG.info("Cannot Load XML '{}'", ex); } } 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 61722c6271..2be581e8d9 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 @@ -227,7 +227,7 @@ private void saveViolation(SensorContext sensorContext, String ruleRepoKey, Stri newIssue.at(location); newIssue.save(); violationsCount++; - } catch (Exception ex) { + } catch (Exception ex) { //NOSONAR LOG.error("Could not add the issue '{}', skipping issue", ex.getMessage()); CxxUtils.validateRecovery(ex, this.language); } @@ -246,7 +246,7 @@ private void saveViolation(SensorContext sensorContext, String ruleRepoKey, Stri newIssue.at(location); newIssue.save(); violationsCount++; - } catch (Exception ex) { + } catch (Exception ex) { //NOSONAR LOG.error("Could not add the issue '{}', skipping issue", ex.getMessage()); CxxUtils.validateRecovery(ex, this.language); } @@ -273,7 +273,7 @@ private int getLineAsInt(String line, int maxLine) { } protected void processReport(final SensorContext context, File report) - throws Exception { + throws Exception { //NOSONAR } abstract protected String reportPathKey(); 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 b6c990eb4d..b74f07e876 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 @@ -52,7 +52,7 @@ public static String normalizePath(String filename) { try { return new File(filename).getCanonicalPath(); } catch (java.io.IOException e) { - LOG.error("path normalizing of '{}' failed: '{}'", filename, e.toString()); + LOG.error("path normalizing of '{}' failed: '{}'", filename, e); return null; } } 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 b7bf5936e2..2540d42040 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,7 @@ public class JsonCompilationDatabase { public static final Logger LOG = Loggers.get(JsonCompilationDatabase.class); - public JsonCompilationDatabase(CxxConfiguration config, File compileCommandsFile) - throws IOException, JsonParseException, JsonMappingException { + public JsonCompilationDatabase(CxxConfiguration config, File compileCommandsFile) throws IOException { LOG.debug("Parsing 'JSON Compilation Database' format"); ObjectMapper mapper = new ObjectMapper(); @@ -63,7 +62,7 @@ public JsonCompilationDatabase(CxxConfiguration config, File compileCommandsFile } absPath = cwd.resolve(commandObject.file); - if (commandObject.file.equals("__global__")) { + if ("__global__".equals(commandObject.file)) { CxxCompilationUnitSettings globalSettings = new CxxCompilationUnitSettings(); parseCommandObject(globalSettings, commandObject); @@ -88,7 +87,7 @@ private void parseCommandObject(CxxCompilationUnitSettings settings, if (commandObject.defines != null || commandObject.includes != null) return; - String cmdLine = null; + String cmdLine; if (commandObject.arguments != null) cmdLine = commandObject.arguments; @@ -100,15 +99,15 @@ else if (commandObject.command != null) String[] args = tokenizeCommandLine(cmdLine); boolean nextInclude = false; boolean nextDefine = false; - List includes = new ArrayList(); - HashMap defines = new HashMap(); + List includes = new ArrayList<>(); + HashMap defines = new HashMap<>(); // Capture defines and includes from command line for (String arg : args) { - if (nextInclude == true) { + if (nextInclude) { nextInclude = false; includes.add(arg); - } else if (nextDefine == true) { + } else if (nextDefine) { nextDefine = false; String[] define = arg.split("=", 2); if (define.length == 1) { @@ -116,11 +115,11 @@ else if (commandObject.command != null) } else { defines.put(define[0], define[1]); } - } else if (arg.equals("-I")) { + } else if ("-I".equals(arg)) { nextInclude = true; } else if (arg.startsWith("-I")) { includes.add(arg.substring(2)); - } else if (arg.equals("-D")) { + } else if ("-D".equals(arg)) { nextDefine = true; } else if (arg.startsWith("-D")) { String[] define = arg.substring(2).split("=", 2); @@ -137,10 +136,10 @@ else if (commandObject.command != null) } private String[] tokenizeCommandLine(String cmdLine) { - List args = new ArrayList(); + List args = new ArrayList<>(); boolean escape = false; char stringOpen = 0; - StringBuffer sb = new StringBuffer(); + StringBuilder sb = new StringBuilder(); // Tokenize command line with support for escaping for (char ch : cmdLine.toCharArray()) { @@ -156,13 +155,11 @@ else if (ch == '\'') stringOpen = '\''; else if (ch == '\"') stringOpen = '\"'; - else if (ch == ' ') { - if (sb.length() > 0) { + else if ((ch == ' ') + && (sb.length() > 0)) { args.add(sb.toString()); - sb = new StringBuffer(); + sb = new StringBuilder(); } - } - if (ch != ' ') sb.append(ch); } else { 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 416126fa10..d05e3a706a 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 @@ -40,7 +40,7 @@ public class CxxVeraxxSensor extends CxxReportSensor { public static final Logger LOG = Loggers.get(CxxVeraxxSensor.class); public static final String REPORT_PATH_KEY = "vera.reportPath"; - public static String KEY = "Vera++"; + public static final String KEY = "Vera++"; /** * {@inheritDoc} @@ -72,8 +72,8 @@ protected void processReport(final SensorContext context, File report) public void stream(SMHierarchicCursor rootCursor) throws javax.xml.stream.XMLStreamException { try { rootCursor.advance(); - } catch (com.ctc.wstx.exc.WstxEOFException eofExc) { - throw new EmptyReportException(); + } catch (com.ctc.wstx.exc.WstxEOFException eofExc) { //NOSONAR + throw new EmptyReportException(); //NOSONAR } SMInputCursor fileCursor = rootCursor.childElementCursor("file"); diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/visitors/CxxCpdVisitor.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/visitors/CxxCpdVisitor.java index 2e70bc3e4f..7cd979332a 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/visitors/CxxCpdVisitor.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/visitors/CxxCpdVisitor.java @@ -103,7 +103,7 @@ public void visitToken(Token token) { try { TextRange range = inputFile.newRange(token.getLine(), token.getColumn(), token.getLine(), token.getColumn() + token.getValue().length()); cpdTokens.addToken(range, text); - } catch (Exception e) { + } catch (IllegalArgumentException e) { //NOSONAR // ignore range errors: parsing errors could lead to wrong location data LOG.debug("CPD error in file '{}' at line:{}, column:{}", getContext().getFile().getAbsoluteFile(), token.getLine(), token.getColumn()); } 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 46698c0c3b..bacc82e7dc 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 @@ -44,7 +44,7 @@ public class CxxHighlighterVisitor extends SquidAstVisitor implements A private NewHighlighting newHighlighting; private final SensorContext context; - private class TokenLocation { + private static class TokenLocation { protected int startLine; protected int startLineOffset; @@ -74,7 +74,7 @@ public int endLineOffset() { return endLineOffset; } - public boolean overlaps(TokenLocation other) { + public boolean overlaps(@Nullable TokenLocation other) { if (other != null) { return !(startLineOffset() > other.endLineOffset() || other.startLineOffset() > endLineOffset() @@ -86,7 +86,7 @@ public boolean overlaps(TokenLocation other) { } - private class CommentLocation extends TokenLocation { + private static class CommentLocation extends TokenLocation { public CommentLocation(Token token) { super(token); @@ -122,15 +122,17 @@ public CxxHighlighterVisitor(SensorContext context) { public void visitFile(@Nullable AstNode astNode) { newHighlighting = context.newHighlighting(); InputFile inputFile = context.fileSystem().inputFile(context.fileSystem().predicates().is(getContext().getFile().getAbsoluteFile())); + if (inputFile != null) { newHighlighting.onFile(inputFile); } + } @Override public void leaveFile(@Nullable AstNode astNode) { try { newHighlighting.save(); } catch (IllegalStateException e) { - // ignore hightlight errors: parsing errors could lead to wrong loacation data + // ignore highlight errors: parsing errors could lead to wrong location data LOG.debug("Highligthing error in file: {}, error: {}", getContext().getFile().getAbsoluteFile(), e); } } @@ -150,22 +152,21 @@ public void visitToken(Token token) { for (Trivia trivia : token.getTrivia()) { if (trivia.isComment()) { highlight(last, new CommentLocation(trivia.getToken()), TypeOfText.COMMENT); - } else if (trivia.isSkippedText()) { - if (trivia.getToken().getType() == CxxTokenType.PREPROCESSOR) { + } else if (trivia.isSkippedText() + && trivia.getToken().getType().equals(CxxTokenType.PREPROCESSOR)) { highlight(last, new PreprocessorDirectiveLocation(trivia.getToken()), TypeOfText.PREPROCESS_DIRECTIVE); } } } } - } private TokenLocation highlight(TokenLocation last, TokenLocation current, TypeOfText typeOfText) { try { if (!current.overlaps(last)) { newHighlighting.highlight(current.startLine(), current.startLineOffset(), current.endLine(), current.endLineOffset(), typeOfText); } - } catch (Exception e) { - // ignore hightlight errors: parsing errors could lead to wrong loacation data + } catch (Exception e) { //NOSONAR + // ignore highlight errors: parsing errors could lead to wrong location data LOG.debug("Highligthing error in file '{}' at line:{}, column:{}", getContext().getFile().getAbsoluteFile(), current.startLine(), current.startLineOffset()); } return current; diff --git a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/drmemory/DrMemoryParserTest.java b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/drmemory/DrMemoryParserTest.java index 40f096bfee..bab25e73e9 100644 --- a/cxx-sensors/src/test/java/org/sonar/cxx/sensors/drmemory/DrMemoryParserTest.java +++ b/cxx-sensors/src/test/java/org/sonar/cxx/sensors/drmemory/DrMemoryParserTest.java @@ -21,6 +21,7 @@ import java.io.File; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.util.List; import org.junit.Assert; @@ -33,7 +34,7 @@ public class DrMemoryParserTest { public void shouldParseTheWholeFile() throws IOException { ClassLoader classLoader = getClass().getClassLoader(); File file = new File(classLoader.getResource("org/sonar/cxx/sensors/reports-project/drmemory-reports/results.txt").getFile()); - List drMemoryErrors = DrMemoryParser.parse(file); + List drMemoryErrors = DrMemoryParser.parse(file, StandardCharsets.UTF_8.name()); Assert.assertEquals(733, drMemoryErrors.size()); } } From b416d6c9423a1c0aec84f1fd43fd474e6570a9cd Mon Sep 17 00:00:00 2001 From: Bert Date: Thu, 20 Apr 2017 20:00:20 +0200 Subject: [PATCH 6/6] final fixes --- .../org/sonar/cxx/sensors/utils/CxxUtils.java | 1 - pom.xml | 46 +++++++++++++++++++ .../java/org/sonar/plugins/c/CLanguage.java | 27 +++++++++++ .../org/sonar/plugins/cxx/CppLanguage.java | 30 +++++++++++- 4 files changed, 102 insertions(+), 2 deletions(-) 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 b74f07e876..dd9ad3f2ae 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 @@ -22,7 +22,6 @@ import java.io.File; import java.io.PrintWriter; import java.io.StringWriter; -import org.sonar.api.config.Settings; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.cxx.CxxLanguage; diff --git a/pom.xml b/pom.xml index a76684fce4..39918e2894 100644 --- a/pom.xml +++ b/pom.xml @@ -330,6 +330,11 @@ license-maven-plugin 3.0 + + org.sonarsource.scanner.maven + sonar-maven-plugin + 3.2 + @@ -341,4 +346,45 @@ + + + + coverage-per-test + + + + org.apache.maven.plugins + maven-surefire-plugin + + 2.13 + + + + listener + org.sonar.java.jacoco.JUnitListener + + + + + + + + + + org.codehaus.sonar-plugins.java + sonar-jacoco-listeners + 1.2 + test + + + + 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 0b9c6e2981..93b992a440 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 @@ -23,6 +23,8 @@ import java.util.Arrays; import java.util.List; import org.sonar.api.config.Settings; +import org.sonar.api.internal.apachecommons.lang.builder.HashCodeBuilder; +import org.sonar.api.resources.AbstractLanguage; import org.sonar.cxx.CxxLanguage; import org.sonar.cxx.checks.BooleanEqualityComparisonCheck; import org.sonar.cxx.checks.ClassComplexityCheck; @@ -97,6 +99,31 @@ public CLanguage(Settings settings) { fileSuffixes = mergeArrays(sourceSuffixes, headerSuffixes); } + @Override + public int hashCode() { + return new HashCodeBuilder(17, 31). // two randomly chosen prime numbers + appendSuper(super.hashCode()). + append(getKey()). + toHashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + + if (obj == null) { + return false; + } + + if (this.getClass() == obj.getClass()) { + return getKey().equals(((CxxLanguage) obj).getKey()); + } else { + return false; + } + } + @Override public String[] getFileSuffixes() { return fileSuffixes; 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 f33d19e78f..941e89cc98 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 @@ -23,6 +23,8 @@ import java.util.Arrays; import java.util.List; import org.sonar.api.config.Settings; +import org.sonar.api.internal.apachecommons.lang.builder.HashCodeBuilder; +import org.sonar.api.resources.AbstractLanguage; import org.sonar.cxx.CxxLanguage; import org.sonar.cxx.checks.BooleanEqualityComparisonCheck; import org.sonar.cxx.checks.ClassComplexityCheck; @@ -97,6 +99,32 @@ public CppLanguage(Settings settings) { fileSuffixes = mergeArrays(sourceSuffixes, headerSuffixes); } + @Override + public int hashCode() { + // two randomly chosen prime numbers + return new HashCodeBuilder(17, 31). + appendSuper(super.hashCode()). + append(getKey()). + toHashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + + if (obj == null) { + return false; + } + + if (this.getClass() == obj.getClass()) { + return getKey().equals(((CxxLanguage) obj).getKey()); + } else { + return false; + } + } + @Override public String[] getFileSuffixes() { return fileSuffixes; @@ -113,7 +141,7 @@ public String[] getHeaderFileSuffixes() { } public List getChecks() { - return new ArrayList(Arrays.asList( + return new ArrayList<>(Arrays.asList( CollapsibleIfCandidateCheck.class, CommentedCodeCheck.class, CommentRegularExpressionCheck.class,