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

Add downcast to CF #213

Closed
wants to merge 15 commits into from
Original file line number Diff line number Diff line change
Expand Up @@ -2333,6 +2333,19 @@ protected void checkTypecastSafety(TypeCastTree typeCastTree) {
}
}

/**
* Allow no incomparable cast by default. Other type systems may override this method to allow
* certain incomparable casts.
*
* @param castType castType
* @param exprType exprType
* @return always false in BaseTypeVisitor
*/
protected boolean isIncomparableCastSafe(
AnnotatedTypeMirror castType, AnnotatedTypeMirror exprType) {
return false;
}

/**
* Returns true if the cast is safe.
*
Expand All @@ -2346,20 +2359,23 @@ protected void checkTypecastSafety(TypeCastTree typeCastTree) {
protected boolean isTypeCastSafe(AnnotatedTypeMirror castType, AnnotatedTypeMirror exprType) {

final TypeKind castTypeKind = castType.getKind();
if (castTypeKind == TypeKind.DECLARED) {
// Don't issue an error if the annotations are equivalent to the qualifier upper bound
// of the type.
AnnotatedDeclaredType castDeclared = (AnnotatedDeclaredType) castType;
Set<AnnotationMirror> bounds =
atypeFactory.getTypeDeclarationBounds(castDeclared.getUnderlyingType());

if (AnnotationUtils.areSame(castDeclared.getAnnotations(), bounds)) {
AndrewShf marked this conversation as resolved.
Show resolved Hide resolved
return true;
QualifierHierarchy qualifierHierarchy = atypeFactory.getQualifierHierarchy();

if (castTypeKind == TypeKind.DECLARED) { // Check if the downcast is valid
TypeMirror castJavaType = castType.getUnderlyingType();
TypeMirror exprJavaType = exprType.getUnderlyingType();
if (TypesUtils.isErasedSubtype(castJavaType, exprJavaType, types)) {
Set<AnnotationMirror> castAnnos = castType.getAnnotations();
Set<AnnotationMirror> exprAnnos = exprType.getAnnotations();
if (qualifierHierarchy.isSubtype(castAnnos, exprAnnos)
|| qualifierHierarchy.isSubtype(exprAnnos, castAnnos)) {
return true;
} else {
return isIncomparableCastSafe(castType, exprType);
}
}
}

QualifierHierarchy qualifierHierarchy = atypeFactory.getQualifierHierarchy();

Set<AnnotationMirror> castAnnos;
if (!checker.hasOption("checkCastElementType")) {
// checkCastElementType option wasn't specified, so only check effective annotations.
Expand Down