]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-3210 Compute new measure for Java files - LoC in file
authorEvgeny Mandrikov <mandrikov@gmail.com>
Wed, 8 Feb 2012 20:07:24 +0000 (00:07 +0400)
committerEvgeny Mandrikov <mandrikov@gmail.com>
Wed, 8 Feb 2012 21:56:03 +0000 (01:56 +0400)
plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/ast/JavaAstScanner.java
plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/ast/visitor/FileLinesVisitor.java [new file with mode: 0644]
plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SonarAccessor.java [new file with mode: 0644]
plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SquidSensor.java
plugins/sonar-squid-java-plugin/src/test/java/org/sonar/java/ast/visitor/FileLinesVisitorTest.java [new file with mode: 0644]
sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java
sonar-squid/src/main/java/org/sonar/squid/text/Source.java

index 761cbe88dfb309efdb9ff5443fb0fcd25f993968..7b6a50128de131fc220824e08dd1c97f55445eb7 100644 (file)
@@ -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 (file)
index 0000000..31202f0
--- /dev/null
@@ -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 (file)
index 0000000..0e6b9b6
--- /dev/null
@@ -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();
+  }
+
+}
index 7ec43f636cef89fa947ef2906d60be905d692181..5f35c1ee39c54b96679b8176181c0b42466bab9d 100644 (file)
@@ -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 (file)
index 0000000..75edd60
--- /dev/null
@@ -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"));
+  }
+
+}
index acdf5c3c225f2ba81404ef2187e90fe6a17da0ac..45d1bd15619a2d078d8a645491abf8f64409f88c 100644 (file)
@@ -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();
 
   //--------------------------------------------------------------------------------------------------------------------
   //
index 7b29770f87d1cfba2fa15cd18cecef8ca6372c51..f7a7339e55f5e793ba403c54b45c7b28ff3b281e 100644 (file)
@@ -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();
+  }
+
 }