Skip to content

Commit

Permalink
formatting
Browse files Browse the repository at this point in the history
  • Loading branch information
msridhar committed Feb 7, 2025
1 parent a2489ea commit ddf2440
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import static com.google.common.base.Verify.verify;
import static com.uber.nullaway.NullabilityUtil.castToNonNull;
import static com.uber.nullaway.NullabilityUtil.findEnclosingMethodOrLambdaOrInitializer;

import com.google.errorprone.VisitorState;
import com.google.errorprone.suppliers.Supplier;
Expand Down Expand Up @@ -41,7 +40,6 @@
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import javax.lang.model.type.ExecutableType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeVariable;
Expand Down Expand Up @@ -452,16 +450,19 @@ public void checkTypeParameterNullnessForAssignability(
// method call has a return type of class type
if (methodSymbol.getReturnType() instanceof Type.ClassType) {
Type.ClassType returnType = (Type.ClassType) methodSymbol.getReturnType();
List<Symbol. TypeVariableSymbol> typeParam = methodSymbol.getTypeParameters();
List<Symbol.TypeVariableSymbol> typeParam = methodSymbol.getTypeParameters();
List<Type> returnTypeTypeArg = returnType.getTypeArguments();

// if generic type in return type
if (!typeParam.isEmpty()) {
Map<Type, Type> genericNullness = new HashMap<>();
for (int i = 0; i < typeParam.size(); i++) {
Type upperBound = typeParam.get(i).type.getUpperBound();
if(getTypeNullness(upperBound, config) == Nullness.NULLABLE) { // generic has nullable upperbound
Type lhsInferredType = inferMethodTypeArgument(typeParam.get(i).type, lhsTypeArguments, returnTypeTypeArg, state);
if (getTypeNullness(upperBound, config)
== Nullness.NULLABLE) { // generic has nullable upperbound
Type lhsInferredType =
inferMethodTypeArgument(
typeParam.get(i).type, lhsTypeArguments, returnTypeTypeArg, state);
if (lhsInferredType != null) { // && has a nullable upperbound
genericNullness.put(typeParam.get(i).type, lhsInferredType);
}
Expand Down Expand Up @@ -523,22 +524,29 @@ public void checkTypeParameterNullnessForAssignability(
}
}

private Type inferMethodTypeArgument(Type typeParam, List<? extends Tree> lhsTypeArg, List<Type> typeArg, VisitorState state) {
private Type inferMethodTypeArgument(
Type typeParam, List<? extends Tree> lhsTypeArg, List<Type> typeArg, VisitorState state) {
// base case
if(typeParam == null || lhsTypeArg == null || typeArg == null) {
if (typeParam == null || lhsTypeArg == null || typeArg == null) {
return null;
}

// recursive case
Type inferType = null;
for(int i=0; i<typeArg.size(); i++) {
for (int i = 0; i < typeArg.size(); i++) {
Type type = typeArg.get(i);
if(state.getTypes().isSameType(typeParam, type)) {
if (state.getTypes().isSameType(typeParam, type)) {
return ASTHelpers.getType(lhsTypeArg.get(i));
} else if(!type.getTypeArguments().isEmpty()) {
// instanceof Type.ForAll TODO: check if the lhsTypeArg is a generic class? -> maybe the base case makes it unnecessary
inferType = inferMethodTypeArgument(typeParam, ((ParameterizedTypeTree) lhsTypeArg.get(i)).getTypeArguments(), typeArg.get(i).getTypeArguments(), state);
if(inferType != null) {
} else if (!type.getTypeArguments().isEmpty()) {
// instanceof Type.ForAll TODO: check if the lhsTypeArg is a generic class? -> maybe
// the base case makes it unnecessary
inferType =
inferMethodTypeArgument(
typeParam,
((ParameterizedTypeTree) lhsTypeArg.get(i)).getTypeArguments(),
typeArg.get(i).getTypeArguments(),
state);
if (inferType != null) {
return inferType;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,15 +179,18 @@ public void genericInferenceOnAssignments() {
" }",
" }",
" static void testLocalAssign() {",
// " // legal",
// " Foo<@Nullable Object> f1 = Foo.makeNull(null);",
// " // BUG: Diagnostic contains: passing @Nullable parameter 'null' where @NonNull is required",
// " Foo<Object> f2 = Foo.makeNull(null);",
// " // ILLEGAL: U does not have a @Nullable upper bound",
// " // BUG: Diagnostic contains: passing @Nullable parameter 'null' where @NonNull is required",
// " Foo<@Nullable Object> f3 = Foo.makeNonNull(null);",
// " // BUG: Diagnostic contains: passing @Nullable parameter 'null' where @NonNull is required",
// " Foo<Object> f4 = Foo.makeNonNull(null);",
// " // legal",
// " Foo<@Nullable Object> f1 = Foo.makeNull(null);",
// " // BUG: Diagnostic contains: passing @Nullable parameter 'null'
// where @NonNull is required",
// " Foo<Object> f2 = Foo.makeNull(null);",
// " // ILLEGAL: U does not have a @Nullable upper bound",
// " // BUG: Diagnostic contains: passing @Nullable parameter 'null'
// where @NonNull is required",
// " Foo<@Nullable Object> f3 = Foo.makeNonNull(null);",
// " // BUG: Diagnostic contains: passing @Nullable parameter 'null'
// where @NonNull is required",
// " Foo<Object> f4 = Foo.makeNonNull(null);",
" Foo<@Nullable Object> f5 = Foo.makeNonNull(new Object());",
" }",
" }")
Expand Down Expand Up @@ -247,24 +250,25 @@ public void genericInferenceOnAssignmentsMultipleParams() {
@Test
public void genericsUsedForGenericClasses() {
makeHelper()
.addSourceLines(
"Test.java",
"package com.uber;",
"import org.jspecify.annotations.Nullable;",
"import java.util.ArrayList;",
"class Test {",
" abstract class Foo<K, V> {",
" abstract <U, R> Foo<U,ArrayList<R>> nonNullTest();",
" abstract <U extends @Nullable Object, R extends @Nullable Object> Foo<U,ArrayList<R>> nullTest();",
" }",
" static void test(Foo<Void, Void> f) {",
" Foo<Integer, ArrayList<String>> fooNonNull_1 = f.nonNullTest();",
" Foo<Integer, ArrayList<@Nullable String>> fooNonNull_2 = f.nonNullTest();", // error message
" Foo<Integer, ArrayList<String>> fooNull_1 = f.nullTest();",
" Foo<Integer, ArrayList<@Nullable String>> fooNull_2 = f.nullTest();", // error message
" }",
"}")
.doTest();
.addSourceLines(
"Test.java",
"package com.uber;",
"import org.jspecify.annotations.Nullable;",
"import java.util.ArrayList;",
"class Test {",
" abstract class Foo<K, V> {",
" abstract <U, R> Foo<U,ArrayList<R>> nonNullTest();",
" abstract <U extends @Nullable Object, R extends @Nullable Object> Foo<U,ArrayList<R>> nullTest();",
" }",
" static void test(Foo<Void, Void> f) {",
" Foo<Integer, ArrayList<String>> fooNonNull_1 = f.nonNullTest();",
" Foo<Integer, ArrayList<@Nullable String>> fooNonNull_2 = f.nonNullTest();", // error message
" Foo<Integer, ArrayList<String>> fooNull_1 = f.nullTest();",
" Foo<Integer, ArrayList<@Nullable String>> fooNull_2 = f.nullTest();", // error
// message
" }",
"}")
.doTest();
}

@Test
Expand Down

0 comments on commit ddf2440

Please sign in to comment.