| /******************************************************************************* |
| * Copyright (c) 2000, 2011 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 |
| * Stephan Herrmann - contribution for bug 337868 - [compiler][model] incomplete support for package-info.java when using SearchableEnvironment |
| *******************************************************************************/ |
| package org.eclipse.jdt.internal.core; |
| |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.OperationCanceledException; |
| import org.eclipse.jdt.core.*; |
| import org.eclipse.jdt.core.compiler.CharOperation; |
| import org.eclipse.jdt.core.search.*; |
| import org.eclipse.jdt.internal.codeassist.ISearchRequestor; |
| import org.eclipse.jdt.internal.compiler.env.AccessRestriction; |
| import org.eclipse.jdt.internal.compiler.env.IBinaryType; |
| import org.eclipse.jdt.internal.compiler.env.ICompilationUnit; |
| import org.eclipse.jdt.internal.compiler.env.INameEnvironment; |
| import org.eclipse.jdt.internal.compiler.env.ISourceType; |
| import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer; |
| import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; |
| import org.eclipse.jdt.internal.core.search.BasicSearchEngine; |
| import org.eclipse.jdt.internal.core.search.IRestrictedAccessConstructorRequestor; |
| import org.eclipse.jdt.internal.core.search.IRestrictedAccessTypeRequestor; |
| import org.eclipse.jdt.internal.core.search.indexing.IndexManager; |
| import org.eclipse.jdt.internal.core.util.Util; |
| |
| /** |
| * This class provides a <code>SearchableBuilderEnvironment</code> for code assist which |
| * uses the Java model as a search tool. |
| */ |
| public class SearchableEnvironment |
| implements INameEnvironment, IJavaSearchConstants { |
| |
| public NameLookup nameLookup; |
| protected ICompilationUnit unitToSkip; |
| protected org.eclipse.jdt.core.ICompilationUnit[] workingCopies; |
| protected WorkingCopyOwner owner; |
| |
| protected JavaProject project; |
| protected IJavaSearchScope searchScope; |
| |
| protected boolean checkAccessRestrictions; |
| |
| /** |
| * Creates a SearchableEnvironment on the given project |
| */ |
| public SearchableEnvironment(JavaProject project, org.eclipse.jdt.core.ICompilationUnit[] workingCopies) throws JavaModelException { |
| this.project = project; |
| this.checkAccessRestrictions = |
| !JavaCore.IGNORE.equals(project.getOption(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE, true)) |
| || !JavaCore.IGNORE.equals(project.getOption(JavaCore.COMPILER_PB_DISCOURAGED_REFERENCE, true)); |
| this.workingCopies = workingCopies; |
| this.nameLookup = project.newNameLookup(workingCopies); |
| } |
| |
| /** |
| * Creates a SearchableEnvironment on the given project |
| */ |
| public SearchableEnvironment(JavaProject project, WorkingCopyOwner owner) throws JavaModelException { |
| this(project, owner == null ? null : JavaModelManager.getJavaModelManager().getWorkingCopies(owner, true/*add primary WCs*/)); |
| this.owner = owner; |
| } |
| |
| private static int convertSearchFilterToModelFilter(int searchFilter) { |
| switch (searchFilter) { |
| case IJavaSearchConstants.CLASS: |
| return NameLookup.ACCEPT_CLASSES; |
| case IJavaSearchConstants.INTERFACE: |
| return NameLookup.ACCEPT_INTERFACES; |
| case IJavaSearchConstants.ENUM: |
| return NameLookup.ACCEPT_ENUMS; |
| case IJavaSearchConstants.ANNOTATION_TYPE: |
| return NameLookup.ACCEPT_ANNOTATIONS; |
| case IJavaSearchConstants.CLASS_AND_ENUM: |
| return NameLookup.ACCEPT_CLASSES | NameLookup.ACCEPT_ENUMS; |
| case IJavaSearchConstants.CLASS_AND_INTERFACE: |
| return NameLookup.ACCEPT_CLASSES | NameLookup.ACCEPT_INTERFACES; |
| default: |
| return NameLookup.ACCEPT_ALL; |
| } |
| } |
| /** |
| * Returns the given type in the the given package if it exists, |
| * otherwise <code>null</code>. |
| */ |
| protected NameEnvironmentAnswer find(String typeName, String packageName) { |
| if (packageName == null) |
| packageName = IPackageFragment.DEFAULT_PACKAGE_NAME; |
| if (this.owner != null) { |
| String source = this.owner.findSource(typeName, packageName); |
| if (source != null) { |
| ICompilationUnit cu = new BasicCompilationUnit(source.toCharArray(), CharOperation.splitOn('.', packageName.toCharArray()), typeName + Util.defaultJavaExtension()); |
| return new NameEnvironmentAnswer(cu, null); |
| } |
| } |
| NameLookup.Answer answer = |
| this.nameLookup.findType( |
| typeName, |
| packageName, |
| false/*exact match*/, |
| NameLookup.ACCEPT_ALL, |
| this.checkAccessRestrictions); |
| if (answer != null) { |
| // construct name env answer |
| if (answer.type instanceof BinaryType) { // BinaryType |
| try { |
| return new NameEnvironmentAnswer((IBinaryType) ((BinaryType) answer.type).getElementInfo(), answer.restriction); |
| } catch (JavaModelException npe) { |
| // fall back to using owner |
| } |
| } else { //SourceType |
| try { |
| // retrieve the requested type |
| SourceTypeElementInfo sourceType = (SourceTypeElementInfo)((SourceType) answer.type).getElementInfo(); |
| ISourceType topLevelType = sourceType; |
| while (topLevelType.getEnclosingType() != null) { |
| topLevelType = topLevelType.getEnclosingType(); |
| } |
| // find all siblings (other types declared in same unit, since may be used for name resolution) |
| IType[] types = sourceType.getHandle().getCompilationUnit().getTypes(); |
| ISourceType[] sourceTypes = new ISourceType[types.length]; |
| |
| // in the resulting collection, ensure the requested type is the first one |
| sourceTypes[0] = sourceType; |
| int length = types.length; |
| for (int i = 0, index = 1; i < length; i++) { |
| ISourceType otherType = |
| (ISourceType) ((JavaElement) types[i]).getElementInfo(); |
| if (!otherType.equals(topLevelType) && index < length) // check that the index is in bounds (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=62861) |
| sourceTypes[index++] = otherType; |
| } |
| return new NameEnvironmentAnswer(sourceTypes, answer.restriction); |
| } catch (JavaModelException jme) { |
| if (jme.isDoesNotExist() && String.valueOf(TypeConstants.PACKAGE_INFO_NAME).equals(typeName)) { |
| // in case of package-info.java the type doesn't exist in the model, |
| // but the CU may still help in order to fetch package level annotations. |
| return new NameEnvironmentAnswer((ICompilationUnit)answer.type.getParent(), answer.restriction); |
| } |
| // no usable answer |
| } |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Find the packages that start with the given prefix. |
| * A valid prefix is a qualified name separated by periods |
| * (ex. java.util). |
| * The packages found are passed to: |
| * ISearchRequestor.acceptPackage(char[][] packageName) |
| */ |
| public void findPackages(char[] prefix, ISearchRequestor requestor) { |
| this.nameLookup.seekPackageFragments( |
| new String(prefix), |
| true, |
| new SearchableEnvironmentRequestor(requestor)); |
| } |
| |
| /** |
| * Find the top-level types that are defined |
| * in the current environment and whose simple name matches the given name. |
| * |
| * The types found are passed to one of the following methods (if additional |
| * information is known about the types): |
| * ISearchRequestor.acceptType(char[][] packageName, char[] typeName) |
| * ISearchRequestor.acceptClass(char[][] packageName, char[] typeName, int modifiers) |
| * ISearchRequestor.acceptInterface(char[][] packageName, char[] typeName, int modifiers) |
| * |
| * This method can not be used to find member types... member |
| * types are found relative to their enclosing type. |
| */ |
| public void findExactTypes(char[] name, final boolean findMembers, int searchFor, final ISearchRequestor storage) { |
| |
| try { |
| final String excludePath; |
| if (this.unitToSkip != null) { |
| if (!(this.unitToSkip instanceof IJavaElement)) { |
| // revert to model investigation |
| findExactTypes( |
| new String(name), |
| storage, |
| convertSearchFilterToModelFilter(searchFor)); |
| return; |
| } |
| excludePath = ((IJavaElement) this.unitToSkip).getPath().toString(); |
| } else { |
| excludePath = null; |
| } |
| |
| IProgressMonitor progressMonitor = new IProgressMonitor() { |
| boolean isCanceled = false; |
| public void beginTask(String n, int totalWork) { |
| // implements interface method |
| } |
| public void done() { |
| // implements interface method |
| } |
| public void internalWorked(double work) { |
| // implements interface method |
| } |
| public boolean isCanceled() { |
| return this.isCanceled; |
| } |
| public void setCanceled(boolean value) { |
| this.isCanceled = value; |
| } |
| public void setTaskName(String n) { |
| // implements interface method |
| } |
| public void subTask(String n) { |
| // implements interface method |
| } |
| public void worked(int work) { |
| // implements interface method |
| } |
| }; |
| IRestrictedAccessTypeRequestor typeRequestor = new IRestrictedAccessTypeRequestor() { |
| public void acceptType(int modifiers, char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, String path, AccessRestriction access) { |
| if (excludePath != null && excludePath.equals(path)) |
| return; |
| if (!findMembers && enclosingTypeNames != null && enclosingTypeNames.length > 0) |
| return; // accept only top level types |
| storage.acceptType(packageName, simpleTypeName, enclosingTypeNames, modifiers, access); |
| } |
| }; |
| try { |
| new BasicSearchEngine(this.workingCopies).searchAllTypeNames( |
| null, |
| SearchPattern.R_EXACT_MATCH, |
| name, |
| SearchPattern.R_EXACT_MATCH, |
| searchFor, |
| getSearchScope(), |
| typeRequestor, |
| CANCEL_IF_NOT_READY_TO_SEARCH, |
| progressMonitor); |
| } catch (OperationCanceledException e) { |
| findExactTypes( |
| new String(name), |
| storage, |
| convertSearchFilterToModelFilter(searchFor)); |
| } |
| } catch (JavaModelException e) { |
| findExactTypes( |
| new String(name), |
| storage, |
| convertSearchFilterToModelFilter(searchFor)); |
| } |
| } |
| |
| /** |
| * Returns all types whose simple name matches with the given <code>name</code>. |
| */ |
| private void findExactTypes(String name, ISearchRequestor storage, int type) { |
| SearchableEnvironmentRequestor requestor = |
| new SearchableEnvironmentRequestor(storage, this.unitToSkip, this.project, this.nameLookup); |
| this.nameLookup.seekTypes(name, null, false, type, requestor); |
| } |
| |
| /** |
| * @see org.eclipse.jdt.internal.compiler.env.INameEnvironment#findType(char[][]) |
| */ |
| public NameEnvironmentAnswer findType(char[][] compoundTypeName) { |
| if (compoundTypeName == null) return null; |
| |
| int length = compoundTypeName.length; |
| if (length <= 1) { |
| if (length == 0) return null; |
| return find(new String(compoundTypeName[0]), null); |
| } |
| |
| int lengthM1 = length - 1; |
| char[][] packageName = new char[lengthM1][]; |
| System.arraycopy(compoundTypeName, 0, packageName, 0, lengthM1); |
| |
| return find( |
| new String(compoundTypeName[lengthM1]), |
| CharOperation.toString(packageName)); |
| } |
| |
| /** |
| * @see org.eclipse.jdt.internal.compiler.env.INameEnvironment#findType(char[], char[][]) |
| */ |
| public NameEnvironmentAnswer findType(char[] name, char[][] packageName) { |
| if (name == null) return null; |
| |
| return find( |
| new String(name), |
| packageName == null || packageName.length == 0 ? null : CharOperation.toString(packageName)); |
| } |
| |
| /** |
| * Find the top-level types that are defined |
| * in the current environment and whose name starts with the |
| * given prefix. The prefix is a qualified name separated by periods |
| * or a simple name (ex. java.util.V or V). |
| * |
| * The types found are passed to one of the following methods (if additional |
| * information is known about the types): |
| * ISearchRequestor.acceptType(char[][] packageName, char[] typeName) |
| * ISearchRequestor.acceptClass(char[][] packageName, char[] typeName, int modifiers) |
| * ISearchRequestor.acceptInterface(char[][] packageName, char[] typeName, int modifiers) |
| * |
| * This method can not be used to find member types... member |
| * types are found relative to their enclosing type. |
| */ |
| public void findTypes(char[] prefix, final boolean findMembers, boolean camelCaseMatch, int searchFor, final ISearchRequestor storage) { |
| findTypes(prefix, findMembers, camelCaseMatch, searchFor, storage, null); |
| } |
| /** |
| * Must be used only by CompletionEngine. |
| * The progress monitor is used to be able to cancel completion operations |
| * |
| * Find the top-level types that are defined |
| * in the current environment and whose name starts with the |
| * given prefix. The prefix is a qualified name separated by periods |
| * or a simple name (ex. java.util.V or V). |
| * |
| * The types found are passed to one of the following methods (if additional |
| * information is known about the types): |
| * ISearchRequestor.acceptType(char[][] packageName, char[] typeName) |
| * ISearchRequestor.acceptClass(char[][] packageName, char[] typeName, int modifiers) |
| * ISearchRequestor.acceptInterface(char[][] packageName, char[] typeName, int modifiers) |
| * |
| * This method can not be used to find member types... member |
| * types are found relative to their enclosing type. |
| */ |
| public void findTypes(char[] prefix, final boolean findMembers, boolean camelCaseMatch, int searchFor, final ISearchRequestor storage, IProgressMonitor monitor) { |
| |
| /* |
| if (true){ |
| findTypes(new String(prefix), storage, NameLookup.ACCEPT_CLASSES | NameLookup.ACCEPT_INTERFACES); |
| return; |
| } |
| */ |
| try { |
| final String excludePath; |
| if (this.unitToSkip != null) { |
| if (!(this.unitToSkip instanceof IJavaElement)) { |
| // revert to model investigation |
| findTypes( |
| new String(prefix), |
| storage, |
| convertSearchFilterToModelFilter(searchFor)); |
| return; |
| } |
| excludePath = ((IJavaElement) this.unitToSkip).getPath().toString(); |
| } else { |
| excludePath = null; |
| } |
| int lastDotIndex = CharOperation.lastIndexOf('.', prefix); |
| char[] qualification, simpleName; |
| if (lastDotIndex < 0) { |
| qualification = null; |
| if (camelCaseMatch) { |
| simpleName = prefix; |
| } else { |
| simpleName = CharOperation.toLowerCase(prefix); |
| } |
| } else { |
| qualification = CharOperation.subarray(prefix, 0, lastDotIndex); |
| if (camelCaseMatch) { |
| simpleName = CharOperation.subarray(prefix, lastDotIndex + 1, prefix.length); |
| } else { |
| simpleName = |
| CharOperation.toLowerCase( |
| CharOperation.subarray(prefix, lastDotIndex + 1, prefix.length)); |
| } |
| } |
| |
| IProgressMonitor progressMonitor = new IProgressMonitor() { |
| boolean isCanceled = false; |
| public void beginTask(String name, int totalWork) { |
| // implements interface method |
| } |
| public void done() { |
| // implements interface method |
| } |
| public void internalWorked(double work) { |
| // implements interface method |
| } |
| public boolean isCanceled() { |
| return this.isCanceled; |
| } |
| public void setCanceled(boolean value) { |
| this.isCanceled = value; |
| } |
| public void setTaskName(String name) { |
| // implements interface method |
| } |
| public void subTask(String name) { |
| // implements interface method |
| } |
| public void worked(int work) { |
| // implements interface method |
| } |
| }; |
| IRestrictedAccessTypeRequestor typeRequestor = new IRestrictedAccessTypeRequestor() { |
| public void acceptType(int modifiers, char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, String path, AccessRestriction access) { |
| if (excludePath != null && excludePath.equals(path)) |
| return; |
| if (!findMembers && enclosingTypeNames != null && enclosingTypeNames.length > 0) |
| return; // accept only top level types |
| storage.acceptType(packageName, simpleTypeName, enclosingTypeNames, modifiers, access); |
| } |
| }; |
| |
| int matchRule = SearchPattern.R_PREFIX_MATCH; |
| if (camelCaseMatch) matchRule |= SearchPattern.R_CAMELCASE_MATCH; |
| if (monitor != null) { |
| IndexManager indexManager = JavaModelManager.getIndexManager(); |
| if (indexManager.awaitingJobsCount() == 0) { |
| // indexes were already there, so perform an immediate search to avoid any index rebuilt |
| new BasicSearchEngine(this.workingCopies).searchAllTypeNames( |
| qualification, |
| SearchPattern.R_EXACT_MATCH, |
| simpleName, |
| matchRule, // not case sensitive |
| searchFor, |
| getSearchScope(), |
| typeRequestor, |
| FORCE_IMMEDIATE_SEARCH, |
| progressMonitor); |
| } else { |
| // indexes were not ready, give the indexing a chance to finish small jobs by sleeping 100ms... |
| try { |
| Thread.sleep(100); |
| } catch (InterruptedException e) { |
| // Do nothing |
| } |
| if (monitor.isCanceled()) { |
| throw new OperationCanceledException(); |
| } |
| if (indexManager.awaitingJobsCount() == 0) { |
| // indexes are now ready, so perform an immediate search to avoid any index rebuilt |
| new BasicSearchEngine(this.workingCopies).searchAllTypeNames( |
| qualification, |
| SearchPattern.R_EXACT_MATCH, |
| simpleName, |
| matchRule, // not case sensitive |
| searchFor, |
| getSearchScope(), |
| typeRequestor, |
| FORCE_IMMEDIATE_SEARCH, |
| progressMonitor); |
| } else { |
| // Indexes are still not ready, so look for types in the model instead of a search request |
| findTypes( |
| new String(prefix), |
| storage, |
| convertSearchFilterToModelFilter(searchFor)); |
| } |
| } |
| } else { |
| try { |
| new BasicSearchEngine(this.workingCopies).searchAllTypeNames( |
| qualification, |
| SearchPattern.R_EXACT_MATCH, |
| simpleName, |
| matchRule, // not case sensitive |
| searchFor, |
| getSearchScope(), |
| typeRequestor, |
| CANCEL_IF_NOT_READY_TO_SEARCH, |
| progressMonitor); |
| } catch (OperationCanceledException e) { |
| findTypes( |
| new String(prefix), |
| storage, |
| convertSearchFilterToModelFilter(searchFor)); |
| } |
| } |
| } catch (JavaModelException e) { |
| findTypes( |
| new String(prefix), |
| storage, |
| convertSearchFilterToModelFilter(searchFor)); |
| } |
| } |
| |
| /** |
| * Must be used only by CompletionEngine. |
| * The progress monitor is used to be able to cancel completion operations |
| * |
| * Find constructor declarations that are defined |
| * in the current environment and whose name starts with the |
| * given prefix. The prefix is a qualified name separated by periods |
| * or a simple name (ex. java.util.V or V). |
| * |
| * The constructors found are passed to one of the following methods: |
| * ISearchRequestor.acceptConstructor(...) |
| */ |
| public void findConstructorDeclarations(char[] prefix, boolean camelCaseMatch, final ISearchRequestor storage, IProgressMonitor monitor) { |
| try { |
| final String excludePath; |
| if (this.unitToSkip != null && this.unitToSkip instanceof IJavaElement) { |
| excludePath = ((IJavaElement) this.unitToSkip).getPath().toString(); |
| } else { |
| excludePath = null; |
| } |
| |
| int lastDotIndex = CharOperation.lastIndexOf('.', prefix); |
| char[] qualification, simpleName; |
| if (lastDotIndex < 0) { |
| qualification = null; |
| if (camelCaseMatch) { |
| simpleName = prefix; |
| } else { |
| simpleName = CharOperation.toLowerCase(prefix); |
| } |
| } else { |
| qualification = CharOperation.subarray(prefix, 0, lastDotIndex); |
| if (camelCaseMatch) { |
| simpleName = CharOperation.subarray(prefix, lastDotIndex + 1, prefix.length); |
| } else { |
| simpleName = |
| CharOperation.toLowerCase( |
| CharOperation.subarray(prefix, lastDotIndex + 1, prefix.length)); |
| } |
| } |
| |
| IProgressMonitor progressMonitor = new IProgressMonitor() { |
| boolean isCanceled = false; |
| public void beginTask(String name, int totalWork) { |
| // implements interface method |
| } |
| public void done() { |
| // implements interface method |
| } |
| public void internalWorked(double work) { |
| // implements interface method |
| } |
| public boolean isCanceled() { |
| return this.isCanceled; |
| } |
| public void setCanceled(boolean value) { |
| this.isCanceled = value; |
| } |
| public void setTaskName(String name) { |
| // implements interface method |
| } |
| public void subTask(String name) { |
| // implements interface method |
| } |
| public void worked(int work) { |
| // implements interface method |
| } |
| }; |
| |
| IRestrictedAccessConstructorRequestor constructorRequestor = new IRestrictedAccessConstructorRequestor() { |
| public void acceptConstructor( |
| int modifiers, |
| char[] simpleTypeName, |
| int parameterCount, |
| char[] signature, |
| char[][] parameterTypes, |
| char[][] parameterNames, |
| int typeModifiers, |
| char[] packageName, |
| int extraFlags, |
| String path, |
| AccessRestriction access) { |
| if (excludePath != null && excludePath.equals(path)) |
| return; |
| |
| storage.acceptConstructor( |
| modifiers, |
| simpleTypeName, |
| parameterCount, |
| signature, |
| parameterTypes, |
| parameterNames, |
| typeModifiers, |
| packageName, |
| extraFlags, |
| path, |
| access); |
| } |
| }; |
| |
| int matchRule = SearchPattern.R_PREFIX_MATCH; |
| if (camelCaseMatch) matchRule |= SearchPattern.R_CAMELCASE_MATCH; |
| if (monitor != null) { |
| IndexManager indexManager = JavaModelManager.getIndexManager(); |
| while (indexManager.awaitingJobsCount() > 0) { |
| try { |
| Thread.sleep(50); // indexes are not ready, sleep 50ms... |
| } catch (InterruptedException e) { |
| // Do nothing |
| } |
| if (monitor.isCanceled()) { |
| throw new OperationCanceledException(); |
| } |
| } |
| new BasicSearchEngine(this.workingCopies).searchAllConstructorDeclarations( |
| qualification, |
| simpleName, |
| matchRule, |
| getSearchScope(), |
| constructorRequestor, |
| FORCE_IMMEDIATE_SEARCH, |
| progressMonitor); |
| } else { |
| try { |
| new BasicSearchEngine(this.workingCopies).searchAllConstructorDeclarations( |
| qualification, |
| simpleName, |
| matchRule, |
| getSearchScope(), |
| constructorRequestor, |
| CANCEL_IF_NOT_READY_TO_SEARCH, |
| progressMonitor); |
| } catch (OperationCanceledException e) { |
| // Do nothing |
| } |
| } |
| } catch (JavaModelException e) { |
| // Do nothing |
| } |
| } |
| |
| /** |
| * Returns all types whose name starts with the given (qualified) <code>prefix</code>. |
| * |
| * If the <code>prefix</code> is unqualified, all types whose simple name matches |
| * the <code>prefix</code> are returned. |
| */ |
| private void findTypes(String prefix, ISearchRequestor storage, int type) { |
| //TODO (david) should add camel case support |
| SearchableEnvironmentRequestor requestor = |
| new SearchableEnvironmentRequestor(storage, this.unitToSkip, this.project, this.nameLookup); |
| int index = prefix.lastIndexOf('.'); |
| if (index == -1) { |
| this.nameLookup.seekTypes(prefix, null, true, type, requestor); |
| } else { |
| String packageName = prefix.substring(0, index); |
| JavaElementRequestor elementRequestor = new JavaElementRequestor(); |
| this.nameLookup.seekPackageFragments(packageName, false, elementRequestor); |
| IPackageFragment[] fragments = elementRequestor.getPackageFragments(); |
| if (fragments != null) { |
| String className = prefix.substring(index + 1); |
| for (int i = 0, length = fragments.length; i < length; i++) |
| if (fragments[i] != null) |
| this.nameLookup.seekTypes(className, fragments[i], true, type, requestor); |
| } |
| } |
| } |
| |
| private IJavaSearchScope getSearchScope() { |
| if (this.searchScope == null) { |
| // Create search scope with visible entry on the project's classpath |
| if(this.checkAccessRestrictions) { |
| this.searchScope = BasicSearchEngine.createJavaSearchScope(new IJavaElement[] {this.project}); |
| } else { |
| this.searchScope = BasicSearchEngine.createJavaSearchScope(this.nameLookup.packageFragmentRoots); |
| } |
| } |
| return this.searchScope; |
| } |
| |
| /** |
| * @see org.eclipse.jdt.internal.compiler.env.INameEnvironment#isPackage(char[][], char[]) |
| */ |
| public boolean isPackage(char[][] parentPackageName, char[] subPackageName) { |
| String[] pkgName; |
| if (parentPackageName == null) |
| pkgName = new String[] {new String(subPackageName)}; |
| else { |
| int length = parentPackageName.length; |
| pkgName = new String[length+1]; |
| for (int i = 0; i < length; i++) |
| pkgName[i] = new String(parentPackageName[i]); |
| pkgName[length] = new String(subPackageName); |
| } |
| return |
| (this.owner != null && this.owner.isPackage(pkgName)) |
| || this.nameLookup.isPackage(pkgName); |
| } |
| |
| /** |
| * Returns a printable string for the array. |
| */ |
| protected String toStringChar(char[] name) { |
| return "[" //$NON-NLS-1$ |
| + new String(name) + "]" ; //$NON-NLS-1$ |
| } |
| |
| /** |
| * Returns a printable string for the array. |
| */ |
| protected String toStringCharChar(char[][] names) { |
| StringBuffer result = new StringBuffer(); |
| for (int i = 0; i < names.length; i++) { |
| result.append(toStringChar(names[i])); |
| } |
| return result.toString(); |
| } |
| |
| public void cleanup() { |
| // nothing to do |
| } |
| } |