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

JSpecify: changes for issue #861 #863

Merged
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.code.Types;
import java.util.List;
import javax.lang.model.type.NullType;

/**
* Visitor that checks equality of nullability annotations for all nested generic type arguments
Expand All @@ -21,22 +22,25 @@

@Override
public Boolean visitClassType(Type.ClassType lhsType, Type rhsType) {
if (rhsType instanceof NullType) {
return true;

Check warning on line 26 in nullaway/src/main/java/com/uber/nullaway/generics/CompareNullabilityVisitor.java

View check run for this annotation

Codecov / codecov/patch

nullaway/src/main/java/com/uber/nullaway/generics/CompareNullabilityVisitor.java#L26

Added line #L26 was not covered by tests
}
Types types = state.getTypes();
// The base type of rhsType may be a subtype of lhsType's base type. In such cases, we must
// compare lhsType against the supertype of rhsType with a matching base type.
rhsType = types.asSuper(rhsType, lhsType.tsym);
Type rhsTypeAsSuper = types.asSuper(rhsType, lhsType.tsym);
// This is impossible, considering the fact that standard Java subtyping succeeds before
// running NullAway
if (rhsType == null) {
if (rhsTypeAsSuper == null) {
throw new RuntimeException("Did not find supertype of " + rhsType + " matching " + lhsType);
}
List<Type> lhsTypeArguments = lhsType.getTypeArguments();
List<Type> rhsTypeArguments = rhsType.getTypeArguments();
List<Type> rhsTypeArguments = rhsTypeAsSuper.getTypeArguments();
// This is impossible, considering the fact that standard Java subtyping succeeds before
// running NullAway
if (lhsTypeArguments.size() != rhsTypeArguments.size()) {
throw new RuntimeException(
"Number of types arguments in " + rhsType + " does not match " + lhsType);
"Number of types arguments in " + rhsTypeAsSuper + " does not match " + lhsType);
}
for (int i = 0; i < lhsTypeArguments.size(); i++) {
Type lhsTypeArgument = lhsTypeArguments.get(i);
Expand Down Expand Up @@ -77,6 +81,9 @@

@Override
public Boolean visitArrayType(Type.ArrayType lhsType, Type rhsType) {
if (rhsType instanceof NullType) {
msridhar marked this conversation as resolved.
Show resolved Hide resolved
return true;

Check warning on line 85 in nullaway/src/main/java/com/uber/nullaway/generics/CompareNullabilityVisitor.java

View check run for this annotation

Codecov / codecov/patch

nullaway/src/main/java/com/uber/nullaway/generics/CompareNullabilityVisitor.java#L85

Added line #L85 was not covered by tests
}
Type.ArrayType arrRhsType = (Type.ArrayType) rhsType;
return lhsType.getComponentType().accept(this, arrRhsType.getComponentType());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ public static void checkTypeParameterNullnessForAssignability(
Type lhsType = getTreeType(lhsTree, state);
Type rhsType = getTreeType(rhsTree, state);

if (lhsType instanceof Type.ClassType && rhsType instanceof Type.ClassType) {
if (lhsType != null && rhsType != null) {
boolean isAssignmentValid = compareNullabilityAnnotations(lhsType, rhsType, state);
if (!isAssignmentValid) {
reportInvalidAssignmentInstantiationError(tree, lhsType, rhsType, state, analysis);
Expand Down Expand Up @@ -333,8 +333,7 @@ public static void checkTypeParameterNullnessForFunctionReturnType(
return;
}
Type returnExpressionType = getTreeType(retExpr, state);
if (formalReturnType instanceof Type.ClassType
&& returnExpressionType instanceof Type.ClassType) {
if (formalReturnType != null && returnExpressionType != null) {
boolean isReturnTypeValid =
compareNullabilityAnnotations(formalReturnType, returnExpressionType, state);
if (!isReturnTypeValid) {
Expand Down Expand Up @@ -407,14 +406,14 @@ public static void checkTypeParameterNullnessForConditionalExpression(
// The condExpr type should be the least-upper bound of the true and false part types. To check
// the nullability annotations, we check that the true and false parts are assignable to the
// type of the whole expression
if (condExprType instanceof Type.ClassType) {
if (truePartType instanceof Type.ClassType) {
if (condExprType != null) {
if (truePartType != null) {
if (!compareNullabilityAnnotations(condExprType, truePartType, state)) {
reportMismatchedTypeForTernaryOperator(
truePartTree, condExprType, truePartType, state, analysis);
}
}
if (falsePartType instanceof Type.ClassType) {
if (falsePartType != null) {
if (!compareNullabilityAnnotations(condExprType, falsePartType, state)) {
reportMismatchedTypeForTernaryOperator(
falsePartTree, condExprType, falsePartType, state, analysis);
Expand Down Expand Up @@ -452,8 +451,7 @@ public static void compareGenericTypeParameterNullabilityForCall(
Type formalParameter = formalParams.get(i).type;
if (!formalParameter.getTypeArguments().isEmpty()) {
Type actualParameter = getTreeType(actualParams.get(i), state);
if (formalParameter instanceof Type.ClassType
&& actualParameter instanceof Type.ClassType) {
if (actualParameter != null) {
if (!compareNullabilityAnnotations(formalParameter, actualParameter, state)) {
reportInvalidParametersNullabilityError(
formalParameter, actualParameter, actualParams.get(i), state, analysis);
Expand All @@ -468,8 +466,7 @@ public static void compareGenericTypeParameterNullabilityForCall(
if (!varargsElementType.getTypeArguments().isEmpty()) {
for (int i = formalParams.size() - 1; i < actualParams.size(); i++) {
Type actualParameter = getTreeType(actualParams.get(i), state);
if (varargsElementType instanceof Type.ClassType
&& actualParameter instanceof Type.ClassType) {
if (actualParameter != null) {
if (!compareNullabilityAnnotations(varargsElementType, actualParameter, state)) {
reportInvalidParametersNullabilityError(
varargsElementType, actualParameter, actualParams.get(i), state, analysis);
Expand Down Expand Up @@ -777,8 +774,7 @@ private static void checkTypeParameterNullnessForOverridingMethodParameterType(
for (int i = 0; i < methodParameters.size(); i++) {
Type overridingMethodParameterType = ASTHelpers.getType(methodParameters.get(i));
Type overriddenMethodParameterType = overriddenMethodParameterTypes.get(i);
if (overriddenMethodParameterType instanceof Type.ClassType
&& overridingMethodParameterType instanceof Type.ClassType) {
if (overriddenMethodParameterType != null && overridingMethodParameterType != null) {
if (!compareNullabilityAnnotations(
overriddenMethodParameterType, overridingMethodParameterType, state)) {
reportInvalidOverridingMethodParamTypeError(
Expand Down Expand Up @@ -806,10 +802,10 @@ private static void checkTypeParameterNullnessForOverridingMethodReturnType(
MethodTree tree, Type overriddenMethodType, NullAway analysis, VisitorState state) {
Type overriddenMethodReturnType = overriddenMethodType.getReturnType();
Type overridingMethodReturnType = ASTHelpers.getType(tree.getReturnType());
if (!(overriddenMethodReturnType instanceof Type.ClassType)) {
if (overriddenMethodReturnType == null) {
return;
}
Preconditions.checkArgument(overridingMethodReturnType instanceof Type.ClassType);
Preconditions.checkArgument(overridingMethodReturnType != null);
if (!compareNullabilityAnnotations(
overriddenMethodReturnType, overridingMethodReturnType, state)) {
reportInvalidOverridingMethodReturnTypeError(
Expand Down