Bug 77430 - [1.5] case statements with enum values not correctly supported
Summary: [1.5] case statements with enum values not correctly supported
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.1   Edit
Hardware: PC Windows XP
: P3 critical with 2 votes (vote)
Target Milestone: 3.1 M4   Edit
Assignee: Philipe Mulet CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 78394 79169 80115 (view as bug list)
Depends on:
Blocks:
 
Reported: 2004-11-01 17:20 EST by Khaled Agrama CLA
Modified: 2004-12-14 12:22 EST (History)
10 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Khaled Agrama CLA 2004-11-01 17:20:18 EST
consider the following:

enum X { a,b }
...
X x = ...
switch(x) {
 case a: ...
 case b: ...
}

The above is valid Java 1.5 code.  However the current eclipse build I am
running (integration build 11/1/04) flags the case statements as errors.  If I
change them to:
case X.a: ...
case X.b: ...
The JDT compiler accepts them.  However, this is *invalid* Java 1.5 code (don't
ask me why).
Comment 1 Olivier Thomann CLA 2004-11-01 17:56:25 EST
Could you please provide a complete test case?
Comment 2 Olivier Thomann CLA 2004-11-01 18:09:21 EST
Ok, I think I got a test case.
This code reports two errors, but it compiles fine using JDK1.5.0.

package p;

public enum X { a,b }

class A {
	void foo() {
		for (X x : X.values()) {
			switch(x) {
			 case a:
			 case b:
			 	System.out.println(x.name());
			}
		}
	}
}

If the class A is defined in a separate file, javac also compiles it.
package p;

public class A {
	void foo() {
		for (X x : X.values()) {
			switch(x) {
			 case a:
			 case b:
			 	System.out.println(x.name());
			}
		}
	}
}

Eclipse compiler requires a static import to be added.
Comment 3 Andre Weinand CLA 2004-11-02 12:19:21 EST
In I20041101 this compiled fine:

public class Enums2 {
    enum Color { RED, GREEN };
    public static void main(String[] args) {
        Color c= Color.GREEN;
        switch (c) {
        case Color.RED:
            System.out.println(Color.RED);
            break;
        case Color.GREEN:
            System.out.println(c);
            break;
        }
    }
}

In I20041102 I have to remove the qualyfier "Color" in the case labels.
However the resulting code doesn't compile:

public class Enums2 {
    enum Color { RED, GREEN };
    public static void main(String[] args) {
        Color c= Color.GREEN;
        switch (c) {
        case RED:
            System.out.println(Color.RED);
            break;
        case GREEN:
            System.out.println(c);
            break;
        }
    }
}

Comment 4 Olivier Thomann CLA 2004-11-02 13:19:43 EST
Color.RED is illegal. Only the simple name has to be used.
It seems that the enum constants of a enum type are implicitely visible.
Comment 5 Philipe Mulet CLA 2004-11-03 08:37:16 EST
Qualifying is indeed forbidden, and we tightened the compiler recently. However
we are missing the free access to member enum members.
Comment 6 Nils Hammar CLA 2004-11-05 07:31:59 EST
FYI: I have registered an RFE at Sun regarding use of qualified enums in case
statements.

"(Review ID: 328931) - Ability to use qualified enums in case statements"

If enough people is requesting this feature, we may see it in the future!
Comment 7 Philipe Mulet CLA 2004-11-05 12:01:55 EST
Would indeed make the most sense, as one can already qualify non enum constants
in case statements. Feels like an artificial limitation.
Comment 8 Nils Hammar CLA 2004-11-06 01:00:09 EST
Additional information:

SUN has now decided that the inability to use qualified enums is likely to be a 
bug. The current implementation actually conflicts with JSR201, 
(http://jcp.org/en/jsr/detail?id=201) regarding the enum definition 
(http://jcp.org/aboutJava/communityprocess/jsr/tiger/enum.html).

Following is an email from SUN:
-------------------------------
Thank you for helping us narrow the focus of this issue. 

We have determined that this report is a new bug and entered the bug into our 
internal bug tracking system under Bug Id: 6191812. 

You can monitor this bug and look for related issues on The Java Developer 
Connection Bug Database at: 
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6191812 

It may take a day or two before your bug shows up in this external database. 

Note that bug 4936393 (http://bugs.sun.com/bugdatabase/view_bug.do?
bug_id=4936393) mentions that we explicitly chose this behavior.  However, this 
RFE gives the development team a chance to explain its reasoning in the 
Evaluation and reconsider the decision.

The Java Developer Connection is a free channel that is maintained by staff 
here at Sun.  Access this web page to join: 
http://developer.java.sun.com/servlet/RegistrationServlet. 

The home page for the Java Developer Connection is: 
http://java.sun.com/jdc. 

-------------------------------
Comment 9 Frederic Fusier CLA 2004-11-11 11:01:08 EST
*** Bug 78394 has been marked as a duplicate of this bug. ***
Comment 10 Olivier Thomann CLA 2004-11-22 09:55:49 EST
*** Bug 79169 has been marked as a duplicate of this bug. ***
Comment 11 Olivier Thomann CLA 2004-12-03 10:59:03 EST
*** Bug 80115 has been marked as a duplicate of this bug. ***
Comment 12 Philipe Mulet CLA 2004-12-09 04:49:01 EST
I suspect that even if they abandon the restriction on simple name for enum
constant cases, we will still have to honour resolving to sibling member enums.

Comment 13 Kent Johnson CLA 2004-12-09 12:05:39 EST
To enable qualified enum constants we need to remove the check in 
CaseStatement resolveCase()

if (constantExpression instanceof QualifiedNameReference) {
  scope.problemReporter().cannotUseQualifiedEnumConstantInCaseLabel
((QualifiedNameReference)constantExpression);
}


As for the following testcase:

enum X { a }
class A {
	public static void main(String[] args) {
		for (X x : X.values()) {
			int a = 3;
			switch(x) {
				case a : System.out.println(a); // prints '3'
			}
		}
	}
}

We need to know that we are resolving the constantExpression of a case & walk 
the Enum X before looking for a normal variable.

I think this needs to be done in CaseStatement resolveCase(), before we call:

  TypeBinding caseType = constantExpression.resolveType(scope);
Comment 14 Kent Johnson CLA 2004-12-09 12:25:57 EST
This test should generate 3 errors:

enum X { a }
class A {
	public static void main(String[] args) {
		test(X.a, 9);
		test2(X.a, 3);
	}
	static void test(X x, int a) {
		if (x == a) a++; // incomparable types: X and int
		switch(x) {
			case a : System.out.println(a); // prints '9'
		}
	}
	static void test2(X x, final int aa) {
		switch(x) {
			case aa : // unqualified enum constant error
				System.out.println(a); // cannot find a
		}
	}
}
Comment 15 Philipe Mulet CLA 2004-12-09 16:43:34 EST
Added support to resolve simple name relatively to enum type (switchExpressionType).
Added EnumTest#test057-058.
Fixed
Comment 16 Olivier Thomann CLA 2004-12-14 12:22:36 EST
Verified in 200412140800