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. */
6062severity =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
8594private static final Matcher <MethodTree >LOOKS_LIKE_TEST_CASE =
8695allOf (
87- enclosingClass (isJUnit3TestClass ),
88- not (isJunit3TestCase ),
8996anyOf (methodHasNoParameters (),hasModifier (Modifier .PUBLIC )),
9097enclosingClass ((t ,s ) -> !getSymbol (t ).getSimpleName ().toString ().endsWith ("Base" )),
9198methodReturns (VOID_TYPE ));
@@ -96,6 +103,9 @@ public Description matchCompilationUnit(CompilationUnitTree unused, VisitorState
96103new SuppressibleTreePathScanner <Void ,Void >(state ) {
97104@ Override
98105public Void visitMethod (MethodTree tree ,Void unused ) {
106+ if (isGeneratedConstructor (tree )) {
107+ return super .visitMethod (tree ,null );
108+ }
99109checkMethod (tree ,calledMethods ,state .withPath (getCurrentPath ()))
100110 .ifPresent (state ::reportMatch );
101111return super .visitMethod (tree ,null );
@@ -128,29 +138,40 @@ public Void visitMethodInvocation(MethodInvocationTree tree, Void unused) {
128138 */
129139public Optional <Description >checkMethod (
130140MethodTree 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 )) {
132145return Optional .empty ();
133146 }
134147if (!LOOKS_LIKE_TEST_CASE .matches (methodTree ,state )) {
135148return Optional .empty ();
136149 }
150+ if (calledMethods .contains (getSymbol (methodTree ))) {
151+ return Optional .empty ();
152+ }
137153if (!findSuperMethods (getSymbol (methodTree ),state .getTypes ()).isEmpty ()) {
138154return 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 ) {
141166SuggestedFix .Builder fix =SuggestedFix .builder ();
142167
143168String methodName =methodTree .getName ().toString ();
144169if (!methodName .startsWith ("test" )) {
145170var 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 );
154175fix .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.
160181removeModifiers (methodTree ,state ,Modifier .STATIC ).ifPresent (fix ::merge );
161182
162- return Optional . of ( describeMatch (methodTree ,fix .build () ));
183+ return describeMatch (methodTree ,fix .build ());
163184 }
164185}