Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 118059 Details for
Bug 255452
[1.5][compiler] Eclipse allows forward reference in enum constructor
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
[patch]
Proposed patch
255452.txt (text/plain), 13.76 KB, created by
Philipe Mulet
on 2008-11-17 11:23:09 EST
(
hide
)
Description:
Proposed patch
Filename:
MIME Type:
Creator:
Philipe Mulet
Created:
2008-11-17 11:23:09 EST
Size:
13.76 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.jdt.core >Index: eval/org/eclipse/jdt/internal/eval/CodeSnippetQualifiedNameReference.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetQualifiedNameReference.java,v >retrieving revision 1.58 >diff -u -r1.58 CodeSnippetQualifiedNameReference.java >--- eval/org/eclipse/jdt/internal/eval/CodeSnippetQualifiedNameReference.java 25 Sep 2008 23:10:29 -0000 1.58 >+++ eval/org/eclipse/jdt/internal/eval/CodeSnippetQualifiedNameReference.java 17 Nov 2008 16:22:30 -0000 >@@ -10,6 +10,7 @@ > *******************************************************************************/ > package org.eclipse.jdt.internal.eval; > >+import org.eclipse.jdt.internal.compiler.ast.ASTNode; > import org.eclipse.jdt.internal.compiler.ast.Assignment; > import org.eclipse.jdt.internal.compiler.ast.CompoundAssignment; > import org.eclipse.jdt.internal.compiler.ast.Expression; >@@ -25,6 +26,7 @@ > import org.eclipse.jdt.internal.compiler.lookup.FieldBinding; > import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding; > import org.eclipse.jdt.internal.compiler.lookup.MethodBinding; >+import org.eclipse.jdt.internal.compiler.lookup.MethodScope; > import org.eclipse.jdt.internal.compiler.lookup.ProblemBinding; > import org.eclipse.jdt.internal.compiler.lookup.ProblemFieldBinding; > import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons; >@@ -47,6 +49,26 @@ > super(sources, positions, sourceStart, sourceEnd); > this.evaluationContext = evaluationContext; > } >+ >+/** >+ * Check and/or redirect the field access to the delegate receiver if any >+ */ >+public TypeBinding checkFieldAccess(BlockScope scope) { >+ FieldBinding fieldBinding = (FieldBinding) this.binding; >+ MethodScope methodScope = scope.methodScope(); >+ // check for forward references >+ if (this.indexOfFirstFieldBinding == 1 >+ && methodScope.enclosingSourceType() == fieldBinding.original().declaringClass >+ && methodScope.lastVisibleFieldID >= 0 >+ && fieldBinding.id >= methodScope.lastVisibleFieldID >+ && (!fieldBinding.isStatic() || methodScope.isStatic)) { >+ scope.problemReporter().forwardReference(this, 0, methodScope.enclosingSourceType()); >+ } >+ this.bits &= ~ASTNode.RestrictiveFlagMASK; // clear bits >+ this.bits |= Binding.FIELD; >+ return getOtherFieldBindings(scope); >+} >+ > public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) { > int pc = codeStream.position; > if ((this.bits & Binding.VARIABLE) == 0) { // nothing to do if type ref >Index: compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java,v >retrieving revision 1.136 >diff -u -r1.136 QualifiedNameReference.java >--- compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java 5 Nov 2008 00:36:27 -0000 1.136 >+++ compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java 17 Nov 2008 16:22:30 -0000 >@@ -209,25 +209,6 @@ > return flowInfo; > } > >-/** >- * Check and/or redirect the field access to the delegate receiver if any >- */ >-public TypeBinding checkFieldAccess(BlockScope scope) { >- FieldBinding fieldBinding = (FieldBinding) this.binding; >- MethodScope methodScope = scope.methodScope(); >- // check for forward references >- if (this.indexOfFirstFieldBinding == 1 >- && methodScope.enclosingSourceType() == fieldBinding.original().declaringClass >- && methodScope.lastVisibleFieldID >= 0 >- && fieldBinding.id >= methodScope.lastVisibleFieldID >- && (!fieldBinding.isStatic() || methodScope.isStatic)) { >- scope.problemReporter().forwardReference(this, 0, methodScope.enclosingSourceType()); >- } >- this.bits &= ~ASTNode.RestrictiveFlagMASK; // clear bits >- this.bits |= Binding.FIELD; >- return getOtherFieldBindings(scope); >-} >- > public void checkNPE(BlockScope scope, FlowContext flowContext, FlowInfo flowInfo, boolean checkString) { > // cannot override localVariableBinding because this would project o.m onto o when > // analysing assignments >@@ -682,27 +663,7 @@ > public TypeBinding getOtherFieldBindings(BlockScope scope) { > // At this point restrictiveFlag may ONLY have two potential value : FIELD LOCAL (i.e cast <<(VariableBinding) binding>> is valid) > int length = this.tokens.length; >- FieldBinding field; >- if ((this.bits & Binding.FIELD) != 0) { >- field = (FieldBinding) this.binding; >- if (!field.isStatic()) { >- //must check for the static status.... >- if (this.indexOfFirstFieldBinding > 1 //accessing to a field using a type as "receiver" is allowed only with static field >- || scope.methodScope().isStatic) { // the field is the first token of the qualified reference.... >- scope.problemReporter().staticFieldAccessToNonStaticVariable(this, field); >- return null; >- } >- } else if (this.indexOfFirstFieldBinding > 1 >- && field.declaringClass != this.actualReceiverType >- && field.declaringClass.canBeSeenBy(scope)) { >- scope.problemReporter().indirectAccessToStaticField(this, field); >- } >- // only last field is actually a write access if any >- if (isFieldUseDeprecated(field, scope, (this.bits & ASTNode.IsStrictlyAssigned) != 0 && this.indexOfFirstFieldBinding == length)) >- scope.problemReporter().deprecatedField(field, this); >- } else { >- field = null; >- } >+ FieldBinding field = ((this.bits & Binding.FIELD) != 0) ? (FieldBinding) this.binding : null; > TypeBinding type = ((VariableBinding) this.binding).type; > int index = this.indexOfFirstFieldBinding; > if (index == length) { // restrictiveFlag == FIELD >@@ -754,11 +715,18 @@ > } > > if (field.isStatic()) { >- // check if accessing enum static field in initializer >- ReferenceBinding declaringClass = field.declaringClass; >+ ReferenceBinding declaringClass = field.original().declaringClass; > if (declaringClass.isEnum()) { > MethodScope methodScope = scope.methodScope(); > SourceTypeBinding sourceType = methodScope.enclosingSourceType(); >+ if ((this.bits & ASTNode.IsStrictlyAssigned) == 0 >+ && sourceType == declaringClass >+ && methodScope.lastVisibleFieldID >= 0 >+ && field.id >= methodScope.lastVisibleFieldID >+ && (!field.isStatic() || methodScope.isStatic)) { >+ scope.problemReporter().forwardReference(this, index-1, methodScope.enclosingSourceType()); >+ } >+ // check if accessing enum static field in initializer > if ((sourceType == declaringClass || sourceType.superclass == declaringClass) // enum constant body > && field.constant() == Constant.NotAConstant > && !methodScope.isStatic >@@ -931,18 +899,18 @@ > case Binding.VARIABLE : //============only variable=========== > case Binding.TYPE | Binding.VARIABLE : > if (this.binding instanceof LocalVariableBinding) { >- LocalVariableBinding local = (LocalVariableBinding) this.binding; >- if (!local.isFinal() && ((this.bits & ASTNode.DepthMASK) != 0)) >- scope.problemReporter().cannotReferToNonFinalOuterLocal((LocalVariableBinding) this.binding, this); > this.bits &= ~ASTNode.RestrictiveFlagMASK; // clear bits > this.bits |= Binding.LOCAL; >+ LocalVariableBinding local = (LocalVariableBinding) this.binding; >+ if (!local.isFinal() && ((this.bits & ASTNode.DepthMASK) != 0)) { >+ 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) { >+ 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; >@@ -950,21 +918,27 @@ > return this.resolvedType; > } > if (this.binding instanceof FieldBinding) { >+ this.bits &= ~ASTNode.RestrictiveFlagMASK; // clear bits >+ this.bits |= Binding.FIELD; > FieldBinding fieldBinding = (FieldBinding) this.binding; > MethodScope methodScope = scope.methodScope(); >+ ReferenceBinding declaringClass = fieldBinding.original().declaringClass; >+ SourceTypeBinding sourceType = methodScope.enclosingSourceType(); > // check for forward references > if (this.indexOfFirstFieldBinding == 1 >- && methodScope.enclosingSourceType() == fieldBinding.original().declaringClass >+ && sourceType == declaringClass > && methodScope.lastVisibleFieldID >= 0 > && fieldBinding.id >= methodScope.lastVisibleFieldID > && (!fieldBinding.isStatic() || methodScope.isStatic)) { > scope.problemReporter().forwardReference(this, 0, methodScope.enclosingSourceType()); > } >+ if (isFieldUseDeprecated(fieldBinding, scope, (this.bits & ASTNode.IsStrictlyAssigned) != 0 && this.indexOfFirstFieldBinding == this.tokens.length)) { >+ scope.problemReporter().deprecatedField(fieldBinding, this); >+ } > if (fieldBinding.isStatic()) { >- ReferenceBinding declaringClass = fieldBinding.declaringClass; >+ // only last field is actually a write access if any > // check if accessing enum static field in initializer > if (declaringClass.isEnum()) { >- SourceTypeBinding sourceType = methodScope.enclosingSourceType(); > if ((sourceType == declaringClass || sourceType.superclass == declaringClass) // enum constant body > && fieldBinding.constant() == Constant.NotAConstant > && !methodScope.isStatic >@@ -972,18 +946,23 @@ > scope.problemReporter().enumStaticFieldUsedDuringInitialization(fieldBinding, this); > } > } >- } else if (this.indexOfFirstFieldBinding == 1 && scope.compilerOptions().getSeverity(CompilerOptions.UnqualifiedFieldAccess) != ProblemSeverities.Ignore) { >- scope.problemReporter().unqualifiedFieldAccess(this, fieldBinding); >+ if (this.indexOfFirstFieldBinding > 1 >+ && fieldBinding.declaringClass != this.actualReceiverType >+ && fieldBinding.declaringClass.canBeSeenBy(scope)) { >+ scope.problemReporter().indirectAccessToStaticField(this, fieldBinding); >+ } >+ } else { >+ if (this.indexOfFirstFieldBinding == 1 && scope.compilerOptions().getSeverity(CompilerOptions.UnqualifiedFieldAccess) != ProblemSeverities.Ignore) { >+ scope.problemReporter().unqualifiedFieldAccess(this, fieldBinding); >+ } >+ //must check for the static status.... >+ if (this.indexOfFirstFieldBinding > 1 //accessing to a field using a type as "receiver" is allowed only with static field >+ || scope.methodScope().isStatic) { // the field is the first token of the qualified reference.... >+ scope.problemReporter().staticFieldAccessToNonStaticVariable(this, fieldBinding); >+ return null; >+ } > } >- this.bits &= ~ASTNode.RestrictiveFlagMASK; // clear bits >- this.bits |= Binding.FIELD; >- >-// // check for deprecated receiver type >-// // deprecation check for receiver type if not first token >-// if (indexOfFirstFieldBinding > 1) { >-// if (isTypeUseDeprecated(this.actualReceiverType, scope)) >-// scope.problemReporter().deprecatedType(this.actualReceiverType, this); >-// } >+ > this.resolvedType = getOtherFieldBindings(scope); > if (this.resolvedType != null > && (this.resolvedType.tagBits & TagBits.HasMissingType) != 0) { >#P org.eclipse.jdt.core.tests.compiler >Index: src/org/eclipse/jdt/core/tests/compiler/regression/EnumTest.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/EnumTest.java,v >retrieving revision 1.135 >diff -u -r1.135 EnumTest.java >--- src/org/eclipse/jdt/core/tests/compiler/regression/EnumTest.java 23 Oct 2008 17:22:28 -0000 1.135 >+++ src/org/eclipse/jdt/core/tests/compiler/regression/EnumTest.java 17 Nov 2008 16:22:32 -0000 >@@ -5939,4 +5939,38 @@ > false, > false); > } >-} >+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=255452 >+public void test168() { >+ this.runNegativeTest( >+ new String[] { >+ "X.java", // ================= >+ "enum BadEnum {\n" + >+ " CRAZY(CRAZY), // <-- illegal forward reference reported by all compilers\n" + >+ " IMPOSSIBLE(BadEnum.IMPOSSIBLE); // <-- illegal forward reference (javac 1.6 only)\n" + >+ " private BadEnum(BadEnum self) {\n" + >+ " }\n" + >+ "}\n" + >+ "public class X {\n" + >+ " X x1 = new X(x1);//1 - WRONG\n" + >+ " static X X2 = new X(X.X2);//2 - OK\n" + >+ " X x3 = new X(this.x3);//3 - OK\n" + >+ " X(X x) {\n" + >+ " }\n" + >+ "}\n" + >+ "class Y extends X {\n" + >+ " X x1 = new X(x1);//4 - WRONG\n" + >+ " static X X2 = new X(Y.X2);//5 - OK\n" + >+ " X x3 = new X(this.x3);//6 - OK\n" + >+ " Y(Y y) {\n" + >+ " super(y);\n" + >+ " }\n" + >+ "}\n", // ================= >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 3)\n" + >+ " private X valueOf(String arg0) { return null; }\n" + >+ " ^^^^^^^^^^^^^^^^^^^^\n" + >+ "The enum X already defines the method valueOf(String) implicitly\n" + >+ "----------\n" >+ ); >+}}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 255452
:
118059
|
118188
|
118206