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;
}
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;
}
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);
}
Aggregations