// interpreting 'type' as a provided type, compute the provide null bits // we inspect the main type plus bounds of type variables and wildcards static long providedNullTagBits(TypeBinding type) { long tagBits = type.tagBits & TagBits.AnnotationNullMASK; if (tagBits != 0) return validNullTagBits(tagBits); if (type.isWildcard()) { // wildcard can be 'provided' during inheritance checks WildcardBinding wildcard = (WildcardBinding) type; if (wildcard.boundKind == Wildcard.UNBOUND) return 0; tagBits = wildcard.bound.tagBits & TagBits.AnnotationNullMASK; if (tagBits == 0) return 0; switch (wildcard.boundKind) { case Wildcard.EXTENDS: if (tagBits == TagBits.AnnotationNonNull) return TagBits.AnnotationNonNull; return TagBits.AnnotationNullMASK; // @Nullable or better case Wildcard.SUPER: if (tagBits == TagBits.AnnotationNullable) return TagBits.AnnotationNullable; return TagBits.AnnotationNullMASK; // @NonNull or worse } return 0; } if (type.isTypeVariable()) { // incl. captures TypeVariableBinding typeVariable = (TypeVariableBinding) type; boolean haveNullBits = false; if (typeVariable.isCapture()) { TypeBinding lowerBound = ((CaptureBinding) typeVariable).lowerBound; if (lowerBound != null) { tagBits = lowerBound.tagBits & TagBits.AnnotationNullMASK; if (tagBits == TagBits.AnnotationNullable) return TagBits.AnnotationNullable; // cannot be @NonNull haveNullBits |= (tagBits != 0); } } if (typeVariable.firstBound != null) { long boundBits = typeVariable.firstBound.tagBits & TagBits.AnnotationNullMASK; if (boundBits == TagBits.AnnotationNonNull) return TagBits.AnnotationNonNull; // cannot be @Nullable haveNullBits |= (boundBits != 0); } if (haveNullBits) return TagBits .AnnotationNullMASK; // could be either, can only match to a wildcard accepting both } return 0; }
// interpreting 'type' as a required type, compute the required null bits // we inspect the main type plus bounds of type variables and wildcards static long requiredNullTagBits(TypeBinding type) { long tagBits = type.tagBits & TagBits.AnnotationNullMASK; if (tagBits != 0) return validNullTagBits(tagBits); if (type.isWildcard()) { WildcardBinding wildcard = (WildcardBinding) type; if (wildcard.boundKind == Wildcard.UNBOUND) return 0; tagBits = wildcard.bound.tagBits & TagBits.AnnotationNullMASK; if (tagBits == 0) return 0; switch (wildcard.boundKind) { case Wildcard.EXTENDS: if (tagBits == TagBits.AnnotationNonNull) return TagBits.AnnotationNonNull; return TagBits.AnnotationNullMASK; // wildcard accepts @Nullable or better case Wildcard.SUPER: if (tagBits == TagBits.AnnotationNullable) return TagBits.AnnotationNullable; return TagBits.AnnotationNullMASK; // wildcard accepts @NonNull or worse } return 0; } if (type.isTypeVariable()) { // assume we must require @NonNull, unless: (1) lower @Nullable bound, or (2) no nullness // specified TypeVariableBinding typeVariable = (TypeVariableBinding) type; boolean haveNullBits = false; if (type.isCapture()) { TypeBinding lowerBound = ((CaptureBinding) type).lowerBound; if (lowerBound != null) { tagBits = lowerBound.tagBits & TagBits.AnnotationNullMASK; if (tagBits == TagBits.AnnotationNullable) return TagBits.AnnotationNullable; // (1) type cannot require @NonNull haveNullBits = tagBits != 0; } } if (typeVariable.firstBound != null) haveNullBits |= (typeVariable.firstBound.tagBits & TagBits.AnnotationNullMASK) != 0; if (haveNullBits) return TagBits .AnnotationNonNull; // could require @NonNull (unless (2) unspecified nullness) } return 0; }