Exemplo n.º 1
0
 /**
  * Same as above, but consider specified signature for argument mapping (using AnchorMapping).
  *
  * @param receiverType receiver of the method call.
  * @param scope
  * @param isBaseSide
  * @param callinExpected whether this method spec is the LHS of a replace callin.
  * @param allowEnclosing whether a method may be found in an enclosing type of receiverType
  */
 public void resolveFeatureWithArgMapping(
     ReferenceBinding receiverType,
     BlockScope scope,
     boolean isBaseSide,
     boolean callinExpected,
     boolean allowEnclosing) {
   FieldReference receiver = null;
   if (isBaseSide) {
     // construct temporary faked receiver
     ReferenceContext referenceContext = scope.referenceContext();
     CheckPoint cp = referenceContext.compilationResult().getCheckPoint(referenceContext);
     receiver =
         new FieldReference(
             IOTConstants._OT_BASE,
             0L); // can't fail, help the compiler recognize that receiver won't be null below.
     try {
       receiver.receiver = ThisReference.implicitThis();
       receiver.resolveType(scope);
     } finally {
       if (receiver.binding == null || !receiver.binding.isValidBinding()) {
         // resolve didn't work, which happens if role is ifc, thus has no base field
         // at least set the receiver type.
         // TODO(SH): this means, role ifcs can not use base-anchored types.
         receiver.resolvedType = receiverType;
         referenceContext.compilationResult().rollBack(cp);
       }
     }
   }
   AnchorMapping anchorMapping = null;
   try {
     anchorMapping = AnchorMapping.setupNewMapping(receiver, this.arguments, scope);
     resolveFeature(receiverType, scope, callinExpected, isBaseSide, allowEnclosing);
   } finally {
     AnchorMapping.removeCurrentMapping(anchorMapping);
   }
 }
Exemplo n.º 2
0
  public TypeBinding resolveType(BlockScope scope) {
    // compute a new constant if the cast is effective

    this.constant = Constant.NotAConstant;
    this.implicitConversion = TypeIds.T_undefined;

    boolean exprContainCast = false;

    TypeBinding castType = this.resolvedType = this.type.resolveType(scope);
    if (scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_8) {
      this.expression.setExpressionContext(CASTING_CONTEXT);
      if (this.expression instanceof FunctionalExpression) {
        this.expression.setExpectedType(this.resolvedType);
        this.bits |= ASTNode.DisableUnnecessaryCastCheck;
      }
    }
    if (this.expression instanceof CastExpression) {
      this.expression.bits |= ASTNode.DisableUnnecessaryCastCheck;
      exprContainCast = true;
    }
    TypeBinding expressionType = this.expression.resolveType(scope);
    if (this.expression instanceof MessageSend) {
      MessageSend messageSend = (MessageSend) this.expression;
      MethodBinding methodBinding = messageSend.binding;
      if (methodBinding != null && methodBinding.isPolymorphic()) {
        messageSend.binding =
            scope
                .environment()
                .updatePolymorphicMethodReturnType(
                    (PolymorphicMethodBinding) methodBinding, castType);
        if (TypeBinding.notEquals(expressionType, castType)) {
          expressionType = castType;
          this.bits |= ASTNode.DisableUnnecessaryCastCheck;
        }
      }
    }
    if (castType != null) {
      if (expressionType != null) {

        boolean nullAnnotationMismatch =
            scope.compilerOptions().isAnnotationBasedNullAnalysisEnabled
                && NullAnnotationMatching.analyse(castType, expressionType, -1).isAnyMismatch();

        boolean isLegal =
            checkCastTypesCompatibility(scope, castType, expressionType, this.expression);
        if (isLegal) {
          this.expression.computeConversion(scope, castType, expressionType);
          if ((this.bits & ASTNode.UnsafeCast) != 0) { // unsafe cast
            if (scope.compilerOptions().reportUnavoidableGenericTypeProblems
                || !(expressionType.isRawType()
                    && this.expression.forcedToBeRaw(scope.referenceContext()))) {
              scope.problemReporter().unsafeCast(this, scope);
            }
          } else if (nullAnnotationMismatch) {
            // report null annotation issue at medium priority
            scope.problemReporter().unsafeNullnessCast(this, scope);
          } else {
            if (castType.isRawType()
                && scope.compilerOptions().getSeverity(CompilerOptions.RawTypeReference)
                    != ProblemSeverities.Ignore) {
              scope.problemReporter().rawTypeReference(this.type, castType);
            }
            if ((this.bits & (ASTNode.UnnecessaryCast | ASTNode.DisableUnnecessaryCastCheck))
                == ASTNode.UnnecessaryCast) { // unnecessary cast
              if (!isIndirectlyUsed()) // used for generic type inference or boxing ?
              scope.problemReporter().unnecessaryCast(this);
            }
          }
        } else { // illegal cast
          if ((castType.tagBits & TagBits.HasMissingType) == 0) { // no complaint if secondary error
            scope.problemReporter().typeCastError(this, castType, expressionType);
          }
          this.bits |= ASTNode.DisableUnnecessaryCastCheck; // disable further secondary diagnosis
        }
      }
      this.resolvedType =
          castType.capture(
              scope,
              this.type.sourceStart,
              this.type
                  .sourceEnd); // make it unique, a cast expression shares source end with the
                               // expression.
      if (exprContainCast) {
        checkNeedForCastCast(scope, this);
      }
    }
    return this.resolvedType;
  }
Exemplo n.º 3
0
  /**
   * Resolve the method or field (see FieldAccessSpec).
   *
   * @param receiverType receiver of the method call.
   * @param scope
   * @param callinExpected whether this method spec is the LHS of a replace callin.
   * @param isBaseSide whether this method spec is the RHS (any binding kind)
   * @param allowEnclosing whether a method may be found in an enclosing type of receiverType
   * @return the resolved method (may be problem method) or null
   */
  public MethodBinding resolveFeature(
      ReferenceBinding receiverType,
      BlockScope scope,
      boolean callinExpected,
      boolean isBaseSide,
      boolean allowEnclosing) {
    // getRealClass() is used, because decapsulation needs to find private methods,
    // which for roles are found only in the class part.
    ReferenceBinding receiverClass = receiverType.getRealClass();
    boolean isConstructorSpec = CharOperation.equals(this.selector, receiverClass.sourceName());
    char[] realSelector = isConstructorSpec ? TypeConstants.INIT : this.selector;
    if (this.hasSignature) {
      TypeBinding[] enhancedParameters = this.parameters;
      // first chance: try enhanced:
      enhancedParameters = MethodSignatureEnhancer.enhanceParameters(scope, this.parameters);
      CompilationResult compilationResult = scope.referenceContext().compilationResult();
      CheckPoint cp = compilationResult.getCheckPoint(scope.referenceContext());

      this.resolvedMethod =
          TypeAnalyzer.findMethod(
              scope,
              receiverClass,
              realSelector,
              enhancedParameters,
              isBaseSide,
              isBaseSide ? this : null);
      if (!this.resolvedMethod.isValidBinding()
          && this.resolvedMethod.problemId() == ProblemReasons.NotFound) {
        // second+ chance: try plain:
        while (receiverClass != null) {
          compilationResult.rollBack(cp);
          MethodBinding plainMethod =
              TypeAnalyzer.findMethod(
                  scope,
                  receiverClass,
                  realSelector,
                  this.parameters,
                  isBaseSide,
                  isBaseSide ? this : null);
          if (!callinExpected) {
            this.resolvedMethod = plainMethod;
          } else {
            if (plainMethod != null && plainMethod.isValidBinding())
              scope.problemReporter().replaceMappingToNonCallin(this, plainMethod);
            // mark the ProblemMethodBinding consistently to what we have been looking for last:
            this.resolvedMethod.modifiers |=
                ExtraCompilerModifiers.AccCallin | ClassFileConstants.AccStatic;
          }
          if (plainMethod != null && plainMethod.isValidBinding()) break;
          if (allowEnclosing) receiverClass = receiverClass.enclosingType();
          else receiverClass = null;
        }
      }
    } else {
      CompilationResult compilationResult = scope.referenceContext().compilationResult();
      CheckPoint cp = compilationResult.getCheckPoint(scope.referenceContext());
      while (receiverClass != null) {
        this.resolvedMethod = receiverClass.getMethod(scope, realSelector);
        if (this.resolvedMethod != null && this.resolvedMethod.isValidBinding()) break; // good
        if (!allowEnclosing) break; // bad
        compilationResult.rollBack(cp);
        receiverClass = receiverClass.enclosingType();
      }
    }
    if (this.resolvedMethod != null) {
      if (this.resolvedMethod.isValidBinding()) {
        // check visibility of role-side in callin:
        if (!isBaseSide
            && scope.referenceContext() instanceof CallinMappingDeclaration
            && !this.resolvedMethod.canBeSeenBy(this, scope)) {
          scope.problemReporter().invisibleMethod(this, this.resolvedMethod);
          this.resolvedMethod =
              new ProblemMethodBinding(
                  this.resolvedMethod, this.selector, this.parameters, ProblemReasons.NotVisible);
        }
      }
      if (!this.resolvedMethod.isValidBinding() && this.resolvedMethod.declaringClass == null)
        this.resolvedMethod.declaringClass = receiverClass; // needed for computeUniqueKey (via
      // CallinCalloutBinding.computeUniqueKey)
    }
    return this.resolvedMethod;
  }