Bug 214948 - Incorrect deprecation warning on annotation instances
Summary: Incorrect deprecation warning on annotation instances
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.5 M5   Edit
Assignee: Kent Johnson CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 99638 (view as bug list)
Depends on:
Blocks: 258906
  Show dependency tree
 
Reported: 2008-01-10 14:55 EST by Walter Harley CLA
Modified: 2009-01-27 04:57 EST (History)
4 users (show)

See Also:


Attachments
Screen shot showing problem (152.04 KB, image/png)
2008-01-10 14:56 EST, Walter Harley CLA
no flags Details
Preliminary patch (9.96 KB, patch)
2009-01-07 12:59 EST, Srikanth Sankaran CLA
no flags Details | Diff
Scope change (1.61 KB, patch)
2009-01-07 16:08 EST, Kent Johnson CLA
no flags Details | Diff
Patch with earlier review suggestions incorporated (11.13 KB, patch)
2009-01-08 09:13 EST, Srikanth Sankaran CLA
no flags Details | Diff
Proposed patch (5.44 KB, patch)
2009-01-08 15:33 EST, Kent Johnson CLA
no flags Details | Diff
Trace dumper patch (1.39 KB, patch)
2009-01-09 00:34 EST, Srikanth Sankaran CLA
no flags Details | Diff
Proposed patch (11.83 KB, patch)
2009-01-09 12:45 EST, Kent Johnson CLA
no flags Details | Diff
Proposed patch (12.22 KB, patch)
2009-01-09 14:19 EST, Kent Johnson CLA
no flags Details | Diff
Added test (2.20 KB, patch)
2009-01-12 13:35 EST, Kent Johnson CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Walter Harley CLA 2008-01-10 14:55:47 EST
In N20080110-0010, and in general since 3.4M4, I am seeing incorrect deprecation warnings on some annotation instances.  The annotation types being warned about are in the same package and are not actually deprecated.  Not all instances of the same annotation type in a given compilation unit get the warnings, only some.  I will attach a screen capture showing the problem; note that the annotations types @RTVisible, @RTInvisible, and @SimpleAnnotation are showing deprecation warnings (both yellow squiggles and entries in the Problems view), but not all instances of them, only some.

If I edit the file (e.g., add whitespace and delete it again), nothing changes.  If I then save (and autobuild) the warnings will go away.  

At this point, the following actions will NOT make the warnings return:
  - close and reopen the file
  - save a change to a different unrelated file in the same package
  - save a change to one of the annotation types involved

The following actions WILL make the warnings return:
  - clean and build of the affected project.
  - clean and build all projects in the workspace.

However, a clean build of all projects *will* make the warnings return.

I do not yet have a concise repro case for this.  However, it should be possible to see it by checking out the org.eclipse.jdt.apt.tests plug-in from CVS (this will also require org.eclipse.jdt.apt.core, org.eclipse.jdt.core.tests.*, and org.eclipse.test.performance, in order to build).  I will try to come up with a more restricted repro case.
Comment 1 Walter Harley CLA 2008-01-10 14:56:46 EST
Created attachment 86597 [details]
Screen shot showing problem
Comment 2 Kent Johnson CLA 2008-03-28 15:00:52 EDT
Walter - I'm seeing 8 deprecation warnings in the type AnnotationTest that disappear if I touch the file.

Doing a full build brings them back.

Is that what you're seeing with HEAD ?
Comment 3 Kent Johnson CLA 2008-03-28 16:27:01 EDT
Somehow the package binding of the 3 annotation types is being flagged as deprecated.
Comment 4 Kent Johnson CLA 2008-03-28 16:38:07 EDT
So the package question appears to be correctly flagged as deprecated from package-info.java

@Deprecated package question;

I don't see how an incremental build is going to reproduce this & also keep it flagged as deprecated.

So a few questions, is it reasonable to flag a type as deprecated because of its package ?

And if so does the package-info.java get 'built' before any type in the package ? Even during an incremental build ?
Comment 5 Walter Harley CLA 2008-03-28 17:47:54 EDT
Re comment #2, yes, that's what I'm seeing.

Re comment #4, doh, you're right, package-info.java.  So, I retract what I said about the not being deprecated; presumably they should all be deprecated.  (I hate package annotations!)  Yes, I guess that a type should be deprecated if its package is deprecated; I can't think of any other reason to deprecate a package, other than to get warnings on all its types.

The strange thing, unless I'm missing something else obvious, is that only some of the instances of that annotation type in that file are flagged as deprecated, and then only in incremental build.

Did I mention how I feel about package annotations?
Comment 6 Srikanth Sankaran CLA 2008-12-15 02:17:50 EST
    1. The incremental v full build disparities in warnings issue aside: are these warnings even required/meaningful/useful ? The package in question namely ``question'' is being deprecated and the warnings (when they are produced) are about the components that *constitute* the package (and not for some external client entity that imports it which would make sense)

    Per JLS 3.0, section 9.6.1.6,

A program element annotated @Deprecated is one that programmers are discouraged
from using, typically because it is dangerous, or because a better alternative
exists. A Java compiler must produce a warning when a deprecated type,
method, field, or constructor is used (overridden, invoked, or referenced by name)
unless:
• The use is within an entity that itself is is annotated with the annotation @Deprecated;

   So is, 

   must + unless == must not ? ||
   must + unless == need not ?

    2. So the real question is, for references outside the constituents of the package, is there a consistent, predictable and correct warning behavior regardless of incremental v full build ?

     This needs to be checked.

Comment 7 Kent Johnson CLA 2008-12-15 11:55:48 EST
*** Bug 99638 has been marked as a duplicate of this bug. ***
Comment 8 Kent Johnson CLA 2008-12-15 12:02:03 EST
From bug 99638, javac's bug is http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6492694

I've tried the latest javac 7 version & deprecated packages still have no affect in javac inside or outside of their package.

Do we want to support deprecated packages at all ?



I tried : javac -Xlint:deprecation  question\package-info.java question\A.java question\B.java other\Z.java

file: question/package-info.java
@Deprecated package question;

file: question/A.java
package question;
public class A {
	B b;
}

file: question/B.java
package question;
public class B {
	A a;
}

file: other/Z.java
package other;
import question.*;
class Z extends question.A {
	B b;
}
Comment 9 Kent Johnson CLA 2008-12-15 15:12:19 EST
Walter, how load would you scream if we stopped tagging packages as deprecated ?
Comment 10 Kent Johnson CLA 2008-12-15 15:32:57 EST
If only I could type...

How loud would you scream if we stopped tagging packages as deprecated?
Comment 11 Walter Harley CLA 2008-12-15 16:08:22 EST
You mean, if you stopped issuing a warning on deprecated packages?  I don't have any problem with that at all.  My strictly personal opinion is that package-info.java is a crock.

If you're talking about hiding the 'deprecated' attribute on a package object altogether - so that there's no way for APT to determine whether a given package declaration has the @Deprecated annotation - I doubt it is a user issue but it might conceivably cause the compiler to fail Java compliance tests.
Comment 12 Kent Johnson CLA 2008-12-15 16:34:34 EST
Yes - it was the second one.

As far as the compiler & likely most users are concerned, the notion of a package being deprecated is not interesting.

But if APT tests care, then we're stuck...
Comment 13 Walter Harley CLA 2008-12-15 18:12:58 EST
(In reply to comment #12)
> But if APT tests care, then we're stuck...

It wouldn't be APT tests per se - if any APT tests break, we can change them.  I'm more worried about Sun JCK tests.  No timely way to find out whether those break, though.  The JLS does explicitly mention (7.4.1.1) the possibility of package annotations, so it is reasonable to expect that the compliance tests cover them.  Whether they touch on @Deprecated in particular is unknown, but I think that if we ignore package annotations altogether we'll probably be in trouble.
Comment 14 Walter Harley CLA 2008-12-16 13:01:04 EST
Perhaps by coincidence, bug 258906 was just reported, which appears to be the same problem, package-level annotations not being visible to a Java 6 processor.  I haven't dug into that one yet but this is an indication that contrary to my hopes, people actually are trying to use this feature in the field.
Comment 15 Kent Johnson CLA 2008-12-17 16:38:09 EST
Srikanth - I'm going to take this one back since its going to be tricky to get the resolution order correct for incremental builds.
Comment 16 Srikanth Sankaran CLA 2008-12-18 00:44:45 EST
(In reply to comment #15)
> Srikanth - I'm going to take this one back since its going to be tricky to get
> the resolution order correct for incremental builds.

Hello Kent,

	I am happy working on it - as long as it is recognized to be a tricky issue and as such one that would take some time for a newcomer to fix.

	I am happy not working on it also :), so either way is good.
Comment 17 Kent Johnson CLA 2008-12-18 16:30:02 EST
Srikanth - give it a try. I suggest you start with bug 258906 - its easier.


I have a patch for this case & bug 258906 that seems to work so ask for hints if you want.

Not much will happen around here for the next 2 weeks so we can 'fix' it in a week or two.
Comment 18 Srikanth Sankaran CLA 2009-01-07 12:59:43 EST
Created attachment 121836 [details]
Preliminary patch


    Kent, take a look and let me know if you see any major problems. This patch
addresses most of the issues, but still needs more testing. 

    The one known glitch is :

    When the name/lookup environment instantiated is one that is based on the Java model (such as the Cancellable/Searchable env), there is a problem is restoring package level deprecations. This is because the Java model does not store the package-info synthetic type.

    I think it is really a bad idea that package-info type was hidden from the Java model. I can't think of any good reason for this. I'll continue to investigate this and see how this can be resolved. (unless you have solution already)

    This patch in particular ensures that,

    - Deprecated warnings are not issued when already in deprecated context
    - Incremental build of package-info.java by changing and saving package-info.java file triggers a build of other elements in the package if the said changes involve annotation changes.
    - In full build mode, package level deprecation details are available during resolution of any type (even for a type that preceded package-info.java in the compile queue)
Comment 19 Kent Johnson CLA 2009-01-07 16:08:43 EST
Created attachment 121875 [details]
Scope change

Instead of your change to Scope try this one instead (it requires no changes to MethodBinding)

The ClassFileReader change is covered by bug 149768 - double check that patch please.

Also take a look at CompilationUnitDeclaration where the package annotations are currently resolved to see if that is still necessary.
Comment 20 Jerome Lanneluc CLA 2009-01-08 04:33:34 EST
(In reply to comment #18)
>     I think it is really a bad idea that package-info type was hidden from the
> Java model. I can't think of any good reason for this. I'll continue to
> investigate this and see how this can be resolved. (unless you have solution
> already)
The Java model only shows what's in the source. Since the package-info.java file doesn't contain any type, the fake package-info type cannot appear as a child of the package fragment. Similarly, if an interface defines a method "void myMethod();" the flags (IMember#getFlags()) don't include the 'public' flag.

That said, we could still store the deprecation on the IPackageFragment (by making it an IAnnotatable for example.)
Comment 21 Srikanth Sankaran CLA 2009-01-08 09:13:24 EST
Created attachment 121950 [details]
Patch with earlier review suggestions incorporated


Kent, please take a look again. This patch addresses the previous comments. It also restores package deprecation status properly even when

org.eclipse.jdt.internal.compiler.lookup.PackageBinding.getType(char[]) fails to find package-info.java due to its absence in the model.

I am yet to run the automated tests fully. I am posting this patch in advance for fear that my laptop may die on me anytime, I met with the blue screen more than a couple of times in the last few hours - if tests finish ok, I'll update status here.

I also haven't created a test yet, did you happen to write any ?
Comment 22 Srikanth Sankaran CLA 2009-01-08 09:23:05 EST
(In reply to comment #20)
> (In reply to comment #18)
> >     I think it is really a bad idea that package-info type was hidden from the
> > Java model. I can't think of any good reason for this. I'll continue to
> > investigate this and see how this can be resolved. (unless you have solution
> > already)
> The Java model only shows what's in the source. Since the package-info.java
> file doesn't contain any type, the fake package-info type cannot appear as a
> child of the package fragment. Similarly, if an interface defines a method
> "void myMethod();" the flags (IMember#getFlags()) don't include the 'public'
> flag.
> That said, we could still store the deprecation on the IPackageFragment (by
> making it an IAnnotatable for example.)

I see what you mean - this issue has reared its head in some manner, form or fashion (either complicating the fix or writing the test) in the three or four defects I worked on this area - so you can see where my comment is coming from!

I wonder if it would have been better for the model to have still stored package-info and supplied some filters which clients can engage to hide them. 

Comment 23 Srikanth Sankaran CLA 2009-01-08 10:53:50 EST
Tests finished OK.
Comment 24 Kent Johnson CLA 2009-01-08 15:33:41 EST
Created attachment 122006 [details]
Proposed patch

This is the patch that works for me. Does it fail some of your tests ?

Is all of the extra code for the JavaModel case in PackageBinding.getAnnotationTagBits() necessary ? I thought PackageElementImpl.getAnnotationBindings() handled finding the annotations for a package in the DOM.

Also, do you have a case that requires the additional QualifiedReference in CompilationUnitScope ? I do not need an additional reference to get incremental builds to work.

For testing - I'm using Walter's case & checking incremental vs. full build scenarios.

And what does setting 'declaration.javadoc = this.referenceContext.javadoc' in the CompilationUnitScope do ? Who needs it ?
Comment 25 Srikanth Sankaran CLA 2009-01-09 00:29:36 EST
(In reply to comment #24)
> Created an attachment (id=122006) [details]
> Proposed patch
> This is the patch that works for me. Does it fail some of your tests ?

Yes, it does.

> For testing - I'm using Walter's case & checking incremental vs. full build
> scenarios.

Per steps in comment #0 in bug #258906 import the `testprocessor' project into your workspace and import the project 'test' into the PDE workspace you run from your top level eclipse instance.

1. Full build of 'test' should not throw any errors since that bug #258906
is closed.
2. Now edit package-info.java and comment out the line 
   @javax.xml.bind.annotation.XmlSchema (namespace = "test") and save it.
3. Autobuild triggers. You should really get an error "XML namespace must be given in @XmlType or @XmlSchema", but you DON'T.
4. Clean and trigger full build - you get the error.
5. Edit package-info.java and undo (2) and save. Error does not go away.
6. Clean and full build - error goes away.

> Also, do you have a case that requires the additional QualifiedReference in
> CompilationUnitScope ? I do not need an additional reference to get incremental
> builds to work.

    As my comment in the code explains, if you introduce material changes to package-info.java and save it, thereby triggering in an incremental compile of it, there is nothing in HEAD that ensures that elements in the package get rebuilt.

Creating the additional QualifiedReference in CompilationUnitScope achieves this.

> And what does setting 'declaration.javadoc = this.referenceContext.javadoc' in
> the CompilationUnitScope do ? Who needs it ?

This is some `drive-by-bug-shooting'. This change is unrelated to the current defect, nor does it actually cause a problem today (the way the downstream code works). 

It is just a dormant bug in that, the concerned code on HEAD leaves the AST in an improper state. Compare the synthetic type creation code in CompilationUnitScope.buildTypeBindings with the code in Parser.consumeEmptyInternalCompilationUnit for example.
    
> Is all of the extra code for the JavaModel case in
> PackageBinding.getAnnotationTagBits() necessary ? I thought
> PackageElementImpl.getAnnotationBindings() handled finding the annotations for
> a package in the DOM.

Please apply the soon to be attached tracedump patch on top of (head + your patch) and try the following steps.

1. Launch a PDE instance, import eclipse.org.jdt.apt.tests into it along with needed projects mentioned in comment #0.
2. Clean and trigger full build of eclipse.org.jdt.apt.tests. Plya around a bit by changing notypes.package-info.java a bit with and without immediate save.
You should see the following on the console:

BAD: question.SimpleAnnotaion is NOT viewed as deprecated !
GOOD: question.SimpleAnnotaion is viewed as deprecated !
GOOD: question.SimpleAnnotaion is viewed as deprecated !
GOOD: question.SimpleAnnotaion is viewed as deprecated !
GOOD: question.SimpleAnnotaion is viewed as deprecated !
GOOD: question.SimpleAnnotaion is viewed as deprecated !
GOOD: question.SimpleAnnotaion is viewed as deprecated !
GOOD: question.SimpleAnnotaion is viewed as deprecated !
GOOD: question.SimpleAnnotaion is viewed as deprecated !
GOOD: question.SimpleAnnotaion is viewed as deprecated !
GOOD: question.SimpleAnnotaion is viewed as deprecated !
GOOD: question.SimpleAnnotaion is viewed as deprecated !
GOOD: question.SimpleAnnotaion is viewed as deprecated !
GOOD: question.SimpleAnnotaion is viewed as deprecated !
GOOD: question.SimpleAnnotaion is viewed as deprecated !
GOOD: question.SimpleAnnotaion is viewed as deprecated !
BAD: question.SimpleAnnotaion is NOT viewed as deprecated !

So, on few of the occasions we are wrong. My changes in PackageBinding.java addresses these cases.

It should be mentioned that so far as I have seen, the BAD cases occur only in
		Daemon Thread [org.eclipse.jdt.internal.ui.text.JavaReconciler] (Suspended (breakpoint at line 473 in ASTNode))	
			QualifiedTypeReference(ASTNode).isTypeUseDeprecated(TypeBinding, Scope) line: 473	
			QualifiedTypeReference(TypeReference).internalResolveType(Scope) line: 150	
			QualifiedTypeReference(TypeReference).resolveType(BlockScope, boolean) line: 197	
			QualifiedTypeReference(TypeReference).resolveType(BlockScope) line: 193	
			SingleMemberAnnotation(Annotation).resolveType(BlockScope) line: 233	
			ASTNode.resolveAnnotations(BlockScope, Annotation[], Binding) line: 614	
			SourceTypeBinding.getAnnotationTagBits() line: 691	
			SourceTypeBinding.faultInTypesForFieldsAndMethods() line: 588	
			CompilationUnitScope.faultInTypes() line: 450	
			CompilationUnitProblemFinder(Compiler).resolve(CompilationUnitDeclaration, ICompilationUnit, boolean, boolean, boolean) line: 847	
			CompilationUnitProblemFinder(Compiler).resolve(ICompilationUnit, boolean, boolean, boolean) line: 899	
			CompilationUnitProblemFinder.process(CompilationUnit, SourceElementParser, WorkingCopyOwner, HashMap, boolean, int, IProgressMonitor) line: 182	
			CompilationUnitProblemFinder.process(CompilationUnit, WorkingCopyOwner, HashMap, boolean, int, IProgressMonitor) line: 243	
			ReconcileWorkingCopyOperation.makeConsistent(CompilationUnit) line: 190	
			ReconcileWorkingCopyOperation.executeOperation() line: 89	
			ReconcileWorkingCopyOperation(JavaModelOperation).run(IProgressMonitor) line: 721	
			ReconcileWorkingCopyOperation(JavaModelOperation).runOperation(IProgressMonitor) line: 781	
			CompilationUnit.reconcile(int, int, WorkingCopyOwner, IProgressMonitor) line: 1242	
			JavaReconcilingStrategy.reconcile(ICompilationUnit, boolean) line: 124	
			JavaReconcilingStrategy.access$0(JavaReconcilingStrategy, ICompilationUnit, boolean) line: 108	
			JavaReconcilingStrategy$1.run() line: 89	
			SafeRunner.run(ISafeRunnable) line: 37	
			JavaReconcilingStrategy.reconcile(boolean) line: 87	
			JavaReconcilingStrategy.reconcile(IRegion) line: 149	
			JavaCompositeReconcilingStrategy(CompositeReconcilingStrategy).reconcile(IRegion) line: 86	
			JavaCompositeReconcilingStrategy.reconcile(IRegion) line: 102	
			JavaReconciler(MonoReconciler).process(DirtyRegion) line: 77	
			AbstractReconciler$BackgroundThread.run() line: 206	

and never in

		Daemon Thread [Compiler Processing Task] (Suspended (breakpoint at line 478 in ASTNode))	
			SingleTypeReference(ASTNode).isTypeUseDeprecated(TypeBinding, Scope) line: 478	
			SingleTypeReference(TypeReference).internalResolveType(Scope) line: 150	
			SingleTypeReference(TypeReference).resolveType(BlockScope, boolean) line: 197	
			SourceTypeBinding.resolveTypesFor(MethodBinding) line: 1395	
			SourceTypeBinding.methods() line: 1087	
			SourceTypeBinding.faultInTypesForFieldsAndMethods() line: 593	
			CompilationUnitScope.faultInTypes() line: 450	
			Compiler.process(CompilationUnitDeclaration, int) line: 731	
			ProcessTaskManager.run() line: 137	
			Thread.run() line: 735	
	C:\IBMJava60\jre\bin\javaw.exe (Jan 9, 2009 10:35:54 AM)

I think this is due to the name environments being different, one based on model and the other file system.	


I don't have a test case that actually shows an end user problem due to this.
I don't think we anyway guarantee that on the fly reconcile operation would catch all problems. So may be we are ok leaving out these elaborate changes. Please use your judegement. In the event of deleting these changes, leaving
the comment intact with an added reference to this defect may make sense ?


Comment 26 Srikanth Sankaran CLA 2009-01-09 00:34:55 EST
Created attachment 122065 [details]
Trace dumper patch


This shows potential bug in org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding.isViewedAsDeprecated()
when invoked by the Java Reconciler.
Comment 27 Jerome Lanneluc CLA 2009-01-09 06:50:18 EST
(In reply to comment #22)
> I wonder if it would have been better for the model to have still stored
> package-info and supplied some filters which clients can engage to hide them. 
That might work as well. However if you surface it to the clients with a flag, I think the default should be to hide the fake type so that existing clients are not broken (i.e. a client that retrieves the source range of the type could be broken if this source range is (-1, -1). )
Comment 28 Kent Johnson CLA 2009-01-09 12:45:39 EST
Created attachment 122138 [details]
Proposed patch

Good work - but instead of adding an additional reference to every single compilation unit for the package-info type, which may or may not exist, I would prefer to detect this case in the incremental builder.


As for the extra code in PackageBinding, I'm inclined to leave it out for now, but we should talk about it on Monday.
Comment 29 Kent Johnson CLA 2009-01-09 14:19:18 EST
Created attachment 122149 [details]
Proposed patch

Actually I prefer this one instead
Comment 30 Srikanth Sankaran CLA 2009-01-12 01:11:40 EST
(In reply to comment #29)
> Created an attachment (id=122149) [details]
> Proposed patch
> Actually I prefer this one instead

PackageBinding.java has some System.out.print statements left in.

It may be useful to add a comment to PackageBinding.getAnnotationTagBits() to the effect that it doesn't retrieve the deprecation annotations properly if the INameEnvironment is based on Java model.





Comment 31 Kent Johnson CLA 2009-01-12 13:35:20 EST
Created attachment 122306 [details]
Added test
Comment 32 Kent Johnson CLA 2009-01-12 13:36:26 EST
Fix and test released for 3.5M5
Comment 33 David Audel CLA 2009-01-27 04:57:54 EST
Verified for 3.5M5 using I20090126-1300