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.io.InputStream;
14 import java.util.ArrayList;
16 import net.sourceforge.phpdt.core.ICompilationUnit;
17 import net.sourceforge.phpdt.core.IField;
18 import net.sourceforge.phpdt.core.IJavaElement;
19 import net.sourceforge.phpdt.core.IJavaProject;
20 import net.sourceforge.phpdt.core.IMember;
21 import net.sourceforge.phpdt.core.IMethod;
22 import net.sourceforge.phpdt.core.IPackageFragment;
23 import net.sourceforge.phpdt.core.IParent;
24 import net.sourceforge.phpdt.core.IType;
25 import net.sourceforge.phpdt.core.ITypeHierarchy;
26 import net.sourceforge.phpdt.core.IWorkingCopy;
27 import net.sourceforge.phpdt.core.JavaModelException;
28 import net.sourceforge.phpdt.core.WorkingCopyOwner;
29 import net.sourceforge.phpdt.core.jdom.IDOMNode;
30 import net.sourceforge.phpdt.internal.core.util.Util;
31 import net.sourceforge.phpdt.internal.corext.Assert;
33 import org.eclipse.core.runtime.IProgressMonitor;
36 * Handle for a source type. Info object is a SourceTypeElementInfo.
38 * Note: Parent is either an IClassFile, an ICompilationUnit or an IType.
43 public class SourceType extends Member implements IType {
45 * An empty list of Strings
47 protected static final String[] fgEmptyList = new String[] {};
48 protected SourceType(JavaElement parent, String name) {
50 Assert.isTrue(name.indexOf('.') == -1, Util.bind("sourcetype.invalidName", name)); //$NON-NLS-1$
56 //public void codeComplete(char[] snippet,int insertion,int position,char[][] localVariableTypeNames,char[][]
57 // localVariableNames,int[] localVariableModifiers,boolean isStatic,ICompletionRequestor requestor) throws JavaModelException {
58 // if (requestor == null) {
59 // throw new IllegalArgumentException(ProjectPrefUtil.bind("codeAssist.nullRequestor")); //$NON-NLS-1$
62 // JavaProject project = (JavaProject) getJavaProject();
63 // SearchableEnvironment environment = (SearchableEnvironment) project.getSearchableNameEnvironment();
64 // NameLookup nameLookup = project.getNameLookup();
65 // CompletionEngine engine = new CompletionEngine(environment, new CompletionRequestorWrapper(requestor,nameLookup),
66 // project.getOptions(true), project);
68 // String source = getCompilationUnit().getSource();
69 // if (source != null && insertion > -1 && insertion < source.length()) {
70 // String encoding = project.getOption(JavaCore.CORE_ENCODING, true);
72 // char[] prefix = CharOperation.concat(source.substring(0, insertion).toCharArray(), new char[]{'{'});
73 // char[] suffix = CharOperation.concat(new char[]{'}'}, source.substring(insertion).toCharArray());
74 // char[] fakeSource = CharOperation.concat(prefix, snippet, suffix);
76 // BasicCompilationUnit cu =
77 // new BasicCompilationUnit(
83 // engine.complete(cu, prefix.length + position, prefix.length);
85 // engine.complete(this, snippet, position, localVariableTypeNames, localVariableNames, localVariableModifiers, isStatic);
91 //public IField createField(String contents, IJavaElement sibling, boolean force, IProgressMonitor monitor) throws
92 // JavaModelException {
93 // CreateFieldOperation op = new CreateFieldOperation(this, contents, force);
94 // if (sibling != null) {
95 // op.createBefore(sibling);
97 // runOperation(op, monitor);
98 // return (IField) op.getResultElements()[0];
103 //public IInitializer createInitializer(String contents, IJavaElement sibling, IProgressMonitor monitor) throws
104 // JavaModelException {
105 // CreateInitializerOperation op = new CreateInitializerOperation(this, contents);
106 // if (sibling != null) {
107 // op.createBefore(sibling);
109 // runOperation(op, monitor);
110 // return (IInitializer) op.getResultElements()[0];
115 //public IMethod createMethod(String contents, IJavaElement sibling, boolean force, IProgressMonitor monitor) throws
116 // JavaModelException {
117 // CreateMethodOperation op = new CreateMethodOperation(this, contents, force);
118 // if (sibling != null) {
119 // op.createBefore(sibling);
121 // runOperation(op, monitor);
122 // return (IMethod) op.getResultElements()[0];
127 //public IType createType(String contents, IJavaElement sibling, boolean force, IProgressMonitor monitor) throws
128 // JavaModelException {
129 // CreateTypeOperation op = new CreateTypeOperation(this, contents, force);
130 // if (sibling != null) {
131 // op.createBefore(sibling);
133 // runOperation(op, monitor);
134 // return (IType) op.getResultElements()[0];
137 * @see JavaElement#equalsDOMNode
139 protected boolean equalsDOMNode(IDOMNode node) throws JavaModelException {
140 return (node.getNodeType() == IDOMNode.TYPE) && super.equalsDOMNode(node);
146 public IMethod[] findMethods(IMethod method) {
148 return this.findMethods(method, this.getMethods());
149 } catch (JavaModelException e) {
150 // if type doesn't exist, no matching method can exist
158 public IType getDeclaringType() {
159 IJavaElement parent = getParent();
160 while (parent != null) {
161 if (parent.getElementType() == IJavaElement.TYPE) {
162 return (IType) parent;
163 } else if (parent instanceof IMember) {
164 parent = parent.getParent();
175 public int getElementType() {
180 * @see IType#getField
182 public IField getField(String name) {
183 return new SourceField(this, name);
189 public IField[] getFields() throws JavaModelException {
190 ArrayList list = getChildrenOfType(FIELD);
191 IField[] array = new IField[list.size()];
197 * @see IType#getFullyQualifiedName
199 public String getFullyQualifiedName() {
200 return this.getFullyQualifiedName('$');
204 * @see IType#getFullyQualifiedName(char)
206 public String getFullyQualifiedName(char enclosingTypeSeparator) {
207 String packageName = getPackageFragment().getElementName();
208 if (packageName.equals(IPackageFragment.DEFAULT_PACKAGE_NAME)) {
209 return getTypeQualifiedName(enclosingTypeSeparator);
211 return packageName + '.' + getTypeQualifiedName(enclosingTypeSeparator);
217 //public IInitializer getInitializer(int occurrenceCount) {
218 // return new Initializer(this, occurrenceCount);
223 //public IInitializer[] getInitializers() throws JavaModelException {
224 // ArrayList list = getChildrenOfType(INITIALIZER);
225 // IInitializer[] array= new IInitializer[list.size()];
226 // list.toArray(array);
230 * @see IType#getMethod
232 public IMethod getMethod(String name, String[] parameterTypeSignatures) {
233 return new SourceMethod(this, name, parameterTypeSignatures);
239 public IMethod[] getMethods() throws JavaModelException {
240 ArrayList list = getChildrenOfType(METHOD);
241 IMethod[] array = new IMethod[list.size()];
249 public IPackageFragment getPackageFragment() {
250 IJavaElement parentElement = this.parent;
251 while (parentElement != null) {
252 if (parentElement.getElementType() == IJavaElement.PACKAGE_FRAGMENT) {
253 return (IPackageFragment) parentElement;
255 parentElement = parentElement.getParent();
258 Assert.isTrue(false); // should not happen
265 public String getSuperclassName() throws JavaModelException {
266 SourceTypeElementInfo info = (SourceTypeElementInfo) getElementInfo();
267 char[] superclassName = info.getSuperclassName();
268 if (superclassName == null) {
271 return new String(superclassName);
277 public String[] getSuperInterfaceNames() throws JavaModelException {
278 SourceTypeElementInfo info = (SourceTypeElementInfo) getElementInfo();
279 char[][] names = info.getInterfaceNames();
283 String[] strings = new String[names.length];
284 for (int i = 0; i < names.length; i++) {
285 strings[i] = new String(names[i]);
293 public IType getType(String name) {
294 return new SourceType(this, name);
298 * @see IType#getTypeQualifiedName
300 public String getTypeQualifiedName() {
301 return this.getTypeQualifiedName('$');
305 * @see IType#getTypeQualifiedName(char)
307 public String getTypeQualifiedName(char enclosingTypeSeparator) {
308 if (parent.getElementType() == IJavaElement.COMPILATION_UNIT) {
311 return ((IType) parent).getTypeQualifiedName(enclosingTypeSeparator) + enclosingTypeSeparator + name;
318 public IType[] getTypes() throws JavaModelException {
319 ArrayList list = getChildrenOfType(TYPE);
320 IType[] array = new IType[list.size()];
328 public boolean hasChildren() throws JavaModelException {
329 return getChildren().length > 0;
333 * @see IType#isAnonymous()
335 public boolean isAnonymous() throws JavaModelException {
336 return false; // cannot create source handle onto anonymous types
342 public boolean isClass() throws JavaModelException {
343 return !isInterface();
349 public boolean isInterface() throws JavaModelException {
350 Object obj = getElementInfo();
351 if (obj instanceof SourceTypeElementInfo) {
352 SourceTypeElementInfo info = (SourceTypeElementInfo) getElementInfo();
353 return info.isInterface();
359 * @see IType#isLocal()
361 public boolean isLocal() throws JavaModelException {
362 return false; // cannot create source handle onto local types
366 * @see IType#isMember()
368 public boolean isMember() throws JavaModelException {
369 return getDeclaringType() != null;
375 // public ITypeHierarchy loadTypeHierachy(InputStream input, IProgressMonitor monitor) throws JavaModelException {
376 // return loadTypeHierachy(input, DefaultWorkingCopyOwner.PRIMARY, monitor);
379 * NOTE: This method is not part of the API has it is not clear clients would easily use it: they would need to
380 * first make sure all working copies for the given owner exist before calling it. This is especially har at startup
382 * In case clients want this API, here is how it should be specified:
384 * Loads a previously saved ITypeHierarchy from an input stream. A type hierarchy can
385 * be stored using ITypeHierachy#store(OutputStream). A compilation unit of a
386 * loaded type has the given owner if such a working copy exists, otherwise the type's
387 * compilation unit is a primary compilation unit.
389 * Only hierarchies originally created by the following methods can be loaded:
391 * <li>IType#newSupertypeHierarchy(IProgressMonitor)</li>
392 * <li>IType#newSupertypeHierarchy(WorkingCopyOwner, IProgressMonitor)</li>
393 * <li>IType#newTypeHierarchy(IJavaProject, IProgressMonitor)</li>
394 * <li>IType#newTypeHierarchy(IJavaProject, WorkingCopyOwner, IProgressMonitor)</li>
395 * <li>IType#newTypeHierarchy(IProgressMonitor)</li>
396 * <li>IType#newTypeHierarchy(WorkingCopyOwner, IProgressMonitor)</li>
399 * @param input stream where hierarchy will be read
400 * @param monitor the given progress monitor
401 * @return the stored hierarchy
402 * @exception JavaModelException if the hierarchy could not be restored, reasons include:
403 * - type is not the focus of the hierarchy or
404 * - unable to read the input stream (wrong format, IOException during reading, ...)
405 * @see ITypeHierarchy#store(java.io.OutputStream, IProgressMonitor)
408 // public ITypeHierarchy loadTypeHierachy(InputStream input, WorkingCopyOwner owner, IProgressMonitor monitor) throws JavaModelException {
409 // // TODO monitor should be passed to TypeHierarchy.load(...)
410 // return TypeHierarchy.load(this, input, owner);
415 // public ITypeHierarchy newSupertypeHierarchy(IProgressMonitor monitor) throws JavaModelException {
416 // return this.newSupertypeHierarchy(DefaultWorkingCopyOwner.PRIMARY, monitor);
419 * @see IType#newSupertypeHierarchy(ICompilationUnit[], IProgressMonitor)
421 // public ITypeHierarchy newSupertypeHierarchy(
422 // ICompilationUnit[] workingCopies,
423 // IProgressMonitor monitor)
424 // throws JavaModelException {
426 // CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation(this, workingCopies, SearchEngine.createWorkspaceScope(), false);
427 // op.runOperation(monitor);
428 // return op.getResult();
431 * @param workingCopies the working copies that take precedence over their original compilation units
432 * @param monitor the given progress monitor
433 * @return a type hierarchy for this type containing this type and all of its supertypes
434 * @exception JavaModelException if this element does not exist or if an
435 * exception occurs while accessing its corresponding resource.
437 * @see IType#newSupertypeHierarchy(IWorkingCopy[], IProgressMonitor)
440 public ITypeHierarchy newSupertypeHierarchy(
441 IWorkingCopy[] workingCopies,
442 IProgressMonitor monitor)
443 throws JavaModelException {
445 ICompilationUnit[] copies;
446 if (workingCopies == null) {
449 int length = workingCopies.length;
450 System.arraycopy(workingCopies, 0, copies = new ICompilationUnit[length], 0, length);
452 return newSupertypeHierarchy(copies, monitor);
455 * @see IType#newSupertypeHierarchy(WorkingCopyOwner, IProgressMonitor)
457 // public ITypeHierarchy newSupertypeHierarchy(
458 // WorkingCopyOwner owner,
459 // IProgressMonitor monitor)
460 // throws JavaModelException {
462 // ICompilationUnit[] workingCopies = JavaModelManager.getJavaModelManager().getWorkingCopies(owner, true/*add primary working copies*/);
463 // CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation(this, workingCopies, SearchEngine.createWorkspaceScope(), false);
464 // op.runOperation(monitor);
465 // return op.getResult();
470 // public ITypeHierarchy newTypeHierarchy(IJavaProject project, IProgressMonitor monitor) throws JavaModelException {
471 // return newTypeHierarchy(project, DefaultWorkingCopyOwner.PRIMARY, monitor);
474 * @see IType#newTypeHierarchy(IJavaProject, WorkingCopyOwner, IProgressMonitor)
476 // public ITypeHierarchy newTypeHierarchy(IJavaProject project, WorkingCopyOwner owner, IProgressMonitor monitor) throws JavaModelException {
477 // if (project == null) {
478 // throw new IllegalArgumentException(Util.bind("hierarchy.nullProject")); //$NON-NLS-1$
480 // ICompilationUnit[] workingCopies = JavaModelManager.getJavaModelManager().getWorkingCopies(owner, true/*add primary working copies*/);
481 // ICompilationUnit[] projectWCs = null;
482 // if (workingCopies != null) {
483 // int length = workingCopies.length;
484 // projectWCs = new ICompilationUnit[length];
486 // for (int i = 0; i < length; i++) {
487 // ICompilationUnit wc = workingCopies[i];
488 // if (project.equals(wc.getJavaProject())) {
489 // projectWCs[index++] = wc;
492 // if (index != length) {
493 // System.arraycopy(projectWCs, 0, projectWCs = new ICompilationUnit[index], 0, index);
496 // CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation(
501 // op.runOperation(monitor);
502 // return op.getResult();
507 // public ITypeHierarchy newTypeHierarchy(IProgressMonitor monitor) throws JavaModelException {
508 // CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation(this, null, SearchEngine.createWorkspaceScope(), true);
509 // op.runOperation(monitor);
510 // return op.getResult();
513 * @see IType#newTypeHierarchy(ICompilationUnit[], IProgressMonitor)
515 // public ITypeHierarchy newTypeHierarchy(
516 // ICompilationUnit[] workingCopies,
517 // IProgressMonitor monitor)
518 // throws JavaModelException {
520 // CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation(this, workingCopies, SearchEngine.createWorkspaceScope(), true);
521 // op.runOperation(monitor);
522 // return op.getResult();
525 * @see IType#newTypeHierarchy(IWorkingCopy[], IProgressMonitor)
528 public ITypeHierarchy newTypeHierarchy(
529 IWorkingCopy[] workingCopies,
530 IProgressMonitor monitor)
531 throws JavaModelException {
533 ICompilationUnit[] copies;
534 if (workingCopies == null) {
537 int length = workingCopies.length;
538 System.arraycopy(workingCopies, 0, copies = new ICompilationUnit[length], 0, length);
540 return newTypeHierarchy(copies, monitor);
543 * @see IType#newTypeHierarchy(WorkingCopyOwner, IProgressMonitor)
545 // public ITypeHierarchy newTypeHierarchy(
546 // WorkingCopyOwner owner,
547 // IProgressMonitor monitor)
548 // throws JavaModelException {
550 // ICompilationUnit[] workingCopies = JavaModelManager.getJavaModelManager().getWorkingCopies(owner, true/*add primary working copies*/);
551 // CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation(this, workingCopies, SearchEngine.createWorkspaceScope(), true);
552 // op.runOperation(monitor);
553 // return op.getResult();
556 // public String[][] resolveType(String typeName) throws JavaModelException {
557 // ISourceType info = (ISourceType) this.getElementInfo();
558 // ISearchableNameEnvironment environment = ((JavaProject)getJavaProject()).getSearchableNameEnvironment();
560 // class TypeResolveRequestor implements ISelectionRequestor {
561 // String[][] answers = null;
562 // void acceptType(String[] answer){
563 // if (answers == null) {
564 // answers = new String[][]{ answer };
567 // int length = answers.length;
568 // System.arraycopy(answers, 0, answers = new String[length+1][], 0, length);
569 // answers[length] = answer;
572 // public void acceptClass(char[] packageName, char[] className, boolean needQualification) {
573 // acceptType(new String[] { new String(packageName), new String(className) });
576 // public void acceptInterface(char[] packageName, char[] interfaceName, boolean needQualification) {
577 // acceptType(new String[] { new String(packageName), new String(interfaceName) });
580 // public void acceptError(IProblem error) {}
581 // public void acceptField(char[] declaringTypePackageName, char[] declaringTypeName, char[] name) {}
582 // public void acceptMethod(char[] declaringTypePackageName, char[] declaringTypeName, char[] selector, char[][]
583 // parameterPackageNames, char[][] parameterTypeNames, boolean isConstructor) {}
584 // public void acceptPackage(char[] packageName){}
587 // TypeResolveRequestor requestor = new TypeResolveRequestor();
588 // SelectionEngine engine =
589 // new SelectionEngine(environment, requestor, this.getJavaProject().getOptions(true));
591 // IType[] topLevelTypes = this.getCompilationUnit().getTypes();
592 // int length = topLevelTypes.length;
593 // ISourceType[] topLevelInfos = new ISourceType[length];
594 // for (int i = 0; i < length; i++) {
595 // topLevelInfos[i] = (ISourceType)((SourceType)topLevelTypes[i]).getElementInfo();
598 // engine.selectType(info, typeName.toCharArray(), topLevelInfos, false);
599 // return requestor.answers;
602 * @private Debugging purposes
604 protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
605 buffer.append(this.tabString(tab));
607 buffer.append(this.getElementName());
608 buffer.append(" (not open)"); //$NON-NLS-1$
609 } else if (info == NO_INFO) {
610 buffer.append(getElementName());
613 if (this.isInterface()) {
614 buffer.append("interface "); //$NON-NLS-1$
616 buffer.append("class "); //$NON-NLS-1$
618 buffer.append(this.getElementName());
619 } catch (JavaModelException e) {
620 buffer.append("<JavaModelException in toString of " + getElementName()); //$NON-NLS-1$