Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding support for nullable type upper bounds considering Library mod… #893

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
94 commits
Select commit Hold shift + click to select a range
f71df65
Adding support for nullable type upper bounds considering Library mod…
akulk022 Jan 10, 2024
e27b474
Adding implementation for nullableVariableTypeUpperBounds method
akulk022 Jan 10, 2024
529a26b
Adding method onOverrideTypeParameterUpperBound to Handler Interface …
akulk022 Jan 11, 2024
f10c491
Updating java docs
akulk022 Jan 12, 2024
b122a66
updating variable name and removing redundant variable
akulk022 Jan 12, 2024
50578d7
Update nullaway/src/main/java/com/uber/nullaway/handlers/Handler.java
akulk022 Jan 15, 2024
273a959
updating var name and documentation
akulk022 Jan 15, 2024
88a4799
Merge remote-tracking branch 'origin/library_models_Function_abhijitk…
akulk022 Jan 15, 2024
7849690
Merge branch 'master' into library_models_Function_abhijitk7
akulk022 Jan 15, 2024
ce9609c
using putAll instead of loop
akulk022 Jan 15, 2024
b56733a
adding positive test case
akulk022 Jan 15, 2024
81f8b7d
Adding EmptyLibraryModels abstract class for LibraryModels interface
akulk022 Jan 16, 2024
488f005
Revert "Adding EmptyLibraryModels abstract class for LibraryModels in…
akulk022 Jan 16, 2024
2634b16
Adding documentation for onOverrideTypeParameterUpperBound in Composi…
akulk022 Jan 16, 2024
2730d2a
Adding default implementations for typeVariablesWithNullableUpperBoun…
akulk022 Jan 16, 2024
ec115af
Update nullaway/src/main/java/com/uber/nullaway/handlers/LibraryModel…
akulk022 Jan 16, 2024
f72959f
Removing redundant default implementations from ExampleLibraryModels …
akulk022 Jan 16, 2024
3e0fb0b
Removing positive test case and incorrect java.util.Map library model
akulk022 Jan 17, 2024
ee15c59
documentation improvements
msridhar Jan 17, 2024
f7462aa
Adding support for nullable type upper bounds considering Library mod…
akulk022 Jan 10, 2024
2ee3522
Adding implementation for nullableVariableTypeUpperBounds method
akulk022 Jan 10, 2024
8699e85
Adding method onOverrideTypeParameterUpperBound to Handler Interface …
akulk022 Jan 11, 2024
ae62aaa
Updating java docs
akulk022 Jan 12, 2024
c3eb477
updating variable name and removing redundant variable
akulk022 Jan 12, 2024
c3e17cf
updating var name and documentation
akulk022 Jan 15, 2024
107d40c
Update nullaway/src/main/java/com/uber/nullaway/handlers/Handler.java
akulk022 Jan 15, 2024
e80e35f
using putAll instead of loop
akulk022 Jan 15, 2024
0cfd0e2
adding positive test case
akulk022 Jan 15, 2024
dc1af63
Adding EmptyLibraryModels abstract class for LibraryModels interface
akulk022 Jan 16, 2024
e4d5813
Revert "Adding EmptyLibraryModels abstract class for LibraryModels in…
akulk022 Jan 16, 2024
3bf421d
Adding documentation for onOverrideTypeParameterUpperBound in Composi…
akulk022 Jan 16, 2024
334af66
Adding default implementations for typeVariablesWithNullableUpperBoun…
akulk022 Jan 16, 2024
20f3fe1
Update nullaway/src/main/java/com/uber/nullaway/handlers/LibraryModel…
akulk022 Jan 16, 2024
2453b08
Removing redundant default implementations from ExampleLibraryModels …
akulk022 Jan 16, 2024
c70ec1d
Removing positive test case and incorrect java.util.Map library model
akulk022 Jan 17, 2024
84247a2
library models for nullmarked classes
akulk022 Jan 22, 2024
ac94e7a
Merge remote-tracking branch 'origin/library_models_Function_abhijitk…
akulk022 Jan 22, 2024
6b92af4
updating isAnnotatedTopLevelClass
akulk022 Jan 22, 2024
27918ff
bug fix, still more to do
msridhar Jan 23, 2024
026970c
more fixes, still needs cleanup
msridhar Jan 23, 2024
4e829d7
Updating javadoc for nullMarkedClasses
akulk022 Jan 25, 2024
b94597a
Fix bug with implicit equals() methods in interfaces (#898)
msridhar Jan 25, 2024
091ac38
Fix crash with raw types in overrides in JSpecify mode (#899)
msridhar Jan 25, 2024
115d683
Update instructions for Android and our sample app (#900)
msridhar Jan 25, 2024
373917e
docs
msridhar Jan 29, 2024
986d060
Prepare for release 0.10.22.
yuxincs Jan 29, 2024
00a317a
Prepare next development version.
yuxincs Jan 29, 2024
35eac21
Adding support for nullable type upper bounds considering Library mod…
akulk022 Jan 10, 2024
71cecb4
Adding implementation for nullableVariableTypeUpperBounds method
akulk022 Jan 10, 2024
18a0c6d
Adding method onOverrideTypeParameterUpperBound to Handler Interface …
akulk022 Jan 11, 2024
1f28ff5
Updating java docs
akulk022 Jan 12, 2024
c911842
updating variable name and removing redundant variable
akulk022 Jan 12, 2024
9aea517
updating var name and documentation
akulk022 Jan 15, 2024
ba88839
Update nullaway/src/main/java/com/uber/nullaway/handlers/Handler.java
akulk022 Jan 15, 2024
75436eb
using putAll instead of loop
akulk022 Jan 15, 2024
865873e
adding positive test case
akulk022 Jan 15, 2024
91a12f4
Adding EmptyLibraryModels abstract class for LibraryModels interface
akulk022 Jan 16, 2024
db16c7a
Revert "Adding EmptyLibraryModels abstract class for LibraryModels in…
akulk022 Jan 16, 2024
836ff44
Adding documentation for onOverrideTypeParameterUpperBound in Composi…
akulk022 Jan 16, 2024
6a9d7c1
Adding default implementations for typeVariablesWithNullableUpperBoun…
akulk022 Jan 16, 2024
cea3614
Update nullaway/src/main/java/com/uber/nullaway/handlers/LibraryModel…
akulk022 Jan 16, 2024
7bf7497
Removing redundant default implementations from ExampleLibraryModels …
akulk022 Jan 16, 2024
37c7cb0
Removing positive test case and incorrect java.util.Map library model
akulk022 Jan 17, 2024
26c82dd
library models for nullmarked classes
akulk022 Jan 22, 2024
cd0e659
Adding support for nullable type upper bounds considering Library mod…
akulk022 Jan 10, 2024
1bf78df
Adding implementation for nullableVariableTypeUpperBounds method
akulk022 Jan 10, 2024
268022a
Adding method onOverrideTypeParameterUpperBound to Handler Interface …
akulk022 Jan 11, 2024
5e5df6a
Updating java docs
akulk022 Jan 12, 2024
6c24cbd
updating variable name and removing redundant variable
akulk022 Jan 12, 2024
32f84ac
updating var name and documentation
akulk022 Jan 15, 2024
5f6d9a8
using putAll instead of loop
akulk022 Jan 15, 2024
dcc1507
adding positive test case
akulk022 Jan 15, 2024
4bba915
Adding EmptyLibraryModels abstract class for LibraryModels interface
akulk022 Jan 16, 2024
d24e9c5
Revert "Adding EmptyLibraryModels abstract class for LibraryModels in…
akulk022 Jan 16, 2024
2ba7932
Adding default implementations for typeVariablesWithNullableUpperBoun…
akulk022 Jan 16, 2024
2ea0b77
Removing redundant default implementations from ExampleLibraryModels …
akulk022 Jan 16, 2024
1c1316d
Removing positive test case and incorrect java.util.Map library model
akulk022 Jan 17, 2024
924396c
documentation improvements
msridhar Jan 17, 2024
24d5ed0
updating isAnnotatedTopLevelClass
akulk022 Jan 22, 2024
0de4d12
bug fix, still more to do
msridhar Jan 23, 2024
32aef72
more fixes, still needs cleanup
msridhar Jan 23, 2024
2acffb3
docs
msridhar Jan 29, 2024
e1e23d1
handler updates
akulk022 Jan 29, 2024
fb23172
handler updates
akulk022 Jan 29, 2024
bc0edd1
Merge remote-tracking branch 'origin/library_models_Function_abhijitk…
akulk022 Jan 30, 2024
2dd0ca6
fixes
akulk022 Jan 30, 2024
badfd16
updating docs
akulk022 Jan 30, 2024
6fc4337
fixes
akulk022 Jan 30, 2024
c97e8dc
Merge remote-tracking branch 'origin/library_models_Function_abhijitk…
akulk022 Jan 30, 2024
05fe856
Revert "Prepare next development version."
akulk022 Jan 30, 2024
37a2008
Revert "Prepare for release 0.10.22."
akulk022 Jan 30, 2024
57a2116
Revert "Update instructions for Android and our sample app (#900)"
akulk022 Jan 30, 2024
e2beddc
Revert "Fix crash with raw types in overrides in JSpecify mode (#899)"
akulk022 Jan 30, 2024
f6996d1
Fix crash with raw types in overrides in JSpecify mode (#899)
msridhar Jan 25, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 26 additions & 10 deletions nullaway/src/main/java/com/uber/nullaway/CodeAnnotationInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@
import com.google.errorprone.util.ASTHelpers;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.util.Context;
import com.uber.nullaway.handlers.Handler;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Nullable;
import javax.lang.model.element.ElementKind;

/**
Expand Down Expand Up @@ -120,7 +122,7 @@ public boolean isGenerated(Symbol symbol, Config config) {
symbol));
return false;
}
Symbol.ClassSymbol outermostClassSymbol = get(classSymbol, config).outermostClassSymbol;
Symbol.ClassSymbol outermostClassSymbol = get(classSymbol, config, null).outermostClassSymbol;
return hasDirectAnnotationWithSimpleName(outermostClassSymbol, "Generated");
}

Expand All @@ -145,10 +147,11 @@ private static boolean isClassFieldOfPrimitiveType(Symbol symbol) {
*
* @param symbol symbol for entity
* @param config NullAway config
* @param handler NullAway Handler
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* @param handler NullAway Handler
* @param handler optional NullAway Handler

* @return true if symbol represents an entity contained in a class that is unannotated; false
* otherwise
*/
public boolean isSymbolUnannotated(Symbol symbol, Config config) {
public boolean isSymbolUnannotated(Symbol symbol, Config config, @Nullable Handler handler) {
Symbol.ClassSymbol classSymbol;
if (symbol instanceof Symbol.ClassSymbol) {
classSymbol = (Symbol.ClassSymbol) symbol;
Expand All @@ -162,7 +165,7 @@ public boolean isSymbolUnannotated(Symbol symbol, Config config) {
} else {
classSymbol = castToNonNull(ASTHelpers.enclosingClass(symbol));
}
final ClassCacheRecord classCacheRecord = get(classSymbol, config);
final ClassCacheRecord classCacheRecord = get(classSymbol, config, handler);
boolean inAnnotatedClass = classCacheRecord.isNullnessAnnotated;
if (symbol.getKind().equals(ElementKind.METHOD)
|| symbol.getKind().equals(ElementKind.CONSTRUCTOR)) {
Expand All @@ -176,12 +179,15 @@ public boolean isSymbolUnannotated(Symbol symbol, Config config) {
* Check whether a class should be treated as nullness-annotated.
*
* @param classSymbol The symbol for the class to be checked
* @param config NullAway config
* @param handler NullAway handler
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* @param handler NullAway handler
* @param handler optional NullAway handler

* @return Whether this class should be treated as null-annotated, taking into account annotations
* on enclosing classes, the containing package, and other NullAway configuration like
* annotated packages
*/
public boolean isClassNullAnnotated(Symbol.ClassSymbol classSymbol, Config config) {
return get(classSymbol, config).isNullnessAnnotated;
public boolean isClassNullAnnotated(
Symbol.ClassSymbol classSymbol, Config config, Handler handler) {
return get(classSymbol, config, handler).isNullnessAnnotated;
}

/**
Expand All @@ -190,12 +196,15 @@ public boolean isClassNullAnnotated(Symbol.ClassSymbol classSymbol, Config confi
* <p>This method is recursive, using the cache on the way up and populating it on the way down.
*
* @param classSymbol The class to query, possibly an inner class
* @param config NullAway config
* @param handler NullAway handler
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* @param handler NullAway handler
* @param handler optional NullAway handler

* @return A record including the outermost class in which the given class is nested, as well as
* boolean flag noting whether it should be treated as nullness-annotated, taking into account
* annotations on enclosing classes, the containing package, and other NullAway configuration
* like annotated packages
*/
private ClassCacheRecord get(Symbol.ClassSymbol classSymbol, Config config) {
private ClassCacheRecord get(
Symbol.ClassSymbol classSymbol, Config config, @Nullable Handler handler) {
ClassCacheRecord record = classCache.getIfPresent(classSymbol);
if (record != null) {
return record;
Expand All @@ -211,7 +220,7 @@ private ClassCacheRecord get(Symbol.ClassSymbol classSymbol, Config config) {
Symbol.ClassSymbol enclosingClass = ASTHelpers.enclosingClass(classSymbol);
// enclosingClass can be null in weird cases like for array methods
if (enclosingClass != null) {
ClassCacheRecord recordForEnclosing = get(enclosingClass, config);
ClassCacheRecord recordForEnclosing = get(enclosingClass, config, handler);
// Check if this class is annotated, recall that enclosed scopes override enclosing scopes
boolean isAnnotated = recordForEnclosing.isNullnessAnnotated;
if (enclosingMethod != null) {
Expand All @@ -232,7 +241,8 @@ record = new ClassCacheRecord(recordForEnclosing.outermostClassSymbol, isAnnotat
}
if (record == null) {
// We are already at the outermost class (we can find), so let's create a record for it
record = new ClassCacheRecord(classSymbol, isAnnotatedTopLevelClass(classSymbol, config));
record =
new ClassCacheRecord(classSymbol, isAnnotatedTopLevelClass(classSymbol, config, handler));
}
classCache.put(classSymbol, record);
return record;
Expand All @@ -258,7 +268,8 @@ private boolean shouldTreatAsUnannotated(Symbol.ClassSymbol classSymbol, Config
return false;
}

private boolean isAnnotatedTopLevelClass(Symbol.ClassSymbol classSymbol, Config config) {
private boolean isAnnotatedTopLevelClass(
Symbol.ClassSymbol classSymbol, Config config, @Nullable Handler handler) {
// First, check for an explicitly @NullUnmarked top level class
if (hasDirectAnnotationWithSimpleName(classSymbol, NullabilityUtil.NULLUNMARKED_SIMPLE_NAME)) {
return false;
Expand All @@ -269,7 +280,12 @@ private boolean isAnnotatedTopLevelClass(Symbol.ClassSymbol classSymbol, Config
// make sure it's not explicitly configured as unannotated
return !shouldTreatAsUnannotated(classSymbol, config);
}
return false;
// Check if it is NullMarked inside a Library Model when in JSpecify Mode
if (config.isJSpecifyMode() && handler != null) {
return handler.onOverrideNullMarkedClasses(classSymbol.toString());
} else {
return false;
}
}

/**
Expand Down
24 changes: 23 additions & 1 deletion nullaway/src/main/java/com/uber/nullaway/LibraryModels.java
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,26 @@
*/
ImmutableSet<MethodRef> nonNullReturns();

/**
* Get the (className, type argument index) pairs for library classes where the generic type
* argument has a {@code @Nullable} upper bound. Only used in JSpecify mode.
*
* @return map from the className to the positions of the generic type arguments that have a
* {@code Nullable} upper bound.
*/
default ImmutableSetMultimap<String, Integer> typeVariablesWithNullableUpperBounds() {
return ImmutableSetMultimap.of();
}

/**
* Get the set of library classes that are NullMarked. Only used in JSpecify mode.
*
* @return set of library classes that are NullMarked.
*/
default ImmutableSet<String> nullMarkedClasses() {
return ImmutableSet.of();
}

/**
* Get (method, parameter) pairs that act as castToNonNull(...) methods.
*
Expand All @@ -137,7 +157,9 @@
*
* @return set of library fields that may be {@code null}.
*/
ImmutableSet<FieldRef> nullableFields();
default ImmutableSet<FieldRef> nullableFields() {
return ImmutableSet.of();

Check warning on line 161 in nullaway/src/main/java/com/uber/nullaway/LibraryModels.java

View check run for this annotation

Codecov / codecov/patch

nullaway/src/main/java/com/uber/nullaway/LibraryModels.java#L161

Added line #L161 was not covered by tests
}

/**
* Get a list of custom stream library specifications.
Expand Down
71 changes: 47 additions & 24 deletions nullaway/src/main/java/com/uber/nullaway/NullAway.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import com.google.auto.service.AutoService;
import com.google.auto.value.AutoValue;
import com.google.common.base.Preconditions;
import com.google.common.base.Verify;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableSet;
Expand Down Expand Up @@ -306,7 +307,7 @@ public NullAway(ErrorProneFlags flags) {
private boolean isMethodUnannotated(MethodInvocationNode invocationNode) {
return invocationNode == null
|| codeAnnotationInfo.isSymbolUnannotated(
ASTHelpers.getSymbol(invocationNode.getTree()), config);
ASTHelpers.getSymbol(invocationNode.getTree()), config, handler);
}

private boolean withinAnnotatedCode(VisitorState state) {
Expand Down Expand Up @@ -345,7 +346,7 @@ private boolean checkMarkingForPath(VisitorState state) {
if (enclosingMarkableSymbol == null) {
return false;
}
return !codeAnnotationInfo.isSymbolUnannotated(enclosingMarkableSymbol, config);
return !codeAnnotationInfo.isSymbolUnannotated(enclosingMarkableSymbol, config, handler);
}

@Override
Expand Down Expand Up @@ -399,16 +400,31 @@ public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState
if (!withinAnnotatedCode(state)) {
return Description.NO_MATCH;
}
final Symbol.MethodSymbol methodSymbol = ASTHelpers.getSymbol(tree);
if (methodSymbol == null) {
throw new RuntimeException("not expecting unresolved method here");
}
Symbol.MethodSymbol methodSymbol = getSymbolForMethodInvocation(tree, state);
handler.onMatchMethodInvocation(this, tree, state, methodSymbol);
// assuming this list does not include the receiver
List<? extends ExpressionTree> actualParams = tree.getArguments();
return handleInvocation(tree, state, methodSymbol, actualParams);
}

private static Symbol.MethodSymbol getSymbolForMethodInvocation(
MethodInvocationTree tree, VisitorState state) {
Symbol.MethodSymbol methodSymbol = ASTHelpers.getSymbol(tree);
Verify.verify(methodSymbol != null, "not expecting unresolved method here");
// For interface methods, if the method is an implicit method corresponding to a method from
// java.lang.Object, use the symbol for the java.lang.Object method instead. We do this to
// properly treat the method as unannotated, which is particularly important for equals()
// methods. This is an adaptation to a change in JDK 18; see
// https://bugs.openjdk.org/browse/JDK-8272564
if (methodSymbol.owner.isInterface()) {
Symbol.MethodSymbol baseSymbol = (Symbol.MethodSymbol) methodSymbol.baseSymbol();
if (baseSymbol != methodSymbol && baseSymbol.owner == state.getSymtab().objectType.tsym) {
methodSymbol = baseSymbol;
}
}
return methodSymbol;
}

@Override
public Description matchNewClass(NewClassTree tree, VisitorState state) {
if (!withinAnnotatedCode(state)) {
Expand Down Expand Up @@ -596,7 +612,7 @@ private void checkForMethodNullMarkedness(MethodTree tree, VisitorState state) {
methodSymbol, NullabilityUtil.NULLMARKED_SIMPLE_NAME)) {
// We still care here if this is a transition between @NullUnmarked and @NullMarked code,
// within partially marked code, see checks below for markedMethodInUnmarkedContext.
if (!codeAnnotationInfo.isClassNullAnnotated(methodSymbol.enclClass(), config)) {
if (!codeAnnotationInfo.isClassNullAnnotated(methodSymbol.enclClass(), config, handler)) {
markedMethodInUnmarkedContext = true;
}
}
Expand Down Expand Up @@ -697,7 +713,8 @@ public Description matchParameterizedType(ParameterizedTypeTree tree, VisitorSta
return Description.NO_MATCH;
}
if (config.isJSpecifyMode()) {
GenericsChecks.checkInstantiationForParameterizedTypedTree(tree, state, this, config);
GenericsChecks.checkInstantiationForParameterizedTypedTree(
tree, state, this, config, handler);
}
return Description.NO_MATCH;
}
Expand Down Expand Up @@ -725,7 +742,7 @@ private Description checkParamOverriding(
(memberReferenceTree != null)
&& ((JCTree.JCMemberReference) memberReferenceTree).kind.isUnbound();
final boolean isOverriddenMethodAnnotated =
!codeAnnotationInfo.isSymbolUnannotated(overriddenMethod, config);
!codeAnnotationInfo.isSymbolUnannotated(overriddenMethod, config, handler);

// Get argument nullability for the overridden method. If overriddenMethodArgNullnessMap[i] is
// null, parameter i is treated as unannotated.
Expand Down Expand Up @@ -845,7 +862,8 @@ static Trees getTreesInstance(VisitorState state) {

private Nullness getMethodReturnNullness(
Symbol.MethodSymbol methodSymbol, VisitorState state, Nullness defaultForUnannotated) {
final boolean isMethodAnnotated = !codeAnnotationInfo.isSymbolUnannotated(methodSymbol, config);
final boolean isMethodAnnotated =
!codeAnnotationInfo.isSymbolUnannotated(methodSymbol, config, handler);
Nullness methodReturnNullness =
defaultForUnannotated; // Permissive default for unannotated code.
if (isMethodAnnotated) {
Expand Down Expand Up @@ -900,13 +918,15 @@ private Description checkReturnExpression(
// type is @Nullable, and if so, bail out.
if (getMethodReturnNullness(methodSymbol, state, Nullness.NULLABLE).equals(Nullness.NULLABLE)) {
return Description.NO_MATCH;
} else if (config.isJSpecifyMode()
&& lambdaTree != null
&& GenericsChecks.getGenericMethodReturnTypeNullness(
methodSymbol, ASTHelpers.getType(lambdaTree), state, config)
.equals(Nullness.NULLABLE)) {
// In JSpecify mode, the return type of a lambda may be @Nullable via a type argument
return Description.NO_MATCH;
} else if (config.isJSpecifyMode() && lambdaTree != null) {
if (GenericsChecks.getGenericMethodReturnTypeNullness(
methodSymbol, ASTHelpers.getType(lambdaTree), state, config)
.equals(Nullness.NULLABLE)
|| GenericsChecks.passingLambdaOrMethodRefWithGenericReturnToUnmarkedCode(
methodSymbol, lambdaTree, state, config, codeAnnotationInfo, handler)) {
// In JSpecify mode, the return type of a lambda may be @Nullable via a type argument
return Description.NO_MATCH;
}
}

// Return type is @NonNull. Check if the expression is @Nullable
Expand Down Expand Up @@ -934,7 +954,7 @@ public Description matchLambdaExpression(LambdaExpressionTree tree, VisitorState
// (like Rx nullability) run dataflow analysis
updateEnvironmentMapping(state.getPath(), state);
handler.onMatchLambdaExpression(this, tree, state, funcInterfaceMethod);
if (codeAnnotationInfo.isSymbolUnannotated(funcInterfaceMethod, config)) {
if (codeAnnotationInfo.isSymbolUnannotated(funcInterfaceMethod, config, handler)) {
return Description.NO_MATCH;
}
Description description =
Expand Down Expand Up @@ -1049,8 +1069,10 @@ private boolean overriddenMethodReturnsNonNull(
// For a method reference, we get generic type arguments from javac's inferred type for the
// tree, which properly preserves type-use annotations
return GenericsChecks.getGenericMethodReturnTypeNullness(
overriddenMethod, ASTHelpers.getType(memberReferenceTree), state, config)
.equals(Nullness.NONNULL);
overriddenMethod, ASTHelpers.getType(memberReferenceTree), state, config)
.equals(Nullness.NONNULL)
&& !GenericsChecks.passingLambdaOrMethodRefWithGenericReturnToUnmarkedCode(
overriddenMethod, memberReferenceTree, state, config, codeAnnotationInfo, handler);
} else {
// Use the enclosing class of the overriding method to find generic type arguments
return GenericsChecks.getGenericMethodReturnTypeNullness(
Expand Down Expand Up @@ -1160,7 +1182,7 @@ private boolean relevantInitializerMethodOrBlock(
// in those cases, we won't even have a populated class2Entities map). We skip this check if
// we are not inside a @NullMarked/annotated *class*:
if (nullMarkingForTopLevelClass == NullMarking.PARTIALLY_MARKED
&& !codeAnnotationInfo.isClassNullAnnotated(enclClassSymbol, config)) {
&& !codeAnnotationInfo.isClassNullAnnotated(enclClassSymbol, config, handler)) {
return false;
}

Expand Down Expand Up @@ -1681,7 +1703,8 @@ private Description handleInvocation(
return Description.NO_MATCH;
}

final boolean isMethodAnnotated = !codeAnnotationInfo.isSymbolUnannotated(methodSymbol, config);
final boolean isMethodAnnotated =
!codeAnnotationInfo.isSymbolUnannotated(methodSymbol, config, handler);
// If argumentPositionNullness[i] == null, parameter i is unannotated
Nullness[] argumentPositionNullness = new Nullness[formalParams.size()];

Expand Down Expand Up @@ -2271,7 +2294,7 @@ private boolean isExcludedClass(Symbol.ClassSymbol classSymbol) {
if (config.isExcludedClass(className)) {
return true;
}
if (!codeAnnotationInfo.isClassNullAnnotated(classSymbol, config)) {
if (!codeAnnotationInfo.isClassNullAnnotated(classSymbol, config, handler)) {
return true;
}
// check annotations
Expand Down Expand Up @@ -2404,7 +2427,7 @@ private boolean mayBeNullExpr(VisitorState state, ExpressionTree expr) {

private boolean mayBeNullMethodCall(
Symbol.MethodSymbol exprSymbol, MethodInvocationTree invocationTree, VisitorState state) {
if (codeAnnotationInfo.isSymbolUnannotated(exprSymbol, config)) {
if (codeAnnotationInfo.isSymbolUnannotated(exprSymbol, config, handler)) {
return false;
}
if (Nullness.hasNullableAnnotation(exprSymbol, config)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ public static boolean mayBeNullFieldFromType(
Symbol symbol, Config config, CodeAnnotationInfo codeAnnotationInfo) {
return !(symbol.getSimpleName().toString().equals("class")
|| symbol.isEnum()
|| codeAnnotationInfo.isSymbolUnannotated(symbol, config))
|| codeAnnotationInfo.isSymbolUnannotated(symbol, config, null))
&& Nullness.hasNullableAnnotation(symbol, config);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ private static NullnessStore lambdaInitialStore(
types.memberType(ASTHelpers.getType(code), fiMethodSymbol).getParameterTypes();
// If fiArgumentPositionNullness[i] == null, parameter position i is unannotated
Nullness[] fiArgumentPositionNullness = new Nullness[fiMethodParameters.size()];
final boolean isFIAnnotated = !codeAnnotationInfo.isSymbolUnannotated(fiMethodSymbol, config);
final boolean isFIAnnotated =
!codeAnnotationInfo.isSymbolUnannotated(fiMethodSymbol, config, handler);
if (isFIAnnotated) {
for (int i = 0; i < fiMethodParameters.size(); i++) {
if (Nullness.hasNullableAnnotation(fiMethodParameters.get(i), config)) {
Expand Down
Loading
Loading