diff options
author | Evgeny Mandrikov <mandrikov@gmail.com> | 2012-02-09 00:07:24 +0400 |
---|---|---|
committer | Evgeny Mandrikov <mandrikov@gmail.com> | 2012-02-09 01:56:03 +0400 |
commit | 4eedeb8c01eb478ef0015de0a46849d781766114 (patch) | |
tree | 48c6ea53fcc20fa6efd58594355666118fe0fe73 | |
parent | fff856ad40b5a27148e6f1f48819797ae2f0c94f (diff) | |
download | sonarqube-4eedeb8c01eb478ef0015de0a46849d781766114.tar.gz sonarqube-4eedeb8c01eb478ef0015de0a46849d781766114.zip |
SONAR-3210 Compute new measure for Java files - LoC in file
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(); + } + } |