aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvgeny Mandrikov <mandrikov@gmail.com>2012-02-09 00:07:24 +0400
committerEvgeny Mandrikov <mandrikov@gmail.com>2012-02-09 01:56:03 +0400
commit4eedeb8c01eb478ef0015de0a46849d781766114 (patch)
tree48c6ea53fcc20fa6efd58594355666118fe0fe73
parentfff856ad40b5a27148e6f1f48819797ae2f0c94f (diff)
downloadsonarqube-4eedeb8c01eb478ef0015de0a46849d781766114.tar.gz
sonarqube-4eedeb8c01eb478ef0015de0a46849d781766114.zip
SONAR-3210 Compute new measure for Java files - LoC in file
-rw-r--r--plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/ast/JavaAstScanner.java1
-rw-r--r--plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/ast/visitor/FileLinesVisitor.java77
-rw-r--r--plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SonarAccessor.java48
-rw-r--r--plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SquidSensor.java1
-rw-r--r--plugins/sonar-squid-java-plugin/src/test/java/org/sonar/java/ast/visitor/FileLinesVisitorTest.java66
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java21
-rw-r--r--sonar-squid/src/main/java/org/sonar/squid/text/Source.java13
7 files changed, 227 insertions, 0 deletions
diff --git a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/ast/JavaAstScanner.java b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/ast/JavaAstScanner.java
index 761cbe88dfb..7b6a50128de 100644
--- a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/ast/JavaAstScanner.java
+++ b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/ast/JavaAstScanner.java
@@ -172,6 +172,7 @@ public class JavaAstScanner extends CodeScanner<JavaAstVisitor> {
}
visitorClasses.add(ComplexityVisitor.class);
visitorClasses.add(LinesOfCodeVisitor.class);
+ visitorClasses.add(FileLinesVisitor.class);
return visitorClasses;
}
diff --git a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/ast/visitor/FileLinesVisitor.java b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/ast/visitor/FileLinesVisitor.java
new file mode 100644
index 00000000000..31202f01d51
--- /dev/null
+++ b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/ast/visitor/FileLinesVisitor.java
@@ -0,0 +1,77 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.java.ast.visitor;
+
+import com.puppycrawl.tools.checkstyle.api.DetailAST;
+import org.sonar.api.batch.SquidUtils;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.Measure;
+import org.sonar.api.measures.PersistenceMode;
+import org.sonar.api.resources.JavaFile;
+import org.sonar.plugins.squid.SonarAccessor;
+import org.sonar.squid.api.SourceFile;
+import org.sonar.squid.measures.Metric;
+import org.sonar.squid.text.Source;
+
+/**
+ * Saves information about lines directly into {@link org.sonar.api.batch.SensorContext}.
+ */
+public class FileLinesVisitor extends JavaAstVisitor {
+
+ private final SonarAccessor sonarAccessor;
+
+ /**
+ * Default constructor for case when {@link SonarAccessor} not available.
+ */
+ public FileLinesVisitor() {
+ this.sonarAccessor = null;
+ }
+
+ public FileLinesVisitor(SonarAccessor sonarAccessor) {
+ this.sonarAccessor = sonarAccessor;
+ }
+
+ @Override
+ public void visitFile(DetailAST ast) {
+ if (sonarAccessor != null) {
+ processFile();
+ }
+ }
+
+ private void processFile() {
+ SourceFile file = (SourceFile) peekSourceCode();
+ Source source = getSource();
+ StringBuilder data = new StringBuilder();
+ for (int line = 1; line <= source.getNumberOfLines(); line++) {
+ int linesOfCode = source.getMeasure(Metric.LINES_OF_CODE, line, line);
+ if (linesOfCode == 1) {
+ if (data.length() > 0) {
+ data.append(',');
+ }
+ data.append(line);
+ }
+ }
+ JavaFile javaFile = SquidUtils.convertJavaFileKeyFromSquidFormat(file.getKey());
+ Measure measure = new Measure(CoreMetrics.NCLOC_DATA, data.toString())
+ .setPersistenceMode(PersistenceMode.DATABASE);
+ sonarAccessor.getSensorContext().saveMeasure(javaFile, measure);
+ }
+
+}
diff --git a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SonarAccessor.java b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SonarAccessor.java
new file mode 100644
index 00000000000..0e6b9b661dd
--- /dev/null
+++ b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SonarAccessor.java
@@ -0,0 +1,48 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.plugins.squid;
+
+import org.sonar.api.batch.SensorContext;
+import org.sonar.squid.api.CodeScanner;
+
+import java.util.Collection;
+import java.util.Collections;
+
+/**
+ * TODO Godin: I didn't found better way to register component in picocontainer for Squid.
+ */
+public class SonarAccessor extends CodeScanner {
+
+ private SensorContext sensorContext;
+
+ public void setSensorContext(SensorContext sensorContext) {
+ this.sensorContext = sensorContext;
+ }
+
+ public SensorContext getSensorContext() {
+ return sensorContext;
+ }
+
+ @Override
+ public Collection getVisitorClasses() {
+ return Collections.emptyList();
+ }
+
+}
diff --git a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SquidSensor.java b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SquidSensor.java
index 7ec43f636ce..5f35c1ee39c 100644
--- a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SquidSensor.java
+++ b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SquidSensor.java
@@ -74,6 +74,7 @@ public class SquidSensor implements Sensor {
AnnotationCheckFactory factory = AnnotationCheckFactory.create(profile, SquidConstants.REPOSITORY_KEY, SquidRuleRepository.getCheckClasses());
SquidExecutor squidExecutor = new SquidExecutor(analyzePropertyAccessors, fieldNamesToExcludeFromLcom4Computation, factory, charset);
+ squidExecutor.getSquid().register(SonarAccessor.class).setSensorContext(context);
squidExecutor.scan(getMainSourceFiles(project), getBytecodeFiles(project));
squidExecutor.save(project, context, noSonarFilter);
squidExecutor.flush();
diff --git a/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/java/ast/visitor/FileLinesVisitorTest.java b/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/java/ast/visitor/FileLinesVisitorTest.java
new file mode 100644
index 00000000000..75edd60fb84
--- /dev/null
+++ b/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/java/ast/visitor/FileLinesVisitorTest.java
@@ -0,0 +1,66 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.java.ast.visitor;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.sonar.api.batch.SensorContext;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.Measure;
+import org.sonar.api.measures.PersistenceMode;
+import org.sonar.api.resources.Resource;
+import org.sonar.java.ast.JavaAstScanner;
+import org.sonar.java.ast.SquidTestUtils;
+import org.sonar.java.squid.JavaSquidConfiguration;
+import org.sonar.plugins.squid.SonarAccessor;
+import org.sonar.squid.Squid;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.*;
+
+public class FileLinesVisitorTest {
+
+ private Squid squid;
+ private SensorContext context;
+
+ @Before
+ public void setUp() {
+ squid = new Squid(new JavaSquidConfiguration());
+ context = mock(SensorContext.class);
+ }
+
+ @Test
+ public void analyseTestNcloc() {
+ squid.register(SonarAccessor.class).setSensorContext(context);
+ squid.register(JavaAstScanner.class).scanFile(SquidTestUtils.getInputFile("/metrics/ncloc/TestNcloc.java"));
+
+ ArgumentCaptor<Resource> resourceCaptor = ArgumentCaptor.forClass(Resource.class);
+ ArgumentCaptor<Measure> measureCaptor = ArgumentCaptor.forClass(Measure.class);
+ verify(context, times(1)).saveMeasure(resourceCaptor.capture(), measureCaptor.capture());
+ assertThat(resourceCaptor.getValue().getKey(), is("[default].TestNcloc"));
+ Measure measure = measureCaptor.getValue();
+ assertThat(measure.getMetricKey(), is(CoreMetrics.NCLOC_DATA_KEY));
+ assertThat(measure.getPersistenceMode(), is(PersistenceMode.DATABASE));
+ assertThat(measure.getData(), is("1,3,4,5,6,7,8,13,14,15,16,17,19,20,21,22,23,24,25,26,27,28,29,30,32,39"));
+ }
+
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java b/sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java
index acdf5c3c225..45d1bd15619 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java
@@ -19,6 +19,7 @@
*/
package org.sonar.api.measures;
+import com.google.common.annotations.Beta;
import com.google.common.collect.Lists;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.resources.Scopes;
@@ -1637,6 +1638,26 @@ public final class CoreMetrics {
.setOptimizedBestValue(true)
.create();
+ // --------------------------------------------------------------------------------------------------------------------
+ //
+ // FILE DATA
+ //
+ // --------------------------------------------------------------------------------------------------------------------
+
+ /**
+ * @since 2.14
+ */
+ @Beta
+ public static final String NCLOC_DATA_KEY = "ncloc_data";
+
+ /**
+ * @since 2.14
+ */
+ @Beta
+ public static final Metric NCLOC_DATA = new Metric.Builder(NCLOC_DATA_KEY, "ncloc_data", Metric.ValueType.DATA)
+ .setHidden(true)
+ .setDomain(DOMAIN_SIZE)
+ .create();
//--------------------------------------------------------------------------------------------------------------------
//
diff --git a/sonar-squid/src/main/java/org/sonar/squid/text/Source.java b/sonar-squid/src/main/java/org/sonar/squid/text/Source.java
index 7b29770f87d..f7a7339e55f 100644
--- a/sonar-squid/src/main/java/org/sonar/squid/text/Source.java
+++ b/sonar-squid/src/main/java/org/sonar/squid/text/Source.java
@@ -19,6 +19,7 @@
*/
package org.sonar.squid.text;
+import com.google.common.annotations.Beta;
import org.sonar.squid.measures.Metric;
import org.sonar.squid.recognizer.CodeRecognizer;
@@ -107,6 +108,9 @@ public class Source {
return getMeasure(metric, 1, lines.size());
}
+ /**
+ * Numbering of lines starts from 1.
+ */
public int getMeasure(Metric metric, int fromLine, int toLine) {
if (toLine > lines.size()) {
throw new IllegalStateException("There are only " + lines.size() + " lines in the file and you're trying to reach line " + toLine);
@@ -125,4 +129,13 @@ public class Source {
public Set<Integer> getNoSonarTagLines() {
return noSonarTagLines;
}
+
+ /**
+ * @since 2.14
+ */
+ @Beta
+ public int getNumberOfLines() {
+ return lines.size();
+ }
+
}