3131import static com .google .errorprone .matchers .Matchers .hasModifier ;
3232import static com .google .errorprone .matchers .Matchers .methodHasNoParameters ;
3333import static com .google .errorprone .matchers .Matchers .methodReturns ;
34- import static com .google .errorprone .matchers .Matchers .not ;
3534import static com .google .errorprone .suppliers .Suppliers .VOID_TYPE ;
3635import static com .google .errorprone .util .ASTHelpers .findSuperMethods ;
3736import static com .google .errorprone .util .ASTHelpers .getSymbol ;
37+ import static com .google .errorprone .util .ASTHelpers .isGeneratedConstructor ;
3838
3939import com .google .common .collect .ImmutableSet ;
4040import com .google .errorprone .BugPattern ;
41+ import com .google .errorprone .ErrorProneFlags ;
4142import com .google .errorprone .VisitorState ;
4243import com .google .errorprone .bugpatterns .BugChecker .CompilationUnitTreeMatcher ;
4344import com .google .errorprone .fixes .SuggestedFix ;
5051import com .sun .tools .javac .code .Symbol .MethodSymbol ;
5152import java .util .Optional ;
5253import java .util .regex .Pattern ;
54+ import javax .inject .Inject ;
5355import javax .lang .model .element .Modifier ;
5456
5557/** A bugpattern; see the associated summary. */
6062 severity = ERROR )
6163public final class JUnit3TestNotRun extends BugChecker implements CompilationUnitTreeMatcher {
6264
65+ private final boolean matchTestsize ;
66+
67+ @ Inject
68+ JUnit3TestNotRun (ErrorProneFlags flags ) {
69+ this .matchTestsize = flags .getBoolean ("JUnit3TestNotRun:MatchTestsize" ).orElse (true );
70+ }
71+
6372 /**
6473 * Regular expression for test method name that is misspelled and should be replaced with "test".
6574 * ".est" and "est" are omitted, because they catch real words like "restore", "destroy", "best",
@@ -84,8 +93,6 @@ public final class JUnit3TestNotRun extends BugChecker implements CompilationUni
8493
8594 private static final Matcher <MethodTree > LOOKS_LIKE_TEST_CASE =
8695 allOf (
87- enclosingClass (isJUnit3TestClass ),
88- not (isJunit3TestCase ),
8996 anyOf (methodHasNoParameters (), hasModifier (Modifier .PUBLIC )),
9097 enclosingClass ((t , s ) -> !getSymbol (t ).getSimpleName ().toString ().endsWith ("Base" )),
9198 methodReturns (VOID_TYPE ));
@@ -96,6 +103,9 @@ public Description matchCompilationUnit(CompilationUnitTree unused, VisitorState
96103 new SuppressibleTreePathScanner <Void , Void >(state ) {
97104 @ Override
98105 public Void visitMethod (MethodTree tree , Void unused ) {
106+ if (isGeneratedConstructor (tree )) {
107+ return super .visitMethod (tree , null );
108+ }
99109 checkMethod (tree , calledMethods , state .withPath (getCurrentPath ()))
100110 .ifPresent (state ::reportMatch );
101111 return super .visitMethod (tree , null );
@@ -128,29 +138,40 @@ public Void visitMethodInvocation(MethodInvocationTree tree, Void unused) {
128138 */
129139 public Optional <Description > checkMethod (
130140 MethodTree methodTree , ImmutableSet <MethodSymbol > calledMethods , VisitorState state ) {
131- if (calledMethods .contains (getSymbol (methodTree ))) {
141+ if (!enclosingClass (isJUnit3TestClass ).matches (methodTree , state )) {
142+ return Optional .empty ();
143+ }
144+ if (isJunit3TestCase .matches (methodTree , state )) {
132145 return Optional .empty ();
133146 }
134147 if (!LOOKS_LIKE_TEST_CASE .matches (methodTree , state )) {
135148 return Optional .empty ();
136149 }
150+ if (calledMethods .contains (getSymbol (methodTree ))) {
151+ return Optional .empty ();
152+ }
137153 if (!findSuperMethods (getSymbol (methodTree ), state .getTypes ()).isEmpty ()) {
138154 return Optional .empty ();
139155 }
156+ String methodName = methodTree .getName ().toString ();
157+ if (!methodName .startsWith ("test" )
158+ && !MISSPELLED_NAME .matcher (methodName ).lookingAt ()
159+ && !wouldRunInJUnit4 .matches (methodTree , state )) {
160+ return Optional .empty ();
161+ }
162+ return Optional .of (describeFixes (methodTree , state ));
163+ }
140164
165+ private Description describeFixes (MethodTree methodTree , VisitorState state ) {
141166 SuggestedFix .Builder fix = SuggestedFix .builder ();
142167
143168 String methodName = methodTree .getName ().toString ();
144169 if (!methodName .startsWith ("test" )) {
145170 var matcher = MISSPELLED_NAME .matcher (methodName );
146- String fixedName ;
147- if (matcher .lookingAt ()) {
148- fixedName = matcher .replaceFirst ("test" );
149- } else if (wouldRunInJUnit4 .matches (methodTree , state )) {
150- fixedName = "test" + toUpperCase (methodName .substring (0 , 1 )) + methodName .substring (1 );
151- } else {
152- return Optional .empty ();
153- }
171+ String fixedName =
172+ matcher .lookingAt ()
173+ ? matcher .replaceFirst ("test" )
174+ : "test" + toUpperCase (methodName .substring (0 , 1 )) + methodName .substring (1 );
154175 fix .merge (renameMethod (methodTree , fixedName , state ));
155176 }
156177
@@ -159,6 +180,6 @@ public Optional<Description> checkMethod(
159180 // N.B. must occur in separate step because removeModifiers only removes one modifier at a time.
160181 removeModifiers (methodTree , state , Modifier .STATIC ).ifPresent (fix ::merge );
161182
162- return Optional . of ( describeMatch (methodTree , fix .build () ));
183+ return describeMatch (methodTree , fix .build ());
163184 }
164185}
0 commit comments