| Summary: | DOM VariableBinding.getConstantValue() and MethodBinding.getDefaultValue() from ASTParser.createAST(IProgressMonitor) returned incorrect value | ||
|---|---|---|---|
| Product: | [Eclipse Project] JDT | Reporter: | Theodora Yeung <tyeung> |
| Component: | Core | Assignee: | JDT-Core-Inbox <jdt-core-inbox> |
| Status: | CLOSED WONTFIX | QA Contact: | |
| Severity: | normal | ||
| Priority: | P3 | ||
| Version: | 3.1 | ||
| Target Milestone: | --- | ||
| Hardware: | PC | ||
| OS: | Windows XP | ||
| Whiteboard: | |||
Unortunately createAST(IProgressMmonitor) is not designed to resolve all types reachable from the AST being built. In this particular case, you should use createASTs(...) which will ensure that the constants are correcty initialized even for CUs not directly requested. With the fix to Bugzilla 111822, calling createASTs(...) should resolve the problem as Jerome mentioned. Will give that a shot. Again, need the fix to Bugzilla 111822 in the APT jdt.core branch. thanks. Problem fixed in APT land. Closing. |
Build a DOM AST through the ASTParser.createAST(IProgressMonitor) then navigate to the TypeBinding (X) that is referenced by a field declaration ("X field;")in the DOM AST that's just been built. The fields and annotation methods, if any, of X is always returning null for constants and annotation method defaults regardless of actual value in source. Perhaps SourceTypeBinding.methods() and SourceTypeBinding.fields() needs to resolve field initializer and annotation method default, if they exists? Repro: 1)Create a new java project with 2 java files. BuildDomAST.java: package astTest; public class BuildDomAST{ ClassWithNestedAnnotation nestedAnno; } ClassWithNestedAnnotation.java: package astTest; public class ClassWithNestedAnnotation { public final int FOUR = 4; public @interface NestedAnnotation{ public enum Character{ Winnie, Tiger, Piglet, Eore; } Character value() default Character.Eore; } } 2) Build a DOM AST for BuildDomAST.java through the ASTParser.createAST() API with resolve binding set to true. CompilationUnit createAST(){ ASTParser p = ASTParser.newParser( AST.JLS3 ); p.setSource(/*the source of BuildDomAST.java */); p.setResolveBindings( true ); p.setProject( /*the java project created earlier*/ ); p.setUnitName( "BuildDomAST" ); p.setFocalPosition( 0 ); p.setKind( ASTParser.K_COMPILATION_UNIT ); return (CompilationUnit)p.createAST( null ); } 3) Examine the constant value of the field ClassWithNestedAnnotation.FOUR from the AST that just got created. Starting from the top-level type binding representing "BuildDomAST". Then look into the type of field "nestedAnno", which is "ClassWithNestedAnnotation". Finally navigate to the variable binding for field "FOUR". VariableBinding (for "FOUR).getConstantValue() should return Integer 4 but null is returned. A similar problem occurs when you examine the default value of the annotation method ClassWithNestedAnnotation.NestedAnnotation.value(). The enum constant Character.Eore should be returned but got null back. The code I used to do the navigation is as below. final List<AbstractTypeDeclaration> typeDecls = createAST().types(); for( AbstractTypeDeclaration typeDecl : typeDecls ){ final ITypeBinding typeBinding = typeDecl.resolveBinding(); final IVariableBinding[] fields = typeBinding.getDeclaredFields(); for(IVariableBinding field : fields){ final String name = field.getName(); // only interested at the field named "nestedAnno" // which has type "ClassWithNestedAnnotation" if( "nestedAnno".equals(name)){ final ITypeBinding fieldType = field.getType(); final ITypeBinding[] nestedTypes = fieldType.getDeclaredTypes(); for(ITypeBinding nestedType : nestedTypes ){ if( "NestedAnnotation".equals(nestedType.getName()) ){ final IMethodBinding[] annotationMethods = nestedType.getDeclaredMethods(); for( IMethodBinding annotationMethod : annotationMethods ){ // examine the default value of NestedAnnotation.value() if( "value".equals(annotationMethod.getName()) ){ // This is currently returning null // The expected value is the enum Character.Eore Object defValue = annotationMethod.getDefaultValue(); } } } } final IVariableBinding[] nestedAnnoFields = fieldType.getDeclaredFields (); // The only thing you should find is the field named "FOUR" for(IVariableBinding nestedAnnoField : nestedAnnoFields ){ // This is currently returning null // The expected value is Integer 4. Object constantValue = nestedAnnoField.getConstantValue() ); } } }