}
visitorClasses.add(ComplexityVisitor.class);
visitorClasses.add(LinesOfCodeVisitor.class);
+ visitorClasses.add(FileLinesVisitor.class);
return visitorClasses;
}
--- /dev/null
+/*
+ * 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);
+ }
+
+}
--- /dev/null
+/*
+ * 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();
+ }
+
+}
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();
--- /dev/null
+/*
+ * 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"));
+ }
+
+}
*/
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;
.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();
//--------------------------------------------------------------------------------------------------------------------
//
*/
package org.sonar.squid.text;
+import com.google.common.annotations.Beta;
import org.sonar.squid.measures.Metric;
import org.sonar.squid.recognizer.CodeRecognizer;
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);
public Set<Integer> getNoSonarTagLines() {
return noSonarTagLines;
}
+
+ /**
+ * @since 2.14
+ */
+ @Beta
+ public int getNumberOfLines() {
+ return lines.size();
+ }
+
}