### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core.tests.model Index: src/org/eclipse/jdt/core/tests/dom/ASTConverter15Test.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15Test.java,v retrieving revision 1.207 diff -u -r1.207 ASTConverter15Test.java --- src/org/eclipse/jdt/core/tests/dom/ASTConverter15Test.java 28 Aug 2006 18:15:46 -0000 1.207 +++ src/org/eclipse/jdt/core/tests/dom/ASTConverter15Test.java 5 Sep 2006 15:34:15 -0000 @@ -7096,7 +7096,7 @@ assertEquals("Wrong size", 0, annotations.length); } - public void _test0227() throws JavaModelException { + public void test0227() throws JavaModelException { this.workingCopy = getWorkingCopy("/Converter15/src/X.java", true/*resolve*/); String contents = "import anno.Anno;\n" + @@ -7105,7 +7105,10 @@ "\n" + "public class X extends B {\n" + " @Anno(clz=IFoo.IBar.class)\n" + - " public void f() {}\n" + + // the annotation we chase up is not this one, but the one + // carried by B#f + " public void f() {}\n" + + " IFoo.IBar m;\n" + "}"; class TestASTRequestor extends ASTRequestor { public ArrayList asts = new ArrayList(); @@ -7154,8 +7157,10 @@ assertEquals("Wrong kind", IBinding.MEMBER_VALUE_PAIR, memberValuePairBinding.getKind()); Object value = memberValuePairBinding.getValue(); assertNotNull("No value", value); - assertTrue("not a type binding", value instanceof ITypeBinding); - ITypeBinding typeBinding2 = (ITypeBinding) value; - assertEquals("Wrong qualified name", "intf.IFoo.IBar", typeBinding2.getQualifiedName()); + assertTrue("Not a type binding", value instanceof ITypeBinding); + IVariableBinding[] fields = + declaration.resolveBinding().getDeclaredFields(); + assertTrue("Bad field definition", fields != null && fields.length == 1); + assertEquals("Type binding mismatch", value, fields[0].getType()); } } \ No newline at end of file #P org.eclipse.jdt.core Index: compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java,v retrieving revision 1.97 diff -u -r1.97 BinaryTypeBinding.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java 28 Jun 2006 17:17:04 -0000 1.97 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java 5 Sep 2006 15:34:21 -0000 @@ -83,7 +83,7 @@ char[] typeName = annotationInfo.getTypeName(); ReferenceBinding annotationType = env.getTypeFromConstantPoolName(typeName, 1, typeName.length - 1, false); - return AnnotationBinding.createUnresolvedAnnotation(annotationType, pairs, env); + return new UnresolvedAnnotationBinding(annotationType, pairs, env); } public static AnnotationBinding[] createAnnotations(IBinaryAnnotation[] annotationInfos, LookupEnvironment env) { int length = annotationInfos == null ? 0 : annotationInfos.length; Index: compiler/org/eclipse/jdt/internal/compiler/lookup/UnresolvedAnnotationBinding.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/UnresolvedAnnotationBinding.java,v retrieving revision 1.2 diff -u -r1.2 UnresolvedAnnotationBinding.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/UnresolvedAnnotationBinding.java 29 Mar 2006 02:45:27 -0000 1.2 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/UnresolvedAnnotationBinding.java 5 Sep 2006 15:34:21 -0000 @@ -12,6 +12,7 @@ public class UnresolvedAnnotationBinding extends AnnotationBinding { private LookupEnvironment env; + private boolean typeUnresolved = true; UnresolvedAnnotationBinding(ReferenceBinding type, ElementValuePair[] pairs, LookupEnvironment env) { super(type, pairs); @@ -19,20 +20,37 @@ } public ReferenceBinding getAnnotationType() { - // the type is resolved when requested - if (this.env != null) { - // annotation type are never parameterized + if (this.typeUnresolved) { // the type is resolved when requested this.type = BinaryTypeBinding.resolveType(this.type, this.env, false); - this.env = null; - setMethodBindings(); + // annotation type are never parameterized + this.typeUnresolved = false; } return this.type; } public ElementValuePair[] getElementValuePairs() { - if (this.env != null) - getAnnotationType(); // resolve the annotation type & method bindings of each pair - + if (this.env != null) { + if (this.typeUnresolved) { + getAnnotationType(); // resolve the annotation type + } + // resolve method binding and value type (if unresolved) for each pair + for (int i = this.pairs.length; --i >= 0;) { + ElementValuePair pair = this.pairs[i]; + MethodBinding[] methods = this.type.getMethods(pair.getName()); + // there should be exactly one since the type is an annotation type. + if (methods != null && methods.length == 1) { + pair.setMethodBinding(methods[0]); + } // else silently leave a null there + Object value = pair.getValue(); + if (value instanceof UnresolvedReferenceBinding) { + pair.setValue(((UnresolvedReferenceBinding) value). + resolve(this.env, false)); + // no parameterized types in annotation values + } // do nothing for UnresolvedAnnotationBinding-s, since their + // content is only accessed through get* methods + } + this.env = null; + } return this.pairs; } } Index: compiler/org/eclipse/jdt/internal/compiler/lookup/ElementValuePair.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ElementValuePair.java,v retrieving revision 1.2 diff -u -r1.2 ElementValuePair.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/ElementValuePair.java 29 Mar 2006 02:40:11 -0000 1.2 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/ElementValuePair.java 5 Sep 2006 15:34:21 -0000 @@ -95,4 +95,9 @@ // lazily set after annotation type was resolved this.binding = binding; } + +void setValue(Object value) { + // can be modified after the initialization if holding an unresolved ref + this.value = value; +} } Index: compiler/org/eclipse/jdt/internal/compiler/lookup/AnnotationBinding.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/AnnotationBinding.java,v retrieving revision 1.5 diff -u -r1.5 AnnotationBinding.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/AnnotationBinding.java 29 Mar 2006 02:40:11 -0000 1.5 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/AnnotationBinding.java 5 Sep 2006 15:34:19 -0000 @@ -16,6 +16,8 @@ * Represents JSR 175 Annotation instances in the type-system. */ public class AnnotationBinding{ + // do not access directly - use getters instead (UnresolvedAnnotationBinding + // resolves types for type and pair contents just in time) ReferenceBinding type; ElementValuePair[] pairs; @@ -74,7 +76,9 @@ } private static AnnotationBinding buildRetentionAnnotation(long bits, LookupEnvironment env) { - ReferenceBinding retentionPolicy = env.getResolvedType(TypeConstants.JAVA_LANG_ANNOTATION_RETENTIONPOLICY, null); + ReferenceBinding retentionPolicy = + env.getResolvedType(TypeConstants.JAVA_LANG_ANNOTATION_RETENTIONPOLICY, + null); Object value = null; if ((bits & TagBits.AnnotationRuntimeRetention) != 0) value = retentionPolicy.getField(TypeConstants.UPPER_RUNTIME, true); @@ -82,10 +86,11 @@ value = retentionPolicy.getField(TypeConstants.UPPER_CLASS, true); else if ((bits & TagBits.AnnotationSourceRetention) != 0) value = retentionPolicy.getField(TypeConstants.UPPER_SOURCE, true); - - ReferenceBinding retention = env.getResolvedType(TypeConstants.JAVA_LANG_ANNOTATION_RETENTION, null); - ElementValuePair[] pairs = new ElementValuePair[] { new ElementValuePair(TypeConstants.VALUE, value, null) }; - return createUnresolvedAnnotation(retention, pairs, env); + return (new AnnotationBinding( + env.getResolvedType(TypeConstants.JAVA_LANG_ANNOTATION_RETENTION, null), + new ElementValuePair[] { + new ElementValuePair(TypeConstants.VALUE, value, null)})). + setMethodBindings(); } private static AnnotationBinding buildTargetAnnotation(long bits, LookupEnvironment env) { @@ -131,22 +136,12 @@ if ((bits & TagBits.AnnotationForType) != 0) value[index++] = elementType.getField(TypeConstants.TYPE, true); } - - ElementValuePair[] pairs = new ElementValuePair[] { new ElementValuePair(TypeConstants.VALUE, value, null) }; - return createUnresolvedAnnotation(target, pairs, env); -} - -public static AnnotationBinding createUnresolvedAnnotation(ReferenceBinding type, ElementValuePair[] pairs, LookupEnvironment env) { - // if type is unresolved then answer a lazy instance that will resolve the type & fault in the method of each pair when requested - if (type instanceof UnresolvedReferenceBinding) - return new UnresolvedAnnotationBinding(type, pairs, env); - - AnnotationBinding newInstance = new AnnotationBinding(type, pairs); - newInstance.setMethodBindings(); - return newInstance; + return (new AnnotationBinding(target, + new ElementValuePair[] { + new ElementValuePair(TypeConstants.VALUE, value, null)}). + setMethodBindings()); } - public AnnotationBinding(ReferenceBinding type, ElementValuePair[] pairs) { this.type = type; this.pairs = pairs; @@ -164,9 +159,8 @@ return this.pairs; } -protected void setMethodBindings() { +private AnnotationBinding setMethodBindings() { // set the method bindings of each element value pair - if (this.type == null) return; for (int i = this.pairs.length; --i >= 0;) { ElementValuePair pair = this.pairs[i]; MethodBinding[] methods = this.type.getMethods(pair.getName()); @@ -174,5 +168,6 @@ if (methods != null && methods.length == 1) pair.setMethodBinding(methods[0]); } + return this; } -} +} \ No newline at end of file