diff --git a/nullaway/src/main/java/com/uber/nullaway/NullAway.java b/nullaway/src/main/java/com/uber/nullaway/NullAway.java index 01a43ae229..925fab01c9 100644 --- a/nullaway/src/main/java/com/uber/nullaway/NullAway.java +++ b/nullaway/src/main/java/com/uber/nullaway/NullAway.java @@ -761,7 +761,10 @@ private Description checkParamOverriding( // Check handlers for any further/overriding nullness information overriddenMethodArgNullnessMap = handler.onOverrideMethodInvocationParametersNullability( - state, overriddenMethod, isOverriddenMethodAnnotated, overriddenMethodArgNullnessMap); + state.context, + overriddenMethod, + isOverriddenMethodAnnotated, + overriddenMethodArgNullnessMap); // If we have an unbound method reference, the first parameter of the overridden method must be // @NonNull, as this parameter will be used as a method receiver inside the generated lambda. @@ -1712,7 +1715,7 @@ private Description handleInvocation( // Allow handlers to override the list of non-null argument positions argumentPositionNullness = handler.onOverrideMethodInvocationParametersNullability( - state, methodSymbol, isMethodAnnotated, argumentPositionNullness); + state.context, methodSymbol, isMethodAnnotated, argumentPositionNullness); // now actually check the arguments // NOTE: the case of an invocation on a possibly-null reference diff --git a/nullaway/src/main/java/com/uber/nullaway/dataflow/AccessPathNullnessPropagation.java b/nullaway/src/main/java/com/uber/nullaway/dataflow/AccessPathNullnessPropagation.java index fb18368afe..b68665ad0b 100644 --- a/nullaway/src/main/java/com/uber/nullaway/dataflow/AccessPathNullnessPropagation.java +++ b/nullaway/src/main/java/com/uber/nullaway/dataflow/AccessPathNullnessPropagation.java @@ -206,7 +206,7 @@ private static Node unwrapAssignExpr(Node node) { public NullnessStore initialStore( UnderlyingAST underlyingAST, List parameters) { return nullnessStoreInitializer.getInitialStore( - underlyingAST, parameters, handler, state, config); + underlyingAST, parameters, handler, state.context, state.getTypes(), config); } @Override diff --git a/nullaway/src/main/java/com/uber/nullaway/dataflow/CoreNullnessStoreInitializer.java b/nullaway/src/main/java/com/uber/nullaway/dataflow/CoreNullnessStoreInitializer.java index 170ccb1a7d..2dfce9fc74 100644 --- a/nullaway/src/main/java/com/uber/nullaway/dataflow/CoreNullnessStoreInitializer.java +++ b/nullaway/src/main/java/com/uber/nullaway/dataflow/CoreNullnessStoreInitializer.java @@ -3,7 +3,6 @@ import static com.uber.nullaway.Nullness.NONNULL; import static com.uber.nullaway.Nullness.NULLABLE; -import com.google.errorprone.VisitorState; import com.google.errorprone.util.ASTHelpers; import com.sun.source.tree.ClassTree; import com.sun.source.tree.LambdaExpressionTree; @@ -31,9 +30,9 @@ public NullnessStore getInitialStore( UnderlyingAST underlyingAST, List parameters, Handler handler, - VisitorState state, + Context context, + Types types, Config config) { - Context context = state.context; if (underlyingAST.getKind().equals(UnderlyingAST.Kind.ARBITRARY_CODE)) { // not a method or a lambda; an initializer expression or block UnderlyingAST.CFGStatement ast = (UnderlyingAST.CFGStatement) underlyingAST; @@ -45,7 +44,8 @@ public NullnessStore getInitialStore( (UnderlyingAST.CFGLambda) underlyingAST, parameters, handler, - state, + context, + types, config, getCodeAnnotationInfo(context)); } else { @@ -77,12 +77,13 @@ private static NullnessStore lambdaInitialStore( UnderlyingAST.CFGLambda underlyingAST, List parameters, Handler handler, - VisitorState state, + Context context, + Types types, Config config, CodeAnnotationInfo codeAnnotationInfo) { // include nullness info for locals from enclosing environment EnclosingEnvironmentNullness environmentNullness = - EnclosingEnvironmentNullness.instance(state.context); + EnclosingEnvironmentNullness.instance(context); NullnessStore environmentMapping = Objects.requireNonNull( environmentNullness.getEnvironmentMapping(underlyingAST.getLambdaTree()), @@ -90,7 +91,6 @@ private static NullnessStore lambdaInitialStore( NullnessStore.Builder result = environmentMapping.toBuilder(); LambdaExpressionTree code = underlyingAST.getLambdaTree(); // need to check annotation for i'th parameter of functional interface declaration - Types types = state.getTypes(); Symbol.MethodSymbol fiMethodSymbol = NullabilityUtil.getFunctionalInterfaceMethod(code, types); com.sun.tools.javac.util.List fiMethodParameters = fiMethodSymbol.getParameters(); @@ -119,7 +119,7 @@ private static NullnessStore lambdaInitialStore( } fiArgumentPositionNullness = handler.onOverrideMethodInvocationParametersNullability( - state, fiMethodSymbol, isFIAnnotated, fiArgumentPositionNullness); + context, fiMethodSymbol, isFIAnnotated, fiArgumentPositionNullness); for (int i = 0; i < parameters.size(); i++) { LocalVariableNode param = parameters.get(i); diff --git a/nullaway/src/main/java/com/uber/nullaway/dataflow/NullnessStoreInitializer.java b/nullaway/src/main/java/com/uber/nullaway/dataflow/NullnessStoreInitializer.java index 37c68d3a61..c654621933 100644 --- a/nullaway/src/main/java/com/uber/nullaway/dataflow/NullnessStoreInitializer.java +++ b/nullaway/src/main/java/com/uber/nullaway/dataflow/NullnessStoreInitializer.java @@ -1,10 +1,10 @@ package com.uber.nullaway.dataflow; -import com.google.errorprone.VisitorState; import com.google.errorprone.util.ASTHelpers; import com.sun.source.tree.ClassTree; import com.sun.source.util.Trees; import com.sun.tools.javac.code.Symbol; +import com.sun.tools.javac.code.Types; import com.sun.tools.javac.processing.JavacProcessingEnvironment; import com.sun.tools.javac.util.Context; import com.uber.nullaway.Config; @@ -30,7 +30,8 @@ public abstract class NullnessStoreInitializer { * @param underlyingAST The AST node being matched. * @param parameters list of local variable nodes. * @param handler reference to the handler invoked. - * @param state the visitor state. + * @param context context. + * @param types types. * @param config config for analysis. * @return Initial Nullness store. */ @@ -38,7 +39,8 @@ public abstract NullnessStore getInitialStore( UnderlyingAST underlyingAST, List parameters, Handler handler, - VisitorState state, + Context context, + Types types, Config config); /** diff --git a/nullaway/src/main/java/com/uber/nullaway/handlers/BaseNoOpHandler.java b/nullaway/src/main/java/com/uber/nullaway/handlers/BaseNoOpHandler.java index 9260711d74..815b46d7aa 100644 --- a/nullaway/src/main/java/com/uber/nullaway/handlers/BaseNoOpHandler.java +++ b/nullaway/src/main/java/com/uber/nullaway/handlers/BaseNoOpHandler.java @@ -126,7 +126,7 @@ public boolean onOverrideFieldNullability(Symbol field) { @Override public Nullness[] onOverrideMethodInvocationParametersNullability( - VisitorState state, + Context context, Symbol.MethodSymbol methodSymbol, boolean isAnnotated, Nullness[] argumentPositionNullness) { diff --git a/nullaway/src/main/java/com/uber/nullaway/handlers/CompositeHandler.java b/nullaway/src/main/java/com/uber/nullaway/handlers/CompositeHandler.java index f857d06fef..2001269fbd 100644 --- a/nullaway/src/main/java/com/uber/nullaway/handlers/CompositeHandler.java +++ b/nullaway/src/main/java/com/uber/nullaway/handlers/CompositeHandler.java @@ -149,14 +149,14 @@ public boolean onOverrideFieldNullability(Symbol field) { @Override public Nullness[] onOverrideMethodInvocationParametersNullability( - VisitorState state, + Context context, Symbol.MethodSymbol methodSymbol, boolean isAnnotated, Nullness[] argumentPositionNullness) { for (Handler h : handlers) { argumentPositionNullness = h.onOverrideMethodInvocationParametersNullability( - state, methodSymbol, isAnnotated, argumentPositionNullness); + context, methodSymbol, isAnnotated, argumentPositionNullness); } return argumentPositionNullness; } diff --git a/nullaway/src/main/java/com/uber/nullaway/handlers/Handler.java b/nullaway/src/main/java/com/uber/nullaway/handlers/Handler.java index 7033e40ea5..b2018ee294 100644 --- a/nullaway/src/main/java/com/uber/nullaway/handlers/Handler.java +++ b/nullaway/src/main/java/com/uber/nullaway/handlers/Handler.java @@ -192,7 +192,7 @@ Nullness onOverrideMethodReturnNullability( * considered isAnnotated or not. We use a mutable map for performance, but it should not outlive * the chain of handler invocations. * - * @param state The current visitor state. + * @param context The current context. * @param methodSymbol The method symbol for the method in question. * @param isAnnotated A boolean flag indicating whether the called method is considered to be * within isAnnotated or unannotated code, used to avoid querying for this information @@ -205,7 +205,7 @@ Nullness onOverrideMethodReturnNullability( * handler. */ Nullness[] onOverrideMethodInvocationParametersNullability( - VisitorState state, + Context context, Symbol.MethodSymbol methodSymbol, boolean isAnnotated, Nullness[] argumentPositionNullness); diff --git a/nullaway/src/main/java/com/uber/nullaway/handlers/InferredJARModelsHandler.java b/nullaway/src/main/java/com/uber/nullaway/handlers/InferredJARModelsHandler.java index 71dbd92b62..bd70059580 100644 --- a/nullaway/src/main/java/com/uber/nullaway/handlers/InferredJARModelsHandler.java +++ b/nullaway/src/main/java/com/uber/nullaway/handlers/InferredJARModelsHandler.java @@ -28,6 +28,7 @@ import com.sun.source.tree.Tree; import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.code.Type; +import com.sun.tools.javac.util.Context; import com.uber.nullaway.Config; import com.uber.nullaway.NullAway; import com.uber.nullaway.Nullness; @@ -121,7 +122,7 @@ private void loadStubxFiles() { @Override public Nullness[] onOverrideMethodInvocationParametersNullability( - VisitorState state, + Context context, Symbol.MethodSymbol methodSymbol, boolean isAnnotated, Nullness[] argumentPositionNullness) { diff --git a/nullaway/src/main/java/com/uber/nullaway/handlers/LibraryModelsHandler.java b/nullaway/src/main/java/com/uber/nullaway/handlers/LibraryModelsHandler.java index 09f1c41ffb..fe87278edd 100644 --- a/nullaway/src/main/java/com/uber/nullaway/handlers/LibraryModelsHandler.java +++ b/nullaway/src/main/java/com/uber/nullaway/handlers/LibraryModelsHandler.java @@ -103,11 +103,11 @@ public NullnessHint onDataflowVisitFieldAccess( @Override public Nullness[] onOverrideMethodInvocationParametersNullability( - VisitorState state, + Context context, Symbol.MethodSymbol methodSymbol, boolean isAnnotated, Nullness[] argumentPositionNullness) { - OptimizedLibraryModels optimizedLibraryModels = getOptLibraryModels(state.context); + OptimizedLibraryModels optimizedLibraryModels = getOptLibraryModels(context); ImmutableSet nullableParamsFromModel = optimizedLibraryModels.explicitlyNullableParameters(methodSymbol); ImmutableSet nonNullParamsFromModel = diff --git a/nullaway/src/main/java/com/uber/nullaway/handlers/LombokHandler.java b/nullaway/src/main/java/com/uber/nullaway/handlers/LombokHandler.java index 7d76611b9d..7069497800 100644 --- a/nullaway/src/main/java/com/uber/nullaway/handlers/LombokHandler.java +++ b/nullaway/src/main/java/com/uber/nullaway/handlers/LombokHandler.java @@ -86,26 +86,4 @@ public Nullness onOverrideMethodReturnNullability( } return returnNullness; } - - /** - * Mark the first argument of Lombok-generated {@code equals} methods as {@code @Nullable}, since - * Lombok does not generate the annotation. - */ - @Override - public Nullness[] onOverrideMethodInvocationParametersNullability( - VisitorState state, - Symbol.MethodSymbol methodSymbol, - boolean isAnnotated, - Nullness[] argumentPositionNullness) { - if (ASTHelpers.hasAnnotation(methodSymbol, LOMBOK_GENERATED_ANNOTATION_NAME, state)) { - // We assume that Lombok-generated equals methods with a single argument override - // Object.equals and are not an overload. - if (methodSymbol.getSimpleName().contentEquals("equals") - && methodSymbol.params().size() == 1) { - // The parameter is not annotated with @Nullable, but it should be. - argumentPositionNullness[0] = Nullness.NULLABLE; - } - } - return argumentPositionNullness; - } } diff --git a/nullaway/src/main/java/com/uber/nullaway/handlers/RestrictiveAnnotationHandler.java b/nullaway/src/main/java/com/uber/nullaway/handlers/RestrictiveAnnotationHandler.java index 7c5c9baf8f..561ac6ebae 100644 --- a/nullaway/src/main/java/com/uber/nullaway/handlers/RestrictiveAnnotationHandler.java +++ b/nullaway/src/main/java/com/uber/nullaway/handlers/RestrictiveAnnotationHandler.java @@ -99,7 +99,7 @@ private CodeAnnotationInfo getCodeAnnotationInfo(Context context) { @Override public Nullness[] onOverrideMethodInvocationParametersNullability( - VisitorState state, + Context context, Symbol.MethodSymbol methodSymbol, boolean isAnnotated, Nullness[] argumentPositionNullness) { diff --git a/nullaway/src/main/java/com/uber/nullaway/handlers/contract/ContractNullnessStoreInitializer.java b/nullaway/src/main/java/com/uber/nullaway/handlers/contract/ContractNullnessStoreInitializer.java index 155bd900ca..41b25d525d 100644 --- a/nullaway/src/main/java/com/uber/nullaway/handlers/contract/ContractNullnessStoreInitializer.java +++ b/nullaway/src/main/java/com/uber/nullaway/handlers/contract/ContractNullnessStoreInitializer.java @@ -3,11 +3,12 @@ import static com.uber.nullaway.Nullness.NONNULL; import static com.uber.nullaway.Nullness.NULLABLE; -import com.google.errorprone.VisitorState; import com.google.errorprone.util.ASTHelpers; import com.sun.source.tree.ClassTree; import com.sun.source.tree.MethodTree; import com.sun.tools.javac.code.Symbol; +import com.sun.tools.javac.code.Types; +import com.sun.tools.javac.util.Context; import com.uber.nullaway.Config; import com.uber.nullaway.Nullness; import com.uber.nullaway.dataflow.AccessPath; @@ -30,7 +31,8 @@ public NullnessStore getInitialStore( UnderlyingAST underlyingAST, List parameters, Handler handler, - VisitorState state, + Context context, + Types types, Config config) { assert underlyingAST.getKind() == UnderlyingAST.Kind.METHOD; @@ -47,7 +49,7 @@ public NullnessStore getInitialStore( String[] parts = clauses[0].split("->"); String[] antecedent = parts[0].split(","); - NullnessStore envStore = getEnvNullnessStoreForClass(classTree, state.context); + NullnessStore envStore = getEnvNullnessStoreForClass(classTree, context); NullnessStore.Builder result = envStore.toBuilder(); for (int i = 0; i < antecedent.length; ++i) { diff --git a/test-java-lib-lombok/src/main/java/com/uber/lombok/UsesDTO.java b/test-java-lib-lombok/src/main/java/com/uber/lombok/UsesDTO.java index bef6f7898f..f236a65056 100644 --- a/test-java-lib-lombok/src/main/java/com/uber/lombok/UsesDTO.java +++ b/test-java-lib-lombok/src/main/java/com/uber/lombok/UsesDTO.java @@ -38,9 +38,4 @@ public static String foo(LombokDTO ldto) { s += (ldto.getNullableField() == null ? "" : ldto.getNullableField().toString()); return s; } - - public static boolean callEquals(LombokDTO ldto, @Nullable Object o) { - // No error should be reported since equals() parameter should be treated as @Nullable - return ldto.equals(o); - } }