Bug 196339 - [search] SearchEngine not returning correct result
Summary: [search] SearchEngine not returning correct result
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.3   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 3.4 M1   Edit
Assignee: Frederic Fusier CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-07-12 12:08 EDT by Máirtín CLA
Modified: 2007-08-03 10:13 EDT (History)
0 users

See Also:


Attachments
Proposed patch (5.83 KB, patch)
2007-07-12 12:30 EDT, Frederic Fusier CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Máirtín CLA 2007-07-12 12:08:13 EDT
This bug has arisen out of a problem from here http://www.eclipse.org/newsportal/article.php?id=20957&group=eclipse.tools.jdt#20957 

Here is the summary of the problem:

I have a class Baz


  package x.y.z;

  import a.b.c.Foo;

  public class Baz extends Foo{
  }


in my project which does not compile as the class


   a.b.c.Foo


does not exist in the project.


I want to find all classes that extend a.b.c.Foo.

I am using the following code to search for classes that extend a.b.c.Foo.



final Set<SearchMatch> classesThatExtendFoo= new HashSet<SearchMatch>();

IJavaSearchScope scope= SearchEngine.createWorkspaceScope();
SearchPattern pattern= SearchPattern.createPattern("a.b.c.Foo", IJavaSearchConstants.TYPE, IJavaSearchConstants.IMPLEMENTORS, SearchPattern.R_EXACT_MATCH);
SearchEngine engine= new SearchEngine();
engine.search(pattern, new SearchParticipant[] { SearchEngine.getDefaultSearchParticipant()}, scope, new SearchRequestor() {

@Override
public void acceptSearchMatch(SearchMatch match) throws CoreException {
if (match.getAccuracy() == SearchMatch.A_ACCURATE && !match.isInsideDocComment())
System.out.println(match);
classesThatExtendFoo.add(match);
}

}, new SubProgressMonitor(monitor, 1, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL));


However the SearchEngine does not find the class x.y.z.Baz.


Setting a breakpoint at SuperTypeReferencePattern constructors shows that 'mustResolve' is set to true. However the class "a.b.c.Foo" cannot be resolved as it does not exist.


Can this be fixed so that the SearchEngine returns the correct result? Thanks.

-- máirtín
Comment 1 Máirtín CLA 2007-07-12 12:08:58 EDT
The version of Eclipse that I am using is Version: 3.3.0, Build id: I20070503-1400.
Comment 2 Frederic Fusier CLA 2007-07-12 12:27:20 EDT
Here's your code snippet with a search requestor which may workaround your problem waiting for a build with the fix of this problem: 

final Set<SearchMatch> classesThatExtendFoo= new HashSet<SearchMatch>();

IJavaSearchScope scope = SearchEngine.createWorkspaceScope();
SearchPattern pattern = SearchPattern.createPattern("Foo",
    IJavaSearchConstants.TYPE,
    IJavaSearchConstants.IMPLEMENTORS,
    SearchPattern.R_EXACT_MATCH);

final String qualifiedType = "a.b.c.Foo";
SearchRequestor requestor = new SearchRequestor() {
    public void acceptSearchMatch(SearchMatch searchMatch) throws CoreException {
        Object element = searchMatch.getElement();
        if (element instanceof IType) {
            IType type = (IType) element;
            // Look if super interface names matches the qualified type
            String[] superInterfaces = type.getSuperInterfaceNames();
            int length = superInterfaces == null ? 0 : superInterfaces.length;
            for (int i=0; i<length; i++) {
                if (superInterfaces[i].equals(qualifiedType)) {
                    System.out.println(searchMatch);
                    classesThatExtendFoo.add(searchMatch);
                    return;
                }
            }
            // Look if an import declaration matches the qualified type
            IImportDeclaration[] imports = ((ICompilationUnit) type.getAncestor(IJavaElement.COMPILATION_UNIT)).getImports();
            length = imports == null ? 0 : imports.length;
            for (int i=0; i<length; i++) {
                String importName = imports[i].getElementName();
                if (importName.equals(qualifiedType)) {
                    System.out.println(searchMatch);
                    classesThatExtendFoo.add(searchMatch);
                    return;
                }
                if (imports[i].isOnDemand()) {
                    int idx = importName.lastIndexOf('.');
                    if (idx > 0 && importName.substring(0, idx).equals(qualifiedType.substring(0, idx))) {
                        System.out.println(searchMatch);
                        classesThatExtendFoo.add(searchMatch);
                        return;
                    }
                }
            }
        }
    }
}

new SearchEngine().search(pattern,
    new SearchParticipant[] { SearchEngine.getDefaultSearchParticipant()},
    scope,
    requestor,
    new SubProgressMonitor(monitor, 1, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL));

You will then be able to find following classes even if Foo is not implemented yet:
Bar1.java
    package x.y.z;
    import a.b.c.Foo;
    public class Bar1 implements Foo {}
Bar2.java
    package x.y.z;
    import a.b.c.*;
    public class Bar2 implements Foo {}
Bar3.java
    package x.y.z;
    public class Bar3 implements a.b.c.Foo {}
Comment 3 Frederic Fusier CLA 2007-07-12 12:30:16 EDT
Created attachment 73680 [details]
Proposed patch
Comment 4 Frederic Fusier CLA 2007-07-17 02:30:13 EDT
Released for 3.4M1 in HEAD stream.
Comment 5 Frederic Fusier CLA 2007-08-03 10:13:00 EDT
Verified for 3.4M1 using build I20070802-0800.