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;
14 import java.util.HashMap;
17 import net.sourceforge.phpdt.core.IBuffer;
18 import net.sourceforge.phpdt.core.IBufferFactory;
19 import net.sourceforge.phpdt.core.ICompilationUnit;
20 import net.sourceforge.phpdt.core.IImportDeclaration;
21 import net.sourceforge.phpdt.core.IJavaElement;
22 import net.sourceforge.phpdt.core.IJavaModelStatusConstants;
23 import net.sourceforge.phpdt.core.IJavaProject;
24 import net.sourceforge.phpdt.core.IMember;
25 import net.sourceforge.phpdt.core.IMethod;
26 import net.sourceforge.phpdt.core.IOpenable;
27 import net.sourceforge.phpdt.core.IPackageDeclaration;
28 import net.sourceforge.phpdt.core.IPackageFragmentRoot;
29 import net.sourceforge.phpdt.core.IParent;
30 import net.sourceforge.phpdt.core.IProblemRequestor;
31 import net.sourceforge.phpdt.core.ISourceManipulation;
32 import net.sourceforge.phpdt.core.ISourceRange;
33 import net.sourceforge.phpdt.core.ISourceReference;
34 import net.sourceforge.phpdt.core.IType;
35 import net.sourceforge.phpdt.core.IWorkingCopy;
36 import net.sourceforge.phpdt.core.JavaModelException;
37 import net.sourceforge.phpdt.core.Signature;
38 import net.sourceforge.phpdt.core.WorkingCopyOwner;
39 import net.sourceforge.phpdt.core.compiler.CharOperation;
40 import net.sourceforge.phpdt.core.jdom.IDOMNode;
41 import net.sourceforge.phpdt.internal.compiler.IProblemFactory;
42 import net.sourceforge.phpdt.internal.compiler.SourceElementParser;
43 import net.sourceforge.phpdt.internal.compiler.impl.CompilerOptions;
44 import net.sourceforge.phpdt.internal.compiler.problem.DefaultProblemFactory;
45 import net.sourceforge.phpdt.internal.core.util.Util;
46 import net.sourceforge.phpeclipse.internal.compiler.ast.CompilationUnitDeclaration;
48 import org.eclipse.core.resources.IContainer;
49 import org.eclipse.core.resources.IFile;
50 import org.eclipse.core.resources.IMarker;
51 import org.eclipse.core.resources.IResource;
52 import org.eclipse.core.runtime.IPath;
53 import org.eclipse.core.runtime.IProgressMonitor;
54 import org.eclipse.core.runtime.Path;
57 * @see ICompilationUnit
60 public class CompilationUnit extends Openable implements ICompilationUnit,
61 net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit {
62 public WorkingCopyOwner owner;
65 * Constructs a handle to a compilation unit with the given name in the specified package for the specified owner
67 * @exception IllegalArgumentException
68 * if the name of the compilation unit does not end with ".java"
70 protected CompilationUnit(PackageFragment parent, String name, WorkingCopyOwner owner) {
76 * Accepts the given visitor onto the parsed tree of this compilation unit, after having runned the name resolution. The visitor's
77 * corresponding <code>visit</code> method is called with the corresponding parse tree. If the visitor returns <code>true</code>,
78 * this method visits this parse node's members.
82 * @exception JavaModelException
83 * if this method fails. Reasons include:
85 * <li>This element does not exist.</li>
86 * <li>The visitor failed with this exception.</li>
89 //public void accept(IAbstractSyntaxTreeVisitor visitor) throws JavaModelException {
90 // CompilationUnitVisitor.visit(this, visitor);
93 * @see ICompilationUnit#becomeWorkingCopy(IProblemRequestor, IProgressMonitor)
95 public void becomeWorkingCopy(IProblemRequestor problemRequestor, IProgressMonitor monitor) throws JavaModelException {
96 JavaModelManager manager = JavaModelManager.getJavaModelManager();
97 JavaModelManager.PerWorkingCopyInfo perWorkingCopyInfo = manager.getPerWorkingCopyInfo(this, false/* don't create */,
98 true /* record usage */, null/* no problem requestor needed */);
99 if (perWorkingCopyInfo == null) {
100 // close cu and its children
103 BecomeWorkingCopyOperation operation = new BecomeWorkingCopyOperation(this, problemRequestor);
104 operation.runOperation(monitor);
108 //protected void buildStructure(OpenableElementInfo info, IProgressMonitor monitor) throws JavaModelException {
110 // if (monitor != null && monitor.isCanceled()) return;
112 // // remove existing (old) infos
115 // HashMap newElements = new HashMap(11);
116 // info.setIsStructureKnown(generateInfos(info, monitor, newElements, getResource()));
117 // JavaModelManager.getJavaModelManager().getElementsOutOfSynchWithBuffers().remove(this);
118 // for (Iterator iter = newElements.keySet().iterator(); iter.hasNext();) {
119 // IJavaElement key = (IJavaElement) iter.next();
120 // Object value = newElements.get(key);
121 // JavaModelManager.getJavaModelManager().putInfo(key, value);
123 // // add the info for this at the end, to ensure that a getInfo cannot reply null in case the LRU cache needs
124 // // to be flushed. Might lead to performance issues.
125 // // see PR 1G2K5S7: ITPJCORE:ALL - NPE when accessing source for a binary type
126 // JavaModelManager.getJavaModelManager().putInfo(this, info);
128 protected boolean buildStructure(OpenableElementInfo info, final IProgressMonitor pm, Map newElements,
129 IResource underlyingResource) throws JavaModelException {
131 // check if this compilation unit can be opened
132 if (!isWorkingCopy()) { // no check is done on root kind or exclusion pattern for working copies
133 if ( // ((IPackageFragment)getParent()).getKind() == IPackageFragmentRoot.K_BINARY||
134 !isValidCompilationUnit() || !underlyingResource.isAccessible()) {
135 throw newNotPresentException();
139 // prevents reopening of non-primary working copies (they are closed when they are discarded and should not be reopened)
140 if (!isPrimary() && getPerWorkingCopyInfo() == null) {
141 throw newNotPresentException();
144 CompilationUnitElementInfo unitInfo = (CompilationUnitElementInfo) info;
146 // get buffer contents
147 IBuffer buffer = getBufferManager().getBuffer(CompilationUnit.this);
148 if (buffer == null) {
149 buffer = openBuffer(pm, unitInfo); // open buffer independently from the info, since we are building the info
151 final char[] contents = buffer == null ? null : buffer.getCharacters();
153 // generate structure and compute syntax problems if needed
154 CompilationUnitStructureRequestor requestor = new CompilationUnitStructureRequestor(this, unitInfo, newElements);
155 JavaModelManager.PerWorkingCopyInfo perWorkingCopyInfo = getPerWorkingCopyInfo();
156 IJavaProject project = getJavaProject();
157 boolean computeProblems = JavaProject.hasJavaNature(project.getProject()) && perWorkingCopyInfo != null
158 && perWorkingCopyInfo.isActive();
159 IProblemFactory problemFactory = new DefaultProblemFactory();
160 Map options = project.getOptions(true);
162 if (underlyingResource == null) {
163 underlyingResource = getResource();
166 SourceElementParser parser = new SourceElementParser(requestor, problemFactory,
167 new CompilerOptions(options));
168 //, true/*report local declarations*/);
169 requestor.parser = parser;
170 CompilationUnitDeclaration unit = parser.parseCompilationUnit(
171 new net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit() {
172 public char[] getContents() {
176 public char[] getMainTypeName() {
177 return CompilationUnit.this.getMainTypeName();
180 public char[][] getPackageName() {
181 return CompilationUnit.this.getPackageName();
184 public char[] getFileName() {
185 return CompilationUnit.this.getFileName();
188 public IResource getResource() {
189 return CompilationUnit.this.getResource();
191 }, true /* full parse to find local elements */);
193 // update timestamp (might be IResource.NULL_STAMP if original does not exist)
195 unitInfo.timestamp = ((IFile) underlyingResource).getModificationStamp();
197 // compute other problems if needed
198 CompilationUnitDeclaration compilationUnitDeclaration = null;
200 if (computeProblems) {
201 perWorkingCopyInfo.beginReporting();
202 compilationUnitDeclaration = CompilationUnitProblemFinder.process(unit, this, contents, parser, this.owner,
203 perWorkingCopyInfo, problemFactory, false/* don't cleanup cu */, pm);
204 perWorkingCopyInfo.endReporting();
207 // if (info instanceof ASTHolderCUInfo) {
208 // int astLevel = ((ASTHolderCUInfo) info).astLevel;
209 // org.eclipse.jdt.core.dom.CompilationUnit cu = AST.convertCompilationUnit(astLevel, unit, contents, options, pm);
210 // ((ASTHolderCUInfo) info).ast = cu;
213 if (compilationUnitDeclaration != null) {
214 compilationUnitDeclaration.cleanUp();
218 return unitInfo.isStructureKnown();
222 // * @see ICodeAssist#codeComplete(int, ICompletionRequestor)
224 //public void codeComplete(int offset, ICompletionRequestor requestor) throws JavaModelException {
225 // codeComplete(this, isWorkingCopy() ? (org.eclipse.jdt.internal.compiler.env.ICompilationUnit) getOriginalElement() : this,
226 // offset, requestor);
229 * @see ICodeAssist#codeSelect(int, int)
231 //public IJavaElement[] codeSelect(int offset, int length) throws JavaModelException {
232 // return super.codeSelect(this, offset, length);
235 * @see IWorkingCopy#commit(boolean, IProgressMonitor)
237 public void commit(boolean force, IProgressMonitor monitor) throws JavaModelException {
238 commitWorkingCopy(force, monitor);
239 // throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, this));
243 * @see ICompilationUnit#commitWorkingCopy(boolean, IProgressMonitor)
245 public void commitWorkingCopy(boolean force, IProgressMonitor monitor) throws JavaModelException {
246 CommitWorkingCopyOperation op = new CommitWorkingCopyOperation(this, force);
247 op.runOperation(monitor);
251 * @see ISourceManipulation#copy(IJavaElement, IJavaElement, String, boolean, IProgressMonitor)
253 public void copy(IJavaElement container, IJavaElement sibling, String rename, boolean force, IProgressMonitor monitor)
254 throws JavaModelException {
255 if (container == null) {
256 throw new IllegalArgumentException(Util.bind("operation.nullContainer")); //$NON-NLS-1$
258 IJavaElement[] elements = new IJavaElement[] { this };
259 IJavaElement[] containers = new IJavaElement[] { container };
260 String[] renamings = null;
261 if (rename != null) {
262 renamings = new String[] { rename };
264 getJavaModel().copy(elements, containers, null, renamings, force, monitor);
268 * Returns a new element info for this element.
270 protected Object createElementInfo() {
271 return new CompilationUnitElementInfo();
275 // * @see ICompilationUnit#createImport(String, IJavaElement, IProgressMonitor)
277 //public IImportDeclaration createImport(String name, IJavaElement sibling, IProgressMonitor monitor) throws JavaModelException {
278 // CreateImportOperation op = new CreateImportOperation(name, this);
279 // if (sibling != null) {
280 // op.createBefore(sibling);
282 // runOperation(op, monitor);
283 // return getImport(name);
286 * @see ICompilationUnit#createPackageDeclaration(String, IProgressMonitor)
288 public IPackageDeclaration createPackageDeclaration(String name, IProgressMonitor monitor) throws JavaModelException {
290 CreatePackageDeclarationOperation op = new CreatePackageDeclarationOperation(name, this);
291 runOperation(op, monitor);
292 return getPackageDeclaration(name);
296 // * @see ICompilationUnit#createType(String, IJavaElement, boolean, IProgressMonitor)
298 //public IType createType(String content, IJavaElement sibling, boolean force, IProgressMonitor monitor) throws
299 // JavaModelException {
301 // //autogenerate this compilation unit
302 // IPackageFragment pkg = (IPackageFragment) getParent();
303 // String source = ""; //$NON-NLS-1$
304 // if (pkg.getElementName().length() > 0) {
305 // //not the default package...add the package declaration
306 // source = "package " + pkg.getElementName() + ";" + org.eclipse.jdt.internal.compiler.util.ProjectPrefUtil.LINE_SEPARATOR +
307 // org.eclipse.jdt.internal.compiler.util.ProjectPrefUtil.LINE_SEPARATOR; //$NON-NLS-1$ //$NON-NLS-2$
309 // CreateCompilationUnitOperation op = new CreateCompilationUnitOperation(pkg, fName, source, force);
310 // runOperation(op, monitor);
312 // CreateTypeOperation op = new CreateTypeOperation(this, content, force);
313 // if (sibling != null) {
314 // op.createBefore(sibling);
316 // runOperation(op, monitor);
317 // return (IType) op.getResultElements()[0];
320 * @see ISourceManipulation#delete(boolean, IProgressMonitor)
322 public void delete(boolean force, IProgressMonitor monitor) throws JavaModelException {
323 IJavaElement[] elements = new IJavaElement[] { this };
324 getJavaModel().delete(elements, force, monitor);
328 * @see IWorkingCopy#destroy()
331 public void destroy() {
333 discardWorkingCopy();
334 } catch (JavaModelException e) {
340 * @see ICompilationUnit#discardWorkingCopy
342 public void discardWorkingCopy() throws JavaModelException {
343 // discard working copy and its children
344 DiscardWorkingCopyOperation op = new DiscardWorkingCopyOperation(this);
345 op.runOperation(null);
349 * Returns true if this handle represents the same Java element as the given handle.
351 * @see Object#equals(java.lang.Object)
353 public boolean equals(Object obj) {
354 if (!(obj instanceof CompilationUnit))
356 CompilationUnit other = (CompilationUnit) obj;
357 return this.owner.equals(other.owner) && super.equals(obj);
361 * @see JavaElement#equalsDOMNode(IDOMNode)
363 protected boolean equalsDOMNode(IDOMNode node) throws JavaModelException {
364 String name = getElementName();
365 if (node.getNodeType() == IDOMNode.COMPILATION_UNIT && name != null) {
366 String nodeName = node.getName();
367 if (nodeName == null)
369 if (name.equals(nodeName)) {
372 // iterate through all the types inside the receiver and see if one of them can fit
373 IType[] types = getTypes();
374 String typeNodeName = nodeName.substring(0, nodeName.indexOf(".java")); //$NON-NLS-1$
375 for (int i = 0, max = types.length; i < max; i++) {
376 if (types[i].getElementName().equals(typeNodeName)) {
386 * @see IWorkingCopy#findElements(IJavaElement)
388 public IJavaElement[] findElements(IJavaElement element) {
389 ArrayList children = new ArrayList();
390 while (element != null && element.getElementType() != IJavaElement.COMPILATION_UNIT) {
391 children.add(element);
392 element = element.getParent();
396 IJavaElement currentElement = this;
397 for (int i = children.size() - 1; i >= 0; i--) {
398 IJavaElement child = (IJavaElement) children.get(i);
399 switch (child.getElementType()) {
400 // case IJavaElement.PACKAGE_DECLARATION:
401 // currentElement = ((ICompilationUnit)currentElement).getPackageDeclaration(child.getElementName());
403 // case IJavaElement.IMPORT_CONTAINER:
404 // currentElement = ((ICompilationUnit)currentElement).getImportContainer();
406 // case IJavaElement.IMPORT_DECLARATION:
407 // currentElement = ((IImportContainer)currentElement).getImport(child.getElementName());
409 case IJavaElement.TYPE:
410 if (currentElement.getElementType() == IJavaElement.COMPILATION_UNIT) {
411 currentElement = ((ICompilationUnit) currentElement).getType(child.getElementName());
413 currentElement = ((IType) currentElement).getType(child.getElementName());
416 // case IJavaElement.INITIALIZER:
417 // currentElement = ((IType)currentElement).getInitializer(((JavaElement)child).getOccurrenceCount());
419 case IJavaElement.FIELD:
420 currentElement = ((IType) currentElement).getField(child.getElementName());
422 case IJavaElement.METHOD:
423 return ((IType) currentElement).findMethods((IMethod) child);
427 if (currentElement != null && currentElement.exists()) {
428 return new IJavaElement[] { currentElement };
435 * @see IWorkingCopy#findPrimaryType()
437 public IType findPrimaryType() {
438 String typeName = Signature.getQualifier(this.getElementName());
439 IType primaryType = this.getType(typeName);
440 if (primaryType.exists()) {
447 * @see IWorkingCopy#findSharedWorkingCopy(IBufferFactory)
450 public IJavaElement findSharedWorkingCopy(IBufferFactory factory) {
452 // if factory is null, default factory must be used
454 factory = this.getBufferManager().getDefaultBufferFactory();
456 return findWorkingCopy(BufferFactoryWrapper.create(factory));
460 * @see ICompilationUnit#findWorkingCopy(WorkingCopyOwner)
462 public ICompilationUnit findWorkingCopy(WorkingCopyOwner workingCopyOwner) {
463 CompilationUnit cu = new CompilationUnit((PackageFragment) this.parent, getElementName(), workingCopyOwner);
464 if (workingCopyOwner == DefaultWorkingCopyOwner.PRIMARY) {
467 // must be a working copy
468 JavaModelManager.PerWorkingCopyInfo perWorkingCopyInfo = cu.getPerWorkingCopyInfo();
469 if (perWorkingCopyInfo != null) {
470 return perWorkingCopyInfo.getWorkingCopy();
477 //protected boolean generateInfos(OpenableElementInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource)
478 // throws JavaModelException {
480 //// if (getParent() instanceof JarPackageFragment) {
481 //// // ignore .java files in jar
482 //// throw newNotPresentException();
484 // // put the info now, because getting the contents requires it
485 // JavaModelManager.getJavaModelManager().putInfo(this, info);
486 // CompilationUnitElementInfo unitInfo = (CompilationUnitElementInfo) info;
488 // // generate structure
489 // CompilationUnitStructureRequestor requestor = new CompilationUnitStructureRequestor(this, unitInfo, newElements);
490 // IProblemFactory factory = new DefaultProblemFactory();
491 // SourceElementParser parser = new SourceElementParser(requestor, factory, new
492 // CompilerOptions(getJavaProject().getOptions(true)));
493 //// SourceElementParser parser = new SourceElementParser(requestor, factory);
494 // requestor.parser = parser;
495 // parser.parseCompilationUnit(this, false);
496 // if (isWorkingCopy()) {
497 // CompilationUnit original = (CompilationUnit) getOriginalElement();
498 // // might be IResource.NULL_STAMP if original does not exist
499 // unitInfo.timestamp = ((IFile) original.getResource()).getModificationStamp();
501 // return unitInfo.isStructureKnown();
505 * @see ICompilationUnit#getAllTypes()
507 public IType[] getAllTypes() throws JavaModelException {
508 IJavaElement[] types = getTypes();
510 ArrayList allTypes = new ArrayList(types.length);
511 ArrayList typesToTraverse = new ArrayList(types.length);
512 for (i = 0; i < types.length; i++) {
513 typesToTraverse.add(types[i]);
515 while (!typesToTraverse.isEmpty()) {
516 IType type = (IType) typesToTraverse.get(0);
517 typesToTraverse.remove(type);
519 types = type.getTypes();
520 for (i = 0; i < types.length; i++) {
521 typesToTraverse.add(types[i]);
524 IType[] arrayOfAllTypes = new IType[allTypes.size()];
525 allTypes.toArray(arrayOfAllTypes);
526 return arrayOfAllTypes;
530 * @see IMember#getCompilationUnit()
532 public ICompilationUnit getCompilationUnit() {
537 * @see org.eclipse.jdt.internal.compiler.env.ICompilationUnit#getContents()
539 public char[] getContents() {
541 IBuffer buffer = this.getBuffer();
542 return buffer == null ? null : buffer.getCharacters();
543 } catch (JavaModelException e) {
544 return CharOperation.NO_CHAR;
549 * A compilation unit has a corresponding resource unless it is contained in a jar.
551 * @see IJavaElement#getCorrespondingResource()
553 public IResource getCorrespondingResource() throws JavaModelException {
554 IPackageFragmentRoot root = (IPackageFragmentRoot) getParent().getParent();
555 if (root.isArchive()) {
558 return getUnderlyingResource();
563 * @see ICompilationUnit#getElementAt(int)
565 public IJavaElement getElementAt(int position) throws JavaModelException {
567 IJavaElement e = getSourceElementAt(position);
578 public int getElementType() {
579 return COMPILATION_UNIT;
582 public char[] getFileName() {
583 return getElementName().toCharArray();
587 * @see JavaElement#getHandleMementoDelimiter()
589 protected char getHandleMementoDelimiter() {
590 return JavaElement.JEM_COMPILATIONUNIT;
594 * @see ICompilationUnit#getImport(String)
596 public IImportDeclaration getImport(String importName) {
597 return new ImportDeclaration((ImportContainer) getImportContainer(), importName);
601 * @see ICompilationUnit#getImportContainer()
603 public ImportContainer getImportContainer() {
604 return new ImportContainer(this);
608 * @see ICompilationUnit#getImports()
610 //public IImportDeclaration[] getImports() throws JavaModelException {
611 // IImportContainer container= getImportContainer();
612 // if (container.exists()) {
613 // IJavaElement[] elements= container.getChildren();
614 // IImportDeclaration[] imprts= new IImportDeclaration[elements.length];
615 // System.arraycopy(elements, 0, imprts, 0, elements.length);
617 // } else if (!exists()) {
618 // throw newNotPresentException();
620 // return new IImportDeclaration[0];
625 * @see org.eclipse.jdt.internal.compiler.env.ICompilationUnit#getMainTypeName()
627 public char[] getMainTypeName() {
628 String name = getElementName();
630 name = name.substring(0, name.length() - 5);
631 return name.toCharArray();
635 * @see IWorkingCopy#getOriginal(IJavaElement)
638 public IJavaElement getOriginal(IJavaElement workingCopyElement) {
639 // backward compatibility
640 if (!isWorkingCopy())
642 CompilationUnit cu = (CompilationUnit) workingCopyElement.getAncestor(COMPILATION_UNIT);
643 if (cu == null || !this.owner.equals(cu.owner)) {
647 return workingCopyElement.getPrimaryElement();
651 * @see IWorkingCopy#getOriginalElement()
654 public IJavaElement getOriginalElement() {
655 // backward compatibility
656 if (!isWorkingCopy())
659 return getPrimaryElement();
663 * @see ICompilationUnit#getOwner()
665 public WorkingCopyOwner getOwner() {
666 return isPrimary() || !isWorkingCopy() ? null : this.owner;
670 * @see ICompilationUnit#getPackageDeclaration(String)
672 public IPackageDeclaration getPackageDeclaration(String name) {
673 return new PackageDeclaration(this, name);
677 * @see ICompilationUnit#getPackageDeclarations()
679 public IPackageDeclaration[] getPackageDeclarations() throws JavaModelException {
680 ArrayList list = getChildrenOfType(PACKAGE_DECLARATION);
681 IPackageDeclaration[] array = new IPackageDeclaration[list.size()];
687 * @see org.eclipse.jdt.internal.compiler.env.ICompilationUnit#getPackageName()
689 public char[][] getPackageName() {
694 * @see IJavaElement#getPath()
696 public IPath getPath() {
697 PackageFragmentRoot root = this.getPackageFragmentRoot();
698 if (root.isArchive()) {
699 return root.getPath();
701 return this.getParent().getPath().append(this.getElementName());
706 * Returns the per working copy info for the receiver, or null if none exist. Note: the use count of the per working copy info is
709 public JavaModelManager.PerWorkingCopyInfo getPerWorkingCopyInfo() {
710 return JavaModelManager.getJavaModelManager().getPerWorkingCopyInfo(this, false/* don't create */, false/* don't record usage */,
711 null/* no problem requestor needed */);
715 * @see ICompilationUnit#getPrimary()
717 public ICompilationUnit getPrimary() {
718 return (ICompilationUnit) getPrimaryElement(true);
722 * @see JavaElement#getPrimaryElement(boolean)
724 public IJavaElement getPrimaryElement(boolean checkOwner) {
725 if (checkOwner && isPrimary())
727 return new CompilationUnit((PackageFragment) getParent(), getElementName(), DefaultWorkingCopyOwner.PRIMARY);
731 * @see IJavaElement#getResource()
733 public IResource getResource() {
734 PackageFragmentRoot root = this.getPackageFragmentRoot();
735 if (root.isArchive()) {
736 return root.getResource();
738 return ((IContainer) this.getParent().getResource()).getFile(new Path(this.getElementName()));
743 * @see ISourceReference#getSource()
745 public String getSource() throws JavaModelException {
746 IBuffer buffer = getBuffer();
748 return ""; //$NON-NLS-1$
749 return buffer.getContents();
753 * @see ISourceReference#getSourceRange()
755 public ISourceRange getSourceRange() throws JavaModelException {
756 return ((CompilationUnitElementInfo) getElementInfo()).getSourceRange();
760 * @see ICompilationUnit#getType(String)
762 public IType getType(String name) {
763 return new SourceType(this, name);
767 * @see ICompilationUnit#getTypes()
769 public IType[] getTypes() throws JavaModelException {
770 ArrayList list = getChildrenOfType(TYPE);
771 IType[] array = new IType[list.size()];
779 public IResource getUnderlyingResource() throws JavaModelException {
780 if (isWorkingCopy() && !isPrimary())
782 return super.getUnderlyingResource();
786 // * @see IWorkingCopy#getSharedWorkingCopy(IProgressMonitor, IBufferFactory, IProblemRequestor)
788 //public IJavaElement getSharedWorkingCopy(IProgressMonitor pm, IBufferFactory factory, IProblemRequestor problemRequestor)
789 // throws JavaModelException {
791 // // if factory is null, default factory must be used
792 // if (factory == null) factory = this.getBufferManager().getDefaultBufferFactory();
794 // JavaModelManager manager = JavaModelManager.getJavaModelManager();
796 // // In order to be shared, working copies have to denote the same compilation unit
797 // // AND use the same buffer factory.
798 // // Assuming there is a little set of buffer factories, then use a 2 level Map cache.
799 // Map sharedWorkingCopies = manager.sharedWorkingCopies;
801 // Map perFactoryWorkingCopies = (Map) sharedWorkingCopies.get(factory);
802 // if (perFactoryWorkingCopies == null){
803 // perFactoryWorkingCopies = new HashMap();
804 // sharedWorkingCopies.put(factory, perFactoryWorkingCopies);
806 // WorkingCopy workingCopy = (WorkingCopy)perFactoryWorkingCopies.get(this);
807 // if (workingCopy != null) {
808 // workingCopy.useCount++;
810 // if (SHARED_WC_VERBOSE) {
811 // System.out.println("Incrementing use count of shared working copy " + workingCopy.toStringWithAncestors()); //$NON-NLS-1$
814 // return workingCopy;
816 // CreateWorkingCopyOperation op = new CreateWorkingCopyOperation(this, perFactoryWorkingCopies, factory, problemRequestor);
817 // runOperation(op, pm);
818 // return op.getResultElements()[0];
822 // * @see IWorkingCopy#getWorkingCopy()
824 //public IJavaElement getWorkingCopy() throws JavaModelException {
825 // return this.getWorkingCopy(null, null, null);
829 // * @see IWorkingCopy#getWorkingCopy(IProgressMonitor, IBufferFactory, IProblemRequestor)
831 //public IJavaElement getWorkingCopy(IProgressMonitor pm, IBufferFactory factory, IProblemRequestor problemRequestor) throws
832 // JavaModelException {
833 // CreateWorkingCopyOperation op = new CreateWorkingCopyOperation(this, null, factory, problemRequestor);
834 // runOperation(op, pm);
835 // return op.getResultElements()[0];
838 * @see IWorkingCopy#getSharedWorkingCopy(IProgressMonitor, IBufferFactory, IProblemRequestor)
841 public IJavaElement getSharedWorkingCopy(IProgressMonitor pm, IBufferFactory factory, IProblemRequestor problemRequestor)
842 throws JavaModelException {
844 // if factory is null, default factory must be used
846 factory = this.getBufferManager().getDefaultBufferFactory();
848 return getWorkingCopy(BufferFactoryWrapper.create(factory), problemRequestor, pm);
852 * @see IWorkingCopy#getWorkingCopy()
855 public IJavaElement getWorkingCopy() throws JavaModelException {
856 return getWorkingCopy(null);
860 * @see ICompilationUnit#getWorkingCopy(IProgressMonitor)
862 public ICompilationUnit getWorkingCopy(IProgressMonitor monitor) throws JavaModelException {
863 return getWorkingCopy(new WorkingCopyOwner() {/* non shared working copy */
864 }, null/* no problem requestor */, monitor);
868 * @see IWorkingCopy#getWorkingCopy(IProgressMonitor, IBufferFactory, IProblemRequestor)
871 public IJavaElement getWorkingCopy(IProgressMonitor monitor, IBufferFactory factory, IProblemRequestor problemRequestor)
872 throws JavaModelException {
873 return getWorkingCopy(BufferFactoryWrapper.create(factory), problemRequestor, monitor);
877 * @see ICompilationUnit#getWorkingCopy(WorkingCopyOwner, IProblemRequestor, IProgressMonitor)
879 public ICompilationUnit getWorkingCopy(WorkingCopyOwner workingCopyOwner, IProblemRequestor problemRequestor,
880 IProgressMonitor monitor) throws JavaModelException {
884 JavaModelManager manager = JavaModelManager.getJavaModelManager();
886 CompilationUnit workingCopy = new CompilationUnit((PackageFragment) getParent(), getElementName(), workingCopyOwner);
887 JavaModelManager.PerWorkingCopyInfo perWorkingCopyInfo = manager.getPerWorkingCopyInfo(workingCopy, false/* don't create */,
888 true/* record usage */, null/* not used since don't create */);
889 if (perWorkingCopyInfo != null) {
890 return perWorkingCopyInfo.getWorkingCopy(); // return existing handle instead of the one created above
892 BecomeWorkingCopyOperation op = new BecomeWorkingCopyOperation(workingCopy, problemRequestor);
893 op.runOperation(monitor);
898 * If I am not open, return true to avoid parsing.
900 * @see IParent#hasChildren()
902 public boolean hasChildren() throws JavaModelException {
904 // return getChildren().length > 0;
912 * @see Openable#hasBuffer()
914 protected boolean hasBuffer() {
919 * @see ICompilationUnit#hasResourceChanged()
921 public boolean hasResourceChanged() {
922 if (!isWorkingCopy())
925 // if resource got deleted, then #getModificationStamp() will answer IResource.NULL_STAMP, which is always different from the
928 Object info = JavaModelManager.getJavaModelManager().getInfo(this);
931 return ((CompilationUnitElementInfo) info).timestamp != getResource().getModificationStamp();
935 * @see IWorkingCopy#isBasedOn(IResource)
938 public boolean isBasedOn(IResource resource) {
939 if (!isWorkingCopy())
941 if (!getResource().equals(resource))
943 return !hasResourceChanged();
947 * @see IOpenable#isConsistent()
949 public boolean isConsistent() {
950 return JavaModelManager.getJavaModelManager().getElementsOutOfSynchWithBuffers().get(this) == null;
957 public boolean isOpen() {
958 Object info = JavaModelManager.getJavaModelManager().getInfo(this);
959 return info != null && ((CompilationUnitElementInfo) info).isOpen();
962 public boolean isPrimary() {
963 return this.owner == DefaultWorkingCopyOwner.PRIMARY;
967 * @see Openable#isSourceElement()
969 protected boolean isSourceElement() {
973 protected boolean isValidCompilationUnit() {
974 IPackageFragmentRoot root = getPackageFragmentRoot();
976 if (root.getKind() != IPackageFragmentRoot.K_SOURCE)
978 } catch (JavaModelException e) {
981 // IResource resource = getResource();
982 // if (resource != null) {
983 // char[][] inclusionPatterns = ((PackageFragmentRoot)root).fullInclusionPatternChars();
984 // char[][] exclusionPatterns = ((PackageFragmentRoot)root).fullExclusionPatternChars();
985 // if (ProjectPrefUtil.isExcluded(resource, inclusionPatterns, exclusionPatterns)) return false;
987 if (!Util.isValidCompilationUnitName(getElementName()))
993 * @see ICompilationUnit#isWorkingCopy()
995 public boolean isWorkingCopy() {
996 // For backward compatibility, non primary working copies are always returning true; in removal
997 // delta, clients can still check that element was a working copy before being discarded.
998 return !isPrimary() || getPerWorkingCopyInfo() != null;
1002 * @see IOpenable#makeConsistent(IProgressMonitor)
1004 public void makeConsistent(IProgressMonitor monitor) throws JavaModelException {
1005 makeConsistent(false/* don't create AST */, 0, monitor);
1008 public Object makeConsistent(boolean createAST, int astLevel, IProgressMonitor monitor) throws JavaModelException {
1012 // create a new info and make it the current info
1013 // (this will remove the info and its children just before storing the new infos)
1015 // ASTHolderCUInfo info = new ASTHolderCUInfo();
1016 // info.astLevel = astLevel;
1017 // openWhenClosed(info, monitor);
1018 // org.eclipse.jdt.core.dom.CompilationUnit result = info.ast;
1022 openWhenClosed(createElementInfo(), monitor);
1027 //public net.sourceforge.phpdt.core.dom.CompilationUnit makeConsistent(boolean createAST, int astLevel, IProgressMonitor monitor)
1028 // throws JavaModelException {
1029 // if (isConsistent()) return null;
1031 // // create a new info and make it the current info
1032 // // (this will remove the info and its children just before storing the new infos)
1034 // ASTHolderCUInfo info = new ASTHolderCUInfo();
1035 // info.astLevel = astLevel;
1036 // openWhenClosed(info, monitor);
1037 // net.sourceforge.phpdt.core.dom.CompilationUnit result = info.ast;
1041 // openWhenClosed(createElementInfo(), monitor);
1047 * @see ISourceManipulation#move(IJavaElement, IJavaElement, String, boolean, IProgressMonitor)
1049 public void move(IJavaElement container, IJavaElement sibling, String rename, boolean force, IProgressMonitor monitor)
1050 throws JavaModelException {
1051 if (container == null) {
1052 throw new IllegalArgumentException(Util.bind("operation.nullContainer")); //$NON-NLS-1$
1054 IJavaElement[] elements = new IJavaElement[] { this };
1055 IJavaElement[] containers = new IJavaElement[] { container };
1057 String[] renamings = null;
1058 if (rename != null) {
1059 renamings = new String[] { rename };
1061 getJavaModel().move(elements, containers, null, renamings, force, monitor);
1065 // * @see Openable#openBuffer(IProgressMonitor)
1067 //protected IBuffer openBuffer(IProgressMonitor pm) throws JavaModelException {
1069 // // create buffer - compilation units only use default buffer factory
1070 // BufferManager bufManager = getBufferManager();
1071 // IBuffer buffer = getBufferFactory().createBuffer(this);
1072 // if (buffer == null) return null;
1074 // // set the buffer source
1075 // if (buffer.getCharacters() == null){
1076 // IFile file = (IFile)this.getResource();
1077 // if (file == null || !file.exists()) throw newNotPresentException();
1078 // buffer.setContents(ProjectPrefUtil.getResourceContentsAsCharArray(file));
1081 // // add buffer to buffer cache
1082 // bufManager.addBuffer(buffer);
1084 // // listen to buffer changes
1085 // buffer.addBufferChangedListener(this);
1090 * @see Openable#openBuffer(IProgressMonitor, Object)
1092 protected IBuffer openBuffer(IProgressMonitor pm, Object info) throws JavaModelException {
1095 boolean isWorkingCopy = isWorkingCopy();
1096 IBuffer buffer = isWorkingCopy ? this.owner.createBuffer(this) : BufferManager.getDefaultBufferManager().createBuffer(this);
1100 // set the buffer source
1101 if (buffer.getCharacters() == null) {
1102 if (isWorkingCopy) {
1103 ICompilationUnit original;
1105 && (original = new CompilationUnit((PackageFragment) getParent(), getElementName(), DefaultWorkingCopyOwner.PRIMARY))
1107 buffer.setContents(original.getSource());
1109 IFile file = (IFile) getResource();
1110 if (file == null || !file.exists()) {
1111 // initialize buffer with empty contents
1112 buffer.setContents(CharOperation.NO_CHAR);
1114 buffer.setContents(Util.getResourceContentsAsCharArray(file));
1118 IFile file = (IFile) this.getResource();
1119 if (file == null || !file.exists())
1120 throw newNotPresentException();
1121 buffer.setContents(Util.getResourceContentsAsCharArray(file));
1125 // add buffer to buffer cache
1126 BufferManager bufManager = getBufferManager();
1127 bufManager.addBuffer(buffer);
1129 // listen to buffer changes
1130 buffer.addBufferChangedListener(this);
1136 * @see Openable#openParent
1138 protected void openParent(Object childInfo, HashMap newElements, IProgressMonitor pm) throws JavaModelException {
1140 super.openParent(childInfo, newElements, pm);
1141 } catch (JavaModelException e) {
1142 // allow parent to not exist for working copies defined outside classpath
1143 if (!isWorkingCopy() && !e.isDoesNotExist()) {
1150 * @see ICompilationUnit#reconcile()
1153 public IMarker[] reconcile() throws JavaModelException {
1154 reconcile(NO_AST, false/* don't force problem detection */, null/* use primary owner */, null/* no progress monitor */);
1159 * @see ICompilationUnit#reconcile(int, boolean, WorkingCopyOwner, IProgressMonitor)
1161 public void reconcile(boolean forceProblemDetection, IProgressMonitor monitor) throws JavaModelException {
1162 reconcile(NO_AST, forceProblemDetection, null/* use primary owner */, monitor);
1166 * @see ICompilationUnit#reconcile(int, boolean, WorkingCopyOwner, IProgressMonitor)
1169 //public org.eclipse.jdt.core.dom.CompilationUnit reconcile(
1170 public Object reconcile(int astLevel, boolean forceProblemDetection, WorkingCopyOwner workingCopyOwner, IProgressMonitor monitor)
1171 throws JavaModelException {
1173 if (!isWorkingCopy())
1174 return null; // Reconciling is not supported on non working copies
1175 if (workingCopyOwner == null)
1176 workingCopyOwner = DefaultWorkingCopyOwner.PRIMARY;
1178 boolean createAST = false;
1179 // if (astLevel == AST.JLS2) {
1180 // // client asking for level 2 AST; these are supported
1181 // createAST = true;
1182 // } else if (astLevel == AST.JLS3) {
1183 // // client asking for level 3 ASTs; these are not supported
1184 // // TODO (jerome) - these should also be supported in 1.5 stream
1185 // createAST = false;
1187 // // client asking for no AST (0) or unknown ast level
1188 // // either way, request denied
1189 // createAST = false;
1191 ReconcileWorkingCopyOperation op = new ReconcileWorkingCopyOperation(this, createAST, astLevel, forceProblemDetection,
1193 op.runOperation(monitor);
1199 * @see ISourceManipulation#rename(String, boolean, IProgressMonitor)
1201 public void rename(String name, boolean force, IProgressMonitor monitor) throws JavaModelException {
1203 throw new IllegalArgumentException(Util.bind("operation.nullName")); //$NON-NLS-1$
1205 IJavaElement[] elements = new IJavaElement[] { this };
1206 IJavaElement[] dests = new IJavaElement[] { this.getParent() };
1207 String[] renamings = new String[] { name };
1208 getJavaModel().rename(elements, dests, renamings, force, monitor);
1212 * @see ICompilationUnit
1214 public void restore() throws JavaModelException {
1216 if (!isWorkingCopy())
1219 CompilationUnit original = (CompilationUnit) getOriginalElement();
1220 IBuffer buffer = this.getBuffer();
1223 buffer.setContents(original.getContents());
1224 updateTimeStamp(original);
1225 makeConsistent(null);
1229 * @see ICodeAssist#codeComplete(int, ICodeCompletionRequestor)
1230 * @deprecated - use codeComplete(int, ICompletionRequestor)
1232 //public void codeComplete(int offset, final ICodeCompletionRequestor requestor) throws JavaModelException {
1234 // if (requestor == null){
1235 // codeComplete(offset, (ICompletionRequestor)null);
1240 // new ICompletionRequestor(){
1241 // public void acceptAnonymousType(char[] superTypePackageName,char[] superTypeName,char[][] parameterPackageNames,char[][]
1242 // parameterTypeNames,char[][] parameterNames,char[] completionName,int modifiers,int completionStart,int completionEnd, int
1245 // public void acceptClass(char[] packageName, char[] className, char[] completionName, int modifiers, int completionStart, int
1246 // completionEnd, int relevance) {
1247 // requestor.acceptClass(packageName, className, completionName, modifiers, completionStart, completionEnd);
1249 // public void acceptError(IProblem error) {
1250 // if (true) return; // was disabled in 1.0
1253 // IMarker marker = ResourcesPlugin.getWorkspace().getRoot().createMarker(IJavaModelMarker.TRANSIENT_PROBLEM);
1254 // marker.setAttribute(IJavaModelMarker.ID, error.getID());
1255 // marker.setAttribute(IMarker.CHAR_START, error.getSourceStart());
1256 // marker.setAttribute(IMarker.CHAR_END, error.getSourceEnd() + 1);
1257 // marker.setAttribute(IMarker.LINE_NUMBER, error.getSourceLineNumber());
1258 // marker.setAttribute(IMarker.MESSAGE, error.getMessage());
1259 // marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
1260 // requestor.acceptError(marker);
1261 // } catch(CoreException e){
1264 // public void acceptField(char[] declaringTypePackageName, char[] declaringTypeName, char[] name, char[] typePackageName, char[]
1265 // typeName, char[] completionName, int modifiers, int completionStart, int completionEnd, int relevance) {
1266 // requestor.acceptField(declaringTypePackageName, declaringTypeName, name, typePackageName, typeName, completionName, modifiers,
1267 // completionStart, completionEnd);
1269 // public void acceptInterface(char[] packageName,char[] interfaceName,char[] completionName,int modifiers,int completionStart,int
1270 // completionEnd, int relevance) {
1271 // requestor.acceptInterface(packageName, interfaceName, completionName, modifiers, completionStart, completionEnd);
1273 // public void acceptKeyword(char[] keywordName,int completionStart,int completionEnd, int relevance){
1274 // requestor.acceptKeyword(keywordName, completionStart, completionEnd);
1276 // public void acceptLabel(char[] labelName,int completionStart,int completionEnd, int relevance){
1277 // requestor.acceptLabel(labelName, completionStart, completionEnd);
1279 // public void acceptLocalVariable(char[] name,char[] typePackageName,char[] typeName,int modifiers,int completionStart,int
1280 // completionEnd, int relevance){
1283 // public void acceptMethod(char[] declaringTypePackageName,char[] declaringTypeName,char[] selector,char[][]
1284 // parameterPackageNames,char[][] parameterTypeNames,char[][] parameterNames,char[] returnTypePackageName,char[]
1285 // returnTypeName,char[] completionName,int modifiers,int completionStart,int completionEnd, int relevance){
1286 // // skip parameter names
1287 // requestor.acceptMethod(declaringTypePackageName, declaringTypeName, selector, parameterPackageNames, parameterTypeNames,
1288 // returnTypePackageName, returnTypeName, completionName, modifiers, completionStart, completionEnd);
1290 // public void acceptMethodDeclaration(char[] declaringTypePackageName,char[] declaringTypeName,char[] selector,char[][]
1291 // parameterPackageNames,char[][] parameterTypeNames,char[][] parameterNames,char[] returnTypePackageName,char[]
1292 // returnTypeName,char[] completionName,int modifiers,int completionStart,int completionEnd, int relevance){
1295 // public void acceptModifier(char[] modifierName,int completionStart,int completionEnd, int relevance){
1296 // requestor.acceptModifier(modifierName, completionStart, completionEnd);
1298 // public void acceptPackage(char[] packageName,char[] completionName,int completionStart,int completionEnd, int relevance){
1299 // requestor.acceptPackage(packageName, completionName, completionStart, completionEnd);
1301 // public void acceptType(char[] packageName,char[] typeName,char[] completionName,int completionStart,int completionEnd, int
1303 // requestor.acceptType(packageName, typeName, completionName, completionStart, completionEnd);
1305 // public void acceptVariableName(char[] typePackageName,char[] typeName,char[] name,char[] completionName,int completionStart,int
1306 // completionEnd, int relevance){
1312 // * @see JavaElement#rootedAt(IJavaProject)
1314 //public IJavaElement rootedAt(IJavaProject project) {
1316 // new CompilationUnit(
1317 // (IPackageFragment)((JavaElement)parent).rootedAt(project),
1321 * Assume that this is a working copy
1323 protected void updateTimeStamp(CompilationUnit original) throws JavaModelException {
1324 long timeStamp = ((IFile) original.getResource()).getModificationStamp();
1325 if (timeStamp == IResource.NULL_STAMP) {
1326 throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INVALID_RESOURCE));
1328 ((CompilationUnitElementInfo) getElementInfo()).timestamp = timeStamp;