コード例 #1
0
  public ParameterizedTypeBinding getParameterizedType(
      ReferenceBinding genericType,
      TypeBinding[] typeArguments,
      ReferenceBinding enclosingType,
      AnnotationBinding[] annotations) {

    if (genericType.hasTypeAnnotations()) // @NonNull (List<String>) and not (@NonNull List)<String>
    throw new IllegalStateException();

    ParameterizedTypeBinding parameterizedType =
        this.parameterizedTypes.get(genericType, typeArguments, enclosingType, annotations);
    if (parameterizedType != null) return parameterizedType;

    ParameterizedTypeBinding nakedType =
        super.getParameterizedType(genericType, typeArguments, enclosingType);

    if (!haveTypeAnnotations(genericType, enclosingType, typeArguments, annotations))
      return nakedType;

    parameterizedType =
        new ParameterizedTypeBinding(genericType, typeArguments, enclosingType, this.environment);
    parameterizedType.id = nakedType.id;
    parameterizedType.setTypeAnnotations(annotations, this.isAnnotationBasedNullAnalysisEnabled);
    this.parameterizedTypes.put(genericType, typeArguments, enclosingType, parameterizedType);
    return (ParameterizedTypeBinding) cacheDerivedType(genericType, nakedType, parameterizedType);
  }
  public void checkBounds(Scope scope) {
    if (this.resolvedType == null) return;

    if (this.resolvedType.leafComponentType() instanceof ParameterizedTypeBinding) {
      ParameterizedTypeBinding parameterizedType =
          (ParameterizedTypeBinding) this.resolvedType.leafComponentType();
      ReferenceBinding currentType = parameterizedType.genericType();
      TypeVariableBinding[] typeVariables = currentType.typeVariables();
      TypeBinding[] argTypes = parameterizedType.arguments;
      if (argTypes != null && typeVariables != null) { // may be null in error cases
        parameterizedType.boundCheck(scope, this.typeArguments);
      }
    }
  }
コード例 #3
0
 public void checkTypeArgumentRedundancy(
     ParameterizedTypeBinding allocationType,
     ReferenceBinding enclosingType,
     TypeBinding[] argumentTypes,
     final BlockScope scope) {
   ProblemReporter reporter = scope.problemReporter();
   if ((reporter.computeSeverity(IProblem.RedundantSpecificationOfTypeArguments)
           == ProblemSeverities.Ignore)
       || scope.compilerOptions().sourceLevel < ClassFileConstants.JDK1_7) return;
   if (allocationType.arguments == null) return; // raw binding
   if (this.genericTypeArguments != null)
     return; // diamond can't occur with explicit type args for constructor
   if (argumentTypes == Binding.NO_PARAMETERS
       && this.typeExpected instanceof ParameterizedTypeBinding) {
     ParameterizedTypeBinding expected = (ParameterizedTypeBinding) this.typeExpected;
     if (expected.arguments != null
         && allocationType.arguments.length == expected.arguments.length) {
       // check the case when no ctor takes no params and inference uses the expected type directly
       // eg. X<String> x = new X<String>()
       int i;
       for (i = 0; i < allocationType.arguments.length; i++) {
         if (allocationType.arguments[i] != expected.arguments[i]) break;
       }
       if (i == allocationType.arguments.length) {
         reporter.redundantSpecificationOfTypeArguments(this.type, allocationType.arguments);
         return;
       }
     }
   }
   TypeBinding[] inferredTypes =
       inferElidedTypes(allocationType.genericType(), enclosingType, argumentTypes, scope);
   if (inferredTypes == null) {
     return;
   }
   for (int i = 0; i < inferredTypes.length; i++) {
     if (inferredTypes[i] != allocationType.arguments[i]) return;
   }
   reporter.redundantSpecificationOfTypeArguments(this.type, allocationType.arguments);
 }
コード例 #4
0
 boolean addConstraintsFromTypeParameters(
     TypeBinding subCandidate, ParameterizedTypeBinding ca, List<ConstraintFormula> constraints) {
   TypeBinding[] ai = ca.arguments; // C<A1,A2,...>
   if (ai == null) return true; // no arguments here means nothing to check
   TypeBinding cb = subCandidate.findSuperTypeOriginatingFrom(ca); // C<B1,B2,...>
   if (cb == null) return false; // nothing here means we failed
   if (TypeBinding.equalsEquals(ca, cb)) // incl C#RAW vs C#RAW
   return true;
   if (!(cb instanceof ParameterizedTypeBinding)) {
     // if C is parameterized with its own type variables, there're no more constraints to be
     // created here, otherwise let's fail
     return ca.isParameterizedWithOwnVariables();
   }
   TypeBinding[] bi = ((ParameterizedTypeBinding) cb).arguments;
   if (cb.isRawType() || bi == null || bi.length == 0)
     return (this.isSoft && InferenceContext18.SIMULATE_BUG_JDK_8026527)
         ? true
         : false; // FALSE would conform to the spec
   for (int i = 0; i < ai.length; i++)
     constraints.add(
         ConstraintTypeFormula.create(bi[i], ai[i], TYPE_ARGUMENT_CONTAINED, this.isSoft));
   return true;
 }
  private TypeBinding internalResolveLeafType(
      Scope scope, ReferenceBinding enclosingType, boolean checkBounds) {
    ReferenceBinding currentType;
    if (enclosingType == null) {
      this.resolvedType = scope.getType(this.token);
      if (this.resolvedType.isValidBinding()) {
        currentType = (ReferenceBinding) this.resolvedType;
      } else {
        reportInvalidType(scope);
        switch (this.resolvedType.problemId()) {
          case ProblemReasons.NotFound:
          case ProblemReasons.NotVisible:
          case ProblemReasons.InheritedNameHidesEnclosingName:
            TypeBinding type = this.resolvedType.closestMatch();
            if (type instanceof ReferenceBinding) {
              currentType = (ReferenceBinding) type;
              break;
            }
            // $FALL-THROUGH$ - unable to complete type binding, but still resolve type arguments
          default:
            boolean isClassScope = scope.kind == Scope.CLASS_SCOPE;
            int argLength = this.typeArguments.length;
            for (int i = 0; i < argLength; i++) {
              TypeReference typeArgument = this.typeArguments[i];
              if (isClassScope) {
                typeArgument.resolveType((ClassScope) scope);
              } else {
                typeArgument.resolveType((BlockScope) scope, checkBounds);
              }
            }
            return null;
        }
        // be resilient, still attempt resolving arguments
      }
      enclosingType = currentType.enclosingType(); // if member type
      if (enclosingType != null) {
        enclosingType =
            currentType.isStatic()
                ? (ReferenceBinding)
                    scope
                        .environment()
                        .convertToRawType(
                            enclosingType, false /*do not force conversion of enclosing types*/)
                : scope.environment().convertToParameterizedType(enclosingType);
        currentType =
            scope
                .environment()
                .createParameterizedType(
                    (ReferenceBinding) currentType.erasure(), null /* no arg */, enclosingType);
      }
    } else { // resolving member type (relatively to enclosingType)
      this.resolvedType = currentType = scope.getMemberType(this.token, enclosingType);
      if (!this.resolvedType.isValidBinding()) {
        scope.problemReporter().invalidEnclosingType(this, currentType, enclosingType);
        return null;
      }
      if (isTypeUseDeprecated(currentType, scope))
        scope.problemReporter().deprecatedType(currentType, this);
      ReferenceBinding currentEnclosing = currentType.enclosingType();
      if (currentEnclosing != null && currentEnclosing.erasure() != enclosingType.erasure()) {
        enclosingType =
            currentEnclosing; // inherited member type, leave it associated with its enclosing
                              // rather than subtype
      }
    }

    // check generic and arity
    boolean isClassScope = scope.kind == Scope.CLASS_SCOPE;
    TypeReference keep = null;
    if (isClassScope) {
      keep = ((ClassScope) scope).superTypeReference;
      ((ClassScope) scope).superTypeReference = null;
    }
    int argLength = this.typeArguments.length;
    TypeBinding[] argTypes = new TypeBinding[argLength];
    boolean argHasError = false;
    ReferenceBinding currentOriginal = (ReferenceBinding) currentType.original();
    for (int i = 0; i < argLength; i++) {
      TypeReference typeArgument = this.typeArguments[i];
      TypeBinding argType =
          isClassScope
              ? typeArgument.resolveTypeArgument((ClassScope) scope, currentOriginal, i)
              : typeArgument.resolveTypeArgument((BlockScope) scope, currentOriginal, i);
      this.bits |= (typeArgument.bits & ASTNode.HasTypeAnnotations);
      if (argType == null) {
        argHasError = true;
      } else {
        if (typeArgument.annotations != null)
          argTypes[i] =
              captureTypeAnnotations(scope, enclosingType, argType, typeArgument.annotations[0]);
        else argTypes[i] = argType;
      }
    }
    if (argHasError) {
      return null;
    }
    if (isClassScope) {
      ((ClassScope) scope).superTypeReference = keep;
      if (((ClassScope) scope).detectHierarchyCycle(currentOriginal, this)) return null;
    }

    final boolean isDiamond = (this.bits & ASTNode.IsDiamond) != 0;
    TypeVariableBinding[] typeVariables = currentOriginal.typeVariables();
    if (typeVariables == Binding.NO_TYPE_VARIABLES) { // non generic invoked with arguments
      boolean isCompliant15 =
          scope.compilerOptions().originalSourceLevel >= ClassFileConstants.JDK1_5;
      if ((currentOriginal.tagBits & TagBits.HasMissingType) == 0) {
        if (isCompliant15) { // below 1.5, already reported as syntax error
          this.resolvedType = currentType;
          scope
              .problemReporter()
              .nonGenericTypeCannotBeParameterized(0, this, currentType, argTypes);
          return null;
        }
      }
      // resilience do not rebuild a parameterized type unless compliance is allowing it
      if (!isCompliant15) {
        if (!this.resolvedType.isValidBinding()) return currentType;
        return this.resolvedType = currentType;
      }
      // if missing generic type, and compliance >= 1.5, then will rebuild a parameterized binding
    } else if (argLength != typeVariables.length) {
      if (!isDiamond) { // check arity, IsDiamond never set for 1.6-
        scope.problemReporter().incorrectArityForParameterizedType(this, currentType, argTypes);
        return null;
      }
    } else if (!currentType.isStatic()) {
      ReferenceBinding actualEnclosing = currentType.enclosingType();
      if (actualEnclosing != null && actualEnclosing.isRawType()) {
        scope
            .problemReporter()
            .rawMemberTypeCannotBeParameterized(
                this,
                scope.environment().createRawType(currentOriginal, actualEnclosing),
                argTypes);
        return null;
      }
    }

    ParameterizedTypeBinding parameterizedType =
        scope.environment().createParameterizedType(currentOriginal, argTypes, enclosingType);
    // check argument type compatibility for non <> cases - <> case needs no bounds check, we will
    // scream foul if needed during inference.
    if (!isDiamond) {
      if (checkBounds) // otherwise will do it in Scope.connectTypeVariables() or generic method
                       // resolution
      parameterizedType.boundCheck(scope, this.typeArguments);
      else scope.deferBoundCheck(this);
    }
    if (isTypeUseDeprecated(parameterizedType, scope))
      reportDeprecatedType(parameterizedType, scope);

    if (!this.resolvedType.isValidBinding()) {
      return parameterizedType;
    }
    return this.resolvedType = parameterizedType;
  }