View | Details | Raw Unified | Return to bug 255452 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/jdt/core/tests/compiler/regression/EnumTest.java (+151 lines)
Lines 5609-5612 Link Here
5609
		},
5609
		},
5610
		"");
5610
		"");
5611
}
5611
}
5612
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=255452
5613
public void test168() {
5614
	this.runNegativeTest(
5615
		new String[] {
5616
			"X.java", // =================
5617
			"enum BadEnum {\n" + 
5618
			"    CRAZY(CRAZY), // <-- illegal forward reference reported by all compilers\n" + 
5619
			"    IMPOSSIBLE(BadEnum.IMPOSSIBLE); // <-- illegal forward reference (javac 1.6 only)\n" + 
5620
			"    private BadEnum(BadEnum self) {\n" + 
5621
			"    }\n" + 
5622
			"}\n" + 
5623
			"public class X {\n" + 
5624
			"    X x1 = new X(x1);//1 - WRONG\n" + 
5625
			"    static X X2 = new X(X.X2);//2 - OK\n" + 
5626
			"    X x3 = new X(this.x3);//3 - OK\n" + 
5627
			"    X(X x) {}\n" + 
5628
			"    X(int i) {}\n" + 
5629
			"    static int VALUE() { return 13; }\n" + 
5630
			"    int value() { return 14; }\n" + 
5631
			"}\n" + 
5632
			"class Y extends X {\n" + 
5633
			"    X x1 = new X(x1);//6 - WRONG\n" + 
5634
			"    static X X2 = new X(Y.X2);//7 - OK\n" + 
5635
			"    X x3 = new X(this.x3);//8 - OK\n" + 
5636
			"    Y(Y y) { super(y); }\n" + 
5637
			"}\n", // =================
5638
		},
5639
		"----------\n" + 
5640
		"1. ERROR in X.java (at line 2)\n" + 
5641
		"	CRAZY(CRAZY), // <-- illegal forward reference reported by all compilers\n" + 
5642
		"	      ^^^^^\n" + 
5643
		"Cannot reference a field before it is defined\n" + 
5644
		"----------\n" + 
5645
		"2. ERROR in X.java (at line 3)\n" + 
5646
		"	IMPOSSIBLE(BadEnum.IMPOSSIBLE); // <-- illegal forward reference (javac 1.6 only)\n" + 
5647
		"	                   ^^^^^^^^^^\n" + 
5648
		"Cannot reference a field before it is defined\n" + 
5649
		"----------\n" + 
5650
		"3. ERROR in X.java (at line 8)\n" + 
5651
		"	X x1 = new X(x1);//1 - WRONG\n" + 
5652
		"	             ^^\n" + 
5653
		"Cannot reference a field before it is defined\n" + 
5654
		"----------\n" + 
5655
		"4. WARNING in X.java (at line 17)\n" + 
5656
		"	X x1 = new X(x1);//6 - WRONG\n" + 
5657
		"	  ^^\n" + 
5658
		"The field Y.x1 is hiding a field from type X\n" + 
5659
		"----------\n" + 
5660
		"5. ERROR in X.java (at line 17)\n" + 
5661
		"	X x1 = new X(x1);//6 - WRONG\n" + 
5662
		"	             ^^\n" + 
5663
		"Cannot reference a field before it is defined\n" + 
5664
		"----------\n" + 
5665
		"6. WARNING in X.java (at line 18)\n" + 
5666
		"	static X X2 = new X(Y.X2);//7 - OK\n" + 
5667
		"	         ^^\n" + 
5668
		"The field Y.X2 is hiding a field from type X\n" + 
5669
		"----------\n" + 
5670
		"7. WARNING in X.java (at line 19)\n" + 
5671
		"	X x3 = new X(this.x3);//8 - OK\n" + 
5672
		"	  ^^\n" + 
5673
		"The field Y.x3 is hiding a field from type X\n" + 
5674
		"----------\n");
5675
}
5676
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=255452 - variation
5677
public void test169() {
5678
	this.runNegativeTest(
5679
		new String[] {
5680
			"X.java", // =================
5681
			"enum BadEnum {\n" + 
5682
			"    NOWAY(BadEnum.NOWAY.CONST),\n" + 
5683
			"    INVALID(INVALID.CONST),\n" + 
5684
			"    WRONG(WRONG.VALUE()),\n" + 
5685
			"    ILLEGAL(ILLEGAL.value());\n" + 
5686
			"    final static int CONST = 12;\n" + 
5687
			"    private BadEnum(int i) {\n" + 
5688
			"    }\n" + 
5689
			"    static int VALUE() { return 13; }\n" + 
5690
			"    int value() { return 14; }\n" + 
5691
			"}\n" + 
5692
			"public class X {\n" + 
5693
			"    final static int CONST = 12;\n" + 
5694
			"    X x4 = new X(x4.CONST);//4 - WRONG\n" + 
5695
			"    X x5 = new X(x5.value());//5 - WRONG\n" + 
5696
			"    X(int i) {}\n" + 
5697
			"    static int VALUE() { return 13; }\n" + 
5698
			"    int value() { return 14; }\n" + 
5699
			"}\n", // =================
5700
		},
5701
		"----------\n" + 
5702
		"1. ERROR in X.java (at line 2)\n" + 
5703
		"	NOWAY(BadEnum.NOWAY.CONST),\n" + 
5704
		"	              ^^^^^\n" + 
5705
		"Cannot reference a field before it is defined\n" + 
5706
		"----------\n" + 
5707
		"2. ERROR in X.java (at line 2)\n" + 
5708
		"	NOWAY(BadEnum.NOWAY.CONST),\n" + 
5709
		"	                    ^^^^^\n" + 
5710
		"Cannot reference a field before it is defined\n" + 
5711
		"----------\n" + 
5712
		"3. WARNING in X.java (at line 2)\n" + 
5713
		"	NOWAY(BadEnum.NOWAY.CONST),\n" + 
5714
		"	                    ^^^^^\n" + 
5715
		"The static field BadEnum.CONST should be accessed in a static way\n" + 
5716
		"----------\n" + 
5717
		"4. ERROR in X.java (at line 3)\n" + 
5718
		"	INVALID(INVALID.CONST),\n" + 
5719
		"	        ^^^^^^^\n" + 
5720
		"Cannot reference a field before it is defined\n" + 
5721
		"----------\n" + 
5722
		"5. ERROR in X.java (at line 3)\n" + 
5723
		"	INVALID(INVALID.CONST),\n" + 
5724
		"	                ^^^^^\n" + 
5725
		"Cannot reference a field before it is defined\n" + 
5726
		"----------\n" + 
5727
		"6. WARNING in X.java (at line 3)\n" + 
5728
		"	INVALID(INVALID.CONST),\n" + 
5729
		"	                ^^^^^\n" + 
5730
		"The static field BadEnum.CONST should be accessed in a static way\n" + 
5731
		"----------\n" + 
5732
		"7. ERROR in X.java (at line 4)\n" + 
5733
		"	WRONG(WRONG.VALUE()),\n" + 
5734
		"	      ^^^^^\n" + 
5735
		"Cannot reference a field before it is defined\n" + 
5736
		"----------\n" + 
5737
		"8. WARNING in X.java (at line 4)\n" + 
5738
		"	WRONG(WRONG.VALUE()),\n" + 
5739
		"	      ^^^^^^^^^^^^^\n" + 
5740
		"The static method VALUE() from the type BadEnum should be accessed in a static way\n" + 
5741
		"----------\n" + 
5742
		"9. ERROR in X.java (at line 5)\n" + 
5743
		"	ILLEGAL(ILLEGAL.value());\n" + 
5744
		"	        ^^^^^^^\n" + 
5745
		"Cannot reference a field before it is defined\n" + 
5746
		"----------\n" + 
5747
		"10. ERROR in X.java (at line 14)\n" + 
5748
		"	X x4 = new X(x4.CONST);//4 - WRONG\n" + 
5749
		"	             ^^\n" + 
5750
		"Cannot reference a field before it is defined\n" + 
5751
		"----------\n" + 
5752
		"11. WARNING in X.java (at line 14)\n" + 
5753
		"	X x4 = new X(x4.CONST);//4 - WRONG\n" + 
5754
		"	                ^^^^^\n" + 
5755
		"The static field X.CONST should be accessed in a static way\n" + 
5756
		"----------\n" + 
5757
		"12. ERROR in X.java (at line 15)\n" + 
5758
		"	X x5 = new X(x5.value());//5 - WRONG\n" + 
5759
		"	             ^^\n" + 
5760
		"Cannot reference a field before it is defined\n" + 
5761
		"----------\n");
5762
}
5612
}
5763
}
(-)src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java (-1 / +1 lines)
Lines 36286-36292 Link Here
36286
		"----------\n" + 
36286
		"----------\n" + 
36287
		"6. ERROR in Y.java (at line 9)\n" + 
36287
		"6. ERROR in Y.java (at line 9)\n" + 
36288
		"	E e2 = e2.e;\n" + 
36288
		"	E e2 = e2.e;\n" + 
36289
		"	       ^^^^\n" + 
36289
		"	       ^^\n" + 
36290
		"Cannot reference a field before it is defined\n" + 
36290
		"Cannot reference a field before it is defined\n" + 
36291
		"----------\n" + 
36291
		"----------\n" + 
36292
		"7. ERROR in Y.java (at line 9)\n" + 
36292
		"7. ERROR in Y.java (at line 9)\n" + 
(-)buildnotes_jdt-core.html (-1 / +3 lines)
Lines 48-54 Link Here
48
<h2>What's new in this drop</h2>
48
<h2>What's new in this drop</h2>
49
49
50
<h3>Problem Reports Fixed</h3>
50
<h3>Problem Reports Fixed</h3>
51
<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=250297">250297</a>
51
<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=255452">255452</a>
52
[1.5][compiler] Eclipse allows forward reference in enum constructor
53
<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=250297">250297</a>
52
[compiler] NPE in org.eclipse.jdt.internal.compiler.problem.ProblemReporter.missingTypeInMethod(ProblemReporter.java:4925)
54
[compiler] NPE in org.eclipse.jdt.internal.compiler.problem.ProblemReporter.missingTypeInMethod(ProblemReporter.java:4925)
53
55
54
<a name="v_889_R34x"></a>
56
<a name="v_889_R34x"></a>
(-)compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java (-1 / +1 lines)
Lines 208-214 Link Here
208
			&& methodScope.lastVisibleFieldID >= 0
208
			&& methodScope.lastVisibleFieldID >= 0
209
			&& fieldBinding.id >= methodScope.lastVisibleFieldID
209
			&& fieldBinding.id >= methodScope.lastVisibleFieldID
210
			&& (!fieldBinding.isStatic() || methodScope.isStatic)) {
210
			&& (!fieldBinding.isStatic() || methodScope.isStatic)) {
211
		scope.problemReporter().forwardReference(this, 0, methodScope.enclosingSourceType());
211
		scope.problemReporter().forwardReference(this, 0, fieldBinding);
212
		this.bits |= ASTNode.IgnoreNoEffectAssignCheck;
212
		this.bits |= ASTNode.IgnoreNoEffectAssignCheck;
213
	}
213
	}
214
	return fieldBinding.type;
214
	return fieldBinding.type;
(-)compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java (-10 / +18 lines)
Lines 265-277 Link Here
265
public TypeBinding checkFieldAccess(BlockScope scope) {
265
public TypeBinding checkFieldAccess(BlockScope scope) {
266
	FieldBinding fieldBinding = (FieldBinding) this.binding;
266
	FieldBinding fieldBinding = (FieldBinding) this.binding;
267
	MethodScope methodScope = scope.methodScope();
267
	MethodScope methodScope = scope.methodScope();
268
	TypeBinding declaringClass = fieldBinding.original().declaringClass;
268
	// check for forward references
269
	// check for forward references
269
	if (this.indexOfFirstFieldBinding == 1
270
	if ((this.indexOfFirstFieldBinding == 1 || declaringClass.isEnum())
270
			&& methodScope.enclosingSourceType() == fieldBinding.original().declaringClass
271
			&& methodScope.enclosingSourceType() == declaringClass
271
			&& methodScope.lastVisibleFieldID >= 0
272
			&& methodScope.lastVisibleFieldID >= 0
272
			&& fieldBinding.id >= methodScope.lastVisibleFieldID
273
			&& fieldBinding.id >= methodScope.lastVisibleFieldID
273
			&& (!fieldBinding.isStatic() || methodScope.isStatic)) {
274
			&& (!fieldBinding.isStatic() || methodScope.isStatic)) {
274
		scope.problemReporter().forwardReference(this, 0, methodScope.enclosingSourceType());
275
		scope.problemReporter().forwardReference(this, 0, fieldBinding);
275
	}
276
	}
276
	this.bits &= ~ASTNode.RestrictiveFlagMASK; // clear bits
277
	this.bits &= ~ASTNode.RestrictiveFlagMASK; // clear bits
277
	this.bits |= Binding.FIELD;
278
	this.bits |= Binding.FIELD;
Lines 779-796 Link Here
779
			}
780
			}
780
781
781
			if (field.isStatic()) {
782
			if (field.isStatic()) {
782
				// check if accessing enum static field in initializer
783
				ReferenceBinding declaringClass = field.original().declaringClass;
783
				ReferenceBinding declaringClass = field.declaringClass;
784
				if (declaringClass.isEnum()) {
784
				if (declaringClass.isEnum()) {
785
					MethodScope methodScope = scope.methodScope();
785
					MethodScope methodScope = scope.methodScope();
786
					SourceTypeBinding sourceType = methodScope.enclosingSourceType();
786
					SourceTypeBinding sourceType = methodScope.enclosingSourceType();
787
					if ((this.bits & ASTNode.IsStrictlyAssigned) == 0
788
							&& sourceType == declaringClass
789
							&& methodScope.lastVisibleFieldID >= 0
790
							&& field.id >= methodScope.lastVisibleFieldID
791
							&& (!field.isStatic() || methodScope.isStatic)) {
792
						scope.problemReporter().forwardReference(this, index, field);
793
					}					
794
					// check if accessing enum static field in initializer
787
					if ((sourceType == declaringClass || sourceType.superclass == declaringClass) // enum constant body
795
					if ((sourceType == declaringClass || sourceType.superclass == declaringClass) // enum constant body
788
							&& field.constant() == Constant.NotAConstant
796
							&& field.constant() == Constant.NotAConstant
789
							&& !methodScope.isStatic
797
							&& !methodScope.isStatic
790
							&& methodScope.isInsideInitializerOrConstructor()) {
798
							&& methodScope.isInsideInitializerOrConstructor()) {
791
						scope.problemReporter().enumStaticFieldUsedDuringInitialization(field, this);
799
						scope.problemReporter().enumStaticFieldUsedDuringInitialization(field, this);
792
					}
800
					}
793
				}					
801
				}
794
				// static field accessed through receiver? legal but unoptimal (optional warning)
802
				// static field accessed through receiver? legal but unoptimal (optional warning)
795
				scope.problemReporter().nonStaticAccessToStaticField(this, field, index);
803
				scope.problemReporter().nonStaticAccessToStaticField(this, field, index);
796
				// indirect static reference ?
804
				// indirect static reference ?
Lines 1004-1019 Link Here
1004
				if (this.binding instanceof FieldBinding) {
1012
				if (this.binding instanceof FieldBinding) {
1005
					FieldBinding fieldBinding = (FieldBinding) this.binding;
1013
					FieldBinding fieldBinding = (FieldBinding) this.binding;
1006
					MethodScope methodScope = scope.methodScope();
1014
					MethodScope methodScope = scope.methodScope();
1015
					TypeBinding declaringClass = fieldBinding.original().declaringClass;
1007
					// check for forward references
1016
					// check for forward references
1008
					if (this.indexOfFirstFieldBinding == 1
1017
					if ((this.indexOfFirstFieldBinding == 1 || declaringClass.isEnum())
1009
							&& methodScope.enclosingSourceType() == fieldBinding.original().declaringClass
1018
							&& methodScope.enclosingSourceType() == declaringClass
1010
							&& methodScope.lastVisibleFieldID >= 0
1019
							&& methodScope.lastVisibleFieldID >= 0
1011
							&& fieldBinding.id >= methodScope.lastVisibleFieldID
1020
							&& fieldBinding.id >= methodScope.lastVisibleFieldID
1012
							&& (!fieldBinding.isStatic() || methodScope.isStatic)) {
1021
							&& (!fieldBinding.isStatic() || methodScope.isStatic)) {
1013
						scope.problemReporter().forwardReference(this, 0, methodScope.enclosingSourceType());
1022
						scope.problemReporter().forwardReference(this, 0, fieldBinding);
1014
					}
1023
					}
1015
					if (fieldBinding.isStatic()) {
1024
					if (fieldBinding.isStatic()) {
1016
						ReferenceBinding declaringClass = fieldBinding.declaringClass;
1017
						// check if accessing enum static field in initializer					
1025
						// check if accessing enum static field in initializer					
1018
						if (declaringClass.isEnum()) {
1026
						if (declaringClass.isEnum()) {
1019
							SourceTypeBinding sourceType = methodScope.enclosingSourceType();
1027
							SourceTypeBinding sourceType = methodScope.enclosingSourceType();
(-)compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java (-3 / +3 lines)
Lines 1769-1781 Link Here
1769
		location.sourceStart,
1769
		location.sourceStart,
1770
		location.sourceEnd);
1770
		location.sourceEnd);
1771
}
1771
}
1772
public void forwardReference(Reference reference, int indexInQualification, TypeBinding type) {
1772
public void forwardReference(Reference reference, int indexInQualification, FieldBinding field) {
1773
	this.handle(
1773
	this.handle(
1774
		IProblem.ReferenceToForwardField,
1774
		IProblem.ReferenceToForwardField,
1775
		NoArgument,
1775
		NoArgument,
1776
		NoArgument,
1776
		NoArgument,
1777
		reference.sourceStart,
1777
		nodeSourceStart(field, reference, indexInQualification),
1778
		reference.sourceEnd);
1778
		nodeSourceEnd(field, reference, indexInQualification));
1779
}
1779
}
1780
public void forwardTypeVariableReference(ASTNode location, TypeVariableBinding type) {
1780
public void forwardTypeVariableReference(ASTNode location, TypeVariableBinding type) {
1781
	this.handle(
1781
	this.handle(
(-)Eclipse Java Tests Compiler/org/eclipse/jdt/tests/compiler/regression/InitializationTest.java (-3 / +3 lines)
Lines 1560-1571 Link Here
1560
		"----------\n" + 
1560
		"----------\n" + 
1561
		"1. ERROR in X.java (at line 5)\n" + 
1561
		"1. ERROR in X.java (at line 5)\n" + 
1562
		"	X z = z.i; \n" + 
1562
		"	X z = z.i; \n" + 
1563
		"	      ^^^\n" + 
1563
		"	      ^\n" + 
1564
		"Cannot reference a field before it is defined\n" + 
1564
		"Cannot reference a field before it is defined\n" + 
1565
		"----------\n" + 
1565
		"----------\n" + 
1566
		"2. ERROR in X.java (at line 6)\n" + 
1566
		"2. ERROR in X.java (at line 6)\n" + 
1567
		"	X x = new X(x.i); // should notice illegal forward reference.\n" + 
1567
		"	X x = new X(x.i); // should notice illegal forward reference.\n" + 
1568
		"	            ^^^\n" + 
1568
		"	            ^\n" + 
1569
		"Cannot reference a field before it is defined\n" + 
1569
		"Cannot reference a field before it is defined\n" + 
1570
		"----------\n"
1570
		"----------\n"
1571
	);									
1571
	);									
Lines 1589-1595 Link Here
1589
		"----------\n" + 
1589
		"----------\n" + 
1590
		"1. ERROR in B.java (at line 2)\n" + 
1590
		"1. ERROR in B.java (at line 2)\n" + 
1591
		"	static B b = a.b; \n" + 
1591
		"	static B b = a.b; \n" + 
1592
		"	             ^^^\n" + 
1592
		"	             ^\n" + 
1593
		"Cannot reference a field before it is defined\n" + 
1593
		"Cannot reference a field before it is defined\n" + 
1594
		"----------\n" + 
1594
		"----------\n" + 
1595
		"2. WARNING in B.java (at line 2)\n" + 
1595
		"2. WARNING in B.java (at line 2)\n" + 

Return to bug 255452