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[] {};
46 protected SourceType(JavaElement parent, String name) {
48 Assert.isTrue(name.indexOf('.') == -1, Util.bind(
49 "sourcetype.invalidName", name)); //$NON-NLS-1$
55 // public void codeComplete(char[] snippet,int insertion,int
56 // position,char[][] localVariableTypeNames,char[][]
57 // localVariableNames,int[] localVariableModifiers,boolean
58 // isStatic,ICompletionRequestor requestor) throws JavaModelException {
59 // if (requestor == null) {
61 // IllegalArgumentException(ProjectPrefUtil.bind("codeAssist.nullRequestor"));
65 // JavaProject project = (JavaProject) getJavaProject();
66 // SearchableEnvironment environment = (SearchableEnvironment)
67 // project.getSearchableNameEnvironment();
68 // NameLookup nameLookup = project.getNameLookup();
69 // CompletionEngine engine = new CompletionEngine(environment, new
70 // CompletionRequestorWrapper(requestor,nameLookup),
71 // project.getOptions(true), project);
73 // String source = getCompilationUnit().getSource();
74 // if (source != null && insertion > -1 && insertion < source.length()) {
75 // String encoding = project.getOption(JavaCore.CORE_ENCODING, true);
77 // char[] prefix = CharOperation.concat(source.substring(0,
78 // insertion).toCharArray(), new char[]{'{'});
79 // char[] suffix = CharOperation.concat(new char[]{'}'},
80 // source.substring(insertion).toCharArray());
81 // char[] fakeSource = CharOperation.concat(prefix, snippet, suffix);
83 // BasicCompilationUnit cu =
84 // new BasicCompilationUnit(
90 // engine.complete(cu, prefix.length + position, prefix.length);
92 // engine.complete(this, snippet, position, localVariableTypeNames,
93 // localVariableNames, localVariableModifiers, isStatic);
99 // public IField createField(String contents, IJavaElement sibling, boolean
100 // force, IProgressMonitor monitor) throws
101 // JavaModelException {
102 // CreateFieldOperation op = new CreateFieldOperation(this, contents,
104 // if (sibling != null) {
105 // op.createBefore(sibling);
107 // runOperation(op, monitor);
108 // return (IField) op.getResultElements()[0];
113 // public IInitializer createInitializer(String contents, IJavaElement
114 // sibling, IProgressMonitor monitor) throws
115 // JavaModelException {
116 // CreateInitializerOperation op = new CreateInitializerOperation(this,
118 // if (sibling != null) {
119 // op.createBefore(sibling);
121 // runOperation(op, monitor);
122 // return (IInitializer) op.getResultElements()[0];
127 // public IMethod createMethod(String contents, IJavaElement sibling,
128 // boolean force, IProgressMonitor monitor) throws
129 // JavaModelException {
130 // CreateMethodOperation op = new CreateMethodOperation(this, contents,
132 // if (sibling != null) {
133 // op.createBefore(sibling);
135 // runOperation(op, monitor);
136 // return (IMethod) op.getResultElements()[0];
141 // public IType createType(String contents, IJavaElement sibling, boolean
142 // force, IProgressMonitor monitor) throws
143 // JavaModelException {
144 // CreateTypeOperation op = new CreateTypeOperation(this, contents, force);
145 // if (sibling != null) {
146 // op.createBefore(sibling);
148 // runOperation(op, monitor);
149 // return (IType) op.getResultElements()[0];
152 * @see JavaElement#equalsDOMNode
154 protected boolean equalsDOMNode(IDOMNode node) throws JavaModelException {
155 return (node.getNodeType() == IDOMNode.TYPE)
156 && super.equalsDOMNode(node);
162 public IMethod[] findMethods(IMethod method) {
164 return this.findMethods(method, this.getMethods());
165 } catch (JavaModelException e) {
166 // if type doesn't exist, no matching method can exist
174 public IType getDeclaringType() {
175 IJavaElement parent = getParent();
176 while (parent != null) {
177 if (parent.getElementType() == IJavaElement.TYPE) {
178 return (IType) parent;
179 } else if (parent instanceof IMember) {
180 parent = parent.getParent();
191 public int getElementType() {
196 * @see IType#getField
198 public IField getField(String name) {
199 return new SourceField(this, name);
205 public IField[] getFields() throws JavaModelException {
206 ArrayList list = getChildrenOfType(FIELD);
207 IField[] array = new IField[list.size()];
213 * @see IType#getFullyQualifiedName
215 public String getFullyQualifiedName() {
216 return this.getFullyQualifiedName('$');
220 * @see IType#getFullyQualifiedName(char)
222 public String getFullyQualifiedName(char enclosingTypeSeparator) {
223 String packageName = getPackageFragment().getElementName();
224 if (packageName.equals(IPackageFragment.DEFAULT_PACKAGE_NAME)) {
225 return getTypeQualifiedName(enclosingTypeSeparator);
227 return packageName + '.' + getTypeQualifiedName(enclosingTypeSeparator);
233 // public IInitializer getInitializer(int occurrenceCount) {
234 // return new Initializer(this, occurrenceCount);
239 // public IInitializer[] getInitializers() throws JavaModelException {
240 // ArrayList list = getChildrenOfType(INITIALIZER);
241 // IInitializer[] array= new IInitializer[list.size()];
242 // list.toArray(array);
246 * @see IType#getMethod
248 public IMethod getMethod(String name, String[] parameterTypeSignatures) {
249 return new SourceMethod(this, name, parameterTypeSignatures);
255 public IMethod[] getMethods() throws JavaModelException {
256 ArrayList list = getChildrenOfType(METHOD);
257 IMethod[] array = new IMethod[list.size()];
265 public IPackageFragment getPackageFragment() {
266 IJavaElement parentElement = this.parent;
267 while (parentElement != null) {
268 if (parentElement.getElementType() == IJavaElement.PACKAGE_FRAGMENT) {
269 return (IPackageFragment) parentElement;
271 parentElement = parentElement.getParent();
274 Assert.isTrue(false); // should not happen
281 public String getSuperclassName() throws JavaModelException {
282 SourceTypeElementInfo info = (SourceTypeElementInfo) getElementInfo();
283 char[] superclassName = info.getSuperclassName();
284 if (superclassName == null) {
287 return new String(superclassName);
293 public String[] getSuperInterfaceNames() throws JavaModelException {
294 SourceTypeElementInfo info = (SourceTypeElementInfo) getElementInfo();
295 char[][] names = info.getInterfaceNames();
299 String[] strings = new String[names.length];
300 for (int i = 0; i < names.length; i++) {
301 strings[i] = new String(names[i]);
309 public IType getType(String name) {
310 return new SourceType(this, name);
314 * @see IType#getTypeQualifiedName
316 public String getTypeQualifiedName() {
317 return this.getTypeQualifiedName('$');
321 * @see IType#getTypeQualifiedName(char)
323 public String getTypeQualifiedName(char enclosingTypeSeparator) {
324 if (parent.getElementType() == IJavaElement.COMPILATION_UNIT) {
327 return ((IType) parent)
328 .getTypeQualifiedName(enclosingTypeSeparator)
329 + enclosingTypeSeparator + name;
336 public IType[] getTypes() throws JavaModelException {
337 ArrayList list = getChildrenOfType(TYPE);
338 IType[] array = new IType[list.size()];
346 public boolean hasChildren() throws JavaModelException {
347 return getChildren().length > 0;
351 * @see IType#isAnonymous()
353 public boolean isAnonymous() throws JavaModelException {
354 return false; // cannot create source handle onto anonymous types
360 public boolean isClass() throws JavaModelException {
361 return !isInterface();
367 public boolean isInterface() throws JavaModelException {
368 Object obj = getElementInfo();
369 if (obj instanceof SourceTypeElementInfo) {
370 SourceTypeElementInfo info = (SourceTypeElementInfo) getElementInfo();
371 return info.isInterface();
377 * @see IType#isLocal()
379 public boolean isLocal() throws JavaModelException {
380 return false; // cannot create source handle onto local types
384 * @see IType#isMember()
386 public boolean isMember() throws JavaModelException {
387 return getDeclaringType() != null;
393 // public ITypeHierarchy loadTypeHierachy(InputStream input,
394 // IProgressMonitor monitor) throws JavaModelException {
395 // return loadTypeHierachy(input, DefaultWorkingCopyOwner.PRIMARY, monitor);
398 * NOTE: This method is not part of the API has it is not clear clients
399 * would easily use it: they would need to first make sure all working
400 * copies for the given owner exist before calling it. This is especially
401 * har at startup time. In case clients want this API, here is how it should
404 * Loads a previously saved ITypeHierarchy from an input stream. A type
405 * hierarchy can be stored using ITypeHierachy#store(OutputStream). A
406 * compilation unit of a loaded type has the given owner if such a working
407 * copy exists, otherwise the type's compilation unit is a primary
410 * Only hierarchies originally created by the following methods can be
413 * <li>IType#newSupertypeHierarchy(IProgressMonitor)</li>
414 * <li>IType#newSupertypeHierarchy(WorkingCopyOwner, IProgressMonitor)</li>
415 * <li>IType#newTypeHierarchy(IJavaProject, IProgressMonitor)</li>
416 * <li>IType#newTypeHierarchy(IJavaProject, WorkingCopyOwner,
417 * IProgressMonitor)</li>
418 * <li>IType#newTypeHierarchy(IProgressMonitor)</li>
419 * <li>IType#newTypeHierarchy(WorkingCopyOwner, IProgressMonitor)</li>
423 * stream where hierarchy will be read
425 * the given progress monitor
426 * @return the stored hierarchy
427 * @exception JavaModelException
428 * if the hierarchy could not be restored, reasons include: -
429 * type is not the focus of the hierarchy or - unable to read
430 * the input stream (wrong format, IOException during
432 * @see ITypeHierarchy#store(java.io.OutputStream, IProgressMonitor)
435 // public ITypeHierarchy loadTypeHierachy(InputStream input,
436 // WorkingCopyOwner owner, IProgressMonitor monitor) throws
437 // JavaModelException {
438 // // TODO monitor should be passed to TypeHierarchy.load(...)
439 // return TypeHierarchy.load(this, input, owner);
444 // public ITypeHierarchy newSupertypeHierarchy(IProgressMonitor monitor)
445 // throws JavaModelException {
446 // return this.newSupertypeHierarchy(DefaultWorkingCopyOwner.PRIMARY,
450 * @see IType#newSupertypeHierarchy(ICompilationUnit[], IProgressMonitor)
452 // public ITypeHierarchy newSupertypeHierarchy(
453 // ICompilationUnit[] workingCopies,
454 // IProgressMonitor monitor)
455 // throws JavaModelException {
457 // CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation(this,
458 // workingCopies, SearchEngine.createWorkspaceScope(), false);
459 // op.runOperation(monitor);
460 // return op.getResult();
463 * @param workingCopies
464 * the working copies that take precedence over their original
467 * the given progress monitor
468 * @return a type hierarchy for this type containing this type and all of
470 * @exception JavaModelException
471 * if this element does not exist or if an exception occurs
472 * while accessing its corresponding resource.
474 * @see IType#newSupertypeHierarchy(IWorkingCopy[], IProgressMonitor)
477 public ITypeHierarchy newSupertypeHierarchy(IWorkingCopy[] workingCopies,
478 IProgressMonitor monitor) throws JavaModelException {
480 ICompilationUnit[] copies;
481 if (workingCopies == null) {
484 int length = workingCopies.length;
485 System.arraycopy(workingCopies, 0,
486 copies = new ICompilationUnit[length], 0, length);
488 return newSupertypeHierarchy(copies, monitor);
492 * @see IType#newSupertypeHierarchy(WorkingCopyOwner, IProgressMonitor)
494 // public ITypeHierarchy newSupertypeHierarchy(
495 // WorkingCopyOwner owner,
496 // IProgressMonitor monitor)
497 // throws JavaModelException {
499 // ICompilationUnit[] workingCopies =
500 // JavaModelManager.getJavaModelManager().getWorkingCopies(owner, true/*add
501 // primary working copies*/);
502 // CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation(this,
503 // workingCopies, SearchEngine.createWorkspaceScope(), false);
504 // op.runOperation(monitor);
505 // return op.getResult();
510 // public ITypeHierarchy newTypeHierarchy(IJavaProject project,
511 // IProgressMonitor monitor) throws JavaModelException {
512 // return newTypeHierarchy(project, DefaultWorkingCopyOwner.PRIMARY,
516 * @see IType#newTypeHierarchy(IJavaProject, WorkingCopyOwner,
519 // public ITypeHierarchy newTypeHierarchy(IJavaProject project,
520 // WorkingCopyOwner owner, IProgressMonitor monitor) throws
521 // JavaModelException {
522 // if (project == null) {
523 // throw new IllegalArgumentException(Util.bind("hierarchy.nullProject"));
526 // ICompilationUnit[] workingCopies =
527 // JavaModelManager.getJavaModelManager().getWorkingCopies(owner, true/*add
528 // primary working copies*/);
529 // ICompilationUnit[] projectWCs = null;
530 // if (workingCopies != null) {
531 // int length = workingCopies.length;
532 // projectWCs = new ICompilationUnit[length];
534 // for (int i = 0; i < length; i++) {
535 // ICompilationUnit wc = workingCopies[i];
536 // if (project.equals(wc.getJavaProject())) {
537 // projectWCs[index++] = wc;
540 // if (index != length) {
541 // System.arraycopy(projectWCs, 0, projectWCs = new ICompilationUnit[index],
545 // CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation(
550 // op.runOperation(monitor);
551 // return op.getResult();
556 // public ITypeHierarchy newTypeHierarchy(IProgressMonitor monitor) throws
557 // JavaModelException {
558 // CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation(this,
559 // null, SearchEngine.createWorkspaceScope(), true);
560 // op.runOperation(monitor);
561 // return op.getResult();
564 * @see IType#newTypeHierarchy(ICompilationUnit[], IProgressMonitor)
566 // public ITypeHierarchy newTypeHierarchy(
567 // ICompilationUnit[] workingCopies,
568 // IProgressMonitor monitor)
569 // throws JavaModelException {
571 // CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation(this,
572 // workingCopies, SearchEngine.createWorkspaceScope(), true);
573 // op.runOperation(monitor);
574 // return op.getResult();
577 * @see IType#newTypeHierarchy(IWorkingCopy[], IProgressMonitor)
580 public ITypeHierarchy newTypeHierarchy(IWorkingCopy[] workingCopies,
581 IProgressMonitor monitor) throws JavaModelException {
583 ICompilationUnit[] copies;
584 if (workingCopies == null) {
587 int length = workingCopies.length;
588 System.arraycopy(workingCopies, 0,
589 copies = new ICompilationUnit[length], 0, length);
591 return newTypeHierarchy(copies, monitor);
595 * @see IType#newTypeHierarchy(WorkingCopyOwner, IProgressMonitor)
597 // public ITypeHierarchy newTypeHierarchy(
598 // WorkingCopyOwner owner,
599 // IProgressMonitor monitor)
600 // throws JavaModelException {
602 // ICompilationUnit[] workingCopies =
603 // JavaModelManager.getJavaModelManager().getWorkingCopies(owner, true/*add
604 // primary working copies*/);
605 // CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation(this,
606 // workingCopies, SearchEngine.createWorkspaceScope(), true);
607 // op.runOperation(monitor);
608 // return op.getResult();
610 // public String[][] resolveType(String typeName) throws JavaModelException
612 // ISourceType info = (ISourceType) this.getElementInfo();
613 // ISearchableNameEnvironment environment =
614 // ((JavaProject)getJavaProject()).getSearchableNameEnvironment();
616 // class TypeResolveRequestor implements ISelectionRequestor {
617 // String[][] answers = null;
618 // void acceptType(String[] answer){
619 // if (answers == null) {
620 // answers = new String[][]{ answer };
623 // int length = answers.length;
624 // System.arraycopy(answers, 0, answers = new String[length+1][], 0,
626 // answers[length] = answer;
629 // public void acceptClass(char[] packageName, char[] className, boolean
630 // needQualification) {
631 // acceptType(new String[] { new String(packageName), new String(className)
635 // public void acceptInterface(char[] packageName, char[] interfaceName,
636 // boolean needQualification) {
637 // acceptType(new String[] { new String(packageName), new
638 // String(interfaceName) });
641 // public void acceptError(IProblem error) {}
642 // public void acceptField(char[] declaringTypePackageName, char[]
643 // declaringTypeName, char[] name) {}
644 // public void acceptMethod(char[] declaringTypePackageName, char[]
645 // declaringTypeName, char[] selector, char[][]
646 // parameterPackageNames, char[][] parameterTypeNames, boolean
648 // public void acceptPackage(char[] packageName){}
651 // TypeResolveRequestor requestor = new TypeResolveRequestor();
652 // SelectionEngine engine =
653 // new SelectionEngine(environment, requestor,
654 // this.getJavaProject().getOptions(true));
656 // IType[] topLevelTypes = this.getCompilationUnit().getTypes();
657 // int length = topLevelTypes.length;
658 // ISourceType[] topLevelInfos = new ISourceType[length];
659 // for (int i = 0; i < length; i++) {
660 // topLevelInfos[i] =
661 // (ISourceType)((SourceType)topLevelTypes[i]).getElementInfo();
664 // engine.selectType(info, typeName.toCharArray(), topLevelInfos, false);
665 // return requestor.answers;
668 * @private Debugging purposes
670 protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
671 buffer.append(this.tabString(tab));
673 buffer.append(this.getElementName());
674 buffer.append(" (not open)"); //$NON-NLS-1$
675 } else if (info == NO_INFO) {
676 buffer.append(getElementName());
679 if (this.isInterface()) {
680 buffer.append("interface "); //$NON-NLS-1$
682 buffer.append("class "); //$NON-NLS-1$
684 buffer.append(this.getElementName());
685 } catch (JavaModelException e) {
687 .append("<JavaModelException in toString of " + getElementName()); //$NON-NLS-1$