aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-plugin-api
diff options
context:
space:
mode:
authorJulien HENRY <julien.henry@sonarsource.com>2018-11-13 15:38:22 +0100
committersonartech <sonartech@sonarsource.com>2019-01-16 09:42:59 +0100
commit4a659a05cf4ff177629e9cb78aa6a0721810ff61 (patch)
tree6f9a066e40db44cff8808f3d58285d2e7600fd8e /sonar-plugin-api
parent8bbac3c6e0023978a59814cd1e77fd0efcb6c265 (diff)
downloadsonarqube-4a659a05cf4ff177629e9cb78aa6a0721810ff61.tar.gz
sonarqube-4a659a05cf4ff177629e9cb78aa6a0721810ff61.zip
SONAR-11465 NoSonarFilter moved to project level
Diffstat (limited to 'sonar-plugin-api')
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputFile.java17
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/issue/NoSonarFilter.java43
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/issue/NoSonarFilterTest.java69
3 files changed, 31 insertions, 98 deletions
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputFile.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputFile.java
index 278d288d185..f7d640a4dbb 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputFile.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputFile.java
@@ -30,6 +30,8 @@ import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
import java.util.function.Consumer;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
@@ -56,6 +58,7 @@ public class DefaultInputFile extends DefaultInputComponent implements InputFile
private Metadata metadata;
private boolean published;
private boolean excludedForCoverage;
+ private final Set<Integer> noSonarLines = new HashSet<>();
public DefaultInputFile(DefaultIndexedFile indexedFile, Consumer<DefaultInputFile> metadataGenerator) {
this(indexedFile, metadataGenerator, null);
@@ -82,7 +85,7 @@ public class DefaultInputFile extends DefaultInputComponent implements InputFile
public InputStream inputStream() throws IOException {
return contents != null ? new ByteArrayInputStream(contents.getBytes(charset()))
: new BOMInputStream(Files.newInputStream(path()),
- ByteOrderMark.UTF_8, ByteOrderMark.UTF_16LE, ByteOrderMark.UTF_16BE, ByteOrderMark.UTF_32LE, ByteOrderMark.UTF_32BE);
+ ByteOrderMark.UTF_8, ByteOrderMark.UTF_16LE, ByteOrderMark.UTF_16BE, ByteOrderMark.UTF_32LE, ByteOrderMark.UTF_32BE);
}
@Override
@@ -242,7 +245,7 @@ public class DefaultInputFile extends DefaultInputComponent implements InputFile
checkMetadata();
Preconditions.checkState(metadata.originalLineEndOffsets() != null, "InputFile is not properly initialized.");
Preconditions.checkState(metadata.originalLineEndOffsets().length == metadata.lines(),
- "InputFile is not properly initialized. 'originalLineEndOffsets' property length should be equal to 'lines'");
+ "InputFile is not properly initialized. 'originalLineEndOffsets' property length should be equal to 'lines'");
return metadata.originalLineEndOffsets();
}
@@ -299,7 +302,7 @@ public class DefaultInputFile extends DefaultInputComponent implements InputFile
int line = findLine(globalOffset);
int startLineOffset = originalLineStartOffsets()[line - 1];
// In case the global offset is between \r and \n, move the pointer to a valid location
- return new DefaultTextPointer(line, Math.min(globalOffset, originalLineEndOffsets()[line -1]) - startLineOffset);
+ return new DefaultTextPointer(line, Math.min(globalOffset, originalLineEndOffsets()[line - 1]) - startLineOffset);
}
public DefaultInputFile setStatus(Status status) {
@@ -369,4 +372,12 @@ public class DefaultInputFile extends DefaultInputComponent implements InputFile
return indexedFile.uri();
}
+ public void noSonarAt(Set<Integer> noSonarLines) {
+ this.noSonarLines.addAll(noSonarLines);
+ }
+
+ public boolean hasNoSonarAt(int line) {
+ return this.noSonarLines.contains(line);
+ }
+
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/issue/NoSonarFilter.java b/sonar-plugin-api/src/main/java/org/sonar/api/issue/NoSonarFilter.java
index 947b6d28c18..a58e5f02e4f 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/issue/NoSonarFilter.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/issue/NoSonarFilter.java
@@ -19,63 +19,34 @@
*/
package org.sonar.api.issue;
-import java.util.HashMap;
-import java.util.Map;
import java.util.Set;
-import org.apache.commons.lang.StringUtils;
-import org.sonar.api.batch.ScannerSide;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
-import org.sonar.api.scan.issue.filter.FilterableIssue;
-import org.sonar.api.scan.issue.filter.IssueFilter;
-import org.sonar.api.scan.issue.filter.IssueFilterChain;
+import org.sonar.api.scanner.ScannerSide;
/**
* Issue filter used to ignore issues created on lines commented with the tag "NOSONAR".
* <br>
- * Plugins, via {@link ScannerSide}s, must feed this filter by registering the
+ * Plugins, via {@link org.sonar.api.batch.sensor.Sensor}s, must feed this filter by registering the
* lines that contain "NOSONAR". Note that filters are disabled for the issues reported by
* end-users from UI or web services.
*
* @since 3.6
*/
-public class NoSonarFilter implements IssueFilter {
-
- private final Map<String, Set<Integer>> noSonarLinesByResource = new HashMap<>();
-
- /**
- * @deprecated since 5.0 use {@link #noSonarInFile(InputFile, Set)}
- */
- @Deprecated
- public NoSonarFilter addComponent(String componentKey, Set<Integer> noSonarLines) {
- noSonarLinesByResource.put(componentKey, noSonarLines);
- return this;
- }
+@ScannerSide
+public class NoSonarFilter {
/**
* Register lines in a file that contains the NOSONAR flag.
+ *
* @param inputFile
* @param noSonarLines Line number starts at 1 in a file
* @since 5.0
+ * @since 7.6 the method can be called multiple times by different sensors, and NOSONAR lines are merged
*/
public NoSonarFilter noSonarInFile(InputFile inputFile, Set<Integer> noSonarLines) {
- noSonarLinesByResource.put(((DefaultInputFile) inputFile).key(), noSonarLines);
+ ((DefaultInputFile) inputFile).noSonarAt(noSonarLines);
return this;
}
- @Override
- public boolean accept(FilterableIssue issue, IssueFilterChain chain) {
- boolean accepted = true;
- if (issue.line() != null) {
- Set<Integer> noSonarLines = noSonarLinesByResource.get(issue.componentKey());
- accepted = noSonarLines == null || !noSonarLines.contains(issue.line());
- if (!accepted && StringUtils.containsIgnoreCase(issue.ruleKey().rule(), "nosonar")) {
- accepted = true;
- }
- }
- if (accepted) {
- accepted = chain.accept(issue);
- }
- return accepted;
- }
}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/issue/NoSonarFilterTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/issue/NoSonarFilterTest.java
index 3e4435f489b..0665df11878 100644
--- a/sonar-plugin-api/src/test/java/org/sonar/api/issue/NoSonarFilterTest.java
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/issue/NoSonarFilterTest.java
@@ -19,72 +19,23 @@
*/
package org.sonar.api.issue;
-import org.sonar.api.scan.issue.filter.FilterableIssue;
-
-import com.google.common.collect.ImmutableSet;
-import org.junit.Before;
+import java.util.Arrays;
+import java.util.HashSet;
import org.junit.Test;
-import org.sonar.api.scan.issue.filter.IssueFilterChain;
-import org.sonar.api.rule.RuleKey;
-
-import java.util.Set;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.ArgumentMatchers.isA;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
public class NoSonarFilterTest {
- NoSonarFilter filter = new NoSonarFilter();
- IssueFilterChain chain = mock(IssueFilterChain.class);
-
- @Before
- public void setupChain() {
- when(chain.accept(isA(FilterableIssue.class))).thenReturn(true);
- }
-
- @Test
- public void should_ignore_lines_commented_with_nosonar() {
- FilterableIssue issue = mock(FilterableIssue.class);
- when(issue.componentKey()).thenReturn("struts:org.apache.Action");
- when(issue.ruleKey()).thenReturn(RuleKey.of("squid", "AvoidCycles"));
-
- Set<Integer> noSonarLines = ImmutableSet.of(31, 55);
- filter.addComponent("struts:org.apache.Action", noSonarLines);
-
- // issue on file
- when(issue.line()).thenReturn(null);
- assertThat(filter.accept(issue, chain)).isTrue();
-
- // issue on lines
- when(issue.line()).thenReturn(31);
- assertThat(filter.accept(issue, chain)).isFalse();
-
- when(issue.line()).thenReturn(222);
- assertThat(filter.accept(issue, chain)).isTrue();
-
- verify(chain, times(2)).accept(issue);
- }
-
@Test
- public void should_accept_issues_on_no_sonar_rules() {
- // The "No Sonar" rule logs violations on the lines that are flagged with "NOSONAR" !!
- FilterableIssue issue = mock(FilterableIssue.class);
- when(issue.componentKey()).thenReturn("struts:org.apache.Action");
- when(issue.ruleKey()).thenReturn(RuleKey.of("squid", "NoSonarCheck"));
-
- Set<Integer> noSonarLines = ImmutableSet.of(31, 55);
- filter.addComponent("struts:org.apache.Action", noSonarLines);
-
- when(issue.line()).thenReturn(31);
- assertThat(filter.accept(issue, chain)).isTrue();
-
- when(issue.line()).thenReturn(222);
- assertThat(filter.accept(issue, chain)).isTrue();
+ public void should_store_nosonar_lines_on_inputfile() {
+ DefaultInputFile f = TestInputFileBuilder.create("module1", "myfile.java").build();
+ new NoSonarFilter().noSonarInFile(f, new HashSet<>(Arrays.asList(1,4)));
- verify(chain, times(2)).accept(issue);
+ assertThat(f.hasNoSonarAt(1)).isTrue();
+ assertThat(f.hasNoSonarAt(2)).isFalse();
+ assertThat(f.hasNoSonarAt(4)).isTrue();
}
}