Community
Participate
Working Groups
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:
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".
Hi Jerome, thanks for the fast response. The solution that you proposed will work for us. Thanks!
Created attachment 83534 [details] Corresponding implementation and tests
API, implementation and tests released for 3.4M4
'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(); }
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;
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).
Verified for 3.4M4 looking at v_829 contents.
(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) )