From d78c26534ac670f0684759e5ebf5489150d9a7a8 Mon Sep 17 00:00:00 2001 From: Doug Schaefer Date: Thu, 9 Mar 2006 19:31:31 +0000 Subject: [PATCH] PDOM Search - more functional now. Satisfies simple searches. --- .../org/eclipse/cdt/core/dom/IPDOM.java | 2 - .../internal/core/dom/parser/c/CVisitor.java | 7 --- .../core/dom/parser/cpp/CPPSemantics.java | 9 +--- .../cdt/internal/core/pdom/PDOMDatabase.java | 11 ++++- .../internal/core/pdom/dom/PDOMLinkage.java | 36 +++++++++++++++ .../core/pdom/dom/c/PDOMCLinkage.java | 6 +++ .../core/pdom/dom/cpp/PDOMCPPLinkage.java | 7 +++ .../ui/search/PDOMSearchBindingQuery.java | 28 +----------- .../internal/ui/search/PDOMSearchPage.java | 30 ++++++++++--- .../ui/search/PDOMSearchPatternQuery.java | 45 +++++++++++++++++-- .../internal/ui/search/PDOMSearchQuery.java | 37 +++++++++++++++ 11 files changed, 164 insertions(+), 54 deletions(-) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/IPDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/IPDOM.java index 7d6c561319c..af50aa132c4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/IPDOM.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/IPDOM.java @@ -26,8 +26,6 @@ public interface IPDOM { public IBinding resolveBinding(IASTName name); - public IBinding[] resolvePrefix(IASTName name); - public IASTName[] getDeclarations(IBinding binding); public void delete() throws CoreException; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java index e7bccf53498..4c31280d150 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java @@ -1906,13 +1906,6 @@ public class CVisitor { } } - IASTTranslationUnit tu = name.getTranslationUnit(); - if (tu != null) { - IPDOM pdom = tu.getIndex(); - if (pdom != null) - result = (IBinding[])ArrayUtil.addAll(IBinding.class, result, pdom.resolvePrefix(name)); - } - return (IBinding[]) ArrayUtil.trim( IBinding.class, result ); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java index 9838cfe81fa..d3ab571d5e7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java @@ -1466,7 +1466,7 @@ public class CPPSemantics { item = nodes[idx]; } else { item = null; - nullItem: while( item == null ){ + while( item == null ){ if( namespaceIdx > -1 ) { //check all definitions of this namespace while( namespaceIdx > -1 && namespaceDefs.length > ++namespaceIdx ){ @@ -3279,13 +3279,6 @@ public class CPPSemantics { } } - IASTTranslationUnit tu = name.getTranslationUnit(); - if (tu != null) { - IPDOM pdom = tu.getIndex(); - if (pdom != null) - result = (IBinding[])ArrayUtil.addAll(IBinding.class, result, pdom.resolvePrefix(name)); - } - return (IBinding[]) ArrayUtil.trim( IBinding.class, result ); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMDatabase.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMDatabase.java index 349b85ae235..ec94f821d84 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMDatabase.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMDatabase.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom; +import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; import java.util.List; @@ -191,8 +192,14 @@ public class PDOMDatabase implements IPDOM { return null; } - public IBinding[] resolvePrefix(IASTName name) { - return new IBinding[0]; + public PDOMBinding[] findBindings(String pattern) throws CoreException { + List bindings = new ArrayList(); + PDOMLinkage linkage = getFirstLinkage(); + while (linkage != null) { + linkage.findBindings(pattern, bindings); + linkage = linkage.getNextLinkage(); + } + return (PDOMBinding[])bindings.toArray(new PDOMBinding[bindings.size()]); } public PDOMLinkage getLinkage(ILanguage language) throws CoreException { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java index 8fc671b72f2..5f409526b07 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java @@ -11,11 +11,16 @@ package org.eclipse.cdt.internal.core.pdom.dom; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.internal.core.pdom.PDOMDatabase; import org.eclipse.cdt.internal.core.pdom.db.BTree; import org.eclipse.cdt.internal.core.pdom.db.Database; +import org.eclipse.cdt.internal.core.pdom.db.IBTreeVisitor; import org.eclipse.core.runtime.CoreException; /** @@ -26,6 +31,35 @@ import org.eclipse.core.runtime.CoreException; */ public abstract class PDOMLinkage extends PDOMNode { + protected static final class MatchBinding implements IBTreeVisitor { + private final PDOMDatabase pdom; + private final List bindings; + private final Pattern pattern; + + public MatchBinding(PDOMDatabase pdom, String pattern, List bindings) { + this.pdom = pdom; + this.bindings = bindings; + this.pattern = Pattern.compile(pattern); + } + + public boolean visit(int record) throws CoreException { + if (record == 0) + return true; + + // TODO of course do something smarter here + PDOMBinding binding = pdom.getBinding(record); + if (binding != null) { + Matcher matcher = pattern.matcher(binding.getName()); + if (matcher.matches()) + bindings.add(binding); + } + return true; + } + public int compare(int record) throws CoreException { + return 1; + } + } + private static final int ID_OFFSET = PDOMNode.RECORD_SIZE + 0; private static final int NEXT_OFFSET = PDOMNode.RECORD_SIZE + 4; private static final int INDEX_OFFSET = PDOMNode.RECORD_SIZE + 8; @@ -88,5 +122,7 @@ public abstract class PDOMLinkage extends PDOMNode { public abstract PDOMBinding getBinding(int record) throws CoreException; public abstract PDOMBinding resolveBinding(IASTName name) throws CoreException; + + public abstract void findBindings(String pattern, List bindings) throws CoreException; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCLinkage.java index 507e7ff8e7b..72ab5e50c62 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCLinkage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCLinkage.java @@ -11,6 +11,8 @@ package org.eclipse.cdt.internal.core.pdom.dom.c; +import java.util.List; + import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement; import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression; import org.eclipse.cdt.core.dom.ast.IASTIdExpression; @@ -208,4 +210,8 @@ public class PDOMCLinkage extends PDOMLinkage { return null; } + public void findBindings(String pattern, List bindings) throws CoreException { + MatchBinding visitor = new MatchBinding(pdom, pattern, bindings); + getIndex().visit(visitor); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java index a6309a2b2f5..d2988cd7ae6 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java @@ -11,6 +11,8 @@ package org.eclipse.cdt.internal.core.pdom.dom.cpp; +import java.util.List; + import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression; import org.eclipse.cdt.core.dom.ast.IASTIdExpression; import org.eclipse.cdt.core.dom.ast.IASTName; @@ -252,4 +254,9 @@ public class PDOMCPPLinkage extends PDOMLinkage { return null; } + public void findBindings(String pattern, List bindings) throws CoreException { + MatchBinding visitor = new MatchBinding(pdom, pattern, bindings); + getIndex().visit(visitor); + } + } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchBindingQuery.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchBindingQuery.java index 9c01b868690..786a5f6b59d 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchBindingQuery.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchBindingQuery.java @@ -11,9 +11,7 @@ package org.eclipse.cdt.internal.ui.search; -import org.eclipse.cdt.core.dom.ast.IASTFileLocation; import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding; -import org.eclipse.cdt.internal.core.pdom.dom.PDOMName; import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; @@ -37,31 +35,7 @@ public class PDOMSearchBindingQuery extends PDOMSearchQuery { public IStatus run(IProgressMonitor monitor) throws OperationCanceledException { try { - if ((flags & FIND_DECLARATIONS) != 0) { - PDOMName name = binding.getFirstDeclaration(); - while (name != null) { - IASTFileLocation loc = name.getFileLocation(); - result.addMatch(new PDOMSearchMatch(name, loc.getNodeOffset(), loc.getNodeLength())); - name = name.getNextInBinding(); - } - } - if ((flags & (FIND_DECLARATIONS)) != 0) { - // for decls we do defs too - PDOMName name = binding.getFirstDefinition(); - while (name != null) { - IASTFileLocation loc = name.getFileLocation(); - result.addMatch(new PDOMSearchMatch(name, loc.getNodeOffset(), loc.getNodeLength())); - name = name.getNextInBinding(); - } - } - if ((flags & FIND_REFERENCES) != 0) { - PDOMName name = binding.getFirstReference(); - while (name != null) { - IASTFileLocation loc = name.getFileLocation(); - result.addMatch(new PDOMSearchMatch(name, loc.getNodeOffset(), loc.getNodeLength())); - name = name.getNextInBinding(); - } - } + createMatches(binding); return Status.OK_STATUS; } catch (CoreException e) { return new Status(IStatus.ERROR, CUIPlugin.PLUGIN_ID, 0, e.getLocalizedMessage(), e); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchPage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchPage.java index 96e7c28f6f6..5f9b73b16e2 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchPage.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchPage.java @@ -234,8 +234,27 @@ public class PDOMSearchPage extends DialogPage implements ISearchPage { IDialogSettings settings = getDialogSettings(); settings.put(STORE_CASE_SENSITIVE, isCaseSensitive); - if (previousPatterns != null) - settings.put(STORE_PREVIOUS_PATTERNS, previousPatterns); + if (previousPatterns == null) + previousPatterns = new String[] { pattern }; + else { + // Add only if we don't have it already + boolean addit = true; + for (int i = 0; i < previousPatterns.length; ++i) { + if (pattern.equals(previousPatterns[i])) { + addit = false; + break; + } + } + if (addit) { + // Insert it into the beginning of the list + String[] newPatterns = new String[previousPatterns.length + 1]; + System.arraycopy(previousPatterns, 0, newPatterns, 1, previousPatterns.length); + newPatterns[0] = pattern; + previousPatterns = newPatterns; + } + } + + settings.put(STORE_PREVIOUS_PATTERNS, previousPatterns); settings.put(STORE_SEARCH_FLAGS, searchFlags); @@ -452,6 +471,10 @@ public class PDOMSearchPage extends DialogPage implements ISearchPage { // Int was unitialized, assume the defaults } + previousPatterns = settings.getArray(STORE_PREVIOUS_PATTERNS); + if (previousPatterns != null) + patternCombo.setItems(previousPatterns); + // Initialize the selection ISelection selection = getContainer().getSelection(); if (selection instanceof IStructuredSelection) { @@ -510,9 +533,6 @@ public class PDOMSearchPage extends DialogPage implements ISearchPage { // the selection is valid. } - String[] previousPatterns = settings.getArray(STORE_PREVIOUS_PATTERNS); - if (previousPatterns != null) - patternCombo.setItems(previousPatterns); caseSensitiveButton.setSelection(settings.getBoolean(STORE_CASE_SENSITIVE)); if ((searchFlags & PDOMSearchPatternQuery.FIND_ALL_TYPES) == PDOMSearchPatternQuery.FIND_ALL_TYPES) { diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchPatternQuery.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchPatternQuery.java index 563187525d0..7d879395304 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchPatternQuery.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchPatternQuery.java @@ -11,8 +11,18 @@ package org.eclipse.cdt.internal.ui.search; -import org.eclipse.cdt.core.model.ICElement; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.cdt.core.dom.PDOM; +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.internal.core.pdom.PDOMDatabase; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding; +import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.OperationCanceledException; @@ -58,8 +68,37 @@ public class PDOMSearchPatternQuery extends PDOMSearchQuery { } public IStatus run(IProgressMonitor monitor) throws OperationCanceledException { - // TODO Auto-generated method stub - return Status.OK_STATUS; + // get the list of projects we need to search + List projects = new ArrayList(); + for (int i = 0; i < scope.length; ++i) { + if (scope[i] instanceof IWorkspaceRoot) { + IProject[] p = ((IWorkspaceRoot)scope[i]).getProjects(); + for (int j = 0; j < p.length; ++j) + projects.add(p[j]); + } else + projects.add(scope[i].getProject()); + } + + try { + for (Iterator iproject = projects.iterator(); iproject.hasNext();) + searchProject((IProject)iproject.next()); + return Status.OK_STATUS; + } catch (CoreException e) { + return e.getStatus(); + } + } + + private void searchProject(IProject project) throws CoreException { + if (!CoreModel.hasCNature(project)) + // Not a CDT project + return; + + PDOMDatabase pdom = (PDOMDatabase)PDOM.getPDOM(project); + PDOMBinding[] bindings = pdom.findBindings(pattern); + + for (int i = 0; i < bindings.length; ++i) { + createMatches(bindings[i]); + } } public String getLabel() { diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchQuery.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchQuery.java index bd9d3e6a674..221b415ac11 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchQuery.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchQuery.java @@ -11,6 +11,10 @@ package org.eclipse.cdt.internal.ui.search; +import org.eclipse.cdt.core.dom.ast.IASTFileLocation; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMName; +import org.eclipse.core.runtime.CoreException; import org.eclipse.search.ui.ISearchQuery; import org.eclipse.search.ui.ISearchResult; @@ -55,4 +59,37 @@ public abstract class PDOMSearchQuery implements ISearchQuery { return result; } + /** + * Return true to filter name out of the match list. + * Override in a subclass to add scoping. + * @param name + * @return true to filter name out of the match list + */ + protected boolean filterName(PDOMName name) { + return false; // i.e. keep it + } + + private void collectNames(PDOMName name) throws CoreException { + while (name != null) { + if (!filterName(name)) { + IASTFileLocation loc = name.getFileLocation(); + result.addMatch(new PDOMSearchMatch(name, loc.getNodeOffset(), loc.getNodeLength())); + name = name.getNextInBinding(); + } + } + } + + protected void createMatches(PDOMBinding binding) throws CoreException { + if ((flags & FIND_DECLARATIONS) != 0) { + collectNames(binding.getFirstDeclaration()); + } + if ((flags & FIND_DECLARATIONS) != 0) { + collectNames(binding.getFirstDefinition()); + } + if ((flags & FIND_REFERENCES) != 0) { + collectNames(binding.getFirstReference()); + } + + } + }