View | Details | Raw Unified | Return to bug 200016
Collapse All | Expand All

(-)src/org/eclipse/jdt/core/tests/compiler/regression/EnumTest.java (-47 / +48 lines)
Lines 1499-1510 Link Here
1499
			"	public abstract void foo();\n" + 
1499
			"	public abstract void foo();\n" + 
1500
			"}\n"
1500
			"}\n"
1501
		},
1501
		},
1502
	"----------\n" + 
1502
		"----------\n" + 
1503
	"1. ERROR in X.java (at line 5)\n" + 
1503
		"1. ERROR in X.java (at line 2)\n" + 
1504
	"	public abstract void foo();\n" + 
1504
		"	A\n" + 
1505
	"	                     ^^^^^\n" + 
1505
		"	^\n" + 
1506
	"The enum X can only define the abstract method foo() if it also defines enum constants with corresponding implementations\n" + 
1506
		"The enum constant A must define the abstract method foo()\n" + 
1507
	"----------\n"
1507
		"----------\n"
1508
	);
1508
	);
1509
}		
1509
}		
1510
1510
Lines 1540-1551 Link Here
1540
			"	public abstract void foo();\n" + 
1540
			"	public abstract void foo();\n" + 
1541
			"}\n"
1541
			"}\n"
1542
		},
1542
		},
1543
	"----------\n" + 
1543
		"----------\n" + 
1544
	"1. ERROR in X.java (at line 2)\n" + 
1544
		"1. ERROR in X.java (at line 2)\n" + 
1545
	"	A() {}\n" + 
1545
		"	A() {}\n" + 
1546
	"	    ^\n" + 
1546
		"	^\n" + 
1547
	"The type new X(){} must implement the inherited abstract method X.foo()\n" + 
1547
		"The enum constant A must define the abstract method foo()\n" + 
1548
	"----------\n"
1548
		"----------\n"
1549
	);
1549
	);
1550
}			
1550
}			
1551
1551
Lines 2165-2174 Link Here
2165
			"interface I { void test(); }\n"
2165
			"interface I { void test(); }\n"
2166
		},
2166
		},
2167
		"----------\n" + 
2167
		"----------\n" + 
2168
		"1. ERROR in X3a.java (at line 3)\n" + 
2168
		"1. ERROR in X3a.java (at line 2)\n" + 
2169
		"	public abstract void test();\n" + 
2169
		"	A;\n" + 
2170
		"	                     ^^^^^^\n" + 
2170
		"	^\n" + 
2171
		"The enum X3a can only define the abstract method test() if it also defines enum constants with corresponding implementations\n" + 
2171
		"The enum constant A must define the abstract method test()\n" + 
2172
		"----------\n"
2172
		"----------\n"
2173
		// X3a is not abstract and does not override abstract method test() in X3a
2173
		// X3a is not abstract and does not override abstract method test() in X3a
2174
	);
2174
	);
Lines 2195-2202 Link Here
2195
		"----------\n" + 
2195
		"----------\n" + 
2196
		"1. ERROR in X3c.java (at line 2)\n" + 
2196
		"1. ERROR in X3c.java (at line 2)\n" + 
2197
		"	A() { void random() {} };\n" + 
2197
		"	A() { void random() {} };\n" + 
2198
		"	    ^\n" + 
2198
		"	^\n" + 
2199
		"The type new X3c(){} must implement the inherited abstract method X3c.test()\n" + 
2199
		"The enum constant A must define the abstract method test()\n" + 
2200
		"----------\n"
2200
		"----------\n"
2201
		// <anonymous X3c$1> is not abstract and does not override abstract method test() in X3c
2201
		// <anonymous X3c$1> is not abstract and does not override abstract method test() in X3c
2202
	);
2202
	);
Lines 2229-2238 Link Here
2229
			"}\n"
2229
			"}\n"
2230
		},
2230
		},
2231
		"----------\n" + 
2231
		"----------\n" + 
2232
		"1. ERROR in X4a.java (at line 3)\n" + 
2232
		"1. ERROR in X4a.java (at line 2)\n" + 
2233
		"	public abstract void test();\n" + 
2233
		"	A;\n" + 
2234
		"	                     ^^^^^^\n" + 
2234
		"	^\n" + 
2235
		"The enum X4a can only define the abstract method test() if it also defines enum constants with corresponding implementations\n" + 
2235
		"The enum constant A must define the abstract method test()\n" + 
2236
		"----------\n"
2236
		"----------\n"
2237
		// X4a is not abstract and does not override abstract method test() in X4a
2237
		// X4a is not abstract and does not override abstract method test() in X4a
2238
	);
2238
	);
Lines 2257-2264 Link Here
2257
		"----------\n" + 
2257
		"----------\n" + 
2258
		"1. ERROR in X4c.java (at line 2)\n" + 
2258
		"1. ERROR in X4c.java (at line 2)\n" + 
2259
		"	A() { void random() {} };\n" + 
2259
		"	A() { void random() {} };\n" + 
2260
		"	    ^\n" + 
2260
		"	^\n" + 
2261
		"The type new X4c(){} must implement the inherited abstract method X4c.test()\n" + 
2261
		"The enum constant A must define the abstract method test()\n" + 
2262
		"----------\n"
2262
		"----------\n"
2263
		// <anonymous X4c$1> is not abstract and does not override abstract method test() in X4c
2263
		// <anonymous X4c$1> is not abstract and does not override abstract method test() in X4c
2264
	);
2264
	);
Lines 2322-2329 Link Here
2322
		"----------\n" + 
2322
		"----------\n" + 
2323
		"1. ERROR in X5c.java (at line 2)\n" + 
2323
		"1. ERROR in X5c.java (at line 2)\n" + 
2324
		"	A() { void random() {} };\n" + 
2324
		"	A() { void random() {} };\n" + 
2325
		"	    ^\n" + 
2325
		"	^\n" + 
2326
		"The type new X5c(){} must implement the inherited abstract method I.test()\n" + 
2326
		"The enum constant A must define the abstract method test()\n" + 
2327
		"----------\n"
2327
		"----------\n"
2328
		// <anonymous X5c$1> is not abstract and does not override abstract method test() in I
2328
		// <anonymous X5c$1> is not abstract and does not override abstract method test() in I
2329
	);
2329
	);
Lines 4909-4918 Link Here
4909
}
4909
}
4910
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=156591 - variation
4910
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=156591 - variation
4911
public void test139() {
4911
public void test139() {
4912
 this.runNegativeTest(
4912
	this.runNegativeTest(
4913
     new String[] {
4913
		new String[] {
4914
    	    "X.java",
4914
			"X.java",
4915
 			"public enum X {\n" + 
4915
			"public enum X {\n" + 
4916
			"	PLUS {\n" + 
4916
			"	PLUS {\n" + 
4917
			"		double eval(double x, double y) {\n" + 
4917
			"		double eval(double x, double y) {\n" + 
4918
			"			return x + y;\n" + 
4918
			"			return x + y;\n" + 
Lines 4925-4947 Link Here
4925
			"	abstract double eval(double x, double y);\n" + 
4925
			"	abstract double eval(double x, double y);\n" + 
4926
			"}\n" + 
4926
			"}\n" + 
4927
			"\n", // =================
4927
			"\n", // =================
4928
     },
4928
		},
4929
	"----------\n" + 
4929
		"----------\n" + 
4930
	"1. WARNING in X.java (at line 3)\n" + 
4930
		"1. WARNING in X.java (at line 3)\n" + 
4931
	"	double eval(double x, double y) {\n" + 
4931
		"	double eval(double x, double y) {\n" + 
4932
	"	       ^^^^^^^^^^^^^^^^^^^^^^^^\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" + 
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" + 
4934
		"----------\n" + 
4935
	"2. ERROR in X.java (at line 7)\n" + 
4935
		"2. ERROR in X.java (at line 7)\n" + 
4936
	"	MINUS {\n" + 
4936
		"	MINUS {\n" + 
4937
	"	      ^\n" + 
4937
		"	^^^^^\n" + 
4938
	"The type new X(){} must implement the inherited abstract method X.eval(double, double)\n" + 
4938
		"The enum constant MINUS must define the abstract method eval(double, double)\n" + 
4939
	"----------\n" + 
4939
		"----------\n" + 
4940
	"3. ERROR in X.java (at line 8)\n" + 
4940
		"3. ERROR in X.java (at line 8)\n" + 
4941
	"	abstract double eval2(double x, double y);\n" + 
4941
		"	abstract double eval2(double x, double y);\n" + 
4942
	"	                ^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
4942
		"	                ^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
4943
	"The abstract method eval2 in type new X(){} can only be defined by an abstract class\n" + 
4943
		"The abstract method eval2 in type new X(){} can only be defined by an abstract class\n" + 
4944
	"----------\n");
4944
		"----------\n"
4945
	);
4945
}
4946
}
4946
//check final modifier
4947
//check final modifier
4947
public void test140() {
4948
public void test140() {
(-)compiler/org/eclipse/jdt/core/compiler/IProblem.java (+2 lines)
Lines 1242-1247 Link Here
1242
	int MissingEnumConstantCase = FieldRelated + 761;
1242
	int MissingEnumConstantCase = FieldRelated + 761;
1243
	/** @since 3.2 */ // TODO need to fix 3.1.1 contribution (inline this constant on client side)
1243
	/** @since 3.2 */ // TODO need to fix 3.1.1 contribution (inline this constant on client side)
1244
	int EnumStaticFieldInInInitializerContext = FieldRelated + 762;
1244
	int EnumStaticFieldInInInitializerContext = FieldRelated + 762;
1245
	/** @since 3.4 */
1246
	int EnumConstantMustImplementAbstractMethod = MethodRelated + 763;
1245
	
1247
	
1246
	/**
1248
	/**
1247
	 * Var args
1249
	 * Var args
(-)compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties (+1 lines)
Lines 571-576 Link Here
571
760 = Illegal modifier for the enum constructor; only private is permitted.
571
760 = Illegal modifier for the enum constructor; only private is permitted.
572
761 = The enum constant {0}.{1} has no corresponding case label
572
761 = The enum constant {0}.{1} has no corresponding case label
573
762 = Cannot refer to the static enum field {0}.{1} within an initializer
573
762 = Cannot refer to the static enum field {0}.{1} within an initializer
574
763 = The enum constant {2} must define the abstract method {0}({1})
574
575
575
### VARARGS
576
### VARARGS
576
800 = Extended dimensions are illegal for a variable argument
577
800 = Extended dimensions are illegal for a variable argument
(-)compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java (-18 / +56 lines)
Lines 474-497 Link Here
474
		methodDecl.sourceEnd);
474
		methodDecl.sourceEnd);
475
}
475
}
476
public void abstractMethodMustBeImplemented(SourceTypeBinding type, MethodBinding abstractMethod) {
476
public void abstractMethodMustBeImplemented(SourceTypeBinding type, MethodBinding abstractMethod) {
477
	this.handle(
477
	if (type.isEnum() && type.isLocalType()) {
478
		// Must implement the inherited abstract method %1
478
		FieldBinding field = type.scope.enclosingMethodScope().initializedField;
479
		// 8.4.3 - Every non-abstract subclass of an abstract type, A, must provide a concrete implementation of all of A's methods.
479
		FieldDeclaration decl = field.sourceField();
480
		IProblem.AbstractMethodMustBeImplemented,
480
		this.handle(
481
		new String[] { 
481
			// Must implement the inherited abstract method %1
482
		        new String(abstractMethod.selector),
482
			// 8.4.3 - Every non-abstract subclass of an abstract type, A, must provide a concrete implementation of all of A's methods.
483
		        typesAsString(abstractMethod.isVarargs(), abstractMethod.parameters, false), 
483
			IProblem.EnumConstantMustImplementAbstractMethod,
484
		        new String(abstractMethod.declaringClass.readableName()), 
484
			new String[] { 
485
		        new String(type.readableName()), 
485
			        new String(abstractMethod.selector),
486
		},
486
			        typesAsString(abstractMethod.isVarargs(), abstractMethod.parameters, false), 
487
		new String[] { 
487
			        new String(decl.name), 
488
		        new String(abstractMethod.selector),
488
			},
489
		        typesAsString(abstractMethod.isVarargs(), abstractMethod.parameters, true), 
489
			new String[] { 
490
		        new String(abstractMethod.declaringClass.shortReadableName()), 
490
			        new String(abstractMethod.selector),
491
		        new String(type.shortReadableName()), 
491
			        typesAsString(abstractMethod.isVarargs(), abstractMethod.parameters, true), 
492
		},
492
			        new String(decl.name), 
493
		type.sourceStart(),
493
			},
494
		type.sourceEnd());
494
			decl.sourceStart(),
495
			decl.sourceEnd());
496
	} else {
497
		this.handle(
498
			// Must implement the inherited abstract method %1
499
			// 8.4.3 - Every non-abstract subclass of an abstract type, A, must provide a concrete implementation of all of A's methods.
500
			IProblem.AbstractMethodMustBeImplemented,
501
			new String[] { 
502
			        new String(abstractMethod.selector),
503
			        typesAsString(abstractMethod.isVarargs(), abstractMethod.parameters, false), 
504
			        new String(abstractMethod.declaringClass.readableName()), 
505
			        new String(type.readableName()), 
506
			},
507
			new String[] { 
508
			        new String(abstractMethod.selector),
509
			        typesAsString(abstractMethod.isVarargs(), abstractMethod.parameters, true), 
510
			        new String(abstractMethod.declaringClass.shortReadableName()), 
511
			        new String(type.shortReadableName()), 
512
			},
513
			type.sourceStart(),
514
			type.sourceEnd());
515
	}
495
}
516
}
496
public void abstractMethodNeedingNoBody(AbstractMethodDeclaration method) {
517
public void abstractMethodNeedingNoBody(AbstractMethodDeclaration method) {
497
	this.handle(
518
	this.handle(
Lines 1508-1513 Link Here
1508
		method.sourceStart(),
1529
		method.sourceStart(),
1509
		method.sourceEnd());
1530
		method.sourceEnd());
1510
}
1531
}
1532
public void enumConstantMustImplementAbstractMethod(AbstractMethodDeclaration method, FieldDeclaration field) {
1533
	MethodBinding abstractMethod = method.binding;
1534
	this.handle(
1535
		IProblem.EnumConstantMustImplementAbstractMethod,
1536
		new String[] { 
1537
		        new String(abstractMethod.selector),
1538
		        typesAsString(abstractMethod.isVarargs(), abstractMethod.parameters, false), 
1539
		        new String(field.name), 
1540
		},
1541
		new String[] { 
1542
		        new String(abstractMethod.selector),
1543
		        typesAsString(abstractMethod.isVarargs(), abstractMethod.parameters, true), 
1544
		        new String(field.name), 
1545
		},
1546
		field.sourceStart(),
1547
		field.sourceEnd());
1548
}
1511
public void enumConstantsCannotBeSurroundedByParenthesis(Expression expression) {
1549
public void enumConstantsCannotBeSurroundedByParenthesis(Expression expression) {
1512
	this.handle(
1550
	this.handle(
1513
		IProblem.EnumConstantsCannotBeSurroundedByParenthesis,
1551
		IProblem.EnumConstantsCannotBeSurroundedByParenthesis,
(-)compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java (-5 / +16 lines)
Lines 1002-1008 Link Here
1002
		this.maxFieldCount = 0;
1002
		this.maxFieldCount = 0;
1003
		int lastVisibleFieldID = -1;
1003
		int lastVisibleFieldID = -1;
1004
		boolean hasEnumConstants = false;
1004
		boolean hasEnumConstants = false;
1005
		boolean hasEnumConstantsWithoutBody = false;
1005
		FieldDeclaration[] enumConstantsWithoutBody = null;
1006
		
1006
		
1007
		if (this.typeParameters != null) {
1007
		if (this.typeParameters != null) {
1008
			for (int i = 0, count = this.typeParameters.length; i < count; i++) {
1008
			for (int i = 0, count = this.typeParameters.length; i < count; i++) {
Lines 1020-1027 Link Here
1020
				switch(field.getKind()) {
1020
				switch(field.getKind()) {
1021
					case AbstractVariableDeclaration.ENUM_CONSTANT:
1021
					case AbstractVariableDeclaration.ENUM_CONSTANT:
1022
						hasEnumConstants = true;
1022
						hasEnumConstants = true;
1023
						if (!(field.initialization instanceof QualifiedAllocationExpression))
1023
						if (!(field.initialization instanceof QualifiedAllocationExpression)) {
1024
							hasEnumConstantsWithoutBody = true;
1024
							if (enumConstantsWithoutBody == null)
1025
								enumConstantsWithoutBody = new FieldDeclaration[count];
1026
							enumConstantsWithoutBody[i] = field;
1027
						}
1025
					case AbstractVariableDeclaration.FIELD:
1028
					case AbstractVariableDeclaration.FIELD:
1026
						FieldBinding fieldBinding = field.binding;
1029
						FieldBinding fieldBinding = field.binding;
1027
						if (fieldBinding == null) {
1030
						if (fieldBinding == null) {
Lines 1063-1073 Link Here
1063
			case TypeDeclaration.ENUM_DECL :
1066
			case TypeDeclaration.ENUM_DECL :
1064
				// check enum abstract methods
1067
				// check enum abstract methods
1065
				if (this.binding.isAbstract()) {
1068
				if (this.binding.isAbstract()) {
1066
					if (!hasEnumConstants || hasEnumConstantsWithoutBody) {
1069
					if (!hasEnumConstants) {
1067
						for (int i = 0, count = this.methods.length; i < count; i++) {
1070
						for (int i = 0, count = this.methods.length; i < count; i++) {
1068
							final AbstractMethodDeclaration methodDeclaration = this.methods[i];
1071
							final AbstractMethodDeclaration methodDeclaration = this.methods[i];
1069
							if (methodDeclaration.isAbstract() && methodDeclaration.binding != null) {
1072
							if (methodDeclaration.isAbstract() && methodDeclaration.binding != null)
1070
								this.scope.problemReporter().enumAbstractMethodMustBeImplemented(methodDeclaration);
1073
								this.scope.problemReporter().enumAbstractMethodMustBeImplemented(methodDeclaration);
1074
						}
1075
					} else if (enumConstantsWithoutBody != null) {
1076
						for (int i = 0, count = this.methods.length; i < count; i++) {
1077
							final AbstractMethodDeclaration methodDeclaration = this.methods[i];
1078
							if (methodDeclaration.isAbstract() && methodDeclaration.binding != null) {
1079
								for (int f = 0, l = enumConstantsWithoutBody.length; f < l; f++)
1080
									if (enumConstantsWithoutBody[f] != null)
1081
										this.scope.problemReporter().enumConstantMustImplementAbstractMethod(methodDeclaration, enumConstantsWithoutBody[f]);
1071
							}
1082
							}
1072
						}
1083
						}
1073
					}
1084
					}

Return to bug 200016