예제 #1
0
 /**
  * Check whether this type reference conforms to the null constraints defined for the
  * corresponding type variable.
  */
 protected void checkNullConstraints(
     Scope scope, Substitution substitution, TypeBinding[] variables, int rank) {
   if (variables != null && variables.length > rank) {
     TypeBinding variable = variables[rank];
     if (variable.hasNullTypeAnnotations()) {
       if (NullAnnotationMatching.analyse(
               variable, this.resolvedType, null, substitution, -1, null, CheckMode.BOUND_CHECK)
           .isAnyMismatch())
         scope.problemReporter().nullityMismatchTypeArgument(variable, this.resolvedType, this);
     }
   }
   checkIllegalNullAnnotation(scope);
 }
 // additional parameter strict: if true we do not tolerate incompatibly missing annotations on
 // type parameters (for overriding analysis)
 public static NullAnnotationMatching analyse(
     TypeBinding requiredType, TypeBinding providedType, int nullStatus, boolean strict) {
   int severity = 0;
   TypeBinding superTypeHint = null;
   if (requiredType instanceof ArrayBinding) {
     long[] requiredDimsTagBits = ((ArrayBinding) requiredType).nullTagBitsPerDimension;
     if (requiredDimsTagBits != null) {
       int dims = requiredType.dimensions();
       if (requiredType.dimensions() == providedType.dimensions()) {
         long[] providedDimsTagBits = ((ArrayBinding) providedType).nullTagBitsPerDimension;
         if (providedDimsTagBits == null) {
           severity = 1; // required is annotated, provided not, need unchecked conversion
         } else {
           for (int i = 0; i <= dims; i++) {
             long requiredBits = validNullTagBits(requiredDimsTagBits[i]);
             long providedBits = validNullTagBits(providedDimsTagBits[i]);
             if (i > 0) nullStatus = -1; // don't use beyond the outermost dimension
             severity =
                 Math.max(
                     severity,
                     computeNullProblemSeverity(requiredBits, providedBits, nullStatus, strict));
             if (severity == 2) return NullAnnotationMatching.NULL_ANNOTATIONS_MISMATCH;
           }
         }
       } else if (providedType.id == TypeIds.T_null) {
         if (dims > 0 && requiredDimsTagBits[0] == TagBits.AnnotationNonNull)
           return NullAnnotationMatching.NULL_ANNOTATIONS_MISMATCH;
       }
     }
   } else if (requiredType.hasNullTypeAnnotations() || providedType.hasNullTypeAnnotations()) {
     long requiredBits = requiredNullTagBits(requiredType);
     if (requiredBits != TagBits.AnnotationNullable // nullable lhs accepts everything, ...
         || nullStatus == -1) // only at detail/recursion even nullable must be matched exactly
     {
       long providedBits = providedNullTagBits(providedType);
       severity =
           computeNullProblemSeverity(
               requiredBits, providedBits, nullStatus, strict && nullStatus == -1);
     }
     if (severity < 2) {
       TypeBinding providedSuper = providedType.findSuperTypeOriginatingFrom(requiredType);
       if (providedSuper != providedType) // $IDENTITY-COMPARISON$
       superTypeHint = providedSuper;
       if (requiredType.isParameterizedType()
           && providedSuper
               instanceof ParameterizedTypeBinding) { // TODO(stephan): handle providedType.isRaw()
         TypeBinding[] requiredArguments = ((ParameterizedTypeBinding) requiredType).arguments;
         TypeBinding[] providedArguments = ((ParameterizedTypeBinding) providedSuper).arguments;
         if (requiredArguments != null
             && providedArguments != null
             && requiredArguments.length == providedArguments.length) {
           for (int i = 0; i < requiredArguments.length; i++) {
             NullAnnotationMatching status =
                 analyse(requiredArguments[i], providedArguments[i], -1, strict);
             severity = Math.max(severity, status.severity);
             if (severity == 2) return new NullAnnotationMatching(severity, superTypeHint);
           }
         }
       }
       TypeBinding requiredEnclosing = requiredType.enclosingType();
       TypeBinding providedEnclosing = providedType.enclosingType();
       if (requiredEnclosing != null && providedEnclosing != null) {
         NullAnnotationMatching status = analyse(requiredEnclosing, providedEnclosing, -1, strict);
         severity = Math.max(severity, status.severity);
       }
     }
   }
   if (severity == 0) return NullAnnotationMatching.NULL_ANNOTATIONS_OK;
   return new NullAnnotationMatching(severity, superTypeHint);
 }