diff --git a/java-checks/src/main/java/org/sonar/java/checks/NoSonarCheck.java b/java-checks/src/main/java/org/sonar/java/checks/NoSonarCheck.java index c6a12cd5726..c5188461ec9 100644 --- a/java-checks/src/main/java/org/sonar/java/checks/NoSonarCheck.java +++ b/java-checks/src/main/java/org/sonar/java/checks/NoSonarCheck.java @@ -21,12 +21,14 @@ import com.google.common.collect.ImmutableList; import org.sonar.check.Rule; +import org.sonar.check.RuleProperty; import org.sonar.java.RspecKey; import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; import org.sonar.plugins.java.api.tree.SyntaxTrivia; import org.sonar.plugins.java.api.tree.Tree; import java.util.List; +import java.util.regex.Pattern; /** * Note that {@link org.sonar.squidbridge.checks.AbstractNoSonarCheck} can't be used because of bug SSLRSQBR-16. @@ -36,9 +38,17 @@ public class NoSonarCheck extends IssuableSubscriptionVisitor { private static final String PATTERN = "NOSONAR"; + private static final String PATTERN_ONLY_WHEN_NO_DETAILS = "^[/\\*\\s]*NOSONAR[/\\*\\s]*$"; private static final String MESSAGE = "Is //NOSONAR used to exclude false-positive or to hide real quality flaw ?"; private final CommentContainsPatternChecker checker = new CommentContainsPatternChecker(this, PATTERN, MESSAGE); + private final Pattern noDetailsOnlyChecker = Pattern.compile(PATTERN_ONLY_WHEN_NO_DETAILS); + + @RuleProperty( + key = "onlyWhenNoDetailsProvided", + description = "Only raise an issue when //NOSONAR is used alone, without further text (expected to describe why it has been added)", + defaultValue = "false") + protected boolean onlyWhenNoDetailsProvided = false; @Override public List nodesToVisit() { @@ -47,7 +57,13 @@ public List nodesToVisit() { @Override public void visitTrivia(SyntaxTrivia syntaxTrivia) { - checker.checkTrivia(syntaxTrivia); + if (onlyWhenNoDetailsProvided) { + if (noDetailsOnlyChecker.matcher(syntaxTrivia.comment()).matches()) { + addIssue(syntaxTrivia.startLine(), MESSAGE); + } + } else { + checker.checkTrivia(syntaxTrivia); + } } } diff --git a/java-checks/src/main/resources/org/sonar/l10n/java/rules/squid/S1291_java.html b/java-checks/src/main/resources/org/sonar/l10n/java/rules/squid/S1291_java.html index 17cd097d907..3696700f5ce 100644 --- a/java-checks/src/main/resources/org/sonar/l10n/java/rules/squid/S1291_java.html +++ b/java-checks/src/main/resources/org/sonar/l10n/java/rules/squid/S1291_java.html @@ -1,4 +1,6 @@

Any issue to quality rule can be deactivated with the NOSONAR marker. This marker is pretty useful to exclude false-positive results but it can also be used abusively to hide real quality flaws.

This rule raises an issue when NOSONAR is used.

+

If option onlyWhenNoDetailsProvided is set, this rule only raises an isssue when NOSONAR is used alone with no further text on the comment line.
+Enable this option if your policy is to allow usage of NOSONAR but require that the developer adds further comments explaining why.

diff --git a/java-checks/src/test/files/checks/NoSonar.java b/java-checks/src/test/files/checks/NoSonar.java index f61d143ef87..3efb9396e9d 100644 --- a/java-checks/src/test/files/checks/NoSonar.java +++ b/java-checks/src/test/files/checks/NoSonar.java @@ -1,4 +1,5 @@ public class HelloWorld { // Noncompliant {{Is //NOSONAR used to exclude false-positive or to hide real quality flaw ?}} +/* NOSONAR */ // Noncompliant // OK } diff --git a/java-checks/src/test/files/checks/NoSonarNoDetails.java b/java-checks/src/test/files/checks/NoSonarNoDetails.java new file mode 100644 index 00000000000..8869de5133b --- /dev/null +++ b/java-checks/src/test/files/checks/NoSonarNoDetails.java @@ -0,0 +1,14 @@ +public class HelloWorld { +//NOSONAR this is a test message which makes this line // Compliant + +//NOSONAR +// Noncompliant@-1 + +// NOSONAR +// Noncompliant@-1 + +/* NOSONAR */ +// Noncompliant@-1 + +// OK +} diff --git a/java-checks/src/test/java/org/sonar/java/checks/NoSonarCheckTest.java b/java-checks/src/test/java/org/sonar/java/checks/NoSonarCheckTest.java index 95870819781..d879c1a644f 100644 --- a/java-checks/src/test/java/org/sonar/java/checks/NoSonarCheckTest.java +++ b/java-checks/src/test/java/org/sonar/java/checks/NoSonarCheckTest.java @@ -27,6 +27,9 @@ public class NoSonarCheckTest { @Test public void test() { JavaCheckVerifier.verify("src/test/files/checks/NoSonar.java", new NoSonarCheck()); + NoSonarCheck checkOnlyNoDetails = new NoSonarCheck(); + checkOnlyNoDetails.onlyWhenNoDetailsProvided = true; + JavaCheckVerifier.verify("src/test/files/checks/NoSonarNoDetails.java", checkOnlyNoDetails); } }