Skip to content

Commit 691c64a

Browse files
klueverError Prone Team
authored andcommitted
Flag IO.print[ln]() in SystemOut.
#java25 PiperOrigin-RevId: 808172163
1 parent 0b751cd commit 691c64a

File tree

2 files changed

+31
-12
lines changed

2 files changed

+31
-12
lines changed

core/src/main/java/com/google/errorprone/bugpatterns/SystemOut.java

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,19 +37,21 @@
3737
/** A {@link BugChecker}; see the associated {@link BugPattern} annotation for details. */
3838
@BugPattern(
3939
summary =
40-
"Printing to standard output should only be used for debugging, not in production code",
40+
"Production code should not print to standard out or standard error. Standard out and"
41+
+ " standard error should only be used for debugging.",
4142
severity = WARNING,
4243
tags = StandardTags.LIKELY_ERROR)
43-
public class SystemOut extends BugChecker
44+
public final class SystemOut extends BugChecker
4445
implements MethodInvocationTreeMatcher, MemberSelectTreeMatcher {
4546

46-
private static final Matcher<ExpressionTree> SYSTEM_OUT =
47+
private static final Matcher<ExpressionTree> BAD_FIELDS =
4748
anyOf(
4849
staticField(System.class.getName(), "out"), //
4950
staticField(System.class.getName(), "err"));
5051

51-
private static final Matcher<ExpressionTree> PRINT_STACK_TRACE =
52+
private static final Matcher<ExpressionTree> BAD_METHODS =
5253
anyOf(
54+
staticMethod().onClass("java.lang.IO").namedAnyOf("print", "println"),
5355
staticMethod().onClass(Thread.class.getName()).named("dumpStack").withNoParameters(),
5456
instanceMethod()
5557
.onDescendantOf(Throwable.class.getName())
@@ -58,17 +60,11 @@ public class SystemOut extends BugChecker
5860

5961
@Override
6062
public Description matchMemberSelect(MemberSelectTree tree, VisitorState state) {
61-
if (SYSTEM_OUT.matches(tree, state)) {
62-
return describeMatch(tree);
63-
}
64-
return NO_MATCH;
63+
return BAD_FIELDS.matches(tree, state) ? describeMatch(tree) : NO_MATCH;
6564
}
6665

6766
@Override
6867
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
69-
if (PRINT_STACK_TRACE.matches(tree, state)) {
70-
return describeMatch(tree);
71-
}
72-
return NO_MATCH;
68+
return BAD_METHODS.matches(tree, state) ? describeMatch(tree) : NO_MATCH;
7369
}
7470
}

core/src/test/java/com/google/errorprone/bugpatterns/SystemOutTest.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package com.google.errorprone.bugpatterns;
1818

19+
import static com.google.common.truth.TruthJUnit.assume;
20+
1921
import com.google.errorprone.CompilationTestHelper;
2022
import org.junit.Test;
2123
import org.junit.runner.RunWith;
@@ -58,6 +60,27 @@ private void p(PrintStream ps) {}
5860
.doTest();
5961
}
6062

63+
@Test
64+
public void positiveIoPrint() {
65+
assume().that(Runtime.version().feature()).isAtLeast(25);
66+
helper
67+
.addSourceLines(
68+
"Test.java",
69+
"""
70+
class Test {
71+
void main() {
72+
// BUG: Diagnostic contains: SystemOut
73+
IO.print("hello JDK 25");
74+
// BUG: Diagnostic contains: SystemOut
75+
IO.println();
76+
// BUG: Diagnostic contains: SystemOut
77+
IO.println("hello JDK 25");
78+
}
79+
}
80+
""")
81+
.doTest();
82+
}
83+
6184
@Test
6285
public void negative() {
6386
helper

0 commit comments

Comments
 (0)