Bug 209625 - [search] Enhance java search scope to express more sophisticated locations
Summary: [search] Enhance java search scope to express more sophisticated locations
Status: NEW
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.3   Edit
Hardware: PC Windows XP
: P5 enhancement (vote)
Target Milestone: ---   Edit
Assignee: JDT-Core-Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords: api
Depends on: 209996
Blocks:
  Show dependency tree
 
Reported: 2007-11-13 07:52 EST by Frederic Fusier CLA
Modified: 2016-01-14 12:46 EST (History)
5 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Frederic Fusier CLA 2007-11-13 07:52:22 EST
Fine grained search (see bug 155013) may be addressed using several ways.

One of this possible was described by Philippe in bug 155013 comment 14:
> If finegrain flags are passed to a search pattern to better discriminate;
> it should be possible to ask a search match for the same information.
> Like if you search for all refs to a given type, you could be interested
> to know that certain matches were located inside annotations, without doing
> a separate query.
>
> Taking some distance a little, scopes are usually used for narrowing the
> location of a match (i.e. look for type refs inside type X). Shouldn't
> thus scope be enhanced to express more sophisticated locations ?
> Like inside annotations ? I could imagine an approach where a scope could
> be even given some search patterns (declaration patterns), so you could
> search for reference to type IOException inside #main(*) methods.
> So it would only take the addition of a pattern for representing an 
> annotation, so as to be able to combine it in the scope:
> search for type ref X inside annotations

In fact this way seems to be the most reasonable approach to address easily the requirement 3) expressed by Ernest in bug 155013 comment 8...

So, after having discussed with Jerome, we decided to split the fine grained search work into 2 separated bugs:
 - bug 155013 will address requirement 1) of bug 155013 comment 8 and also
   most of the Martin's initial requirements using an  additional flag on 
   SearchPattern#createPattern(...) methods as described in bug 155013
   comment 11
 - this bug will address requirement 3) of bug 155013 comment 8

Note that requirement 2) of bug 155013 comment 8 is already addressed by search engine using a method reference query...
Comment 1 Martin Aeschlimann CLA 2007-11-13 08:33:17 EST
Isn't this already possible? You can already create a Java search scope with any Java element; IType, IMethod ect. (a.)

You can then search for a given annotation type in this scope.

You can also create a hierarchy scope to search for annotations on a class of a given type (b.)

The fine grained search flags as suggested in bug 155013 would help you to make sure that you only get results in the annotations, but not somewhere in the method body or return type.
Currently you have to do this yourself when getting the search match by testing the match location.
This is what we do to find JUnit 4 test cases.

The only think that I believe isn't possible right now is to say that you only want to find annotation matches in interfaces or in classes. You would have to test for this when getting the search match.

Comment 2 Frederic Fusier CLA 2007-11-13 09:19:29 EST
(In reply to comment #1)
> Isn't this already possible? You can already create a Java search scope with
> any Java element; IType, IMethod ect. (a.)
>
> You can then search for a given annotation type in this scope.
> 
Yes, but enhancing the search scope with a given declaration pattern will allow user to specify more than one java element without having to create an array of them. You could then easily find all the @Test annotation specified on "test*" method for example. The fine grained search could not be so precise and so, it would be difficult to use it to search for the JUnit 4 test cases...

> You can also create a hierarchy scope to search for annotations on a class of > a given type (b.)
> 
My understanding of 3b.) is that they may also want to be able to find annotations on classes, interfaces or other particular type, not a specific given type. So, IMO, this point is not 3b)

> The fine grained search flags as suggested in bug 155013 would help you to 
> make sure that you only get results in the annotations, but not somewhere
> in the method body or return type.
> Currently you have to do this yourself when getting the search match by 
> testing the match location.
> This is what we do to find JUnit 4 test cases.
> 
As I said before, using enhanced scope will be easier to address this need rather than the fine grained search...

> The only think that I believe isn't possible right now is to say that you only
> want to find annotation matches in interfaces or in classes. You would have to
> test for this when getting the search match.
> 
I think this point is 3b.) and will be addressed by the enhanced scope more efficiently than the fine grained search.

Note that the enhanced scope may also be view as a fine grained search as specifying a pattern on the scope would obviously refine the results you got with the current scope...
Comment 3 Frederic Fusier CLA 2007-11-13 12:09:20 EST
Here's the proposed API addition on SearchEngine to create this new enhanced JavaSearchScope:

/**
 * Returns a Java search scope both limited to the given Java elements and
 * the given search pattern.
 * The Java elements resulting from a search with this scope will
 * be children of the given elements and will match the given pattern.
 * 
 * If an element is an IJavaProject, then it includes:
 * - its source folders if IJavaSearchScope.SOURCES is specified, 
 * - its application libraries (internal and external jars, class folders that 
 *   are on the raw classpath, 
 *   or the ones that are coming from a classpath path variable,
 *   or the ones that are coming from a classpath container with the 
 *   K_APPLICATION kind)
 *   if IJavaSearchScope.APPLICATION_LIBRARIES is specified
 * - its system libraries (internal and external jars, class folders that are 
 *   coming from an IClasspathContainer with the K_SYSTEM kind) 
 *   if IJavaSearchScope.APPLICATION_LIBRARIES is specified
 * - its referenced projects (with their source folders and jars, recursively) 
 *   if IJavaSearchScope.REFERENCED_PROJECTS is specified.
 * If an element is an IPackageFragmentRoot, then only the package fragments of 
 * this package fragment root will be included.
 * If an element is an IPackageFragment, then only the compilation unit and 
 * class files of this package fragment will be included. Subpackages will NOT 
 * be included.
 *
 * @param elements the Java elements the scope is limited to
 * @param includeMask the bit-wise OR of all include types of interest
 * @param searchPattern the search pattern used to refine the scope
 * @return a new Java search scope
 * @see IJavaSearchScope#SOURCES
 * @see IJavaSearchScope#APPLICATION_LIBRARIES
 * @see IJavaSearchScope#SYSTEM_LIBRARIES
 * @see IJavaSearchScope#REFERENCED_PROJECTS
 * @since 3.4
 */
public static IJavaSearchScope createJavaSearchPatternScope(IJavaElement[] elements, int includeMask, SearchPattern searchPattern) {
Comment 4 Frederic Fusier CLA 2007-11-14 07:06:43 EST
After Jeromre's review, I made the javadoc a little bit more verbose:
/**
 * Returns a Java search scope both limited to the given Java elements and
 * the given search declaration pattern.
 * The Java elements resulting from a search with this scope (see
 * {@link SearchMatch#getElement()}) will be children of the given elements and
 * will match the given declaration pattern.
 * <p>
 * Note that the search may NOT return any results if the pattern does not match
 * any of the possible Java elements. For example, this would be the case if all 
 * the possible matches of a search request were {@link IMethod methods} and
 * the specified scope declaration pattern was a {@link FieldPattern field 
 * pattern}.
 * </p>
...
 * @param searchPattern the search pattern used to refine the scope. If
 *   <code>null</code>, then the scope is not refined and this method will return 
 *   the same results as if {@link #createJavaSearchScope(IJavaElement[], int)}
 *   was used to create the scope.
 * @throws IllegalArgumentException If the given pattern is not a declaration
 *   pattern (e.g. neither have the <code>IJavaSearchConstant.DECLARATIONS</code>
 *   nor the <code>IJavaSearchConstant.ALL_OCCURRENCES</code> nature of
 *   match)
...

Comment 5 Martin Aeschlimann CLA 2007-11-14 08:37:41 EST
Note that JUnit 4 tests don't need to have a name matching 'test* '. You can name the method as you like. The annotation '@Test' is all what's required. So searching for '@Test' is all we need to find the methods that are tests.
And the @Test annotation is only applicable to methods anyways.
The bigger problem we're having is to make sure the match is really in the annotations section, not in the method body or return type.

Ernest, can you give more details about the searches you are performing, so we can see if this new API is really required.




Comment 6 Frederic Fusier CLA 2007-11-15 05:55:08 EST
(In reply to comment #5)
> Note that JUnit 4 tests don't need to have a name matching 'test* '. You can
> name the method as you like. The annotation '@Test' is all what's required. So
> searching for '@Test' is all we need to find the methods that are tests.
> And the @Test annotation is only applicable to methods anyways.
>
Even if in this case it's not necessary, it's not a problem to offer a more powerful API, is it?

> The bigger problem we're having is to make sure the match is really in the
> annotations section, not in the method body or return type.
> 
Not sure to understand, can you provide an example of a @Test annotation in the method body or in return type? Do you mean that this API would not match your requirement?

> Ernest, can you give more details about the searches you are performing, so we
> can see if this new API is really required.
> 
I think Ernest already gave more details in bug 155013 comment 12.

As I said in comment 0, the purpose of this bug is to address the requirement 3). Point a) could be addressed by the current Java search scope only if user already has the Java element in hand while creating the scope. If he does not have it, but only knows its characteristics, then creating a pattern to refine the scope may be necessary. Furthermore, as point b) could not be addressed
with the current scope, this enhancement is necessary for it.
Comment 7 Markus Keller CLA 2007-11-15 13:35:47 EST
> Even if in this case it's not necessary, it's not a problem to offer a more
> powerful API, is it?

The problem with APIs that have been designed without at least one client is that they usually have to be deprecated in the next version because they have not been polished enough, or that their implementation has a tiny bug that makes them unusable for the first client.

> > The bigger problem we're having is to make sure the match is really in the
> > annotations section, not in the method body or return type.
> > 
> Not sure to understand, can you provide an example of a @Test annotation in
> the method body or in return type?

Sure, see bug 204682 (annotation types can be referenced like interface types).
An ANNOTATION_TYPE_REFERENCE flag (bug 155013 comment 26) or access to the enclosing annotation from the search match (bug 209996) would fit our needs in an easier way.
Comment 8 Frederic Fusier CLA 2007-11-28 03:15:47 EST
As ANNOTATION_TYPE_REFERENCE fine grain flag has been implemented in bug 155013, this enhancement is less critical to address Ernest requirements. As it was already said in this bug, client can inspect the context of the returned Java element while accepting the match in his/her requestor and see if it's a class, an interface, an enum or an annotation.

However, that means that blocking bug 209996 must be fixed for 3.4 in order to address the 3.a) request (see bug 155013 comment 8).

So, reset target and reduce priority of this bug.