Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import java.io.IO;

void main() {
IO.println(""); // Compliant
IO.print(""); // Compliant
f();
new A().f();
}

void f() {
IO.println(""); // Compliant
IO.print(""); // Compliant
}

class A {
void f() {
IO.println(""); // Compliant
IO.print(""); // Compliant
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package checks;


import java.io.IO;
import java.io.PrintStream;

class IoPrintlnUsageCheckSample {

void f() {
IO.println(""); // Noncompliant {{Replace this use of IO.println by a logger.}}
IO.print(""); // Noncompliant {{Replace this use of IO.print by a logger.}}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import org.sonar.plugins.java.api.tree.IdentifierTree;
import org.sonar.plugins.java.api.tree.MemberSelectExpressionTree;
import org.sonar.plugins.java.api.tree.Tree;

import java.util.List;

@Rule(key = "S106")
Expand Down Expand Up @@ -53,11 +52,12 @@ public void visitNode(Tree tree) {

private void visitMemberSelectExpression(MemberSelectExpressionTree mset) {
String name = mset.identifier().name();

if ("out".equals(name) && isSystem(mset.expression())) {
reportIssue(mset, "Replace this use of System.out by a logger.");
} else if ("err".equals(name) && isSystem(mset.expression())) {
reportIssue(mset, "Replace this use of System.err by a logger.");
} else if (isIoPrintFunction(mset)) {
reportIssue(mset, "Replace this use of IO." + mset.identifier().name() + " by a logger.");
}
}

Expand All @@ -70,4 +70,12 @@ private static boolean isSystem(ExpressionTree expression) {
}
return identifierTree != null && "System".equals(identifierTree.name());
}

private static boolean isIoPrintFunction(MemberSelectExpressionTree mset) {
boolean isIoFunction = mset.expression().parent() instanceof MemberSelectExpressionTree tree &&
tree.expression() instanceof IdentifierTree identifierTree &&
"IO".equals(identifierTree.name());
// use contains to cover both print and println methods
return isIoFunction && mset.identifier().name().contains("print");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,41 @@
import org.sonar.java.checks.verifier.CheckVerifier;

import static org.sonar.java.checks.verifier.TestUtils.mainCodeSourcesPath;
import static org.sonar.java.checks.verifier.TestUtils.nonCompilingTestSourcesPath;

class SystemOutOrErrUsageCheckTest {
@Test
void test() {
void test_sout() {
CheckVerifier.newVerifier()
.onFile(mainCodeSourcesPath("checks/SystemOutOrErrUsageCheckSample.java"))
.withCheck(new SystemOutOrErrUsageCheck())
.verifyIssues();
}

@Test
void test_compact_source_file() {
void test_sout_compact_source_file() {
CheckVerifier.newVerifier()
.onFile(mainCodeSourcesPath("checks/SystemOutOrErrUsageCheckCompactOnlyMainSample.java"))
.withCheck(new SystemOutOrErrUsageCheck())
.verifyNoIssues();
}

@Test
void test_io() {
CheckVerifier.newVerifier()
.onFile(nonCompilingTestSourcesPath("checks/IoPrintlnUsageCheckSample.java"))
.withCheck(new SystemOutOrErrUsageCheck())
.verifyIssues();
}

@Test
void test_io_compact_source_file() {
CheckVerifier.newVerifier()
.onFile(nonCompilingTestSourcesPath("checks/IoPrintlnUsageCheckCompactSample.java"))
.withCheck(new SystemOutOrErrUsageCheck())
.verifyNoIssues();
}

@Test
void test_compact_source_file_with_regular_class() {
CheckVerifier.newVerifier()
Expand Down
Loading