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

Collapse All | Expand All

(-)src/org/eclipse/jdt/core/tests/compiler/regression/EnumTest.java (+101 lines)
Lines 4875-4878 Link Here
4875
     },
4875
     },
4876
	"0");
4876
	"0");
4877
}
4877
}
4878
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=156591
4879
public void test138() {
4880
 this.runNegativeTest(
4881
     new String[] {
4882
    	    "X.java",
4883
 			"public enum X {\n" + 
4884
			"	PLUS {\n" + 
4885
			"		double eval(double x, double y) {\n" + 
4886
			"			return x + y;\n" + 
4887
			"		}\n" + 
4888
			"	},\n" + 
4889
			"	MINUS {\n" + 
4890
			"		@Override\n" +
4891
			"		abstract double eval(double x, double y);\n" + 
4892
			"	};\n" + 
4893
			"\n" + 
4894
			"	abstract double eval(double x, double y);\n" + 
4895
			"}\n" + 
4896
			"\n", // =================
4897
     },
4898
	"----------\n" + 
4899
	"1. WARNING in X.java (at line 3)\n" + 
4900
	"	double eval(double x, double y) {\n" + 
4901
	"	       ^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
4902
	"The method eval(double, double) of type new X(){} should be tagged with @Override since it actually overrides a superclass method\n" + 
4903
	"----------\n" + 
4904
	"2. ERROR in X.java (at line 9)\n" + 
4905
	"	abstract double eval(double x, double y);\n" + 
4906
	"	                ^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
4907
	"The abstract method eval in type new X(){} can only be defined by an abstract class\n" + 
4908
	"----------\n");
4909
}
4910
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=156591 - variation
4911
public void test139() {
4912
 this.runNegativeTest(
4913
     new String[] {
4914
    	    "X.java",
4915
 			"public enum X {\n" + 
4916
			"	PLUS {\n" + 
4917
			"		double eval(double x, double y) {\n" + 
4918
			"			return x + y;\n" + 
4919
			"		}\n" + 
4920
			"	},\n" + 
4921
			"	MINUS {\n" + 
4922
			"		abstract double eval2(double x, double y);\n" + 
4923
			"	};\n" + 
4924
			"\n" + 
4925
			"	abstract double eval(double x, double y);\n" + 
4926
			"}\n" + 
4927
			"\n", // =================
4928
     },
4929
	"----------\n" + 
4930
	"1. WARNING in X.java (at line 3)\n" + 
4931
	"	double eval(double x, double y) {\n" + 
4932
	"	       ^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
4933
	"The method eval(double, double) of type new X(){} should be tagged with @Override since it actually overrides a superclass method\n" + 
4934
	"----------\n" + 
4935
	"2. ERROR in X.java (at line 7)\n" + 
4936
	"	MINUS {\n" + 
4937
	"	      ^\n" + 
4938
	"The type new X(){} must implement the inherited abstract method X.eval(double, double)\n" + 
4939
	"----------\n" + 
4940
	"3. ERROR in X.java (at line 8)\n" + 
4941
	"	abstract double eval2(double x, double y);\n" + 
4942
	"	                ^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
4943
	"The abstract method eval2 in type new X(){} can only be defined by an abstract class\n" + 
4944
	"----------\n");
4945
}
4946
//check final modifier
4947
public void test140() {
4948
 this.runConformTest(
4949
     new String[] {
4950
    	        "X.java",
4951
    			"public enum X {\n" + 
4952
    			"	PLUS {/*ANONYMOUS*/}, MINUS;\n" + 
4953
    			"	void bar(X x) {\n" + 
4954
    			"		Runnable r = (Runnable)x;\n" + 
4955
    			"	}\n" + 
4956
    			"}", // =================
4957
     },
4958
	"");
4959
}
4960
//check final modifier
4961
public void test141() {
4962
 this.runNegativeTest(
4963
     new String[] {
4964
    	        "X.java",
4965
    			"public enum X {\n" + 
4966
    			"	PLUS, MINUS;\n" + 
4967
    			"	void bar(X x) {\n" + 
4968
    			"		Runnable r = (Runnable)x;\n" + 
4969
    			"	}\n" + 
4970
    			"}", // =================
4971
     },
4972
		"----------\n" + 
4973
		"1. ERROR in X.java (at line 4)\n" + 
4974
		"	Runnable r = (Runnable)x;\n" + 
4975
		"	             ^^^^^^^^^^^\n" + 
4976
		"Cannot cast from X to Runnable\n" + 
4977
		"----------\n");
4978
}
4878
}
4979
}
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java (-13 / +27 lines)
Lines 456-469 Link Here
456
				if ((realModifiers & UNEXPECTED_MODIFIERS) != 0)
456
				if ((realModifiers & UNEXPECTED_MODIFIERS) != 0)
457
					problemReporter().illegalModifierForEnum(sourceType);
457
					problemReporter().illegalModifierForEnum(sourceType);
458
			}
458
			}
459
459
			if (!sourceType.isAnonymousType()) {
460
			// what about inherited interface methods?
461
			if ((referenceContext.bits & ASTNode.HasAbstractMethods) != 0) {
462
				modifiers |= ClassFileConstants.AccAbstract;
463
			} else if (!sourceType.isAnonymousType()) {
464
				// body of enum constant must implement any inherited abstract methods
465
				// enum type needs to implement abstract methods if one of its constants does not supply a body
466
				checkAbstractEnum: {
460
				checkAbstractEnum: {
461
					// does define abstract methods ?
462
					if ((referenceContext.bits & ASTNode.HasAbstractMethods) != 0) {
463
						modifiers |= ClassFileConstants.AccAbstract;
464
						break checkAbstractEnum;
465
					} 					
466
					// body of enum constant must implement any inherited abstract methods
467
					// enum type needs to implement abstract methods if one of its constants does not supply a body
467
					TypeDeclaration typeDeclaration = this.referenceContext;
468
					TypeDeclaration typeDeclaration = this.referenceContext;
468
					FieldDeclaration[] fields = typeDeclaration.fields;
469
					FieldDeclaration[] fields = typeDeclaration.fields;
469
					int fieldsLength = fields == null ? 0 : fields.length;
470
					int fieldsLength = fields == null ? 0 : fields.length;
Lines 479-488 Link Here
479
					for (int i = 0; i < fieldsLength; i++) {
480
					for (int i = 0; i < fieldsLength; i++) {
480
						FieldDeclaration fieldDecl = fields[i];
481
						FieldDeclaration fieldDecl = fields[i];
481
						if (fieldDecl.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {
482
						if (fieldDecl.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {
482
							if (!(fieldDecl.initialization instanceof QualifiedAllocationExpression)) {
483
							if (fieldDecl.initialization instanceof QualifiedAllocationExpression) {
483
								break checkAbstractEnum;
484
							} else {
485
								needAbstractBit = true;
484
								needAbstractBit = true;
485
							} else {
486
								break checkAbstractEnum;
486
							}
487
							}
487
						}
488
						}
488
					}
489
					}
Lines 492-499 Link Here
492
						modifiers |= ClassFileConstants.AccAbstract;
493
						modifiers |= ClassFileConstants.AccAbstract;
493
					}
494
					}
494
				}
495
				}
496
				// final if no enum constant with anonymous body
497
				checkFinalEnum: {
498
					TypeDeclaration typeDeclaration = this.referenceContext;
499
					FieldDeclaration[] fields = typeDeclaration.fields;
500
					if (fields != null) {
501
						for (int i = 0, fieldsLength = fields.length; i < fieldsLength; i++) {
502
							FieldDeclaration fieldDecl = fields[i];
503
							if (fieldDecl.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {
504
								if (fieldDecl.initialization instanceof QualifiedAllocationExpression) {
505
									break checkFinalEnum;
506
								}
507
							}
508
						}
509
					}
510
					modifiers |= ClassFileConstants.AccFinal;
511
				}			
495
			}
512
			}
496
			modifiers |= ClassFileConstants.AccFinal;
497
		} else {
513
		} else {
498
			// detect abnormal cases for classes
514
			// detect abnormal cases for classes
499
			if (isMemberType) { // includes member types defined inside local types
515
			if (isMemberType) { // includes member types defined inside local types
Lines 591-598 Link Here
591
		
607
		
592
			// set the modifiers
608
			// set the modifiers
593
			final int IMPLICIT_MODIFIERS = ClassFileConstants.AccPublic | ClassFileConstants.AccStatic | ClassFileConstants.AccFinal | ClassFileConstants.AccEnum;
609
			final int IMPLICIT_MODIFIERS = ClassFileConstants.AccPublic | ClassFileConstants.AccStatic | ClassFileConstants.AccFinal | ClassFileConstants.AccEnum;
594
			if (fieldDecl.initialization instanceof QualifiedAllocationExpression)
595
				declaringClass.modifiers &= ~ClassFileConstants.AccFinal;
596
			fieldBinding.modifiers|= IMPLICIT_MODIFIERS;
610
			fieldBinding.modifiers|= IMPLICIT_MODIFIERS;
597
			return;
611
			return;
598
		}
612
		}

Return to bug 156591