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 e15971d854..9755800197 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 @@ -71,6 +71,7 @@ public String getRegularExpression() { return regularExpression; } + @SuppressWarnings("squid:S2696") // ... initialize SquidAstVisitor @Override public void init() { String regEx = getRegularExpression(); 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 d48d9aa848..171c791e43 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 @@ -66,6 +66,7 @@ public String getRegularExpression() { return regularExpression; } + @SuppressWarnings("squid:S2696") // ... initialize SquidAstVisitor @Override public void init() { String regEx = getRegularExpression(); diff --git a/cxx-lint/src/test/java/org/codehaus/sonarplugins/cxx/cxxlint/CxxLintTest.java b/cxx-lint/src/test/java/org/codehaus/sonarplugins/cxx/cxxlint/CxxLintTest.java index d55e040401..0886e2e037 100644 --- a/cxx-lint/src/test/java/org/codehaus/sonarplugins/cxx/cxxlint/CxxLintTest.java +++ b/cxx-lint/src/test/java/org/codehaus/sonarplugins/cxx/cxxlint/CxxLintTest.java @@ -20,7 +20,8 @@ package org.codehaus.sonarplugins.cxx.cxxlint; import java.io.File; -import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; + import org.junit.Test; import org.sonar.cxx.cxxlint.CxxLint; @@ -29,7 +30,6 @@ * @author jocs */ public class CxxLintTest { -// private static final Logger LOG = Loggers.get(CxxLintTest.class); /** * Test of main method, of class CxxLint. @@ -43,7 +43,7 @@ public void runsToolWithoutSettingsWithoutExceptions() { args[0] = "-f"; args[1] = fileToAnalyse.getAbsolutePath(); CxxLint.main(args); - assertThat(true); + assertThatCode(() -> CxxLint.main(args)).doesNotThrowAnyException(); } /** @@ -61,12 +61,7 @@ public void runsToolWithSettingsWithoutExceptions() { args[2] = "-s"; args[3] = settingsFile.getAbsolutePath(); -// try { CxxLint.main(args); - assertThat(true); -// } catch (Exception ex) { -// LOG.info("Exception Found: " + ex); -// assertThat(false); -// } + assertThatCode(() -> CxxLint.main(args)).doesNotThrowAnyException(); } } 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 826102f9da..9e5ea33883 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 @@ -34,7 +34,7 @@ public class CxxCompilerGccParser implements CompilerParser { private static final Logger LOG = Loggers.get(CxxCompilerGccParser.class); - public static final String KEY = "GCC"; + public static final String KEY_GCC = "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]+:\\x20warning:\\x20(.*)\\x20\\[(.*)\\]$"; // 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 CxxCompilerGccParser implements CompilerParser { */ @Override public String key() { - return KEY; + return KEY_GCC; } /** @@ -79,7 +79,7 @@ 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", KEY_GCC); Scanner scanner = new Scanner(report, charset); Pattern p = Pattern.compile(reportRegEx, Pattern.MULTILINE); 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 e2c6a32b75..dd2d617b52 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 @@ -45,7 +45,7 @@ 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.KEY_VC; public static final String DEFAULT_CHARSET_DEF = "UTF-8"; public static final String KEY = "Compiler"; 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 511dbe3aab..f691a12c8d 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 { private static final Logger LOG = Loggers.get(CxxCompilerVcParser.class); - public static final String KEY = "Visual C++"; + public static final String KEY_VC = "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+):(.*)$"; // sample regex for VS2012/2013: "^.*>(?.*)\\((?\\d+)\\):\\x20warning\\x20(?C\\d+):(?.*)$"; @@ -46,7 +46,7 @@ public class CxxCompilerVcParser implements CompilerParser { */ @Override public String key() { - return KEY; + return KEY_VC; } /** diff --git a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/visitors/CxxFileLinesVisitor.java b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/visitors/CxxFileLinesVisitor.java index ebaec34c8a..6f96168794 100644 --- a/cxx-sensors/src/main/java/org/sonar/cxx/sensors/visitors/CxxFileLinesVisitor.java +++ b/cxx-sensors/src/main/java/org/sonar/cxx/sensors/visitors/CxxFileLinesVisitor.java @@ -77,9 +77,10 @@ public class CxxFileLinesVisitor extends SquidAstVisitor implements Ast * @param context for coverage analysis * @param fileLinesContextFactory container for linesOfCode, linesOfComments, executableLines * @param allLinesOfCode set of lines for a source file + * @param language properties */ - public CxxFileLinesVisitor(CxxLanguage language, FileLinesContextFactory fileLinesContextFactory, SensorContext context, - Map> allLinesOfCode) { + public CxxFileLinesVisitor(CxxLanguage language, FileLinesContextFactory fileLinesContextFactory, + SensorContext context, Map> allLinesOfCode) { this.language = language; this.fileLinesContextFactory = fileLinesContextFactory; this.fileSystem = context.fileSystem(); @@ -117,7 +118,7 @@ public void visitNode(AstNode astNode) { switch ((CxxGrammarImpl) astNode.getType()) { case functionDefinition: if (!isDefaultOrDeleteFunctionBody(astNode)) { - isWithinFunctionDefinition++; + increaseFunctionDefinition(); } break; case labeledStatement: @@ -133,6 +134,7 @@ public void visitNode(AstNode astNode) { } } + /** * @param astNode */ @@ -150,10 +152,24 @@ private static void visitStatement(AstNode astNode) { @Override public void leaveNode(AstNode astNode) { if (!isDefaultOrDeleteFunctionBody(astNode)) { - isWithinFunctionDefinition--; + decreaseFunctionDefinitions(); } } + /** + * + */ + private static void increaseFunctionDefinition() { + isWithinFunctionDefinition++; + } + + /** + * + */ + private static void decreaseFunctionDefinitions() { + isWithinFunctionDefinition--; + } + private static boolean isDefaultOrDeleteFunctionBody(AstNode astNode) { AstNode node = astNode.getFirstChild(CxxGrammarImpl.functionBody); if ((node != null)) { 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 0557294a77..6ef7699ba1 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 @@ -60,7 +60,7 @@ public void shouldReportCorrectGccViolations() { SensorContextTester context = SensorContextTester.create(fs.baseDir()); settings.setProperty(language.getPluginProperty(CxxCompilerSensor.REPORT_PATH_KEY), "compiler-reports/build.gcclog"); - settings.setProperty(language.getPluginProperty(CxxCompilerSensor.PARSER_KEY_DEF), CxxCompilerGccParser.KEY); + settings.setProperty(language.getPluginProperty(CxxCompilerSensor.PARSER_KEY_DEF), CxxCompilerGccParser.KEY_GCC); context.setSettings(settings); context.fileSystem().add(TestInputFileBuilder.create("ProjectKey", "src/zipmanager.cpp") @@ -76,7 +76,7 @@ public void shouldReportACorrectVcViolations() { SensorContextTester context = SensorContextTester.create(fs.baseDir()); settings.setProperty(language.getPluginProperty(CxxCompilerSensor.REPORT_PATH_KEY), "compiler-reports/BuildLog.htm"); - settings.setProperty(language.getPluginProperty(CxxCompilerSensor.PARSER_KEY_DEF), CxxCompilerVcParser.KEY); + settings.setProperty(language.getPluginProperty(CxxCompilerSensor.PARSER_KEY_DEF), CxxCompilerVcParser.KEY_VC); settings.setProperty(language.getPluginProperty(CxxCompilerSensor.REPORT_CHARSET_DEF), "UTF-16"); context.setSettings(settings); @@ -94,7 +94,7 @@ public void shouldReportBCorrectVcViolations() { SensorContextTester context = SensorContextTester.create(fs.baseDir()); settings.setProperty(language.getPluginProperty(CxxCompilerSensor.REPORT_PATH_KEY), "compiler-reports/VC-report.vclog"); - settings.setProperty(language.getPluginProperty(CxxCompilerSensor.PARSER_KEY_DEF), CxxCompilerVcParser.KEY); + settings.setProperty(language.getPluginProperty(CxxCompilerSensor.PARSER_KEY_DEF), CxxCompilerVcParser.KEY_VC); settings.setProperty(language.getPluginProperty(CxxCompilerSensor.REPORT_CHARSET_DEF), "UTF-8"); settings.setProperty(language.getPluginProperty(CxxCompilerSensor.REPORT_REGEX_DEF), "^.*>(?.*)\\((?\\d+)\\):\\x20warning\\x20(?C\\d+):(?.*)$"); context.setSettings(settings); @@ -112,7 +112,7 @@ public void shouldReportCorrectVcViolations() { SensorContextTester context = SensorContextTester.create(fs.baseDir()); settings.setProperty(language.getPluginProperty(CxxCompilerSensor.REPORT_PATH_KEY), "compiler-reports/VC-report.vclog"); - settings.setProperty(language.getPluginProperty(CxxCompilerSensor.PARSER_KEY_DEF), CxxCompilerVcParser.KEY); + settings.setProperty(language.getPluginProperty(CxxCompilerSensor.PARSER_KEY_DEF), CxxCompilerVcParser.KEY_VC); settings.setProperty(language.getPluginProperty(CxxCompilerSensor.REPORT_CHARSET_DEF), "UTF-8"); settings.setProperty(language.getPluginProperty(CxxCompilerSensor.REPORT_REGEX_DEF), "^(.*)\\((\\d+)\\):\\x20warning\\x20(C\\d+):(.*)$"); context.setSettings(settings); diff --git a/cxx-squid/src/test/java/org/sonar/cxx/parser/CxxParserTest.java b/cxx-squid/src/test/java/org/sonar/cxx/parser/CxxParserTest.java index 4bdc930637..c62cbca7dc 100644 --- a/cxx-squid/src/test/java/org/sonar/cxx/parser/CxxParserTest.java +++ b/cxx-squid/src/test/java/org/sonar/cxx/parser/CxxParserTest.java @@ -19,20 +19,25 @@ */ package org.sonar.cxx.parser; +import com.sonar.sslr.api.AstNode; import com.sonar.sslr.api.Grammar; import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.HashMap; import java.util.List; import org.apache.commons.io.FileUtils; -import static org.junit.Assert.fail; + import org.junit.Test; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; + import org.sonar.cxx.CxxConfiguration; import org.sonar.cxx.CxxFileTesterHelper; import org.sonar.squidbridge.SquidAstVisitorContext; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; public class CxxParserTest extends ParserBaseTestHelper { @@ -54,12 +59,37 @@ public CxxParserTest() { @Test public void testParsingOnDiverseSourceFiles() { Collection files = listFiles(goodFiles, new String[]{"cc", "cpp", "hpp"}); + HashMap map = new HashMap() { + private static final long serialVersionUID = 6029310517902718597L; + { + put("ignore.hpp", 2); + put("ignore1.cpp", 2); + put("ignoreparam.hpp", 4); + put("ignoreparam1.cpp", 2); + put("inbuf1.cpp", 2); + put("io1.cpp", 3); + put("outbuf1.cpp", 2); + put("outbuf1.hpp", 2); + put("outbuf1x.cpp", 2); + put("outbuf1x.hpp", 4); + put("outbuf2.cpp", 2); + put("outbuf2.hpp", 3); + put("outbuf3.cpp", 2); + put("outbuf3.hpp", 2); + put("outbuf2.cpp", 2); + }}; for (File file : files) { - p.parse(file); + AstNode root = p.parse(file); CxxParser.finishedParsing(file); + if (map.containsKey(file.getName())) { + assertThat(root.getNumberOfChildren()).as("check number of nodes for file %s",file.getName()).isEqualTo(map.get(file.getName())); + } else { + assertThat(root.hasChildren()).isTrue(); + } } } + @SuppressWarnings("unchecked") @Test public void testPreproccessorParsingOnDiverseSourceFiles() { conf = new CxxConfiguration(); @@ -78,16 +108,32 @@ public void testPreproccessorParsingOnDiverseSourceFiles() { "resources", "resources\\parser\\preprocessor") ); + + HashMap map = new HashMap() { + private static final long serialVersionUID = 1433381506274827684L; + { + put("variadic_macros.cpp", 2); + put("apply_wrap.hpp", 1); + put("boost_macros_short.hpp", 1); + put("boost_macros.hpp", 1); + }}; + p = CxxParser.create(mock(SquidAstVisitorContext.class), conf, CxxFileTesterHelper.mockCxxLanguage()); Collection files = listFiles(preprocessorFiles, new String[]{"cc", "cpp", "hpp", "h"}); for (File file : files) { - p.parse(file); + AstNode root = p.parse(file); CxxParser.finishedParsing(file); + if (map.containsKey(file.getName())) { + assertThat(root.getNumberOfChildren()).as("check number of nodes for file %s",file.getName()).isEqualTo(map.get(file.getName())); + } else { + assertThat(root.hasChildren()).isTrue(); + } } } + @SuppressWarnings("unchecked") @Test - public void testParsingInCCompatMode() { + public void testParsingInCCompatMode() { //ToDo: Fix this compatibility test - currently it is useless // The C-compatibility replaces c++ keywords, which aren't keywords in C, // with non-keyword-strings via the preprocessor. // This mode works if such a file causes parsing errors when the mode @@ -101,30 +147,33 @@ public void testParsingInCCompatMode() { conf.setCFilesPatterns(new String[]{""}); p = CxxParser.create(context, conf, CxxFileTesterHelper.mockCxxLanguage()); try { - p.parse(cfile); + AstNode root = p.parse(cfile); + assertThat(root.getNumberOfChildren()).isEqualTo(2); } catch (com.sonar.sslr.api.RecognitionException re) { } conf.setCFilesPatterns(new String[]{"*.c"}); p = CxxParser.create(context, conf, CxxFileTesterHelper.mockCxxLanguage()); - p.parse(cfile); + AstNode root = p.parse(cfile); + assertThat(root.getNumberOfChildren()).isEqualTo(2); } @Test - public void testParseErrorRecovery() { + public void testParseErrorRecoveryDisabled() { // The error recovery works, if: // - a syntacticly incorrect file causes a parse error when recovery is disabled - // - but doesn't cause such an error if we run with default settings - - try { - p.parse(erroneousSources); - fail("Parser could not recognize the syntax error"); - } catch (com.sonar.sslr.api.RecognitionException re) { - } + assertThatThrownBy(() -> {p.parse(erroneousSources);}).isInstanceOf(com.sonar.sslr.api.RecognitionException.class); + } + @SuppressWarnings("unchecked") + @Test + public void testParseErrorRecoveryEnabled() { + // The error recovery works, if: + // - but doesn't cause such an error if we run with default settings conf.setErrorRecoveryEnabled(true); p = CxxParser.create(mock(SquidAstVisitorContext.class), conf, CxxFileTesterHelper.mockCxxLanguage()); - p.parse(erroneousSources); //<-- this shouldn't throw now + AstNode root = p.parse(erroneousSources); //<-- this shouldn't throw now + assertThat(root.getNumberOfChildren()).isEqualTo(6); } private Collection listFiles(String[] dirs, String[] extensions) { diff --git a/pom.xml b/pom.xml index 67430485dd..d56986adb8 100644 --- a/pom.xml +++ b/pom.xml @@ -294,7 +294,7 @@ org.assertj assertj-core - 3.6.1 + 3.9.0 org.mockito 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 c35e64e28e..3920f120cc 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 @@ -354,7 +354,7 @@ private static List compilerWarningsProperties() { .defaultValue(CxxCompilerSensor.DEFAULT_PARSER_DEF) .name("Format") .type(PropertyType.SINGLE_SELECT_LIST) - .options(CxxCompilerVcParser.KEY, CxxCompilerGccParser.KEY) + .options(CxxCompilerVcParser.KEY_VC, CxxCompilerGccParser.KEY_GCC) .description("The format of the warnings file. Currently supported are Visual C++ and GCC.") .subCategory(subcateg) .onQualifiers(Qualifiers.PROJECT, Qualifiers.MODULE) 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 4265db188b..35ee9a9624 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 @@ -359,7 +359,7 @@ private static List compilerWarningsProperties() { .defaultValue(CxxCompilerSensor.DEFAULT_PARSER_DEF) .name("Format") .type(PropertyType.SINGLE_SELECT_LIST) - .options(CxxCompilerVcParser.KEY, CxxCompilerGccParser.KEY) + .options(CxxCompilerVcParser.KEY_VC, CxxCompilerGccParser.KEY_GCC) .description("The format of the warnings file. Currently supported are Visual C++ and GCC.") .subCategory(subcateg) .onQualifiers(Qualifiers.PROJECT, Qualifiers.MODULE)