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;
29 //import net.sourceforge.phpdt.internal.corext.Assert;
30 import org.eclipse.core.runtime.Assert;
32 import org.eclipse.core.runtime.IProgressMonitor;
35 * Handle for a source type. Info object is a SourceTypeElementInfo.
37 * Note: Parent is either an IClassFile, an ICompilationUnit or an IType.
42 public class SourceType extends Member implements IType {
44 * An empty list of Strings
46 protected static final String[] fgEmptyList = new String[] {};
48 protected SourceType(JavaElement parent, String name) {
50 Assert.isTrue(name.indexOf('.') == -1, Util.bind(
51 "sourcetype.invalidName", name)); //$NON-NLS-1$
57 // public void codeComplete(char[] snippet,int insertion,int
58 // position,char[][] localVariableTypeNames,char[][]
59 // localVariableNames,int[] localVariableModifiers,boolean
60 // isStatic,ICompletionRequestor requestor) throws JavaModelException {
61 // if (requestor == null) {
63 // IllegalArgumentException(ProjectPrefUtil.bind("codeAssist.nullRequestor"));
67 // JavaProject project = (JavaProject) getJavaProject();
68 // SearchableEnvironment environment = (SearchableEnvironment)
69 // project.getSearchableNameEnvironment();
70 // NameLookup nameLookup = project.getNameLookup();
71 // CompletionEngine engine = new CompletionEngine(environment, new
72 // CompletionRequestorWrapper(requestor,nameLookup),
73 // project.getOptions(true), project);
75 // String source = getCompilationUnit().getSource();
76 // if (source != null && insertion > -1 && insertion < source.length()) {
77 // String encoding = project.getOption(JavaCore.CORE_ENCODING, true);
79 // char[] prefix = CharOperation.concat(source.substring(0,
80 // insertion).toCharArray(), new char[]{'{'});
81 // char[] suffix = CharOperation.concat(new char[]{'}'},
82 // source.substring(insertion).toCharArray());
83 // char[] fakeSource = CharOperation.concat(prefix, snippet, suffix);
85 // BasicCompilationUnit cu =
86 // new BasicCompilationUnit(
92 // engine.complete(cu, prefix.length + position, prefix.length);
94 // engine.complete(this, snippet, position, localVariableTypeNames,
95 // localVariableNames, localVariableModifiers, isStatic);
101 // public IField createField(String contents, IJavaElement sibling, boolean
102 // force, IProgressMonitor monitor) throws
103 // JavaModelException {
104 // CreateFieldOperation op = new CreateFieldOperation(this, contents,
106 // if (sibling != null) {
107 // op.createBefore(sibling);
109 // runOperation(op, monitor);
110 // return (IField) op.getResultElements()[0];
115 // public IInitializer createInitializer(String contents, IJavaElement
116 // sibling, IProgressMonitor monitor) throws
117 // JavaModelException {
118 // CreateInitializerOperation op = new CreateInitializerOperation(this,
120 // if (sibling != null) {
121 // op.createBefore(sibling);
123 // runOperation(op, monitor);
124 // return (IInitializer) op.getResultElements()[0];
129 // public IMethod createMethod(String contents, IJavaElement sibling,
130 // boolean force, IProgressMonitor monitor) throws
131 // JavaModelException {
132 // CreateMethodOperation op = new CreateMethodOperation(this, contents,
134 // if (sibling != null) {
135 // op.createBefore(sibling);
137 // runOperation(op, monitor);
138 // return (IMethod) op.getResultElements()[0];
143 // public IType createType(String contents, IJavaElement sibling, boolean
144 // force, IProgressMonitor monitor) throws
145 // JavaModelException {
146 // CreateTypeOperation op = new CreateTypeOperation(this, contents, force);
147 // if (sibling != null) {
148 // op.createBefore(sibling);
150 // runOperation(op, monitor);
151 // return (IType) op.getResultElements()[0];
154 * @see JavaElement#equalsDOMNode
156 protected boolean equalsDOMNode(IDOMNode node) throws JavaModelException {
157 return (node.getNodeType() == IDOMNode.TYPE)
158 && super.equalsDOMNode(node);
164 public IMethod[] findMethods(IMethod method) {
166 return this.findMethods(method, this.getMethods());
167 } catch (JavaModelException e) {
168 // if type doesn't exist, no matching method can exist
176 public IType getDeclaringType() {
177 IJavaElement parent = getParent();
178 while (parent != null) {
179 if (parent.getElementType() == IJavaElement.TYPE) {
180 return (IType) parent;
181 } else if (parent instanceof IMember) {
182 parent = parent.getParent();
193 public int getElementType() {
198 * @see IType#getField
200 public IField getField(String name) {
201 return new SourceField(this, name);
207 public IField[] getFields() throws JavaModelException {
208 ArrayList list = getChildrenOfType(FIELD);
209 IField[] array = new IField[list.size()];
215 * @see IType#getFullyQualifiedName
217 public String getFullyQualifiedName() {
218 return this.getFullyQualifiedName('$');
222 * @see IType#getFullyQualifiedName(char)
224 public String getFullyQualifiedName(char enclosingTypeSeparator) {
225 String packageName = getPackageFragment().getElementName();
226 if (packageName.equals(IPackageFragment.DEFAULT_PACKAGE_NAME)) {
227 return getTypeQualifiedName(enclosingTypeSeparator);
229 return packageName + '.' + getTypeQualifiedName(enclosingTypeSeparator);
235 // public IInitializer getInitializer(int occurrenceCount) {
236 // return new Initializer(this, occurrenceCount);
241 // public IInitializer[] getInitializers() throws JavaModelException {
242 // ArrayList list = getChildrenOfType(INITIALIZER);
243 // IInitializer[] array= new IInitializer[list.size()];
244 // list.toArray(array);
248 * @see IType#getMethod
250 public IMethod getMethod(String name, String[] parameterTypeSignatures) {
251 return new SourceMethod(this, name, parameterTypeSignatures);
257 public IMethod[] getMethods() throws JavaModelException {
258 ArrayList list = getChildrenOfType(METHOD);
259 IMethod[] array = new IMethod[list.size()];
267 public IPackageFragment getPackageFragment() {
268 IJavaElement parentElement = this.parent;
269 while (parentElement != null) {
270 if (parentElement.getElementType() == IJavaElement.PACKAGE_FRAGMENT) {
271 return (IPackageFragment) parentElement;
273 parentElement = parentElement.getParent();
276 Assert.isTrue(false); // should not happen
283 public String getSuperclassName() throws JavaModelException {
284 SourceTypeElementInfo info = (SourceTypeElementInfo) getElementInfo();
285 char[] superclassName = info.getSuperclassName();
286 if (superclassName == null) {
289 return new String(superclassName);
295 public String[] getSuperInterfaceNames() throws JavaModelException {
296 SourceTypeElementInfo info = (SourceTypeElementInfo) getElementInfo();
297 char[][] names = info.getInterfaceNames();
301 String[] strings = new String[names.length];
302 for (int i = 0; i < names.length; i++) {
303 strings[i] = new String(names[i]);
311 public IType getType(String name) {
312 return new SourceType(this, name);
316 * @see IType#getTypeQualifiedName
318 public String getTypeQualifiedName() {
319 return this.getTypeQualifiedName('$');
323 * @see IType#getTypeQualifiedName(char)
325 public String getTypeQualifiedName(char enclosingTypeSeparator) {
326 if (parent.getElementType() == IJavaElement.COMPILATION_UNIT) {
329 return ((IType) parent)
330 .getTypeQualifiedName(enclosingTypeSeparator)
331 + enclosingTypeSeparator + name;
338 public IType[] getTypes() throws JavaModelException {
339 ArrayList list = getChildrenOfType(TYPE);
340 IType[] array = new IType[list.size()];
348 public boolean hasChildren() throws JavaModelException {
349 return getChildren().length > 0;
353 * @see IType#isAnonymous()
355 public boolean isAnonymous() throws JavaModelException {
356 return false; // cannot create source handle onto anonymous types
362 public boolean isClass() throws JavaModelException {
363 return !isInterface();
369 public boolean isInterface() throws JavaModelException {
370 Object obj = getElementInfo();
371 if (obj instanceof SourceTypeElementInfo) {
372 SourceTypeElementInfo info = (SourceTypeElementInfo) getElementInfo();
373 return info.isInterface();
379 * @see IType#isLocal()
381 public boolean isLocal() throws JavaModelException {
382 return false; // cannot create source handle onto local types
386 * @see IType#isMember()
388 public boolean isMember() throws JavaModelException {
389 return getDeclaringType() != null;
395 // public ITypeHierarchy loadTypeHierachy(InputStream input,
396 // IProgressMonitor monitor) throws JavaModelException {
397 // return loadTypeHierachy(input, DefaultWorkingCopyOwner.PRIMARY, monitor);
400 * NOTE: This method is not part of the API has it is not clear clients
401 * would easily use it: they would need to first make sure all working
402 * copies for the given owner exist before calling it. This is especially
403 * har at startup time. In case clients want this API, here is how it should
406 * Loads a previously saved ITypeHierarchy from an input stream. A type
407 * hierarchy can be stored using ITypeHierachy#store(OutputStream). A
408 * compilation unit of a loaded type has the given owner if such a working
409 * copy exists, otherwise the type's compilation unit is a primary
412 * Only hierarchies originally created by the following methods can be
415 * <li>IType#newSupertypeHierarchy(IProgressMonitor)</li>
416 * <li>IType#newSupertypeHierarchy(WorkingCopyOwner, IProgressMonitor)</li>
417 * <li>IType#newTypeHierarchy(IJavaProject, IProgressMonitor)</li>
418 * <li>IType#newTypeHierarchy(IJavaProject, WorkingCopyOwner,
419 * IProgressMonitor)</li>
420 * <li>IType#newTypeHierarchy(IProgressMonitor)</li>
421 * <li>IType#newTypeHierarchy(WorkingCopyOwner, IProgressMonitor)</li>
425 * stream where hierarchy will be read
427 * the given progress monitor
428 * @return the stored hierarchy
429 * @exception JavaModelException
430 * if the hierarchy could not be restored, reasons include: -
431 * type is not the focus of the hierarchy or - unable to read
432 * the input stream (wrong format, IOException during
434 * @see ITypeHierarchy#store(java.io.OutputStream, IProgressMonitor)
437 // public ITypeHierarchy loadTypeHierachy(InputStream input,
438 // WorkingCopyOwner owner, IProgressMonitor monitor) throws
439 // JavaModelException {
440 // // TODO monitor should be passed to TypeHierarchy.load(...)
441 // return TypeHierarchy.load(this, input, owner);
446 // public ITypeHierarchy newSupertypeHierarchy(IProgressMonitor monitor)
447 // throws JavaModelException {
448 // return this.newSupertypeHierarchy(DefaultWorkingCopyOwner.PRIMARY,
452 * @see IType#newSupertypeHierarchy(ICompilationUnit[], IProgressMonitor)
454 // public ITypeHierarchy newSupertypeHierarchy(
455 // ICompilationUnit[] workingCopies,
456 // IProgressMonitor monitor)
457 // throws JavaModelException {
459 // CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation(this,
460 // workingCopies, SearchEngine.createWorkspaceScope(), false);
461 // op.runOperation(monitor);
462 // return op.getResult();
465 * @param workingCopies
466 * the working copies that take precedence over their original
469 * the given progress monitor
470 * @return a type hierarchy for this type containing this type and all of
472 * @exception JavaModelException
473 * if this element does not exist or if an exception occurs
474 * while accessing its corresponding resource.
476 * @see IType#newSupertypeHierarchy(IWorkingCopy[], IProgressMonitor)
479 public ITypeHierarchy newSupertypeHierarchy(IWorkingCopy[] workingCopies,
480 IProgressMonitor monitor) throws JavaModelException {
482 ICompilationUnit[] copies;
483 if (workingCopies == null) {
486 int length = workingCopies.length;
487 System.arraycopy(workingCopies, 0,
488 copies = new ICompilationUnit[length], 0, length);
490 return newSupertypeHierarchy(copies, monitor);
494 * @see IType#newSupertypeHierarchy(WorkingCopyOwner, IProgressMonitor)
496 // public ITypeHierarchy newSupertypeHierarchy(
497 // WorkingCopyOwner owner,
498 // IProgressMonitor monitor)
499 // throws JavaModelException {
501 // ICompilationUnit[] workingCopies =
502 // JavaModelManager.getJavaModelManager().getWorkingCopies(owner, true/*add
503 // primary working copies*/);
504 // CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation(this,
505 // workingCopies, SearchEngine.createWorkspaceScope(), false);
506 // op.runOperation(monitor);
507 // return op.getResult();
512 // public ITypeHierarchy newTypeHierarchy(IJavaProject project,
513 // IProgressMonitor monitor) throws JavaModelException {
514 // return newTypeHierarchy(project, DefaultWorkingCopyOwner.PRIMARY,
518 * @see IType#newTypeHierarchy(IJavaProject, WorkingCopyOwner,
521 // public ITypeHierarchy newTypeHierarchy(IJavaProject project,
522 // WorkingCopyOwner owner, IProgressMonitor monitor) throws
523 // JavaModelException {
524 // if (project == null) {
525 // throw new IllegalArgumentException(Util.bind("hierarchy.nullProject"));
528 // ICompilationUnit[] workingCopies =
529 // JavaModelManager.getJavaModelManager().getWorkingCopies(owner, true/*add
530 // primary working copies*/);
531 // ICompilationUnit[] projectWCs = null;
532 // if (workingCopies != null) {
533 // int length = workingCopies.length;
534 // projectWCs = new ICompilationUnit[length];
536 // for (int i = 0; i < length; i++) {
537 // ICompilationUnit wc = workingCopies[i];
538 // if (project.equals(wc.getJavaProject())) {
539 // projectWCs[index++] = wc;
542 // if (index != length) {
543 // System.arraycopy(projectWCs, 0, projectWCs = new ICompilationUnit[index],
547 // CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation(
552 // op.runOperation(monitor);
553 // return op.getResult();
558 // public ITypeHierarchy newTypeHierarchy(IProgressMonitor monitor) throws
559 // JavaModelException {
560 // CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation(this,
561 // null, SearchEngine.createWorkspaceScope(), true);
562 // op.runOperation(monitor);
563 // return op.getResult();
566 * @see IType#newTypeHierarchy(ICompilationUnit[], IProgressMonitor)
568 // public ITypeHierarchy newTypeHierarchy(
569 // ICompilationUnit[] workingCopies,
570 // IProgressMonitor monitor)
571 // throws JavaModelException {
573 // CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation(this,
574 // workingCopies, SearchEngine.createWorkspaceScope(), true);
575 // op.runOperation(monitor);
576 // return op.getResult();
579 * @see IType#newTypeHierarchy(IWorkingCopy[], IProgressMonitor)
582 public ITypeHierarchy newTypeHierarchy(IWorkingCopy[] workingCopies,
583 IProgressMonitor monitor) throws JavaModelException {
585 ICompilationUnit[] copies;
586 if (workingCopies == null) {
589 int length = workingCopies.length;
590 System.arraycopy(workingCopies, 0,
591 copies = new ICompilationUnit[length], 0, length);
593 return newTypeHierarchy(copies, monitor);
597 * @see IType#newTypeHierarchy(WorkingCopyOwner, IProgressMonitor)
599 // public ITypeHierarchy newTypeHierarchy(
600 // WorkingCopyOwner owner,
601 // IProgressMonitor monitor)
602 // throws JavaModelException {
604 // ICompilationUnit[] workingCopies =
605 // JavaModelManager.getJavaModelManager().getWorkingCopies(owner, true/*add
606 // primary working copies*/);
607 // CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation(this,
608 // workingCopies, SearchEngine.createWorkspaceScope(), true);
609 // op.runOperation(monitor);
610 // return op.getResult();
612 // public String[][] resolveType(String typeName) throws JavaModelException
614 // ISourceType info = (ISourceType) this.getElementInfo();
615 // ISearchableNameEnvironment environment =
616 // ((JavaProject)getJavaProject()).getSearchableNameEnvironment();
618 // class TypeResolveRequestor implements ISelectionRequestor {
619 // String[][] answers = null;
620 // void acceptType(String[] answer){
621 // if (answers == null) {
622 // answers = new String[][]{ answer };
625 // int length = answers.length;
626 // System.arraycopy(answers, 0, answers = new String[length+1][], 0,
628 // answers[length] = answer;
631 // public void acceptClass(char[] packageName, char[] className, boolean
632 // needQualification) {
633 // acceptType(new String[] { new String(packageName), new String(className)
637 // public void acceptInterface(char[] packageName, char[] interfaceName,
638 // boolean needQualification) {
639 // acceptType(new String[] { new String(packageName), new
640 // String(interfaceName) });
643 // public void acceptError(IProblem error) {}
644 // public void acceptField(char[] declaringTypePackageName, char[]
645 // declaringTypeName, char[] name) {}
646 // public void acceptMethod(char[] declaringTypePackageName, char[]
647 // declaringTypeName, char[] selector, char[][]
648 // parameterPackageNames, char[][] parameterTypeNames, boolean
650 // public void acceptPackage(char[] packageName){}
653 // TypeResolveRequestor requestor = new TypeResolveRequestor();
654 // SelectionEngine engine =
655 // new SelectionEngine(environment, requestor,
656 // this.getJavaProject().getOptions(true));
658 // IType[] topLevelTypes = this.getCompilationUnit().getTypes();
659 // int length = topLevelTypes.length;
660 // ISourceType[] topLevelInfos = new ISourceType[length];
661 // for (int i = 0; i < length; i++) {
662 // topLevelInfos[i] =
663 // (ISourceType)((SourceType)topLevelTypes[i]).getElementInfo();
666 // engine.selectType(info, typeName.toCharArray(), topLevelInfos, false);
667 // return requestor.answers;
670 * @private Debugging purposes
672 protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
673 buffer.append(this.tabString(tab));
675 buffer.append(this.getElementName());
676 buffer.append(" (not open)"); //$NON-NLS-1$
677 } else if (info == NO_INFO) {
678 buffer.append(getElementName());
681 if (this.isInterface()) {
682 buffer.append("interface "); //$NON-NLS-1$
684 buffer.append("class "); //$NON-NLS-1$
686 buffer.append(this.getElementName());
687 } catch (JavaModelException e) {
689 .append("<JavaModelException in toString of " + getElementName()); //$NON-NLS-1$