### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core Index: compiler/org/eclipse/jdt/internal/compiler/lookup/PackageBinding.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PackageBinding.java,v retrieving revision 1.48 diff -u -r1.48 PackageBinding.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/PackageBinding.java 14 Nov 2008 20:28:34 -0000 1.48 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/PackageBinding.java 7 Jan 2009 17:47:51 -0000 @@ -205,6 +205,21 @@ return null; } +/** + * Compute the tagbits for standard annotations. For source types, these could require + * lazily resolving corresponding annotation nodes, in case of forward references. + * @see org.eclipse.jdt.internal.compiler.lookup.Binding#getAnnotationTagBits() + */ +public long getAnnotationTagBits() { + if ((this.tagBits & TagBits.AnnotationResolved) == 0) { + this.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved); + ReferenceBinding packageInfo = this.getType(TypeConstants.PACKAGE_INFO_NAME); + if (packageInfo != null) + this.tagBits |= (packageInfo.getAnnotationTagBits() & TagBits.AllStandardAnnotationsMask); + } + return this.tagBits; +} + /* API * Answer the receiver's binding type from Binding.BindingID. */ Index: compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java,v retrieving revision 1.128 diff -u -r1.128 ReferenceBinding.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java 5 Dec 2008 16:49:14 -0000 1.128 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java 7 Jan 2009 17:47:52 -0000 @@ -1175,7 +1175,7 @@ */ public final boolean isViewedAsDeprecated() { return (this.modifiers & (ClassFileConstants.AccDeprecated | ExtraCompilerModifiers.AccDeprecatedImplicitly)) != 0 - || (getPackage().tagBits & TagBits.AnnotationDeprecated) != 0; + || (getPackage().getAnnotationTagBits() & TagBits.AnnotationDeprecated) != 0; } public ReferenceBinding[] memberTypes() { Index: compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java,v retrieving revision 1.112 diff -u -r1.112 MethodBinding.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java 5 Dec 2008 12:41:29 -0000 1.112 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java 7 Jan 2009 17:47:51 -0000 @@ -468,13 +468,37 @@ if (scope != null) { TypeDeclaration typeDecl = scope.referenceContext; AbstractMethodDeclaration methodDecl = typeDecl.declarationOf(originalMethod); - if (methodDecl != null) + if (methodDecl != null) { ASTNode.resolveAnnotations(methodDecl.scope, methodDecl.annotations, originalMethod); + if ((originalMethod.tagBits & TagBits.AnnotationDeprecated) != 0) + originalMethod.modifiers |= ClassFileConstants.AccDeprecated; + } } } return originalMethod.tagBits; } + + +/** + * @see org.eclipse.jdt.internal.compiler.lookup.Binding#initializeDeprecatedAnnotationTagBits() +*/ +public void initializeDeprecatedAnnotationTagBits() { + MethodBinding originalMethod = original(); + if ((originalMethod.tagBits & TagBits.DeprecatedAnnotationResolved) == 0 && originalMethod.declaringClass instanceof SourceTypeBinding) { + ClassScope scope = ((SourceTypeBinding) originalMethod.declaringClass).scope; + if (scope != null) { + TypeDeclaration typeDecl = scope.referenceContext; + AbstractMethodDeclaration methodDecl = typeDecl.declarationOf(originalMethod); + if (methodDecl != null) + ASTNode.resolveDeprecatedAnnotations(methodDecl.scope, methodDecl.annotations, originalMethod); + originalMethod.tagBits |= TagBits.DeprecatedAnnotationResolved; + } + if ((originalMethod.tagBits & TagBits.AnnotationDeprecated) != 0) + originalMethod.modifiers |= ClassFileConstants.AccDeprecated; + } +} + /** * @return the default value for this annotation method or null if there is no default value */ @@ -776,7 +800,13 @@ /* Answer true if the receiver's declaring type is deprecated (or any of its enclosing types) */ public final boolean isViewedAsDeprecated() { - return (this.modifiers & (ClassFileConstants.AccDeprecated | ExtraCompilerModifiers.AccDeprecatedImplicitly)) != 0; + if ((this.modifiers & (ClassFileConstants.AccDeprecated | ExtraCompilerModifiers.AccDeprecatedImplicitly)) != 0) + return true; + if (this.declaringClass != null) { + this.declaringClass.initializeDeprecatedAnnotationTagBits(); + return this.declaringClass.isViewedAsDeprecated(); + } + return false; } public final int kind() { Index: compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java,v retrieving revision 1.124 diff -u -r1.124 CompilationUnitScope.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java 7 Jan 2009 17:34:23 -0000 1.124 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java 7 Jan 2009 17:47:50 -0000 @@ -105,6 +105,9 @@ this.referenceContext.types[0].annotations = this.referenceContext.currentPackage.annotations; } recordQualifiedReference(this.currentPackageName); // always dependent on your own package + // Record a reference arc against "package-info", so a delta against package-info.java causes + // the current unit to be compiled afresh + recordQualifiedReference(CharOperation.arrayConcat(this.currentPackageName, TypeConstants.PACKAGE_INFO_NAME)); } // Skip typeDeclarations which know of previously reported errors Index: compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java,v retrieving revision 1.346 diff -u -r1.346 Scope.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java 5 Dec 2008 12:41:29 -0000 1.346 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java 7 Jan 2009 17:47:55 -0000 @@ -2807,8 +2807,11 @@ if (!methodScope.isInsideInitializer()){ // check method modifiers to see if deprecated MethodBinding context = ((AbstractMethodDeclaration)methodScope.referenceContext).binding; - if (context != null && context.isViewedAsDeprecated()) - return true; + if (context != null) { + context.initializeDeprecatedAnnotationTagBits(); // may not have been resolved until then + if (context.isViewedAsDeprecated()) + return true; + } } else { SourceTypeBinding type = ((BlockScope)this).referenceType().binding; // inside field declaration ? check field modifier to see if deprecated Index: compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileReader.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileReader.java,v retrieving revision 1.86 diff -u -r1.86 ClassFileReader.java --- compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileReader.java 27 Jun 2008 16:04:13 -0000 1.86 +++ compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileReader.java 7 Jan 2009 17:47:50 -0000 @@ -20,6 +20,7 @@ import org.eclipse.jdt.internal.compiler.env.*; import org.eclipse.jdt.internal.compiler.impl.Constant; import org.eclipse.jdt.internal.compiler.lookup.TagBits; +import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; import org.eclipse.jdt.internal.compiler.lookup.TypeIds; import org.eclipse.jdt.internal.compiler.util.Util; @@ -917,6 +918,35 @@ } else if (newMissingTypes != null) { return true; } + + /* As the original test case attached to https://bugs.eclipse.org/bugs/show_bug.cgi?id=258906 + * shows, (non-standard) annotations attached to package-info have an influence outside of the + * file and so are structurally material. + */ + if (CharOperation.equals(this.getSourceName(), TypeConstants.PACKAGE_INFO_NAME)) { + IBinaryAnnotation [] thisAnnotations = getAnnotations(); + IBinaryAnnotation [] newAnnotations = newClassFile.getAnnotations(); + int thisAnnotationsLength = thisAnnotations != null ? thisAnnotations.length : 0; + int newAnnotationsLength = newAnnotations != null ? newAnnotations.length : 0; + if (thisAnnotationsLength != newAnnotationsLength) + return true; + for (int i = 0; i < thisAnnotationsLength; i++) { + if (!CharOperation.equals(thisAnnotations[i].getTypeName(), newAnnotations[i].getTypeName())) + return true; + IBinaryElementValuePair[] thisElementValuePairInfo = thisAnnotations[i].getElementValuePairs(); + IBinaryElementValuePair[] newElementValuePairInfo = newAnnotations[i].getElementValuePairs(); + int thisPairLength = thisElementValuePairInfo != null ? thisElementValuePairInfo.length : 0; + int newPairLength = newElementValuePairInfo != null ? newElementValuePairInfo.length : 0; + if (thisPairLength != newPairLength) + return true; + for (int j = 0; j < thisPairLength; j++) { + if (!CharOperation.equals(thisElementValuePairInfo[j].getName(), newElementValuePairInfo[j].getName())) + return true; + // Comparing values is futile as they will be seen to be different by Object.equals + } + } + } + return false; } catch (ClassFormatException e) { return true;