public TypeBinding resolveType(BlockScope scope) {
    // added for code assist...cannot occur with 'normal' code
    if (this.anonymousType == null && this.enclosingInstance == null) {
      return super.resolveType(scope);
    }

    // Propagate the type checking to the arguments, and checks if the constructor is defined.
    // ClassInstanceCreationExpression ::= Primary '.' 'new' SimpleName '(' ArgumentListopt ')'
    // ClassBodyopt
    // ClassInstanceCreationExpression ::= Name '.' 'new' SimpleName '(' ArgumentListopt ')'
    // ClassBodyopt

    this.constant = Constant.NotAConstant;
    TypeBinding enclosingInstanceType = null;
    ReferenceBinding enclosingInstanceReference = null;
    TypeBinding receiverType = null;
    boolean hasError = false;
    boolean enclosingInstanceContainsCast = false;
    boolean argsContainCast = false;

    if (this.enclosingInstance != null) {
      if (this.enclosingInstance instanceof CastExpression) {
        this.enclosingInstance.bits |= ASTNode.DisableUnnecessaryCastCheck; // will check later on
        enclosingInstanceContainsCast = true;
      }
      if ((enclosingInstanceType = this.enclosingInstance.resolveType(scope)) == null) {
        hasError = true;
      } else if (enclosingInstanceType.isBaseType() || enclosingInstanceType.isArrayType()) {
        scope
            .problemReporter()
            .illegalPrimitiveOrArrayTypeForEnclosingInstance(
                enclosingInstanceType, this.enclosingInstance);
        hasError = true;
      } else if (this.type instanceof QualifiedTypeReference) {
        scope
            .problemReporter()
            .illegalUsageOfQualifiedTypeReference((QualifiedTypeReference) this.type);
        hasError = true;
      } else if (!(enclosingInstanceReference = (ReferenceBinding) enclosingInstanceType)
          .canBeSeenBy(scope)) {
        // https://bugs.eclipse.org/bugs/show_bug.cgi?id=317212
        enclosingInstanceType =
            new ProblemReferenceBinding(
                enclosingInstanceReference.compoundName,
                enclosingInstanceReference,
                ProblemReasons.NotVisible);
        scope.problemReporter().invalidType(this.enclosingInstance, enclosingInstanceType);
        hasError = true;
      } else {
        receiverType =
            ((SingleTypeReference) this.type)
                .resolveTypeEnclosing(scope, (ReferenceBinding) enclosingInstanceType);
        if (receiverType != null && enclosingInstanceContainsCast) {
          CastExpression.checkNeedForEnclosingInstanceCast(
              scope, this.enclosingInstance, enclosingInstanceType, receiverType);
        }
      }
    } else {
      if (this.type == null) {
        // initialization of an enum constant
        receiverType = scope.enclosingSourceType();
      } else {
        receiverType = this.type.resolveType(scope, true /* check bounds*/);
        checkParameterizedAllocation:
        {
          if (receiverType == null || !receiverType.isValidBinding())
            break checkParameterizedAllocation;
          if (this.type
              instanceof
              ParameterizedQualifiedTypeReference) { // disallow new X<String>.Y<Integer>()
            ReferenceBinding currentType = (ReferenceBinding) receiverType;
            do {
              // isStatic() is answering true for toplevel types
              if ((currentType.modifiers & ClassFileConstants.AccStatic) != 0)
                break checkParameterizedAllocation;
              if (currentType.isRawType()) break checkParameterizedAllocation;
            } while ((currentType = currentType.enclosingType()) != null);
            ParameterizedQualifiedTypeReference qRef =
                (ParameterizedQualifiedTypeReference) this.type;
            for (int i = qRef.typeArguments.length - 2; i >= 0; i--) {
              if (qRef.typeArguments[i] != null) {
                scope
                    .problemReporter()
                    .illegalQualifiedParameterizedTypeAllocation(this.type, receiverType);
                break;
              }
            }
          }
        }
      }
    }
    if (receiverType == null || !receiverType.isValidBinding()) {
      hasError = true;
    }

    // resolve type arguments (for generic constructor call)
    final boolean isDiamond = this.type != null && (this.type.bits & ASTNode.IsDiamond) != 0;
    if (this.typeArguments != null) {
      int length = this.typeArguments.length;
      boolean argHasError = scope.compilerOptions().sourceLevel < ClassFileConstants.JDK1_5;
      this.genericTypeArguments = new TypeBinding[length];
      for (int i = 0; i < length; i++) {
        TypeReference typeReference = this.typeArguments[i];
        if ((this.genericTypeArguments[i] =
                typeReference.resolveType(scope, true /* check bounds*/))
            == null) {
          argHasError = true;
        }
        if (argHasError && typeReference instanceof Wildcard) {
          scope.problemReporter().illegalUsageOfWildcard(typeReference);
        }
      }
      if (isDiamond) {
        scope.problemReporter().diamondNotWithExplicitTypeArguments(this.typeArguments);
        return null;
      }
      if (argHasError) {
        if (this.arguments != null) { // still attempt to resolve arguments
          for (int i = 0, max = this.arguments.length; i < max; i++) {
            this.arguments[i].resolveType(scope);
          }
        }
        return null;
      }
    }

    // will check for null after args are resolved
    TypeBinding[] argumentTypes = Binding.NO_PARAMETERS;
    if (this.arguments != null) {
      int length = this.arguments.length;
      argumentTypes = new TypeBinding[length];
      for (int i = 0; i < length; i++) {
        Expression argument = this.arguments[i];
        if (argument instanceof CastExpression) {
          argument.bits |= ASTNode.DisableUnnecessaryCastCheck; // will check later on
          argsContainCast = true;
        }
        if ((argumentTypes[i] = argument.resolveType(scope)) == null) {
          hasError = true;
        }
      }
    }

    // limit of fault-tolerance
    if (hasError) {
      /* https://bugs.eclipse.org/bugs/show_bug.cgi?id=345359, if arguments have errors, completely bail out in the <> case.
        No meaningful type resolution is possible since inference of the elided types is fully tied to argument types. Do
        not return the partially resolved type.
      */
      if (isDiamond) {
        return null; // not the partially cooked this.resolvedType
      }
      if (receiverType instanceof ReferenceBinding) {
        ReferenceBinding referenceReceiver = (ReferenceBinding) receiverType;
        if (receiverType.isValidBinding()) {
          // record a best guess, for clients who need hint about possible contructor match
          int length = this.arguments == null ? 0 : this.arguments.length;
          TypeBinding[] pseudoArgs = new TypeBinding[length];
          for (int i = length; --i >= 0; ) {
            pseudoArgs[i] =
                argumentTypes[i] == null
                    ? TypeBinding.NULL
                    : argumentTypes[i]; // replace args with errors with null type
          }
          this.binding = scope.findMethod(referenceReceiver, TypeConstants.INIT, pseudoArgs, this);
          if (this.binding != null && !this.binding.isValidBinding()) {
            MethodBinding closestMatch = ((ProblemMethodBinding) this.binding).closestMatch;
            // record the closest match, for clients who may still need hint about possible method
            // match
            if (closestMatch != null) {
              if (closestMatch.original().typeVariables
                  != Binding.NO_TYPE_VARIABLES) { // generic method
                // shouldn't return generic method outside its context, rather convert it to raw
                // method (175409)
                closestMatch =
                    scope
                        .environment()
                        .createParameterizedGenericMethod(
                            closestMatch.original(), (RawTypeBinding) null);
              }
              this.binding = closestMatch;
              MethodBinding closestMatchOriginal = closestMatch.original();
              if (closestMatchOriginal.isOrEnclosedByPrivateType()
                  && !scope.isDefinedInMethod(closestMatchOriginal)) {
                // ignore cases where method is used from within inside itself (e.g. direct
                // recursions)
                closestMatchOriginal.modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
              }
            }
          }
        }
        if (this.anonymousType != null) {
          // insert anonymous type in scope (see
          // https://bugs.eclipse.org/bugs/show_bug.cgi?id=210070)
          scope.addAnonymousType(this.anonymousType, referenceReceiver);
          this.anonymousType.resolve(scope);
          return this.resolvedType = this.anonymousType.binding;
        }
      }
      return this.resolvedType = receiverType;
    }
    if (this.anonymousType == null) {
      // qualified allocation with no anonymous type
      if (!receiverType.canBeInstantiated()) {
        scope.problemReporter().cannotInstantiate(this.type, receiverType);
        return this.resolvedType = receiverType;
      }
      if (isDiamond) {
        TypeBinding[] inferredTypes =
            inferElidedTypes(
                ((ParameterizedTypeBinding) receiverType).genericType(),
                receiverType.enclosingType(),
                argumentTypes,
                scope);
        if (inferredTypes == null) {
          scope.problemReporter().cannotInferElidedTypes(this);
          return this.resolvedType = null;
        }
        receiverType =
            this.type.resolvedType =
                scope
                    .environment()
                    .createParameterizedType(
                        ((ParameterizedTypeBinding) receiverType).genericType(),
                        inferredTypes,
                        ((ParameterizedTypeBinding) receiverType).enclosingType());
      }
      ReferenceBinding allocationType = (ReferenceBinding) receiverType;
      if ((this.binding = scope.getConstructor(allocationType, argumentTypes, this))
          .isValidBinding()) {
        if (isMethodUseDeprecated(this.binding, scope, true)) {
          scope.problemReporter().deprecatedMethod(this.binding, this);
        }
        if (checkInvocationArguments(
            scope,
            null,
            allocationType,
            this.binding,
            this.arguments,
            argumentTypes,
            argsContainCast,
            this)) {
          this.bits |= ASTNode.Unchecked;
        }
        if (this.typeArguments != null
            && this.binding.original().typeVariables == Binding.NO_TYPE_VARIABLES) {
          scope
              .problemReporter()
              .unnecessaryTypeArgumentsForMethodInvocation(
                  this.binding, this.genericTypeArguments, this.typeArguments);
        }
      } else {
        if (this.binding.declaringClass == null) {
          this.binding.declaringClass = allocationType;
        }
        if (this.type != null && !this.type.resolvedType.isValidBinding()) {
          // problem already got signaled on type reference, do not report secondary problem
          return null;
        }
        scope.problemReporter().invalidConstructor(this, this.binding);
        return this.resolvedType = receiverType;
      }
      if ((this.binding.tagBits & TagBits.HasMissingType) != 0) {
        scope.problemReporter().missingTypeInConstructor(this, this.binding);
      }
      if (!isDiamond && receiverType.isParameterizedTypeWithActualArguments()) {
        checkTypeArgumentRedundancy(
            (ParameterizedTypeBinding) receiverType,
            receiverType.enclosingType(),
            argumentTypes,
            scope);
      }
      // The enclosing instance must be compatible with the innermost enclosing type
      ReferenceBinding expectedType = this.binding.declaringClass.enclosingType();
      if (expectedType
          != enclosingInstanceType) // must call before computeConversion() and typeMismatchError()
      scope.compilationUnitScope().recordTypeConversion(expectedType, enclosingInstanceType);
      if (enclosingInstanceType.isCompatibleWith(expectedType)
          || scope.isBoxingCompatibleWith(enclosingInstanceType, expectedType)) {
        this.enclosingInstance.computeConversion(scope, expectedType, enclosingInstanceType);
        return this.resolvedType = receiverType;
      }
      scope
          .problemReporter()
          .typeMismatchError(enclosingInstanceType, expectedType, this.enclosingInstance, null);
      return this.resolvedType = receiverType;
    } else {
      if (isDiamond) {
        scope.problemReporter().diamondNotWithAnoymousClasses(this.type);
        return null;
      }
    }
    ReferenceBinding superType = (ReferenceBinding) receiverType;
    if (superType.isTypeVariable()) {
      superType =
          new ProblemReferenceBinding(
              new char[][] {superType.sourceName()},
              superType,
              ProblemReasons.IllegalSuperTypeVariable);
      scope.problemReporter().invalidType(this, superType);
      return null;
    } else if (this.type != null && superType.isEnum()) { // tolerate enum constant body
      scope.problemReporter().cannotInstantiate(this.type, superType);
      return this.resolvedType = superType;
    }
    // anonymous type scenario
    // an anonymous class inherits from java.lang.Object when declared "after" an interface
    ReferenceBinding anonymousSuperclass =
        superType.isInterface() ? scope.getJavaLangObject() : superType;
    // insert anonymous type in scope
    scope.addAnonymousType(this.anonymousType, superType);
    this.anonymousType.resolve(scope);

    // find anonymous super constructor
    this.resolvedType = this.anonymousType.binding; // 1.2 change
    if ((this.resolvedType.tagBits & TagBits.HierarchyHasProblems) != 0) {
      return null; // stop secondary errors
    }
    MethodBinding inheritedBinding = scope.getConstructor(anonymousSuperclass, argumentTypes, this);
    if (!inheritedBinding.isValidBinding()) {
      if (inheritedBinding.declaringClass == null) {
        inheritedBinding.declaringClass = anonymousSuperclass;
      }
      if (this.type != null && !this.type.resolvedType.isValidBinding()) {
        // problem already got signaled on type reference, do not report secondary problem
        return null;
      }
      scope.problemReporter().invalidConstructor(this, inheritedBinding);
      return this.resolvedType;
    }
    if ((inheritedBinding.tagBits & TagBits.HasMissingType) != 0) {
      scope.problemReporter().missingTypeInConstructor(this, inheritedBinding);
    }
    if (this.enclosingInstance != null) {
      ReferenceBinding targetEnclosing = inheritedBinding.declaringClass.enclosingType();
      if (targetEnclosing == null) {
        scope
            .problemReporter()
            .unnecessaryEnclosingInstanceSpecification(this.enclosingInstance, superType);
        return this.resolvedType;
      } else if (!enclosingInstanceType.isCompatibleWith(targetEnclosing)
          && !scope.isBoxingCompatibleWith(enclosingInstanceType, targetEnclosing)) {
        scope
            .problemReporter()
            .typeMismatchError(
                enclosingInstanceType, targetEnclosing, this.enclosingInstance, null);
        return this.resolvedType;
      }
      this.enclosingInstance.computeConversion(scope, targetEnclosing, enclosingInstanceType);
    }
    if (this.arguments != null) {
      if (checkInvocationArguments(
          scope,
          null,
          anonymousSuperclass,
          inheritedBinding,
          this.arguments,
          argumentTypes,
          argsContainCast,
          this)) {
        this.bits |= ASTNode.Unchecked;
      }
    }
    if (this.typeArguments != null
        && inheritedBinding.original().typeVariables == Binding.NO_TYPE_VARIABLES) {
      scope
          .problemReporter()
          .unnecessaryTypeArgumentsForMethodInvocation(
              inheritedBinding, this.genericTypeArguments, this.typeArguments);
    }
    // Update the anonymous inner class : superclass, interface
    this.binding =
        this.anonymousType.createDefaultConstructorWithBinding(
            inheritedBinding,
            (this.bits & ASTNode.Unchecked) != 0 && this.genericTypeArguments == null);
    return this.resolvedType;
  }
Exemplo n.º 2
0
  private static void checkAlternateBinding(
      BlockScope scope,
      Expression receiver,
      TypeBinding receiverType,
      MethodBinding binding,
      Expression[] arguments,
      TypeBinding[] originalArgumentTypes,
      TypeBinding[] alternateArgumentTypes,
      final InvocationSite invocationSite) {
    InvocationSite fakeInvocationSite =
        new InvocationSite() {
          public TypeBinding[] genericTypeArguments() {
            return null;
          }

          public boolean isSuperAccess() {
            return invocationSite.isSuperAccess();
          }

          public boolean isTypeAccess() {
            return invocationSite.isTypeAccess();
          }

          public void setActualReceiverType(ReferenceBinding actualReceiverType) {
            /* ignore */
          }

          public void setDepth(int depth) {
            /* ignore */
          }

          public void setFieldIndex(int depth) {
            /* ignore */
          }

          public int sourceStart() {
            return 0;
          }

          public int sourceEnd() {
            return 0;
          }
        };
    MethodBinding bindingIfNoCast;
    if (binding.isConstructor()) {
      bindingIfNoCast =
          scope.getConstructor(
              (ReferenceBinding) receiverType, alternateArgumentTypes, fakeInvocationSite);
    } else {
      bindingIfNoCast =
          receiver.isImplicitThis()
              ? scope.getImplicitMethod(
                  binding.selector, alternateArgumentTypes, fakeInvocationSite)
              : scope.getMethod(
                  receiverType, binding.selector, alternateArgumentTypes, fakeInvocationSite);
    }
    if (bindingIfNoCast == binding) {
      int argumentLength = originalArgumentTypes.length;
      if (binding.isVarargs()) {
        int paramLength = binding.parameters.length;
        if (paramLength == argumentLength) {
          int varargsIndex = paramLength - 1;
          ArrayBinding varargsType = (ArrayBinding) binding.parameters[varargsIndex];
          TypeBinding lastArgType = alternateArgumentTypes[varargsIndex];
          // originalType may be compatible already, but cast mandated
          // to clarify between varargs/non-varargs call
          if (varargsType.dimensions != lastArgType.dimensions()) {
            return;
          }
          if (lastArgType.isCompatibleWith(varargsType.elementsType())
              && lastArgType.isCompatibleWith(varargsType)) {
            return;
          }
        }
      }
      for (int i = 0; i < argumentLength; i++) {
        if (originalArgumentTypes[i] != alternateArgumentTypes[i]) {
          scope.problemReporter().unnecessaryCast((CastExpression) arguments[i]);
        }
      }
    }
  }
  public TypeBinding resolveType(BlockScope scope) {
    // Propagate the type checking to the arguments, and check if the constructor is defined.
    this.constant = Constant.NotAConstant;
    if (this.type == null) {
      // initialization of an enum constant
      this.resolvedType = scope.enclosingReceiverType();
    } else {
      this.resolvedType = this.type.resolveType(scope, true /* check bounds*/);
      checkParameterizedAllocation:
      {
        if (this.type
            instanceof ParameterizedQualifiedTypeReference) { // disallow new X<String>.Y<Integer>()
          ReferenceBinding currentType = (ReferenceBinding) this.resolvedType;
          if (currentType == null) return currentType;
          do {
            // isStatic() is answering true for toplevel types
            if ((currentType.modifiers & ClassFileConstants.AccStatic) != 0)
              break checkParameterizedAllocation;
            if (currentType.isRawType()) break checkParameterizedAllocation;
          } while ((currentType = currentType.enclosingType()) != null);
          ParameterizedQualifiedTypeReference qRef =
              (ParameterizedQualifiedTypeReference) this.type;
          for (int i = qRef.typeArguments.length - 2; i >= 0; i--) {
            if (qRef.typeArguments[i] != null) {
              scope
                  .problemReporter()
                  .illegalQualifiedParameterizedTypeAllocation(this.type, this.resolvedType);
              break;
            }
          }
        }
      }
    }
    // will check for null after args are resolved

    final boolean isDiamond = this.type != null && (this.type.bits & ASTNode.IsDiamond) != 0;
    // resolve type arguments (for generic constructor call)
    if (this.typeArguments != null) {
      int length = this.typeArguments.length;
      boolean argHasError = scope.compilerOptions().sourceLevel < ClassFileConstants.JDK1_5;
      this.genericTypeArguments = new TypeBinding[length];
      for (int i = 0; i < length; i++) {
        TypeReference typeReference = this.typeArguments[i];
        if ((this.genericTypeArguments[i] =
                typeReference.resolveType(scope, true /* check bounds*/))
            == null) {
          argHasError = true;
        }
        if (argHasError && typeReference instanceof Wildcard) {
          scope.problemReporter().illegalUsageOfWildcard(typeReference);
        }
      }
      if (isDiamond) {
        scope.problemReporter().diamondNotWithExplicitTypeArguments(this.typeArguments);
        return null;
      }
      if (argHasError) {
        if (this.arguments != null) { // still attempt to resolve arguments
          for (int i = 0, max = this.arguments.length; i < max; i++) {
            this.arguments[i].resolveType(scope);
          }
        }
        return null;
      }
    }

    // buffering the arguments' types
    boolean argsContainCast = false;
    TypeBinding[] argumentTypes = Binding.NO_PARAMETERS;
    if (this.arguments != null) {
      boolean argHasError = false;
      int length = this.arguments.length;
      argumentTypes = new TypeBinding[length];
      for (int i = 0; i < length; i++) {
        Expression argument = this.arguments[i];
        if (argument instanceof CastExpression) {
          argument.bits |= DisableUnnecessaryCastCheck; // will check later on
          argsContainCast = true;
        }
        if ((argumentTypes[i] = argument.resolveType(scope)) == null) {
          argHasError = true;
        }
      }
      if (argHasError) {
        /* https://bugs.eclipse.org/bugs/show_bug.cgi?id=345359, if arguments have errors, completely bail out in the <> case.
          No meaningful type resolution is possible since inference of the elided types is fully tied to argument types. Do
          not return the partially resolved type.
        */
        if (isDiamond) {
          return null; // not the partially cooked this.resolvedType
        }
        if (this.resolvedType instanceof ReferenceBinding) {
          // record a best guess, for clients who need hint about possible constructor match
          TypeBinding[] pseudoArgs = new TypeBinding[length];
          for (int i = length; --i >= 0; ) {
            pseudoArgs[i] =
                argumentTypes[i] == null
                    ? TypeBinding.NULL
                    : argumentTypes[i]; // replace args with errors with null type
          }
          this.binding =
              scope.findMethod(
                  (ReferenceBinding) this.resolvedType, TypeConstants.INIT, pseudoArgs, this);
          if (this.binding != null && !this.binding.isValidBinding()) {
            MethodBinding closestMatch = ((ProblemMethodBinding) this.binding).closestMatch;
            // record the closest match, for clients who may still need hint about possible method
            // match
            if (closestMatch != null) {
              if (closestMatch.original().typeVariables
                  != Binding.NO_TYPE_VARIABLES) { // generic method
                // shouldn't return generic method outside its context, rather convert it to raw
                // method (175409)
                closestMatch =
                    scope
                        .environment()
                        .createParameterizedGenericMethod(
                            closestMatch.original(), (RawTypeBinding) null);
              }
              this.binding = closestMatch;
              MethodBinding closestMatchOriginal = closestMatch.original();
              if (closestMatchOriginal.isOrEnclosedByPrivateType()
                  && !scope.isDefinedInMethod(closestMatchOriginal)) {
                // ignore cases where method is used from within inside itself (e.g. direct
                // recursions)
                closestMatchOriginal.modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
              }
            }
          }
        }
        return this.resolvedType;
      }
    }
    if (this.resolvedType == null || !this.resolvedType.isValidBinding()) {
      return null;
    }

    // null type denotes fake allocation for enum constant inits
    if (this.type != null && !this.resolvedType.canBeInstantiated()) {
      scope.problemReporter().cannotInstantiate(this.type, this.resolvedType);
      return this.resolvedType;
    }
    if (isDiamond) {
      TypeBinding[] inferredTypes =
          inferElidedTypes(
              ((ParameterizedTypeBinding) this.resolvedType).genericType(),
              null,
              argumentTypes,
              scope);
      if (inferredTypes == null) {
        scope.problemReporter().cannotInferElidedTypes(this);
        return this.resolvedType = null;
      }
      this.resolvedType =
          this.type.resolvedType =
              scope
                  .environment()
                  .createParameterizedType(
                      ((ParameterizedTypeBinding) this.resolvedType).genericType(),
                      inferredTypes,
                      ((ParameterizedTypeBinding) this.resolvedType).enclosingType());
    }
    ReferenceBinding allocationType = (ReferenceBinding) this.resolvedType;
    if (!(this.binding = scope.getConstructor(allocationType, argumentTypes, this))
        .isValidBinding()) {
      if (this.binding.declaringClass == null) {
        this.binding.declaringClass = allocationType;
      }
      if (this.type != null && !this.type.resolvedType.isValidBinding()) {
        return null;
      }
      scope.problemReporter().invalidConstructor(this, this.binding);
      return this.resolvedType;
    }
    if ((this.binding.tagBits & TagBits.HasMissingType) != 0) {
      scope.problemReporter().missingTypeInConstructor(this, this.binding);
    }
    if (isMethodUseDeprecated(this.binding, scope, true))
      scope.problemReporter().deprecatedMethod(this.binding, this);
    if (checkInvocationArguments(
        scope,
        null,
        allocationType,
        this.binding,
        this.arguments,
        argumentTypes,
        argsContainCast,
        this)) {
      this.bits |= ASTNode.Unchecked;
    }
    if (this.typeArguments != null
        && this.binding.original().typeVariables == Binding.NO_TYPE_VARIABLES) {
      scope
          .problemReporter()
          .unnecessaryTypeArgumentsForMethodInvocation(
              this.binding, this.genericTypeArguments, this.typeArguments);
    }
    if (!isDiamond && this.resolvedType.isParameterizedTypeWithActualArguments()) {
      checkTypeArgumentRedundancy(
          (ParameterizedTypeBinding) this.resolvedType, null, argumentTypes, scope);
    }
    final CompilerOptions compilerOptions = scope.compilerOptions();
    if (compilerOptions.isAnnotationBasedNullAnalysisEnabled
        && (this.binding.tagBits & TagBits.IsNullnessKnown) == 0) {
      new ImplicitNullAnnotationVerifier(
              scope.environment(), compilerOptions.inheritNullAnnotations)
          .checkImplicitNullAnnotations(this.binding, null /*srcMethod*/, false, scope);
    }
    return allocationType;
  }