Lines 209-233
Link Here
|
209 |
return flowInfo; |
209 |
return flowInfo; |
210 |
} |
210 |
} |
211 |
|
211 |
|
212 |
/** |
|
|
213 |
* Check and/or redirect the field access to the delegate receiver if any |
214 |
*/ |
215 |
public TypeBinding checkFieldAccess(BlockScope scope) { |
216 |
FieldBinding fieldBinding = (FieldBinding) this.binding; |
217 |
MethodScope methodScope = scope.methodScope(); |
218 |
// check for forward references |
219 |
if (this.indexOfFirstFieldBinding == 1 |
220 |
&& methodScope.enclosingSourceType() == fieldBinding.original().declaringClass |
221 |
&& methodScope.lastVisibleFieldID >= 0 |
222 |
&& fieldBinding.id >= methodScope.lastVisibleFieldID |
223 |
&& (!fieldBinding.isStatic() || methodScope.isStatic)) { |
224 |
scope.problemReporter().forwardReference(this, 0, methodScope.enclosingSourceType()); |
225 |
} |
226 |
this.bits &= ~ASTNode.RestrictiveFlagMASK; // clear bits |
227 |
this.bits |= Binding.FIELD; |
228 |
return getOtherFieldBindings(scope); |
229 |
} |
230 |
|
231 |
public void checkNPE(BlockScope scope, FlowContext flowContext, FlowInfo flowInfo, boolean checkString) { |
212 |
public void checkNPE(BlockScope scope, FlowContext flowContext, FlowInfo flowInfo, boolean checkString) { |
232 |
// cannot override localVariableBinding because this would project o.m onto o when |
213 |
// cannot override localVariableBinding because this would project o.m onto o when |
233 |
// analysing assignments |
214 |
// analysing assignments |
Lines 682-708
Link Here
|
682 |
public TypeBinding getOtherFieldBindings(BlockScope scope) { |
663 |
public TypeBinding getOtherFieldBindings(BlockScope scope) { |
683 |
// At this point restrictiveFlag may ONLY have two potential value : FIELD LOCAL (i.e cast <<(VariableBinding) binding>> is valid) |
664 |
// At this point restrictiveFlag may ONLY have two potential value : FIELD LOCAL (i.e cast <<(VariableBinding) binding>> is valid) |
684 |
int length = this.tokens.length; |
665 |
int length = this.tokens.length; |
685 |
FieldBinding field; |
666 |
FieldBinding field = ((this.bits & Binding.FIELD) != 0) ? (FieldBinding) this.binding : null; |
686 |
if ((this.bits & Binding.FIELD) != 0) { |
|
|
687 |
field = (FieldBinding) this.binding; |
688 |
if (!field.isStatic()) { |
689 |
//must check for the static status.... |
690 |
if (this.indexOfFirstFieldBinding > 1 //accessing to a field using a type as "receiver" is allowed only with static field |
691 |
|| scope.methodScope().isStatic) { // the field is the first token of the qualified reference.... |
692 |
scope.problemReporter().staticFieldAccessToNonStaticVariable(this, field); |
693 |
return null; |
694 |
} |
695 |
} else if (this.indexOfFirstFieldBinding > 1 |
696 |
&& field.declaringClass != this.actualReceiverType |
697 |
&& field.declaringClass.canBeSeenBy(scope)) { |
698 |
scope.problemReporter().indirectAccessToStaticField(this, field); |
699 |
} |
700 |
// only last field is actually a write access if any |
701 |
if (isFieldUseDeprecated(field, scope, (this.bits & ASTNode.IsStrictlyAssigned) != 0 && this.indexOfFirstFieldBinding == length)) |
702 |
scope.problemReporter().deprecatedField(field, this); |
703 |
} else { |
704 |
field = null; |
705 |
} |
706 |
TypeBinding type = ((VariableBinding) this.binding).type; |
667 |
TypeBinding type = ((VariableBinding) this.binding).type; |
707 |
int index = this.indexOfFirstFieldBinding; |
668 |
int index = this.indexOfFirstFieldBinding; |
708 |
if (index == length) { // restrictiveFlag == FIELD |
669 |
if (index == length) { // restrictiveFlag == FIELD |
Lines 754-764
Link Here
|
754 |
} |
715 |
} |
755 |
|
716 |
|
756 |
if (field.isStatic()) { |
717 |
if (field.isStatic()) { |
757 |
// check if accessing enum static field in initializer |
718 |
ReferenceBinding declaringClass = field.original().declaringClass; |
758 |
ReferenceBinding declaringClass = field.declaringClass; |
|
|
759 |
if (declaringClass.isEnum()) { |
719 |
if (declaringClass.isEnum()) { |
760 |
MethodScope methodScope = scope.methodScope(); |
720 |
MethodScope methodScope = scope.methodScope(); |
761 |
SourceTypeBinding sourceType = methodScope.enclosingSourceType(); |
721 |
SourceTypeBinding sourceType = methodScope.enclosingSourceType(); |
|
|
722 |
if ((this.bits & ASTNode.IsStrictlyAssigned) == 0 |
723 |
&& sourceType == declaringClass |
724 |
&& methodScope.lastVisibleFieldID >= 0 |
725 |
&& field.id >= methodScope.lastVisibleFieldID |
726 |
&& (!field.isStatic() || methodScope.isStatic)) { |
727 |
scope.problemReporter().forwardReference(this, index-1, methodScope.enclosingSourceType()); |
728 |
} |
729 |
// check if accessing enum static field in initializer |
762 |
if ((sourceType == declaringClass || sourceType.superclass == declaringClass) // enum constant body |
730 |
if ((sourceType == declaringClass || sourceType.superclass == declaringClass) // enum constant body |
763 |
&& field.constant() == Constant.NotAConstant |
731 |
&& field.constant() == Constant.NotAConstant |
764 |
&& !methodScope.isStatic |
732 |
&& !methodScope.isStatic |
Lines 931-948
Link Here
|
931 |
case Binding.VARIABLE : //============only variable=========== |
899 |
case Binding.VARIABLE : //============only variable=========== |
932 |
case Binding.TYPE | Binding.VARIABLE : |
900 |
case Binding.TYPE | Binding.VARIABLE : |
933 |
if (this.binding instanceof LocalVariableBinding) { |
901 |
if (this.binding instanceof LocalVariableBinding) { |
934 |
LocalVariableBinding local = (LocalVariableBinding) this.binding; |
|
|
935 |
if (!local.isFinal() && ((this.bits & ASTNode.DepthMASK) != 0)) |
936 |
scope.problemReporter().cannotReferToNonFinalOuterLocal((LocalVariableBinding) this.binding, this); |
937 |
this.bits &= ~ASTNode.RestrictiveFlagMASK; // clear bits |
902 |
this.bits &= ~ASTNode.RestrictiveFlagMASK; // clear bits |
938 |
this.bits |= Binding.LOCAL; |
903 |
this.bits |= Binding.LOCAL; |
|
|
904 |
LocalVariableBinding local = (LocalVariableBinding) this.binding; |
905 |
if (!local.isFinal() && ((this.bits & ASTNode.DepthMASK) != 0)) { |
906 |
scope.problemReporter().cannotReferToNonFinalOuterLocal((LocalVariableBinding) this.binding, this); |
907 |
} |
939 |
if (local.type != null && (local.type.tagBits & TagBits.HasMissingType) != 0) { |
908 |
if (local.type != null && (local.type.tagBits & TagBits.HasMissingType) != 0) { |
940 |
// only complain if field reference (for local, its type got flagged already) |
909 |
// only complain if field reference (for local, its type got flagged already) |
941 |
return null; |
910 |
return null; |
942 |
} |
911 |
} |
943 |
this.resolvedType = getOtherFieldBindings(scope); |
912 |
this.resolvedType = getOtherFieldBindings(scope); |
944 |
if (this.resolvedType != null |
913 |
if (this.resolvedType != null && (this.resolvedType.tagBits & TagBits.HasMissingType) != 0) { |
945 |
&& (this.resolvedType.tagBits & TagBits.HasMissingType) != 0) { |
|
|
946 |
FieldBinding lastField = this.otherBindings[this.otherBindings.length - 1]; |
914 |
FieldBinding lastField = this.otherBindings[this.otherBindings.length - 1]; |
947 |
scope.problemReporter().invalidField(this, new ProblemFieldBinding(lastField.declaringClass, lastField.name, ProblemReasons.NotFound), this.tokens.length, this.resolvedType.leafComponentType()); |
915 |
scope.problemReporter().invalidField(this, new ProblemFieldBinding(lastField.declaringClass, lastField.name, ProblemReasons.NotFound), this.tokens.length, this.resolvedType.leafComponentType()); |
948 |
return null; |
916 |
return null; |
Lines 950-970
Link Here
|
950 |
return this.resolvedType; |
918 |
return this.resolvedType; |
951 |
} |
919 |
} |
952 |
if (this.binding instanceof FieldBinding) { |
920 |
if (this.binding instanceof FieldBinding) { |
|
|
921 |
this.bits &= ~ASTNode.RestrictiveFlagMASK; // clear bits |
922 |
this.bits |= Binding.FIELD; |
953 |
FieldBinding fieldBinding = (FieldBinding) this.binding; |
923 |
FieldBinding fieldBinding = (FieldBinding) this.binding; |
954 |
MethodScope methodScope = scope.methodScope(); |
924 |
MethodScope methodScope = scope.methodScope(); |
|
|
925 |
ReferenceBinding declaringClass = fieldBinding.original().declaringClass; |
926 |
SourceTypeBinding sourceType = methodScope.enclosingSourceType(); |
955 |
// check for forward references |
927 |
// check for forward references |
956 |
if (this.indexOfFirstFieldBinding == 1 |
928 |
if (this.indexOfFirstFieldBinding == 1 |
957 |
&& methodScope.enclosingSourceType() == fieldBinding.original().declaringClass |
929 |
&& sourceType == declaringClass |
958 |
&& methodScope.lastVisibleFieldID >= 0 |
930 |
&& methodScope.lastVisibleFieldID >= 0 |
959 |
&& fieldBinding.id >= methodScope.lastVisibleFieldID |
931 |
&& fieldBinding.id >= methodScope.lastVisibleFieldID |
960 |
&& (!fieldBinding.isStatic() || methodScope.isStatic)) { |
932 |
&& (!fieldBinding.isStatic() || methodScope.isStatic)) { |
961 |
scope.problemReporter().forwardReference(this, 0, methodScope.enclosingSourceType()); |
933 |
scope.problemReporter().forwardReference(this, 0, methodScope.enclosingSourceType()); |
962 |
} |
934 |
} |
|
|
935 |
if (isFieldUseDeprecated(fieldBinding, scope, (this.bits & ASTNode.IsStrictlyAssigned) != 0 && this.indexOfFirstFieldBinding == this.tokens.length)) { |
936 |
scope.problemReporter().deprecatedField(fieldBinding, this); |
937 |
} |
963 |
if (fieldBinding.isStatic()) { |
938 |
if (fieldBinding.isStatic()) { |
964 |
ReferenceBinding declaringClass = fieldBinding.declaringClass; |
939 |
// only last field is actually a write access if any |
965 |
// check if accessing enum static field in initializer |
940 |
// check if accessing enum static field in initializer |
966 |
if (declaringClass.isEnum()) { |
941 |
if (declaringClass.isEnum()) { |
967 |
SourceTypeBinding sourceType = methodScope.enclosingSourceType(); |
|
|
968 |
if ((sourceType == declaringClass || sourceType.superclass == declaringClass) // enum constant body |
942 |
if ((sourceType == declaringClass || sourceType.superclass == declaringClass) // enum constant body |
969 |
&& fieldBinding.constant() == Constant.NotAConstant |
943 |
&& fieldBinding.constant() == Constant.NotAConstant |
970 |
&& !methodScope.isStatic |
944 |
&& !methodScope.isStatic |
Lines 972-989
Link Here
|
972 |
scope.problemReporter().enumStaticFieldUsedDuringInitialization(fieldBinding, this); |
946 |
scope.problemReporter().enumStaticFieldUsedDuringInitialization(fieldBinding, this); |
973 |
} |
947 |
} |
974 |
} |
948 |
} |
975 |
} else if (this.indexOfFirstFieldBinding == 1 && scope.compilerOptions().getSeverity(CompilerOptions.UnqualifiedFieldAccess) != ProblemSeverities.Ignore) { |
949 |
if (this.indexOfFirstFieldBinding > 1 |
976 |
scope.problemReporter().unqualifiedFieldAccess(this, fieldBinding); |
950 |
&& fieldBinding.declaringClass != this.actualReceiverType |
|
|
951 |
&& fieldBinding.declaringClass.canBeSeenBy(scope)) { |
952 |
scope.problemReporter().indirectAccessToStaticField(this, fieldBinding); |
953 |
} |
954 |
} else { |
955 |
if (this.indexOfFirstFieldBinding == 1 && scope.compilerOptions().getSeverity(CompilerOptions.UnqualifiedFieldAccess) != ProblemSeverities.Ignore) { |
956 |
scope.problemReporter().unqualifiedFieldAccess(this, fieldBinding); |
957 |
} |
958 |
//must check for the static status.... |
959 |
if (this.indexOfFirstFieldBinding > 1 //accessing to a field using a type as "receiver" is allowed only with static field |
960 |
|| scope.methodScope().isStatic) { // the field is the first token of the qualified reference.... |
961 |
scope.problemReporter().staticFieldAccessToNonStaticVariable(this, fieldBinding); |
962 |
return null; |
963 |
} |
977 |
} |
964 |
} |
978 |
this.bits &= ~ASTNode.RestrictiveFlagMASK; // clear bits |
965 |
|
979 |
this.bits |= Binding.FIELD; |
|
|
980 |
|
981 |
// // check for deprecated receiver type |
982 |
// // deprecation check for receiver type if not first token |
983 |
// if (indexOfFirstFieldBinding > 1) { |
984 |
// if (isTypeUseDeprecated(this.actualReceiverType, scope)) |
985 |
// scope.problemReporter().deprecatedType(this.actualReceiverType, this); |
986 |
// } |
987 |
this.resolvedType = getOtherFieldBindings(scope); |
966 |
this.resolvedType = getOtherFieldBindings(scope); |
988 |
if (this.resolvedType != null |
967 |
if (this.resolvedType != null |
989 |
&& (this.resolvedType.tagBits & TagBits.HasMissingType) != 0) { |
968 |
&& (this.resolvedType.tagBits & TagBits.HasMissingType) != 0) { |