Java: Add lambda-aware test detection to VisibleForTesting query

This commit is contained in:
Napalys Klicius
2025-08-24 10:02:43 +00:00
parent 4149968f33
commit 38f517ecfa
3 changed files with 18 additions and 6 deletions

View File

@@ -39,6 +39,20 @@ predicate isWithinVisibleForTestingContext(Callable c) {
isWithinVisibleForTestingContext(c.getEnclosingCallable())
}
/**
* Holds if `e` is within a test method context, including lambda expressions
* within test methods and nested lambdas.
*/
private predicate isWithinTest(Expr e) {
e.getEnclosingCallable() instanceof LikelyTestMethod
or
exists(Method lambda, LambdaExpr lambdaExpr |
lambda = lambdaExpr.asMethod() and
lambda.getEnclosingCallable*() instanceof LikelyTestMethod and
e.getEnclosingCallable() = lambda
)
}
from Annotatable annotated, Expr e
where
annotated.getAnAnnotation().getType().hasName("VisibleForTesting") and
@@ -89,7 +103,7 @@ where
)
) and
// not in a test where use is appropriate
not e.getEnclosingCallable() instanceof LikelyTestMethod and
not isWithinTest(e) and
// not when the accessing method or any enclosing method is @VisibleForTesting (test-to-test communication)
not isWithinVisibleForTestingContext(e.getEnclosingCallable()) and
// not when used in annotation contexts

View File

@@ -14,6 +14,4 @@
| packagetwo/Source.java:14:17:14:29 | f(...) | Access of $@ annotated with VisibleForTesting found in production code. | packagetwo/Annotated.java:16:16:16:16 | f | element |
| packagetwo/Source.java:20:28:20:47 | new AnnotatedClass(...) | Access of $@ annotated with VisibleForTesting found in production code. | packageone/AnnotatedClass.java:4:14:4:27 | AnnotatedClass | element |
| packagetwo/Source.java:24:30:24:40 | Annotated.m | Access of $@ annotated with VisibleForTesting found in production code. | packagetwo/Annotated.java:7:19:7:19 | m | element |
| packagetwo/Source.java:28:27:28:39 | f(...) | Access of $@ annotated with VisibleForTesting found in production code. | packagetwo/Annotated.java:16:16:16:16 | f | element |
| packagetwo/Test.java:24:30:24:40 | Annotated.m | Access of $@ annotated with VisibleForTesting found in production code. | packagetwo/Annotated.java:7:19:7:19 | m | element |
| packagetwo/Test.java:28:27:28:39 | f(...) | Access of $@ annotated with VisibleForTesting found in production code. | packagetwo/Annotated.java:16:16:16:16 | f | element |
| packagetwo/Source.java:28:27:28:39 | f(...) | Access of $@ annotated with VisibleForTesting found in production code. | packagetwo/Annotated.java:16:16:16:16 | f | element |

View File

@@ -21,11 +21,11 @@ public class Test {
// Lambda usage
Runnable lambda = () -> {
String lambdaS = Annotated.m; // $ SPURIOUS: Alert
String lambdaS = Annotated.m; // COMPLIANT
String lambdaS1 = Annotated.m1; // COMPLIANT
String lambdaS2 = Annotated.m2; // COMPLIANT
int lambdaI = Annotated.f(); // $ SPURIOUS: Alert
int lambdaI = Annotated.f(); // COMPLIANT
int lambdaI2 = Annotated.fPublic(); // COMPLIANT
int lambdaI3 = Annotated.fProtected(); // COMPLIANT
};