@@ -42,56 +42,9 @@ predicate isWithinVisibleForTestingContext(Callable c) {
4242 isWithinVisibleForTestingContext ( c .getEnclosingCallable ( ) )
4343}
4444
45- /**
46- * Holds if a nested class is within a static context
47- */
48- predicate withinStaticContext ( NestedClass c ) {
49- c .isStatic ( ) or
50- c .( AnonymousClass ) .getClassInstanceExpr ( ) .getEnclosingCallable ( ) .isStatic ( ) // JLS 15.9.2
51- }
52-
53- /**
54- * Gets the enclosing instance type for a non-static inner class
55- */
56- RefType enclosingInstanceType ( Class inner ) {
57- not withinStaticContext ( inner ) and
58- result = inner .( NestedClass ) .getEnclosingType ( )
59- }
60-
61- /**
62- * A class that encloses one or more inner classes
63- */
64- class OuterClass extends Class {
65- OuterClass ( ) { this = enclosingInstanceType + ( _) }
66- }
67-
68- /**
69- * Holds if an innerclass is accessed outside of its outerclass
70- * and also outside of its fellow inner parallel classes
71- */
72- predicate isWithinDirectOuterClassOrSiblingInner (
73- Callable classInstanceEnclosing , RefType typeBeingConstructed
74- ) {
75- exists ( NestedClass inner , OuterClass outer |
76- outer = enclosingInstanceType ( inner ) and
77- typeBeingConstructed = inner and
78- // where the inner is called from the outer class
79- classInstanceEnclosing .getDeclaringType ( ) = outer
80- )
81- or
82- // and inner is called from the a parallel inner
83- exists ( NestedClass inner , OuterClass outer , NestedClass otherinner |
84- typeBeingConstructed = inner and
85- outer = enclosingInstanceType ( otherinner ) and
86- outer = enclosingInstanceType ( inner ) and
87- classInstanceEnclosing .getDeclaringType ( ) = otherinner
88- )
89- }
90-
91- from Annotatable annotated , Annotation annotation , Expr e
45+ from Annotatable annotated , Expr e
9246where
93- annotation .getType ( ) .hasName ( "VisibleForTesting" ) and
94- annotated .getAnAnnotation ( ) = annotation and
47+ annotated .getAnAnnotation ( ) .getType ( ) .hasName ( "VisibleForTesting" ) and
9548 (
9649 // field access
9750 exists ( FieldAccess v |
@@ -109,24 +62,6 @@ where
10962 )
11063 )
11164 or
112- // class instantiation
113- exists ( ClassInstanceExpr c |
114- c = e and
115- c .getConstructedType ( ) = annotated and
116- // depending on the visiblity of the class, using the annotation to abuse the visibility may/may not be occurring
117- // if public report when its used outside its package because package protected should have been enough (package only permitted)
118- (
119- c .getConstructedType ( ) .isPublic ( ) and
120- not isWithinPackage ( c , c .getConstructedType ( ) )
121- or
122- // if its package protected report when its used outside its outer class bc it should have been private (outer class only permitted)
123- c .getConstructedType ( ) .hasNoModifier ( ) and
124- // and the class is an innerclass, because otherwise recommending a lower accessibility makes no sense (only inner classes can be private)
125- exists ( enclosingInstanceType ( c .getConstructedType ( ) ) ) and
126- not isWithinDirectOuterClassOrSiblingInner ( c .getEnclosingCallable ( ) , c .getConstructedType ( ) )
127- )
128- )
129- or
13065 // method access
13166 exists ( MethodCall c |
13267 c = e and
@@ -142,6 +77,19 @@ where
14277 not isWithinPackage ( c , c .getMethod ( ) .getDeclaringType ( ) )
14378 )
14479 )
80+ or
81+ // Class instantiation - report if used outside appropriate scope
82+ exists ( ClassInstanceExpr c |
83+ c = e and
84+ c .getConstructedType ( ) = annotated and
85+ (
86+ c .getConstructedType ( ) .isPublic ( ) and not isWithinPackage ( c , c .getConstructedType ( ) )
87+ or
88+ c .getConstructedType ( ) .hasNoModifier ( ) and
89+ c .getConstructedType ( ) instanceof NestedClass and
90+ not isWithinType ( c .getEnclosingCallable ( ) , c .getConstructedType ( ) )
91+ )
92+ )
14593 ) and
14694 // not in a test where use is appropriate
14795 not e .getEnclosingCallable ( ) instanceof LikelyTestMethod and
0 commit comments