Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 93144 Details for
Bug 209996
[search] Add a way to access the most local enclosing annotation for reference search matches
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
[patch]
Last proposed patch
v12.txt (text/plain), 110.37 KB, created by
Frederic Fusier
on 2008-03-21 11:55:39 EDT
(
hide
)
Description:
Last proposed patch
Filename:
MIME Type:
Creator:
Frederic Fusier
Created:
2008-03-21 11:55:39 EDT
Size:
110.37 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.jdt.core >Index: search/org/eclipse/jdt/core/search/PackageReferenceMatch.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/PackageReferenceMatch.java,v >retrieving revision 1.11 >diff -u -r1.11 PackageReferenceMatch.java >--- search/org/eclipse/jdt/core/search/PackageReferenceMatch.java 10 May 2006 18:03:46 -0000 1.11 >+++ search/org/eclipse/jdt/core/search/PackageReferenceMatch.java 21 Mar 2008 15:54:37 -0000 >@@ -12,6 +12,7 @@ > > import org.eclipse.core.resources.IResource; > import org.eclipse.jdt.core.IJavaElement; >+import org.eclipse.jdt.internal.core.search.matching.InternalReferenceMatch; > > /** > * A Java search match that represents a package reference. >@@ -22,22 +23,21 @@ > * > * @since 3.0 > */ >-public class PackageReferenceMatch extends SearchMatch { >+public class PackageReferenceMatch extends InternalReferenceMatch { > >- /** >- * Creates a new package reference match. >- * >- * @param enclosingElement the inner-most enclosing member that references this package >- * @param accuracy one of {@link #A_ACCURATE} or {@link #A_INACCURATE} >- * @param offset the offset the match starts at, or -1 if unknown >- * @param length the length of the match, or -1 if unknown >- * @param insideDocComment <code>true</code> if this search match is inside a doc >- * comment, and <code>false</code> otherwise >- * @param participant the search participant that created the match >- * @param resource the resource of the element >- */ >- public PackageReferenceMatch(IJavaElement enclosingElement, int accuracy, int offset, int length, boolean insideDocComment, SearchParticipant participant, IResource resource) { >- super(enclosingElement, accuracy, offset, length, participant, resource); >- setInsideDocComment(insideDocComment); >- } >+/** >+ * Creates a new package reference match. >+ * >+ * @param enclosingElement the inner-most enclosing member that references this package >+ * @param accuracy one of {@link #A_ACCURATE} or {@link #A_INACCURATE} >+ * @param offset the offset the match starts at, or -1 if unknown >+ * @param length the length of the match, or -1 if unknown >+ * @param insideDocComment <code>true</code> if this search match is inside a doc >+ * comment, and <code>false</code> otherwise >+ * @param participant the search participant that created the match >+ * @param resource the resource of the element >+ */ >+public PackageReferenceMatch(IJavaElement enclosingElement, int accuracy, int offset, int length, boolean insideDocComment, SearchParticipant participant, IResource resource) { >+ super(enclosingElement, accuracy, offset, length, insideDocComment, participant, resource); >+} > } >Index: search/org/eclipse/jdt/core/search/FieldReferenceMatch.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/FieldReferenceMatch.java,v >retrieving revision 1.17 >diff -u -r1.17 FieldReferenceMatch.java >--- search/org/eclipse/jdt/core/search/FieldReferenceMatch.java 30 Jan 2008 15:58:34 -0000 1.17 >+++ search/org/eclipse/jdt/core/search/FieldReferenceMatch.java 21 Mar 2008 15:54:37 -0000 >@@ -12,6 +12,7 @@ > > import org.eclipse.core.resources.IResource; > import org.eclipse.jdt.core.IJavaElement; >+import org.eclipse.jdt.internal.core.search.matching.InternalReferenceMatch; > > /** > * A Java search match that represents a field reference. >@@ -22,50 +23,50 @@ > * > * @since 3.0 > */ >-public class FieldReferenceMatch extends SearchMatch { >+public class FieldReferenceMatch extends InternalReferenceMatch { > >- private boolean isReadAccess; >- private boolean isWriteAccess; >+private boolean isReadAccess; >+private boolean isWriteAccess; >+ >+/** >+ * Creates a new field reference match. >+ * >+ * @param enclosingElement the inner-most enclosing member that references >+ * this field >+ * @param accuracy one of {@link #A_ACCURATE} or {@link #A_INACCURATE} >+ * @param offset the offset the match starts at, or -1 if unknown >+ * @param length the length of the match, or -1 if unknown >+ * @param isReadAccess whether the match represents a read access >+ * @param isWriteAccess whether the match represents a write access >+ * @param insideDocComment <code>true</code> if this search match is inside a >+ * doc comment, and <code>false</code> otherwise >+ * @param participant the search participant that created the match >+ * @param resource the resource of the element >+ */ >+public FieldReferenceMatch(IJavaElement enclosingElement, int accuracy, int offset, int length, boolean isReadAccess, boolean isWriteAccess, boolean insideDocComment, SearchParticipant participant, IResource resource) { >+ super(enclosingElement, accuracy, offset, length, insideDocComment, participant, resource); >+ this.isReadAccess = isReadAccess; >+ this.isWriteAccess = isWriteAccess; >+} >+ >+/** >+ * Returns whether the field reference is a read access to the field. >+ * Note that a field reference can be read and written at once in case of compound assignments (e.g. i += 0;) >+ * >+ * @return whether the field reference is a read access to the field. >+ */ >+public final boolean isReadAccess() { >+ return this.isReadAccess; >+} >+ >+/** >+ * Returns whether the field reference is a write access to the field. >+ * Note that a field reference can be read and written at once in case of compound assignments (e.g. i += 0;) >+ * >+ * @return whether the field reference is a write access to the field. >+ */ >+public final boolean isWriteAccess() { >+ return this.isWriteAccess; >+} > >- /** >- * Creates a new field reference match. >- * >- * @param enclosingElement the inner-most enclosing member that references this field >- * @param accuracy one of {@link #A_ACCURATE} or {@link #A_INACCURATE} >- * @param offset the offset the match starts at, or -1 if unknown >- * @param length the length of the match, or -1 if unknown >- * @param isReadAccess whether the match represents a read access >- * @param isWriteAccess whether the match represents a write access >- * @param insideDocComment <code>true</code> if this search match is inside a doc >- * comment, and <code>false</code> otherwise >- * @param participant the search participant that created the match >- * @param resource the resource of the element >- */ >- public FieldReferenceMatch(IJavaElement enclosingElement, int accuracy, int offset, int length, boolean isReadAccess, boolean isWriteAccess, boolean insideDocComment, SearchParticipant participant, IResource resource) { >- super(enclosingElement, accuracy, offset, length, participant, resource); >- this.isReadAccess = isReadAccess; >- this.isWriteAccess = isWriteAccess; >- setInsideDocComment(insideDocComment); >- } >- >- /** >- * Returns whether the field reference is a read access to the field. >- * Note that a field reference can be read and written at once in case of compound assignments (e.g. i += 0;) >- * >- * @return whether the field reference is a read access to the field. >- */ >- public final boolean isReadAccess() { >- return this.isReadAccess; >- } >- >- /** >- * Returns whether the field reference is a write access to the field. >- * Note that a field reference can be read and written at once in case of compound assignments (e.g. i += 0;) >- * >- * @return whether the field reference is a write access to the field. >- */ >- public final boolean isWriteAccess() { >- return this.isWriteAccess; >- } >- > } >Index: search/org/eclipse/jdt/core/search/MethodReferenceMatch.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/MethodReferenceMatch.java,v >retrieving revision 1.24 >diff -u -r1.24 MethodReferenceMatch.java >--- search/org/eclipse/jdt/core/search/MethodReferenceMatch.java 21 Mar 2007 17:45:10 -0000 1.24 >+++ search/org/eclipse/jdt/core/search/MethodReferenceMatch.java 21 Mar 2008 15:54:37 -0000 >@@ -12,6 +12,7 @@ > > import org.eclipse.core.resources.IResource; > import org.eclipse.jdt.core.IJavaElement; >+import org.eclipse.jdt.internal.core.search.matching.InternalReferenceMatch; > > /** > * A Java search match that represents a method reference. >@@ -22,108 +23,107 @@ > * > * @since 3.0 > */ >-public class MethodReferenceMatch extends SearchMatch { >+public class MethodReferenceMatch extends InternalReferenceMatch { > private boolean constructor; > private boolean synthetic; > private boolean superInvocation; > >- /** >- * Creates a new method reference match. >- * >- * @param enclosingElement the inner-most enclosing member that references this method >- * @param accuracy one of {@link #A_ACCURATE} or {@link #A_INACCURATE} >- * @param offset the offset the match starts at, or -1 if unknown >- * @param length the length of the match, or -1 if unknown >- * @param insideDocComment <code>true</code> if this search match is inside a doc >- * comment, and <code>false</code> otherwise >- * @param participant the search participant that created the match >- * @param resource the resource of the element >- */ >- public MethodReferenceMatch(IJavaElement enclosingElement, int accuracy, int offset, int length, boolean insideDocComment, SearchParticipant participant, IResource resource) { >- super(enclosingElement, accuracy, offset, length, participant, resource); >- setInsideDocComment(insideDocComment); >- } >- >- /** >- * Creates a new method reference match. >- * >- * @param enclosingElement the inner-most enclosing member that references this method >- * @param accuracy one of {@link #A_ACCURATE} or {@link #A_INACCURATE} >- * @param offset the offset the match starts at, or -1 if unknown >- * @param length the length of the match, or -1 if unknown >- * @param constructor <code>true</code> if this search match a constructor >- * <code>false</code> otherwise >- * @param synthetic <code>true</code> if this search match a synthetic element >- * <code>false</code> otherwise >- * @param insideDocComment <code>true</code> if this search match is inside a doc >- * comment, and <code>false</code> otherwise >- * @param participant the search participant that created the match >- * @param resource the resource of the element >- * @since 3.1 >- */ >- public MethodReferenceMatch(IJavaElement enclosingElement, int accuracy, int offset, int length, boolean constructor, boolean synthetic, boolean insideDocComment, SearchParticipant participant, IResource resource) { >- this(enclosingElement, accuracy, offset, length, insideDocComment, participant, resource); >- this.constructor = constructor; >- this.synthetic = synthetic; >- } >- >- /** >- * Creates a new method reference match. >- * >- * @param enclosingElement the inner-most enclosing member that references this method >- * @param accuracy one of {@link #A_ACCURATE} or {@link #A_INACCURATE} >- * @param offset the offset the match starts at, or -1 if unknown >- * @param length the length of the match, or -1 if unknown >- * @param constructor <code>true</code> if this search matches a constructor >- * <code>false</code> otherwise >- * @param synthetic <code>true</code> if this search matches a synthetic element >- * <code>false</code> otherwise >- * @param superInvocation <code>true</code> if this search matches a super-type invocation >- * element <code>false</code> otherwise >- * @param insideDocComment <code>true</code> if this search match is inside a doc >- * comment, and <code>false</code> otherwise >- * @param participant the search participant that created the match >- * @param resource the resource of the element >- * @since 3.3 >- */ >- public MethodReferenceMatch(IJavaElement enclosingElement, int accuracy, int offset, int length, boolean constructor, boolean synthetic, boolean superInvocation, boolean insideDocComment, SearchParticipant participant, IResource resource) { >- this(enclosingElement, accuracy, offset, length, constructor, synthetic, insideDocComment, participant, resource); >- this.superInvocation = superInvocation; >- } >- >- /** >- * Returns whether the reference is on a constructor. >- * >- * @return Returns whether the reference is on a constructor or not. >- * @since 3.1 >- */ >- public final boolean isConstructor() { >- return this.constructor; >- } >- >- /** >- * Returns whether the reference is on a synthetic element. >- * Note that this field is only used for constructor reference. This happens when default constructor >- * declaration is used or implicit super constructor is called. >- * >- * @return whether the reference is synthetic or not. >- * @since 3.1 >- */ >- public final boolean isSynthetic() { >- return this.synthetic; >- } >- >- /** >- * Returns whether the reference is on a message sent from a type >- * which is a super type of the searched method declaring type. >- * If <code>true</code>, the method called at run-time may or may not be >- * the search target, depending on the run-time type of the receiver object. >- * >- * @return <code>true</code> if the reference is on a message sent from >- * a super-type of the searched method declaring class, <code>false </code> otherwise >- * @since 3.3 >- */ >- public boolean isSuperInvocation() { >- return this.superInvocation; >- } >+/** >+ * Creates a new method reference match. >+ * >+ * @param enclosingElement the inner-most enclosing member that references this method >+ * @param accuracy one of {@link #A_ACCURATE} or {@link #A_INACCURATE} >+ * @param offset the offset the match starts at, or -1 if unknown >+ * @param length the length of the match, or -1 if unknown >+ * @param insideDocComment <code>true</code> if this search match is inside a doc >+ * comment, and <code>false</code> otherwise >+ * @param participant the search participant that created the match >+ * @param resource the resource of the element >+ */ >+public MethodReferenceMatch(IJavaElement enclosingElement, int accuracy, int offset, int length, boolean insideDocComment, SearchParticipant participant, IResource resource) { >+ super(enclosingElement, accuracy, offset, length, insideDocComment, participant, resource); >+} >+ >+/** >+ * Creates a new method reference match. >+ * >+ * @param enclosingElement the inner-most enclosing member that references this method >+ * @param accuracy one of {@link #A_ACCURATE} or {@link #A_INACCURATE} >+ * @param offset the offset the match starts at, or -1 if unknown >+ * @param length the length of the match, or -1 if unknown >+ * @param constructor <code>true</code> if this search match a constructor >+ * <code>false</code> otherwise >+ * @param synthetic <code>true</code> if this search match a synthetic element >+ * <code>false</code> otherwise >+ * @param insideDocComment <code>true</code> if this search match is inside a doc >+ * comment, and <code>false</code> otherwise >+ * @param participant the search participant that created the match >+ * @param resource the resource of the element >+ * @since 3.1 >+ */ >+public MethodReferenceMatch(IJavaElement enclosingElement, int accuracy, int offset, int length, boolean constructor, boolean synthetic, boolean insideDocComment, SearchParticipant participant, IResource resource) { >+ this(enclosingElement, accuracy, offset, length, insideDocComment, participant, resource); >+ this.constructor = constructor; >+ this.synthetic = synthetic; >+} >+ >+/** >+ * Creates a new method reference match. >+ * >+ * @param enclosingElement the inner-most enclosing member that references this method >+ * @param accuracy one of {@link #A_ACCURATE} or {@link #A_INACCURATE} >+ * @param offset the offset the match starts at, or -1 if unknown >+ * @param length the length of the match, or -1 if unknown >+ * @param constructor <code>true</code> if this search matches a constructor >+ * <code>false</code> otherwise >+ * @param synthetic <code>true</code> if this search matches a synthetic element >+ * <code>false</code> otherwise >+ * @param superInvocation <code>true</code> if this search matches a super-type invocation >+ * element <code>false</code> otherwise >+ * @param insideDocComment <code>true</code> if this search match is inside a doc >+ * comment, and <code>false</code> otherwise >+ * @param participant the search participant that created the match >+ * @param resource the resource of the element >+ * @since 3.3 >+ */ >+public MethodReferenceMatch(IJavaElement enclosingElement, int accuracy, int offset, int length, boolean constructor, boolean synthetic, boolean superInvocation, boolean insideDocComment, SearchParticipant participant, IResource resource) { >+ this(enclosingElement, accuracy, offset, length, constructor, synthetic, insideDocComment, participant, resource); >+ this.superInvocation = superInvocation; >+} >+ >+/** >+ * Returns whether the reference is on a constructor. >+ * >+ * @return Returns whether the reference is on a constructor or not. >+ * @since 3.1 >+ */ >+public final boolean isConstructor() { >+ return this.constructor; >+} >+ >+/** >+ * Returns whether the reference is on a synthetic element. >+ * Note that this field is only used for constructor reference. This happens when default constructor >+ * declaration is used or implicit super constructor is called. >+ * >+ * @return whether the reference is synthetic or not. >+ * @since 3.1 >+ */ >+public final boolean isSynthetic() { >+ return this.synthetic; >+} >+ >+/** >+ * Returns whether the reference is on a message sent from a type >+ * which is a super type of the searched method declaring type. >+ * If <code>true</code>, the method called at run-time may or may not be >+ * the search target, depending on the run-time type of the receiver object. >+ * >+ * @return <code>true</code> if the reference is on a message sent from >+ * a super-type of the searched method declaring class, <code>false </code> otherwise >+ * @since 3.3 >+ */ >+public boolean isSuperInvocation() { >+ return this.superInvocation; >+} > } >Index: search/org/eclipse/jdt/core/search/TypeReferenceMatch.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/TypeReferenceMatch.java,v >retrieving revision 1.18 >diff -u -r1.18 TypeReferenceMatch.java >--- search/org/eclipse/jdt/core/search/TypeReferenceMatch.java 10 May 2006 18:03:46 -0000 1.18 >+++ search/org/eclipse/jdt/core/search/TypeReferenceMatch.java 21 Mar 2008 15:54:37 -0000 >@@ -11,7 +11,8 @@ > package org.eclipse.jdt.core.search; > > import org.eclipse.core.resources.IResource; >-import org.eclipse.jdt.core.IJavaElement; >+import org.eclipse.jdt.core.*; >+import org.eclipse.jdt.internal.core.search.matching.InternalReferenceMatch; > > /** > * A Java search match that represents a type reference. >@@ -22,75 +23,87 @@ > * > * @since 3.0 > */ >-public class TypeReferenceMatch extends SearchMatch { >+public class TypeReferenceMatch extends InternalReferenceMatch { > >- private IJavaElement localElement; > private IJavaElement[] otherElements; > >- /** >- * Creates a new type reference match. >- * >- * @param enclosingElement the inner-most enclosing member that references this type >- * @param accuracy one of {@link #A_ACCURATE} or {@link #A_INACCURATE} >- * @param offset the offset the match starts at, or -1 if unknown >- * @param length the length of the match, or -1 if unknown >- * @param insideDocComment <code>true</code> if this search match is inside a doc >- * comment, and <code>false</code> otherwise >- * @param participant the search participant that created the match >- * @param resource the resource of the element >- */ >- public TypeReferenceMatch(IJavaElement enclosingElement, int accuracy, int offset, int length, boolean insideDocComment, SearchParticipant participant, IResource resource) { >- super(enclosingElement, accuracy, offset, length, participant, resource); >- setInsideDocComment(insideDocComment); >- } >- >- /** >- * Returns the local element of this search match. >- * This may be a local variable which declaring type is the referenced one >- * or a type parameter which extends it. >- * >- * @return the element of the search match, or <code>null</code> if none or there's >- * no more specific local element than the element itself ({@link SearchMatch#getElement()}). >- * @since 3.2 >- */ >- public final IJavaElement getLocalElement() { >- return this.localElement; >- } >+/** >+ * Creates a new type reference match. >+ * >+ * @param enclosingElement the inner-most enclosing member that references this type >+ * @param accuracy one of {@link #A_ACCURATE} or {@link #A_INACCURATE} >+ * @param offset the offset the match starts at, or -1 if unknown >+ * @param length the length of the match, or -1 if unknown >+ * @param insideDocComment <code>true</code> if this search match is inside a doc >+ * comment, and <code>false</code> otherwise >+ * @param participant the search participant that created the match >+ * @param resource the resource of the element >+ */ >+public TypeReferenceMatch(IJavaElement enclosingElement, int accuracy, int offset, int length, boolean insideDocComment, SearchParticipant participant, IResource resource) { >+ super(enclosingElement, accuracy, offset, length, insideDocComment, participant, resource); >+} > >- /** >- * Returns other enclosing elements of this search match. >- * >- * If {@link #getLocalElement()} is not <code>null</code>, these may be other >- * local elements such as additional local variables of a multiple local >- * variables declaration. Otherwise, these may be other elements such as >- * additional fields of a multiple fields declaration. >- * >- * @return the other elements of the search match, or <code>null</code> if none >- * @since 3.2 >- */ >- public final IJavaElement[] getOtherElements() { >+/** >+ * Returns other elements also enclosing the type reference. This typically can >+ * happen for multiple fields or local variable declarations. >+ *<p> >+ * For example, >+ * <ul> >+ * <li>searching for the references to the type <code>Test</code> in >+ * <pre> >+ * public class Test { >+ * Test test1, test2, test3; >+ * void method() {} >+ * } >+ * </pre> >+ * will return one match whose other elements is an array of two fields: >+ * {@link IField test2} and {@link IField test3}. >+ * </li> >+ * <li>searching for the references to the type <code>Test</code> in >+ * <pre> >+ * public class Test { >+ * String str; >+ * void method() { >+ * Test local1, local2, local3; >+ * } >+ * } >+ * </pre> >+ * will return one match whose other elements is an array of two local >+ * variables: {@link ILocalVariable local2} and {@link ILocalVariable local3}. >+ * </li> >+ * </ul> >+ * >+ * @return the other elements of the search match, or <code>null</code> if none >+ */ >+public final IJavaElement[] getOtherElements() { >+ IJavaElement localElement = super.getLocalElement(); >+ if (localElement == null || localElement.getElementType() != IJavaElement.ANNOTATION) { > return this.otherElements; > } >+ return null; >+} > >- /** >- * Sets the local element of this search match. >- * >- * @param localElement A more specific local element that corresponds to the match, >- * or <code>null</code> if none >- * @since 3.2 >- */ >- public final void setLocalElement(IJavaElement localElement) { >- this.localElement = localElement; >- } >+/** >+ * Sets the local element of this search match. >+ * >+ * @param localElement A more specific local element that corresponds to the match, >+ * or <code>null</code> if none >+ * @since 3.2 >+ */ >+public final void setLocalElement(IJavaElement localElement) { >+ super.setLocalElement(localElement); >+} > >- /** >- * Sets the other elements of this search match. >- * >- * @param otherElements the other elements of the match, >- * or <code>null</code> if none >- * @since 3.2 >- */ >- public final void setOtherElements(IJavaElement[] otherElements) { >- this.otherElements = otherElements; >- } >+/** >+ * Sets the other elements of this search match. >+ * >+ * @see #getOtherElements() >+ * >+ * @param otherElements the other elements of the match, >+ * or <code>null</code> if none >+ * @since 3.2 >+ */ >+public final void setOtherElements(IJavaElement[] otherElements) { >+ this.otherElements = otherElements; >+} > } >Index: buildnotes_jdt-core.html >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/buildnotes_jdt-core.html,v >retrieving revision 1.6364 >diff -u -r1.6364 buildnotes_jdt-core.html >--- buildnotes_jdt-core.html 21 Mar 2008 01:48:49 -0000 1.6364 >+++ buildnotes_jdt-core.html 21 Mar 2008 15:54:37 -0000 >@@ -46,6 +46,89 @@ > <br>Project org.eclipse.jdt.core v_846 > (<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_846">cvs</a>). > <h2>What's new in this drop</h2> >+<li>All search reference matches may now have a local element. Clients can access >+this local element using the <code>getLocalElement()</code> method on the new >+<code>ReferenceMatch</code> API class:<pre> >+ * Returns the local element of this search match, or <code>null</code> if none. >+ * A local element is the inner most element that contains the reference and that is not >+ * reachable by navigating from the root of the {@link IJavaModel} using >+ * {@link IParent#getChildren()}. >+ * >+ * Known element types for local elements are {@link IJavaElement#ANNOTATION}, >+ * {@link IJavaElement#LOCAL_VARIABLE} and {@link IJavaElement#TYPE_PARAMETER}. >+ * However clients should not assume that this set of element types is closed as >+ * other types of elements may be returned in the future, e.g. if new types >+ * of elements are added in the Java model. Clients can only assume that the >+ * {@link IJavaElement#getParent() parent} chain of this local element eventually leads >+ * to the element from {@link #getElement()}. >+ * >+ * The local element being an {@link IAnnotation} is the most usal case. For example, >+ * >+ * . searching for the references to the method <code>Annot.clazz()</code> in >+ * >+ * public class Test { >+ * void method() { >+ * @Annot(clazz=Test.class) int x; >+ * } >+ * } >+ * >+ * will return one {@link MethodReferenceMatch} match whose local element >+ * is the {@link IAnnotation} '<code>Annot</code>'. >+ * >+ * . searching for the references to the type <code>Deprecated</code> in >+ * >+ * public class Test { >+ * @Deprecated void method() {} >+ * } >+ * >+ * will return one {@link TypeReferenceMatch} match whose local element >+ * is the {@link IAnnotation} '<code>Deprecated</code>'. >+ * >+ * . searching for the references to the field <code>CONST</code> in >+ * >+ * @Num(number= Num.CONST) >+ * @interface Num { >+ * public static final int CONST= 42; >+ * int number(); >+ * } >+ * >+ * will return one {@link FieldReferenceMatch} match whose local element >+ * is the {@link IAnnotation} '<code>Num</code>'. >+ * >+ * A local element may also be a {@link ILocalVariable} whose type is the referenced type. For example, >+ * >+ * . searching for the references to the type <code>Test</code> in >+ * >+ * public class Test { >+ * void foo() { >+ * Test local; >+ * } >+ * } >+ * >+ * will return one {@link TypeReferenceMatch} match whose local element >+ * is the {@link ILocalVariable} '<code>local</code>'. >+ * >+ * Or a local element may be an {@link ITypeParameter} that extends the referenced type. For example, >+ * >+ * . searching for the references to the type <code>Test</code> in >+ * >+ * public class X< T extends Test> { >+ * } >+ * >+ * will return one {@link TypeReferenceMatch} match whose local element >+ * is the {@link ITypeParameter} '<code>T</code>'. >+ * >+ * @return the local element of this search match, or <code>null</code> if none. >+ * >+ * @since 3.4 >+ */ >+public IJavaElement getLocalElement() { >+ return null; >+} >+</pre> >+See <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=209996">bug 209996</a> >+for more details. >+</li> > > <h3>Problem Reports Fixed</h3> > <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=223253">223253</a> >@@ -523,6 +606,93 @@ > <br>Project org.eclipse.jdt.core v_838 > (<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_838">cvs</a>). > <h2>What's new in this drop</h2> >+<li>All search reference matches may now have a local element. Clients can access >+this local element using the <code>getLocalElement()</code> method on the new >+<code>ReferenceMatch</code> API class:<pre> >+/** >+ * Returns the local element of this search match. >+ * >+ * By default, a reference match has no local element but in certain circumstances, >+ * it may have one. >+ * >+ * The most usual case is while reporting a reference which is enclosed by an >+ * {@link IJavaElement#ANNOTATION}. >+ * For example, >+ * >+ * . searching for the reference to the method <code>Annot.clazz()</code>: >+ * >+ * public class Test { >+ * void method() { >+ * @Annot(clazz=Test.class) int x; >+ * } >+ * } >+ * >+ * will return one {@link MethodReferenceMatch} match whose local element >+ * is set to the {@link IAnnotation} '<code>Annot</code>'. >+ * >+ * . searching for the reference to the type <code>Deprecated</code>: >+ * >+ * public class Test { >+ * @Deprecated void method() {} >+ * } >+ * >+ * will return one {@link TypeReferenceMatch} match whose local element is >+ * set to the {@link IAnnotation} '<code>Annot</code>'. >+ * >+ * . searching for the reference to the field <code>CONST</code>: >+ * >+ * @Num(number= Num.CONST) >+ * @interface Num { >+ * public static final int CONST= 42; >+ * int number(); >+ * } >+ * >+ * will return one {@link FieldReferenceMatch} match whose local element is >+ * set to the {@link IAnnotation} '<code>Num</code>'. >+ * >+ * This may be also a local variable whose declaring type is the referenced one or >+ * a type parameter which extends it. >+ * For example, >+ * >+ * . searching for the reference to the type <code>Test</code> in the >+ * following snippet: >+ * >+ * public class Test { >+ * void foo() { >+ * Test local; >+ * } >+ * } >+ * >+ * the local element of the returned {@link TypeReferenceMatch} will be >+ * the {@link ILocalVariable} <code>local</code>. >+ * >+ * . searching for the reference to the type <code>Test</code> in the >+ * following snippet: >+ * >+ * public class X< T extends Test> { >+ * } >+ * >+ * the local element of the returned {@link TypeReferenceMatch} will be >+ * the {@link ITypeParameter} <code>T</code>. >+ * >+ * However clients should not assume that this will always be the only cases as >+ * other types of elements may be returned in the future, e.g. if new types >+ * of elements are added in the Java model. >+ * >+ * @return <code>null</code> if the search match does not have any local >+ * element. Otherwise, a Java element whose parent (see >+ * {@link IJavaElement#getParent()}) chain eventually leads to the element >+ * from {@link #getElement()}. >+ >+ * @since 3.4 >+ */ >+public IJavaElement getLocalElement() { >+ return null; >+} >+</pre> >+See <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=209996">bug 209996</a> >+for more details. >+</li> > > <h3>Problem Reports Fixed</h3> > <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=217995">217995</a> >Index: search/org/eclipse/jdt/internal/core/search/matching/ClassFileMatchLocator.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ClassFileMatchLocator.java,v >retrieving revision 1.38 >diff -u -r1.38 ClassFileMatchLocator.java >--- search/org/eclipse/jdt/internal/core/search/matching/ClassFileMatchLocator.java 5 Dec 2007 21:06:57 -0000 1.38 >+++ search/org/eclipse/jdt/internal/core/search/matching/ClassFileMatchLocator.java 21 Mar 2008 15:54:37 -0000 >@@ -307,7 +307,7 @@ > /* > * Look for annotations references > */ >-void matchAnnotations(SearchPattern pattern, MatchLocator locator, ClassFile classFile, IBinaryType binaryType) throws CoreException { >+private void matchAnnotations(SearchPattern pattern, MatchLocator locator, ClassFile classFile, IBinaryType binaryType) throws CoreException { > // Only process TypeReference patterns > switch (((InternalSearchPattern)pattern).kind) { > case TYPE_REF_PATTERN: >@@ -329,7 +329,9 @@ > BinaryTypeBinding binaryTypeBinding = null; > if (checkAnnotations(typeReferencePattern, annotations, binaryType.getTagBits())) { > classFileBinaryType = new ResolvedBinaryType((JavaElement) classFileBinaryType.getParent(), classFileBinaryType.getElementName(), classFileBinaryType.getKey()); >- SearchMatch match = new TypeReferenceMatch(classFileBinaryType, SearchMatch.A_ACCURATE, -1, 0, false, locator.getParticipant(), locator.currentPossibleMatch.resource); >+ TypeReferenceMatch match = new TypeReferenceMatch(classFileBinaryType, SearchMatch.A_ACCURATE, -1, 0, false, locator.getParticipant(), locator.currentPossibleMatch.resource); >+ // TODO 3.4 M7 (frederic) - bug 209996: see how create the annotation handle from the binary and put it in the local element >+ match.setLocalElement(null); > locator.report(match); > } > >@@ -343,7 +345,9 @@ > IMethod methodHandle = classFileBinaryType.getMethod( > new String(method.isConstructor() ? binaryTypeBinding.compoundName[binaryTypeBinding.compoundName.length-1] : method.getSelector()), > CharOperation.toStrings(Signature.getParameterTypes(convertClassFileFormat(method.getMethodDescriptor())))); >- SearchMatch match = new TypeReferenceMatch(methodHandle, SearchMatch.A_ACCURATE, -1, 0, false, locator.getParticipant(), locator.currentPossibleMatch.resource); >+ TypeReferenceMatch match = new TypeReferenceMatch(methodHandle, SearchMatch.A_ACCURATE, -1, 0, false, locator.getParticipant(), locator.currentPossibleMatch.resource); >+ // TODO 3.4 M7 (frederic) - bug 209996: see how create the annotation handle from the binary and put it in the local element >+ match.setLocalElement(null); > locator.report(match); > } > } >@@ -356,7 +360,9 @@ > FieldInfo field = fields[i]; > if (checkAnnotations(typeReferencePattern, field.getAnnotations(), field.getTagBits())) { > IField fieldHandle = classFileBinaryType.getField(new String(field.getName())); >- SearchMatch match = new TypeReferenceMatch(fieldHandle, SearchMatch.A_ACCURATE, -1, 0, false, locator.getParticipant(), locator.currentPossibleMatch.resource); >+ TypeReferenceMatch match = new TypeReferenceMatch(fieldHandle, SearchMatch.A_ACCURATE, -1, 0, false, locator.getParticipant(), locator.currentPossibleMatch.resource); >+ // TODO 3.4 M7 (frederic) - bug 209996: see how create the annotation handle from the binary and put it in the local element >+ match.setLocalElement(null); > locator.report(match); > } > } >Index: search/org/eclipse/jdt/internal/core/search/matching/MethodLocator.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MethodLocator.java,v >retrieving revision 1.80 >diff -u -r1.80 MethodLocator.java >--- search/org/eclipse/jdt/internal/core/search/matching/MethodLocator.java 28 Nov 2007 08:04:10 -0000 1.80 >+++ search/org/eclipse/jdt/internal/core/search/matching/MethodLocator.java 21 Mar 2008 15:54:38 -0000 >@@ -313,10 +313,13 @@ > } > return false; > } >+protected void matchReportReference(ASTNode reference, IJavaElement element, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException { >+ matchReportReference(reference, element, null, null, elementBinding, accuracy, locator); >+} > /** > * @see org.eclipse.jdt.internal.core.search.matching.PatternLocator#matchReportReference(org.eclipse.jdt.internal.compiler.ast.ASTNode, org.eclipse.jdt.core.IJavaElement, Binding, int, org.eclipse.jdt.internal.core.search.matching.MatchLocator) > */ >-protected void matchReportReference(ASTNode reference, IJavaElement element, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException { >+protected void matchReportReference(ASTNode reference, IJavaElement element, IJavaElement localElement, IJavaElement[] otherElements, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException { > MethodBinding methodBinding = (reference instanceof MessageSend) ? ((MessageSend)reference).binding: ((elementBinding instanceof MethodBinding) ? (MethodBinding) elementBinding : null); > if (this.isDeclarationOfReferencedMethodsPattern) { > if (methodBinding == null) return; >@@ -331,7 +334,9 @@ > reportDeclaration(methodBinding, locator, declPattern.knownMethods); > } > } else { >- match = locator.newMethodReferenceMatch(element, elementBinding, accuracy, -1, -1, false /*not constructor*/, false/*not synthetic*/, reference); >+ MethodReferenceMatch methodReferenceMatch = locator.newMethodReferenceMatch(element, elementBinding, accuracy, -1, -1, false /*not constructor*/, false/*not synthetic*/, reference); >+ methodReferenceMatch.setLocalElement(localElement); >+ this.match = methodReferenceMatch; > if (this.pattern.findReferences && reference instanceof MessageSend) { > IJavaElement focus = ((InternalSearchPattern) this.pattern).focus; > // verify closest match if pattern was bound >Index: search/org/eclipse/jdt/internal/core/search/matching/TypeReferenceLocator.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeReferenceLocator.java,v >retrieving revision 1.62 >diff -u -r1.62 TypeReferenceLocator.java >--- search/org/eclipse/jdt/internal/core/search/matching/TypeReferenceLocator.java 26 Feb 2008 11:06:22 -0000 1.62 >+++ search/org/eclipse/jdt/internal/core/search/matching/TypeReferenceLocator.java 21 Mar 2008 15:54:38 -0000 >@@ -332,63 +332,6 @@ > locator.report(match); > } > } >-/** >- * Reports the match of the given reference. Also provide a scope to look for possible local and other elements. >- */ >-protected void matchReportReference(ASTNode reference, IJavaElement element, Binding elementBinding, Scope scope, int accuracy, MatchLocator locator) throws CoreException { >- if (scope == null || (scope.kind != Scope.BLOCK_SCOPE && scope.kind != Scope.METHOD_SCOPE)) { >- matchReportReference(reference, element, elementBinding, accuracy, locator); >- return; >- } >- >- // Look if some block scope local variable declarations include reference start position >- BlockScope blockScope = (BlockScope) scope; >- LocalDeclaration[] localDeclarations = blockScope.findLocalVariableDeclarations(reference.sourceStart); >- IJavaElement localElement = null; >- IJavaElement[] otherElements = null; >- >- // Some local variable declaration are matching >- if (localDeclarations != null) { >- int length = localDeclarations.length; >- >- // Set local element to first matching local declaration >- int idx = 0; >- for (; idx<length; idx++) { >- if (localDeclarations[idx] == null) break; >- if (reference.sourceStart == localDeclarations[idx].declarationSourceStart) { >- localElement = locator.createHandle(localDeclarations[idx], element); >- break; >- } >- if (idx>0 && localDeclarations[idx].sourceStart > reference.sourceStart) { >- localElement = locator.createHandle(localDeclarations[idx-1], element); >- break; >- } >- } >- if (localElement == null && idx > 0) { >- if (reference.sourceEnd < localDeclarations[idx-1].declarationEnd) { >- localElement = locator.createHandle(localDeclarations[idx-1], element); >- } >- } >- >- // Store other local variable declarations in other elements >- int size = 0; >- for (int j=1; j<length; j++) { >- if (localDeclarations[j] == null) break; >- if (reference.sourceStart == localDeclarations[j].declarationSourceStart) { >- if (otherElements == null) { >- otherElements = new IJavaElement[length-j]; >- } >- otherElements[size++] = locator.createHandle(localDeclarations[j], element); >- } >- } >- if (size > 0 && size != (length-1)) { >- System.arraycopy(otherElements, 0, otherElements = new IJavaElement[size], 0, size); >- } >- } >- >- // Report match with local and other elements if any >- matchReportReference(reference, element, localElement, otherElements, elementBinding, accuracy, locator); >-} > protected void matchReportReference(QualifiedNameReference qNameRef, IJavaElement element, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException { > Binding binding = qNameRef.binding; > TypeBinding typeBinding = null; >Index: search/org/eclipse/jdt/internal/core/search/matching/PackageReferenceLocator.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PackageReferenceLocator.java,v >retrieving revision 1.41 >diff -u -r1.41 PackageReferenceLocator.java >--- search/org/eclipse/jdt/internal/core/search/matching/PackageReferenceLocator.java 21 Dec 2007 14:46:11 -0000 1.41 >+++ search/org/eclipse/jdt/internal/core/search/matching/PackageReferenceLocator.java 21 Mar 2008 15:54:38 -0000 >@@ -16,6 +16,7 @@ > import org.eclipse.jdt.core.IPackageFragment; > import org.eclipse.jdt.core.IPackageFragmentRoot; > import org.eclipse.jdt.core.JavaModelException; >+import org.eclipse.jdt.core.search.PackageReferenceMatch; > import org.eclipse.jdt.core.search.SearchPattern; > import org.eclipse.jdt.core.compiler.CharOperation; > import org.eclipse.jdt.internal.compiler.ast.*; >@@ -186,6 +187,9 @@ > } > } > protected void matchReportReference(ASTNode reference, IJavaElement element, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException { >+ matchReportReference(reference, element, null, null, elementBinding, accuracy, locator); >+} >+protected void matchReportReference(ASTNode reference, IJavaElement element, IJavaElement localElement, IJavaElement[] otherElements, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException { > long[] positions = null; > int last = -1; > if (reference instanceof ImportReference) { >@@ -259,8 +263,10 @@ > if (last > positions.length) last = positions.length; > int sourceStart = (int) (positions[0] >>> 32); > int sourceEnd = ((int) positions[last - 1]); >- match = locator.newPackageReferenceMatch(element, accuracy, sourceStart, sourceEnd-sourceStart+1, reference); >- locator.report(match); >+ PackageReferenceMatch packageReferenceMatch = locator.newPackageReferenceMatch(element, accuracy, sourceStart, sourceEnd-sourceStart+1, reference); >+ packageReferenceMatch.setLocalElement(localElement); >+ this.match = packageReferenceMatch; >+ locator.report(this.match); > } > protected int referenceType() { > return IJavaElement.PACKAGE_FRAGMENT; >Index: search/org/eclipse/jdt/internal/core/search/matching/PatternLocator.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PatternLocator.java,v >retrieving revision 1.70 >diff -u -r1.70 PatternLocator.java >--- search/org/eclipse/jdt/internal/core/search/matching/PatternLocator.java 22 Feb 2008 09:49:37 -0000 1.70 >+++ search/org/eclipse/jdt/internal/core/search/matching/PatternLocator.java 21 Mar 2008 15:54:38 -0000 >@@ -398,7 +398,7 @@ > match = locator.newTypeReferenceMatch(element, elementBinding, accuracy, offset, reference.sourceEnd-offset+1, reference); > break; > case IJavaElement.FIELD: >- match = locator.newFieldReferenceMatch(element, elementBinding, accuracy, offset, reference.sourceEnd-offset+1, reference); >+ match = locator.newFieldReferenceMatch(element, null, elementBinding, accuracy, offset, reference.sourceEnd-offset+1, reference); > break; > case IJavaElement.LOCAL_VARIABLE: > match = locator.newLocalVariableReferenceMatch(element, accuracy, offset, reference.sourceEnd-offset+1, reference); >@@ -417,12 +417,6 @@ > protected void matchReportReference(ASTNode reference, IJavaElement element, IJavaElement localElement, IJavaElement[] otherElements, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException { > matchReportReference(reference, element, elementBinding, accuracy, locator); > } >-/** >- * Reports the match of the given reference. Also provide a scope to look for potential other elements. >- */ >-protected void matchReportReference(ASTNode reference, IJavaElement element, Binding elementBinding, Scope scope, int accuracy, MatchLocator locator) throws CoreException { >- matchReportReference(reference, element, elementBinding, accuracy, locator); >-} > public SearchMatch newDeclarationMatch(ASTNode reference, IJavaElement element, Binding elementBinding, int accuracy, int length, MatchLocator locator) { > return locator.newDeclarationMatch(element, elementBinding, accuracy, reference.sourceStart, length); > } >Index: search/org/eclipse/jdt/internal/core/search/matching/FieldLocator.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/FieldLocator.java,v >retrieving revision 1.48 >diff -u -r1.48 FieldLocator.java >--- search/org/eclipse/jdt/internal/core/search/matching/FieldLocator.java 28 Nov 2007 08:04:07 -0000 1.48 >+++ search/org/eclipse/jdt/internal/core/search/matching/FieldLocator.java 21 Mar 2008 15:54:38 -0000 >@@ -137,6 +137,9 @@ > return super.matchReference(node, nodeSet, writeOnlyAccess); > } > protected void matchReportReference(ASTNode reference, IJavaElement element, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException { >+ matchReportReference(reference, element, null, null, elementBinding, accuracy, locator); >+} >+protected void matchReportReference(ASTNode reference, IJavaElement element, IJavaElement localElement, IJavaElement[] otherElements,Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException { > if (this.isDeclarationOfAccessedFieldsPattern) { > // need exact match to be able to open on type ref > if (accuracy != SearchMatch.A_ACCURATE) return; >@@ -166,18 +169,18 @@ > int lastIndex = importRef.tokens.length - 1; > int start = (int) ((positions[lastIndex]) >>> 32); > int end = (int) positions[lastIndex]; >- match = locator.newFieldReferenceMatch(element, elementBinding, accuracy, start, end-start+1, importRef); >+ match = locator.newFieldReferenceMatch(element, localElement, elementBinding, accuracy, start, end-start+1, importRef); > locator.report(match); > } else if (reference instanceof FieldReference) { > FieldReference fieldReference = (FieldReference) reference; > long position = fieldReference.nameSourcePosition; > int start = (int) (position >>> 32); > int end = (int) position; >- match = locator.newFieldReferenceMatch(element, elementBinding, accuracy, start, end-start+1, fieldReference); >+ match = locator.newFieldReferenceMatch(element, localElement, elementBinding, accuracy, start, end-start+1, fieldReference); > locator.report(match); > } else if (reference instanceof SingleNameReference) { > int offset = reference.sourceStart; >- match = locator.newFieldReferenceMatch(element, elementBinding, accuracy, offset, reference.sourceEnd-offset+1, reference); >+ match = locator.newFieldReferenceMatch(element, localElement, elementBinding, accuracy, offset, reference.sourceEnd-offset+1, reference); > locator.report(match); > } else if (reference instanceof QualifiedNameReference) { > QualifiedNameReference qNameRef = (QualifiedNameReference) reference; >@@ -190,14 +193,14 @@ > if (matchesName(this.pattern.name, qNameRef.tokens[indexOfFirstFieldBinding]) && !(nameBinding instanceof LocalVariableBinding)) { > FieldBinding fieldBinding = nameBinding instanceof FieldBinding ? (FieldBinding) nameBinding : null; > if (fieldBinding == null) { >- matches[indexOfFirstFieldBinding] = locator.newFieldReferenceMatch(element, elementBinding, accuracy, -1, -1, reference); >+ matches[indexOfFirstFieldBinding] = locator.newFieldReferenceMatch(element, localElement, elementBinding, accuracy, -1, -1, reference); > } else { > switch (matchField(fieldBinding, false)) { > case ACCURATE_MATCH: >- matches[indexOfFirstFieldBinding] = locator.newFieldReferenceMatch(element, elementBinding, SearchMatch.A_ACCURATE, -1, -1, reference); >+ matches[indexOfFirstFieldBinding] = locator.newFieldReferenceMatch(element, localElement, elementBinding, SearchMatch.A_ACCURATE, -1, -1, reference); > break; > case INACCURATE_MATCH: >- match = locator.newFieldReferenceMatch(element, elementBinding, SearchMatch.A_INACCURATE, -1, -1, reference); >+ match = locator.newFieldReferenceMatch(element, localElement, elementBinding, SearchMatch.A_INACCURATE, -1, -1, reference); > if (fieldBinding.type != null && fieldBinding.type.isParameterizedType() && this.pattern.hasTypeArguments()) { > updateMatch((ParameterizedTypeBinding) fieldBinding.type, this.pattern.getTypeArguments(), locator); > } >@@ -213,14 +216,14 @@ > if (matchesName(this.pattern.name, token)) { > FieldBinding otherBinding = qNameRef.otherBindings == null ? null : qNameRef.otherBindings[i-(indexOfFirstFieldBinding+1)]; > if (otherBinding == null) { >- matches[i] = locator.newFieldReferenceMatch(element, elementBinding, accuracy, -1, -1, reference); >+ matches[i] = locator.newFieldReferenceMatch(element, localElement, elementBinding, accuracy, -1, -1, reference); > } else { > switch (matchField(otherBinding, false)) { > case ACCURATE_MATCH: >- matches[i] = locator.newFieldReferenceMatch(element, elementBinding, SearchMatch.A_ACCURATE, -1, -1, reference); >+ matches[i] = locator.newFieldReferenceMatch(element, localElement, elementBinding, SearchMatch.A_ACCURATE, -1, -1, reference); > break; > case INACCURATE_MATCH: >- match = locator.newFieldReferenceMatch(element, elementBinding, SearchMatch.A_INACCURATE, -1, -1, reference); >+ match = locator.newFieldReferenceMatch(element, localElement, elementBinding, SearchMatch.A_INACCURATE, -1, -1, reference); > if (otherBinding.type != null && otherBinding.type.isParameterizedType() && this.pattern.hasTypeArguments()) { > updateMatch((ParameterizedTypeBinding) otherBinding.type, this.pattern.getTypeArguments(), locator); > } >Index: search/org/eclipse/jdt/internal/core/search/matching/AndLocator.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/AndLocator.java,v >retrieving revision 1.1 >diff -u -r1.1 AndLocator.java >--- search/org/eclipse/jdt/internal/core/search/matching/AndLocator.java 4 Jul 2007 13:59:58 -0000 1.1 >+++ search/org/eclipse/jdt/internal/core/search/matching/AndLocator.java 21 Mar 2008 15:54:37 -0000 >@@ -214,7 +214,7 @@ > } > weakestPattern.matchReportImportRef(importRef, binding, element, accuracy, locator); > } >-protected void matchReportReference(ASTNode reference, IJavaElement element, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException { >+protected void matchReportReference(ASTNode reference, IJavaElement element, IJavaElement localElement, IJavaElement[] otherElements, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException { > PatternLocator weakestPattern = null; > int level = IMPOSSIBLE_MATCH; > for (int i = 0, length = this.patternLocators.length; i < length; i++) { >@@ -226,7 +226,7 @@ > level = newLevel; > } > } >- weakestPattern.matchReportReference(reference, element, elementBinding, accuracy, locator); >+ weakestPattern.matchReportReference(reference, element, localElement, otherElements, elementBinding, accuracy, locator); > } > public int resolveLevel(ASTNode node) { > int level = ACCURATE_MATCH; >Index: search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java,v >retrieving revision 1.311 >diff -u -r1.311 MatchLocator.java >--- search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java 4 Mar 2008 10:52:04 -0000 1.311 >+++ search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java 21 Mar 2008 15:54:38 -0000 >@@ -21,6 +21,8 @@ > import org.eclipse.core.resources.IResource; > import org.eclipse.core.runtime.*; > import org.eclipse.jdt.core.Flags; >+import org.eclipse.jdt.core.IAnnotatable; >+import org.eclipse.jdt.core.IAnnotation; > import org.eclipse.jdt.core.IClassFile; > import org.eclipse.jdt.core.IJavaElement; > import org.eclipse.jdt.core.IJavaModelStatusConstants; >@@ -35,7 +37,6 @@ > import org.eclipse.jdt.core.Signature; > import org.eclipse.jdt.core.compiler.*; > import org.eclipse.jdt.core.search.*; >-import org.eclipse.jdt.internal.compiler.ASTVisitor; > import org.eclipse.jdt.internal.compiler.CompilationResult; > import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies; > import org.eclipse.jdt.internal.compiler.ast.*; >@@ -48,7 +49,6 @@ > import org.eclipse.jdt.internal.compiler.lookup.*; > import org.eclipse.jdt.internal.compiler.parser.*; > import org.eclipse.jdt.internal.compiler.problem.*; >-import org.eclipse.jdt.internal.compiler.util.HashtableOfIntValues; > import org.eclipse.jdt.internal.compiler.util.Messages; > import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable; > import org.eclipse.jdt.internal.compiler.util.SimpleSet; >@@ -146,46 +146,6 @@ > > private final boolean searchPackageDeclaration; > >-/** >- * An ast visitor that visits local type declarations. >- */ >-public class LocalDeclarationVisitor extends ASTVisitor { >- IJavaElement enclosingElement; >- Binding enclosingElementBinding; >- MatchingNodeSet nodeSet; >- HashtableOfIntValues occurrencesCounts = new HashtableOfIntValues(); // key = class name (char[]), value = occurrenceCount (int) >- public LocalDeclarationVisitor(IJavaElement enclosingElement, Binding enclosingElementBinding, MatchingNodeSet nodeSet) { >- this.enclosingElement = enclosingElement; >- this.enclosingElementBinding = enclosingElementBinding; >- this.nodeSet = nodeSet; >- } >- public boolean visit(TypeDeclaration typeDeclaration, BlockScope unused) { >- try { >- char[] simpleName; >- if ((typeDeclaration.bits & ASTNode.IsAnonymousType) != 0) { >- simpleName = CharOperation.NO_CHAR; >- } else { >- simpleName = typeDeclaration.name; >- } >- int occurrenceCount = occurrencesCounts.get(simpleName); >- if (occurrenceCount == HashtableOfIntValues.NO_VALUE) { >- occurrenceCount = 1; >- } else { >- occurrenceCount = occurrenceCount + 1; >- } >- occurrencesCounts.put(simpleName, occurrenceCount); >- if ((typeDeclaration.bits & ASTNode.IsAnonymousType) != 0) { >- reportMatching(typeDeclaration, this.enclosingElement, -1, nodeSet, occurrenceCount); >- } else { >- Integer level = (Integer) nodeSet.matchingNodes.removeKey(typeDeclaration); >- reportMatching(typeDeclaration, this.enclosingElement, level != null ? level.intValue() : -1, nodeSet, occurrenceCount); >- } >- return false; // don't visit members as this was done during reportMatching(...) >- } catch (CoreException e) { >- throw new WrappedCoreException(e); >- } >- } >-} > public static class WorkingCopyDocument extends JavaSearchDocument { > public org.eclipse.jdt.core.ICompilationUnit workingCopy; > WorkingCopyDocument(org.eclipse.jdt.core.ICompilationUnit workingCopy, SearchParticipant participant) { >@@ -600,7 +560,7 @@ > return ((IType) parent).getInitializer(occurrenceCount); > } > /** >- * Create an handle for a local variable declartion (may be a local variable or type parameter). >+ * Create an handle for a local variable declaration (may be a local variable or type parameter). > */ > protected IJavaElement createHandle(AbstractVariableDeclaration variableDeclaration, IJavaElement parent) { > switch (variableDeclaration.getKind()) { >@@ -629,6 +589,28 @@ > } > return null; > } >+/** >+ * Create an handle for a local variable declaration (may be a local variable or type parameter). >+ */ >+protected IJavaElement createHandle(Annotation annotation, IAnnotatable parent) { >+ if (parent == null) return null; >+ TypeReference typeRef = annotation.type; >+ char[][] typeName = typeRef.getTypeName(); >+ String name = new String(typeName[typeName.length-1]); >+ try { >+ IAnnotation[] annotations = parent.getAnnotations(); >+ int length = annotations == null ? 0 : annotations.length; >+ for (int i=0; i<length; i++) { >+ if (annotations[i].getElementName().equals(name)) { >+ return annotations[i]; >+ } >+ } >+ } >+ catch (JavaModelException jme) { >+ // skip >+ } >+ return null; >+} > /* > * Creates hierarchy resolver if needed. > * Returns whether focus is visible. >@@ -1387,13 +1369,13 @@ > } > } > >-public SearchMatch newFieldReferenceMatch( >+public FieldReferenceMatch newFieldReferenceMatch( > IJavaElement enclosingElement, >+ IJavaElement localElement, > Binding enclosingBinding, >- int accuracy, >- int offset, >- int length, >- ASTNode reference) { >+ int accuracy, >+ int offset, >+ int length, ASTNode reference) { > int bits = reference.bits; > boolean isCompoundAssigned = (bits & ASTNode.IsCompoundAssigned) != 0; > boolean isReadAccess = isCompoundAssigned || (bits & ASTNode.IsStrictlyAssigned) == 0; >@@ -1411,9 +1393,12 @@ > boolean insideDocComment = (bits & ASTNode.InsideJavadoc) != 0; > SearchParticipant participant = getParticipant(); > IResource resource = this.currentPossibleMatch.resource; >- if (enclosingBinding != null) >+ if (enclosingBinding != null) { > enclosingElement = ((JavaElement) enclosingElement).resolved(enclosingBinding); >- return new FieldReferenceMatch(enclosingElement, accuracy, offset, length, isReadAccess, isWriteAccess, insideDocComment, participant, resource); >+ } >+ FieldReferenceMatch match = new FieldReferenceMatch(enclosingElement, accuracy, offset, length, isReadAccess, isWriteAccess, insideDocComment, participant, resource); >+ match.setLocalElement(localElement); >+ return match; > } > > public SearchMatch newLocalVariableReferenceMatch( >@@ -1442,7 +1427,7 @@ > return new LocalVariableReferenceMatch(enclosingElement, accuracy, offset, length, isReadAccess, isWriteAccess, insideDocComment, participant, resource); > } > >-public SearchMatch newMethodReferenceMatch( >+public MethodReferenceMatch newMethodReferenceMatch( > IJavaElement enclosingElement, > Binding enclosingBinding, > int accuracy, >@@ -1460,7 +1445,7 @@ > return new MethodReferenceMatch(enclosingElement, accuracy, offset, length, isConstructor, isSynthetic, isOverridden, insideDocComment, participant, resource); > } > >-public SearchMatch newPackageReferenceMatch( >+public PackageReferenceMatch newPackageReferenceMatch( > IJavaElement enclosingElement, > int accuracy, > int offset, >@@ -2073,14 +2058,29 @@ > > // handle nodes for the local type first > if ((method.bits & ASTNode.HasLocalType) != 0) { >- if (enclosingElement == null) >+ if (enclosingElement == null) { > enclosingElement = createHandle(method, parent); >- LocalDeclarationVisitor localDeclarationVisitor = new LocalDeclarationVisitor(enclosingElement, method.binding, nodeSet); >+ } >+ // Traverse method declaration to report matches both in local types declaration >+ // and in local variables declaration >+ ASTNode[] nodes = typeInHierarchy ? nodeSet.matchingNodes(method.declarationSourceStart, method.declarationSourceEnd) : null; >+ boolean report = (this.matchContainer & PatternLocator.METHOD_CONTAINER) != 0 && encloses(enclosingElement); >+ MemberDeclarationVisitor declarationVisitor = new MemberDeclarationVisitor(enclosingElement, report ? nodes : null, nodeSet, this); > try { >- method.traverse(localDeclarationVisitor, (ClassScope) null); >+ method.traverse(declarationVisitor, (ClassScope) null); > } catch (WrappedCoreException e) { > throw e.coreException; > } >+ // Report all nodes and remove them >+ if (nodes != null) { >+ int length = nodes.length; >+ for (int i = 0; i < length; i++) { >+ Integer level = (Integer) nodeSet.matchingNodes.removeKey(nodes[i]); >+ if (report && level != null) { >+ this.patternLocator.matchReportReference(nodes[i], enclosingElement, declarationVisitor.getLocalElement(i), declarationVisitor.getOtherElements(i), method.binding, level.intValue(), this); >+ } >+ } >+ } > } > > // report the type parameters >@@ -2105,13 +2105,25 @@ > ASTNode[] nodes = nodeSet.matchingNodes(method.declarationSourceStart, method.declarationSourceEnd); > if (nodes != null) { > if ((this.matchContainer & PatternLocator.METHOD_CONTAINER) != 0) { >- if (enclosingElement == null) >+ if (enclosingElement == null) { > enclosingElement = createHandle(method, parent); >+ } > if (encloses(enclosingElement)) { >- for (int i = 0, l = nodes.length; i < l; i++) { >- ASTNode node = nodes[i]; >- Integer level = (Integer) nodeSet.matchingNodes.removeKey(node); >- this.patternLocator.matchReportReference(node, enclosingElement, method.binding, method.scope, level.intValue(), this); >+ if (((InternalSearchPattern)this.pattern).mustResolve) { >+ // Visit only if the pattern must resolve >+ MemberDeclarationVisitor declarationVisitor = new MemberDeclarationVisitor(enclosingElement, nodes, nodeSet, this); >+ method.traverse(declarationVisitor, (ClassScope) null); >+ int length = nodes.length; >+ for (int i = 0; i < length; i++) { >+ Integer level = (Integer) nodeSet.matchingNodes.removeKey(nodes[i]); >+ this.patternLocator.matchReportReference(nodes[i], enclosingElement, declarationVisitor.getLocalElement(i), declarationVisitor.getOtherElements(i), method.binding, level.intValue(), this); >+ } >+ } else { >+ for (int i = 0, l = nodes.length; i < l; i++) { >+ ASTNode node = nodes[i]; >+ Integer level = (Integer) nodeSet.matchingNodes.removeKey(node); >+ this.patternLocator.matchReportReference(node, enclosingElement, null, null, method.binding, level.intValue(), this); >+ } > } > return; > } >@@ -2129,12 +2141,14 @@ > protected void reportMatching(Annotation[] annotations, IJavaElement enclosingElement, Binding elementBinding, MatchingNodeSet nodeSet, boolean matchedContainer, boolean enclosesElement) throws CoreException { > for (int i=0, al=annotations.length; i<al; i++) { > Annotation annotationType = annotations[i]; >+ IJavaElement localElement = null; > > // Look for annotation type ref > TypeReference typeRef = annotationType.type; > Integer level = (Integer) nodeSet.matchingNodes.removeKey(typeRef); > if (level != null && matchedContainer) { >- this.patternLocator.matchReportReference(typeRef, enclosingElement, elementBinding, level.intValue(), this); >+ localElement = createHandle(annotationType, (IAnnotatable) enclosingElement); >+ this.patternLocator.matchReportReference(typeRef, enclosingElement, localElement, null, elementBinding, level.intValue(), this); > } > > // Look for attribute ref >@@ -2144,7 +2158,10 @@ > level = (Integer) nodeSet.matchingNodes.removeKey(pair); > if (level != null && enclosesElement) { > ASTNode reference = (annotationType instanceof SingleMemberAnnotation) ? (ASTNode) annotationType: pair; >- this.patternLocator.matchReportReference(reference, enclosingElement, pair.binding, level.intValue(), this); >+ if (localElement == null) { >+ localElement = createHandle(annotationType, (IAnnotatable) enclosingElement); >+ } >+ this.patternLocator.matchReportReference(reference, enclosingElement, localElement, null, pair.binding, level.intValue(), this); > } > } > >@@ -2160,7 +2177,10 @@ > ASTNode node = nodes[j]; > level = (Integer) nodeSet.matchingNodes.removeKey(node); > if (enclosesElement) { >- this.patternLocator.matchReportReference(node, enclosingElement, elementBinding, level.intValue(), this); >+ if (localElement == null) { >+ localElement = createHandle(annotationType, (IAnnotatable) enclosingElement); >+ } >+ this.patternLocator.matchReportReference(node, enclosingElement, localElement, null, elementBinding, level.intValue(), this); > } > } > } >@@ -2235,7 +2255,7 @@ > ASTNode node = nodes[i]; > Integer level = (Integer) nodeSet.matchingNodes.removeKey(node); > if (encloses(element)) { >- this.patternLocator.matchReportReference(node, element, null/*no binding*/, level.intValue(), this); >+ this.patternLocator.matchReportReference(node, element, null, null, null/*no binding*/, level.intValue(), this); > } > } > } >@@ -2300,14 +2320,38 @@ > > // handle the nodes for the local type first > if ((field.bits & ASTNode.HasLocalType) != 0) { >- if (enclosingElement == null) >+ if (enclosingElement == null) { > enclosingElement = createHandle(field, type, parent); >- LocalDeclarationVisitor localDeclarationVisitor = new LocalDeclarationVisitor(enclosingElement, field.binding, nodeSet); >+ } >+ // Traverse field declaration(s) to report matches both in local types declaration >+ // and in local variables declaration >+ int fieldEnd = field.endPart2Position == 0 ? field.declarationSourceEnd : field.endPart2Position; >+ ASTNode[] nodes = typeInHierarchy ? nodeSet.matchingNodes(field.sourceStart, fieldEnd) : null; >+ boolean report = (this.matchContainer & PatternLocator.FIELD_CONTAINER) != 0 && encloses(enclosingElement); >+ MemberDeclarationVisitor declarationVisitor = new MemberDeclarationVisitor(enclosingElement, report ? nodes : null, nodeSet, this); > try { >- field.traverse(localDeclarationVisitor, null); >+ field.traverse(declarationVisitor, (MethodScope) null); > } catch (WrappedCoreException e) { > throw e.coreException; > } >+ // Report all nodes and remove them >+ if (nodes != null) { >+ int length = nodes.length; >+ for (int i = 0; i < length; i++) { >+ ASTNode node = nodes[i]; >+ Integer level = (Integer) nodeSet.matchingNodes.removeKey(node); >+ if (report && level != null) { >+ if (node instanceof TypeDeclaration) { >+ // use field declaration to report match (see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=88174) >+ AllocationExpression allocation = ((TypeDeclaration)node).allocation; >+ if (allocation != null && allocation.enumConstant != null) { >+ node = field; >+ } >+ } >+ this.patternLocator.matchReportReference(node, enclosingElement, declarationVisitor.getLocalElement(i), declarationVisitor.getOtherElements(i), field.binding, level.intValue(), this); >+ } >+ } >+ } > } > > // report annotations >@@ -2357,14 +2401,18 @@ > ASTNode[] nodes = nodeSet.matchingNodes(field.sourceStart, fieldEnd); > if (nodes != null) { > if ((this.matchContainer & PatternLocator.FIELD_CONTAINER) == 0) { >- for (int i = 0, l = nodes.length; i < l; i++) >+ for (int i = 0, l = nodes.length; i < l; i++) { > nodeSet.matchingNodes.removeKey(nodes[i]); >+ } > } else { > if (enclosingElement == null) { > enclosingElement = createHandle(field, type, parent); > } > if (encloses(enclosingElement)) { >- for (int i = 0, l = nodes.length; i < l; i++) { >+ MemberDeclarationVisitor declarationVisitor = new MemberDeclarationVisitor(enclosingElement, nodes, nodeSet, this); >+ field.traverse(declarationVisitor, (MethodScope) null); >+ int length = nodes.length; >+ for (int i = 0; i < length; i++) { > ASTNode node = nodes[i]; > Integer level = (Integer) nodeSet.matchingNodes.removeKey(node); > if (node instanceof TypeDeclaration) { >@@ -2374,13 +2422,7 @@ > node = field; > } > } >- // Set block scope for initializer in case there would have other local and other elements to report >- BlockScope blockScope = null; >- if (field.getKind() == AbstractVariableDeclaration.INITIALIZER) { >- Block block = ((Initializer)field).block; >- if (block != null) blockScope = block.scope; >- } >- this.patternLocator.matchReportReference(node, enclosingElement, field.binding, blockScope, level.intValue(), this); >+ this.patternLocator.matchReportReference(node, enclosingElement, declarationVisitor.getLocalElement(i), declarationVisitor.getOtherElements(i), field.binding, level.intValue(), this); > } > return; > } >@@ -2441,7 +2483,7 @@ > ASTNode node = nodes[i]; > Integer level = (Integer) nodeSet.matchingNodes.removeKey(node); > if (enclosesElement) { >- this.patternLocator.matchReportReference(node, enclosingElement, type.binding, level.intValue(), this); >+ this.patternLocator.matchReportReference(node, enclosingElement, null, null, type.binding, level.intValue(), this); > } > } > } >@@ -2454,7 +2496,7 @@ > if (superType != null) { > Integer level = (Integer) nodeSet.matchingNodes.removeKey(superType); > if (level != null && matchedClassContainer) >- this.patternLocator.matchReportReference(superType, enclosingElement, type.binding, level.intValue(), this); >+ this.patternLocator.matchReportReference(superType, enclosingElement, null, null, type.binding, level.intValue(), this); > } > } else { > TypeReference superClass = type.superclass; >@@ -2639,13 +2681,13 @@ > for (int i = 0, l = nodes.length; i < l; i++) { > ASTNode node = nodes[i]; > Integer level = (Integer) nodeSet.matchingNodes.removeKey(node); >- this.patternLocator.matchReportReference(node, enclosingElement, elementBinding, level.intValue(), this); >+ this.patternLocator.matchReportReference(node, enclosingElement, null, null, elementBinding, level.intValue(), this); > } > } > } else if (encloses(enclosingElement)) { > Integer level = (Integer) nodeSet.matchingNodes.removeKey(superReference); > if (level != null && matchedClassContainer) >- this.patternLocator.matchReportReference(superReference, enclosingElement, elementBinding, level.intValue(), this); >+ this.patternLocator.matchReportReference(superReference, enclosingElement, null, null, elementBinding, level.intValue(), this); > } > } > protected boolean typeInHierarchy(ReferenceBinding binding) { >Index: search/org/eclipse/jdt/internal/core/search/matching/OrLocator.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/OrLocator.java,v >retrieving revision 1.20 >diff -u -r1.20 OrLocator.java >--- search/org/eclipse/jdt/internal/core/search/matching/OrLocator.java 4 Jul 2007 13:59:58 -0000 1.20 >+++ search/org/eclipse/jdt/internal/core/search/matching/OrLocator.java 21 Mar 2008 15:54:38 -0000 >@@ -249,7 +249,7 @@ > if (closestPattern != null) > closestPattern.matchReportImportRef(importRef, binding, element, accuracy, locator); > } >-protected void matchReportReference(ASTNode reference, IJavaElement element, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException { >+protected void matchReportReference(ASTNode reference, IJavaElement element, IJavaElement localElement, IJavaElement[] otherElements, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException { > PatternLocator closestPattern = null; > int level = IMPOSSIBLE_MATCH; > for (int i = 0, length = this.patternLocators.length; i < length; i++) { >@@ -262,7 +262,7 @@ > } > } > if (closestPattern != null) >- closestPattern.matchReportReference(reference, element, elementBinding, accuracy, locator); >+ closestPattern.matchReportReference(reference, element, localElement, otherElements, elementBinding, accuracy, locator); > } > public SearchMatch newDeclarationMatch(ASTNode reference, IJavaElement element, Binding elementBinding, int accuracy, int length, MatchLocator locator) { > PatternLocator closestPattern = null; >Index: search/org/eclipse/jdt/internal/core/search/matching/MemberDeclarationVisitor.java >=================================================================== >RCS file: search/org/eclipse/jdt/internal/core/search/matching/MemberDeclarationVisitor.java >diff -N search/org/eclipse/jdt/internal/core/search/matching/MemberDeclarationVisitor.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ search/org/eclipse/jdt/internal/core/search/matching/MemberDeclarationVisitor.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,269 @@ >+/******************************************************************************* >+ * Copyright (c) 2000, 2008 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jdt.internal.core.search.matching; >+ >+import org.eclipse.core.runtime.CoreException; >+import org.eclipse.jdt.core.IAnnotatable; >+import org.eclipse.jdt.core.IJavaElement; >+import org.eclipse.jdt.core.compiler.CharOperation; >+import org.eclipse.jdt.internal.compiler.ASTVisitor; >+import org.eclipse.jdt.internal.compiler.ast.*; >+import org.eclipse.jdt.internal.compiler.lookup.BlockScope; >+import org.eclipse.jdt.internal.compiler.util.HashtableOfIntValues; >+import org.eclipse.jdt.internal.core.search.matching.MatchLocator.WrappedCoreException; >+ >+/** >+ * Specific visitor of field or method declaration which can identify and store >+ * the local and other elements of one or several matching nodes. >+ * <p> >+ * This visitor can also peek up local or anonymous type declaration and restart >+ * a new {@link MatchLocator} traverse on this type. >+ * </p> >+ */ >+class MemberDeclarationVisitor extends ASTVisitor { >+ // Matches information >+ private final MatchLocator locator; >+ private final IJavaElement enclosingElement; >+ private final MatchingNodeSet nodeSet; >+ private final ASTNode[] matchingNodes; >+ private final ASTNode matchingNode; >+ >+ // Local type storage >+ HashtableOfIntValues occurrencesCounts = new HashtableOfIntValues(); // key = class name (char[]), value = occurrenceCount (int) >+ int nodesCount = 0; >+ >+ // Local and other elements storage >+ IJavaElement currentDeclaration; >+ private Annotation annotation; >+ private LocalDeclaration localDeclaration; >+ IJavaElement localElement; >+ IJavaElement[] localElements, otherElements; >+ IJavaElement[][] allOtherElements; >+ int ptr = -1; >+ int[] ptrs; >+ >+public MemberDeclarationVisitor(IJavaElement element, ASTNode[] nodes, MatchingNodeSet set, MatchLocator locator) { >+ this.enclosingElement = element; >+ this.nodeSet = set; >+ this.locator = locator; >+ if (nodes == null) { >+ this.matchingNode = null; >+ this.matchingNodes = null; >+ } else { >+ this.nodesCount = nodes.length; >+ if (nodes.length == 1) { >+ this.matchingNode = nodes[0]; >+ this.matchingNodes = null; >+ } else { >+ this.matchingNode = null; >+ this.matchingNodes = nodes; >+ this.localElements = new IJavaElement[this.nodesCount]; >+ this.ptrs = new int[this.nodesCount]; >+ this.allOtherElements = new IJavaElement[this.nodesCount][]; >+ } >+ } >+} >+public void endVisit(Argument argument, BlockScope scope) { >+ this.localDeclaration = null; >+} >+public void endVisit(LocalDeclaration declaration, BlockScope scope) { >+ this.localDeclaration = null; >+} >+public void endVisit(MarkerAnnotation markerAnnotation, BlockScope unused) { >+ this.annotation = null; >+} >+public void endVisit(NormalAnnotation normalAnnotation, BlockScope unused) { >+ this.annotation = null; >+} >+public void endVisit(SingleMemberAnnotation singleMemberAnnotation, BlockScope unused) { >+ this.annotation = null; >+} >+IJavaElement getLocalElement(int idx) { >+ if (this.nodesCount == 1) { >+ return this.localElement; >+ } >+ if (this.localElements != null) { >+ return this.localElements[idx]; >+ } >+ return null; >+} >+IJavaElement[] getOtherElements(int idx) { >+ if (this.nodesCount == 1) { >+ if (this.otherElements != null) { >+ int length = this.otherElements.length; >+ if (this.ptr < (length-1)) { >+ System.arraycopy(this.otherElements, 0, this.otherElements = new IJavaElement[this.ptr+1], 0, this.ptr+1); >+ } >+ } >+ return this.otherElements; >+ } >+ IJavaElement[] elements = this.allOtherElements == null ? null : this.allOtherElements[idx]; >+ if (elements != null) { >+ int length = elements.length; >+ if (this.ptrs[idx] < (length-1)) { >+ System.arraycopy(elements, 0, elements = this.allOtherElements[idx] = new IJavaElement[this.ptrs[idx]+1], 0, this.ptrs[idx]+1); >+ } >+ } >+ return elements; >+} >+private int matchNode(ASTNode reference) { >+ if (this.matchingNode != null) { >+ if (this.matchingNode == reference) return 0; >+ } else { >+ int length = this.matchingNodes.length; >+ for (int i=0; i<length; i++) { >+ if (this.matchingNodes[i] == reference) { // == is intentional >+ return i; >+ } >+ } >+ } >+ return -1; >+} >+/* >+ * Store the handle for the reference of the given index (e.g. peek in #matchingNodes >+ * or #matchingNode). >+ * Note that for performance reason, matching node and associated handles are >+ * not stored in array when there's only one reference to identify. >+ */ >+private void storeHandle(int idx) { >+ if (this.localDeclaration == null) return; >+ IJavaElement handle = locator.createHandle(this.localDeclaration, this.enclosingElement); >+ if (this.nodesCount == 1) { >+ if (this.localElement == null) { >+ if (this.annotation == null) { >+ this.localElement = handle; >+ } else { >+ IJavaElement annotHandle = this.locator.createHandle(this.annotation, (IAnnotatable) handle); >+ if (annotHandle == null) { >+ annotHandle = this.locator.createHandle(this.annotation, (IAnnotatable) this.enclosingElement); >+ } >+ this.localElement = annotHandle == null ? handle : annotHandle; >+ } >+ } else { >+ if (++this.ptr == 0) { >+ this.otherElements = new IJavaElement[10]; >+ } else { >+ int length = this.otherElements.length; >+ if (this.ptr == length) { >+ System.arraycopy(this.otherElements, 0, this.otherElements = new IJavaElement[length+10], 0, length); >+ } >+ } >+ this.otherElements[this.ptr] = handle; >+ } >+ } else { >+ if (this.localElements[idx] == null) { >+ if (this.annotation == null) { >+ this.localElements[idx] = handle; >+ } else { >+ IJavaElement annotHandle = locator.createHandle(this.annotation, (IAnnotatable) handle); >+ if (annotHandle == null) { >+ annotHandle = locator.createHandle(this.annotation, (IAnnotatable) this.enclosingElement); >+ } >+ this.localElements[idx] = annotHandle == null ? handle : annotHandle; >+ } >+ this.ptrs[idx] = -1; >+ } else { >+ int oPtr = ++this.ptrs[idx]; >+ if (oPtr== 0) { >+ this.allOtherElements[idx] = new IJavaElement[10]; >+ } else { >+ int length = this.allOtherElements[idx].length; >+ if (oPtr == length) { >+ System.arraycopy(this.allOtherElements[idx], 0, this.allOtherElements[idx] = new IJavaElement[length+10], 0, length); >+ } >+ } >+ this.allOtherElements[idx][oPtr] = handle; >+ } >+ } >+} >+public boolean visit(Argument argument, BlockScope scope) { >+ this.localDeclaration = argument; >+ return true; >+} >+public boolean visit(LocalDeclaration declaration, BlockScope scope) { >+ this.localDeclaration = declaration; >+ return true; >+} >+public boolean visit(MarkerAnnotation markerAnnotation, BlockScope unused) { >+ this.annotation = markerAnnotation; >+ return true; >+} >+public boolean visit(NormalAnnotation normalAnnotation, BlockScope unused) { >+ this.annotation = normalAnnotation; >+ return true; >+} >+public boolean visit(QualifiedNameReference nameReference, BlockScope unused) { >+ if (this.nodesCount > 0){ >+ int idx = matchNode(nameReference); >+ if (idx >= 0) { >+ storeHandle(idx); >+ } >+ } >+ return false; >+} >+public boolean visit(QualifiedTypeReference typeReference, BlockScope unused) { >+ if (this.nodesCount > 0){ >+ int idx = matchNode(typeReference); >+ if (idx >= 0) { >+ storeHandle(idx); >+ } >+ } >+ return false; >+} >+public boolean visit(SingleMemberAnnotation singleMemberAnnotation, BlockScope unused) { >+ this.annotation = singleMemberAnnotation; >+ return true; >+} >+public boolean visit(SingleNameReference nameReference, BlockScope unused) { >+ if (this.nodesCount > 0){ >+ int idx = matchNode(nameReference); >+ if (idx >= 0) { >+ storeHandle(idx); >+ } >+ } >+ return false; >+} >+public boolean visit(SingleTypeReference typeReference, BlockScope unused) { >+ if (this.nodesCount > 0){ >+ int idx = matchNode(typeReference); >+ if (idx >= 0) { >+ storeHandle(idx); >+ } >+ } >+ return false; >+} >+public boolean visit(TypeDeclaration typeDeclaration, BlockScope unused) { >+ try { >+ char[] simpleName; >+ if ((typeDeclaration.bits & ASTNode.IsAnonymousType) != 0) { >+ simpleName = CharOperation.NO_CHAR; >+ } else { >+ simpleName = typeDeclaration.name; >+ } >+ int occurrenceCount = occurrencesCounts.get(simpleName); >+ if (occurrenceCount == HashtableOfIntValues.NO_VALUE) { >+ occurrenceCount = 1; >+ } else { >+ occurrenceCount = occurrenceCount + 1; >+ } >+ occurrencesCounts.put(simpleName, occurrenceCount); >+ if ((typeDeclaration.bits & ASTNode.IsAnonymousType) != 0) { >+ this.locator.reportMatching(typeDeclaration, this.enclosingElement, -1, nodeSet, occurrenceCount); >+ } else { >+ Integer level = (Integer) nodeSet.matchingNodes.removeKey(typeDeclaration); >+ this.locator.reportMatching(typeDeclaration, this.enclosingElement, level != null ? level.intValue() : -1, nodeSet, occurrenceCount); >+ } >+ return false; // don't visit members as this was done during reportMatching(...) >+ } catch (CoreException e) { >+ throw new WrappedCoreException(e); >+ } >+} >+} >Index: search/org/eclipse/jdt/core/search/ReferenceMatch.java >=================================================================== >RCS file: search/org/eclipse/jdt/core/search/ReferenceMatch.java >diff -N search/org/eclipse/jdt/core/search/ReferenceMatch.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ search/org/eclipse/jdt/core/search/ReferenceMatch.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,122 @@ >+/******************************************************************************* >+ * Copyright (c) 2000, 2008 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jdt.core.search; >+ >+import org.eclipse.core.resources.IResource; >+import org.eclipse.jdt.core.*; >+ >+/** >+ * An abstract Java search match that represents a reference. >+ * >+ * @since 3.4 >+ */ >+public abstract class ReferenceMatch extends SearchMatch { >+ >+/** >+ * Creates a new reference match. >+ * >+ * @param enclosingElement the inner-most enclosing member that references this java element >+ * @param accuracy one of {@link #A_ACCURATE} or {@link #A_INACCURATE} >+ * @param offset the offset the match starts at, or -1 if unknown >+ * @param length the length of the match, or -1 if unknown >+ * @param insideDocComment <code>true</code> if this search match is inside a doc >+ * comment, and <code>false</code> otherwise >+ * @param participant the search participant that created the match >+ * @param resource the resource of the element >+ */ >+public ReferenceMatch(IJavaElement enclosingElement, int accuracy, int offset, int length, boolean insideDocComment, SearchParticipant participant, IResource resource) { >+ super(enclosingElement, accuracy, offset, length, participant, resource); >+ setInsideDocComment(insideDocComment); >+} >+ >+/** >+ * Returns the local element of this search match, or <code>null</code> if none. >+ * A local element is the inner most element that contains the reference and that is not >+ * reachable by navigating from the root of the {@link IJavaModel} using >+ * {@link IParent#getChildren()}. >+ * <p> >+ * Known element types for local elements are {@link IJavaElement#ANNOTATION}, >+ * {@link IJavaElement#LOCAL_VARIABLE} and {@link IJavaElement#TYPE_PARAMETER}. >+ * However clients should not assume that this set of element types is closed as >+ * other types of elements may be returned in the future, e.g. if new types >+ * of elements are added in the Java model. Clients can only assume that the >+ * {@link IJavaElement#getParent() parent} chain of this local element eventually leads >+ * to the element from {@link #getElement()}. >+ * </p><p> >+ * The local element being an {@link IAnnotation} is the most usal case. For example, >+ * <ul> >+ * <li>searching for the references to the method <code>Annot.clazz()</code> in >+ * <pre> >+ * public class Test { >+ * void method() { >+ * @Annot(clazz=Test.class) int x; >+ * } >+ * } >+ * </pre> >+ * will return one {@link MethodReferenceMatch} match whose local element >+ * is the {@link IAnnotation} '<code>Annot</code>'. >+ * </li> >+ * <li>searching for the references to the type <code>Deprecated</code> in >+ * <pre> >+ * public class Test { >+ * @Deprecated void method() {} >+ * } >+ * </pre> >+ * will return one {@link TypeReferenceMatch} match whose local element >+ * is the {@link IAnnotation} '<code>Deprecated</code>'. >+ * </li> >+ * <li>searching for the references to the field <code>CONST</code> in >+ * <pre> >+ * @Num(number= Num.CONST) >+ * @interface Num { >+ * public static final int CONST= 42; >+ * int number(); >+ * } >+ * </pre> >+ * will return one {@link FieldReferenceMatch} match whose local element >+ * is the {@link IAnnotation} '<code>Num</code>'. >+ * </li> >+ * </ul> >+ * </p><p> >+ * A local element may also be a {@link ILocalVariable} whose type is the referenced type. For example, >+ * <ul> >+ * <li>searching for the references to the type <code>Test</code> in >+ * <pre> >+ * public class Test { >+ * void foo() { >+ * Test local; >+ * } >+ * } >+ * </pre> >+ * will return one {@link TypeReferenceMatch} match whose local element >+ * is the {@link ILocalVariable} '<code>local</code>'. >+ * </li> >+ * </ul> >+ * Or a local element may be an {@link ITypeParameter} that extends the referenced type. For example, >+ * <ul> >+ * <li>searching for the references to the type <code>Test</code> in >+ * <pre> >+ * public class X< T extends Test> { >+ * } >+ * </pre> >+ * will return one {@link TypeReferenceMatch} match whose local element >+ * is the {@link ITypeParameter} '<code>T</code>'. >+ * </ul> >+ * </p> >+ * >+ * @return the local element of this search match, or <code>null</code> if none. >+ * >+ * @since 3.4 >+ */ >+public IJavaElement getLocalElement() { >+ return null; >+} >+} >Index: search/org/eclipse/jdt/internal/core/search/matching/InternalReferenceMatch.java >=================================================================== >RCS file: search/org/eclipse/jdt/internal/core/search/matching/InternalReferenceMatch.java >diff -N search/org/eclipse/jdt/internal/core/search/matching/InternalReferenceMatch.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ search/org/eclipse/jdt/internal/core/search/matching/InternalReferenceMatch.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,48 @@ >+/******************************************************************************* >+ * Copyright (c) 2000, 2008 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jdt.internal.core.search.matching; >+ >+import org.eclipse.core.resources.IResource; >+import org.eclipse.jdt.core.*; >+import org.eclipse.jdt.core.search.*; >+ >+/** >+ * An intermediate class to store data in the search match and access them >+ * in a private manner. >+ * >+ * @since 3.4 >+ */ >+public abstract class InternalReferenceMatch extends ReferenceMatch { >+ >+ IJavaElement localElement; >+ >+public InternalReferenceMatch(IJavaElement enclosingElement, int accuracy, int offset, int length, boolean insideDocComment, SearchParticipant participant, IResource resource) { >+ super(enclosingElement, accuracy, offset, length, insideDocComment, participant, resource); >+} >+ >+/* (non-Javadoc) >+ * Override the default behavior to return the stored local element. >+ * >+ * @see org.eclipse.jdt.core.search.ReferenceMatch#getLocalElement() >+ */ >+public IJavaElement getLocalElement() { >+ return this.localElement; >+} >+ >+/** >+ * Store the local element in the match. >+ * >+ * @param localElement The local element to be stored >+ */ >+public void setLocalElement(IJavaElement localElement) { >+ this.localElement = localElement; >+} >+} >#P org.eclipse.jdt.core.tests.model >Index: src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java,v >retrieving revision 1.147 >diff -u -r1.147 JavaSearchBugsTests.java >--- src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java 6 Mar 2008 17:39:52 -0000 1.147 >+++ src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java 21 Mar 2008 15:54:42 -0000 >@@ -64,17 +64,19 @@ > matches.add(searchMatch); > } > } >-class TypeReferencesCollector extends JavaSearchResultCollector { >+class ReferenceCollector extends JavaSearchResultCollector { > protected IJavaElement getElement(SearchMatch searchMatch) { > IJavaElement element = super.getElement(searchMatch); > IJavaElement localElement = null; >- TypeReferenceMatch typeRefMatch = (TypeReferenceMatch) match; >- localElement = typeRefMatch.getLocalElement(); >+ ReferenceMatch refMatch = (ReferenceMatch) match; >+ localElement = refMatch.getLocalElement(); > if (localElement != null) { > return localElement; > } > return element; > } >+} >+class TypeReferenceCollector extends ReferenceCollector { > protected void writeLine() throws CoreException { > super.writeLine(); > TypeReferenceMatch typeRefMatch = (TypeReferenceMatch) this.match; >@@ -5749,7 +5751,7 @@ > "}\n" > ); > IType type = this.workingCopies[0].getType("Test"); >- TypeReferencesCollector collector = new TypeReferencesCollector(); >+ TypeReferenceCollector collector = new TypeReferenceCollector(); > search(type, REFERENCES, EXACT_RULE, getJavaSearchScope(), collector); > assertSearchResults( > "src/b110336/Test.java void b110336.Test.method(Class<Test>).TP [Test]\n" + >@@ -5777,7 +5779,7 @@ > "}\n" > ); > IType type = this.workingCopies[0].getType("Test"); >- TypeReferencesCollector collector = new TypeReferencesCollector(); >+ TypeReferenceCollector collector = new TypeReferenceCollector(); > search(type, REFERENCES, EXACT_RULE, getJavaSearchScope(), collector); > assertSearchResults( > "src/b110336/Test.java void b110336.Test.method1(Test):<anonymous>#1 [Test]\n" + >@@ -5801,7 +5803,7 @@ > "class X {}\n" > ); > IType type = this.workingCopies[0].getType("X"); >- TypeReferencesCollector collector = new TypeReferencesCollector(); >+ TypeReferenceCollector collector = new TypeReferenceCollector(); > search(type, REFERENCES, EXACT_RULE, getJavaSearchScope(), collector); > assertSearchResults( > "src/b110336/Test.java b110336.Test.TP [X]\n" + >@@ -5820,7 +5822,7 @@ > "}\n" > ); > IType type = this.workingCopies[0].getType("Test"); >- TypeReferencesCollector collector = new TypeReferencesCollector(); >+ TypeReferenceCollector collector = new TypeReferenceCollector(); > search(type, REFERENCES, EXACT_RULE, getJavaSearchScope(), collector); > assertSearchResults( > "src/b110336/Test.java b110336.Test.a1Test [Test]+[b1Test,c1Test]\n" + >@@ -5845,7 +5847,7 @@ > "}\n" > ); > IType type = this.workingCopies[0].getType("Test"); >- TypeReferencesCollector collector = new TypeReferencesCollector(); >+ TypeReferenceCollector collector = new TypeReferenceCollector(); > search(type, REFERENCES, EXACT_RULE, getJavaSearchScope(), collector); > assertSearchResults( > "src/b110336/Test.java void b110336.Test.foo().lv1 [Test]+[lv2,lv3]\n" + >@@ -5875,7 +5877,7 @@ > "}\n" > ); > IType type = this.workingCopies[0].getType("Test"); >- TypeReferencesCollector collector = new TypeReferencesCollector(); >+ TypeReferenceCollector collector = new TypeReferenceCollector(); > search(type, REFERENCES, EXACT_RULE, getJavaSearchScope(), collector); > assertSearchResults( > "src/b110336/Test.java void b110336.Test.foo(Test).test1 [Test]\n" + >@@ -5899,7 +5901,7 @@ > "}\n" > ); > IType type = this.workingCopies[0].getType("Test"); >- TypeReferencesCollector collector = new TypeReferencesCollector(); >+ TypeReferenceCollector collector = new TypeReferenceCollector(); > search(type, REFERENCES, EXACT_RULE, getJavaSearchScope(), collector); > assertSearchResults( > "src/b110336/Test.java b110336.Test.{}.lv1 [Test]+[lv2,lv3]\n" + >@@ -5924,7 +5926,7 @@ > "}\n" > ); > IType type = this.workingCopies[0].getType("Test"); >- TypeReferencesCollector collector = new TypeReferencesCollector(); >+ TypeReferenceCollector collector = new TypeReferenceCollector(); > search(type, REFERENCES, EXACT_RULE, getJavaSearchScope(), collector); > assertSearchResults( > "src/b110336/Test.java b110336.Test.static {}.lv1 [Test]+[lv2,lv3]\n" + >@@ -9210,6 +9212,130 @@ > } > > /** >+ * @bug 209778: [search] TypeReferenceMatch#getOtherElements() fails for match in annotation >+ * @test Ensure that the local element is no longer a local variable >+ * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=209778" >+ */ >+public void testBug209778() throws CoreException { >+ workingCopies = new ICompilationUnit[1]; >+ workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/xy/Try.java", >+ "package xy;\n" + >+ "\n" + >+ "public class Try {\n" + >+ " void tryB(int tryKind) {\n" + >+ " @Constants(Try.class) int tryCopy, tryCopy2= tryKind;\n" + >+ " }\n" + >+ " @Constants(value= Try.class) Object fTryA, fTryB;\n" + >+ "}\n" + >+ "\n" + >+ "@interface Constants {\n" + >+ " Class<?> value();\n" + >+ "}" >+ ); >+ IType type = workingCopies[0].getType("Try"); >+ TypeReferenceCollector collector = new TypeReferenceCollector(); >+ search(type, REFERENCES, EXACT_RULE, getJavaSearchScope(), collector); >+ assertSearchResults( >+ "src/xy/Try.java @Constants(value=Try.class) [Try]\n" + >+ "src/xy/Try.java @Constants(value=Try.class) [Try]", >+ collector >+ ); >+} >+ >+/** >+ * @bug 209996: [search] Add a way to access the most local enclosing annotation for reference search matches >+ * @test Verify the behavior of the new Search API {@link ReferenceMatch#getLocalElement()} >+ * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=209996" >+ */ >+public void testBug209996a() throws CoreException { >+ workingCopies = new ICompilationUnit[1]; >+ workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/test/Test.java", >+ "package test;\n" + >+ "public class Test {\n" + >+ " void method() {\n" + >+ " @Annot(clazz=Test.class) int x;\n" + >+ " }\n" + >+ "}\n" + >+ "@interface Annot {\n" + >+ " Class clazz();\n" + >+ "}\n" >+ ); >+ IType type = workingCopies[0].getType("Test"); >+ ReferenceCollector collector = new ReferenceCollector(); >+ collector.showSelection = true; >+ search(type, REFERENCES, EXACT_RULE, getJavaSearchScope(), collector); >+ assertSearchResults( >+ "src/test/Test.java @Annot(clazz=Test.class) [ @Annot(clazz=§|Test|§.class) int x;]", >+ collector >+ ); >+} >+public void testBug209996b() throws CoreException { >+ workingCopies = new ICompilationUnit[1]; >+ workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/test/Test.java", >+ "package test;\n" + >+ "public class Test {\n" + >+ " @Deprecated foo() {}\n" + >+ "}\n" >+ ); >+ ReferenceCollector collector = new ReferenceCollector(); >+ collector.showSelection = true; >+ search("Deprecated", TYPE, REFERENCES, EXACT_RULE, getJavaSearchScope(), collector); >+ assertSearchResults( >+ "src/test/Test.java @Deprecated() [ @§|Deprecated|§ foo() {}]", >+ collector >+ ); >+} >+public void testBug209996_c5() throws CoreException { >+ workingCopies = new ICompilationUnit[1]; >+ workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/comment5/Ref.java", >+ "package comment5;\n" + >+ "public class Ref {\n" + >+ " void doA(Ref ref) {}\n" + >+ " void doB(List<Ref> ref) {}\n" + >+ " void doC(@Tag(Ref.class) Ref ref) {}\n" + >+ " void dontD(@Tag(Ref.class) Object ref) {}\n" + >+ "}\n" + >+ "\n" + >+ "@interface Tag {\n" + >+ " Class value();\n" + >+ "}\n" + >+ "class List<T> {\n" + >+ "}\n" >+ ); >+ IType type = workingCopies[0].getType("Ref"); >+ ReferenceCollector collector = new ReferenceCollector(); >+ collector.showSelection = true; >+ search(type, REFERENCES, EXACT_RULE, getJavaSearchScope(), collector); >+ assertSearchResults( >+ "src/comment5/Ref.java void comment5.Ref.doA(Ref).ref [ void doA(§|Ref|§ ref) {}]\n" + >+ "src/comment5/Ref.java void comment5.Ref.doB(List<Ref>).ref [ void doB(List<§|Ref|§> ref) {}]\n" + >+ "src/comment5/Ref.java @Tag(value=Ref.class) [ void doC(@Tag(§|Ref|§.class) Ref ref) {}]\n" + >+ "src/comment5/Ref.java void comment5.Ref.doC(Ref).ref [ void doC(@Tag(Ref.class) §|Ref|§ ref) {}]\n" + >+ "src/comment5/Ref.java @Tag(value=Ref.class) [ void dontD(@Tag(§|Ref|§.class) Object ref) {}]", >+ collector >+ ); >+} >+public void testBug209996_c10() throws CoreException { >+ workingCopies = new ICompilationUnit[1]; >+ workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/comment10/Ref.java", >+ "package comment10;\n" + >+ "@Num(number= Num.CONST)\n" + >+ "@interface Num {\n" + >+ " public static final int CONST= 42;\n" + >+ " int number();\n" + >+ "}\n" >+ ); >+ IField field = workingCopies[0].getType("Num").getField("CONST"); >+ ReferenceCollector collector = new ReferenceCollector(); >+ collector.showSelection = true; >+ search(field, REFERENCES, EXACT_RULE, getJavaSearchScope(), collector); >+ assertSearchResults( >+ "src/comment10/Ref.java @Num(number=Num.CONST) [@Num(number= Num.§|CONST|§)]", >+ collector >+ ); >+} >+ >+/** > * @bug 210689: [search] Type references are not found in import declarations when JUnit tests only use working copies > * @test Ensure that import references are found when searching on working copies not written on disk > * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=210689" >Index: src/org/eclipse/jdt/core/tests/model/JavaSearchFineGrainTests.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchFineGrainTests.java,v >retrieving revision 1.7 >diff -u -r1.7 JavaSearchFineGrainTests.java >--- src/org/eclipse/jdt/core/tests/model/JavaSearchFineGrainTests.java 4 Mar 2008 10:51:22 -0000 1.7 >+++ src/org/eclipse/jdt/core/tests/model/JavaSearchFineGrainTests.java 21 Mar 2008 15:54:43 -0000 >@@ -1005,15 +1005,15 @@ > "src/test02/Test.java Test<X<Y<Z<String>>>,Y<Z<String>>,Z<String>> test02.Test.field:<anonymous>#1.bar() [ return new Test<X<Y<Z<String>>>, Y<Z<§|String|§>>, Z<String>>();@257] EXACT_MATCH\n" + > "src/test02/Test.java Test<X<Y<Z<String>>>,Y<Z<String>>,Z<String>> test02.Test.field:<anonymous>#1.bar() [ return new Test<X<Y<Z<String>>>, Y<Z<String>>, §|Z|§<String>>();@267] EXACT_MATCH\n" + > "src/test02/Test.java Test<X<Y<Z<String>>>,Y<Z<String>>,Z<String>> test02.Test.field:<anonymous>#1.bar() [ return new Test<X<Y<Z<String>>>, Y<Z<String>>, Z<§|String|§>>();@269] EXACT_MATCH\n" + >- "src/test02/Test.java test02.Test.field [ §|Test|§<A, ? extends B, ? super C> field = new Test<A, Z<String>, X<String>> () {@47] EXACT_MATCH\n" + >- "src/test02/Test.java test02.Test.field [ Test<§|A|§, ? extends B, ? super C> field = new Test<A, Z<String>, X<String>> () {@52] EXACT_MATCH\n" + >- "src/test02/Test.java test02.Test.field [ Test<A, ? extends §|B|§, ? super C> field = new Test<A, Z<String>, X<String>> () {@65] EXACT_MATCH\n" + >- "src/test02/Test.java test02.Test.field [ Test<A, ? extends B, ? super §|C|§> field = new Test<A, Z<String>, X<String>> () {@76] EXACT_MATCH\n" + > "src/test02/Test.java test02.Test.field [ Test<A, ? extends B, ? super C> field = new Test<§|A|§, Z<String>, X<String>> () {@96] EXACT_MATCH\n" + > "src/test02/Test.java test02.Test.field [ Test<A, ? extends B, ? super C> field = new Test<A, §|Z|§<String>, X<String>> () {@99] EXACT_MATCH\n" + > "src/test02/Test.java test02.Test.field [ Test<A, ? extends B, ? super C> field = new Test<A, Z<§|String|§>, X<String>> () {@101] EXACT_MATCH\n" + > "src/test02/Test.java test02.Test.field [ Test<A, ? extends B, ? super C> field = new Test<A, Z<String>, §|X|§<String>> () {@110] EXACT_MATCH\n" + > "src/test02/Test.java test02.Test.field [ Test<A, ? extends B, ? super C> field = new Test<A, Z<String>, X<§|String|§>> () {@112] EXACT_MATCH\n" + >+ "src/test02/Test.java test02.Test.field [ §|Test|§<A, ? extends B, ? super C> field = new Test<A, Z<String>, X<String>> () {@47] EXACT_MATCH\n" + >+ "src/test02/Test.java test02.Test.field [ Test<§|A|§, ? extends B, ? super C> field = new Test<A, Z<String>, X<String>> () {@52] EXACT_MATCH\n" + >+ "src/test02/Test.java test02.Test.field [ Test<A, ? extends §|B|§, ? super C> field = new Test<A, Z<String>, X<String>> () {@65] EXACT_MATCH\n" + >+ "src/test02/Test.java test02.Test.field [ Test<A, ? extends B, ? super §|C|§> field = new Test<A, Z<String>, X<String>> () {@76] EXACT_MATCH\n" + > "src/test02/Test.java Test<? super A,B,? extends C> test02.Test.foo(Test<? extends A,? super B,C>) [ §|Test|§<? super A, B, ? extends C> foo(Test<? extends A, ? super B, C> param) {@290] EXACT_MATCH\n" + > "src/test02/Test.java Test<? super A,B,? extends C> test02.Test.foo(Test<? extends A,? super B,C>) [ Test<? super §|A|§, B, ? extends C> foo(Test<? extends A, ? super B, C> param) {@303] EXACT_MATCH\n" + > "src/test02/Test.java Test<? super A,B,? extends C> test02.Test.foo(Test<? extends A,? super B,C>) [ Test<? super A, §|B|§, ? extends C> foo(Test<? extends A, ? super B, C> param) {@306] EXACT_MATCH\n" + >@@ -1054,14 +1054,14 @@ > "src/test02/Test.java Test<X<Y<Z<String>>>,Y<Z<String>>,Z<String>> test02.Test.field:<anonymous>#1.bar() [ return new Test<X<Y<Z<String>>>, Y<Z<§|String|§>>, Z<String>>();@257] EXACT_MATCH\n" + > "src/test02/Test.java Test<X<Y<Z<String>>>,Y<Z<String>>,Z<String>> test02.Test.field:<anonymous>#1.bar() [ return new Test<X<Y<Z<String>>>, Y<Z<String>>, §|Z|§<String>>();@267] EXACT_MATCH\n" + > "src/test02/Test.java Test<X<Y<Z<String>>>,Y<Z<String>>,Z<String>> test02.Test.field:<anonymous>#1.bar() [ return new Test<X<Y<Z<String>>>, Y<Z<String>>, Z<§|String|§>>();@269] EXACT_MATCH\n" + >- "src/test02/Test.java test02.Test.field [ Test<§|A|§, ? extends B, ? super C> field = new Test<A, Z<String>, X<String>> () {@52] EXACT_MATCH\n" + >- "src/test02/Test.java test02.Test.field [ Test<A, ? extends §|B|§, ? super C> field = new Test<A, Z<String>, X<String>> () {@65] EXACT_MATCH\n" + >- "src/test02/Test.java test02.Test.field [ Test<A, ? extends B, ? super §|C|§> field = new Test<A, Z<String>, X<String>> () {@76] EXACT_MATCH\n" + > "src/test02/Test.java test02.Test.field [ Test<A, ? extends B, ? super C> field = new Test<§|A|§, Z<String>, X<String>> () {@96] EXACT_MATCH\n" + > "src/test02/Test.java test02.Test.field [ Test<A, ? extends B, ? super C> field = new Test<A, §|Z|§<String>, X<String>> () {@99] EXACT_MATCH\n" + > "src/test02/Test.java test02.Test.field [ Test<A, ? extends B, ? super C> field = new Test<A, Z<§|String|§>, X<String>> () {@101] EXACT_MATCH\n" + > "src/test02/Test.java test02.Test.field [ Test<A, ? extends B, ? super C> field = new Test<A, Z<String>, §|X|§<String>> () {@110] EXACT_MATCH\n" + > "src/test02/Test.java test02.Test.field [ Test<A, ? extends B, ? super C> field = new Test<A, Z<String>, X<§|String|§>> () {@112] EXACT_MATCH\n" + >+ "src/test02/Test.java test02.Test.field [ Test<§|A|§, ? extends B, ? super C> field = new Test<A, Z<String>, X<String>> () {@52] EXACT_MATCH\n" + >+ "src/test02/Test.java test02.Test.field [ Test<A, ? extends §|B|§, ? super C> field = new Test<A, Z<String>, X<String>> () {@65] EXACT_MATCH\n" + >+ "src/test02/Test.java test02.Test.field [ Test<A, ? extends B, ? super §|C|§> field = new Test<A, Z<String>, X<String>> () {@76] EXACT_MATCH\n" + > "src/test02/Test.java Test<? super A,B,? extends C> test02.Test.foo(Test<? extends A,? super B,C>) [ Test<? super §|A|§, B, ? extends C> foo(Test<? extends A, ? super B, C> param) {@303] EXACT_MATCH\n" + > "src/test02/Test.java Test<? super A,B,? extends C> test02.Test.foo(Test<? extends A,? super B,C>) [ Test<? super A, §|B|§, ? extends C> foo(Test<? extends A, ? super B, C> param) {@306] EXACT_MATCH\n" + > "src/test02/Test.java Test<? super A,B,? extends C> test02.Test.foo(Test<? extends A,? super B,C>) [ Test<? super A, B, ? extends §|C|§> foo(Test<? extends A, ? super B, C> param) {@319] EXACT_MATCH\n" + >@@ -1097,12 +1097,12 @@ > "src/test02/Test.java Test<X<Y<Z<String>>>,Y<Z<String>>,Z<String>> test02.Test.field:<anonymous>#1.bar() [ return new Test<X<Y<Z<String>>>, Y<Z<§|String|§>>, Z<String>>();@257] EXACT_MATCH\n" + > "src/test02/Test.java Test<X<Y<Z<String>>>,Y<Z<String>>,Z<String>> test02.Test.field:<anonymous>#1.bar() [ return new Test<X<Y<Z<String>>>, Y<Z<String>>, §|Z|§<String>>();@267] EXACT_MATCH\n" + > "src/test02/Test.java Test<X<Y<Z<String>>>,Y<Z<String>>,Z<String>> test02.Test.field:<anonymous>#1.bar() [ return new Test<X<Y<Z<String>>>, Y<Z<String>>, Z<§|String|§>>();@269] EXACT_MATCH\n" + >- "src/test02/Test.java test02.Test.field [ Test<§|A|§, ? extends B, ? super C> field = new Test<A, Z<String>, X<String>> () {@52] EXACT_MATCH\n" + > "src/test02/Test.java test02.Test.field [ Test<A, ? extends B, ? super C> field = new Test<§|A|§, Z<String>, X<String>> () {@96] EXACT_MATCH\n" + > "src/test02/Test.java test02.Test.field [ Test<A, ? extends B, ? super C> field = new Test<A, §|Z|§<String>, X<String>> () {@99] EXACT_MATCH\n" + > "src/test02/Test.java test02.Test.field [ Test<A, ? extends B, ? super C> field = new Test<A, Z<§|String|§>, X<String>> () {@101] EXACT_MATCH\n" + > "src/test02/Test.java test02.Test.field [ Test<A, ? extends B, ? super C> field = new Test<A, Z<String>, §|X|§<String>> () {@110] EXACT_MATCH\n" + > "src/test02/Test.java test02.Test.field [ Test<A, ? extends B, ? super C> field = new Test<A, Z<String>, X<§|String|§>> () {@112] EXACT_MATCH\n" + >+ "src/test02/Test.java test02.Test.field [ Test<§|A|§, ? extends B, ? super C> field = new Test<A, Z<String>, X<String>> () {@52] EXACT_MATCH\n" + > "src/test02/Test.java Test<? super A,B,? extends C> test02.Test.foo(Test<? extends A,? super B,C>) [ Test<? super A, §|B|§, ? extends C> foo(Test<? extends A, ? super B, C> param) {@306] EXACT_MATCH\n" + > "src/test02/Test.java Test<? super A,B,? extends C> test02.Test.foo(Test<? extends A,? super B,C>) [ Test<? super A, B, ? extends C> foo(Test<? extends A, ? super B, §|C|§> param) {@355] EXACT_MATCH\n" + > "src/test02/Test.java test02.C [class C extends X<§|String|§> {}@428] EXACT_MATCH" >Index: src/org/eclipse/jdt/core/tests/model/AbstractJavaSearchTests.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaSearchTests.java,v >retrieving revision 1.34 >diff -u -r1.34 AbstractJavaSearchTests.java >--- src/org/eclipse/jdt/core/tests/model/AbstractJavaSearchTests.java 30 Jan 2008 15:59:42 -0000 1.34 >+++ src/org/eclipse/jdt/core/tests/model/AbstractJavaSearchTests.java 21 Mar 2008 15:54:40 -0000 >@@ -162,6 +162,10 @@ > } else if (element instanceof IPackageDeclaration) { > IPackageDeclaration packageDeclaration = (IPackageDeclaration)element; > unit = (ICompilationUnit)packageDeclaration.getAncestor(IJavaElement.COMPILATION_UNIT); >+ } else if (element instanceof IAnnotation) { >+ line.append(" "); >+ append((IAnnotation)element); >+ unit = (ICompilationUnit) element.getAncestor(IJavaElement.COMPILATION_UNIT); > } > if (resource instanceof IFile) { > char[] contents = getSource(resource, element, unit); >@@ -273,6 +277,28 @@ > private boolean showSuperInvocation() { > return (this.showFlavors & PatternLocator.SUPER_INVOCATION_FLAVOR) != 0; > } >+ protected void append(IAnnotation annotation) throws JavaModelException { >+ line.append("@"); >+ line.append(annotation.getElementName()); >+ line.append('('); >+ IMemberValuePair[] pairs = annotation.getMemberValuePairs(); >+ int length = pairs == null ? 0 : pairs.length; >+ for (int i=0; i<length; i++) { >+ line.append(pairs[i].getMemberName()); >+ line.append('='); >+ Object value = pairs[i].getValue(); >+ switch (pairs[i].getValueKind()) { >+ case IMemberValuePair.K_CLASS: >+ line.append(value); >+ line.append(".class"); >+ break; >+ default: >+ line.append(value); >+ break; >+ } >+ } >+ line.append(')'); >+ } > protected void append(IField field) throws JavaModelException { > append(field.getDeclaringType()); > line.append(".");
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 209996
:
92799
|
92832
|
93144
|
93191
|
93215