| /******************************************************************************* |
| * Copyright (c) 2000, 2005 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; |
| |
| import java.util.*; |
| |
| import org.eclipse.core.resources.*; |
| import org.eclipse.core.runtime.*; |
| |
| import org.eclipse.jdt.core.*; |
| import org.eclipse.jdt.core.compiler.CharOperation; |
| import org.eclipse.jdt.core.search.*; |
| import org.eclipse.jdt.internal.compiler.*; |
| import org.eclipse.jdt.internal.compiler.ast.*; |
| import org.eclipse.jdt.internal.compiler.env.AccessRestriction; |
| import org.eclipse.jdt.internal.compiler.env.AccessRuleSet; |
| import org.eclipse.jdt.internal.compiler.env.IGenericType; |
| import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; |
| import org.eclipse.jdt.internal.compiler.lookup.*; |
| import org.eclipse.jdt.internal.compiler.parser.Parser; |
| import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory; |
| import org.eclipse.jdt.internal.compiler.problem.ProblemReporter; |
| import org.eclipse.jdt.internal.core.*; |
| import org.eclipse.jdt.internal.core.search.indexing.*; |
| import org.eclipse.jdt.internal.core.search.matching.*; |
| import org.eclipse.jdt.internal.core.util.Messages; |
| |
| /** |
| * Search basic engine. Public search engine (see {@link org.eclipse.jdt.core.search.SearchEngine} |
| * for detailed comment), now uses basic engine functionalities. |
| * Note that serch basic engine does not implement deprecated functionalities... |
| */ |
| public class BasicSearchEngine { |
| |
| /* |
| * A default parser to parse non-reconciled working copies |
| */ |
| private Parser parser; |
| private CompilerOptions compilerOptions; |
| |
| /* |
| * A list of working copies that take precedence over their original |
| * compilation units. |
| */ |
| private ICompilationUnit[] workingCopies; |
| |
| /* |
| * A working copy owner whose working copies will take precedent over |
| * their original compilation units. |
| */ |
| private WorkingCopyOwner workingCopyOwner; |
| |
| /** |
| * For tracing purpose. |
| */ |
| public static boolean VERBOSE = false; |
| |
| /* |
| * Creates a new search basic engine. |
| */ |
| public BasicSearchEngine() { |
| // will use working copies of PRIMARY owner |
| } |
| |
| /** |
| * @see org.eclipse.jdt.core.search.SearchEngine#SearchEngine(ICompilationUnit[]) for detailed comment. |
| */ |
| public BasicSearchEngine(ICompilationUnit[] workingCopies) { |
| this.workingCopies = workingCopies; |
| } |
| |
| char convertTypeKind(int typeDeclarationKind) { |
| switch(typeDeclarationKind) { |
| case IGenericType.CLASS_DECL : return IIndexConstants.CLASS_SUFFIX; |
| case IGenericType.INTERFACE_DECL : return IIndexConstants.INTERFACE_SUFFIX; |
| case IGenericType.ENUM_DECL : return IIndexConstants.ENUM_SUFFIX; |
| case IGenericType.ANNOTATION_TYPE_DECL : return IIndexConstants.ANNOTATION_TYPE_SUFFIX; |
| default : return IIndexConstants.TYPE_SUFFIX; |
| } |
| } |
| /** |
| * @see org.eclipse.jdt.core.search.SearchEngine#SearchEngine(WorkingCopyOwner) for detailed comment. |
| */ |
| public BasicSearchEngine(WorkingCopyOwner workingCopyOwner) { |
| this.workingCopyOwner = workingCopyOwner; |
| } |
| |
| /** |
| * @see org.eclipse.jdt.core.search.SearchEngine#createHierarchyScope(IType) for detailed comment. |
| */ |
| public static IJavaSearchScope createHierarchyScope(IType type) throws JavaModelException { |
| return createHierarchyScope(type, DefaultWorkingCopyOwner.PRIMARY); |
| } |
| |
| /** |
| * @see org.eclipse.jdt.core.search.SearchEngine#createHierarchyScope(IType,WorkingCopyOwner) for detailed comment. |
| */ |
| public static IJavaSearchScope createHierarchyScope(IType type, WorkingCopyOwner owner) throws JavaModelException { |
| return new HierarchyScope(type, owner); |
| } |
| |
| /** |
| * @see org.eclipse.jdt.core.search.SearchEngine#createJavaSearchScope(IJavaElement[]) for detailed comment. |
| */ |
| public static IJavaSearchScope createJavaSearchScope(IJavaElement[] elements) { |
| return createJavaSearchScope(elements, true); |
| } |
| |
| /** |
| * @see org.eclipse.jdt.core.search.SearchEngine#createJavaSearchScope(IJavaElement[], boolean) for detailed comment. |
| */ |
| public static IJavaSearchScope createJavaSearchScope(IJavaElement[] elements, boolean includeReferencedProjects) { |
| int includeMask = IJavaSearchScope.SOURCES | IJavaSearchScope.APPLICATION_LIBRARIES | IJavaSearchScope.SYSTEM_LIBRARIES; |
| if (includeReferencedProjects) { |
| includeMask |= IJavaSearchScope.REFERENCED_PROJECTS; |
| } |
| return createJavaSearchScope(elements, includeMask); |
| } |
| |
| /** |
| * @see org.eclipse.jdt.core.search.SearchEngine#createJavaSearchScope(IJavaElement[], int) for detailed comment. |
| */ |
| public static IJavaSearchScope createJavaSearchScope(IJavaElement[] elements, int includeMask) { |
| JavaSearchScope scope = new JavaSearchScope(); |
| HashSet visitedProjects = new HashSet(2); |
| for (int i = 0, length = elements.length; i < length; i++) { |
| IJavaElement element = elements[i]; |
| if (element != null) { |
| try { |
| if (element instanceof JavaProject) { |
| scope.add((JavaProject)element, includeMask, visitedProjects); |
| } else { |
| scope.add(element); |
| } |
| } catch (JavaModelException e) { |
| // ignore |
| } |
| } |
| } |
| return scope; |
| } |
| |
| /** |
| * Returns a Java search scope with the workspace as the only limit. |
| * |
| * @return a new workspace scope |
| */ |
| public static IJavaSearchScope createWorkspaceScope() { |
| return JavaModelManager.getJavaModelManager().getWorkspaceScope(); |
| } |
| |
| /** |
| * Searches for matches to a given query. Search queries can be created using helper |
| * methods (from a String pattern or a Java element) and encapsulate the description of what is |
| * being searched (for example, search method declarations in a case sensitive way). |
| * |
| * @param scope the search result has to be limited to the given scope |
| * @param requestor a callback object to which each match is reported |
| */ |
| public void findMatches(SearchPattern pattern, SearchParticipant[] participants, IJavaSearchScope scope, SearchRequestor requestor, IProgressMonitor monitor) throws CoreException { |
| if (monitor != null && monitor.isCanceled()) throw new OperationCanceledException(); |
| |
| /* initialize progress monitor */ |
| if (monitor != null) |
| monitor.beginTask(Messages.engine_searching, 100); |
| if (BasicSearchEngine.VERBOSE) { |
| System.out.println("Searching for pattern: " + pattern.toString()); //$NON-NLS-1$ |
| System.out.println(scope); //$NON-NLS-1$ |
| } |
| |
| IndexManager indexManager = JavaModelManager.getJavaModelManager().getIndexManager(); |
| try { |
| requestor.beginReporting(); |
| for (int i = 0, l = participants == null ? 0 : participants.length; i < l; i++) { |
| if (monitor != null && monitor.isCanceled()) throw new OperationCanceledException(); |
| |
| SearchParticipant participant = participants[i]; |
| SubProgressMonitor subMonitor= monitor==null ? null : new SubProgressMonitor(monitor, 1000); |
| if (subMonitor != null) subMonitor.beginTask("", 1000); //$NON-NLS-1$ |
| try { |
| if (subMonitor != null) subMonitor.subTask(Messages.bind(Messages.engine_searching_indexing, new String[] {participant.getDescription()})); |
| participant.beginSearching(); |
| requestor.enterParticipant(participant); |
| PathCollector pathCollector = new PathCollector(); |
| indexManager.performConcurrentJob( |
| new PatternSearchJob(pattern, participant, scope, pathCollector), |
| IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH, |
| subMonitor); |
| if (monitor != null && monitor.isCanceled()) throw new OperationCanceledException(); |
| |
| // locate index matches if any (note that all search matches could have been issued during index querying) |
| if (subMonitor != null) subMonitor.subTask(Messages.bind(Messages.engine_searching_matching, new String[] {participant.getDescription()})); |
| String[] indexMatchPaths = pathCollector.getPaths(); |
| pathCollector = null; // release |
| int indexMatchLength = indexMatchPaths == null ? 0 : indexMatchPaths.length; |
| SearchDocument[] indexMatches = new SearchDocument[indexMatchLength]; |
| for (int j = 0; j < indexMatchLength; j++) |
| indexMatches[j] = participant.getDocument(indexMatchPaths[j]); |
| SearchDocument[] matches = MatchLocator.addWorkingCopies(pattern, indexMatches, getWorkingCopies(), participant); |
| participant.locateMatches(matches, pattern, scope, requestor, subMonitor); |
| } finally { |
| requestor.exitParticipant(participant); |
| participant.doneSearching(); |
| } |
| } |
| } finally { |
| requestor.endReporting(); |
| if (monitor != null) |
| monitor.done(); |
| } |
| } |
| /** |
| * Returns a new default Java search participant. |
| * |
| * @return a new default Java search participant |
| * @since 3.0 |
| */ |
| public static SearchParticipant getDefaultSearchParticipant() { |
| return new JavaSearchParticipant(); |
| } |
| |
| private Parser getParser() { |
| if (this.parser == null) { |
| this.compilerOptions = new CompilerOptions(JavaCore.getOptions()); |
| ProblemReporter problemReporter = |
| new ProblemReporter( |
| DefaultErrorHandlingPolicies.proceedWithAllProblems(), |
| this.compilerOptions, |
| new DefaultProblemFactory()); |
| this.parser = new Parser(problemReporter, true); |
| } |
| return this.parser; |
| } |
| |
| /** |
| * Returns the underlying resource of the given element. |
| * @param element an IJavaElement |
| * @return an IResource |
| */ |
| private IResource getResource(IJavaElement element) { |
| if (element instanceof IMember) { |
| ICompilationUnit cu = ((IMember)element).getCompilationUnit(); |
| if (cu != null) { |
| return cu.getResource(); |
| } |
| } |
| return element.getResource(); |
| } |
| |
| /* |
| * Returns the list of working copies used by this search engine. |
| * Returns null if none. |
| */ |
| private ICompilationUnit[] getWorkingCopies() { |
| ICompilationUnit[] copies; |
| if (this.workingCopies != null) { |
| if (this.workingCopyOwner == null) { |
| copies = JavaModelManager.getJavaModelManager().getWorkingCopies(DefaultWorkingCopyOwner.PRIMARY, false/*don't add primary WCs a second time*/); |
| if (copies == null) { |
| copies = this.workingCopies; |
| } else { |
| HashMap pathToCUs = new HashMap(); |
| for (int i = 0, length = copies.length; i < length; i++) { |
| ICompilationUnit unit = copies[i]; |
| pathToCUs.put(unit.getPath(), unit); |
| } |
| for (int i = 0, length = this.workingCopies.length; i < length; i++) { |
| ICompilationUnit unit = this.workingCopies[i]; |
| pathToCUs.put(unit.getPath(), unit); |
| } |
| int length = pathToCUs.size(); |
| copies = new ICompilationUnit[length]; |
| pathToCUs.values().toArray(copies); |
| } |
| } else { |
| copies = this.workingCopies; |
| } |
| } else if (this.workingCopyOwner != null) { |
| copies = JavaModelManager.getJavaModelManager().getWorkingCopies(this.workingCopyOwner, true/*add primary WCs*/); |
| } else { |
| copies = JavaModelManager.getJavaModelManager().getWorkingCopies(DefaultWorkingCopyOwner.PRIMARY, false/*don't add primary WCs a second time*/); |
| } |
| if (copies == null) return null; |
| |
| // filter out primary working copies that are saved |
| ICompilationUnit[] result = null; |
| int length = copies.length; |
| int index = 0; |
| for (int i = 0; i < length; i++) { |
| CompilationUnit copy = (CompilationUnit)copies[i]; |
| try { |
| if (!copy.isPrimary() |
| || copy.hasUnsavedChanges() |
| || copy.hasResourceChanged()) { |
| if (result == null) { |
| result = new ICompilationUnit[length]; |
| } |
| result[index++] = copy; |
| } |
| } catch (JavaModelException e) { |
| // copy doesn't exist: ignore |
| } |
| } |
| if (index != length && result != null) { |
| System.arraycopy(result, 0, result = new ICompilationUnit[index], 0, index); |
| } |
| return result; |
| } |
| |
| /** |
| * Returns the list of working copies used to do the search on the given Java element. |
| * @param element an IJavaElement |
| * @return an array of ICompilationUnit |
| */ |
| private ICompilationUnit[] getWorkingCopies(IJavaElement element) { |
| if (element instanceof IMember) { |
| ICompilationUnit cu = ((IMember)element).getCompilationUnit(); |
| if (cu != null && cu.isWorkingCopy()) { |
| ICompilationUnit[] copies = getWorkingCopies(); |
| int length = copies == null ? 0 : copies.length; |
| if (length > 0) { |
| ICompilationUnit[] newWorkingCopies = new ICompilationUnit[length+1]; |
| System.arraycopy(copies, 0, newWorkingCopies, 0, length); |
| newWorkingCopies[length] = cu; |
| return newWorkingCopies; |
| } |
| return new ICompilationUnit[] {cu}; |
| } |
| } |
| return getWorkingCopies(); |
| } |
| |
| boolean match(char patternTypeSuffix, int modifiers) { |
| switch(patternTypeSuffix) { |
| case IIndexConstants.CLASS_SUFFIX : |
| return (modifiers & (Flags.AccAnnotation | Flags.AccInterface | Flags.AccEnum)) == 0; |
| case IIndexConstants.CLASS_AND_INTERFACE_SUFFIX: |
| return (modifiers & (Flags.AccAnnotation | Flags.AccEnum)) == 0; |
| case IIndexConstants.CLASS_AND_ENUM_SUFFIX: |
| return (modifiers & (Flags.AccAnnotation | Flags.AccInterface)) == 0; |
| case IIndexConstants.INTERFACE_SUFFIX : |
| return (modifiers & Flags.AccInterface) != 0; |
| case IIndexConstants.ENUM_SUFFIX : |
| return (modifiers & Flags.AccEnum) != 0; |
| case IIndexConstants.ANNOTATION_TYPE_SUFFIX : |
| return (modifiers & Flags.AccAnnotation) != 0; |
| } |
| return true; |
| } |
| |
| boolean match(char patternTypeSuffix, char[] patternPkg, char[] patternTypeName, int matchRule, int typeKind, char[] pkg, char[] typeName) { |
| switch(patternTypeSuffix) { |
| case IIndexConstants.CLASS_SUFFIX : |
| if (typeKind != IGenericType.CLASS_DECL) return false; |
| break; |
| case IIndexConstants.CLASS_AND_INTERFACE_SUFFIX: |
| if (typeKind != IGenericType.CLASS_DECL && typeKind != IGenericType.INTERFACE_DECL) return false; |
| break; |
| case IIndexConstants.CLASS_AND_ENUM_SUFFIX: |
| if (typeKind != IGenericType.CLASS_DECL && typeKind != IGenericType.ENUM_DECL) return false; |
| break; |
| case IIndexConstants.INTERFACE_SUFFIX : |
| if (typeKind != IGenericType.INTERFACE_DECL) return false; |
| break; |
| case IIndexConstants.ENUM_SUFFIX : |
| if (typeKind != IGenericType.ENUM_DECL) return false; |
| break; |
| case IIndexConstants.ANNOTATION_TYPE_SUFFIX : |
| if (typeKind != IGenericType.ANNOTATION_TYPE_DECL) return false; |
| break; |
| case IIndexConstants.TYPE_SUFFIX : // nothing |
| } |
| |
| boolean isCaseSensitive = (matchRule & SearchPattern.R_CASE_SENSITIVE) != 0; |
| if (patternPkg != null && !CharOperation.equals(patternPkg, pkg, isCaseSensitive)) |
| return false; |
| |
| if (patternTypeName != null) { |
| int matchMode = matchRule - (isCaseSensitive ? SearchPattern.R_CASE_SENSITIVE : 0); |
| if (!isCaseSensitive) { |
| patternTypeName = CharOperation.toLowerCase(patternTypeName); |
| } |
| switch(matchMode) { |
| case SearchPattern.R_EXACT_MATCH : |
| return CharOperation.equals(patternTypeName, typeName, isCaseSensitive); |
| case SearchPattern.R_PREFIX_MATCH : |
| return CharOperation.prefixEquals(patternTypeName, typeName, isCaseSensitive); |
| case SearchPattern.R_PATTERN_MATCH : |
| return CharOperation.match(patternTypeName, typeName, isCaseSensitive); |
| } |
| } |
| return true; |
| |
| } |
| |
| /** |
| * Searches for matches of a given search pattern. Search patterns can be created using helper |
| * methods (from a String pattern or a Java element) and encapsulate the description of what is |
| * being searched (for example, search method declarations in a case sensitive way). |
| * |
| * @param pattern the pattern to search |
| * @param participants the particpants in the search |
| * @param scope the search scope |
| * @param requestor the requestor to report the matches to |
| * @param monitor the progress monitor used to report progress |
| * @exception CoreException if the search failed. Reasons include: |
| * <ul> |
| * <li>the classpath is incorrectly set</li> |
| * </ul> |
| *@since 3.0 |
| */ |
| public void search(SearchPattern pattern, SearchParticipant[] participants, IJavaSearchScope scope, SearchRequestor requestor, IProgressMonitor monitor) throws CoreException { |
| if (VERBOSE) { |
| System.out.println("BasicSearchEngine.search(SearchPattern, SearchParticipant[], IJavaSearchScope, SearchRequestor, IProgressMonitor)"); //$NON-NLS-1$ |
| } |
| findMatches(pattern, participants, scope, requestor, monitor); |
| } |
| |
| /** |
| * Searches for all top-level types and member types in the given scope. |
| * The search can be selecting specific types (given a package or a type name |
| * prefix and match modes). |
| * |
| * @param packageName the full name of the package of the searched types, or a prefix for this |
| * package, or a wild-carded string for this package. |
| * @param typeName the dot-separated qualified name of the searched type (the qualification include |
| * the enclosing types if the searched type is a member type), or a prefix |
| * for this type, or a wild-carded string for this type. |
| * @param matchRule one of |
| * <ul> |
| * <li><code>SearchPattern.R_EXACT_MATCH</code> if the package name and type name are the full names |
| * of the searched types.</li> |
| * <li><code>SearchPattern.R_PREFIX_MATCH</code> if the package name and type name are prefixes of the names |
| * of the searched types.</li> |
| * <li><code>SearchPattern.R_PATTERN_MATCH</code> if the package name and type name contain wild-cards.</li> |
| * </ul> |
| * combined with <code>SearchPattern.R_CASE_SENSITIVE</code>, |
| * e.g. <code>R_EXACT_MATCH | R_CASE_SENSITIVE</code> if an exact and case sensitive match is requested, |
| * or <code>R_PREFIX_MATCH</code> if a prefix non case sensitive match is requested. |
| * @param searchFor determines the nature of the searched elements |
| * <ul> |
| * <li>{@link IJavaSearchConstants#CLASS}: only look for classes</li> |
| * <li>{@link IJavaSearchConstants#INTERFACE}: only look for interfaces</li> |
| * <li>{@link IJavaSearchConstants#ENUM}: only look for enumeration</li> |
| * <li>{@link IJavaSearchConstants#ANNOTATION_TYPE}: only look for annotation type</li> |
| * <li>{@link IJavaSearchConstants#CLASS_AND_ENUM}: only look for classes and enumerations</li> |
| * <li>{@link IJavaSearchConstants#CLASS_AND_INTERFACE}: only look for classes and interfaces</li> |
| * <li>{@link IJavaSearchConstants#TYPE}: look for all types (ie. classes, interfaces, enum and annotation types)</li> |
| * </ul> |
| * @param scope the scope to search in |
| * @param nameRequestor the requestor that collects the results of the search |
| * @param waitingPolicy one of |
| * <ul> |
| * <li><code>IJavaSearchConstants.FORCE_IMMEDIATE_SEARCH</code> if the search should start immediately</li> |
| * <li><code>IJavaSearchConstants.CANCEL_IF_NOT_READY_TO_SEARCH</code> if the search should be cancelled if the |
| * underlying indexer has not finished indexing the workspace</li> |
| * <li><code>IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH</code> if the search should wait for the |
| * underlying indexer to finish indexing the workspace</li> |
| * </ul> |
| * @param progressMonitor the progress monitor to report progress to, or <code>null</code> if no progress |
| * monitor is provided |
| * @exception JavaModelException if the search failed. Reasons include: |
| * <ul> |
| * <li>the classpath is incorrectly set</li> |
| * </ul> |
| * @since 3.0 |
| */ |
| public void searchAllTypeNames( |
| final char[] packageName, |
| final char[] typeName, |
| final int matchRule, |
| int searchFor, |
| IJavaSearchScope scope, |
| final IRestrictedAccessTypeRequestor nameRequestor, |
| int waitingPolicy, |
| IProgressMonitor progressMonitor) throws JavaModelException { |
| |
| if (VERBOSE) { |
| System.out.println("BasicSearchEngine.searchAllTypeNames(char[], char[], int, int, IJavaSearchScope, IRestrictedAccessTypeRequestor, int, IProgressMonitor)"); //$NON-NLS-1$ |
| System.out.println(" - package name: "+(packageName==null?"null":new String(packageName))); //$NON-NLS-1$ //$NON-NLS-2$ |
| System.out.println(" - type name: "+(typeName==null?"null":new String(typeName))); //$NON-NLS-1$ //$NON-NLS-2$ |
| System.out.println(" - match rule: "+matchRule); //$NON-NLS-1$ |
| System.out.println(" - search for: "+searchFor); //$NON-NLS-1$ |
| System.out.println(" - scope: "+scope); //$NON-NLS-1$ |
| } |
| |
| IndexManager indexManager = JavaModelManager.getJavaModelManager().getIndexManager(); |
| |
| final char typeSuffix; |
| switch(searchFor){ |
| case IJavaSearchConstants.CLASS : |
| typeSuffix = IIndexConstants.CLASS_SUFFIX; |
| break; |
| case IJavaSearchConstants.CLASS_AND_INTERFACE : |
| typeSuffix = IIndexConstants.CLASS_AND_INTERFACE_SUFFIX; |
| break; |
| case IJavaSearchConstants.CLASS_AND_ENUM : |
| typeSuffix = IIndexConstants.CLASS_AND_ENUM_SUFFIX; |
| break; |
| case IJavaSearchConstants.INTERFACE : |
| typeSuffix = IIndexConstants.INTERFACE_SUFFIX; |
| break; |
| case IJavaSearchConstants.ENUM : |
| typeSuffix = IIndexConstants.ENUM_SUFFIX; |
| break; |
| case IJavaSearchConstants.ANNOTATION_TYPE : |
| typeSuffix = IIndexConstants.ANNOTATION_TYPE_SUFFIX; |
| break; |
| default : |
| typeSuffix = IIndexConstants.TYPE_SUFFIX; |
| break; |
| } |
| final TypeDeclarationPattern pattern = new TypeDeclarationPattern( |
| packageName, |
| null, // do find member types |
| typeName, |
| typeSuffix, |
| matchRule); |
| |
| final HashSet workingCopyPaths = new HashSet(); |
| ICompilationUnit[] copies = getWorkingCopies(); |
| if (copies != null) { |
| for (int i = 0, length = copies.length; i < length; i++) { |
| ICompilationUnit workingCopy = copies[i]; |
| workingCopyPaths.add(workingCopy.getPath().toString()); |
| } |
| } |
| |
| IndexQueryRequestor searchRequestor = new IndexQueryRequestor(){ |
| public boolean acceptIndexMatch(String documentPath, SearchPattern indexRecord, SearchParticipant participant, AccessRuleSet access) { |
| TypeDeclarationPattern record = (TypeDeclarationPattern)indexRecord; |
| AccessRestriction accessRestriction = null; |
| if (record.enclosingTypeNames != IIndexConstants.ONE_ZERO_CHAR // filter out local and anonymous classes |
| && !workingCopyPaths.contains(documentPath)) { // filter out working copies |
| if (access != null) { |
| // Compute document relative path |
| int pkgLength = (record.pkg==null || record.pkg.length==0) ? 0 : record.pkg.length+1; |
| int nameLength = record.simpleName==null ? 0 : record.simpleName.length; |
| char[] path = new char[pkgLength+nameLength]; |
| int pos = 0; |
| if (pkgLength > 0) { |
| System.arraycopy(record.pkg, 0, path, pos, pkgLength-1); |
| CharOperation.replace(path, '.', '/'); |
| path[pkgLength-1] = '/'; |
| pos += pkgLength; |
| } |
| if (nameLength > 0) { |
| System.arraycopy(record.simpleName, 0, path, pos, nameLength); |
| pos += nameLength; |
| } |
| // Update access restriction if path is not empty |
| if (pos > 0) { |
| accessRestriction = access.getViolatedRestriction(path); |
| } |
| } |
| if (match(record.typeSuffix, record.modifiers)) { |
| nameRequestor.acceptType(record.modifiers, record.pkg, record.simpleName, record.enclosingTypeNames, documentPath, accessRestriction); |
| } |
| } |
| return true; |
| } |
| }; |
| |
| try { |
| if (progressMonitor != null) { |
| progressMonitor.beginTask(Messages.engine_searching, 100); |
| } |
| // add type names from indexes |
| indexManager.performConcurrentJob( |
| new PatternSearchJob( |
| pattern, |
| getDefaultSearchParticipant(), // Java search only |
| scope, |
| searchRequestor), |
| waitingPolicy, |
| progressMonitor == null ? null : new SubProgressMonitor(progressMonitor, 100)); |
| |
| // add type names from working copies |
| if (copies != null) { |
| for (int i = 0, length = copies.length; i < length; i++) { |
| ICompilationUnit workingCopy = copies[i]; |
| final String path = workingCopy.getPath().toString(); |
| if (workingCopy.isConsistent()) { |
| IPackageDeclaration[] packageDeclarations = workingCopy.getPackageDeclarations(); |
| char[] packageDeclaration = packageDeclarations.length == 0 ? CharOperation.NO_CHAR : packageDeclarations[0].getElementName().toCharArray(); |
| IType[] allTypes = workingCopy.getAllTypes(); |
| for (int j = 0, allTypesLength = allTypes.length; j < allTypesLength; j++) { |
| IType type = allTypes[j]; |
| IJavaElement parent = type.getParent(); |
| char[][] enclosingTypeNames; |
| if (parent instanceof IType) { |
| char[] parentQualifiedName = ((IType)parent).getTypeQualifiedName('.').toCharArray(); |
| enclosingTypeNames = CharOperation.splitOn('.', parentQualifiedName); |
| } else { |
| enclosingTypeNames = CharOperation.NO_CHAR_CHAR; |
| } |
| char[] simpleName = type.getElementName().toCharArray(); |
| int kind; |
| if (type.isEnum()) { |
| kind = IGenericType.ENUM_DECL; |
| } else if (type.isAnnotation()) { |
| kind = IGenericType.ANNOTATION_TYPE_DECL; |
| } else if (type.isClass()) { |
| kind = IGenericType.CLASS_DECL; |
| } else /*if (type.isInterface())*/ { |
| kind = IGenericType.INTERFACE_DECL; |
| } |
| if (match(typeSuffix, packageName, typeName, matchRule, kind, packageDeclaration, simpleName)) { |
| nameRequestor.acceptType(type.getFlags(), packageDeclaration, simpleName, enclosingTypeNames, path, null); |
| } |
| } |
| } else { |
| Parser basicParser = getParser(); |
| final char[] contents = workingCopy.getBuffer().getCharacters(); |
| org.eclipse.jdt.internal.compiler.env.ICompilationUnit unit = new org.eclipse.jdt.internal.compiler.env.ICompilationUnit() { |
| public char[] getContents() { |
| return contents; |
| } |
| public char[] getMainTypeName() { |
| return null; |
| } |
| public char[][] getPackageName() { |
| return null; |
| } |
| public char[] getFileName() { |
| return null; |
| } |
| }; |
| CompilationResult compilationUnitResult = new CompilationResult(unit, 0, 0, this.compilerOptions.maxProblemsPerUnit); |
| CompilationUnitDeclaration parsedUnit = basicParser.dietParse(unit, compilationUnitResult); |
| if (parsedUnit != null) { |
| final char[] packageDeclaration = parsedUnit.currentPackage == null ? CharOperation.NO_CHAR : CharOperation.concatWith(parsedUnit.currentPackage.getImportName(), '.'); |
| class AllTypeDeclarationsVisitor extends ASTVisitor { |
| public boolean visit(TypeDeclaration typeDeclaration, BlockScope blockScope) { |
| return false; // no local/anonymous type |
| } |
| public boolean visit(TypeDeclaration typeDeclaration, CompilationUnitScope compilationUnitScope) { |
| if (match(typeSuffix, packageName, typeName, matchRule, typeDeclaration.kind(), packageDeclaration, typeDeclaration.name)) { |
| nameRequestor.acceptType(typeDeclaration.modifiers, packageDeclaration, typeDeclaration.name, CharOperation.NO_CHAR_CHAR, path, null); |
| } |
| return true; |
| } |
| public boolean visit(TypeDeclaration memberTypeDeclaration, ClassScope classScope) { |
| if (match(typeSuffix, packageName, typeName, matchRule, memberTypeDeclaration.kind(), packageDeclaration, memberTypeDeclaration.name)) { |
| // compute encloising type names |
| TypeDeclaration enclosing = memberTypeDeclaration.enclosingType; |
| char[][] enclosingTypeNames = CharOperation.NO_CHAR_CHAR; |
| while (enclosing != null) { |
| enclosingTypeNames = CharOperation.arrayConcat(new char[][] {enclosing.name}, enclosingTypeNames); |
| if ((enclosing.bits & ASTNode.IsMemberTypeMASK) != 0) { |
| enclosing = enclosing.enclosingType; |
| } else { |
| enclosing = null; |
| } |
| } |
| // report |
| nameRequestor.acceptType(memberTypeDeclaration.modifiers, packageDeclaration, memberTypeDeclaration.name, enclosingTypeNames, path, null); |
| } |
| return true; |
| } |
| } |
| parsedUnit.traverse(new AllTypeDeclarationsVisitor(), parsedUnit.scope); |
| } |
| } |
| } |
| } |
| } finally { |
| if (progressMonitor != null) { |
| progressMonitor.done(); |
| } |
| } |
| } |
| |
| /** |
| * Searches for all top-level types and member types in the given scope using a case sensitive exact match |
| * with the given qualified names and type names. |
| * |
| * @param qualifications the qualified name of the package/enclosing type of the searched types |
| * @param typeNames the simple names of the searched types |
| * @param scope the scope to search in |
| * @param nameRequestor the requestor that collects the results of the search |
| * @param waitingPolicy one of |
| * <ul> |
| * <li><code>IJavaSearchConstants.FORCE_IMMEDIATE_SEARCH</code> if the search should start immediately</li> |
| * <li><code>IJavaSearchConstants.CANCEL_IF_NOT_READY_TO_SEARCH</code> if the search should be cancelled if the |
| * underlying indexer has not finished indexing the workspace</li> |
| * <li><code>IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH</code> if the search should wait for the |
| * underlying indexer to finish indexing the workspace</li> |
| * </ul> |
| * @param progressMonitor the progress monitor to report progress to, or <code>null</code> if no progress |
| * monitor is provided |
| * @exception JavaModelException if the search failed. Reasons include: |
| * <ul> |
| * <li>the classpath is incorrectly set</li> |
| * </ul> |
| * @since 3.0 |
| */ |
| public void searchAllTypeNames( |
| final char[][] qualifications, |
| final char[][] typeNames, |
| final int matchRule, |
| int searchFor, |
| IJavaSearchScope scope, |
| final IRestrictedAccessTypeRequestor nameRequestor, |
| int waitingPolicy, |
| IProgressMonitor progressMonitor) throws JavaModelException { |
| |
| if (VERBOSE) { |
| System.out.println("BasicSearchEngine.searchAllTypeNames(char[][], char[][], int, int, IJavaSearchScope, IRestrictedAccessTypeRequestor, int, IProgressMonitor)"); //$NON-NLS-1$ |
| System.out.println(" - package name: "+(qualifications==null?"null":new String(CharOperation.concatWith(qualifications, ',')))); //$NON-NLS-1$ //$NON-NLS-2$ |
| System.out.println(" - type name: "+(typeNames==null?"null":new String(CharOperation.concatWith(typeNames, ',')))); //$NON-NLS-1$ //$NON-NLS-2$ |
| System.out.println(" - match rule: "+matchRule); //$NON-NLS-1$ |
| System.out.println(" - search for: "+searchFor); //$NON-NLS-1$ |
| System.out.println(" - scope: "+scope); //$NON-NLS-1$ |
| } |
| IndexManager indexManager = JavaModelManager.getJavaModelManager().getIndexManager(); |
| |
| final char typeSuffix; |
| switch(searchFor){ |
| case IJavaSearchConstants.CLASS : |
| typeSuffix = IIndexConstants.CLASS_SUFFIX; |
| break; |
| case IJavaSearchConstants.CLASS_AND_INTERFACE : |
| typeSuffix = IIndexConstants.CLASS_AND_INTERFACE_SUFFIX; |
| break; |
| case IJavaSearchConstants.CLASS_AND_ENUM : |
| typeSuffix = IIndexConstants.CLASS_AND_ENUM_SUFFIX; |
| break; |
| case IJavaSearchConstants.INTERFACE : |
| typeSuffix = IIndexConstants.INTERFACE_SUFFIX; |
| break; |
| case IJavaSearchConstants.ENUM : |
| typeSuffix = IIndexConstants.ENUM_SUFFIX; |
| break; |
| case IJavaSearchConstants.ANNOTATION_TYPE : |
| typeSuffix = IIndexConstants.ANNOTATION_TYPE_SUFFIX; |
| break; |
| default : |
| typeSuffix = IIndexConstants.TYPE_SUFFIX; |
| break; |
| } |
| final MultiTypeDeclarationPattern pattern = new MultiTypeDeclarationPattern(qualifications, typeNames, typeSuffix, matchRule); |
| |
| final HashSet workingCopyPaths = new HashSet(); |
| ICompilationUnit[] copies = getWorkingCopies(); |
| if (copies != null) { |
| for (int i = 0, length = copies.length; i < length; i++) { |
| ICompilationUnit workingCopy = copies[i]; |
| workingCopyPaths.add(workingCopy.getPath().toString()); |
| } |
| } |
| |
| IndexQueryRequestor searchRequestor = new IndexQueryRequestor(){ |
| public boolean acceptIndexMatch(String documentPath, SearchPattern indexRecord, SearchParticipant participant, AccessRuleSet access) { |
| if (!workingCopyPaths.contains(documentPath)) { // filter out working copies |
| QualifiedTypeDeclarationPattern record = (QualifiedTypeDeclarationPattern) indexRecord; |
| AccessRestriction accessRestriction = null; |
| if (access != null) { |
| // Compute document relative path |
| int qualificationLength = (record.qualification == null || record.qualification.length == 0) ? 0 : record.qualification.length + 1; |
| int nameLength = record.simpleName == null ? 0 : record.simpleName.length; |
| char[] path = new char[qualificationLength + nameLength]; |
| int pos = 0; |
| if (qualificationLength > 0) { |
| System.arraycopy(record.qualification, 0, path, pos, qualificationLength - 1); |
| CharOperation.replace(path, '.', '/'); |
| path[qualificationLength-1] = '/'; |
| pos += qualificationLength; |
| } |
| if (nameLength > 0) { |
| System.arraycopy(record.simpleName, 0, path, pos, nameLength); |
| pos += nameLength; |
| } |
| // Update access restriction if path is not empty |
| if (pos > 0) { |
| accessRestriction = access.getViolatedRestriction(path); |
| } |
| } |
| nameRequestor.acceptType(record.modifiers, record.getPackageName(), record.simpleName, record.getEnclosingTypeNames(), documentPath, accessRestriction); |
| } |
| return true; |
| } |
| }; |
| |
| try { |
| if (progressMonitor != null) { |
| progressMonitor.beginTask(Messages.engine_searching, 100); |
| } |
| // add type names from indexes |
| indexManager.performConcurrentJob( |
| new PatternSearchJob( |
| pattern, |
| getDefaultSearchParticipant(), // Java search only |
| scope, |
| searchRequestor), |
| waitingPolicy, |
| progressMonitor == null ? null : new SubProgressMonitor(progressMonitor, 100)); |
| |
| // add type names from working copies |
| if (copies != null) { |
| for (int i = 0, length = copies.length; i < length; i++) { |
| ICompilationUnit workingCopy = copies[i]; |
| final String path = workingCopy.getPath().toString(); |
| if (workingCopy.isConsistent()) { |
| IPackageDeclaration[] packageDeclarations = workingCopy.getPackageDeclarations(); |
| char[] packageDeclaration = packageDeclarations.length == 0 ? CharOperation.NO_CHAR : packageDeclarations[0].getElementName().toCharArray(); |
| IType[] allTypes = workingCopy.getAllTypes(); |
| for (int j = 0, allTypesLength = allTypes.length; j < allTypesLength; j++) { |
| IType type = allTypes[j]; |
| IJavaElement parent = type.getParent(); |
| char[][] enclosingTypeNames; |
| char[] qualification = packageDeclaration; |
| if (parent instanceof IType) { |
| char[] parentQualifiedName = ((IType)parent).getTypeQualifiedName('.').toCharArray(); |
| enclosingTypeNames = CharOperation.splitOn('.', parentQualifiedName); |
| qualification = CharOperation.concat(qualification, parentQualifiedName); |
| } else { |
| enclosingTypeNames = CharOperation.NO_CHAR_CHAR; |
| } |
| char[] simpleName = type.getElementName().toCharArray(); |
| char suffix = IIndexConstants.TYPE_SUFFIX; |
| if (type.isClass()) { |
| suffix = IIndexConstants.CLASS_SUFFIX; |
| } else if (type.isInterface()) { |
| suffix = IIndexConstants.INTERFACE_SUFFIX; |
| } else if (type.isEnum()) { |
| suffix = IIndexConstants.ENUM_SUFFIX; |
| } else if (type.isAnnotation()) { |
| suffix = IIndexConstants.ANNOTATION_TYPE_SUFFIX; |
| } |
| if (pattern.matchesDecodedKey(new QualifiedTypeDeclarationPattern(qualification, simpleName, suffix, matchRule))) { |
| nameRequestor.acceptType(type.getFlags(), packageDeclaration, simpleName, enclosingTypeNames, path, null); |
| } |
| } |
| } else { |
| Parser basicParser = getParser(); |
| final char[] contents = workingCopy.getBuffer().getCharacters(); |
| org.eclipse.jdt.internal.compiler.env.ICompilationUnit unit = new org.eclipse.jdt.internal.compiler.env.ICompilationUnit() { |
| public char[] getContents() { |
| return contents; |
| } |
| public char[] getMainTypeName() { |
| return null; |
| } |
| public char[][] getPackageName() { |
| return null; |
| } |
| public char[] getFileName() { |
| return null; |
| } |
| }; |
| CompilationResult compilationUnitResult = new CompilationResult(unit, 0, 0, this.compilerOptions.maxProblemsPerUnit); |
| CompilationUnitDeclaration parsedUnit = basicParser.dietParse(unit, compilationUnitResult); |
| if (parsedUnit != null) { |
| final char[] packageDeclaration = parsedUnit.currentPackage == null |
| ? CharOperation.NO_CHAR |
| : CharOperation.concatWith(parsedUnit.currentPackage.getImportName(), '.'); |
| class AllTypeDeclarationsVisitor extends ASTVisitor { |
| public boolean visit(TypeDeclaration typeDeclaration, BlockScope blockScope) { |
| return false; // no local/anonymous type |
| } |
| public boolean visit(TypeDeclaration typeDeclaration, CompilationUnitScope compilationUnitScope) { |
| SearchPattern decodedPattern = |
| new QualifiedTypeDeclarationPattern(packageDeclaration, typeDeclaration.name, convertTypeKind(typeDeclaration.kind()), matchRule); |
| if (pattern.matchesDecodedKey(decodedPattern)) { |
| nameRequestor.acceptType(typeDeclaration.modifiers, packageDeclaration, typeDeclaration.name, CharOperation.NO_CHAR_CHAR, path, null); |
| } |
| return true; |
| } |
| public boolean visit(TypeDeclaration memberTypeDeclaration, ClassScope classScope) { |
| // compute encloising type names |
| char[] qualification = packageDeclaration; |
| TypeDeclaration enclosing = memberTypeDeclaration.enclosingType; |
| char[][] enclosingTypeNames = CharOperation.NO_CHAR_CHAR; |
| while (enclosing != null) { |
| qualification = CharOperation.concat(qualification, enclosing.name, '.'); |
| enclosingTypeNames = CharOperation.arrayConcat(new char[][] {enclosing.name}, enclosingTypeNames); |
| if ((enclosing.bits & ASTNode.IsMemberTypeMASK) != 0) { |
| enclosing = enclosing.enclosingType; |
| } else { |
| enclosing = null; |
| } |
| } |
| SearchPattern decodedPattern = |
| new QualifiedTypeDeclarationPattern(qualification, memberTypeDeclaration.name, convertTypeKind(memberTypeDeclaration.kind()), matchRule); |
| if (pattern.matchesDecodedKey(decodedPattern)) { |
| nameRequestor.acceptType(memberTypeDeclaration.modifiers, packageDeclaration, memberTypeDeclaration.name, enclosingTypeNames, path, null); |
| } |
| return true; |
| } |
| } |
| parsedUnit.traverse(new AllTypeDeclarationsVisitor(), parsedUnit.scope); |
| } |
| } |
| } |
| } |
| } finally { |
| if (progressMonitor != null) { |
| progressMonitor.done(); |
| } |
| } |
| } |
| |
| public void searchDeclarations(IJavaElement enclosingElement, SearchRequestor requestor, SearchPattern pattern, IProgressMonitor monitor) throws JavaModelException { |
| if (VERBOSE) { |
| System.out.println(" - java element: "+enclosingElement); //$NON-NLS-1$ |
| } |
| IJavaSearchScope scope = createJavaSearchScope(new IJavaElement[] {enclosingElement}); |
| IResource resource = this.getResource(enclosingElement); |
| try { |
| if (resource instanceof IFile) { |
| try { |
| requestor.beginReporting(); |
| if (VERBOSE) { |
| System.out.println("Searching for " + pattern + " in " + resource.getFullPath()); //$NON-NLS-1$//$NON-NLS-2$ |
| } |
| SearchParticipant participant = getDefaultSearchParticipant(); |
| SearchDocument[] documents = MatchLocator.addWorkingCopies( |
| pattern, |
| new SearchDocument[] {new JavaSearchDocument(enclosingElement.getPath().toString(), participant)}, |
| getWorkingCopies(enclosingElement), |
| participant); |
| participant.locateMatches( |
| documents, |
| pattern, |
| scope, |
| requestor, |
| monitor); |
| } finally { |
| requestor.endReporting(); |
| } |
| } else { |
| search( |
| pattern, |
| new SearchParticipant[] {getDefaultSearchParticipant()}, |
| scope, |
| requestor, |
| monitor); |
| } |
| } catch (CoreException e) { |
| if (e instanceof JavaModelException) |
| throw (JavaModelException) e; |
| throw new JavaModelException(e); |
| } |
| } |
| |
| /** |
| * Searches for all declarations of the fields accessed in the given element. |
| * The element can be a compilation unit, a source type, or a source method. |
| * Reports the field declarations using the given requestor. |
| * <p> |
| * Consider the following code: |
| * <code> |
| * <pre> |
| * class A { |
| * int field1; |
| * } |
| * class B extends A { |
| * String value; |
| * } |
| * class X { |
| * void test() { |
| * B b = new B(); |
| * System.out.println(b.value + b.field1); |
| * }; |
| * } |
| * </pre> |
| * </code> |
| * then searching for declarations of accessed fields in method |
| * <code>X.test()</code> would collect the fields |
| * <code>B.value</code> and <code>A.field1</code>. |
| * </p> |
| * |
| * @param enclosingElement the method, type, or compilation unit to be searched in |
| * @param requestor a callback object to which each match is reported |
| * @param monitor the progress monitor used to report progress |
| * @exception JavaModelException if the search failed. Reasons include: |
| * <ul> |
| * <li>the element doesn't exist</li> |
| * <li>the classpath is incorrectly set</li> |
| * </ul> |
| * @since 3.0 |
| */ |
| public void searchDeclarationsOfAccessedFields(IJavaElement enclosingElement, SearchRequestor requestor, IProgressMonitor monitor) throws JavaModelException { |
| if (VERBOSE) { |
| System.out.println("BasicSearchEngine.searchDeclarationsOfAccessedFields(IJavaElement, SearchRequestor, SearchPattern, IProgressMonitor)"); //$NON-NLS-1$ |
| } |
| SearchPattern pattern = new DeclarationOfAccessedFieldsPattern(enclosingElement); |
| searchDeclarations(enclosingElement, requestor, pattern, monitor); |
| } |
| |
| /** |
| * Searches for all declarations of the types referenced in the given element. |
| * The element can be a compilation unit, a source type, or a source method. |
| * Reports the type declarations using the given requestor. |
| * <p> |
| * Consider the following code: |
| * <code> |
| * <pre> |
| * class A { |
| * } |
| * class B extends A { |
| * } |
| * interface I { |
| * int VALUE = 0; |
| * } |
| * class X { |
| * void test() { |
| * B b = new B(); |
| * this.foo(b, I.VALUE); |
| * }; |
| * } |
| * </pre> |
| * </code> |
| * then searching for declarations of referenced types in method <code>X.test()</code> |
| * would collect the class <code>B</code> and the interface <code>I</code>. |
| * </p> |
| * |
| * @param enclosingElement the method, type, or compilation unit to be searched in |
| * @param requestor a callback object to which each match is reported |
| * @param monitor the progress monitor used to report progress |
| * @exception JavaModelException if the search failed. Reasons include: |
| * <ul> |
| * <li>the element doesn't exist</li> |
| * <li>the classpath is incorrectly set</li> |
| * </ul> |
| * @since 3.0 |
| */ |
| public void searchDeclarationsOfReferencedTypes(IJavaElement enclosingElement, SearchRequestor requestor, IProgressMonitor monitor) throws JavaModelException { |
| if (VERBOSE) { |
| System.out.println("BasicSearchEngine.searchDeclarationsOfReferencedTypes(IJavaElement, SearchRequestor, SearchPattern, IProgressMonitor)"); //$NON-NLS-1$ |
| } |
| SearchPattern pattern = new DeclarationOfReferencedTypesPattern(enclosingElement); |
| searchDeclarations(enclosingElement, requestor, pattern, monitor); |
| } |
| |
| /** |
| * Searches for all declarations of the methods invoked in the given element. |
| * The element can be a compilation unit, a source type, or a source method. |
| * Reports the method declarations using the given requestor. |
| * <p> |
| * Consider the following code: |
| * <code> |
| * <pre> |
| * class A { |
| * void foo() {}; |
| * void bar() {}; |
| * } |
| * class B extends A { |
| * void foo() {}; |
| * } |
| * class X { |
| * void test() { |
| * A a = new B(); |
| * a.foo(); |
| * B b = (B)a; |
| * b.bar(); |
| * }; |
| * } |
| * </pre> |
| * </code> |
| * then searching for declarations of sent messages in method |
| * <code>X.test()</code> would collect the methods |
| * <code>A.foo()</code>, <code>B.foo()</code>, and <code>A.bar()</code>. |
| * </p> |
| * |
| * @param enclosingElement the method, type, or compilation unit to be searched in |
| * @param requestor a callback object to which each match is reported |
| * @param monitor the progress monitor used to report progress |
| * @exception JavaModelException if the search failed. Reasons include: |
| * <ul> |
| * <li>the element doesn't exist</li> |
| * <li>the classpath is incorrectly set</li> |
| * </ul> |
| * @since 3.0 |
| */ |
| public void searchDeclarationsOfSentMessages(IJavaElement enclosingElement, SearchRequestor requestor, IProgressMonitor monitor) throws JavaModelException { |
| if (VERBOSE) { |
| System.out.println("BasicSearchEngine.searchDeclarationsOfSentMessages(IJavaElement, SearchRequestor, SearchPattern, IProgressMonitor)"); //$NON-NLS-1$ |
| } |
| SearchPattern pattern = new DeclarationOfReferencedMethodsPattern(enclosingElement); |
| searchDeclarations(enclosingElement, requestor, pattern, monitor); |
| } |
| } |