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.ICodeAssist;
20 import net.sourceforge.phpdt.core.ICompilationUnit;
21 import net.sourceforge.phpdt.core.IImportContainer;
22 import net.sourceforge.phpdt.core.IImportDeclaration;
23 import net.sourceforge.phpdt.core.IJavaElement;
24 import net.sourceforge.phpdt.core.IJavaModelStatusConstants;
25 import net.sourceforge.phpdt.core.IJavaProject;
26 import net.sourceforge.phpdt.core.IMember;
27 import net.sourceforge.phpdt.core.IMethod;
28 import net.sourceforge.phpdt.core.IOpenable;
29 import net.sourceforge.phpdt.core.IPackageDeclaration;
30 import net.sourceforge.phpdt.core.IPackageFragmentRoot;
31 import net.sourceforge.phpdt.core.IParent;
32 import net.sourceforge.phpdt.core.IProblemRequestor;
33 import net.sourceforge.phpdt.core.ISourceManipulation;
34 import net.sourceforge.phpdt.core.ISourceRange;
35 import net.sourceforge.phpdt.core.ISourceReference;
36 import net.sourceforge.phpdt.core.IType;
37 import net.sourceforge.phpdt.core.IWorkingCopy;
38 import net.sourceforge.phpdt.core.JavaModelException;
39 import net.sourceforge.phpdt.core.Signature;
40 import net.sourceforge.phpdt.core.WorkingCopyOwner;
41 import net.sourceforge.phpdt.core.compiler.CharOperation;
42 import net.sourceforge.phpdt.core.jdom.IDOMNode;
43 import net.sourceforge.phpdt.internal.compiler.IProblemFactory;
44 import net.sourceforge.phpdt.internal.compiler.SourceElementParser;
45 import net.sourceforge.phpdt.internal.compiler.ast.CompilationUnitDeclaration;
46 import net.sourceforge.phpdt.internal.compiler.impl.CompilerOptions;
47 import net.sourceforge.phpdt.internal.compiler.problem.DefaultProblemFactory;
48 import net.sourceforge.phpdt.internal.core.util.MementoTokenizer;
49 import net.sourceforge.phpdt.internal.core.util.Util;
51 import org.eclipse.core.resources.IContainer;
52 import org.eclipse.core.resources.IFile;
53 import org.eclipse.core.resources.IMarker;
54 import org.eclipse.core.resources.IResource;
55 import org.eclipse.core.runtime.IPath;
56 import org.eclipse.core.runtime.IProgressMonitor;
57 import org.eclipse.core.runtime.Path;
60 * @see ICompilationUnit
63 public class CompilationUnit extends Openable implements ICompilationUnit,
64 net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit {
65 public WorkingCopyOwner owner;
67 * Constructs a handle to a compilation unit with the given name in the specified package for the specified owner
69 * @exception IllegalArgumentException
70 * if the name of the compilation unit does not end with ".java"
72 protected CompilationUnit(PackageFragment parent, String name, WorkingCopyOwner owner) {
78 * Accepts the given visitor onto the parsed tree of this compilation unit, after having runned the name resolution. The visitor's
79 * corresponding <code>visit</code> method is called with the corresponding parse tree. If the visitor returns <code>true</code>,
80 * this method visits this parse node's members.
84 * @exception JavaModelException
85 * if this method fails. Reasons include:
87 * <li>This element does not exist.</li>
88 * <li>The visitor failed with this exception.</li>
91 //public void accept(IAbstractSyntaxTreeVisitor visitor) throws JavaModelException {
92 // CompilationUnitVisitor.visit(this, visitor);
95 * @see ICompilationUnit#becomeWorkingCopy(IProblemRequestor, IProgressMonitor)
97 public void becomeWorkingCopy(IProblemRequestor problemRequestor, IProgressMonitor monitor) throws JavaModelException {
98 JavaModelManager manager = JavaModelManager.getJavaModelManager();
99 JavaModelManager.PerWorkingCopyInfo perWorkingCopyInfo = manager.getPerWorkingCopyInfo(this, false/* don't create */,
100 true /* record usage */, null/* no problem requestor needed */);
101 if (perWorkingCopyInfo == null) {
102 // close cu and its children
105 BecomeWorkingCopyOperation operation = new BecomeWorkingCopyOperation(this, problemRequestor);
106 operation.runOperation(monitor);
110 //protected void buildStructure(OpenableElementInfo info, IProgressMonitor monitor) throws JavaModelException {
112 // if (monitor != null && monitor.isCanceled()) return;
114 // // remove existing (old) infos
117 // HashMap newElements = new HashMap(11);
118 // info.setIsStructureKnown(generateInfos(info, monitor, newElements, getResource()));
119 // JavaModelManager.getJavaModelManager().getElementsOutOfSynchWithBuffers().remove(this);
120 // for (Iterator iter = newElements.keySet().iterator(); iter.hasNext();) {
121 // IJavaElement key = (IJavaElement) iter.next();
122 // Object value = newElements.get(key);
123 // JavaModelManager.getJavaModelManager().putInfo(key, value);
125 // // add the info for this at the end, to ensure that a getInfo cannot reply null in case the LRU cache needs
126 // // to be flushed. Might lead to performance issues.
127 // // see PR 1G2K5S7: ITPJCORE:ALL - NPE when accessing source for a binary type
128 // JavaModelManager.getJavaModelManager().putInfo(this, info);
130 protected boolean buildStructure(OpenableElementInfo info, final IProgressMonitor pm, Map newElements,
131 IResource underlyingResource) throws JavaModelException {
133 // check if this compilation unit can be opened
134 if (!isWorkingCopy()) { // no check is done on root kind or exclusion pattern for working copies
135 if ( // ((IPackageFragment)getParent()).getKind() == IPackageFragmentRoot.K_BINARY||
136 !isValidCompilationUnit() || !underlyingResource.isAccessible()) {
137 throw newNotPresentException();
141 // prevents reopening of non-primary working copies (they are closed when they are discarded and should not be reopened)
142 if (!isPrimary() && getPerWorkingCopyInfo() == null) {
143 throw newNotPresentException();
146 CompilationUnitElementInfo unitInfo = (CompilationUnitElementInfo) info;
148 // get buffer contents
149 IBuffer buffer = getBufferManager().getBuffer(CompilationUnit.this);
150 if (buffer == null) {
151 buffer = openBuffer(pm, unitInfo); // open buffer independently from the info, since we are building the info
153 final char[] contents = buffer == null ? null : buffer.getCharacters();
155 // generate structure and compute syntax problems if needed
156 CompilationUnitStructureRequestor requestor = new CompilationUnitStructureRequestor(this, unitInfo, newElements);
157 JavaModelManager.PerWorkingCopyInfo perWorkingCopyInfo = getPerWorkingCopyInfo();
158 IJavaProject project = getJavaProject();
159 boolean computeProblems = JavaProject.hasJavaNature(project.getProject()) && perWorkingCopyInfo != null
160 && perWorkingCopyInfo.isActive();
161 IProblemFactory problemFactory = new DefaultProblemFactory();
162 Map options = project.getOptions(true);
164 if (underlyingResource == null) {
165 underlyingResource = getResource();
168 SourceElementParser parser = new SourceElementParser(requestor, problemFactory,
169 new CompilerOptions(options));
170 //, true/*report local declarations*/);
171 requestor.parser = parser;
172 CompilationUnitDeclaration unit = parser.parseCompilationUnit(
173 new net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit() {
174 public char[] getContents() {
178 public char[] getMainTypeName() {
179 return CompilationUnit.this.getMainTypeName();
182 public char[][] getPackageName() {
183 return CompilationUnit.this.getPackageName();
186 public char[] getFileName() {
187 return CompilationUnit.this.getFileName();
190 public IResource getResource() {
191 return CompilationUnit.this.getResource();
193 }, true /* full parse to find local elements */);
195 // update timestamp (might be IResource.NULL_STAMP if original does not exist)
197 unitInfo.timestamp = ((IFile) underlyingResource).getModificationStamp();
198 // compute other problems if needed
199 CompilationUnitDeclaration compilationUnitDeclaration = null;
201 if (computeProblems) {
202 perWorkingCopyInfo.beginReporting();
203 compilationUnitDeclaration = CompilationUnitProblemFinder.process(unit, this, contents, parser, this.owner,
204 perWorkingCopyInfo, problemFactory, false/* don't cleanup cu */, pm);
205 perWorkingCopyInfo.endReporting();
208 // if (info instanceof ASTHolderCUInfo) {
209 // int astLevel = ((ASTHolderCUInfo) info).astLevel;
210 // net.sourceforge.phpdt.core.dom.CompilationUnit cu = AST.convertCompilationUnit(astLevel, unit, contents, options, pm);
211 // ((ASTHolderCUInfo) info).ast = cu;
214 if (compilationUnitDeclaration != null) {
215 compilationUnitDeclaration.cleanUp();
219 return unitInfo.isStructureKnown();
223 // * @see ICodeAssist#codeComplete(int, ICompletionRequestor)
225 //public void codeComplete(int offset, ICompletionRequestor requestor) throws JavaModelException {
226 // codeComplete(this, isWorkingCopy() ? (net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit) getOriginalElement() : this,
227 // offset, requestor);
230 * @see ICodeAssist#codeSelect(int, int)
232 //public IJavaElement[] codeSelect(int offset, int length) throws JavaModelException {
233 // return super.codeSelect(this, offset, length);
236 * @see IWorkingCopy#commit(boolean, IProgressMonitor)
238 public void commit(boolean force, IProgressMonitor monitor) throws JavaModelException {
239 commitWorkingCopy(force, monitor);
240 // throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, this));
244 * @see ICompilationUnit#commitWorkingCopy(boolean, IProgressMonitor)
246 public void commitWorkingCopy(boolean force, IProgressMonitor monitor) throws JavaModelException {
247 CommitWorkingCopyOperation op = new CommitWorkingCopyOperation(this, force);
248 op.runOperation(monitor);
252 * @see ISourceManipulation#copy(IJavaElement, IJavaElement, String, boolean, IProgressMonitor)
254 public void copy(IJavaElement container, IJavaElement sibling, String rename, boolean force, IProgressMonitor monitor)
255 throws JavaModelException {
256 if (container == null) {
257 throw new IllegalArgumentException(Util.bind("operation.nullContainer")); //$NON-NLS-1$
259 IJavaElement[] elements = new IJavaElement[] { this };
260 IJavaElement[] containers = new IJavaElement[] { container };
261 String[] renamings = null;
262 if (rename != null) {
263 renamings = new String[] { rename };
265 getJavaModel().copy(elements, containers, null, renamings, force, monitor);
269 * Returns a new element info for this element.
271 protected Object createElementInfo() {
272 return new CompilationUnitElementInfo();
276 // * @see ICompilationUnit#createImport(String, IJavaElement, IProgressMonitor)
278 //public IImportDeclaration createImport(String name, IJavaElement sibling, IProgressMonitor monitor) throws JavaModelException {
279 // CreateImportOperation op = new CreateImportOperation(name, this);
280 // if (sibling != null) {
281 // op.createBefore(sibling);
283 // runOperation(op, monitor);
284 // return getImport(name);
287 * @see ICompilationUnit#createPackageDeclaration(String, IProgressMonitor)
289 public IPackageDeclaration createPackageDeclaration(String name, IProgressMonitor monitor) throws JavaModelException {
291 CreatePackageDeclarationOperation op = new CreatePackageDeclarationOperation(name, this);
292 runOperation(op, monitor);
293 return getPackageDeclaration(name);
297 // * @see ICompilationUnit#createType(String, IJavaElement, boolean, IProgressMonitor)
299 //public IType createType(String content, IJavaElement sibling, boolean force, IProgressMonitor monitor) throws
300 // JavaModelException {
302 // //autogenerate this compilation unit
303 // IPackageFragment pkg = (IPackageFragment) getParent();
304 // String source = ""; //$NON-NLS-1$
305 // if (pkg.getElementName().length() > 0) {
306 // //not the default package...add the package declaration
307 // source = "package " + pkg.getElementName() + ";" + net.sourceforge.phpdt.internal.compiler.util.ProjectPrefUtil.LINE_SEPARATOR +
308 // net.sourceforge.phpdt.internal.compiler.util.ProjectPrefUtil.LINE_SEPARATOR; //$NON-NLS-1$ //$NON-NLS-2$
310 // CreateCompilationUnitOperation op = new CreateCompilationUnitOperation(pkg, fName, source, force);
311 // runOperation(op, monitor);
313 // CreateTypeOperation op = new CreateTypeOperation(this, content, force);
314 // if (sibling != null) {
315 // op.createBefore(sibling);
317 // runOperation(op, monitor);
318 // return (IType) op.getResultElements()[0];
321 * @see ISourceManipulation#delete(boolean, IProgressMonitor)
323 public void delete(boolean force, IProgressMonitor monitor) throws JavaModelException {
324 IJavaElement[] elements = new IJavaElement[] { this };
325 getJavaModel().delete(elements, force, monitor);
329 * @see IWorkingCopy#destroy()
332 public void destroy() {
334 discardWorkingCopy();
335 } catch (JavaModelException e) {
341 * @see ICompilationUnit#discardWorkingCopy
343 public void discardWorkingCopy() throws JavaModelException {
344 // discard working copy and its children
345 DiscardWorkingCopyOperation op = new DiscardWorkingCopyOperation(this);
346 op.runOperation(null);
350 * Returns true if this handle represents the same Java element as the given handle.
352 * @see Object#equals(java.lang.Object)
354 public boolean equals(Object obj) {
355 if (!(obj instanceof CompilationUnit))
357 CompilationUnit other = (CompilationUnit) obj;
358 return this.owner.equals(other.owner) && super.equals(obj);
362 * @see JavaElement#equalsDOMNode(IDOMNode)
364 protected boolean equalsDOMNode(IDOMNode node) throws JavaModelException {
365 String name = getElementName();
366 if (node.getNodeType() == IDOMNode.COMPILATION_UNIT && name != null) {
367 String nodeName = node.getName();
368 if (nodeName == null)
370 if (name.equals(nodeName)) {
373 // iterate through all the types inside the receiver and see if one of them can fit
374 IType[] types = getTypes();
375 String typeNodeName = nodeName.substring(0, nodeName.indexOf(".java")); //$NON-NLS-1$
376 for (int i = 0, max = types.length; i < max; i++) {
377 if (types[i].getElementName().equals(typeNodeName)) {
387 * @see IWorkingCopy#findElements(IJavaElement)
389 public IJavaElement[] findElements(IJavaElement element) {
390 ArrayList children = new ArrayList();
391 while (element != null && element.getElementType() != IJavaElement.COMPILATION_UNIT) {
392 children.add(element);
393 element = element.getParent();
397 IJavaElement currentElement = this;
398 for (int i = children.size() - 1; i >= 0; i--) {
399 IJavaElement child = (IJavaElement) children.get(i);
400 switch (child.getElementType()) {
401 // case IJavaElement.PACKAGE_DECLARATION:
402 // currentElement = ((ICompilationUnit)currentElement).getPackageDeclaration(child.getElementName());
404 // case IJavaElement.IMPORT_CONTAINER:
405 // currentElement = ((ICompilationUnit)currentElement).getImportContainer();
407 // case IJavaElement.IMPORT_DECLARATION:
408 // currentElement = ((IImportContainer)currentElement).getImport(child.getElementName());
410 case IJavaElement.TYPE:
411 if (currentElement.getElementType() == IJavaElement.COMPILATION_UNIT) {
412 currentElement = ((ICompilationUnit) currentElement).getType(child.getElementName());
414 currentElement = ((IType) currentElement).getType(child.getElementName());
417 // case IJavaElement.INITIALIZER:
418 // currentElement = ((IType)currentElement).getInitializer(((JavaElement)child).getOccurrenceCount());
420 case IJavaElement.FIELD:
421 currentElement = ((IType) currentElement).getField(child.getElementName());
423 case IJavaElement.METHOD:
424 return ((IType) currentElement).findMethods((IMethod) child);
428 if (currentElement != null && currentElement.exists()) {
429 return new IJavaElement[] { currentElement };
436 * @see IWorkingCopy#findPrimaryType()
438 public IType findPrimaryType() {
439 String typeName = Signature.getQualifier(this.getElementName());
440 IType primaryType = this.getType(typeName);
441 if (primaryType.exists()) {
448 * @see IWorkingCopy#findSharedWorkingCopy(IBufferFactory)
451 public IJavaElement findSharedWorkingCopy(IBufferFactory factory) {
453 // if factory is null, default factory must be used
455 factory = this.getBufferManager().getDefaultBufferFactory();
457 return findWorkingCopy(BufferFactoryWrapper.create(factory));
461 * @see ICompilationUnit#findWorkingCopy(WorkingCopyOwner)
463 public ICompilationUnit findWorkingCopy(WorkingCopyOwner workingCopyOwner) {
464 CompilationUnit cu = new CompilationUnit((PackageFragment) this.parent, getElementName(), workingCopyOwner);
465 if (workingCopyOwner == DefaultWorkingCopyOwner.PRIMARY) {
468 // must be a working copy
469 JavaModelManager.PerWorkingCopyInfo perWorkingCopyInfo = cu.getPerWorkingCopyInfo();
470 if (perWorkingCopyInfo != null) {
471 return perWorkingCopyInfo.getWorkingCopy();
478 //protected boolean generateInfos(OpenableElementInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource)
479 // throws JavaModelException {
481 //// if (getParent() instanceof JarPackageFragment) {
482 //// // ignore .java files in jar
483 //// throw newNotPresentException();
485 // // put the info now, because getting the contents requires it
486 // JavaModelManager.getJavaModelManager().putInfo(this, info);
487 // CompilationUnitElementInfo unitInfo = (CompilationUnitElementInfo) info;
489 // // generate structure
490 // CompilationUnitStructureRequestor requestor = new CompilationUnitStructureRequestor(this, unitInfo, newElements);
491 // IProblemFactory factory = new DefaultProblemFactory();
492 // SourceElementParser parser = new SourceElementParser(requestor, factory, new
493 // CompilerOptions(getJavaProject().getOptions(true)));
494 //// SourceElementParser parser = new SourceElementParser(requestor, factory);
495 // requestor.parser = parser;
496 // parser.parseCompilationUnit(this, false);
497 // if (isWorkingCopy()) {
498 // CompilationUnit original = (CompilationUnit) getOriginalElement();
499 // // might be IResource.NULL_STAMP if original does not exist
500 // unitInfo.timestamp = ((IFile) original.getResource()).getModificationStamp();
502 // return unitInfo.isStructureKnown();
506 * @see ICompilationUnit#getAllTypes()
508 public IType[] getAllTypes() throws JavaModelException {
509 IJavaElement[] types = getTypes();
511 ArrayList allTypes = new ArrayList(types.length);
512 ArrayList typesToTraverse = new ArrayList(types.length);
513 for (i = 0; i < types.length; i++) {
514 typesToTraverse.add(types[i]);
516 while (!typesToTraverse.isEmpty()) {
517 IType type = (IType) typesToTraverse.get(0);
518 typesToTraverse.remove(type);
520 types = type.getTypes();
521 for (i = 0; i < types.length; i++) {
522 typesToTraverse.add(types[i]);
525 IType[] arrayOfAllTypes = new IType[allTypes.size()];
526 allTypes.toArray(arrayOfAllTypes);
527 return arrayOfAllTypes;
531 * @see IMember#getCompilationUnit()
533 public ICompilationUnit getCompilationUnit() {
538 * @see net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit#getContents()
540 public char[] getContents() {
542 IBuffer buffer = this.getBuffer();
543 return buffer == null ? null : buffer.getCharacters();
544 } catch (JavaModelException e) {
545 return CharOperation.NO_CHAR;
550 * A compilation unit has a corresponding resource unless it is contained in a jar.
552 * @see IJavaElement#getCorrespondingResource()
554 public IResource getCorrespondingResource() throws JavaModelException {
555 IPackageFragmentRoot root = (IPackageFragmentRoot) getParent().getParent();
556 if (root.isArchive()) {
559 return getUnderlyingResource();
564 * @see ICompilationUnit#getElementAt(int)
566 public IJavaElement getElementAt(int position) throws JavaModelException {
568 IJavaElement e = getSourceElementAt(position);
579 public int getElementType() {
580 return COMPILATION_UNIT;
583 public char[] getFileName() {
584 return getElementName().toCharArray();
589 public IJavaElement getHandleFromMemento(String token, MementoTokenizer memento, WorkingCopyOwner workingCopyOwner) {
590 switch (token.charAt(0)) {
592 return getHandleUpdatingCountFromMemento(memento, workingCopyOwner);
593 case JEM_IMPORTDECLARATION:
594 JavaElement container = (JavaElement)getImportContainer();
595 return container.getHandleFromMemento(token, memento, workingCopyOwner);
596 case JEM_PACKAGEDECLARATION:
597 String pkgName = memento.nextToken();
598 JavaElement pkgDecl = (JavaElement)getPackageDeclaration(pkgName);
599 return pkgDecl.getHandleFromMemento(memento, workingCopyOwner);
601 String typeName = memento.nextToken();
602 JavaElement type = (JavaElement)getType(typeName);
603 return type.getHandleFromMemento(memento, workingCopyOwner);
609 * @see JavaElement#getHandleMementoDelimiter()
611 protected char getHandleMementoDelimiter() {
612 return JavaElement.JEM_COMPILATIONUNIT;
615 * @see ICompilationUnit#getImport(String)
617 public IImportDeclaration getImport(String importName) {
618 return new ImportDeclaration((ImportContainer)getImportContainer(), importName);
621 * @see ICompilationUnit#getImportContainer()
623 public IImportContainer getImportContainer() {
624 return new ImportContainer(this);
629 * @see ICompilationUnit#getImports()
631 public IImportDeclaration[] getImports() throws JavaModelException {
632 IImportContainer container= getImportContainer();
633 if (container.exists()) {
634 IJavaElement[] elements= container.getChildren();
635 IImportDeclaration[] imprts= new IImportDeclaration[elements.length];
636 System.arraycopy(elements, 0, imprts, 0, elements.length);
638 } else if (!exists()) {
639 throw newNotPresentException();
641 return new IImportDeclaration[0];
647 * @see net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit#getMainTypeName()
649 public char[] getMainTypeName() {
650 String name = getElementName();
652 name = name.substring(0, name.length() - 5);
653 return name.toCharArray();
657 * @see IWorkingCopy#getOriginal(IJavaElement)
660 public IJavaElement getOriginal(IJavaElement workingCopyElement) {
661 // backward compatibility
662 if (!isWorkingCopy())
664 CompilationUnit cu = (CompilationUnit) workingCopyElement.getAncestor(COMPILATION_UNIT);
665 if (cu == null || !this.owner.equals(cu.owner)) {
669 return workingCopyElement.getPrimaryElement();
673 * @see IWorkingCopy#getOriginalElement()
676 public IJavaElement getOriginalElement() {
677 // backward compatibility
678 if (!isWorkingCopy())
681 return getPrimaryElement();
685 * @see ICompilationUnit#getOwner()
687 public WorkingCopyOwner getOwner() {
688 return isPrimary() || !isWorkingCopy() ? null : this.owner;
692 * @see ICompilationUnit#getPackageDeclaration(String)
694 public IPackageDeclaration getPackageDeclaration(String name) {
695 return new PackageDeclaration(this, name);
699 * @see ICompilationUnit#getPackageDeclarations()
701 public IPackageDeclaration[] getPackageDeclarations() throws JavaModelException {
702 ArrayList list = getChildrenOfType(PACKAGE_DECLARATION);
703 IPackageDeclaration[] array = new IPackageDeclaration[list.size()];
709 * @see net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit#getPackageName()
711 public char[][] getPackageName() {
716 * @see IJavaElement#getPath()
718 public IPath getPath() {
719 PackageFragmentRoot root = this.getPackageFragmentRoot();
720 if (root.isArchive()) {
721 return root.getPath();
723 return this.getParent().getPath().append(this.getElementName());
728 * 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
731 public JavaModelManager.PerWorkingCopyInfo getPerWorkingCopyInfo() {
732 return JavaModelManager.getJavaModelManager().getPerWorkingCopyInfo(this, false/* don't create */, false/* don't record usage */,
733 null/* no problem requestor needed */);
737 * @see ICompilationUnit#getPrimary()
739 public ICompilationUnit getPrimary() {
740 return (ICompilationUnit) getPrimaryElement(true);
744 * @see JavaElement#getPrimaryElement(boolean)
746 public IJavaElement getPrimaryElement(boolean checkOwner) {
747 if (checkOwner && isPrimary())
749 return new CompilationUnit((PackageFragment) getParent(), getElementName(), DefaultWorkingCopyOwner.PRIMARY);
753 * @see IJavaElement#getResource()
755 public IResource getResource() {
756 PackageFragmentRoot root = this.getPackageFragmentRoot();
757 if (root.isArchive()) {
758 return root.getResource();
760 return ((IContainer) this.getParent().getResource()).getFile(new Path(this.getElementName()));
765 * @see ISourceReference#getSource()
767 public String getSource() throws JavaModelException {
768 IBuffer buffer = getBuffer();
770 return ""; //$NON-NLS-1$
771 return buffer.getContents();
775 * @see ISourceReference#getSourceRange()
777 public ISourceRange getSourceRange() throws JavaModelException {
778 return ((CompilationUnitElementInfo) getElementInfo()).getSourceRange();
782 * @see ICompilationUnit#getType(String)
784 public IType getType(String name) {
785 return new SourceType(this, name);
789 * @see ICompilationUnit#getTypes()
791 public IType[] getTypes() throws JavaModelException {
792 ArrayList list = getChildrenOfType(TYPE);
793 IType[] array = new IType[list.size()];
801 public IResource getUnderlyingResource() throws JavaModelException {
802 if (isWorkingCopy() && !isPrimary())
804 return super.getUnderlyingResource();
808 // * @see IWorkingCopy#getSharedWorkingCopy(IProgressMonitor, IBufferFactory, IProblemRequestor)
810 //public IJavaElement getSharedWorkingCopy(IProgressMonitor pm, IBufferFactory factory, IProblemRequestor problemRequestor)
811 // throws JavaModelException {
813 // // if factory is null, default factory must be used
814 // if (factory == null) factory = this.getBufferManager().getDefaultBufferFactory();
816 // JavaModelManager manager = JavaModelManager.getJavaModelManager();
818 // // In order to be shared, working copies have to denote the same compilation unit
819 // // AND use the same buffer factory.
820 // // Assuming there is a little set of buffer factories, then use a 2 level Map cache.
821 // Map sharedWorkingCopies = manager.sharedWorkingCopies;
823 // Map perFactoryWorkingCopies = (Map) sharedWorkingCopies.get(factory);
824 // if (perFactoryWorkingCopies == null){
825 // perFactoryWorkingCopies = new HashMap();
826 // sharedWorkingCopies.put(factory, perFactoryWorkingCopies);
828 // WorkingCopy workingCopy = (WorkingCopy)perFactoryWorkingCopies.get(this);
829 // if (workingCopy != null) {
830 // workingCopy.useCount++;
832 // if (SHARED_WC_VERBOSE) {
833 // System.out.println("Incrementing use count of shared working copy " + workingCopy.toStringWithAncestors()); //$NON-NLS-1$
836 // return workingCopy;
838 // CreateWorkingCopyOperation op = new CreateWorkingCopyOperation(this, perFactoryWorkingCopies, factory, problemRequestor);
839 // runOperation(op, pm);
840 // return op.getResultElements()[0];
844 // * @see IWorkingCopy#getWorkingCopy()
846 //public IJavaElement getWorkingCopy() throws JavaModelException {
847 // return this.getWorkingCopy(null, null, null);
851 // * @see IWorkingCopy#getWorkingCopy(IProgressMonitor, IBufferFactory, IProblemRequestor)
853 //public IJavaElement getWorkingCopy(IProgressMonitor pm, IBufferFactory factory, IProblemRequestor problemRequestor) throws
854 // JavaModelException {
855 // CreateWorkingCopyOperation op = new CreateWorkingCopyOperation(this, null, factory, problemRequestor);
856 // runOperation(op, pm);
857 // return op.getResultElements()[0];
860 * @see IWorkingCopy#getSharedWorkingCopy(IProgressMonitor, IBufferFactory, IProblemRequestor)
863 public IJavaElement getSharedWorkingCopy(IProgressMonitor pm, IBufferFactory factory, IProblemRequestor problemRequestor)
864 throws JavaModelException {
866 // if factory is null, default factory must be used
868 factory = this.getBufferManager().getDefaultBufferFactory();
870 return getWorkingCopy(BufferFactoryWrapper.create(factory), problemRequestor, pm);
874 * @see IWorkingCopy#getWorkingCopy()
877 public IJavaElement getWorkingCopy() throws JavaModelException {
878 return getWorkingCopy(null);
882 * @see ICompilationUnit#getWorkingCopy(IProgressMonitor)
884 public ICompilationUnit getWorkingCopy(IProgressMonitor monitor) throws JavaModelException {
885 return getWorkingCopy(new WorkingCopyOwner() {/* non shared working copy */
886 }, null/* no problem requestor */, monitor);
890 * @see IWorkingCopy#getWorkingCopy(IProgressMonitor, IBufferFactory, IProblemRequestor)
893 public IJavaElement getWorkingCopy(IProgressMonitor monitor, IBufferFactory factory, IProblemRequestor problemRequestor)
894 throws JavaModelException {
895 return getWorkingCopy(BufferFactoryWrapper.create(factory), problemRequestor, monitor);
899 * @see ICompilationUnit#getWorkingCopy(WorkingCopyOwner, IProblemRequestor, IProgressMonitor)
901 public ICompilationUnit getWorkingCopy(WorkingCopyOwner workingCopyOwner, IProblemRequestor problemRequestor,
902 IProgressMonitor monitor) throws JavaModelException {
906 JavaModelManager manager = JavaModelManager.getJavaModelManager();
908 CompilationUnit workingCopy = new CompilationUnit((PackageFragment) getParent(), getElementName(), workingCopyOwner);
909 JavaModelManager.PerWorkingCopyInfo perWorkingCopyInfo = manager.getPerWorkingCopyInfo(workingCopy, false/* don't create */,
910 true/* record usage */, null/* not used since don't create */);
911 if (perWorkingCopyInfo != null) {
912 return perWorkingCopyInfo.getWorkingCopy(); // return existing handle instead of the one created above
914 BecomeWorkingCopyOperation op = new BecomeWorkingCopyOperation(workingCopy, problemRequestor);
915 op.runOperation(monitor);
920 * If I am not open, return true to avoid parsing.
922 * @see IParent#hasChildren()
924 public boolean hasChildren() throws JavaModelException {
926 // return getChildren().length > 0;
934 * @see Openable#hasBuffer()
936 protected boolean hasBuffer() {
941 * @see ICompilationUnit#hasResourceChanged()
943 public boolean hasResourceChanged() {
944 if (!isWorkingCopy())
947 // if resource got deleted, then #getModificationStamp() will answer IResource.NULL_STAMP, which is always different from the
950 Object info = JavaModelManager.getJavaModelManager().getInfo(this);
953 return ((CompilationUnitElementInfo) info).timestamp != getResource().getModificationStamp();
957 * @see IWorkingCopy#isBasedOn(IResource)
960 public boolean isBasedOn(IResource resource) {
961 if (!isWorkingCopy())
963 if (!getResource().equals(resource))
965 return !hasResourceChanged();
969 * @see IOpenable#isConsistent()
971 public boolean isConsistent() {
972 return JavaModelManager.getJavaModelManager().getElementsOutOfSynchWithBuffers().get(this) == null;
979 public boolean isOpen() {
980 Object info = JavaModelManager.getJavaModelManager().getInfo(this);
981 return info != null && ((CompilationUnitElementInfo) info).isOpen();
984 public boolean isPrimary() {
985 return this.owner == DefaultWorkingCopyOwner.PRIMARY;
989 * @see Openable#isSourceElement()
991 protected boolean isSourceElement() {
995 protected boolean isValidCompilationUnit() {
996 IPackageFragmentRoot root = getPackageFragmentRoot();
998 if (root.getKind() != IPackageFragmentRoot.K_SOURCE)
1000 } catch (JavaModelException e) {
1003 // IResource resource = getResource();
1004 // if (resource != null) {
1005 // char[][] inclusionPatterns = ((PackageFragmentRoot)root).fullInclusionPatternChars();
1006 // char[][] exclusionPatterns = ((PackageFragmentRoot)root).fullExclusionPatternChars();
1007 // if (ProjectPrefUtil.isExcluded(resource, inclusionPatterns, exclusionPatterns)) return false;
1009 if (!Util.isValidCompilationUnitName(getElementName()))
1015 * @see ICompilationUnit#isWorkingCopy()
1017 public boolean isWorkingCopy() {
1018 // For backward compatibility, non primary working copies are always returning true; in removal
1019 // delta, clients can still check that element was a working copy before being discarded.
1020 return !isPrimary() || getPerWorkingCopyInfo() != null;
1024 * @see IOpenable#makeConsistent(IProgressMonitor)
1026 public void makeConsistent(IProgressMonitor monitor) throws JavaModelException {
1027 makeConsistent(false/* don't create AST */, 0, monitor);
1030 public Object makeConsistent(boolean createAST, int astLevel, IProgressMonitor monitor) throws JavaModelException {
1034 // create a new info and make it the current info
1035 // (this will remove the info and its children just before storing the new infos)
1037 // ASTHolderCUInfo info = new ASTHolderCUInfo();
1038 // info.astLevel = astLevel;
1039 // openWhenClosed(info, monitor);
1040 // net.sourceforge.phpdt.core.dom.CompilationUnit result = info.ast;
1044 openWhenClosed(createElementInfo(), monitor);
1049 //public net.sourceforge.phpdt.core.dom.CompilationUnit makeConsistent(boolean createAST, int astLevel, IProgressMonitor monitor)
1050 // throws JavaModelException {
1051 // if (isConsistent()) return null;
1053 // // create a new info and make it the current info
1054 // // (this will remove the info and its children just before storing the new infos)
1056 // ASTHolderCUInfo info = new ASTHolderCUInfo();
1057 // info.astLevel = astLevel;
1058 // openWhenClosed(info, monitor);
1059 // net.sourceforge.phpdt.core.dom.CompilationUnit result = info.ast;
1063 // openWhenClosed(createElementInfo(), monitor);
1069 * @see ISourceManipulation#move(IJavaElement, IJavaElement, String, boolean, IProgressMonitor)
1071 public void move(IJavaElement container, IJavaElement sibling, String rename, boolean force, IProgressMonitor monitor)
1072 throws JavaModelException {
1073 if (container == null) {
1074 throw new IllegalArgumentException(Util.bind("operation.nullContainer")); //$NON-NLS-1$
1076 IJavaElement[] elements = new IJavaElement[] { this };
1077 IJavaElement[] containers = new IJavaElement[] { container };
1079 String[] renamings = null;
1080 if (rename != null) {
1081 renamings = new String[] { rename };
1083 getJavaModel().move(elements, containers, null, renamings, force, monitor);
1087 // * @see Openable#openBuffer(IProgressMonitor)
1089 //protected IBuffer openBuffer(IProgressMonitor pm) throws JavaModelException {
1091 // // create buffer - compilation units only use default buffer factory
1092 // BufferManager bufManager = getBufferManager();
1093 // IBuffer buffer = getBufferFactory().createBuffer(this);
1094 // if (buffer == null) return null;
1096 // // set the buffer source
1097 // if (buffer.getCharacters() == null){
1098 // IFile file = (IFile)this.getResource();
1099 // if (file == null || !file.exists()) throw newNotPresentException();
1100 // buffer.setContents(ProjectPrefUtil.getResourceContentsAsCharArray(file));
1103 // // add buffer to buffer cache
1104 // bufManager.addBuffer(buffer);
1106 // // listen to buffer changes
1107 // buffer.addBufferChangedListener(this);
1112 * @see Openable#openBuffer(IProgressMonitor, Object)
1114 protected IBuffer openBuffer(IProgressMonitor pm, Object info) throws JavaModelException {
1117 boolean isWorkingCopy = isWorkingCopy();
1118 IBuffer buffer = isWorkingCopy ? this.owner.createBuffer(this) : BufferManager.getDefaultBufferManager().createBuffer(this);
1122 // set the buffer source
1123 if (buffer.getCharacters() == null) {
1124 if (isWorkingCopy) {
1125 ICompilationUnit original;
1127 && (original = new CompilationUnit((PackageFragment) getParent(), getElementName(), DefaultWorkingCopyOwner.PRIMARY))
1129 buffer.setContents(original.getSource());
1131 IFile file = (IFile) getResource();
1132 if (file == null || !file.exists()) {
1133 // initialize buffer with empty contents
1134 buffer.setContents(CharOperation.NO_CHAR);
1136 buffer.setContents(Util.getResourceContentsAsCharArray(file));
1140 IFile file = (IFile) this.getResource();
1141 if (file == null || !file.exists())
1142 throw newNotPresentException();
1143 buffer.setContents(Util.getResourceContentsAsCharArray(file));
1147 // add buffer to buffer cache
1148 BufferManager bufManager = getBufferManager();
1149 bufManager.addBuffer(buffer);
1151 // listen to buffer changes
1152 buffer.addBufferChangedListener(this);
1158 * @see Openable#openParent
1160 protected void openParent(Object childInfo, HashMap newElements, IProgressMonitor pm) throws JavaModelException {
1162 super.openParent(childInfo, newElements, pm);
1163 } catch (JavaModelException e) {
1164 // allow parent to not exist for working copies defined outside classpath
1165 if (!isWorkingCopy() && !e.isDoesNotExist()) {
1172 * @see ICompilationUnit#reconcile()
1175 public IMarker[] reconcile() throws JavaModelException {
1176 reconcile(NO_AST, false/* don't force problem detection */, null/* use primary owner */, null/* no progress monitor */);
1181 * @see ICompilationUnit#reconcile(int, boolean, WorkingCopyOwner, IProgressMonitor)
1183 public void reconcile(boolean forceProblemDetection, IProgressMonitor monitor) throws JavaModelException {
1184 reconcile(NO_AST, forceProblemDetection, null/* use primary owner */, monitor);
1188 * @see ICompilationUnit#reconcile(int, boolean, WorkingCopyOwner, IProgressMonitor)
1191 //public net.sourceforge.phpdt.core.dom.CompilationUnit reconcile(
1192 public Object reconcile(int astLevel, boolean forceProblemDetection, WorkingCopyOwner workingCopyOwner, IProgressMonitor monitor)
1193 throws JavaModelException {
1195 if (!isWorkingCopy())
1196 return null; // Reconciling is not supported on non working copies
1197 if (workingCopyOwner == null)
1198 workingCopyOwner = DefaultWorkingCopyOwner.PRIMARY;
1200 boolean createAST = false;
1201 // if (astLevel == AST.JLS2) {
1202 // // client asking for level 2 AST; these are supported
1203 // createAST = true;
1204 // } else if (astLevel == AST.JLS3) {
1205 // // client asking for level 3 ASTs; these are not supported
1206 // // TODO (jerome) - these should also be supported in 1.5 stream
1207 // createAST = false;
1209 // // client asking for no AST (0) or unknown ast level
1210 // // either way, request denied
1211 // createAST = false;
1213 ReconcileWorkingCopyOperation op = new ReconcileWorkingCopyOperation(this, createAST, astLevel, forceProblemDetection,
1215 op.runOperation(monitor);
1221 * @see ISourceManipulation#rename(String, boolean, IProgressMonitor)
1223 public void rename(String name, boolean force, IProgressMonitor monitor) throws JavaModelException {
1225 throw new IllegalArgumentException(Util.bind("operation.nullName")); //$NON-NLS-1$
1227 IJavaElement[] elements = new IJavaElement[] { this };
1228 IJavaElement[] dests = new IJavaElement[] { this.getParent() };
1229 String[] renamings = new String[] { name };
1230 getJavaModel().rename(elements, dests, renamings, force, monitor);
1234 * @see ICompilationUnit
1236 public void restore() throws JavaModelException {
1238 if (!isWorkingCopy())
1241 CompilationUnit original = (CompilationUnit) getOriginalElement();
1242 IBuffer buffer = this.getBuffer();
1245 buffer.setContents(original.getContents());
1246 updateTimeStamp(original);
1247 makeConsistent(null);
1251 * @see ICodeAssist#codeComplete(int, ICodeCompletionRequestor)
1252 * @deprecated - use codeComplete(int, ICompletionRequestor)
1254 //public void codeComplete(int offset, final ICodeCompletionRequestor requestor) throws JavaModelException {
1256 // if (requestor == null){
1257 // codeComplete(offset, (ICompletionRequestor)null);
1262 // new ICompletionRequestor(){
1263 // public void acceptAnonymousType(char[] superTypePackageName,char[] superTypeName,char[][] parameterPackageNames,char[][]
1264 // parameterTypeNames,char[][] parameterNames,char[] completionName,int modifiers,int completionStart,int completionEnd, int
1267 // public void acceptClass(char[] packageName, char[] className, char[] completionName, int modifiers, int completionStart, int
1268 // completionEnd, int relevance) {
1269 // requestor.acceptClass(packageName, className, completionName, modifiers, completionStart, completionEnd);
1271 // public void acceptError(IProblem error) {
1272 // if (true) return; // was disabled in 1.0
1275 // IMarker marker = ResourcesPlugin.getWorkspace().getRoot().createMarker(IJavaModelMarker.TRANSIENT_PROBLEM);
1276 // marker.setAttribute(IJavaModelMarker.ID, error.getID());
1277 // marker.setAttribute(IMarker.CHAR_START, error.getSourceStart());
1278 // marker.setAttribute(IMarker.CHAR_END, error.getSourceEnd() + 1);
1279 // marker.setAttribute(IMarker.LINE_NUMBER, error.getSourceLineNumber());
1280 // marker.setAttribute(IMarker.MESSAGE, error.getMessage());
1281 // marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
1282 // requestor.acceptError(marker);
1283 // } catch(CoreException e){
1286 // public void acceptField(char[] declaringTypePackageName, char[] declaringTypeName, char[] name, char[] typePackageName, char[]
1287 // typeName, char[] completionName, int modifiers, int completionStart, int completionEnd, int relevance) {
1288 // requestor.acceptField(declaringTypePackageName, declaringTypeName, name, typePackageName, typeName, completionName, modifiers,
1289 // completionStart, completionEnd);
1291 // public void acceptInterface(char[] packageName,char[] interfaceName,char[] completionName,int modifiers,int completionStart,int
1292 // completionEnd, int relevance) {
1293 // requestor.acceptInterface(packageName, interfaceName, completionName, modifiers, completionStart, completionEnd);
1295 // public void acceptKeyword(char[] keywordName,int completionStart,int completionEnd, int relevance){
1296 // requestor.acceptKeyword(keywordName, completionStart, completionEnd);
1298 // public void acceptLabel(char[] labelName,int completionStart,int completionEnd, int relevance){
1299 // requestor.acceptLabel(labelName, completionStart, completionEnd);
1301 // public void acceptLocalVariable(char[] name,char[] typePackageName,char[] typeName,int modifiers,int completionStart,int
1302 // completionEnd, int relevance){
1305 // public void acceptMethod(char[] declaringTypePackageName,char[] declaringTypeName,char[] selector,char[][]
1306 // parameterPackageNames,char[][] parameterTypeNames,char[][] parameterNames,char[] returnTypePackageName,char[]
1307 // returnTypeName,char[] completionName,int modifiers,int completionStart,int completionEnd, int relevance){
1308 // // skip parameter names
1309 // requestor.acceptMethod(declaringTypePackageName, declaringTypeName, selector, parameterPackageNames, parameterTypeNames,
1310 // returnTypePackageName, returnTypeName, completionName, modifiers, completionStart, completionEnd);
1312 // public void acceptMethodDeclaration(char[] declaringTypePackageName,char[] declaringTypeName,char[] selector,char[][]
1313 // parameterPackageNames,char[][] parameterTypeNames,char[][] parameterNames,char[] returnTypePackageName,char[]
1314 // returnTypeName,char[] completionName,int modifiers,int completionStart,int completionEnd, int relevance){
1317 // public void acceptModifier(char[] modifierName,int completionStart,int completionEnd, int relevance){
1318 // requestor.acceptModifier(modifierName, completionStart, completionEnd);
1320 // public void acceptPackage(char[] packageName,char[] completionName,int completionStart,int completionEnd, int relevance){
1321 // requestor.acceptPackage(packageName, completionName, completionStart, completionEnd);
1323 // public void acceptType(char[] packageName,char[] typeName,char[] completionName,int completionStart,int completionEnd, int
1325 // requestor.acceptType(packageName, typeName, completionName, completionStart, completionEnd);
1327 // public void acceptVariableName(char[] typePackageName,char[] typeName,char[] name,char[] completionName,int completionStart,int
1328 // completionEnd, int relevance){
1334 // * @see JavaElement#rootedAt(IJavaProject)
1336 //public IJavaElement rootedAt(IJavaProject project) {
1338 // new CompilationUnit(
1339 // (IPackageFragment)((JavaElement)parent).rootedAt(project),
1343 * Assume that this is a working copy
1345 protected void updateTimeStamp(CompilationUnit original) throws JavaModelException {
1346 long timeStamp = ((IFile) original.getResource()).getModificationStamp();
1347 if (timeStamp == IResource.NULL_STAMP) {
1348 throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INVALID_RESOURCE));
1350 ((CompilationUnitElementInfo) getElementInfo()).timestamp = timeStamp;