Bug 196339

Summary: [search] SearchEngine not returning correct result
Product: [Eclipse Project] JDT Reporter: Máirtín <sshshtgttsbiow>
Component: CoreAssignee: Frederic Fusier <frederic_fusier>
Status: VERIFIED FIXED QA Contact:
Severity: normal    
Priority: P3    
Version: 3.3   
Target Milestone: 3.4 M1   
Hardware: PC   
OS: Windows XP   
Whiteboard:
Attachments:
Description Flags
Proposed patch none

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.