Search in sources :

Example 1 with ProblemFieldBinding

use of org.eclipse.jdt.internal.compiler.lookup.ProblemFieldBinding in project bazel-jdt-java-toolchain by salesforce.

the class FieldReference method resolveType.

@Override
public TypeBinding resolveType(BlockScope scope) {
    // Answer the signature type of the field.
    // constants are propaged when the field is final
    // and initialized with a (compile time) constant
    // always ignore receiver cast, since may affect constant pool reference
    boolean receiverCast = false;
    if (this.receiver instanceof CastExpression) {
        // will check later on
        this.receiver.bits |= ASTNode.DisableUnnecessaryCastCheck;
        receiverCast = true;
    }
    this.actualReceiverType = this.receiver.resolveType(scope);
    if (this.actualReceiverType == null) {
        this.constant = Constant.NotAConstant;
        return null;
    }
    if (receiverCast) {
        // due to change of declaring class with receiver type, only identity cast should be notified
        if (TypeBinding.equalsEquals(((CastExpression) this.receiver).expression.resolvedType, this.actualReceiverType)) {
            scope.problemReporter().unnecessaryCast((CastExpression) this.receiver);
        }
    }
    // the case receiverType.isArrayType and token = 'length' is handled by the scope API
    FieldBinding fieldBinding = this.binding = scope.getField(this.actualReceiverType, this.token, this);
    if (!fieldBinding.isValidBinding()) {
        this.constant = Constant.NotAConstant;
        if (this.receiver.resolvedType instanceof ProblemReferenceBinding) {
            // problem already got signaled on receiver, do not report secondary problem
            return null;
        }
        // https://bugs.eclipse.org/bugs/show_bug.cgi?id=245007 avoid secondary errors in case of
        // missing super type for anonymous classes ...
        ReferenceBinding declaringClass = fieldBinding.declaringClass;
        boolean avoidSecondary = declaringClass != null && declaringClass.isAnonymousType() && declaringClass.superclass() instanceof MissingTypeBinding;
        if (!avoidSecondary) {
            scope.problemReporter().invalidField(this, this.actualReceiverType);
        }
        if (fieldBinding instanceof ProblemFieldBinding) {
            ProblemFieldBinding problemFieldBinding = (ProblemFieldBinding) fieldBinding;
            FieldBinding closestMatch = problemFieldBinding.closestMatch;
            switch(problemFieldBinding.problemId()) {
                case ProblemReasons.InheritedNameHidesEnclosingName:
                case ProblemReasons.NotVisible:
                case ProblemReasons.NonStaticReferenceInConstructorInvocation:
                case ProblemReasons.NonStaticReferenceInStaticContext:
                    if (closestMatch != null) {
                        fieldBinding = closestMatch;
                    }
            }
        }
        if (!fieldBinding.isValidBinding()) {
            return null;
        }
    }
    // handle indirect inheritance thru variable secondary bound
    // receiver may receive generic cast, as part of implicit conversion
    TypeBinding oldReceiverType = this.actualReceiverType;
    this.actualReceiverType = this.actualReceiverType.getErasureCompatibleType(fieldBinding.declaringClass);
    this.receiver.computeConversion(scope, this.actualReceiverType, this.actualReceiverType);
    if (TypeBinding.notEquals(this.actualReceiverType, oldReceiverType) && TypeBinding.notEquals(this.receiver.postConversionType(scope), this.actualReceiverType)) {
        // record need for explicit cast at codegen since receiver could not handle it
        this.bits |= NeedReceiverGenericCast;
    }
    if (isFieldUseDeprecated(fieldBinding, scope, this.bits)) {
        scope.problemReporter().deprecatedField(fieldBinding, this);
    }
    boolean isImplicitThisRcv = this.receiver.isImplicitThis();
    this.constant = isImplicitThisRcv ? fieldBinding.constant(scope) : Constant.NotAConstant;
    if (fieldBinding.isStatic()) {
        // static field accessed through receiver? legal but unoptimal (optional warning)
        if (!(isImplicitThisRcv || (this.receiver instanceof NameReference && (((NameReference) this.receiver).bits & Binding.TYPE) != 0))) {
            scope.problemReporter().nonStaticAccessToStaticField(this, fieldBinding);
        }
        ReferenceBinding declaringClass = this.binding.declaringClass;
        if (!isImplicitThisRcv && TypeBinding.notEquals(declaringClass, this.actualReceiverType) && declaringClass.canBeSeenBy(scope)) {
            scope.problemReporter().indirectAccessToStaticField(this, fieldBinding);
        }
        // check if accessing enum static field in initializer
        if (declaringClass.isEnum() && scope.kind != Scope.MODULE_SCOPE) {
            MethodScope methodScope = scope.methodScope();
            SourceTypeBinding sourceType = scope.enclosingSourceType();
            if (this.constant == Constant.NotAConstant && !methodScope.isStatic && // enum constant body
            (TypeBinding.equalsEquals(sourceType, declaringClass) || TypeBinding.equalsEquals(sourceType.superclass, declaringClass)) && methodScope.isInsideInitializerOrConstructor()) {
                scope.problemReporter().enumStaticFieldUsedDuringInitialization(this.binding, this);
            }
        }
    }
    TypeBinding fieldType = fieldBinding.type;
    if (fieldType != null) {
        if ((this.bits & ASTNode.IsStrictlyAssigned) == 0) {
            // perform capture conversion if read access
            fieldType = fieldType.capture(scope, this.sourceStart, this.sourceEnd);
        }
        this.resolvedType = fieldType;
        if ((fieldType.tagBits & TagBits.HasMissingType) != 0) {
            scope.problemReporter().invalidType(this, fieldType);
            return null;
        }
    }
    return fieldType;
}
Also used : ProblemReferenceBinding(org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding) MissingTypeBinding(org.eclipse.jdt.internal.compiler.lookup.MissingTypeBinding) SourceTypeBinding(org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding) TypeBinding(org.eclipse.jdt.internal.compiler.lookup.TypeBinding) MissingTypeBinding(org.eclipse.jdt.internal.compiler.lookup.MissingTypeBinding) FieldBinding(org.eclipse.jdt.internal.compiler.lookup.FieldBinding) ProblemFieldBinding(org.eclipse.jdt.internal.compiler.lookup.ProblemFieldBinding) ProblemFieldBinding(org.eclipse.jdt.internal.compiler.lookup.ProblemFieldBinding) ReferenceBinding(org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding) ProblemReferenceBinding(org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding) MethodScope(org.eclipse.jdt.internal.compiler.lookup.MethodScope) SourceTypeBinding(org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding)

Example 2 with ProblemFieldBinding

use of org.eclipse.jdt.internal.compiler.lookup.ProblemFieldBinding in project bazel-jdt-java-toolchain by salesforce.

the class QualifiedNameReference method reportError.

/**
 * Normal field binding did not work, try to bind to a field of the delegate receiver.
 */
public TypeBinding reportError(BlockScope scope) {
    Binding inaccessible = scope.environment().getInaccessibleBinding(this.tokens, scope.module());
    if (inaccessible instanceof TypeBinding) {
        this.indexOfFirstFieldBinding = -1;
        this.binding = inaccessible;
        scope.problemReporter().invalidType(this, (TypeBinding) this.binding);
    } else if (this.binding instanceof ProblemFieldBinding) {
        scope.problemReporter().invalidField(this, (FieldBinding) this.binding);
    } else if (this.binding instanceof ProblemReferenceBinding || this.binding instanceof MissingTypeBinding) {
        scope.problemReporter().invalidType(this, (TypeBinding) this.binding);
    } else {
        scope.problemReporter().unresolvableReference(this, this.binding);
    }
    return null;
}
Also used : SourceTypeBinding(org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding) LocalVariableBinding(org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding) FieldBinding(org.eclipse.jdt.internal.compiler.lookup.FieldBinding) Binding(org.eclipse.jdt.internal.compiler.lookup.Binding) TypeBinding(org.eclipse.jdt.internal.compiler.lookup.TypeBinding) MissingTypeBinding(org.eclipse.jdt.internal.compiler.lookup.MissingTypeBinding) MethodBinding(org.eclipse.jdt.internal.compiler.lookup.MethodBinding) VariableBinding(org.eclipse.jdt.internal.compiler.lookup.VariableBinding) ReferenceBinding(org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding) SyntheticMethodBinding(org.eclipse.jdt.internal.compiler.lookup.SyntheticMethodBinding) ProblemFieldBinding(org.eclipse.jdt.internal.compiler.lookup.ProblemFieldBinding) ProblemReferenceBinding(org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding) ProblemReferenceBinding(org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding) MissingTypeBinding(org.eclipse.jdt.internal.compiler.lookup.MissingTypeBinding) SourceTypeBinding(org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding) TypeBinding(org.eclipse.jdt.internal.compiler.lookup.TypeBinding) MissingTypeBinding(org.eclipse.jdt.internal.compiler.lookup.MissingTypeBinding) ProblemFieldBinding(org.eclipse.jdt.internal.compiler.lookup.ProblemFieldBinding) FieldBinding(org.eclipse.jdt.internal.compiler.lookup.FieldBinding) ProblemFieldBinding(org.eclipse.jdt.internal.compiler.lookup.ProblemFieldBinding)

Example 3 with ProblemFieldBinding

use of org.eclipse.jdt.internal.compiler.lookup.ProblemFieldBinding in project bazel-jdt-java-toolchain by salesforce.

the class QualifiedNameReference method resolveType.

@Override
public TypeBinding resolveType(BlockScope scope) {
    // field and/or local are done before type lookups
    // the only available value for the restrictiveFlag BEFORE
    // the TC is Flag_Type Flag_LocalField and Flag_TypeLocalField
    this.actualReceiverType = scope.enclosingReceiverType();
    this.constant = Constant.NotAConstant;
    if ((this.binding = scope.getBinding(this.tokens, this.bits & ASTNode.RestrictiveFlagMASK, this, true)).isValidBinding()) {
        switch(this.bits & ASTNode.RestrictiveFlagMASK) {
            // ============only variable===========
            case Binding.VARIABLE:
            case Binding.TYPE | Binding.VARIABLE:
                if (this.binding instanceof LocalVariableBinding) {
                    // clear bits
                    this.bits &= ~ASTNode.RestrictiveFlagMASK;
                    this.bits |= Binding.LOCAL;
                    LocalVariableBinding local = (LocalVariableBinding) this.binding;
                    if (!local.isFinal() && (this.bits & ASTNode.IsCapturedOuterLocal) != 0) {
                        if (// for 8, defer till effective finality could be ascertained.
                        scope.compilerOptions().sourceLevel < ClassFileConstants.JDK1_8)
                            scope.problemReporter().cannotReferToNonFinalOuterLocal((LocalVariableBinding) this.binding, this);
                    }
                    if (local.type != null && (local.type.tagBits & TagBits.HasMissingType) != 0) {
                        // only complain if field reference (for local, its type got flagged already)
                        return null;
                    }
                    this.resolvedType = getOtherFieldBindings(scope);
                    if (this.resolvedType != null && (this.resolvedType.tagBits & TagBits.HasMissingType) != 0) {
                        FieldBinding lastField = this.otherBindings[this.otherBindings.length - 1];
                        scope.problemReporter().invalidField(this, new ProblemFieldBinding(lastField.declaringClass, lastField.name, ProblemReasons.NotFound), this.tokens.length, this.resolvedType.leafComponentType());
                        return null;
                    }
                    return this.resolvedType;
                }
                if (this.binding instanceof FieldBinding) {
                    // clear bits
                    this.bits &= ~ASTNode.RestrictiveFlagMASK;
                    this.bits |= Binding.FIELD;
                    FieldBinding fieldBinding = (FieldBinding) this.binding;
                    ReferenceBinding declaringClass = fieldBinding.original().declaringClass;
                    MethodScope methodScope = null;
                    SourceTypeBinding sourceType = null;
                    if (scope.kind != Scope.MODULE_SCOPE) {
                        methodScope = scope.methodScope();
                        sourceType = methodScope.enclosingSourceType();
                    }
                    // check for forward references
                    if (scope.kind != Scope.MODULE_SCOPE) {
                        if (// enum constants are checked even when qualified
                        (this.indexOfFirstFieldBinding == 1 || (fieldBinding.modifiers & ClassFileConstants.AccEnum) != 0 || (!fieldBinding.isFinal() && declaringClass.isEnum())) && TypeBinding.equalsEquals(sourceType, declaringClass) && methodScope.lastVisibleFieldID >= 0 && fieldBinding.id >= methodScope.lastVisibleFieldID && (!fieldBinding.isStatic() || methodScope.isStatic)) {
                            if (methodScope.insideTypeAnnotation && fieldBinding.id == methodScope.lastVisibleFieldID) {
                            // false alarm, location is NOT a field initializer but the value in a memberValuePair
                            } else {
                                scope.problemReporter().forwardReference(this, this.indexOfFirstFieldBinding - 1, fieldBinding);
                            }
                        }
                    }
                    if (isFieldUseDeprecated(fieldBinding, scope, this.indexOfFirstFieldBinding == this.tokens.length ? this.bits : 0)) {
                        scope.problemReporter().deprecatedField(fieldBinding, this);
                    }
                    if (fieldBinding.isStatic()) {
                        // check if accessing enum static field in initializer
                        if (declaringClass.isEnum() && scope.kind != Scope.MODULE_SCOPE) {
                            if (// enum constant body
                            (TypeBinding.equalsEquals(sourceType, declaringClass) || TypeBinding.equalsEquals(sourceType.superclass, declaringClass)) && fieldBinding.constant(scope) == Constant.NotAConstant && !methodScope.isStatic && methodScope.isInsideInitializerOrConstructor()) {
                                scope.problemReporter().enumStaticFieldUsedDuringInitialization(fieldBinding, this);
                            }
                        }
                        if (this.indexOfFirstFieldBinding > 1 && TypeBinding.notEquals(fieldBinding.declaringClass, this.actualReceiverType) && fieldBinding.declaringClass.canBeSeenBy(scope)) {
                            scope.problemReporter().indirectAccessToStaticField(this, fieldBinding);
                        }
                    } else {
                        boolean inStaticContext = scope.methodScope().isStatic;
                        if (this.indexOfFirstFieldBinding == 1) {
                            if (scope.compilerOptions().getSeverity(CompilerOptions.UnqualifiedFieldAccess) != ProblemSeverities.Ignore) {
                                scope.problemReporter().unqualifiedFieldAccess(this, fieldBinding);
                            }
                            if (!inStaticContext) {
                                scope.tagAsAccessingEnclosingInstanceStateOf(fieldBinding.declaringClass, false);
                            }
                        }
                        // must check for the static status....
                        if (// accessing to a field using a type as "receiver" is allowed only with static field
                        this.indexOfFirstFieldBinding > 1 || inStaticContext) {
                            // the field is the first token of the qualified reference....
                            scope.problemReporter().staticFieldAccessToNonStaticVariable(this, fieldBinding);
                            return null;
                        }
                    }
                    this.resolvedType = getOtherFieldBindings(scope);
                    if (this.resolvedType != null && (this.resolvedType.tagBits & TagBits.HasMissingType) != 0) {
                        FieldBinding lastField = this.indexOfFirstFieldBinding == this.tokens.length ? (FieldBinding) this.binding : this.otherBindings[this.otherBindings.length - 1];
                        scope.problemReporter().invalidField(this, new ProblemFieldBinding(lastField.declaringClass, lastField.name, ProblemReasons.NotFound), this.tokens.length, this.resolvedType.leafComponentType());
                        return null;
                    }
                    return this.resolvedType;
                }
                // thus it was a type
                // clear bits
                this.bits &= ~ASTNode.RestrictiveFlagMASK;
                this.bits |= Binding.TYPE;
            // $FALL-THROUGH$
            case // =============only type ==============
            Binding.TYPE:
                TypeBinding type = (TypeBinding) this.binding;
                // if (isTypeUseDeprecated(type, scope))
                // scope.problemReporter().deprecatedType(type, this);
                type = scope.environment().convertToRawType(type, false);
                return this.resolvedType = type;
        }
    }
    // ========error cases===============
    return this.resolvedType = reportError(scope);
}
Also used : SourceTypeBinding(org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding) TypeBinding(org.eclipse.jdt.internal.compiler.lookup.TypeBinding) MissingTypeBinding(org.eclipse.jdt.internal.compiler.lookup.MissingTypeBinding) FieldBinding(org.eclipse.jdt.internal.compiler.lookup.FieldBinding) ProblemFieldBinding(org.eclipse.jdt.internal.compiler.lookup.ProblemFieldBinding) ProblemFieldBinding(org.eclipse.jdt.internal.compiler.lookup.ProblemFieldBinding) ReferenceBinding(org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding) ProblemReferenceBinding(org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding) MethodScope(org.eclipse.jdt.internal.compiler.lookup.MethodScope) SourceTypeBinding(org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding) LocalVariableBinding(org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding)

Aggregations

FieldBinding (org.eclipse.jdt.internal.compiler.lookup.FieldBinding)3 MissingTypeBinding (org.eclipse.jdt.internal.compiler.lookup.MissingTypeBinding)3 ProblemFieldBinding (org.eclipse.jdt.internal.compiler.lookup.ProblemFieldBinding)3 ProblemReferenceBinding (org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding)3 ReferenceBinding (org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding)3 SourceTypeBinding (org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding)3 TypeBinding (org.eclipse.jdt.internal.compiler.lookup.TypeBinding)3 LocalVariableBinding (org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding)2 MethodScope (org.eclipse.jdt.internal.compiler.lookup.MethodScope)2 Binding (org.eclipse.jdt.internal.compiler.lookup.Binding)1 MethodBinding (org.eclipse.jdt.internal.compiler.lookup.MethodBinding)1 SyntheticMethodBinding (org.eclipse.jdt.internal.compiler.lookup.SyntheticMethodBinding)1 VariableBinding (org.eclipse.jdt.internal.compiler.lookup.VariableBinding)1