diff options
author | Duarte Meneses <duarte.meneses@sonarsource.com> | 2018-04-24 15:27:56 +0200 |
---|---|---|
committer | SonarTech <sonartech@sonarsource.com> | 2018-05-09 20:20:46 +0200 |
commit | fa4019b992510560be8c6d1b51bc2dc2f6b41546 (patch) | |
tree | 815cf6138b9e0b3a419c27cfe98e691080264af3 /sonar-scanner-engine | |
parent | 09b3d167fa8f399e18a37d56e7c8cbb61f68f97f (diff) | |
download | sonarqube-fa4019b992510560be8c6d1b51bc2dc2f6b41546.tar.gz sonarqube-fa4019b992510560be8c6d1b51bc2dc2f6b41546.zip |
SONAR-10638 Create Java API for analyzers to report significant code
Diffstat (limited to 'sonar-scanner-engine')
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(); |