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 java.util.ArrayList;
15 import net.sourceforge.phpdt.core.ICompilationUnit;
16 import net.sourceforge.phpdt.core.IField;
17 import net.sourceforge.phpdt.core.IJavaElement;
18 import net.sourceforge.phpdt.core.IMember;
19 import net.sourceforge.phpdt.core.IMethod;
20 import net.sourceforge.phpdt.core.IPackageFragment;
21 import net.sourceforge.phpdt.core.IParent;
22 import net.sourceforge.phpdt.core.IType;
23 import net.sourceforge.phpdt.core.ITypeHierarchy;
24 import net.sourceforge.phpdt.core.IWorkingCopy;
25 import net.sourceforge.phpdt.core.JavaModelException;
26 import net.sourceforge.phpdt.core.jdom.IDOMNode;
27 import net.sourceforge.phpdt.internal.core.util.Util;
28 import net.sourceforge.phpdt.internal.corext.Assert;
30 import org.eclipse.core.runtime.IProgressMonitor;
33 * Handle for a source type. Info object is a SourceTypeElementInfo.
35 * Note: Parent is either an IClassFile, an ICompilationUnit or an IType.
40 public class SourceType extends Member implements IType {
42 * An empty list of Strings
44 protected static final String[] fgEmptyList = new String[] {};
45 protected SourceType(JavaElement parent, String name) {
47 Assert.isTrue(name.indexOf('.') == -1, Util.bind("sourcetype.invalidName", name)); //$NON-NLS-1$
53 //public void codeComplete(char[] snippet,int insertion,int position,char[][] localVariableTypeNames,char[][]
54 // localVariableNames,int[] localVariableModifiers,boolean isStatic,ICompletionRequestor requestor) throws JavaModelException {
55 // if (requestor == null) {
56 // throw new IllegalArgumentException(ProjectPrefUtil.bind("codeAssist.nullRequestor")); //$NON-NLS-1$
59 // JavaProject project = (JavaProject) getJavaProject();
60 // SearchableEnvironment environment = (SearchableEnvironment) project.getSearchableNameEnvironment();
61 // NameLookup nameLookup = project.getNameLookup();
62 // CompletionEngine engine = new CompletionEngine(environment, new CompletionRequestorWrapper(requestor,nameLookup),
63 // project.getOptions(true), project);
65 // String source = getCompilationUnit().getSource();
66 // if (source != null && insertion > -1 && insertion < source.length()) {
67 // String encoding = project.getOption(JavaCore.CORE_ENCODING, true);
69 // char[] prefix = CharOperation.concat(source.substring(0, insertion).toCharArray(), new char[]{'{'});
70 // char[] suffix = CharOperation.concat(new char[]{'}'}, source.substring(insertion).toCharArray());
71 // char[] fakeSource = CharOperation.concat(prefix, snippet, suffix);
73 // BasicCompilationUnit cu =
74 // new BasicCompilationUnit(
80 // engine.complete(cu, prefix.length + position, prefix.length);
82 // engine.complete(this, snippet, position, localVariableTypeNames, localVariableNames, localVariableModifiers, isStatic);
88 //public IField createField(String contents, IJavaElement sibling, boolean force, IProgressMonitor monitor) throws
89 // JavaModelException {
90 // CreateFieldOperation op = new CreateFieldOperation(this, contents, force);
91 // if (sibling != null) {
92 // op.createBefore(sibling);
94 // runOperation(op, monitor);
95 // return (IField) op.getResultElements()[0];
100 //public IInitializer createInitializer(String contents, IJavaElement sibling, IProgressMonitor monitor) throws
101 // JavaModelException {
102 // CreateInitializerOperation op = new CreateInitializerOperation(this, contents);
103 // if (sibling != null) {
104 // op.createBefore(sibling);
106 // runOperation(op, monitor);
107 // return (IInitializer) op.getResultElements()[0];
112 //public IMethod createMethod(String contents, IJavaElement sibling, boolean force, IProgressMonitor monitor) throws
113 // JavaModelException {
114 // CreateMethodOperation op = new CreateMethodOperation(this, contents, force);
115 // if (sibling != null) {
116 // op.createBefore(sibling);
118 // runOperation(op, monitor);
119 // return (IMethod) op.getResultElements()[0];
124 //public IType createType(String contents, IJavaElement sibling, boolean force, IProgressMonitor monitor) throws
125 // JavaModelException {
126 // CreateTypeOperation op = new CreateTypeOperation(this, contents, force);
127 // if (sibling != null) {
128 // op.createBefore(sibling);
130 // runOperation(op, monitor);
131 // return (IType) op.getResultElements()[0];
134 * @see JavaElement#equalsDOMNode
136 protected boolean equalsDOMNode(IDOMNode node) throws JavaModelException {
137 return (node.getNodeType() == IDOMNode.TYPE) && super.equalsDOMNode(node);
143 public IMethod[] findMethods(IMethod method) {
145 return this.findMethods(method, this.getMethods());
146 } catch (JavaModelException e) {
147 // if type doesn't exist, no matching method can exist
155 public IType getDeclaringType() {
156 IJavaElement parent = getParent();
157 while (parent != null) {
158 if (parent.getElementType() == IJavaElement.TYPE) {
159 return (IType) parent;
160 } else if (parent instanceof IMember) {
161 parent = parent.getParent();
172 public int getElementType() {
177 * @see IType#getField
179 public IField getField(String name) {
180 return new SourceField(this, name);
186 public IField[] getFields() throws JavaModelException {
187 ArrayList list = getChildrenOfType(FIELD);
188 IField[] array = new IField[list.size()];
194 * @see IType#getFullyQualifiedName
196 public String getFullyQualifiedName() {
197 return this.getFullyQualifiedName('$');
201 * @see IType#getFullyQualifiedName(char)
203 public String getFullyQualifiedName(char enclosingTypeSeparator) {
204 String packageName = getPackageFragment().getElementName();
205 if (packageName.equals(IPackageFragment.DEFAULT_PACKAGE_NAME)) {
206 return getTypeQualifiedName(enclosingTypeSeparator);
208 return packageName + '.' + getTypeQualifiedName(enclosingTypeSeparator);
214 //public IInitializer getInitializer(int occurrenceCount) {
215 // return new Initializer(this, occurrenceCount);
220 //public IInitializer[] getInitializers() throws JavaModelException {
221 // ArrayList list = getChildrenOfType(INITIALIZER);
222 // IInitializer[] array= new IInitializer[list.size()];
223 // list.toArray(array);
227 * @see IType#getMethod
229 public IMethod getMethod(String name, String[] parameterTypeSignatures) {
230 return new SourceMethod(this, name, parameterTypeSignatures);
236 public IMethod[] getMethods() throws JavaModelException {
237 ArrayList list = getChildrenOfType(METHOD);
238 IMethod[] array = new IMethod[list.size()];
246 public IPackageFragment getPackageFragment() {
247 IJavaElement parentElement = this.parent;
248 while (parentElement != null) {
249 if (parentElement.getElementType() == IJavaElement.PACKAGE_FRAGMENT) {
250 return (IPackageFragment) parentElement;
252 parentElement = parentElement.getParent();
255 Assert.isTrue(false); // should not happen
262 public String getSuperclassName() throws JavaModelException {
263 SourceTypeElementInfo info = (SourceTypeElementInfo) getElementInfo();
264 char[] superclassName = info.getSuperclassName();
265 if (superclassName == null) {
268 return new String(superclassName);
274 public String[] getSuperInterfaceNames() throws JavaModelException {
275 SourceTypeElementInfo info = (SourceTypeElementInfo) getElementInfo();
276 char[][] names = info.getInterfaceNames();
280 String[] strings = new String[names.length];
281 for (int i = 0; i < names.length; i++) {
282 strings[i] = new String(names[i]);
290 public IType getType(String name) {
291 return new SourceType(this, name);
295 * @see IType#getTypeQualifiedName
297 public String getTypeQualifiedName() {
298 return this.getTypeQualifiedName('$');
302 * @see IType#getTypeQualifiedName(char)
304 public String getTypeQualifiedName(char enclosingTypeSeparator) {
305 if (parent.getElementType() == IJavaElement.COMPILATION_UNIT) {
308 return ((IType) parent).getTypeQualifiedName(enclosingTypeSeparator) + enclosingTypeSeparator + name;
315 public IType[] getTypes() throws JavaModelException {
316 ArrayList list = getChildrenOfType(TYPE);
317 IType[] array = new IType[list.size()];
325 public boolean hasChildren() throws JavaModelException {
326 return getChildren().length > 0;
330 * @see IType#isAnonymous()
332 public boolean isAnonymous() throws JavaModelException {
333 return false; // cannot create source handle onto anonymous types
339 public boolean isClass() throws JavaModelException {
340 return !isInterface();
346 public boolean isInterface() throws JavaModelException {
347 Object obj = getElementInfo();
348 if (obj instanceof SourceTypeElementInfo) {
349 SourceTypeElementInfo info = (SourceTypeElementInfo) getElementInfo();
350 return info.isInterface();
356 * @see IType#isLocal()
358 public boolean isLocal() throws JavaModelException {
359 return false; // cannot create source handle onto local types
363 * @see IType#isMember()
365 public boolean isMember() throws JavaModelException {
366 return getDeclaringType() != null;
372 // public ITypeHierarchy loadTypeHierachy(InputStream input, IProgressMonitor monitor) throws JavaModelException {
373 // return loadTypeHierachy(input, DefaultWorkingCopyOwner.PRIMARY, monitor);
376 * NOTE: This method is not part of the API has it is not clear clients would easily use it: they would need to
377 * first make sure all working copies for the given owner exist before calling it. This is especially har at startup
379 * In case clients want this API, here is how it should be specified:
381 * Loads a previously saved ITypeHierarchy from an input stream. A type hierarchy can
382 * be stored using ITypeHierachy#store(OutputStream). A compilation unit of a
383 * loaded type has the given owner if such a working copy exists, otherwise the type's
384 * compilation unit is a primary compilation unit.
386 * Only hierarchies originally created by the following methods can be loaded:
388 * <li>IType#newSupertypeHierarchy(IProgressMonitor)</li>
389 * <li>IType#newSupertypeHierarchy(WorkingCopyOwner, IProgressMonitor)</li>
390 * <li>IType#newTypeHierarchy(IJavaProject, IProgressMonitor)</li>
391 * <li>IType#newTypeHierarchy(IJavaProject, WorkingCopyOwner, IProgressMonitor)</li>
392 * <li>IType#newTypeHierarchy(IProgressMonitor)</li>
393 * <li>IType#newTypeHierarchy(WorkingCopyOwner, IProgressMonitor)</li>
396 * @param input stream where hierarchy will be read
397 * @param monitor the given progress monitor
398 * @return the stored hierarchy
399 * @exception JavaModelException if the hierarchy could not be restored, reasons include:
400 * - type is not the focus of the hierarchy or
401 * - unable to read the input stream (wrong format, IOException during reading, ...)
402 * @see ITypeHierarchy#store(java.io.OutputStream, IProgressMonitor)
405 // public ITypeHierarchy loadTypeHierachy(InputStream input, WorkingCopyOwner owner, IProgressMonitor monitor) throws JavaModelException {
406 // // TODO monitor should be passed to TypeHierarchy.load(...)
407 // return TypeHierarchy.load(this, input, owner);
412 // public ITypeHierarchy newSupertypeHierarchy(IProgressMonitor monitor) throws JavaModelException {
413 // return this.newSupertypeHierarchy(DefaultWorkingCopyOwner.PRIMARY, monitor);
416 * @see IType#newSupertypeHierarchy(ICompilationUnit[], IProgressMonitor)
418 // public ITypeHierarchy newSupertypeHierarchy(
419 // ICompilationUnit[] workingCopies,
420 // IProgressMonitor monitor)
421 // throws JavaModelException {
423 // CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation(this, workingCopies, SearchEngine.createWorkspaceScope(), false);
424 // op.runOperation(monitor);
425 // return op.getResult();
428 * @param workingCopies the working copies that take precedence over their original compilation units
429 * @param monitor the given progress monitor
430 * @return a type hierarchy for this type containing this type and all of its supertypes
431 * @exception JavaModelException if this element does not exist or if an
432 * exception occurs while accessing its corresponding resource.
434 * @see IType#newSupertypeHierarchy(IWorkingCopy[], IProgressMonitor)
437 public ITypeHierarchy newSupertypeHierarchy(
438 IWorkingCopy[] workingCopies,
439 IProgressMonitor monitor)
440 throws JavaModelException {
442 ICompilationUnit[] copies;
443 if (workingCopies == null) {
446 int length = workingCopies.length;
447 System.arraycopy(workingCopies, 0, copies = new ICompilationUnit[length], 0, length);
449 return newSupertypeHierarchy(copies, monitor);
452 * @see IType#newSupertypeHierarchy(WorkingCopyOwner, IProgressMonitor)
454 // public ITypeHierarchy newSupertypeHierarchy(
455 // WorkingCopyOwner owner,
456 // IProgressMonitor monitor)
457 // throws JavaModelException {
459 // ICompilationUnit[] workingCopies = JavaModelManager.getJavaModelManager().getWorkingCopies(owner, true/*add primary working copies*/);
460 // CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation(this, workingCopies, SearchEngine.createWorkspaceScope(), false);
461 // op.runOperation(monitor);
462 // return op.getResult();
467 // public ITypeHierarchy newTypeHierarchy(IJavaProject project, IProgressMonitor monitor) throws JavaModelException {
468 // return newTypeHierarchy(project, DefaultWorkingCopyOwner.PRIMARY, monitor);
471 * @see IType#newTypeHierarchy(IJavaProject, WorkingCopyOwner, IProgressMonitor)
473 // public ITypeHierarchy newTypeHierarchy(IJavaProject project, WorkingCopyOwner owner, IProgressMonitor monitor) throws JavaModelException {
474 // if (project == null) {
475 // throw new IllegalArgumentException(Util.bind("hierarchy.nullProject")); //$NON-NLS-1$
477 // ICompilationUnit[] workingCopies = JavaModelManager.getJavaModelManager().getWorkingCopies(owner, true/*add primary working copies*/);
478 // ICompilationUnit[] projectWCs = null;
479 // if (workingCopies != null) {
480 // int length = workingCopies.length;
481 // projectWCs = new ICompilationUnit[length];
483 // for (int i = 0; i < length; i++) {
484 // ICompilationUnit wc = workingCopies[i];
485 // if (project.equals(wc.getJavaProject())) {
486 // projectWCs[index++] = wc;
489 // if (index != length) {
490 // System.arraycopy(projectWCs, 0, projectWCs = new ICompilationUnit[index], 0, index);
493 // CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation(
498 // op.runOperation(monitor);
499 // return op.getResult();
504 // public ITypeHierarchy newTypeHierarchy(IProgressMonitor monitor) throws JavaModelException {
505 // CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation(this, null, SearchEngine.createWorkspaceScope(), true);
506 // op.runOperation(monitor);
507 // return op.getResult();
510 * @see IType#newTypeHierarchy(ICompilationUnit[], IProgressMonitor)
512 // public ITypeHierarchy newTypeHierarchy(
513 // ICompilationUnit[] workingCopies,
514 // IProgressMonitor monitor)
515 // throws JavaModelException {
517 // CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation(this, workingCopies, SearchEngine.createWorkspaceScope(), true);
518 // op.runOperation(monitor);
519 // return op.getResult();
522 * @see IType#newTypeHierarchy(IWorkingCopy[], IProgressMonitor)
525 public ITypeHierarchy newTypeHierarchy(
526 IWorkingCopy[] workingCopies,
527 IProgressMonitor monitor)
528 throws JavaModelException {
530 ICompilationUnit[] copies;
531 if (workingCopies == null) {
534 int length = workingCopies.length;
535 System.arraycopy(workingCopies, 0, copies = new ICompilationUnit[length], 0, length);
537 return newTypeHierarchy(copies, monitor);
540 * @see IType#newTypeHierarchy(WorkingCopyOwner, IProgressMonitor)
542 // public ITypeHierarchy newTypeHierarchy(
543 // WorkingCopyOwner owner,
544 // IProgressMonitor monitor)
545 // throws JavaModelException {
547 // ICompilationUnit[] workingCopies = JavaModelManager.getJavaModelManager().getWorkingCopies(owner, true/*add primary working copies*/);
548 // CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation(this, workingCopies, SearchEngine.createWorkspaceScope(), true);
549 // op.runOperation(monitor);
550 // return op.getResult();
553 // public String[][] resolveType(String typeName) throws JavaModelException {
554 // ISourceType info = (ISourceType) this.getElementInfo();
555 // ISearchableNameEnvironment environment = ((JavaProject)getJavaProject()).getSearchableNameEnvironment();
557 // class TypeResolveRequestor implements ISelectionRequestor {
558 // String[][] answers = null;
559 // void acceptType(String[] answer){
560 // if (answers == null) {
561 // answers = new String[][]{ answer };
564 // int length = answers.length;
565 // System.arraycopy(answers, 0, answers = new String[length+1][], 0, length);
566 // answers[length] = answer;
569 // public void acceptClass(char[] packageName, char[] className, boolean needQualification) {
570 // acceptType(new String[] { new String(packageName), new String(className) });
573 // public void acceptInterface(char[] packageName, char[] interfaceName, boolean needQualification) {
574 // acceptType(new String[] { new String(packageName), new String(interfaceName) });
577 // public void acceptError(IProblem error) {}
578 // public void acceptField(char[] declaringTypePackageName, char[] declaringTypeName, char[] name) {}
579 // public void acceptMethod(char[] declaringTypePackageName, char[] declaringTypeName, char[] selector, char[][]
580 // parameterPackageNames, char[][] parameterTypeNames, boolean isConstructor) {}
581 // public void acceptPackage(char[] packageName){}
584 // TypeResolveRequestor requestor = new TypeResolveRequestor();
585 // SelectionEngine engine =
586 // new SelectionEngine(environment, requestor, this.getJavaProject().getOptions(true));
588 // IType[] topLevelTypes = this.getCompilationUnit().getTypes();
589 // int length = topLevelTypes.length;
590 // ISourceType[] topLevelInfos = new ISourceType[length];
591 // for (int i = 0; i < length; i++) {
592 // topLevelInfos[i] = (ISourceType)((SourceType)topLevelTypes[i]).getElementInfo();
595 // engine.selectType(info, typeName.toCharArray(), topLevelInfos, false);
596 // return requestor.answers;
599 * @private Debugging purposes
601 protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
602 buffer.append(this.tabString(tab));
604 buffer.append(this.getElementName());
605 buffer.append(" (not open)"); //$NON-NLS-1$
606 } else if (info == NO_INFO) {
607 buffer.append(getElementName());
610 if (this.isInterface()) {
611 buffer.append("interface "); //$NON-NLS-1$
613 buffer.append("class "); //$NON-NLS-1$
615 buffer.append(this.getElementName());
616 } catch (JavaModelException e) {
617 buffer.append("<JavaModelException in toString of " + getElementName()); //$NON-NLS-1$