Bug 210565 - Null value is obtained from IMemberValuePair, when type is Enum
Summary: Null value is obtained from IMemberValuePair, when type is Enum
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.4   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 3.4 M4   Edit
Assignee: Jerome Lanneluc CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-11-21 13:34 EST by Leho Nigul CLA
Modified: 2007-12-13 11:39 EST (History)
2 users (show)

See Also:


Attachments
Corresponding implementation and tests (7.07 KB, patch)
2007-11-22 09:52 EST, Jerome Lanneluc CLA
no flags Details | Diff
Improved Javadoc (2.03 KB, patch)
2007-12-13 11:23 EST, Markus Keller CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Leho Nigul CLA 2007-11-21 13:34:16 EST
Build ID: I20071101-0010

Steps To Reproduce:
I have the following code in my workspace

package test;
import static test.TestEnum.Test2;
public class TestBean {
	
	   @TestAnnotation(value=Test2)
	   public int test(int testpoint)
	   {
	      return 0;
	   }
}

When I try to invoke getValue on IMemberValuePair for "value" attribute, I get NULL.

Notice, that if I change the code to be 

package test;

import static test.TestEnum;
public class TestBean {
	
	   @TestAnnotation(value=TestEnum.Test2)
	   public int test(int testpoint)
	   {
	      return 0;
	   }

}

I get the value as expected

The source for TestEnum
package test;

public enum TestEnum {

    Test1  (),
    Test2  ();
    
}

The source for @TestAnnotation

package test;

public @interface TestAnnotation {

	public abstract TestEnum value();
}




More information:
Comment 1 Jerome Lanneluc CLA 2007-11-22 07:07:23 EST
This is a limitation of using the Java model here. We would need to resolve the string "Test2" to know that it corresponds to an enum constant.

Would adding a new value kind help here?

/**
 * Constant indicating that the value is a simple name represented by a {@link String}.
 * This usually represents an enumeration's constant (e.g. "FIRST" when there is a
 * static import for "MyEnum.FIRST"), but this would need to be further analyzed to ensure 
 * that.
 */
int K_SIMPLE_NAME = 13;

In this case, getValue() would return "Test2".
Comment 2 Leho Nigul CLA 2007-11-22 07:35:46 EST
Hi Jerome, thanks for the fast response. The solution that you proposed will work for us.
Thanks!
Comment 3 Jerome Lanneluc CLA 2007-11-22 09:52:03 EST
Created attachment 83534 [details]
Corresponding implementation and tests
Comment 4 Jerome Lanneluc CLA 2007-11-22 10:07:32 EST
API, implementation and tests released for 3.4M4
Comment 5 Maxime Daniel CLA 2007-12-12 10:03:22 EST
'usually' is possibly too strong in the API documentation. The following test case produces a SingleNameReference at parse time, that I would expect to see converted to a K_SIMPLE_NAME?

public class X {
	public static final String CONST = "const";
	@Annot(value=CONST)
    void foo() {
	}
}
@interface Annot {
    String value();
}
Comment 6 Jerome Lanneluc CLA 2007-12-13 07:08:15 EST
After Maxime's feedback, the latest version of this API has been released as:
/**
 * Constant indicating that the value is a simple name represented by a 
 * {@link String}.
 * Especially if the simple name is "FIRST" and there is a static import for 
 * "MyEnum.FIRST", this can represent an enumeration's constant. Use 
 * {@link IType#resolveType(String)} to verify that assumption.
 */
int K_SIMPLE_NAME = 13;
Comment 7 Markus Keller CLA 2007-12-13 11:23:06 EST
Created attachment 85192 [details]
Improved Javadoc

>  * Especially if the simple name is "FIRST" and there is a static import for 
>  * "MyEnum.FIRST", this can represent an enumeration's constant. Use 
>  * {@link IType#resolveType(String)} to verify that assumption.

I don't understand how IType#resolveType(String) could help in determining the resolved element for the string "FIRST". The only way I see how #resolveType(..) could help here is when resolving a K_QUALIFIED_NAME like "TestEnum.Test2" (parse the string and resolve the qualifier "TestEnum").

In general, AFAIK, a K_SIMPLE_NAME or K_QUALIFIED_NAME can only refer to a constant (including statically imported and enum constants). See the patch for how I would write the API (also includes a fix for K_CLASS).
Comment 8 Frederic Fusier CLA 2007-12-13 11:30:49 EST
Verified for 3.4M4 looking at v_829 contents.
Comment 9 Jerome Lanneluc CLA 2007-12-13 11:39:05 EST
(In reply to comment #7)
> Created an attachment (id=85192) [details]
> Improved Javadoc
> 
> >  * Especially if the simple name is "FIRST" and there is a static import for 
> >  * "MyEnum.FIRST", this can represent an enumeration's constant. Use 
> >  * {@link IType#resolveType(String)} to verify that assumption.
> 
> I don't understand how IType#resolveType(String) could help in determining the
> resolved element for the string "FIRST". The only way I see how
> #resolveType(..) could help here is when resolving a K_QUALIFIED_NAME like
> "TestEnum.Test2" (parse the string and resolve the qualifier "TestEnum").
Right. I'm not sure what I was thinking. Thanks for catching this.

> In general, AFAIK, a K_SIMPLE_NAME or K_QUALIFIED_NAME can only refer to a
> constant (including statically imported and enum constants). See the patch for
> how I would write the API (also includes a fix for K_CLASS).
> 
I don't think that we can refer to compile-time constants here since the user can put anything (for example the user forgot .class in the following case: @MyAnnot(clazz=Object) )