1 /*******************************************************************************
2 * Copyright (c) 2000, 2003 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v10.html
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package net.sourceforge.phpdt.internal.core;
13 import net.sourceforge.phpdt.core.ICompilationUnit;
14 import net.sourceforge.phpdt.core.IJavaElement;
15 import net.sourceforge.phpdt.core.IJavaProject;
16 import net.sourceforge.phpdt.core.IPackageFragment;
17 import net.sourceforge.phpdt.core.IType;
18 import net.sourceforge.phpdt.core.JavaModelException;
19 import net.sourceforge.phpdt.core.WorkingCopyOwner;
20 import net.sourceforge.phpdt.core.compiler.CharOperation;
21 import net.sourceforge.phpdt.core.search.IJavaSearchConstants;
22 import net.sourceforge.phpdt.core.search.ITypeNameRequestor;
23 import net.sourceforge.phpdt.internal.codeassist.ISearchRequestor;
24 import net.sourceforge.phpdt.internal.codeassist.ISearchableNameEnvironment;
25 import net.sourceforge.phpdt.internal.compiler.env.IConstants;
26 import net.sourceforge.phpdt.internal.compiler.env.INameEnvironment;
27 import net.sourceforge.phpdt.internal.compiler.env.ISourceType;
28 import net.sourceforge.phpdt.internal.compiler.env.NameEnvironmentAnswer;
30 import org.eclipse.core.runtime.IProgressMonitor;
33 * This class provides a <code>SearchableBuilderEnvironment</code> for code
34 * assist which uses the Java model as a search tool.
36 public class SearchableEnvironment implements ISearchableNameEnvironment,
37 IJavaSearchConstants {
38 protected NameLookup nameLookup;
40 protected ICompilationUnit unitToSkip;
42 protected IJavaProject project;
44 // protected IJavaSearchScope searchScope;
47 * Creates a Sea /** Creates a SearchableEnvironment on the given project
49 public SearchableEnvironment(IJavaProject project)
50 throws JavaModelException {
51 this.project = project;
52 this.nameLookup = (NameLookup) ((JavaProject) project).getNameLookup();
54 // Create search scope with visible entry on the project's classpath
56 // SearchEngine.createJavaSearchScope(this.project.getAllPackageFragmentRoots());
60 * Creates a SearchableEnvironment on the given project
62 public SearchableEnvironment(JavaProject project, WorkingCopyOwner owner)
63 throws JavaModelException {
64 this.project = project;
65 this.nameLookup = project.newNameLookup(owner);
67 // Create search scope with visible entry on the project's classpath
69 // SearchEngine.createJavaSearchScope(this.project.getAllPackageFragmentRoots());
73 * Returns the given type in the the given package if it exists, otherwise
76 protected NameEnvironmentAnswer find(String typeName, String packageName) {
77 if (packageName == null)
78 packageName = IPackageFragment.DEFAULT_PACKAGE_NAME;
80 if (this.nameLookup != null) { // ins axelcl
81 IType type = this.nameLookup.findType(typeName, packageName, false,
82 NameLookup.ACCEPT_CLASSES | NameLookup.ACCEPT_INTERFACES);
84 // if (type instanceof BinaryType) {
86 // return new NameEnvironmentAnswer(
87 // (IBinaryType) ((BinaryType) type).getElementInfo());
88 // } catch (JavaModelException npe) {
91 // } else { //SourceType
93 // retrieve the requested type
94 SourceTypeElementInfo sourceType = (SourceTypeElementInfo) ((SourceType) type)
96 ISourceType topLevelType = sourceType;
97 while (topLevelType.getEnclosingType() != null) {
98 topLevelType = topLevelType.getEnclosingType();
100 // find all siblings (other types declared in same unit,
101 // since may be used for name resolution)
102 IType[] types = sourceType.getHandle().getCompilationUnit()
104 ISourceType[] sourceTypes = new ISourceType[types.length];
106 // in the resulting collection, ensure the requested type is
108 sourceTypes[0] = sourceType;
109 for (int i = 0, index = 1; i < types.length; i++) {
110 ISourceType otherType = (ISourceType) ((JavaElement) types[i])
112 if (!otherType.equals(topLevelType))
113 sourceTypes[index++] = otherType;
115 return new NameEnvironmentAnswer(sourceTypes);
116 } catch (JavaModelException npe) {
126 * @see ISearchableNameEnvironment#findPackages(char[], ISearchRequestor)
128 public void findPackages(char[] prefix, ISearchRequestor requestor) {
129 // this.nameLookup.seekPackageFragments(
130 // new String(prefix),
132 // new SearchableEnvironmentRequestor(requestor));
136 * @see INameEnvironment#findType(char[][])
138 public NameEnvironmentAnswer findType(char[][] compoundTypeName) {
139 if (compoundTypeName == null)
142 int length = compoundTypeName.length;
146 return find(new String(compoundTypeName[0]), null);
149 int lengthM1 = length - 1;
150 char[][] packageName = new char[lengthM1][];
151 System.arraycopy(compoundTypeName, 0, packageName, 0, lengthM1);
153 return find(new String(compoundTypeName[lengthM1]), CharOperation
154 .toString(packageName));
158 * @see INameEnvironment#findType(char[], char[][])
160 public NameEnvironmentAnswer findType(char[] name, char[][] packageName) {
164 return find(new String(name), packageName == null
165 || packageName.length == 0 ? null : CharOperation
166 .toString(packageName));
170 * @see ISearchableNameEnvironment#findTypes(char[], ISearchRequestor)
172 public void findTypes(char[] prefix, final ISearchRequestor storage) {
175 * if (true){ findTypes(new String(prefix), storage,
176 * NameLookup.ACCEPT_CLASSES | NameLookup.ACCEPT_INTERFACES); return; }
179 final String excludePath;
180 if (this.unitToSkip != null) {
181 if (!(this.unitToSkip instanceof IJavaElement)) {
182 // revert to model investigation
183 findTypes(new String(prefix), storage,
184 NameLookup.ACCEPT_CLASSES
185 | NameLookup.ACCEPT_INTERFACES);
188 excludePath = ((IJavaElement) this.unitToSkip).getPath().toString();
192 int lastDotIndex = CharOperation.lastIndexOf('.', prefix);
193 char[] qualification, simpleName;
194 if (lastDotIndex < 0) {
195 qualification = null;
196 simpleName = CharOperation.toLowerCase(prefix);
198 qualification = CharOperation.subarray(prefix, 0, lastDotIndex);
199 simpleName = CharOperation.toLowerCase(CharOperation.subarray(
200 prefix, lastDotIndex + 1, prefix.length));
203 IProgressMonitor progressMonitor = new IProgressMonitor() {
204 boolean isCanceled = false;
206 public void beginTask(String name, int totalWork) {
212 public void internalWorked(double work) {
215 public boolean isCanceled() {
219 public void setCanceled(boolean value) {
223 public void setTaskName(String name) {
226 public void subTask(String name) {
229 public void worked(int work) {
232 ITypeNameRequestor nameRequestor = new ITypeNameRequestor() {
233 public void acceptClass(char[] packageName, char[] simpleTypeName,
234 char[][] enclosingTypeNames, String path) {
235 if (excludePath != null && excludePath.equals(path))
237 if (enclosingTypeNames != null && enclosingTypeNames.length > 0)
238 return; // accept only top level types
239 storage.acceptClass(packageName, simpleTypeName,
240 IConstants.AccPublic);
243 public void acceptInterface(char[] packageName,
244 char[] simpleTypeName, char[][] enclosingTypeNames,
246 if (excludePath != null && excludePath.equals(path))
248 if (enclosingTypeNames != null && enclosingTypeNames.length > 0)
249 return; // accept only top level types
250 storage.acceptInterface(packageName, simpleTypeName,
251 IConstants.AccPublic);
255 // new SearchEngine().searchAllTypeNames(
256 // this.project.getProject().getWorkspace(),
261 // IJavaSearchConstants.TYPE,
264 // CANCEL_IF_NOT_READY_TO_SEARCH,
266 // } catch (OperationCanceledException e) {
268 // new String(prefix),
270 // NameLookup.ACCEPT_CLASSES | NameLookup.ACCEPT_INTERFACES);
272 // } catch (JavaModelException e) {
274 // new String(prefix),
276 // NameLookup.ACCEPT_CLASSES | NameLookup.ACCEPT_INTERFACES);
281 * Returns all types whose name starts with the given (qualified)
282 * <code>prefix</code>.
284 * If the <code>prefix</code> is unqualified, all types whose simple name
285 * matches the <code>prefix</code> are returned.
287 private void findTypes(String prefix, ISearchRequestor storage, int type) {
288 SearchableEnvironmentRequestor requestor = new SearchableEnvironmentRequestor(
289 storage, this.unitToSkip);
290 int index = prefix.lastIndexOf('.');
292 this.nameLookup.seekTypes(prefix, null, true, type, requestor);
294 String packageName = prefix.substring(0, index);
295 JavaElementRequestor elementRequestor = new JavaElementRequestor();
296 this.nameLookup.seekPackageFragments(packageName, false,
298 IPackageFragment[] fragments = elementRequestor
299 .getPackageFragments();
300 if (fragments != null) {
301 String className = prefix.substring(index + 1);
302 for (int i = 0, length = fragments.length; i < length; i++)
303 if (fragments[i] != null)
304 this.nameLookup.seekTypes(className, fragments[i],
305 true, type, requestor);
311 * @see INameEnvironment#isPackage(char[][], char[])
313 public boolean isPackage(char[][] parentPackageName, char[] subPackageName) {
314 if (subPackageName == null
315 || CharOperation.contains('.', subPackageName))
317 if (parentPackageName == null || parentPackageName.length == 0)
318 return isTopLevelPackage(subPackageName);
319 for (int i = 0, length = parentPackageName.length; i < length; i++)
320 if (parentPackageName[i] == null
321 || CharOperation.contains('.', parentPackageName[i]))
324 String packageName = new String(CharOperation.concatWith(
325 parentPackageName, subPackageName, '.'));
326 return this.nameLookup.findPackageFragments(packageName, false) != null;
329 public boolean isTopLevelPackage(char[] packageName) {
330 return packageName != null
331 && !CharOperation.contains('.', packageName)
332 && this.nameLookup.findPackageFragments(
333 new String(packageName), false) != null;
337 * Returns a printable string for the array.
339 protected String toStringChar(char[] name) {
340 return "[" //$NON-NLS-1$
341 + new String(name) + "]"; //$NON-NLS-1$
345 * Returns a printable string for the array.
347 protected String toStringCharChar(char[][] names) {
348 StringBuffer result = new StringBuffer();
349 for (int i = 0; i < names.length; i++) {
350 result.append(toStringChar(names[i]));
352 return result.toString();
355 public void cleanup() {