Refactory: replaced internal copy of Assert class with org.eclipse.core.runtime.Assert
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / core / SourceType.java
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
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package net.sourceforge.phpdt.internal.core;
12
13 import java.util.ArrayList;
14
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 //incastrix
29 //import net.sourceforge.phpdt.internal.corext.Assert;
30 import org.eclipse.core.runtime.Assert;
31
32 import org.eclipse.core.runtime.IProgressMonitor;
33
34 /**
35  * Handle for a source type. Info object is a SourceTypeElementInfo.
36  * 
37  * Note: Parent is either an IClassFile, an ICompilationUnit or an IType.
38  * 
39  * @see IType
40  */
41
42 public class SourceType extends Member implements IType {
43         /**
44          * An empty list of Strings
45          */
46         protected static final String[] fgEmptyList = new String[] {};
47
48         protected SourceType(JavaElement parent, String name) {
49                 super(parent, name);
50                 Assert.isTrue(name.indexOf('.') == -1, Util.bind(
51                                 "sourcetype.invalidName", name)); //$NON-NLS-1$
52         }
53
54         /**
55          * @see IType
56          */
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) {
62         // throw new
63         // IllegalArgumentException(ProjectPrefUtil.bind("codeAssist.nullRequestor"));
64         // //$NON-NLS-1$
65         // }
66         //      
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);
74         //      
75         // String source = getCompilationUnit().getSource();
76         // if (source != null && insertion > -1 && insertion < source.length()) {
77         // String encoding = project.getOption(JavaCore.CORE_ENCODING, true);
78         //              
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);
84         //              
85         // BasicCompilationUnit cu =
86         // new BasicCompilationUnit(
87         // fakeSource,
88         // null,
89         // getElementName(),
90         // encoding);
91         //
92         // engine.complete(cu, prefix.length + position, prefix.length);
93         // } else {
94         // engine.complete(this, snippet, position, localVariableTypeNames,
95         // localVariableNames, localVariableModifiers, isStatic);
96         // }
97         // }
98         /**
99          * @see IType
100          */
101         // public IField createField(String contents, IJavaElement sibling, boolean
102         // force, IProgressMonitor monitor) throws
103         // JavaModelException {
104         // CreateFieldOperation op = new CreateFieldOperation(this, contents,
105         // force);
106         // if (sibling != null) {
107         // op.createBefore(sibling);
108         // }
109         // runOperation(op, monitor);
110         // return (IField) op.getResultElements()[0];
111         // }
112         /**
113          * @see IType
114          */
115         // public IInitializer createInitializer(String contents, IJavaElement
116         // sibling, IProgressMonitor monitor) throws
117         // JavaModelException {
118         // CreateInitializerOperation op = new CreateInitializerOperation(this,
119         // contents);
120         // if (sibling != null) {
121         // op.createBefore(sibling);
122         // }
123         // runOperation(op, monitor);
124         // return (IInitializer) op.getResultElements()[0];
125         // }
126         /**
127          * @see IType
128          */
129         // public IMethod createMethod(String contents, IJavaElement sibling,
130         // boolean force, IProgressMonitor monitor) throws
131         // JavaModelException {
132         // CreateMethodOperation op = new CreateMethodOperation(this, contents,
133         // force);
134         // if (sibling != null) {
135         // op.createBefore(sibling);
136         // }
137         // runOperation(op, monitor);
138         // return (IMethod) op.getResultElements()[0];
139         // }
140         /**
141          * @see IType
142          */
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);
149         // }
150         // runOperation(op, monitor);
151         // return (IType) op.getResultElements()[0];
152         // }
153         /**
154          * @see JavaElement#equalsDOMNode
155          */
156         protected boolean equalsDOMNode(IDOMNode node) throws JavaModelException {
157                 return (node.getNodeType() == IDOMNode.TYPE)
158                                 && super.equalsDOMNode(node);
159         }
160
161         /*
162          * @see IType
163          */
164         public IMethod[] findMethods(IMethod method) {
165                 try {
166                         return this.findMethods(method, this.getMethods());
167                 } catch (JavaModelException e) {
168                         // if type doesn't exist, no matching method can exist
169                         return null;
170                 }
171         }
172
173         /**
174          * @see IMember
175          */
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();
183                         } else {
184                                 return null;
185                         }
186                 }
187                 return null;
188         }
189
190         /**
191          * @see IJavaElement
192          */
193         public int getElementType() {
194                 return TYPE;
195         }
196
197         /**
198          * @see IType#getField
199          */
200         public IField getField(String name) {
201                 return new SourceField(this, name);
202         }
203
204         /**
205          * @see IType
206          */
207         public IField[] getFields() throws JavaModelException {
208                 ArrayList list = getChildrenOfType(FIELD);
209                 IField[] array = new IField[list.size()];
210                 list.toArray(array);
211                 return array;
212         }
213
214         /**
215          * @see IType#getFullyQualifiedName
216          */
217         public String getFullyQualifiedName() {
218                 return this.getFullyQualifiedName('$');
219         }
220
221         /**
222          * @see IType#getFullyQualifiedName(char)
223          */
224         public String getFullyQualifiedName(char enclosingTypeSeparator) {
225                 String packageName = getPackageFragment().getElementName();
226                 if (packageName.equals(IPackageFragment.DEFAULT_PACKAGE_NAME)) {
227                         return getTypeQualifiedName(enclosingTypeSeparator);
228                 }
229                 return packageName + '.' + getTypeQualifiedName(enclosingTypeSeparator);
230         }
231
232         /**
233          * @see IType
234          */
235         // public IInitializer getInitializer(int occurrenceCount) {
236         // return new Initializer(this, occurrenceCount);
237         // }
238         /**
239          * @see IType
240          */
241         // public IInitializer[] getInitializers() throws JavaModelException {
242         // ArrayList list = getChildrenOfType(INITIALIZER);
243         // IInitializer[] array= new IInitializer[list.size()];
244         // list.toArray(array);
245         // return array;
246         // }
247         /**
248          * @see IType#getMethod
249          */
250         public IMethod getMethod(String name, String[] parameterTypeSignatures) {
251                 return new SourceMethod(this, name, parameterTypeSignatures);
252         }
253
254         /**
255          * @see IType
256          */
257         public IMethod[] getMethods() throws JavaModelException {
258                 ArrayList list = getChildrenOfType(METHOD);
259                 IMethod[] array = new IMethod[list.size()];
260                 list.toArray(array);
261                 return array;
262         }
263
264         /**
265          * @see IType
266          */
267         public IPackageFragment getPackageFragment() {
268                 IJavaElement parentElement = this.parent;
269                 while (parentElement != null) {
270                         if (parentElement.getElementType() == IJavaElement.PACKAGE_FRAGMENT) {
271                                 return (IPackageFragment) parentElement;
272                         } else {
273                                 parentElement = parentElement.getParent();
274                         }
275                 }
276                 Assert.isTrue(false); // should not happen
277                 return null;
278         }
279
280         /**
281          * @see IType
282          */
283         public String getSuperclassName() throws JavaModelException {
284                 SourceTypeElementInfo info = (SourceTypeElementInfo) getElementInfo();
285                 char[] superclassName = info.getSuperclassName();
286                 if (superclassName == null) {
287                         return null;
288                 }
289                 return new String(superclassName);
290         }
291
292         /**
293          * @see IType
294          */
295         public String[] getSuperInterfaceNames() throws JavaModelException {
296                 SourceTypeElementInfo info = (SourceTypeElementInfo) getElementInfo();
297                 char[][] names = info.getInterfaceNames();
298                 if (names == null) {
299                         return fgEmptyList;
300                 }
301                 String[] strings = new String[names.length];
302                 for (int i = 0; i < names.length; i++) {
303                         strings[i] = new String(names[i]);
304                 }
305                 return strings;
306         }
307
308         /**
309          * @see IType
310          */
311         public IType getType(String name) {
312                 return new SourceType(this, name);
313         }
314
315         /**
316          * @see IType#getTypeQualifiedName
317          */
318         public String getTypeQualifiedName() {
319                 return this.getTypeQualifiedName('$');
320         }
321
322         /**
323          * @see IType#getTypeQualifiedName(char)
324          */
325         public String getTypeQualifiedName(char enclosingTypeSeparator) {
326                 if (parent.getElementType() == IJavaElement.COMPILATION_UNIT) {
327                         return name;
328                 } else {
329                         return ((IType) parent)
330                                         .getTypeQualifiedName(enclosingTypeSeparator)
331                                         + enclosingTypeSeparator + name;
332                 }
333         }
334
335         /**
336          * @see IType
337          */
338         public IType[] getTypes() throws JavaModelException {
339                 ArrayList list = getChildrenOfType(TYPE);
340                 IType[] array = new IType[list.size()];
341                 list.toArray(array);
342                 return array;
343         }
344
345         /**
346          * @see IParent
347          */
348         public boolean hasChildren() throws JavaModelException {
349                 return getChildren().length > 0;
350         }
351
352         /**
353          * @see IType#isAnonymous()
354          */
355         public boolean isAnonymous() throws JavaModelException {
356                 return false; // cannot create source handle onto anonymous types
357         }
358
359         /**
360          * @see IType
361          */
362         public boolean isClass() throws JavaModelException {
363                 return !isInterface();
364         }
365
366         /**
367          * @see IType
368          */
369         public boolean isInterface() throws JavaModelException {
370                 Object obj = getElementInfo();
371                 if (obj instanceof SourceTypeElementInfo) {
372                         SourceTypeElementInfo info = (SourceTypeElementInfo) getElementInfo();
373                         return info.isInterface();
374                 }
375                 return false;
376         }
377
378         /**
379          * @see IType#isLocal()
380          */
381         public boolean isLocal() throws JavaModelException {
382                 return false; // cannot create source handle onto local types
383         }
384
385         /**
386          * @see IType#isMember()
387          */
388         public boolean isMember() throws JavaModelException {
389                 return getDeclaringType() != null;
390         }
391
392         /**
393          * @see IType
394          */
395         // public ITypeHierarchy loadTypeHierachy(InputStream input,
396         // IProgressMonitor monitor) throws JavaModelException {
397         // return loadTypeHierachy(input, DefaultWorkingCopyOwner.PRIMARY, monitor);
398         // }
399         /**
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
404          * be specified:
405          * <p>
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
410          * compilation unit.
411          * 
412          * Only hierarchies originally created by the following methods can be
413          * loaded:
414          * <ul>
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>
422          * </u>
423          * 
424          * @param input
425          *            stream where hierarchy will be read
426          * @param monitor
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
433          *                reading, ...)
434          * @see ITypeHierarchy#store(java.io.OutputStream, IProgressMonitor)
435          * @since 3.0
436          */
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);
442         // }
443         /**
444          * @see IType
445          */
446         // public ITypeHierarchy newSupertypeHierarchy(IProgressMonitor monitor)
447         // throws JavaModelException {
448         // return this.newSupertypeHierarchy(DefaultWorkingCopyOwner.PRIMARY,
449         // monitor);
450         // }
451         /*
452          * @see IType#newSupertypeHierarchy(ICompilationUnit[], IProgressMonitor)
453          */
454         // public ITypeHierarchy newSupertypeHierarchy(
455         // ICompilationUnit[] workingCopies,
456         // IProgressMonitor monitor)
457         // throws JavaModelException {
458         //
459         // CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation(this,
460         // workingCopies, SearchEngine.createWorkspaceScope(), false);
461         // op.runOperation(monitor);
462         // return op.getResult();
463         // }
464         /**
465          * @param workingCopies
466          *            the working copies that take precedence over their original
467          *            compilation units
468          * @param monitor
469          *            the given progress monitor
470          * @return a type hierarchy for this type containing this type and all of
471          *         its supertypes
472          * @exception JavaModelException
473          *                if this element does not exist or if an exception occurs
474          *                while accessing its corresponding resource.
475          * 
476          * @see IType#newSupertypeHierarchy(IWorkingCopy[], IProgressMonitor)
477          * @deprecated
478          */
479         public ITypeHierarchy newSupertypeHierarchy(IWorkingCopy[] workingCopies,
480                         IProgressMonitor monitor) throws JavaModelException {
481
482                 ICompilationUnit[] copies;
483                 if (workingCopies == null) {
484                         copies = null;
485                 } else {
486                         int length = workingCopies.length;
487                         System.arraycopy(workingCopies, 0,
488                                         copies = new ICompilationUnit[length], 0, length);
489                 }
490                 return newSupertypeHierarchy(copies, monitor);
491         }
492
493         /**
494          * @see IType#newSupertypeHierarchy(WorkingCopyOwner, IProgressMonitor)
495          */
496         // public ITypeHierarchy newSupertypeHierarchy(
497         // WorkingCopyOwner owner,
498         // IProgressMonitor monitor)
499         // throws JavaModelException {
500         //
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();
508         // }
509         /**
510          * @see IType
511          */
512         // public ITypeHierarchy newTypeHierarchy(IJavaProject project,
513         // IProgressMonitor monitor) throws JavaModelException {
514         // return newTypeHierarchy(project, DefaultWorkingCopyOwner.PRIMARY,
515         // monitor);
516         // }
517         /**
518          * @see IType#newTypeHierarchy(IJavaProject, WorkingCopyOwner,
519          *      IProgressMonitor)
520          */
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"));
526         // //$NON-NLS-1$
527         // }
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];
535         // int index = 0;
536         // for (int i = 0; i < length; i++) {
537         // ICompilationUnit wc = workingCopies[i];
538         // if (project.equals(wc.getJavaProject())) {
539         // projectWCs[index++] = wc;
540         // }
541         // }
542         // if (index != length) {
543         // System.arraycopy(projectWCs, 0, projectWCs = new ICompilationUnit[index],
544         // 0, index);
545         // }
546         // }
547         // CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation(
548         // this,
549         // projectWCs,
550         // project,
551         // true);
552         // op.runOperation(monitor);
553         // return op.getResult();
554         // }
555         /**
556          * @see IType
557          */
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();
564         // }
565         /*
566          * @see IType#newTypeHierarchy(ICompilationUnit[], IProgressMonitor)
567          */
568         // public ITypeHierarchy newTypeHierarchy(
569         // ICompilationUnit[] workingCopies,
570         // IProgressMonitor monitor)
571         // throws JavaModelException {
572         //              
573         // CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation(this,
574         // workingCopies, SearchEngine.createWorkspaceScope(), true);
575         // op.runOperation(monitor);
576         // return op.getResult();
577         // }
578         /**
579          * @see IType#newTypeHierarchy(IWorkingCopy[], IProgressMonitor)
580          * @deprecated
581          */
582         public ITypeHierarchy newTypeHierarchy(IWorkingCopy[] workingCopies,
583                         IProgressMonitor monitor) throws JavaModelException {
584
585                 ICompilationUnit[] copies;
586                 if (workingCopies == null) {
587                         copies = null;
588                 } else {
589                         int length = workingCopies.length;
590                         System.arraycopy(workingCopies, 0,
591                                         copies = new ICompilationUnit[length], 0, length);
592                 }
593                 return newTypeHierarchy(copies, monitor);
594         }
595
596         /**
597          * @see IType#newTypeHierarchy(WorkingCopyOwner, IProgressMonitor)
598          */
599         // public ITypeHierarchy newTypeHierarchy(
600         // WorkingCopyOwner owner,
601         // IProgressMonitor monitor)
602         // throws JavaModelException {
603         //              
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();
611         // }
612         // public String[][] resolveType(String typeName) throws JavaModelException
613         // {
614         // ISourceType info = (ISourceType) this.getElementInfo();
615         // ISearchableNameEnvironment environment =
616         // ((JavaProject)getJavaProject()).getSearchableNameEnvironment();
617         //
618         // class TypeResolveRequestor implements ISelectionRequestor {
619         // String[][] answers = null;
620         // void acceptType(String[] answer){
621         // if (answers == null) {
622         // answers = new String[][]{ answer };
623         // } else {
624         // // grow
625         // int length = answers.length;
626         // System.arraycopy(answers, 0, answers = new String[length+1][], 0,
627         // length);
628         // answers[length] = answer;
629         // }
630         // }
631         // public void acceptClass(char[] packageName, char[] className, boolean
632         // needQualification) {
633         // acceptType(new String[] { new String(packageName), new String(className)
634         // });
635         // }
636         //              
637         // public void acceptInterface(char[] packageName, char[] interfaceName,
638         // boolean needQualification) {
639         // acceptType(new String[] { new String(packageName), new
640         // String(interfaceName) });
641         // }
642         //
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
649         // isConstructor) {}
650         // public void acceptPackage(char[] packageName){}
651         //
652         // }
653         // TypeResolveRequestor requestor = new TypeResolveRequestor();
654         // SelectionEngine engine =
655         // new SelectionEngine(environment, requestor,
656         // this.getJavaProject().getOptions(true));
657         //              
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();
664         // }
665         //              
666         // engine.selectType(info, typeName.toCharArray(), topLevelInfos, false);
667         // return requestor.answers;
668         // }
669         /**
670          * @private Debugging purposes
671          */
672         protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
673                 buffer.append(this.tabString(tab));
674                 if (info == null) {
675                         buffer.append(this.getElementName());
676                         buffer.append(" (not open)"); //$NON-NLS-1$
677                 } else if (info == NO_INFO) {
678                         buffer.append(getElementName());
679                 } else {
680                         try {
681                                 if (this.isInterface()) {
682                                         buffer.append("interface "); //$NON-NLS-1$
683                                 } else {
684                                         buffer.append("class "); //$NON-NLS-1$
685                                 }
686                                 buffer.append(this.getElementName());
687                         } catch (JavaModelException e) {
688                                 buffer
689                                                 .append("<JavaModelException in toString of " + getElementName()); //$NON-NLS-1$
690                         }
691                 }
692         }
693 }