matcher) {
+ checkStateOfCurrent();
+ String actual = current.getText(Locale.ENGLISH);
+ assertThat(actual, matcher);
+ return this;
+ }
+
+ /**
+ * @since sslr-squid-bridge 2.3
+ */
+ public CheckMessagesVerifier withCost(Double expectedCost) {
+ checkStateOfCurrent();
+ if (!Objects.equal(expectedCost, current.getCost())) {
+ throw assertionError(expectedCost, current.getCost());
+ }
+ return this;
+ }
+
+ private static AssertionError assertionError(Object expected, Object actual) {
+ return new AssertionError("\nExpected: " + expected + "\ngot: " + actual);
+ }
+
+}
diff --git a/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/checks/CheckMessagesVerifierRule.java b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/checks/CheckMessagesVerifierRule.java
new file mode 100644
index 0000000000..912bda1368
--- /dev/null
+++ b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/checks/CheckMessagesVerifierRule.java
@@ -0,0 +1,65 @@
+/*
+ * C++ Community Plugin (cxx plugin)
+ * Copyright (C) 2021 SonarOpenCommunity
+ * http://github.com/SonarOpenCommunity/sonar-cxx
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+/**
+ * fork of SSLR Squid Bridge: https://github.com/SonarSource/sslr-squid-bridge/tree/2.6.1
+ * Copyright (C) 2010 SonarSource / mailto: sonarqube@googlegroups.com / license: LGPL v3
+ */
+package org.sonar.cxx.squidbridge.checks;
+
+import com.google.common.collect.Lists;
+import java.util.Collection;
+import java.util.List;
+import org.junit.rules.Verifier;
+import org.sonar.cxx.squidbridge.api.CheckMessage;
+
+/**
+ * This JUnit Rule allows to automatically execute {@link CheckMessagesVerifier#noMore()}.
+ *
+ * @org.junit.Rule
+ * public CheckMessagesVerifierRule checkMessagesVerifier = new CheckMessagesVerifierRule();
+ *
+ * @org.junit.Test
+ * public void test() {
+ * checkMessagesVerifier.verify(messages)
+ * .next().atLine(1)
+ * .next().atLine(2);
+ * }
+ *
+ *
+ * @since sslr-squid-bridge 2.1
+ */
+public class CheckMessagesVerifierRule extends Verifier {
+
+ private final List verifiers = Lists.newArrayList();
+
+ public CheckMessagesVerifier verify(Collection messages) {
+ CheckMessagesVerifier verifier = CheckMessagesVerifier.verify(messages);
+ verifiers.add(verifier);
+ return verifier;
+ }
+
+ @Override
+ protected void verify() {
+ for (CheckMessagesVerifier verifier : verifiers) {
+ verifier.noMore();
+ }
+ }
+
+}
diff --git a/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/checks/ChecksHelper.java b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/checks/ChecksHelper.java
new file mode 100644
index 0000000000..31c720a722
--- /dev/null
+++ b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/checks/ChecksHelper.java
@@ -0,0 +1,46 @@
+/*
+ * C++ Community Plugin (cxx plugin)
+ * Copyright (C) 2021 SonarOpenCommunity
+ * http://github.com/SonarOpenCommunity/sonar-cxx
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+/**
+ * fork of SSLR Squid Bridge: https://github.com/SonarSource/sslr-squid-bridge/tree/2.6.1
+ * Copyright (C) 2010 SonarSource / mailto: sonarqube@googlegroups.com / license: LGPL v3
+ */
+package org.sonar.cxx.squidbridge.checks;
+
+import org.sonar.cxx.squidbridge.api.SourceCode;
+import org.sonar.cxx.squidbridge.measures.MetricDef;
+
+public final class ChecksHelper {
+
+ private ChecksHelper() {
+ }
+
+ public static int getRecursiveMeasureInt(SourceCode sourceCode, MetricDef metric) {
+ int childrenValue = 0;
+
+ if (sourceCode.getChildren() != null) {
+ for (SourceCode child : sourceCode.getChildren()) {
+ childrenValue += getRecursiveMeasureInt(child, metric);
+ }
+ }
+
+ return sourceCode.getInt(metric) + childrenValue;
+ }
+
+}
diff --git a/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/checks/SquidCheck.java b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/checks/SquidCheck.java
new file mode 100644
index 0000000000..f824bbdb2f
--- /dev/null
+++ b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/checks/SquidCheck.java
@@ -0,0 +1,37 @@
+/*
+ * C++ Community Plugin (cxx plugin)
+ * Copyright (C) 2021 SonarOpenCommunity
+ * http://github.com/SonarOpenCommunity/sonar-cxx
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+/**
+ * fork of SSLR Squid Bridge: https://github.com/SonarSource/sslr-squid-bridge/tree/2.6.1
+ * Copyright (C) 2010 SonarSource / mailto: sonarqube@googlegroups.com / license: LGPL v3
+ */
+package org.sonar.cxx.squidbridge.checks;
+
+import com.sonar.sslr.api.Grammar;
+import org.sonar.cxx.squidbridge.SquidAstVisitor;
+import org.sonar.cxx.squidbridge.api.CodeCheck;
+
+public abstract class SquidCheck extends SquidAstVisitor implements CodeCheck {
+
+ @Override
+ public String getKey() {
+ return null;
+ }
+
+}
diff --git a/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/checks/ViolationCounterCheck.java b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/checks/ViolationCounterCheck.java
new file mode 100644
index 0000000000..2b5cd2d030
--- /dev/null
+++ b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/checks/ViolationCounterCheck.java
@@ -0,0 +1,309 @@
+/*
+ * C++ Community Plugin (cxx plugin)
+ * Copyright (C) 2021 SonarOpenCommunity
+ * http://github.com/SonarOpenCommunity/sonar-cxx
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+/**
+ * fork of SSLR Squid Bridge: https://github.com/SonarSource/sslr-squid-bridge/tree/2.6.1
+ * Copyright (C) 2010 SonarSource / mailto: sonarqube@googlegroups.com / license: LGPL v3
+ */
+package org.sonar.cxx.squidbridge.checks;
+
+import com.google.common.base.Throwables;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import com.google.common.collect.TreeMultiset;
+import com.sonar.sslr.api.AstNode;
+import com.sonar.sslr.api.Grammar;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.StringUtils;
+import org.sonar.cxx.squidbridge.SquidAstVisitor;
+import org.sonar.cxx.squidbridge.api.CheckMessage;
+
+public class ViolationCounterCheck extends SquidAstVisitor {
+
+ private final ViolationCounter violationCounter;
+ private final String projectsDirCanonicalPath;
+
+ public static class ViolationCounter {
+
+ private final Map>> violationsByFileAndRule;
+
+ public ViolationCounter() {
+ this.violationsByFileAndRule = new HashMap>>();
+ }
+
+ private ViolationCounter(Map>> violationsByFileAndRule) {
+ this.violationsByFileAndRule = violationsByFileAndRule;
+ }
+
+ public void increment(String fileRelativePath, String rule, int line) {
+ if (!violationsByFileAndRule.containsKey(fileRelativePath)) {
+ violationsByFileAndRule.put(fileRelativePath, new HashMap>());
+ }
+ Map> violationsByRule = violationsByFileAndRule.get(fileRelativePath);
+
+ if (!violationsByRule.containsKey(rule)) {
+ violationsByRule.put(rule, TreeMultiset.create());
+ }
+ TreeMultiset violations = violationsByRule.get(rule);
+
+ violations.add(line);
+ }
+
+ public void saveToFile(String destinationFilePath) {
+ FileOutputStream fos = null;
+ ObjectOutputStream oos = null;
+ try {
+ fos = new FileOutputStream(destinationFilePath);
+ oos = new ObjectOutputStream(fos);
+ oos.writeObject(this.violationsByFileAndRule);
+ } catch (Exception e) {
+ throw Throwables.propagate(e);
+ } finally {
+ IOUtils.closeQuietly(fos);
+ IOUtils.closeQuietly(oos);
+ }
+ }
+
+ public static ViolationCounter loadFromFile(File sourceFile) {
+ if (!sourceFile.exists() || sourceFile.length() == 0) {
+ return new ViolationCounter();
+ } else {
+ FileInputStream fis = null;
+ ObjectInputStream ois = null;
+ try {
+ fis = new FileInputStream(sourceFile);
+ ois = new ObjectInputStream(fis);
+ return new ViolationCounter((Map>>) ois.readObject());
+ } catch (Exception e) {
+ throw Throwables.propagate(e);
+ } finally {
+ IOUtils.closeQuietly(fis);
+ IOUtils.closeQuietly(ois);
+ }
+ }
+ }
+ }
+
+ public static class ViolationDifferenceAnalyzer {
+
+ private final ViolationCounter expected;
+ private final ViolationCounter actual;
+ private boolean hasDifferences = false;
+
+ public ViolationDifferenceAnalyzer(ViolationCounter expected, ViolationCounter actual) {
+ this.expected = expected;
+ this.actual = actual;
+ }
+
+ private static void println() {
+ System.out.println();
+ }
+
+ private static void println(String msg) {
+ System.out.println(msg);
+ }
+
+ public void printReport() {
+ println();
+ println();
+ println("********************************");
+ println("* Violation differences report *");
+ println("********************************");
+ println();
+ println();
+ printDifferencesByFile();
+ println();
+ println();
+ printDifferencesByRule();
+ println();
+ println();
+ println("*****************");
+ println("* End of report *");
+ println("*****************");
+ println();
+ println();
+ }
+
+ private void printDifferencesByFile() {
+ println("Differences by file:");
+
+ Set> handledFilesRules = Sets.newHashSet();
+
+ for (String file : expected.violationsByFileAndRule.keySet()) {
+ boolean shouldPrintHeader = true;
+ for (String rule : expected.violationsByFileAndRule.get(file).keySet()) {
+ handledFilesRules.add(Maps.immutableEntry(file, rule));
+ shouldPrintHeader = printDifferencesByFileAndRule(shouldPrintHeader, file, rule);
+ }
+ }
+
+ for (String file : actual.violationsByFileAndRule.keySet()) {
+ boolean shouldPrintHeader = true;
+ for (String rule : actual.violationsByFileAndRule.get(file).keySet()) {
+ if (handledFilesRules.contains(Maps.immutableEntry(file, rule))) {
+ continue;
+ }
+ shouldPrintHeader = printDifferencesByFileAndRule(shouldPrintHeader, file, rule);
+ }
+ }
+
+ println("End of differences by file.");
+ }
+
+ private static void printDifferencesByFileHeader(String file) {
+ println(" File " + file + ":");
+ }
+
+ private boolean printDifferencesByFileAndRule(boolean shouldPrintHeader, String file, String rule) {
+
+ TreeMultiset linesExpected = getLines(expected, file, rule);
+ TreeMultiset linesActual = getLines(actual, file, rule);
+
+ if (!linesExpected.equals(linesActual)) {
+ hasDifferences = true;
+
+ if (shouldPrintHeader) {
+ printDifferencesByFileHeader(file);
+ }
+
+ println(" " + rule + ", (difference only) expected ("
+ + StringUtils.join(setDifference(linesExpected, linesActual), ",") + "), actual ("
+ + StringUtils.join(setDifference(linesActual, linesExpected), ",") + ").");
+
+ return false;
+ } else {
+ return shouldPrintHeader;
+ }
+
+ }
+
+ private static TreeMultiset getLines(ViolationCounter counter, String file, String rule) {
+ if (!counter.violationsByFileAndRule.containsKey(file)
+ || !counter.violationsByFileAndRule.get(file).containsKey(rule)) {
+ return TreeMultiset.create();
+ } else {
+ return counter.violationsByFileAndRule.get(file).get(rule);
+ }
+ }
+
+ private static TreeMultiset setDifference(TreeMultiset a, TreeMultiset b) {
+ TreeMultiset aMinusB = TreeMultiset.create(a);
+ aMinusB.removeAll(b);
+ return aMinusB;
+ }
+
+ private void printDifferencesByRule() {
+ println("Differences by rule:");
+
+ for (String rule : getRules()) {
+ int expectedViolations = getViolationsByRule(expected, rule);
+ int actualViolations = getViolationsByRule(actual, rule);
+
+ println(" " + rule + " expected: " + expectedViolations + ", actual: " + actualViolations + ": "
+ + (expectedViolations == actualViolations ? "OK" : "*** FAILURE ***"));
+ }
+
+ println("End of differences by rule.");
+ }
+
+ private Set getRules() {
+ Set rules = new HashSet();
+
+ for (String file : expected.violationsByFileAndRule.keySet()) {
+ rules.addAll(expected.violationsByFileAndRule.get(file).keySet());
+ }
+
+ for (String file : actual.violationsByFileAndRule.keySet()) {
+ rules.addAll(actual.violationsByFileAndRule.get(file).keySet());
+ }
+
+ return rules;
+ }
+
+ private static int getViolationsByRule(ViolationCounter counter, String rule) {
+ int violations = 0;
+
+ for (String file : counter.violationsByFileAndRule.keySet()) {
+ if (counter.violationsByFileAndRule.get(file).containsKey(rule)) {
+ violations += counter.violationsByFileAndRule.get(file).get(rule).size();
+ }
+ }
+
+ return violations;
+ }
+
+ public boolean hasDifferences() {
+ return hasDifferences;
+ }
+
+ }
+
+ public ViolationCounterCheck(String projectsDir, ViolationCounter violationCounter) {
+ try {
+ this.projectsDirCanonicalPath = new File(projectsDir).getCanonicalPath();
+ } catch (IOException e) {
+ throw Throwables.propagate(e);
+ }
+
+ this.violationCounter = violationCounter;
+ }
+
+ @Override
+ public void leaveFile(AstNode node) {
+ Set violationsOnCurrentFile = new HashSet(getContext().peekSourceCode()
+ .getCheckMessages());
+ for (CheckMessage violation : violationsOnCurrentFile) {
+ violationCounter.increment(getRelativePath(getContext().getFile()), violation.getChecker().getClass()
+ .getSimpleName(),
+ violation.getLine() == null ? -1
+ : violation.getLine());
+ }
+ }
+
+ private String getRelativePath(File file) {
+ if (!file.exists()) {
+ throw new IllegalArgumentException("The file located at \"" + file.getAbsolutePath() + "\" does not exist.");
+ }
+
+ String canonicalPath;
+ try {
+ canonicalPath = file.getCanonicalPath();
+ } catch (IOException e) {
+ throw Throwables.propagate(e);
+ }
+
+ if (!canonicalPath.startsWith(projectsDirCanonicalPath)) {
+ throw new IllegalArgumentException("The file located at \"" + canonicalPath + "\" is not within projectsDir (\""
+ + projectsDirCanonicalPath + "\").");
+ }
+
+ return canonicalPath.substring(projectsDirCanonicalPath.length()).replace('\\', '/');
+ }
+
+}
diff --git a/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/checks/package-info.java b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/checks/package-info.java
new file mode 100644
index 0000000000..a633a3c617
--- /dev/null
+++ b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/checks/package-info.java
@@ -0,0 +1,25 @@
+/*
+ * C++ Community Plugin (cxx plugin)
+ * Copyright (C) 2021 SonarOpenCommunity
+ * http://github.com/SonarOpenCommunity/sonar-cxx
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+/**
+ * fork of SSLR Squid Bridge: https://github.com/SonarSource/sslr-squid-bridge/tree/2.6.1
+ * Copyright (C) 2010 SonarSource / mailto: sonarqube@googlegroups.com / license: LGPL v3
+ */
+@javax.annotation.ParametersAreNonnullByDefault
+package org.sonar.cxx.squidbridge.checks;
diff --git a/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/indexer/QueryByMeasure.java b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/indexer/QueryByMeasure.java
new file mode 100644
index 0000000000..c78d4403df
--- /dev/null
+++ b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/indexer/QueryByMeasure.java
@@ -0,0 +1,74 @@
+/*
+ * C++ Community Plugin (cxx plugin)
+ * Copyright (C) 2021 SonarOpenCommunity
+ * http://github.com/SonarOpenCommunity/sonar-cxx
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+/**
+ * fork of SSLR Squid Bridge: https://github.com/SonarSource/sslr-squid-bridge/tree/2.6.1
+ * Copyright (C) 2010 SonarSource / mailto: sonarqube@googlegroups.com / license: LGPL v3
+ */
+package org.sonar.cxx.squidbridge.indexer;
+
+import org.apache.commons.lang.math.NumberUtils;
+import org.sonar.cxx.squidbridge.api.Query;
+import org.sonar.cxx.squidbridge.api.SourceCode;
+import org.sonar.cxx.squidbridge.measures.Metric;
+import org.sonar.cxx.squidbridge.measures.MetricDef;
+
+public class QueryByMeasure implements Query {
+
+ private final MetricDef metric;
+ private final Operator operator;
+ private final double value;
+
+ public enum Operator {
+ GREATER_THAN, EQUALS, GREATER_THAN_EQUALS, LESS_THAN, LESS_THAN_EQUALS
+ }
+
+ /**
+ * @deprecated use {@link #QueryByMeasure(MetricDef, Operator, double)} instead
+ */
+ @Deprecated
+ public QueryByMeasure(Metric metric, Operator operator, double value) {
+ this((MetricDef) metric, operator, value);
+ }
+
+ public QueryByMeasure(MetricDef metric, Operator operator, double value) {
+ this.metric = metric;
+ this.operator = operator;
+ this.value = value;
+ }
+
+ @Override
+ public boolean match(SourceCode unit) {
+ switch (operator) {
+ case EQUALS:
+ return NumberUtils.compare(unit.getDouble(metric), value) == 0;
+ case GREATER_THAN:
+ return unit.getDouble(metric) > value;
+ case GREATER_THAN_EQUALS:
+ return unit.getDouble(metric) >= value;
+ case LESS_THAN_EQUALS:
+ return unit.getDouble(metric) <= value;
+ case LESS_THAN:
+ return unit.getDouble(metric) < value;
+ default:
+ throw new IllegalStateException("The operator value '" + operator + "' is unknown.");
+ }
+ }
+
+}
diff --git a/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/indexer/QueryByName.java b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/indexer/QueryByName.java
new file mode 100644
index 0000000000..bd70544eb7
--- /dev/null
+++ b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/indexer/QueryByName.java
@@ -0,0 +1,70 @@
+/*
+ * C++ Community Plugin (cxx plugin)
+ * Copyright (C) 2021 SonarOpenCommunity
+ * http://github.com/SonarOpenCommunity/sonar-cxx
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+/**
+ * fork of SSLR Squid Bridge: https://github.com/SonarSource/sslr-squid-bridge/tree/2.6.1
+ * Copyright (C) 2010 SonarSource / mailto: sonarqube@googlegroups.com / license: LGPL v3
+ */
+package org.sonar.cxx.squidbridge.indexer;
+
+import org.sonar.cxx.squidbridge.api.Query;
+import org.sonar.cxx.squidbridge.api.SourceCode;
+
+public class QueryByName implements Query {
+
+ private final String resourceName;
+
+ public QueryByName(String resourceName) {
+ if (resourceName == null) {
+ throw new IllegalStateException("The name can't be null !");
+ }
+ this.resourceName = resourceName;
+ }
+
+ @Override
+ public boolean match(SourceCode unit) {
+ if (unit.getName() != null) {
+ return unit.getName().equals(resourceName);
+ }
+ return false;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof QueryByName)) {
+ return false;
+ }
+
+ QueryByName that = (QueryByName) o;
+
+ if (resourceName != null ? !resourceName.equals(that.resourceName) : that.resourceName != null) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return resourceName.hashCode();
+ }
+}
diff --git a/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/indexer/QueryByParent.java b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/indexer/QueryByParent.java
new file mode 100644
index 0000000000..f06a9cc662
--- /dev/null
+++ b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/indexer/QueryByParent.java
@@ -0,0 +1,41 @@
+/*
+ * C++ Community Plugin (cxx plugin)
+ * Copyright (C) 2021 SonarOpenCommunity
+ * http://github.com/SonarOpenCommunity/sonar-cxx
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+/**
+ * fork of SSLR Squid Bridge: https://github.com/SonarSource/sslr-squid-bridge/tree/2.6.1
+ * Copyright (C) 2010 SonarSource / mailto: sonarqube@googlegroups.com / license: LGPL v3
+ */
+package org.sonar.cxx.squidbridge.indexer;
+
+import org.sonar.cxx.squidbridge.api.Query;
+import org.sonar.cxx.squidbridge.api.SourceCode;
+
+public class QueryByParent implements Query {
+
+ private final SourceCode parent;
+
+ public QueryByParent(SourceCode parent) {
+ this.parent = parent;
+ }
+
+ @Override
+ public boolean match(SourceCode unit) {
+ return unit.hasAmongParents(parent);
+ }
+}
diff --git a/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/indexer/QueryByType.java b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/indexer/QueryByType.java
new file mode 100644
index 0000000000..87ff1baf3d
--- /dev/null
+++ b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/indexer/QueryByType.java
@@ -0,0 +1,67 @@
+/*
+ * C++ Community Plugin (cxx plugin)
+ * Copyright (C) 2021 SonarOpenCommunity
+ * http://github.com/SonarOpenCommunity/sonar-cxx
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+/**
+ * fork of SSLR Squid Bridge: https://github.com/SonarSource/sslr-squid-bridge/tree/2.6.1
+ * Copyright (C) 2010 SonarSource / mailto: sonarqube@googlegroups.com / license: LGPL v3
+ */
+package org.sonar.cxx.squidbridge.indexer;
+
+import org.sonar.cxx.squidbridge.api.Query;
+import org.sonar.cxx.squidbridge.api.SourceCode;
+
+public class QueryByType implements Query {
+
+ private final Class extends SourceCode> resourceType;
+
+ public QueryByType(Class extends SourceCode> resourceType) {
+ if (resourceType == null) {
+ throw new IllegalStateException("The type of resource can't be null !");
+ }
+ this.resourceType = resourceType;
+ }
+
+ @Override
+ public boolean match(SourceCode unit) {
+ return unit.isType(resourceType);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof QueryByType)) {
+ return false;
+ }
+
+ QueryByType that = (QueryByType) o;
+
+ if (resourceType != null ? !resourceType.equals(that.resourceType) : that.resourceType != null) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return resourceType != null ? resourceType.hashCode() : 0;
+ }
+}
diff --git a/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/indexer/SquidIndex.java b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/indexer/SquidIndex.java
new file mode 100644
index 0000000000..e8d4291fef
--- /dev/null
+++ b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/indexer/SquidIndex.java
@@ -0,0 +1,72 @@
+/*
+ * C++ Community Plugin (cxx plugin)
+ * Copyright (C) 2021 SonarOpenCommunity
+ * http://github.com/SonarOpenCommunity/sonar-cxx
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+/**
+ * fork of SSLR Squid Bridge: https://github.com/SonarSource/sslr-squid-bridge/tree/2.6.1
+ * Copyright (C) 2010 SonarSource / mailto: sonarqube@googlegroups.com / license: LGPL v3
+ */
+package org.sonar.cxx.squidbridge.indexer;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import org.sonar.cxx.squidbridge.api.Query;
+import org.sonar.cxx.squidbridge.api.SourceCode;
+import org.sonar.cxx.squidbridge.api.SourceCodeIndexer;
+import org.sonar.cxx.squidbridge.api.SourceCodeSearchEngine;
+
+public class SquidIndex implements SourceCodeIndexer, SourceCodeSearchEngine {
+
+ private final Map index = new TreeMap();
+
+ @Override
+ public Collection search(Query... query) {
+ Set result = new HashSet();
+ for (SourceCode unit : index.values()) {
+ if (isSquidUnitMatchQueries(unit, query)) {
+ result.add(unit);
+ }
+ }
+ return result;
+ }
+
+ private boolean isSquidUnitMatchQueries(SourceCode unit, Query... queries) {
+ boolean match;
+ for (Query query : queries) {
+ match = query.match(unit);
+ if (!match) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public SourceCode search(String key) {
+ return index.get(key);
+ }
+
+ @Override
+ public void index(SourceCode sourceCode) {
+ sourceCode.setSourceCodeIndexer(this);
+ index.put(sourceCode.getKey(), sourceCode);
+ }
+}
diff --git a/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/indexer/package-info.java b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/indexer/package-info.java
new file mode 100644
index 0000000000..00af4dee57
--- /dev/null
+++ b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/indexer/package-info.java
@@ -0,0 +1,25 @@
+/*
+ * C++ Community Plugin (cxx plugin)
+ * Copyright (C) 2021 SonarOpenCommunity
+ * http://github.com/SonarOpenCommunity/sonar-cxx
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+/**
+ * fork of SSLR Squid Bridge: https://github.com/SonarSource/sslr-squid-bridge/tree/2.6.1
+ * Copyright (C) 2010 SonarSource / mailto: sonarqube@googlegroups.com / license: LGPL v3
+ */
+@javax.annotation.ParametersAreNonnullByDefault
+package org.sonar.cxx.squidbridge.indexer;
diff --git a/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/AbstractnessFormula.java b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/AbstractnessFormula.java
new file mode 100644
index 0000000000..0e5afb4e1c
--- /dev/null
+++ b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/AbstractnessFormula.java
@@ -0,0 +1,37 @@
+/*
+ * C++ Community Plugin (cxx plugin)
+ * Copyright (C) 2021 SonarOpenCommunity
+ * http://github.com/SonarOpenCommunity/sonar-cxx
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+/**
+ * fork of SSLR Squid Bridge: https://github.com/SonarSource/sslr-squid-bridge/tree/2.6.1
+ * Copyright (C) 2010 SonarSource / mailto: sonarqube@googlegroups.com / license: LGPL v3
+ */
+package org.sonar.cxx.squidbridge.measures;
+
+public class AbstractnessFormula implements CalculatedMetricFormula {
+
+ @Override
+ public double calculate(Measurable measurable) {
+ if (Double.doubleToRawLongBits(measurable.getDouble(Metric.CLASSES)) == 0) {
+ return 0;
+ }
+ return (measurable.getDouble(Metric.ABSTRACT_CLASSES) + measurable.getDouble(Metric.INTERFACES)) / measurable
+ .getDouble(Metric.CLASSES);
+ }
+
+}
diff --git a/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/AggregationFormula.java b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/AggregationFormula.java
new file mode 100644
index 0000000000..1857fbca2b
--- /dev/null
+++ b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/AggregationFormula.java
@@ -0,0 +1,32 @@
+/*
+ * C++ Community Plugin (cxx plugin)
+ * Copyright (C) 2021 SonarOpenCommunity
+ * http://github.com/SonarOpenCommunity/sonar-cxx
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+/**
+ * fork of SSLR Squid Bridge: https://github.com/SonarSource/sslr-squid-bridge/tree/2.6.1
+ * Copyright (C) 2010 SonarSource / mailto: sonarqube@googlegroups.com / license: LGPL v3
+ */
+package org.sonar.cxx.squidbridge.measures;
+
+import java.util.Collection;
+
+public interface AggregationFormula {
+
+ double aggregate(MetricDef metric, Collection measurables);
+
+}
diff --git a/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/CalculatedMetricFormula.java b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/CalculatedMetricFormula.java
new file mode 100644
index 0000000000..36635b71c3
--- /dev/null
+++ b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/CalculatedMetricFormula.java
@@ -0,0 +1,30 @@
+/*
+ * C++ Community Plugin (cxx plugin)
+ * Copyright (C) 2021 SonarOpenCommunity
+ * http://github.com/SonarOpenCommunity/sonar-cxx
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+/**
+ * fork of SSLR Squid Bridge: https://github.com/SonarSource/sslr-squid-bridge/tree/2.6.1
+ * Copyright (C) 2010 SonarSource / mailto: sonarqube@googlegroups.com / license: LGPL v3
+ */
+package org.sonar.cxx.squidbridge.measures;
+
+public interface CalculatedMetricFormula {
+
+ double calculate(Measurable measurable);
+
+}
diff --git a/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/CommentLinesDensityFormula.java b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/CommentLinesDensityFormula.java
new file mode 100644
index 0000000000..bbe14e6e2b
--- /dev/null
+++ b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/CommentLinesDensityFormula.java
@@ -0,0 +1,38 @@
+/*
+ * C++ Community Plugin (cxx plugin)
+ * Copyright (C) 2021 SonarOpenCommunity
+ * http://github.com/SonarOpenCommunity/sonar-cxx
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+/**
+ * fork of SSLR Squid Bridge: https://github.com/SonarSource/sslr-squid-bridge/tree/2.6.1
+ * Copyright (C) 2010 SonarSource / mailto: sonarqube@googlegroups.com / license: LGPL v3
+ */
+package org.sonar.cxx.squidbridge.measures;
+
+public class CommentLinesDensityFormula implements CalculatedMetricFormula {
+
+ @Override
+ public double calculate(Measurable measurable) {
+ double total = measurable.getDouble(Metric.LINES_OF_CODE) + measurable
+ .getDouble(Metric.COMMENT_LINES_WITHOUT_HEADER);
+ if (Double.doubleToRawLongBits(total) != 0) {
+ return measurable.getDouble(Metric.COMMENT_LINES_WITHOUT_HEADER) / total;
+ }
+ return 0;
+ }
+
+}
diff --git a/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/CommentLinesWithoutHeaderFormula.java b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/CommentLinesWithoutHeaderFormula.java
new file mode 100644
index 0000000000..43206a811d
--- /dev/null
+++ b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/CommentLinesWithoutHeaderFormula.java
@@ -0,0 +1,33 @@
+/*
+ * C++ Community Plugin (cxx plugin)
+ * Copyright (C) 2021 SonarOpenCommunity
+ * http://github.com/SonarOpenCommunity/sonar-cxx
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+/**
+ * fork of SSLR Squid Bridge: https://github.com/SonarSource/sslr-squid-bridge/tree/2.6.1
+ * Copyright (C) 2010 SonarSource / mailto: sonarqube@googlegroups.com / license: LGPL v3
+ */
+package org.sonar.cxx.squidbridge.measures;
+
+public class CommentLinesWithoutHeaderFormula implements CalculatedMetricFormula {
+
+ @Override
+ public double calculate(Measurable mesurable) {
+ return mesurable.getInt(Metric.COMMENT_LINES) - mesurable.getInt(Metric.HEADER_COMMENT_LINES);
+ }
+
+}
diff --git a/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/DistanceFormula.java b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/DistanceFormula.java
new file mode 100644
index 0000000000..381261f5e9
--- /dev/null
+++ b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/DistanceFormula.java
@@ -0,0 +1,33 @@
+/*
+ * C++ Community Plugin (cxx plugin)
+ * Copyright (C) 2021 SonarOpenCommunity
+ * http://github.com/SonarOpenCommunity/sonar-cxx
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+/**
+ * fork of SSLR Squid Bridge: https://github.com/SonarSource/sslr-squid-bridge/tree/2.6.1
+ * Copyright (C) 2010 SonarSource / mailto: sonarqube@googlegroups.com / license: LGPL v3
+ */
+package org.sonar.cxx.squidbridge.measures;
+
+public class DistanceFormula implements CalculatedMetricFormula {
+
+ @Override
+ public double calculate(Measurable measurable) {
+ return Math.abs(measurable.getDouble(Metric.ABSTRACTNESS) + measurable.getDouble(Metric.INSTABILITY) - 1);
+ }
+
+}
diff --git a/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/InstabilityFormula.java b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/InstabilityFormula.java
new file mode 100644
index 0000000000..f9a27b08f0
--- /dev/null
+++ b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/InstabilityFormula.java
@@ -0,0 +1,36 @@
+/*
+ * C++ Community Plugin (cxx plugin)
+ * Copyright (C) 2021 SonarOpenCommunity
+ * http://github.com/SonarOpenCommunity/sonar-cxx
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+/**
+ * fork of SSLR Squid Bridge: https://github.com/SonarSource/sslr-squid-bridge/tree/2.6.1
+ * Copyright (C) 2010 SonarSource / mailto: sonarqube@googlegroups.com / license: LGPL v3
+ */
+package org.sonar.cxx.squidbridge.measures;
+
+public class InstabilityFormula implements CalculatedMetricFormula {
+
+ @Override
+ public double calculate(Measurable measurable) {
+ if (Double.doubleToRawLongBits(measurable.getDouble(Metric.CA) + measurable.getDouble(Metric.CE)) == 0) {
+ return 0;
+ }
+ return measurable.getDouble(Metric.CE) / (measurable.getDouble(Metric.CA) + measurable.getDouble(Metric.CE));
+ }
+
+}
diff --git a/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/MeanAggregationFormula.java b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/MeanAggregationFormula.java
new file mode 100644
index 0000000000..186504c287
--- /dev/null
+++ b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/MeanAggregationFormula.java
@@ -0,0 +1,39 @@
+/*
+ * C++ Community Plugin (cxx plugin)
+ * Copyright (C) 2021 SonarOpenCommunity
+ * http://github.com/SonarOpenCommunity/sonar-cxx
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+/**
+ * fork of SSLR Squid Bridge: https://github.com/SonarSource/sslr-squid-bridge/tree/2.6.1
+ * Copyright (C) 2010 SonarSource / mailto: sonarqube@googlegroups.com / license: LGPL v3
+ */
+package org.sonar.cxx.squidbridge.measures;
+
+import java.util.Collection;
+
+public class MeanAggregationFormula implements AggregationFormula {
+
+ @Override
+ public double aggregate(MetricDef metric, Collection measurables) {
+ if (measurables.isEmpty()) {
+ return 0;
+ }
+ SumAggregationFormula sumFormula = new SumAggregationFormula();
+ return sumFormula.aggregate(metric, measurables) / measurables.size();
+ }
+
+}
diff --git a/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/Measurable.java b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/Measurable.java
new file mode 100644
index 0000000000..703fe54c8e
--- /dev/null
+++ b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/Measurable.java
@@ -0,0 +1,36 @@
+/*
+ * C++ Community Plugin (cxx plugin)
+ * Copyright (C) 2021 SonarOpenCommunity
+ * http://github.com/SonarOpenCommunity/sonar-cxx
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+/**
+ * fork of SSLR Squid Bridge: https://github.com/SonarSource/sslr-squid-bridge/tree/2.6.1
+ * Copyright (C) 2010 SonarSource / mailto: sonarqube@googlegroups.com / license: LGPL v3
+ */
+package org.sonar.cxx.squidbridge.measures;
+
+public interface Measurable {
+
+ double getDouble(T metric);
+
+ int getInt(T metric);
+
+ void setMeasure(T metric, double measure);
+
+ void setMeasure(T metric, int measure);
+
+}
diff --git a/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/Measures.java b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/Measures.java
new file mode 100644
index 0000000000..e2b53af4d5
--- /dev/null
+++ b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/Measures.java
@@ -0,0 +1,96 @@
+/*
+ * C++ Community Plugin (cxx plugin)
+ * Copyright (C) 2021 SonarOpenCommunity
+ * http://github.com/SonarOpenCommunity/sonar-cxx
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+/**
+ * fork of SSLR Squid Bridge: https://github.com/SonarSource/sslr-squid-bridge/tree/2.6.1
+ * Copyright (C) 2010 SonarSource / mailto: sonarqube@googlegroups.com / license: LGPL v3
+ */
+package org.sonar.cxx.squidbridge.measures;
+
+import java.util.IdentityHashMap;
+import java.util.Map;
+
+public class Measures {
+
+ private final Map measures = new IdentityHashMap();
+
+ public double getValue(MetricDef metric) {
+ Measure measure = measures.get(metric);
+ if (measure == null) {
+ return 0;
+ }
+ return measure.getValue();
+ }
+
+ public Object getData(MetricDef metric) {
+ Measure measure = measures.get(metric);
+ if (measure == null) {
+ return null;
+ }
+ return measure.getData();
+ }
+
+ public void setValue(MetricDef metric, double measure) {
+ getMeasureOrCreateIt(metric).setValue(measure);
+ }
+
+ public void setData(MetricDef metric, Object data) {
+ getMeasureOrCreateIt(metric).setData(data);
+ }
+
+ private Measure getMeasureOrCreateIt(MetricDef metric) {
+ Measure measure = measures.get(metric);
+ if (measure == null) {
+ measure = new Measure(0);
+ measures.put(metric, measure);
+ }
+ return measure;
+ }
+
+ public void removeMeasure(MetricDef metric) {
+ measures.remove(metric);
+ }
+
+ private static final class Measure {
+
+ private double value;
+ private Object data;
+
+ private Measure(double value) {
+ this.value = value;
+ }
+
+ private double getValue() {
+ return value;
+ }
+
+ private void setValue(double value) {
+ this.value = value;
+ }
+
+ private Object getData() {
+ return data;
+ }
+
+ private void setData(Object data) {
+ this.data = data;
+ }
+ }
+
+}
diff --git a/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/Metric.java b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/Metric.java
new file mode 100644
index 0000000000..042d3a5720
--- /dev/null
+++ b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/Metric.java
@@ -0,0 +1,86 @@
+/*
+ * C++ Community Plugin (cxx plugin)
+ * Copyright (C) 2021 SonarOpenCommunity
+ * http://github.com/SonarOpenCommunity/sonar-cxx
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+/**
+ * fork of SSLR Squid Bridge: https://github.com/SonarSource/sslr-squid-bridge/tree/2.6.1
+ * Copyright (C) 2010 SonarSource / mailto: sonarqube@googlegroups.com / license: LGPL v3
+ */
+package org.sonar.cxx.squidbridge.measures;
+
+public enum Metric implements MetricDef {
+
+ PACKAGES, CLASSES, ANONYMOUS_INNER_CLASSES, FILES, METHODS, CONSTRUCTORS, STATEMENTS, LINES(false), BLANK_LINES(false),
+ COMMENT_LINES(
+ false), HEADER_COMMENT_LINES(false), COMMENTED_OUT_CODE_LINES(false), BRANCHES, PUBLIC_API, PUBLIC_DOC_API,
+ ACCESSORS,
+ COMMENT_BLANK_LINES(false), LINES_OF_CODE(false), COMMENT_LINES_WITHOUT_HEADER(new CommentLinesWithoutHeaderFormula()),
+ PUBLIC_DOCUMENTED_API_DENSITY(new PublicDocumentedApiDensityFormula()), COMMENT_LINES_DENSITY(
+ new CommentLinesDensityFormula()),
+ COMPLEXITY, INTERFACES, ABSTRACT_CLASSES, ABSTRACTNESS(new AbstractnessFormula()), CA(new NoAggregationFormula()), CE(
+ new NoAggregationFormula()), INSTABILITY(new InstabilityFormula()), DISTANCE(new DistanceFormula()), DIT(
+ new NoAggregationFormula()),
+ RFC(new NoAggregationFormula()), NOC(new NoAggregationFormula()), LCOM4(new NoAggregationFormula()), LCOM4_BLOCKS;
+
+ private CalculatedMetricFormula formula = null;
+
+ private AggregationFormula aggregationFormula = new SumAggregationFormula();
+
+ private boolean aggregateIfThereIsAlreadyAValue = true;
+
+ Metric() {
+ }
+
+ Metric(boolean aggregateIfThereIsAlreadyAValue) {
+ this.aggregateIfThereIsAlreadyAValue = aggregateIfThereIsAlreadyAValue;
+ }
+
+ Metric(AggregationFormula aggregationFormula) {
+ this.aggregationFormula = aggregationFormula;
+ }
+
+ Metric(CalculatedMetricFormula formula) {
+ this.formula = formula;
+ }
+
+ @Override
+ public String getName() {
+ return name();
+ }
+
+ @Override
+ public boolean isCalculatedMetric() {
+ return formula != null;
+ }
+
+ @Override
+ public boolean aggregateIfThereIsAlreadyAValue() {
+ return aggregateIfThereIsAlreadyAValue;
+ }
+
+ @Override
+ public boolean isThereAggregationFormula() {
+ return !(aggregationFormula instanceof NoAggregationFormula);
+ }
+
+ @Override
+ public CalculatedMetricFormula getCalculatedMetricFormula() {
+ return formula;
+ }
+
+}
diff --git a/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/MetricDef.java b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/MetricDef.java
new file mode 100644
index 0000000000..453640047e
--- /dev/null
+++ b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/MetricDef.java
@@ -0,0 +1,37 @@
+/*
+ * C++ Community Plugin (cxx plugin)
+ * Copyright (C) 2021 SonarOpenCommunity
+ * http://github.com/SonarOpenCommunity/sonar-cxx
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+/**
+ * fork of SSLR Squid Bridge: https://github.com/SonarSource/sslr-squid-bridge/tree/2.6.1
+ * Copyright (C) 2010 SonarSource / mailto: sonarqube@googlegroups.com / license: LGPL v3
+ */
+package org.sonar.cxx.squidbridge.measures;
+
+public interface MetricDef {
+
+ String getName();
+
+ boolean isCalculatedMetric();
+
+ boolean aggregateIfThereIsAlreadyAValue();
+
+ boolean isThereAggregationFormula();
+
+ CalculatedMetricFormula getCalculatedMetricFormula();
+}
diff --git a/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/NoAggregationFormula.java b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/NoAggregationFormula.java
new file mode 100644
index 0000000000..e418467ac9
--- /dev/null
+++ b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/NoAggregationFormula.java
@@ -0,0 +1,35 @@
+/*
+ * C++ Community Plugin (cxx plugin)
+ * Copyright (C) 2021 SonarOpenCommunity
+ * http://github.com/SonarOpenCommunity/sonar-cxx
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+/**
+ * fork of SSLR Squid Bridge: https://github.com/SonarSource/sslr-squid-bridge/tree/2.6.1
+ * Copyright (C) 2010 SonarSource / mailto: sonarqube@googlegroups.com / license: LGPL v3
+ */
+package org.sonar.cxx.squidbridge.measures;
+
+import java.util.Collection;
+
+public class NoAggregationFormula implements AggregationFormula {
+
+ @Override
+ public double aggregate(MetricDef metric, Collection measurables) {
+ return 0;
+ }
+
+}
diff --git a/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/PublicDocumentedApiDensityFormula.java b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/PublicDocumentedApiDensityFormula.java
new file mode 100644
index 0000000000..acd6c21fa2
--- /dev/null
+++ b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/PublicDocumentedApiDensityFormula.java
@@ -0,0 +1,36 @@
+/*
+ * C++ Community Plugin (cxx plugin)
+ * Copyright (C) 2021 SonarOpenCommunity
+ * http://github.com/SonarOpenCommunity/sonar-cxx
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+/**
+ * fork of SSLR Squid Bridge: https://github.com/SonarSource/sslr-squid-bridge/tree/2.6.1
+ * Copyright (C) 2010 SonarSource / mailto: sonarqube@googlegroups.com / license: LGPL v3
+ */
+package org.sonar.cxx.squidbridge.measures;
+
+public class PublicDocumentedApiDensityFormula implements CalculatedMetricFormula {
+
+ @Override
+ public double calculate(Measurable measurable) {
+ if (Double.doubleToRawLongBits(measurable.getDouble(Metric.PUBLIC_API)) == 0) {
+ return 1;
+ }
+ return measurable.getDouble(Metric.PUBLIC_DOC_API) / measurable.getDouble(Metric.PUBLIC_API);
+ }
+
+}
diff --git a/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/SumAggregationFormula.java b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/SumAggregationFormula.java
new file mode 100644
index 0000000000..b58afcc6eb
--- /dev/null
+++ b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/SumAggregationFormula.java
@@ -0,0 +1,39 @@
+/*
+ * C++ Community Plugin (cxx plugin)
+ * Copyright (C) 2021 SonarOpenCommunity
+ * http://github.com/SonarOpenCommunity/sonar-cxx
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+/**
+ * fork of SSLR Squid Bridge: https://github.com/SonarSource/sslr-squid-bridge/tree/2.6.1
+ * Copyright (C) 2010 SonarSource / mailto: sonarqube@googlegroups.com / license: LGPL v3
+ */
+package org.sonar.cxx.squidbridge.measures;
+
+import java.util.Collection;
+
+public class SumAggregationFormula implements AggregationFormula {
+
+ @Override
+ public double aggregate(MetricDef metric, Collection measurables) {
+ double aggregation = 0;
+ for (Measurable measurable : measurables) {
+ aggregation += measurable.getDouble(metric);
+ }
+ return aggregation;
+ }
+
+}
diff --git a/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/package-info.java b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/package-info.java
new file mode 100644
index 0000000000..1bce130a54
--- /dev/null
+++ b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/measures/package-info.java
@@ -0,0 +1,25 @@
+/*
+ * C++ Community Plugin (cxx plugin)
+ * Copyright (C) 2021 SonarOpenCommunity
+ * http://github.com/SonarOpenCommunity/sonar-cxx
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+/**
+ * fork of SSLR Squid Bridge: https://github.com/SonarSource/sslr-squid-bridge/tree/2.6.1
+ * Copyright (C) 2010 SonarSource / mailto: sonarqube@googlegroups.com / license: LGPL v3
+ */
+@javax.annotation.ParametersAreNonnullByDefault
+package org.sonar.cxx.squidbridge.measures;
diff --git a/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/metrics/CommentsVisitor.java b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/metrics/CommentsVisitor.java
new file mode 100644
index 0000000000..61e87f37ef
--- /dev/null
+++ b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/metrics/CommentsVisitor.java
@@ -0,0 +1,143 @@
+/*
+ * C++ Community Plugin (cxx plugin)
+ * Copyright (C) 2021 SonarOpenCommunity
+ * http://github.com/SonarOpenCommunity/sonar-cxx
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+/**
+ * fork of SSLR Squid Bridge: https://github.com/SonarSource/sslr-squid-bridge/tree/2.6.1
+ * Copyright (C) 2010 SonarSource / mailto: sonarqube@googlegroups.com / license: LGPL v3
+ */
+package org.sonar.cxx.squidbridge.metrics;
+
+import com.sonar.sslr.api.AstAndTokenVisitor;
+import com.sonar.sslr.api.AstNode;
+import com.sonar.sslr.api.Grammar;
+import com.sonar.sslr.api.Token;
+import com.sonar.sslr.api.Trivia;
+import java.util.HashSet;
+import java.util.Set;
+import org.sonar.cxx.squidbridge.SquidAstVisitor;
+import org.sonar.cxx.squidbridge.api.SourceFile;
+import org.sonar.cxx.squidbridge.measures.MetricDef;
+
+/**
+ * Visitor that computes the number of lines of comments and the number of empty lines of comments.
+ */
+public final class CommentsVisitor extends SquidAstVisitor implements AstAndTokenVisitor {
+
+ private Set noSonar;
+ private Set comments;
+ private boolean seenFirstToken;
+
+ private final boolean enableNoSonar;
+ private final MetricDef commentMetric;
+ private final boolean ignoreHeaderComments;
+
+ private CommentsVisitor(CommentsVisitorBuilder builder) {
+ this.enableNoSonar = builder.enableNoSonar;
+ this.commentMetric = builder.commentMetric;
+ this.ignoreHeaderComments = builder.ignoreHeaderComments;
+ }
+
+ private void addNoSonar(int line) {
+ comments.remove(line);
+ noSonar.add(line);
+ }
+
+ private void addCommentLine(int line) {
+ if (!noSonar.contains(line)) {
+ comments.add(line);
+ }
+ }
+
+ @Override
+ public void visitFile(AstNode astNode) {
+ noSonar = new HashSet();
+ comments = new HashSet();
+ seenFirstToken = false;
+ }
+
+ @Override
+ public void visitToken(Token token) {
+ if (!ignoreHeaderComments || seenFirstToken) {
+ for (Trivia trivia : token.getTrivia()) {
+ if (trivia.isComment()) {
+ String[] commentLines = getContext().getCommentAnalyser().getContents(trivia.getToken().getOriginalValue())
+ .split("(\r)?\n|\r", -1);
+ int line = trivia.getToken().getLine();
+
+ for (String commentLine : commentLines) {
+ if (enableNoSonar && commentLine.contains("NOSONAR")) {
+ addNoSonar(line);
+ } else if (commentMetric != null && !getContext().getCommentAnalyser().isBlank(commentLine)) {
+ addCommentLine(line);
+ }
+
+ line++;
+ }
+ }
+ }
+ }
+
+ seenFirstToken = true;
+ }
+
+ @Override
+ public void leaveFile(AstNode astNode) {
+ if (enableNoSonar) {
+ ((SourceFile) getContext().peekSourceCode()).addNoSonarTagLines(noSonar);
+ }
+ if (commentMetric != null) {
+ getContext().peekSourceCode().add(commentMetric, comments.size());
+ }
+ }
+
+ public static CommentsVisitorBuilder builder() {
+ return new CommentsVisitorBuilder();
+ }
+
+ public static final class CommentsVisitorBuilder {
+
+ private boolean enableNoSonar = false;
+ private MetricDef commentMetric;
+ private boolean ignoreHeaderComments = false;
+
+ private CommentsVisitorBuilder() {
+ }
+
+ public CommentsVisitor build() {
+ return new CommentsVisitor(this);
+ }
+
+ public CommentsVisitorBuilder withNoSonar(boolean enableNoSonar) {
+ this.enableNoSonar = enableNoSonar;
+ return this;
+ }
+
+ public CommentsVisitorBuilder withCommentMetric(MetricDef commentMetric) {
+ this.commentMetric = commentMetric;
+ return this;
+ }
+
+ public CommentsVisitorBuilder withIgnoreHeaderComment(boolean ignoreHeaderComments) {
+ this.ignoreHeaderComments = ignoreHeaderComments;
+ return this;
+ }
+
+ }
+
+}
diff --git a/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/metrics/ComplexityVisitor.java b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/metrics/ComplexityVisitor.java
new file mode 100644
index 0000000000..e6e4091b55
--- /dev/null
+++ b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/metrics/ComplexityVisitor.java
@@ -0,0 +1,113 @@
+/*
+ * C++ Community Plugin (cxx plugin)
+ * Copyright (C) 2021 SonarOpenCommunity
+ * http://github.com/SonarOpenCommunity/sonar-cxx
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+/**
+ * fork of SSLR Squid Bridge: https://github.com/SonarSource/sslr-squid-bridge/tree/2.6.1
+ * Copyright (C) 2010 SonarSource / mailto: sonarqube@googlegroups.com / license: LGPL v3
+ */
+package org.sonar.cxx.squidbridge.metrics;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import com.sonar.sslr.api.AstNode;
+import com.sonar.sslr.api.AstNodeType;
+import com.sonar.sslr.api.Grammar;
+import java.util.Collection;
+import java.util.Set;
+import org.sonar.cxx.squidbridge.SquidAstVisitor;
+import org.sonar.cxx.squidbridge.measures.MetricDef;
+
+public final class ComplexityVisitor extends SquidAstVisitor {
+
+ private final MetricDef metric;
+ private final Set astNodeTypes;
+ private final Set exclusionAstNodeTypes;
+
+ public static final class Builder {
+
+ private MetricDef metric;
+ private Set astNodeTypes = Sets.newHashSet();
+ private Set exclusionAstNodeTypes = Sets.newHashSet();
+
+ private Builder() {
+ }
+
+ public Builder setMetricDef(MetricDef metric) {
+ this.metric = metric;
+ return this;
+ }
+
+ public Builder subscribeTo(AstNodeType... astNodeTypes) {
+ for (AstNodeType astNodeType : astNodeTypes) {
+ this.astNodeTypes.add(astNodeType);
+ }
+ return this;
+ }
+
+ public Builder subscribeTo(Collection astNodeTypes) {
+ this.astNodeTypes = Sets.newHashSet(astNodeTypes);
+ return this;
+ }
+
+ public Builder setExclusions(Collection exclusionAstNodeTypes) {
+ this.exclusionAstNodeTypes = Sets.newHashSet(exclusionAstNodeTypes);
+ return this;
+ }
+
+ public Builder addExclusions(AstNodeType... exclusionAstNodeTypes) {
+ for (AstNodeType exclusionAstNodeType : exclusionAstNodeTypes) {
+ this.exclusionAstNodeTypes.add(exclusionAstNodeType);
+ }
+ return this;
+ }
+
+ public ComplexityVisitor build() {
+ return new ComplexityVisitor(this);
+ }
+
+ }
+
+ private ComplexityVisitor(Builder builder) {
+ this.metric = builder.metric;
+ this.astNodeTypes = ImmutableSet.copyOf(builder.astNodeTypes);
+ this.exclusionAstNodeTypes = ImmutableSet.copyOf(builder.exclusionAstNodeTypes);
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ @Override
+ public void init() {
+ for (AstNodeType astNodeType : astNodeTypes) {
+ subscribeTo(astNodeType);
+ }
+ }
+
+ @Override
+ public void visitNode(AstNode astNode) {
+ for (AstNodeType exclusionAstNodeType : exclusionAstNodeTypes) {
+ if (astNode.hasAncestor(exclusionAstNodeType)) {
+ return;
+ }
+ }
+ getContext().peekSourceCode().add(metric, 1);
+ }
+
+}
diff --git a/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/metrics/CounterVisitor.java b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/metrics/CounterVisitor.java
new file mode 100644
index 0000000000..be9a73caf7
--- /dev/null
+++ b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/metrics/CounterVisitor.java
@@ -0,0 +1,94 @@
+/*
+ * C++ Community Plugin (cxx plugin)
+ * Copyright (C) 2021 SonarOpenCommunity
+ * http://github.com/SonarOpenCommunity/sonar-cxx
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+/**
+ * fork of SSLR Squid Bridge: https://github.com/SonarSource/sslr-squid-bridge/tree/2.6.1
+ * Copyright (C) 2010 SonarSource / mailto: sonarqube@googlegroups.com / license: LGPL v3
+ */
+package org.sonar.cxx.squidbridge.metrics;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import com.sonar.sslr.api.AstNode;
+import com.sonar.sslr.api.AstNodeType;
+import com.sonar.sslr.api.Grammar;
+import java.util.Collection;
+import java.util.Set;
+import org.sonar.cxx.squidbridge.SquidAstVisitor;
+import org.sonar.cxx.squidbridge.measures.MetricDef;
+
+public final class CounterVisitor extends SquidAstVisitor {
+
+ private final MetricDef metric;
+ private final Set astNodeTypes;
+
+ public static final class Builder {
+
+ private MetricDef metric;
+ private Set astNodeTypes = Sets.newHashSet();
+
+ private Builder() {
+ }
+
+ public Builder setMetricDef(MetricDef metric) {
+ this.metric = metric;
+ return this;
+ }
+
+ public Builder subscribeTo(AstNodeType... astNodeTypes) {
+ for (AstNodeType astNodeType : astNodeTypes) {
+ this.astNodeTypes.add(astNodeType);
+ }
+
+ return this;
+ }
+
+ public Builder subscribeTo(Collection astNodeTypes) {
+ this.astNodeTypes = Sets.newHashSet(astNodeTypes);
+ return this;
+ }
+
+ public CounterVisitor build() {
+ return new CounterVisitor(this);
+ }
+
+ }
+
+ private CounterVisitor(Builder builder) {
+ this.metric = builder.metric;
+ this.astNodeTypes = ImmutableSet.copyOf(builder.astNodeTypes);
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ @Override
+ public void init() {
+ for (AstNodeType astNodeType : astNodeTypes) {
+ subscribeTo(astNodeType);
+ }
+ }
+
+ @Override
+ public void visitNode(AstNode astNode) {
+ getContext().peekSourceCode().add(metric, 1);
+ }
+
+}
diff --git a/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/metrics/LinesOfCodeVisitor.java b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/metrics/LinesOfCodeVisitor.java
new file mode 100644
index 0000000000..63f47aebfb
--- /dev/null
+++ b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/metrics/LinesOfCodeVisitor.java
@@ -0,0 +1,70 @@
+/*
+ * C++ Community Plugin (cxx plugin)
+ * Copyright (C) 2021 SonarOpenCommunity
+ * http://github.com/SonarOpenCommunity/sonar-cxx
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+/**
+ * fork of SSLR Squid Bridge: https://github.com/SonarSource/sslr-squid-bridge/tree/2.6.1
+ * Copyright (C) 2010 SonarSource / mailto: sonarqube@googlegroups.com / license: LGPL v3
+ */
+package org.sonar.cxx.squidbridge.metrics;
+
+import com.sonar.sslr.api.AstAndTokenVisitor;
+import com.sonar.sslr.api.AstNode;
+import static com.sonar.sslr.api.GenericTokenType.EOF;
+import com.sonar.sslr.api.Grammar;
+import com.sonar.sslr.api.Token;
+import org.sonar.cxx.squidbridge.SquidAstVisitor;
+import org.sonar.cxx.squidbridge.measures.MetricDef;
+
+/**
+ * Visitor that computes the number of lines of code of a file.
+ */
+public class LinesOfCodeVisitor extends SquidAstVisitor implements AstAndTokenVisitor {
+
+ private final MetricDef metric;
+ private int lastTokenLine;
+
+ public LinesOfCodeVisitor(MetricDef metric) {
+ this.metric = metric;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void visitFile(AstNode node) {
+ lastTokenLine = -1;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void visitToken(Token token) {
+ if (!EOF.equals(token.getType())) {
+ /* 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);
+
+ lastTokenLine = token.getLine() + tokenLines.length - 1;
+ }
+ }
+
+}
diff --git a/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/metrics/LinesVisitor.java b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/metrics/LinesVisitor.java
new file mode 100644
index 0000000000..2dbe3fc056
--- /dev/null
+++ b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/metrics/LinesVisitor.java
@@ -0,0 +1,54 @@
+/*
+ * C++ Community Plugin (cxx plugin)
+ * Copyright (C) 2021 SonarOpenCommunity
+ * http://github.com/SonarOpenCommunity/sonar-cxx
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+/**
+ * fork of SSLR Squid Bridge: https://github.com/SonarSource/sslr-squid-bridge/tree/2.6.1
+ * Copyright (C) 2010 SonarSource / mailto: sonarqube@googlegroups.com / license: LGPL v3
+ */
+package org.sonar.cxx.squidbridge.metrics;
+
+import com.sonar.sslr.api.AstAndTokenVisitor;
+import static com.sonar.sslr.api.GenericTokenType.EOF;
+import com.sonar.sslr.api.Grammar;
+import com.sonar.sslr.api.Token;
+import org.sonar.cxx.squidbridge.SquidAstVisitor;
+import org.sonar.cxx.squidbridge.measures.MetricDef;
+
+/**
+ * Visitor that computes the number of lines of a file.
+ */
+public class LinesVisitor extends SquidAstVisitor implements AstAndTokenVisitor {
+
+ private final MetricDef metric;
+
+ public LinesVisitor(MetricDef metric) {
+ this.metric = metric;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void visitToken(Token token) {
+ if (EOF.equals(token.getType())) {
+ getContext().peekSourceCode().setMeasure(metric, token.getLine());
+ }
+ }
+
+}
diff --git a/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/metrics/package-info.java b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/metrics/package-info.java
new file mode 100644
index 0000000000..45e1e54794
--- /dev/null
+++ b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/metrics/package-info.java
@@ -0,0 +1,25 @@
+/*
+ * C++ Community Plugin (cxx plugin)
+ * Copyright (C) 2021 SonarOpenCommunity
+ * http://github.com/SonarOpenCommunity/sonar-cxx
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+/**
+ * fork of SSLR Squid Bridge: https://github.com/SonarSource/sslr-squid-bridge/tree/2.6.1
+ * Copyright (C) 2010 SonarSource / mailto: sonarqube@googlegroups.com / license: LGPL v3
+ */
+@javax.annotation.ParametersAreNonnullByDefault
+package org.sonar.cxx.squidbridge.metrics;
diff --git a/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/package-info.java b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/package-info.java
new file mode 100644
index 0000000000..b4bbc86211
--- /dev/null
+++ b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/package-info.java
@@ -0,0 +1,25 @@
+/*
+ * C++ Community Plugin (cxx plugin)
+ * Copyright (C) 2021 SonarOpenCommunity
+ * http://github.com/SonarOpenCommunity/sonar-cxx
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+/**
+ * fork of SSLR Squid Bridge: https://github.com/SonarSource/sslr-squid-bridge/tree/2.6.1
+ * Copyright (C) 2010 SonarSource / mailto: sonarqube@googlegroups.com / license: LGPL v3
+ */
+@javax.annotation.ParametersAreNonnullByDefault
+package org.sonar.cxx.squidbridge;
diff --git a/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/rules/ExternalDescriptionLoader.java b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/rules/ExternalDescriptionLoader.java
new file mode 100644
index 0000000000..73e954cc2a
--- /dev/null
+++ b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/rules/ExternalDescriptionLoader.java
@@ -0,0 +1,67 @@
+/*
+ * C++ Community Plugin (cxx plugin)
+ * Copyright (C) 2021 SonarOpenCommunity
+ * http://github.com/SonarOpenCommunity/sonar-cxx
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+/**
+ * fork of SSLR Squid Bridge: https://github.com/SonarSource/sslr-squid-bridge/tree/2.6.1
+ * Copyright (C) 2010 SonarSource / mailto: sonarqube@googlegroups.com / license: LGPL v3
+ */
+package org.sonar.cxx.squidbridge.rules;
+
+import com.google.common.annotations.Beta;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Charsets;
+import com.google.common.io.Resources;
+import java.io.IOException;
+import java.net.URL;
+import org.sonar.api.server.rule.RulesDefinition.NewRepository;
+import org.sonar.api.server.rule.RulesDefinition.NewRule;
+
+@Beta
+public class ExternalDescriptionLoader {
+
+ private final String resourceBasePath;
+
+ public ExternalDescriptionLoader(NewRepository repository, String resourceBasePath) {
+ this.resourceBasePath = resourceBasePath;
+ }
+
+ public static void loadHtmlDescriptions(NewRepository repository, String languageKey) {
+ ExternalDescriptionLoader loader = new ExternalDescriptionLoader(repository, languageKey);
+ for (NewRule newRule : repository.rules()) {
+ loader.addHtmlDescription(newRule);
+ }
+ }
+
+ public void addHtmlDescription(NewRule rule) {
+ URL resource = ExternalDescriptionLoader.class.getResource(resourceBasePath + "/" + rule.key() + ".html");
+ if (resource != null) {
+ addHtmlDescription(rule, resource);
+ }
+ }
+
+ @VisibleForTesting
+ void addHtmlDescription(NewRule rule, URL resource) {
+ try {
+ rule.setHtmlDescription(Resources.toString(resource, Charsets.UTF_8));
+ } catch (IOException e) {
+ throw new IllegalStateException("Failed to read: " + resource, e);
+ }
+ }
+
+}
diff --git a/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/rules/PropertyFileLoader.java b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/rules/PropertyFileLoader.java
new file mode 100644
index 0000000000..28bb85af5e
--- /dev/null
+++ b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/rules/PropertyFileLoader.java
@@ -0,0 +1,73 @@
+/*
+ * C++ Community Plugin (cxx plugin)
+ * Copyright (C) 2021 SonarOpenCommunity
+ * http://github.com/SonarOpenCommunity/sonar-cxx
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+/**
+ * fork of SSLR Squid Bridge: https://github.com/SonarSource/sslr-squid-bridge/tree/2.6.1
+ * Copyright (C) 2010 SonarSource / mailto: sonarqube@googlegroups.com / license: LGPL v3
+ */
+package org.sonar.cxx.squidbridge.rules;
+
+import com.google.common.annotations.Beta;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+import org.sonar.api.server.rule.RulesDefinition.NewParam;
+import org.sonar.api.server.rule.RulesDefinition.NewRepository;
+import org.sonar.api.server.rule.RulesDefinition.NewRule;
+
+@Beta
+public class PropertyFileLoader {
+
+ private PropertyFileLoader() {
+ // This class should not be instantiated
+ }
+
+ public static void loadNames(NewRepository repository, String resourceAbsolutePath) {
+ InputStream stream = PropertyFileLoader.class.getResourceAsStream(resourceAbsolutePath);
+ if (stream == null) {
+ throw new IllegalArgumentException("Cound not find resource: " + resourceAbsolutePath);
+ }
+ loadNames(repository, stream);
+ }
+
+ public static void loadNames(NewRepository repository, InputStream stream) {
+ Properties properties = new Properties();
+ try {
+ properties.load(stream);
+ } catch (IOException e) {
+ throw new IllegalArgumentException("Could not read names from properties", e);
+ }
+ for (NewRule rule : repository.rules()) {
+ String baseKey = "rule." + repository.key() + "." + rule.key();
+ String nameKey = baseKey + ".name";
+ String ruleName = properties.getProperty(nameKey);
+ if (ruleName != null) {
+ rule.setName(ruleName);
+ }
+ for (NewParam param : rule.params()) {
+ String paramDescriptionKey = baseKey + ".param." + param.key();
+ String paramDescription = properties.getProperty(paramDescriptionKey);
+ if (paramDescription != null) {
+ param.setDescription(paramDescription);
+ }
+ }
+ }
+ }
+
+}
diff --git a/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/rules/package-info.java b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/rules/package-info.java
new file mode 100644
index 0000000000..65cb0da355
--- /dev/null
+++ b/cxx-squid-bridge/src/main/java/org/sonar/cxx/squidbridge/rules/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * C++ Community Plugin (cxx plugin)
+ * Copyright (C) 2021 SonarOpenCommunity
+ * http://github.com/SonarOpenCommunity/sonar-cxx
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+/**
+ * fork of SSLR Squid Bridge: https://github.com/SonarSource/sslr-squid-bridge/tree/2.6.1
+ * Copyright (C) 2010 SonarSource / mailto: sonarqube@googlegroups.com / license: LGPL v3
+ */
+package org.sonar.cxx.squidbridge.rules;
diff --git a/cxx-squid-bridge/src/test/java/org/sonar/cxx/squidbridge/MyCodeScanner.java b/cxx-squid-bridge/src/test/java/org/sonar/cxx/squidbridge/MyCodeScanner.java
new file mode 100644
index 0000000000..37defac97e
--- /dev/null
+++ b/cxx-squid-bridge/src/test/java/org/sonar/cxx/squidbridge/MyCodeScanner.java
@@ -0,0 +1,37 @@
+/*
+ * C++ Community Plugin (cxx plugin)
+ * Copyright (C) 2021 SonarOpenCommunity
+ * http://github.com/SonarOpenCommunity/sonar-cxx
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+/**
+ * fork of SSLR Squid Bridge: https://github.com/SonarSource/sslr-squid-bridge/tree/2.6.1
+ * Copyright (C) 2010 SonarSource / mailto: sonarqube@googlegroups.com / license: LGPL v3
+ */
+package org.sonar.cxx.squidbridge;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import org.sonar.cxx.squidbridge.api.CodeScanner;
+import org.sonar.cxx.squidbridge.api.CodeVisitor;
+
+public class MyCodeScanner extends CodeScanner {
+
+ @Override
+ public Collection> getVisitorClasses() {
+ return new ArrayList>();
+ }
+}
diff --git a/cxx-squid-bridge/src/test/java/org/sonar/cxx/squidbridge/ProgressAstScannerTest.java b/cxx-squid-bridge/src/test/java/org/sonar/cxx/squidbridge/ProgressAstScannerTest.java
new file mode 100644
index 0000000000..8c0e69951e
--- /dev/null
+++ b/cxx-squid-bridge/src/test/java/org/sonar/cxx/squidbridge/ProgressAstScannerTest.java
@@ -0,0 +1,159 @@
+/*
+ * C++ Community Plugin (cxx plugin)
+ * Copyright (C) 2021 SonarOpenCommunity
+ * http://github.com/SonarOpenCommunity/sonar-cxx
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+/**
+ * fork of SSLR Squid Bridge: https://github.com/SonarSource/sslr-squid-bridge/tree/2.6.1
+ * Copyright (C) 2010 SonarSource / mailto: sonarqube@googlegroups.com / license: LGPL v3
+ */
+package org.sonar.cxx.squidbridge;
+
+import ch.qos.logback.classic.spi.LoggingEvent;
+import ch.qos.logback.core.Appender;
+import com.google.common.base.Throwables;
+import com.jayway.awaitility.Awaitility;
+import com.jayway.awaitility.Duration;
+import com.sonar.sslr.api.AstNode;
+import com.sonar.sslr.api.Grammar;
+import com.sonar.sslr.impl.Parser;
+import com.sonar.sslr.test.minic.MiniCParser;
+import java.io.File;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.concurrent.CountDownLatch;
+import org.junit.Test;
+import org.mockito.ArgumentMatcher;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonar.cxx.squidbridge.api.SourceProject;
+import org.sonar.cxx.squidbridge.test.miniC.MiniCAstScanner.MiniCMetrics;
+
+public class ProgressAstScannerTest {
+
+ @Test
+ public void test() throws Exception {
+ SquidAstVisitorContextImpl context = new SquidAstVisitorContextImpl(new SourceProject(""));
+ Parser parser = MiniCParser.create();
+ AstScanner scanner = new ProgressAstScanner.Builder(context)
+ .setBaseParser(parser)
+ .setFilesMetric(MiniCMetrics.FILES)
+ .build();
+
+ ch.qos.logback.classic.Logger root = (ch.qos.logback.classic.Logger) LoggerFactory
+ .getLogger(Logger.ROOT_LOGGER_NAME);
+ @SuppressWarnings("unchecked")
+ Appender mockAppender = mock(Appender.class);
+ root.addAppender(mockAppender);
+
+ scanner.scanFile(new File("src/test/resources/metrics/lines.mc"));
+
+ verify(mockAppender).doAppend(argThat(new ArgumentMatcher