Exemplo n.º 1
0
  public TypeBinding resolveType(BlockScope scope) {
    // due to syntax lhs may be only a NameReference, a FieldReference or an ArrayReference
    this.constant = Constant.NotAConstant;
    if (!(this.lhs instanceof Reference) || this.lhs.isThis()) {
      scope.problemReporter().expressionShouldBeAVariable(this.lhs);
      return null;
    }
    TypeBinding lhsType = lhs.resolveType(scope);
    this.expression.setExpectedType(lhsType); // needed in case of generic method invocation
    if (lhsType != null) {
      this.resolvedType = lhsType.capture(scope, this.sourceEnd);
    }
    TypeBinding rhsType = this.expression.resolveType(scope);
    if (lhsType == null || rhsType == null) {
      return null;
    }
    // check for assignment with no effect
    Binding left = getDirectBinding(this.lhs);
    if (left != null && left == getDirectBinding(this.expression)) {
      scope.problemReporter().assignmentHasNoEffect(this, left.shortReadableName());
    }

    // Compile-time conversion of base-types : implicit narrowing integer into byte/short/character
    // may require to widen the rhs expression at runtime
    if (lhsType != rhsType) { // must call before computeConversion() and typeMismatchError()
      scope.compilationUnitScope().recordTypeConversion(lhsType, rhsType);
    }
    if ((this.expression.isConstantValueOfTypeAssignableToType(rhsType, lhsType)
            || (lhsType.isBaseType() && BaseTypeBinding.isWidening(lhsType.id, rhsType.id)))
        || rhsType.isCompatibleWith(lhsType)) {
      this.expression.computeConversion(scope, lhsType, rhsType);
      checkAssignment(scope, lhsType, rhsType);
      if (this.expression instanceof CastExpression
          && (this.expression.bits & ASTNode.UnnecessaryCast) == 0) {
        CastExpression.checkNeedForAssignedCast(scope, lhsType, (CastExpression) this.expression);
      }
      return this.resolvedType;
    } else if (scope.isBoxingCompatibleWith(rhsType, lhsType)
        || (rhsType.isBaseType() // narrowing then boxing ?
            && scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5 // autoboxing
            && !lhsType.isBaseType()
            && this.expression.isConstantValueOfTypeAssignableToType(
                rhsType, scope.environment().computeBoxingType(lhsType)))) {
      this.expression.computeConversion(scope, lhsType, rhsType);
      if (this.expression instanceof CastExpression
          && (this.expression.bits & ASTNode.UnnecessaryCast) == 0) {
        CastExpression.checkNeedForAssignedCast(scope, lhsType, (CastExpression) this.expression);
      }
      return this.resolvedType;
    }
    scope.problemReporter().typeMismatchError(rhsType, lhsType, this.expression, this.lhs);
    return lhsType;
  }
Exemplo n.º 2
0
  protected boolean isBoxingCompatible(
      TypeBinding expressionType, TypeBinding targetType, Expression expression, Scope scope) {
    if (scope.isBoxingCompatibleWith(expressionType, targetType)) return true;

    return expressionType
            .isBaseType() // narrowing then boxing ? Only allowed for some target types see 362279
        && !targetType.isBaseType()
        && !targetType.isTypeVariable()
        && scope.compilerOptions().sourceLevel
            >= org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK1_5 // autoboxing
        && (targetType.id == TypeIds.T_JavaLangByte
            || targetType.id == TypeIds.T_JavaLangShort
            || targetType.id == TypeIds.T_JavaLangCharacter)
        && expression.isConstantValueOfTypeAssignableToType(
            expressionType, scope.environment().computeBoxingType(targetType));
  }
  public TypeBinding resolveType(BlockScope scope) {
    this.constant = Constant.NotAConstant;
    TypeBinding expressionType = this.expression.resolveType(scope);
    TypeBinding checkedType = this.type.resolveType(scope, true /* check bounds*/);
    if (expressionType == null || checkedType == null) return null;

    if (!checkedType.isReifiable()) {
      scope.problemReporter().illegalInstanceOfGenericType(checkedType, this);
    } else if ((expressionType != TypeBinding.NULL
            && expressionType.isBaseType()) // disallow autoboxing
        || !checkCastTypesCompatibility(scope, checkedType, expressionType, null)) {
      scope.problemReporter().notCompatibleTypesError(this, expressionType, checkedType);
    }
    return this.resolvedType = TypeBinding.BOOLEAN;
  }
Exemplo n.º 4
0
  /* Answer true if the type use is considered deprecated.
   * An access in the same compilation unit is allowed.
   */
  public final boolean isTypeUseDeprecated(TypeBinding type, Scope scope) {

    if (type.isArrayType()) {
      type = ((ArrayBinding) type).leafComponentType;
    }
    if (type.isBaseType()) return false;

    ReferenceBinding refType = (ReferenceBinding) type;
    // ignore references insing Javadoc comments
    if ((this.bits & ASTNode.InsideJavadoc) == 0
        && refType.isOrEnclosedByPrivateType()
        && !scope.isDefinedInType(refType)) {
      // ignore cases where type is used from inside itself
      ((ReferenceBinding) refType.erasure()).modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
    }

    if (refType.hasRestrictedAccess()) {
      AccessRestriction restriction = scope.environment().getAccessRestriction(type.erasure());
      if (restriction != null) {
        scope
            .problemReporter()
            .forbiddenReference(
                type,
                this,
                restriction.classpathEntryType,
                restriction.classpathEntryName,
                restriction.getProblemId());
      }
    }

    // force annotations resolution before deciding whether the type may be deprecated
    refType.initializeDeprecatedAnnotationTagBits();

    if (!refType.isViewedAsDeprecated()) return false;

    // inside same unit - no report
    if (scope.isDefinedInSameUnit(refType)) return false;

    // if context is deprecated, may avoid reporting
    if (!scope.compilerOptions().reportDeprecationInsideDeprecatedCode
        && scope.isInsideDeprecatedCode()) return false;
    return true;
  }
Exemplo n.º 5
0
  public TypeBinding resolveTypeExpecting(BlockScope scope, TypeBinding expectedType) {
    // Array initializers can only occur on the right hand side of an assignment
    // expression, therefore the expected type contains the valid information
    // concerning the type that must be enforced by the elements of the array initializer.

    // this method is recursive... (the test on isArrayType is the stop case)

    this.constant = Constant.NotAConstant;

    if (expectedType instanceof ArrayBinding) {
      // allow new List<?>[5]
      if ((this.bits & IsAnnotationDefaultValue)
          == 0) { // annotation default value need only to be commensurate JLS9.7
        // allow new List<?>[5] - only check for generic array when no initializer, since also
        // checked inside initializer resolution
        TypeBinding leafComponentType = expectedType.leafComponentType();
        if (!leafComponentType.isReifiable()) {
          scope.problemReporter().illegalGenericArray(leafComponentType, this);
        }
      }
      this.resolvedType = this.binding = (ArrayBinding) expectedType;
      if (this.expressions == null) return this.binding;
      TypeBinding elementType = this.binding.elementsType();
      for (int i = 0, length = this.expressions.length; i < length; i++) {
        Expression expression = this.expressions[i];
        expression.setExpectedType(elementType);
        TypeBinding expressionType =
            expression instanceof ArrayInitializer
                ? expression.resolveTypeExpecting(scope, elementType)
                : expression.resolveType(scope);
        if (expressionType == null) continue;

        // Compile-time conversion required?
        if (elementType
            != expressionType) // must call before computeConversion() and typeMismatchError()
        scope.compilationUnitScope().recordTypeConversion(elementType, expressionType);

        if (expression.isConstantValueOfTypeAssignableToType(expressionType, elementType)
            || expressionType.isCompatibleWith(elementType)) {
          expression.computeConversion(scope, elementType, expressionType);
        } else if (scope.isBoxingCompatibleWith(expressionType, elementType)
            || (expressionType.isBaseType() // narrowing then boxing ?
                && scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5 // autoboxing
                && !elementType.isBaseType()
                && expression.isConstantValueOfTypeAssignableToType(
                    expressionType, scope.environment().computeBoxingType(elementType)))) {
          expression.computeConversion(scope, elementType, expressionType);
        } else {
          scope.problemReporter().typeMismatchError(expressionType, elementType, expression, null);
        }
      }
      return this.binding;
    }

    // infer initializer type for error reporting based on first element
    TypeBinding leafElementType = null;
    int dim = 1;
    if (this.expressions == null) {
      leafElementType = scope.getJavaLangObject();
    } else {
      Expression expression = this.expressions[0];
      while (expression != null && expression instanceof ArrayInitializer) {
        dim++;
        Expression[] subExprs = ((ArrayInitializer) expression).expressions;
        if (subExprs == null) {
          leafElementType = scope.getJavaLangObject();
          expression = null;
          break;
        }
        expression = ((ArrayInitializer) expression).expressions[0];
      }
      if (expression != null) {
        leafElementType = expression.resolveType(scope);
      }
      // fault-tolerance - resolve other expressions as well
      for (int i = 1, length = this.expressions.length; i < length; i++) {
        expression = this.expressions[i];
        if (expression != null) {
          expression.resolveType(scope);
        }
      }
    }
    if (leafElementType != null) {
      this.resolvedType = scope.createArrayType(leafElementType, dim);
      if (expectedType != null)
        scope.problemReporter().typeMismatchError(this.resolvedType, expectedType, this, null);
    }
    return null;
  }