Skip to content

Commit

Permalink
TypeUtils#isAssignable() improvements (#4696)
Browse files Browse the repository at this point in the history
* Add `TypeUtils` tests for primitives

* Correct `TypeUtils#isAssignableTo()` for primitive array types

* New `TypeUtils#isAssignableTo()` API

We need to consider the "position" when performing the assignability check. I.e. check if a parameterized type compared against a generic type variable is used in a context where the generic type parameter is bound by the parameterized type or not.

* Implement new API

* Remove one more `stream()` call

* Update Javadoc visitors to use `TypeUtils#isAssignableTo()` correctly

* Correction

* Corrections

* Corrections

* More Javadoc fixes

* Add missing `@MinimumJava11` annotation
  • Loading branch information
knutwannheden authored Nov 21, 2024
1 parent 0e52b94 commit 01813e3
Show file tree
Hide file tree
Showing 6 changed files with 607 additions and 115 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -715,8 +715,25 @@ public Tree visitProvides(ProvidesTree node, List<Javadoc> body) {
return null;
}

private boolean paramTypeMatches(JavaType testParamType, Type paramType) {
return TypeUtils.isAssignableTo(testParamType, typeMapping.type(paramType));
private boolean paramTypeMatches(JavaType parameterType, Type javadocType) {
return paramTypeMatches(parameterType, typeMapping.type(javadocType));
}

// Javadoc type references typically don't have generic type parameters
private static boolean paramTypeMatches(JavaType parameterType, JavaType mappedJavadocType) {
if (parameterType instanceof JavaType.Array && mappedJavadocType instanceof JavaType.Array) {
if (((JavaType.Array) parameterType).getElemType() instanceof JavaType.Primitive) {
return TypeUtils.isAssignableTo(parameterType, mappedJavadocType, TypeUtils.TypePosition.In);
}
return paramTypeMatches(((JavaType.Array) parameterType).getElemType(), ((JavaType.Array) mappedJavadocType).getElemType());
} else if (parameterType instanceof JavaType.GenericTypeVariable && !((JavaType.GenericTypeVariable) parameterType).getBounds().isEmpty()) {
return paramTypeMatches(((JavaType.GenericTypeVariable) parameterType).getBounds().get(0), mappedJavadocType);
} else if (parameterType instanceof JavaType.GenericTypeVariable) {
return TypeUtils.isObject(mappedJavadocType);
} else if (parameterType instanceof JavaType.Parameterized && !(mappedJavadocType instanceof JavaType.Parameterized)) {
return paramTypeMatches(((JavaType.Parameterized) parameterType).getType(), mappedJavadocType);
}
return TypeUtils.isAssignableTo(parameterType, mappedJavadocType, TypeUtils.TypePosition.In);
}

private JavaType.@Nullable Variable fieldReferenceType(DCTree.DCReference ref, @Nullable JavaType type) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -718,8 +718,25 @@ public Tree visitProvides(ProvidesTree node, List<Javadoc> body) {
return null;
}

private boolean paramTypeMatches(JavaType testParamType, Type paramType) {
return TypeUtils.isAssignableTo(testParamType, typeMapping.type(paramType));
private boolean paramTypeMatches(JavaType parameterType, Type javadocType) {
return paramTypeMatches(parameterType, typeMapping.type(javadocType));
}

// Javadoc type references typically don't have generic type parameters
private static boolean paramTypeMatches(JavaType parameterType, JavaType mappedJavadocType) {
if (parameterType instanceof JavaType.Array && mappedJavadocType instanceof JavaType.Array) {
if (((JavaType.Array) parameterType).getElemType() instanceof JavaType.Primitive) {
return TypeUtils.isAssignableTo(parameterType, mappedJavadocType, TypeUtils.TypePosition.In);
}
return paramTypeMatches(((JavaType.Array) parameterType).getElemType(), ((JavaType.Array) mappedJavadocType).getElemType());
} else if (parameterType instanceof JavaType.GenericTypeVariable && !((JavaType.GenericTypeVariable) parameterType).getBounds().isEmpty()) {
return paramTypeMatches(((JavaType.GenericTypeVariable) parameterType).getBounds().get(0), mappedJavadocType);
} else if (parameterType instanceof JavaType.GenericTypeVariable) {
return TypeUtils.isObject(mappedJavadocType);
} else if (parameterType instanceof JavaType.Parameterized && !(mappedJavadocType instanceof JavaType.Parameterized)) {
return paramTypeMatches(((JavaType.Parameterized) parameterType).getType(), mappedJavadocType);
}
return TypeUtils.isAssignableTo(parameterType, mappedJavadocType, TypeUtils.TypePosition.In);
}

private JavaType.@Nullable Variable fieldReferenceType(DCTree.DCReference ref, @Nullable JavaType type) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -718,8 +718,25 @@ public Tree visitProvides(ProvidesTree node, List<Javadoc> body) {
return null;
}

private boolean paramTypeMatches(JavaType testParamType, Type paramType) {
return TypeUtils.isAssignableTo(testParamType, typeMapping.type(paramType));
private boolean paramTypeMatches(JavaType parameterType, Type javadocType) {
return paramTypeMatches(parameterType, typeMapping.type(javadocType));
}

// Javadoc type references typically don't have generic type parameters
private static boolean paramTypeMatches(JavaType parameterType, JavaType mappedJavadocType) {
if (parameterType instanceof JavaType.Array && mappedJavadocType instanceof JavaType.Array) {
if (((JavaType.Array) parameterType).getElemType() instanceof JavaType.Primitive) {
return TypeUtils.isAssignableTo(parameterType, mappedJavadocType, TypeUtils.TypePosition.In);
}
return paramTypeMatches(((JavaType.Array) parameterType).getElemType(), ((JavaType.Array) mappedJavadocType).getElemType());
} else if (parameterType instanceof JavaType.GenericTypeVariable && !((JavaType.GenericTypeVariable) parameterType).getBounds().isEmpty()) {
return paramTypeMatches(((JavaType.GenericTypeVariable) parameterType).getBounds().get(0), mappedJavadocType);
} else if (parameterType instanceof JavaType.GenericTypeVariable) {
return TypeUtils.isObject(mappedJavadocType);
} else if (parameterType instanceof JavaType.Parameterized && !(mappedJavadocType instanceof JavaType.Parameterized)) {
return paramTypeMatches(((JavaType.Parameterized) parameterType).getType(), mappedJavadocType);
}
return TypeUtils.isAssignableTo(parameterType, mappedJavadocType, TypeUtils.TypePosition.In);
}

private JavaType.@Nullable Variable fieldReferenceType(DCTree.DCReference ref, @Nullable JavaType type) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -669,8 +669,25 @@ public Tree visitParam(ParamTree node, List<Javadoc> body) {
return null;
}

private boolean paramTypeMatches(JavaType testParamType, Type paramType) {
return TypeUtils.isAssignableTo(testParamType, typeMapping.type(paramType));
private boolean paramTypeMatches(JavaType parameterType, Type javadocType) {
return paramTypeMatches(parameterType, typeMapping.type(javadocType));
}

// Javadoc type references typically don't have generic type parameters
private static boolean paramTypeMatches(JavaType parameterType, JavaType mappedJavadocType) {
if (parameterType instanceof JavaType.Array && mappedJavadocType instanceof JavaType.Array) {
if (((JavaType.Array) parameterType).getElemType() instanceof JavaType.Primitive) {
return TypeUtils.isAssignableTo(parameterType, mappedJavadocType, TypeUtils.TypePosition.In);
}
return paramTypeMatches(((JavaType.Array) parameterType).getElemType(), ((JavaType.Array) mappedJavadocType).getElemType());
} else if (parameterType instanceof JavaType.GenericTypeVariable && !((JavaType.GenericTypeVariable) parameterType).getBounds().isEmpty()) {
return paramTypeMatches(((JavaType.GenericTypeVariable) parameterType).getBounds().get(0), mappedJavadocType);
} else if (parameterType instanceof JavaType.GenericTypeVariable) {
return TypeUtils.isObject(mappedJavadocType);
} else if (parameterType instanceof JavaType.Parameterized && !(mappedJavadocType instanceof JavaType.Parameterized)) {
return paramTypeMatches(((JavaType.Parameterized) parameterType).getType(), mappedJavadocType);
}
return TypeUtils.isAssignableTo(parameterType, mappedJavadocType, TypeUtils.TypePosition.In);
}

private JavaType.@Nullable Variable fieldReferenceType(DCTree.DCReference ref, @Nullable JavaType type) {
Expand Down
Loading

0 comments on commit 01813e3

Please sign in to comment.