From 7cb6b985ff6e8dbc6d804f27cc26982fc732e49a Mon Sep 17 00:00:00 2001 From: Manu Sridharan Date: Wed, 25 Dec 2024 18:23:39 -0700 Subject: [PATCH] [refactoring] Wrap calls to Types.subst and Types.memberType (#1115) This is in preparation to attempt to fix #1091. Just a refactoring, no behavior changes. --- .../CoreNullnessStoreInitializer.java | 6 +++- .../nullaway/generics/GenericsChecks.java | 14 +++++--- .../generics/TypeSubstitutionUtils.java | 35 +++++++++++++++++++ 3 files changed, 49 insertions(+), 6 deletions(-) create mode 100644 nullaway/src/main/java/com/uber/nullaway/generics/TypeSubstitutionUtils.java 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 a969c08453..f61272168d 100644 --- a/nullaway/src/main/java/com/uber/nullaway/dataflow/CoreNullnessStoreInitializer.java +++ b/nullaway/src/main/java/com/uber/nullaway/dataflow/CoreNullnessStoreInitializer.java @@ -1,5 +1,6 @@ package com.uber.nullaway.dataflow; +import static com.uber.nullaway.NullabilityUtil.castToNonNull; import static com.uber.nullaway.Nullness.NONNULL; import static com.uber.nullaway.Nullness.NULLABLE; @@ -16,6 +17,7 @@ import com.uber.nullaway.Config; import com.uber.nullaway.NullabilityUtil; import com.uber.nullaway.Nullness; +import com.uber.nullaway.generics.TypeSubstitutionUtils; import com.uber.nullaway.handlers.Handler; import java.util.List; import java.util.Objects; @@ -104,7 +106,9 @@ private static NullnessStore lambdaInitialStore( // This obtains the types of the functional interface method parameters with preserved // annotations in case of generic type arguments. Only used in JSpecify mode. List overridenMethodParamTypeList = - types.memberType(ASTHelpers.getType(code), fiMethodSymbol).getParameterTypes(); + TypeSubstitutionUtils.memberType( + types, castToNonNull(ASTHelpers.getType(code)), fiMethodSymbol) + .getParameterTypes(); // If fiArgumentPositionNullness[i] == null, parameter position i is unannotated Nullness[] fiArgumentPositionNullness = new Nullness[fiMethodParameters.size()]; boolean isFIAnnotated = diff --git a/nullaway/src/main/java/com/uber/nullaway/generics/GenericsChecks.java b/nullaway/src/main/java/com/uber/nullaway/generics/GenericsChecks.java index 85ca6861bb..758f165f82 100644 --- a/nullaway/src/main/java/com/uber/nullaway/generics/GenericsChecks.java +++ b/nullaway/src/main/java/com/uber/nullaway/generics/GenericsChecks.java @@ -624,7 +624,8 @@ public static void compareGenericTypeParameterNullabilityForCall( enclosingType = methodSymbol.owner.type; } if (enclosingType != null) { - invokedMethodType = state.getTypes().memberType(enclosingType, methodSymbol); + invokedMethodType = + TypeSubstitutionUtils.memberType(state.getTypes(), enclosingType, methodSymbol); } } // substitute type arguments for generic methods @@ -694,7 +695,8 @@ public static void checkTypeParameterNullnessForMethodOverriding( // Obtain type parameters for the overridden method within the context of the overriding // method's class Type methodWithTypeParams = - state.getTypes().memberType(overridingMethod.owner.type, overriddenMethod); + TypeSubstitutionUtils.memberType( + state.getTypes(), overridingMethod.owner.type, overriddenMethod); checkTypeParameterNullnessForOverridingMethodReturnType( tree, methodWithTypeParams, analysis, state); @@ -772,7 +774,8 @@ public static Nullness getGenericMethodReturnTypeNullness( // annotation should have been handled by the caller) return Nullness.NONNULL; } - Type overriddenMethodType = state.getTypes().memberType(enclosingType, method); + Type overriddenMethodType = + TypeSubstitutionUtils.memberType(state.getTypes(), enclosingType, method); verify( overriddenMethodType instanceof ExecutableType, "expected ExecutableType but instead got %s", @@ -873,7 +876,8 @@ private static Type substituteTypeArgsInGenericMethodType( Type.ForAll forAllType = (Type.ForAll) methodSymbol.type; Type.MethodType underlyingMethodType = (Type.MethodType) forAllType.qtype; - return state.getTypes().subst(underlyingMethodType, forAllType.tvars, explicitTypeArgs); + return TypeSubstitutionUtils.subst( + state.getTypes(), underlyingMethodType, forAllType.tvars, explicitTypeArgs); } /** @@ -1007,7 +1011,7 @@ public static Nullness getGenericMethodParameterNullness( // @Nullable annotation is handled elsewhere) return Nullness.NONNULL; } - Type methodType = state.getTypes().memberType(enclosingType, method); + Type methodType = TypeSubstitutionUtils.memberType(state.getTypes(), enclosingType, method); Type paramType = methodType.getParameterTypes().get(parameterIndex); return getTypeNullness(paramType, config); } diff --git a/nullaway/src/main/java/com/uber/nullaway/generics/TypeSubstitutionUtils.java b/nullaway/src/main/java/com/uber/nullaway/generics/TypeSubstitutionUtils.java new file mode 100644 index 0000000000..158264f78d --- /dev/null +++ b/nullaway/src/main/java/com/uber/nullaway/generics/TypeSubstitutionUtils.java @@ -0,0 +1,35 @@ +package com.uber.nullaway.generics; + +import com.sun.tools.javac.code.Symbol; +import com.sun.tools.javac.code.Type; +import com.sun.tools.javac.code.Types; +import com.sun.tools.javac.util.List; + +/** Utility method related to substituting type arguments for type variables. */ +public class TypeSubstitutionUtils { + + /** + * Returns the type of {@code sym} as a member of {@code t}. + * + * @param types the {@link Types} instance + * @param t the enclosing type + * @param sym the symbol + * @return the type of {@code sym} as a member of {@code t} + */ + public static Type memberType(Types types, Type t, Symbol sym) { + return types.memberType(t, sym); + } + + /** + * Substitutes the types in {@code to} for the types in {@code from} in {@code t}. + * + * @param types the {@link Types} instance + * @param t the type to which to perform the substitution + * @param from the types that will be substituted out + * @param to the types that will be substituted in + * @return the type resulting from the substitution + */ + public static Type subst(Types types, Type t, List from, List to) { + return types.subst(t, from, to); + } +}