summaryrefslogtreecommitdiffstats
path: root/sonar-scanner-engine
diff options
context:
space:
mode:
authorDuarte Meneses <duarte.meneses@sonarsource.com>2018-04-24 15:27:56 +0200
committerSonarTech <sonartech@sonarsource.com>2018-05-09 20:20:46 +0200
commitfa4019b992510560be8c6d1b51bc2dc2f6b41546 (patch)
tree815cf6138b9e0b3a419c27cfe98e691080264af3 /sonar-scanner-engine
parent09b3d167fa8f399e18a37d56e7c8cbb61f68f97f (diff)
downloadsonarqube-fa4019b992510560be8c6d1b51bc2dc2f6b41546.tar.gz
sonarqube-fa4019b992510560be8c6d1b51bc2dc2f6b41546.zip
SONAR-10638 Create Java API for analyzers to report significant code
Diffstat (limited to 'sonar-scanner-engine')
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorContext.java11
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorStorage.java27
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/noop/NoOpNewSignificantCode.java45
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorContextTest.java8
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorStorageTest.java38
5 files changed, 128 insertions, 1 deletions
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorContext.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorContext.java
index 595a9d126fb..04b3ca16a2d 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorContext.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorContext.java
@@ -29,6 +29,8 @@ import org.sonar.api.batch.fs.InputModule;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.rule.ActiveRules;
import org.sonar.api.batch.sensor.SensorContext;
+import org.sonar.api.batch.sensor.code.NewSignificantCode;
+import org.sonar.api.batch.sensor.code.internal.DefaultSignificantCode;
import org.sonar.api.batch.sensor.coverage.NewCoverage;
import org.sonar.api.batch.sensor.coverage.internal.DefaultCoverage;
import org.sonar.api.batch.sensor.cpd.NewCpdTokens;
@@ -54,6 +56,7 @@ import org.sonar.scanner.sensor.noop.NoOpNewCoverage;
import org.sonar.scanner.sensor.noop.NoOpNewCpdTokens;
import org.sonar.scanner.sensor.noop.NoOpNewExternalIssue;
import org.sonar.scanner.sensor.noop.NoOpNewHighlighting;
+import org.sonar.scanner.sensor.noop.NoOpNewSignificantCode;
import org.sonar.scanner.sensor.noop.NoOpNewSymbolTable;
@ThreadSafe
@@ -65,6 +68,7 @@ public class DefaultSensorContext implements SensorContext {
static final NoOpNewAnalysisError NO_OP_NEW_ANALYSIS_ERROR = new NoOpNewAnalysisError();
static final NoOpNewCoverage NO_OP_NEW_COVERAGE = new NoOpNewCoverage();
static final NoOpNewExternalIssue NO_OP_NEW_EXTERNAL_ISSUE = new NoOpNewExternalIssue();
+ static final NoOpNewSignificantCode NO_OP_NEW_SIGNIFICANT_CODE = new NoOpNewSignificantCode();
private final Settings mutableSettings;
private final FileSystem fs;
@@ -196,4 +200,11 @@ public class DefaultSensorContext implements SensorContext {
file.setPublished(true);
}
+ @Override
+ public NewSignificantCode newSignificantCode() {
+ if (analysisMode.isIssues()) {
+ return NO_OP_NEW_SIGNIFICANT_CODE;
+ }
+ return new DefaultSignificantCode(sensorStorage);
+ }
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorStorage.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorStorage.java
index 1ccd219c600..c4ca921f7ea 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorStorage.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorStorage.java
@@ -36,6 +36,7 @@ import org.sonar.api.batch.fs.TextRange;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.measure.Metric;
import org.sonar.api.batch.measure.MetricFinder;
+import org.sonar.api.batch.sensor.code.internal.DefaultSignificantCode;
import org.sonar.api.batch.sensor.coverage.internal.DefaultCoverage;
import org.sonar.api.batch.sensor.cpd.internal.DefaultCpdTokens;
import org.sonar.api.batch.sensor.error.AnalysisError;
@@ -424,7 +425,7 @@ public class DefaultSensorStorage implements SensorStorage {
inputFile.setPublished(true);
int componentRef = inputFile.batchId();
if (writer.hasComponentData(FileStructure.Domain.SYMBOLS, componentRef)) {
- throw new UnsupportedOperationException("Trying to save symbol table twice for the same file is not supported: " + symbolTable.inputFile().absolutePath());
+ throw new UnsupportedOperationException("Trying to save symbol table twice for the same file is not supported: " + symbolTable.inputFile());
}
final ScannerReport.Symbol.Builder builder = ScannerReport.Symbol.newBuilder();
final ScannerReport.TextRange.Builder rangeBuilder = ScannerReport.TextRange.newBuilder();
@@ -507,4 +508,28 @@ public class DefaultSensorStorage implements SensorStorage {
contextPropertiesCache.put(key, value);
}
+ @Override
+ public void store(DefaultSignificantCode significantCode) {
+ ScannerReportWriter writer = reportPublisher.getWriter();
+ DefaultInputFile inputFile = (DefaultInputFile) significantCode.inputFile();
+ if (shouldSkipStorage(inputFile)) {
+ return;
+ }
+ inputFile.setPublished(true);
+ int componentRef = inputFile.batchId();
+ if (writer.hasComponentData(FileStructure.Domain.SGNIFICANT_CODE, componentRef)) {
+ throw new UnsupportedOperationException(
+ "Trying to save significant code information twice for the same file is not supported: " + significantCode.inputFile());
+ }
+
+ List<ScannerReport.LineSgnificantCode> protobuf = significantCode.significantCodePerLine().values().stream()
+ .map(range -> ScannerReport.LineSgnificantCode.newBuilder()
+ .setLine(range.start().line())
+ .setStartOffset(range.start().lineOffset())
+ .setEndOffset(range.end().lineOffset())
+ .build())
+ .collect(Collectors.toList());
+
+ writer.writeComponentSignificantCode(componentRef, protobuf);
+ }
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/noop/NoOpNewSignificantCode.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/noop/NoOpNewSignificantCode.java
new file mode 100644
index 00000000000..f7c7f223759
--- /dev/null
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/noop/NoOpNewSignificantCode.java
@@ -0,0 +1,45 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * 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.
+ */
+package org.sonar.scanner.sensor.noop;
+
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.TextRange;
+import org.sonar.api.batch.sensor.code.NewSignificantCode;
+
+public class NoOpNewSignificantCode implements NewSignificantCode {
+
+ @Override
+ public NewSignificantCode onFile(InputFile file) {
+ // no op
+ return this;
+ }
+
+ @Override
+ public NewSignificantCode addRange(TextRange range) {
+ // no op
+ return this;
+ }
+
+ @Override
+ public void save() {
+ // no op
+ }
+
+}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorContextTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorContextTest.java
index ee1c4a34872..1d0e59b46c2 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorContextTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorContextTest.java
@@ -88,6 +88,14 @@ public class DefaultSensorContextTest {
assertThat(adaptor.newMeasure()).isNotNull();
assertThat(adaptor.newAnalysisError()).isEqualTo(DefaultSensorContext.NO_OP_NEW_ANALYSIS_ERROR);
assertThat(adaptor.isCancelled()).isFalse();
+ assertThat(adaptor.newSignificantCode()).isNotNull();
+ }
+
+ @Test
+ public void shouldSkipSignificantCodeOnPreviewMode() {
+ when(analysisMode.isIssues()).thenReturn(true);
+ assertThat(adaptor.newSignificantCode()).isEqualTo(DefaultSensorContext.NO_OP_NEW_SIGNIFICANT_CODE);
+
}
@Test
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorStorageTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorStorageTest.java
index bb039e2da18..27b67e50220 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorStorageTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorStorageTest.java
@@ -34,6 +34,7 @@ import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.fs.internal.DefaultInputModule;
import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
import org.sonar.api.batch.measure.MetricFinder;
+import org.sonar.api.batch.sensor.code.internal.DefaultSignificantCode;
import org.sonar.api.batch.sensor.highlighting.TypeOfText;
import org.sonar.api.batch.sensor.highlighting.internal.DefaultHighlighting;
import org.sonar.api.batch.sensor.issue.ExternalIssue;
@@ -216,6 +217,33 @@ public class DefaultSensorStorageTest {
}
@Test
+ public void should_skip_significant_code_on_pull_request_when_file_status_is_SAME() {
+ DefaultInputFile file = new TestInputFileBuilder("foo", "src/Foo.php")
+ .setStatus(InputFile.Status.SAME)
+ .setContents("foo")
+ .build();
+ when(branchConfiguration.isShortOrPullRequest()).thenReturn(true);
+
+ underTest.store(new DefaultSignificantCode()
+ .onFile(file)
+ .addRange(file.selectLine(1)));
+
+ assertThat(reportWriter.hasComponentData(FileStructure.Domain.SGNIFICANT_CODE, file.batchId())).isFalse();
+ }
+
+ @Test
+ public void should_save_significant_code() {
+ DefaultInputFile file = new TestInputFileBuilder("foo", "src/Foo.php")
+ .setContents("foo")
+ .build();
+ underTest.store(new DefaultSignificantCode()
+ .onFile(file)
+ .addRange(file.selectLine(1)));
+
+ assertThat(reportWriter.hasComponentData(FileStructure.Domain.SGNIFICANT_CODE, file.batchId())).isTrue();
+ }
+
+ @Test
public void should_save_project_measure() throws IOException {
String projectKey = "myProject";
DefaultInputModule module = new DefaultInputModule(ProjectDefinition.create().setKey(projectKey).setBaseDir(temp.newFolder()).setWorkDir(temp.newFolder()));
@@ -244,6 +272,16 @@ public class DefaultSensorStorageTest {
}
@Test(expected = UnsupportedOperationException.class)
+ public void duplicateSignificantCode() throws Exception {
+ InputFile inputFile = new TestInputFileBuilder("foo", "src/Foo.java")
+ .setModuleBaseDir(temp.newFolder().toPath()).build();
+ DefaultSignificantCode h = new DefaultSignificantCode(null)
+ .onFile(inputFile);
+ underTest.store(h);
+ underTest.store(h);
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
public void duplicateSymbolTable() throws Exception {
InputFile inputFile = new TestInputFileBuilder("foo", "src/Foo.java")
.setModuleBaseDir(temp.newFolder().toPath()).build();