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.ICodeCompletionRequestor;
21 import net.sourceforge.phpdt.core.ICompilationUnit;
22 import net.sourceforge.phpdt.core.IImportContainer;
23 import net.sourceforge.phpdt.core.IImportDeclaration;
24 import net.sourceforge.phpdt.core.IJavaElement;
25 import net.sourceforge.phpdt.core.IJavaModelStatusConstants;
26 import net.sourceforge.phpdt.core.IJavaProject;
27 import net.sourceforge.phpdt.core.IMember;
28 import net.sourceforge.phpdt.core.IMethod;
29 import net.sourceforge.phpdt.core.IOpenable;
30 import net.sourceforge.phpdt.core.IPackageDeclaration;
31 import net.sourceforge.phpdt.core.IPackageFragmentRoot;
32 import net.sourceforge.phpdt.core.IParent;
33 import net.sourceforge.phpdt.core.IProblemRequestor;
34 import net.sourceforge.phpdt.core.ISourceManipulation;
35 import net.sourceforge.phpdt.core.ISourceRange;
36 import net.sourceforge.phpdt.core.ISourceReference;
37 import net.sourceforge.phpdt.core.IType;
38 import net.sourceforge.phpdt.core.IWorkingCopy;
39 import net.sourceforge.phpdt.core.JavaModelException;
40 import net.sourceforge.phpdt.core.Signature;
41 import net.sourceforge.phpdt.core.WorkingCopyOwner;
42 import net.sourceforge.phpdt.core.compiler.CharOperation;
43 import net.sourceforge.phpdt.core.jdom.IDOMNode;
44 import net.sourceforge.phpdt.internal.compiler.IProblemFactory;
45 import net.sourceforge.phpdt.internal.compiler.SourceElementParser;
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;
50 import net.sourceforge.phpeclipse.internal.compiler.ast.CompilationUnitDeclaration;
52 import org.eclipse.core.resources.IContainer;
53 import org.eclipse.core.resources.IFile;
54 import org.eclipse.core.resources.IMarker;
55 import org.eclipse.core.resources.IResource;
56 import org.eclipse.core.runtime.IPath;
57 import org.eclipse.core.runtime.IProgressMonitor;
58 import org.eclipse.core.runtime.Path;
61 * @see ICompilationUnit
64 public class CompilationUnit extends Openable implements ICompilationUnit,
65 net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit {
66 public WorkingCopyOwner owner;
68 * Constructs a handle to a compilation unit with the given name in the specified package for the specified owner
70 * @exception IllegalArgumentException
71 * if the name of the compilation unit does not end with ".java"
73 protected CompilationUnit(PackageFragment parent, String name, WorkingCopyOwner owner) {
79 * Accepts the given visitor onto the parsed tree of this compilation unit, after having runned the name resolution. The visitor's
80 * corresponding <code>visit</code> method is called with the corresponding parse tree. If the visitor returns <code>true</code>,
81 * this method visits this parse node's members.
85 * @exception JavaModelException
86 * if this method fails. Reasons include:
88 * <li>This element does not exist.</li>
89 * <li>The visitor failed with this exception.</li>
92 //public void accept(IAbstractSyntaxTreeVisitor visitor) throws JavaModelException {
93 // CompilationUnitVisitor.visit(this, visitor);
96 * @see ICompilationUnit#becomeWorkingCopy(IProblemRequestor, IProgressMonitor)
98 public void becomeWorkingCopy(IProblemRequestor problemRequestor, IProgressMonitor monitor) throws JavaModelException {
99 JavaModelManager manager = JavaModelManager.getJavaModelManager();
100 JavaModelManager.PerWorkingCopyInfo perWorkingCopyInfo = manager.getPerWorkingCopyInfo(this, false/* don't create */,
101 true /* record usage */, null/* no problem requestor needed */);
102 if (perWorkingCopyInfo == null) {
103 // close cu and its children
106 BecomeWorkingCopyOperation operation = new BecomeWorkingCopyOperation(this, problemRequestor);
107 operation.runOperation(monitor);
111 //protected void buildStructure(OpenableElementInfo info, IProgressMonitor monitor) throws JavaModelException {
113 // if (monitor != null && monitor.isCanceled()) return;
115 // // remove existing (old) infos
118 // HashMap newElements = new HashMap(11);
119 // info.setIsStructureKnown(generateInfos(info, monitor, newElements, getResource()));
120 // JavaModelManager.getJavaModelManager().getElementsOutOfSynchWithBuffers().remove(this);
121 // for (Iterator iter = newElements.keySet().iterator(); iter.hasNext();) {
122 // IJavaElement key = (IJavaElement) iter.next();
123 // Object value = newElements.get(key);
124 // JavaModelManager.getJavaModelManager().putInfo(key, value);
126 // // add the info for this at the end, to ensure that a getInfo cannot reply null in case the LRU cache needs
127 // // to be flushed. Might lead to performance issues.
128 // // see PR 1G2K5S7: ITPJCORE:ALL - NPE when accessing source for a binary type
129 // JavaModelManager.getJavaModelManager().putInfo(this, info);
131 protected boolean buildStructure(OpenableElementInfo info, final IProgressMonitor pm, Map newElements,
132 IResource underlyingResource) throws JavaModelException {
134 // check if this compilation unit can be opened
135 if (!isWorkingCopy()) { // no check is done on root kind or exclusion pattern for working copies
136 if ( // ((IPackageFragment)getParent()).getKind() == IPackageFragmentRoot.K_BINARY||
137 !isValidCompilationUnit() || !underlyingResource.isAccessible()) {
138 throw newNotPresentException();
142 // prevents reopening of non-primary working copies (they are closed when they are discarded and should not be reopened)
143 if (!isPrimary() && getPerWorkingCopyInfo() == null) {
144 throw newNotPresentException();
147 CompilationUnitElementInfo unitInfo = (CompilationUnitElementInfo) info;
149 // get buffer contents
150 IBuffer buffer = getBufferManager().getBuffer(CompilationUnit.this);
151 if (buffer == null) {
152 buffer = openBuffer(pm, unitInfo); // open buffer independently from the info, since we are building the info
154 final char[] contents = buffer == null ? null : buffer.getCharacters();
156 // generate structure and compute syntax problems if needed
157 CompilationUnitStructureRequestor requestor = new CompilationUnitStructureRequestor(this, unitInfo, newElements);
158 JavaModelManager.PerWorkingCopyInfo perWorkingCopyInfo = getPerWorkingCopyInfo();
159 IJavaProject project = getJavaProject();
160 boolean computeProblems = JavaProject.hasJavaNature(project.getProject()) && perWorkingCopyInfo != null
161 && perWorkingCopyInfo.isActive();
162 IProblemFactory problemFactory = new DefaultProblemFactory();
163 Map options = project.getOptions(true);
165 if (underlyingResource == null) {
166 underlyingResource = getResource();
169 SourceElementParser parser = new SourceElementParser(requestor, problemFactory,
170 new CompilerOptions(options));
171 //, true/*report local declarations*/);
172 requestor.parser = parser;
173 CompilationUnitDeclaration unit = parser.parseCompilationUnit(
174 new net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit() {
175 public char[] getContents() {
179 public char[] getMainTypeName() {
180 return CompilationUnit.this.getMainTypeName();
183 public char[][] getPackageName() {
184 return CompilationUnit.this.getPackageName();
187 public char[] getFileName() {
188 return CompilationUnit.this.getFileName();
191 public IResource getResource() {
192 return CompilationUnit.this.getResource();
194 }, true /* full parse to find local elements */);
196 // update timestamp (might be IResource.NULL_STAMP if original does not exist)
198 unitInfo.timestamp = ((IFile) underlyingResource).getModificationStamp();
199 // compute other problems if needed
200 CompilationUnitDeclaration compilationUnitDeclaration = null;
202 if (computeProblems) {
203 perWorkingCopyInfo.beginReporting();
204 compilationUnitDeclaration = CompilationUnitProblemFinder.process(unit, this, contents, parser, this.owner,
205 perWorkingCopyInfo, problemFactory, false/* don't cleanup cu */, pm);
206 perWorkingCopyInfo.endReporting();
209 // if (info instanceof ASTHolderCUInfo) {
210 // int astLevel = ((ASTHolderCUInfo) info).astLevel;
211 // net.sourceforge.phpdt.core.dom.CompilationUnit cu = AST.convertCompilationUnit(astLevel, unit, contents, options, pm);
212 // ((ASTHolderCUInfo) info).ast = cu;
215 if (compilationUnitDeclaration != null) {
216 compilationUnitDeclaration.cleanUp();
220 return unitInfo.isStructureKnown();
224 // * @see ICodeAssist#codeComplete(int, ICompletionRequestor)
226 //public void codeComplete(int offset, ICompletionRequestor requestor) throws JavaModelException {
227 // codeComplete(this, isWorkingCopy() ? (net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit) getOriginalElement() : this,
228 // offset, requestor);
231 * @see ICodeAssist#codeSelect(int, int)
233 //public IJavaElement[] codeSelect(int offset, int length) throws JavaModelException {
234 // return super.codeSelect(this, offset, length);
237 * @see IWorkingCopy#commit(boolean, IProgressMonitor)
239 public void commit(boolean force, IProgressMonitor monitor) throws JavaModelException {
240 commitWorkingCopy(force, monitor);
241 // throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, this));
245 * @see ICompilationUnit#commitWorkingCopy(boolean, IProgressMonitor)
247 public void commitWorkingCopy(boolean force, IProgressMonitor monitor) throws JavaModelException {
248 CommitWorkingCopyOperation op = new CommitWorkingCopyOperation(this, force);
249 op.runOperation(monitor);
253 * @see ISourceManipulation#copy(IJavaElement, IJavaElement, String, boolean, IProgressMonitor)
255 public void copy(IJavaElement container, IJavaElement sibling, String rename, boolean force, IProgressMonitor monitor)
256 throws JavaModelException {
257 if (container == null) {
258 throw new IllegalArgumentException(Util.bind("operation.nullContainer")); //$NON-NLS-1$
260 IJavaElement[] elements = new IJavaElement[] { this };
261 IJavaElement[] containers = new IJavaElement[] { container };
262 String[] renamings = null;
263 if (rename != null) {
264 renamings = new String[] { rename };
266 getJavaModel().copy(elements, containers, null, renamings, force, monitor);
270 * Returns a new element info for this element.
272 protected Object createElementInfo() {
273 return new CompilationUnitElementInfo();
277 // * @see ICompilationUnit#createImport(String, IJavaElement, IProgressMonitor)
279 //public IImportDeclaration createImport(String name, IJavaElement sibling, IProgressMonitor monitor) throws JavaModelException {
280 // CreateImportOperation op = new CreateImportOperation(name, this);
281 // if (sibling != null) {
282 // op.createBefore(sibling);
284 // runOperation(op, monitor);
285 // return getImport(name);
288 * @see ICompilationUnit#createPackageDeclaration(String, IProgressMonitor)
290 public IPackageDeclaration createPackageDeclaration(String name, IProgressMonitor monitor) throws JavaModelException {
292 CreatePackageDeclarationOperation op = new CreatePackageDeclarationOperation(name, this);
293 runOperation(op, monitor);
294 return getPackageDeclaration(name);
298 // * @see ICompilationUnit#createType(String, IJavaElement, boolean, IProgressMonitor)
300 //public IType createType(String content, IJavaElement sibling, boolean force, IProgressMonitor monitor) throws
301 // JavaModelException {
303 // //autogenerate this compilation unit
304 // IPackageFragment pkg = (IPackageFragment) getParent();
305 // String source = ""; //$NON-NLS-1$
306 // if (pkg.getElementName().length() > 0) {
307 // //not the default package...add the package declaration
308 // source = "package " + pkg.getElementName() + ";" + net.sourceforge.phpdt.internal.compiler.util.ProjectPrefUtil.LINE_SEPARATOR +
309 // net.sourceforge.phpdt.internal.compiler.util.ProjectPrefUtil.LINE_SEPARATOR; //$NON-NLS-1$ //$NON-NLS-2$
311 // CreateCompilationUnitOperation op = new CreateCompilationUnitOperation(pkg, fName, source, force);
312 // runOperation(op, monitor);
314 // CreateTypeOperation op = new CreateTypeOperation(this, content, force);
315 // if (sibling != null) {
316 // op.createBefore(sibling);
318 // runOperation(op, monitor);
319 // return (IType) op.getResultElements()[0];
322 * @see ISourceManipulation#delete(boolean, IProgressMonitor)
324 public void delete(boolean force, IProgressMonitor monitor) throws JavaModelException {
325 IJavaElement[] elements = new IJavaElement[] { this };
326 getJavaModel().delete(elements, force, monitor);
330 * @see IWorkingCopy#destroy()
333 public void destroy() {
335 discardWorkingCopy();
336 } catch (JavaModelException e) {
342 * @see ICompilationUnit#discardWorkingCopy
344 public void discardWorkingCopy() throws JavaModelException {
345 // discard working copy and its children
346 DiscardWorkingCopyOperation op = new DiscardWorkingCopyOperation(this);
347 op.runOperation(null);
351 * Returns true if this handle represents the same Java element as the given handle.
353 * @see Object#equals(java.lang.Object)
355 public boolean equals(Object obj) {
356 if (!(obj instanceof CompilationUnit))
358 CompilationUnit other = (CompilationUnit) obj;
359 return this.owner.equals(other.owner) && super.equals(obj);
363 * @see JavaElement#equalsDOMNode(IDOMNode)
365 protected boolean equalsDOMNode(IDOMNode node) throws JavaModelException {
366 String name = getElementName();
367 if (node.getNodeType() == IDOMNode.COMPILATION_UNIT && name != null) {
368 String nodeName = node.getName();
369 if (nodeName == null)
371 if (name.equals(nodeName)) {
374 // iterate through all the types inside the receiver and see if one of them can fit
375 IType[] types = getTypes();
376 String typeNodeName = nodeName.substring(0, nodeName.indexOf(".java")); //$NON-NLS-1$
377 for (int i = 0, max = types.length; i < max; i++) {
378 if (types[i].getElementName().equals(typeNodeName)) {
388 * @see IWorkingCopy#findElements(IJavaElement)
390 public IJavaElement[] findElements(IJavaElement element) {
391 ArrayList children = new ArrayList();
392 while (element != null && element.getElementType() != IJavaElement.COMPILATION_UNIT) {
393 children.add(element);
394 element = element.getParent();
398 IJavaElement currentElement = this;
399 for (int i = children.size() - 1; i >= 0; i--) {
400 IJavaElement child = (IJavaElement) children.get(i);
401 switch (child.getElementType()) {
402 // case IJavaElement.PACKAGE_DECLARATION:
403 // currentElement = ((ICompilationUnit)currentElement).getPackageDeclaration(child.getElementName());
405 // case IJavaElement.IMPORT_CONTAINER:
406 // currentElement = ((ICompilationUnit)currentElement).getImportContainer();
408 // case IJavaElement.IMPORT_DECLARATION:
409 // currentElement = ((IImportContainer)currentElement).getImport(child.getElementName());
411 case IJavaElement.TYPE:
412 if (currentElement.getElementType() == IJavaElement.COMPILATION_UNIT) {
413 currentElement = ((ICompilationUnit) currentElement).getType(child.getElementName());
415 currentElement = ((IType) currentElement).getType(child.getElementName());
418 // case IJavaElement.INITIALIZER:
419 // currentElement = ((IType)currentElement).getInitializer(((JavaElement)child).getOccurrenceCount());
421 case IJavaElement.FIELD:
422 currentElement = ((IType) currentElement).getField(child.getElementName());
424 case IJavaElement.METHOD:
425 return ((IType) currentElement).findMethods((IMethod) child);
429 if (currentElement != null && currentElement.exists()) {
430 return new IJavaElement[] { currentElement };
437 * @see IWorkingCopy#findPrimaryType()
439 public IType findPrimaryType() {
440 String typeName = Signature.getQualifier(this.getElementName());
441 IType primaryType = this.getType(typeName);
442 if (primaryType.exists()) {
449 * @see IWorkingCopy#findSharedWorkingCopy(IBufferFactory)
452 public IJavaElement findSharedWorkingCopy(IBufferFactory factory) {
454 // if factory is null, default factory must be used
456 factory = this.getBufferManager().getDefaultBufferFactory();
458 return findWorkingCopy(BufferFactoryWrapper.create(factory));
462 * @see ICompilationUnit#findWorkingCopy(WorkingCopyOwner)
464 public ICompilationUnit findWorkingCopy(WorkingCopyOwner workingCopyOwner) {
465 CompilationUnit cu = new CompilationUnit((PackageFragment) this.parent, getElementName(), workingCopyOwner);
466 if (workingCopyOwner == DefaultWorkingCopyOwner.PRIMARY) {
469 // must be a working copy
470 JavaModelManager.PerWorkingCopyInfo perWorkingCopyInfo = cu.getPerWorkingCopyInfo();
471 if (perWorkingCopyInfo != null) {
472 return perWorkingCopyInfo.getWorkingCopy();
479 //protected boolean generateInfos(OpenableElementInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource)
480 // throws JavaModelException {
482 //// if (getParent() instanceof JarPackageFragment) {
483 //// // ignore .java files in jar
484 //// throw newNotPresentException();
486 // // put the info now, because getting the contents requires it
487 // JavaModelManager.getJavaModelManager().putInfo(this, info);
488 // CompilationUnitElementInfo unitInfo = (CompilationUnitElementInfo) info;
490 // // generate structure
491 // CompilationUnitStructureRequestor requestor = new CompilationUnitStructureRequestor(this, unitInfo, newElements);
492 // IProblemFactory factory = new DefaultProblemFactory();
493 // SourceElementParser parser = new SourceElementParser(requestor, factory, new
494 // CompilerOptions(getJavaProject().getOptions(true)));
495 //// SourceElementParser parser = new SourceElementParser(requestor, factory);
496 // requestor.parser = parser;
497 // parser.parseCompilationUnit(this, false);
498 // if (isWorkingCopy()) {
499 // CompilationUnit original = (CompilationUnit) getOriginalElement();
500 // // might be IResource.NULL_STAMP if original does not exist
501 // unitInfo.timestamp = ((IFile) original.getResource()).getModificationStamp();
503 // return unitInfo.isStructureKnown();
507 * @see ICompilationUnit#getAllTypes()
509 public IType[] getAllTypes() throws JavaModelException {
510 IJavaElement[] types = getTypes();
512 ArrayList allTypes = new ArrayList(types.length);
513 ArrayList typesToTraverse = new ArrayList(types.length);
514 for (i = 0; i < types.length; i++) {
515 typesToTraverse.add(types[i]);
517 while (!typesToTraverse.isEmpty()) {
518 IType type = (IType) typesToTraverse.get(0);
519 typesToTraverse.remove(type);
521 types = type.getTypes();
522 for (i = 0; i < types.length; i++) {
523 typesToTraverse.add(types[i]);
526 IType[] arrayOfAllTypes = new IType[allTypes.size()];
527 allTypes.toArray(arrayOfAllTypes);
528 return arrayOfAllTypes;
532 * @see IMember#getCompilationUnit()
534 public ICompilationUnit getCompilationUnit() {
539 * @see net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit#getContents()
541 public char[] getContents() {
543 IBuffer buffer = this.getBuffer();
544 return buffer == null ? null : buffer.getCharacters();
545 } catch (JavaModelException e) {
546 return CharOperation.NO_CHAR;
551 * A compilation unit has a corresponding resource unless it is contained in a jar.
553 * @see IJavaElement#getCorrespondingResource()
555 public IResource getCorrespondingResource() throws JavaModelException {
556 IPackageFragmentRoot root = (IPackageFragmentRoot) getParent().getParent();
557 if (root.isArchive()) {
560 return getUnderlyingResource();
565 * @see ICompilationUnit#getElementAt(int)
567 public IJavaElement getElementAt(int position) throws JavaModelException {
569 IJavaElement e = getSourceElementAt(position);
580 public int getElementType() {
581 return COMPILATION_UNIT;
584 public char[] getFileName() {
585 return getElementName().toCharArray();
590 public IJavaElement getHandleFromMemento(String token, MementoTokenizer memento, WorkingCopyOwner workingCopyOwner) {
591 switch (token.charAt(0)) {
593 return getHandleUpdatingCountFromMemento(memento, workingCopyOwner);
594 case JEM_IMPORTDECLARATION:
595 JavaElement container = (JavaElement)getImportContainer();
596 return container.getHandleFromMemento(token, memento, workingCopyOwner);
597 case JEM_PACKAGEDECLARATION:
598 String pkgName = memento.nextToken();
599 JavaElement pkgDecl = (JavaElement)getPackageDeclaration(pkgName);
600 return pkgDecl.getHandleFromMemento(memento, workingCopyOwner);
602 String typeName = memento.nextToken();
603 JavaElement type = (JavaElement)getType(typeName);
604 return type.getHandleFromMemento(memento, workingCopyOwner);
610 * @see JavaElement#getHandleMementoDelimiter()
612 protected char getHandleMementoDelimiter() {
613 return JavaElement.JEM_COMPILATIONUNIT;
616 * @see ICompilationUnit#getImport(String)
618 public IImportDeclaration getImport(String importName) {
619 return new ImportDeclaration((ImportContainer)getImportContainer(), importName);
622 * @see ICompilationUnit#getImportContainer()
624 public IImportContainer getImportContainer() {
625 return new ImportContainer(this);
630 * @see ICompilationUnit#getImports()
632 public IImportDeclaration[] getImports() throws JavaModelException {
633 IImportContainer container= getImportContainer();
634 if (container.exists()) {
635 IJavaElement[] elements= container.getChildren();
636 IImportDeclaration[] imprts= new IImportDeclaration[elements.length];
637 System.arraycopy(elements, 0, imprts, 0, elements.length);
639 } else if (!exists()) {
640 throw newNotPresentException();
642 return new IImportDeclaration[0];
648 * @see net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit#getMainTypeName()
650 public char[] getMainTypeName() {
651 String name = getElementName();
653 name = name.substring(0, name.length() - 5);
654 return name.toCharArray();
658 * @see IWorkingCopy#getOriginal(IJavaElement)
661 public IJavaElement getOriginal(IJavaElement workingCopyElement) {
662 // backward compatibility
663 if (!isWorkingCopy())
665 CompilationUnit cu = (CompilationUnit) workingCopyElement.getAncestor(COMPILATION_UNIT);
666 if (cu == null || !this.owner.equals(cu.owner)) {
670 return workingCopyElement.getPrimaryElement();
674 * @see IWorkingCopy#getOriginalElement()
677 public IJavaElement getOriginalElement() {
678 // backward compatibility
679 if (!isWorkingCopy())
682 return getPrimaryElement();
686 * @see ICompilationUnit#getOwner()
688 public WorkingCopyOwner getOwner() {
689 return isPrimary() || !isWorkingCopy() ? null : this.owner;
693 * @see ICompilationUnit#getPackageDeclaration(String)
695 public IPackageDeclaration getPackageDeclaration(String name) {
696 return new PackageDeclaration(this, name);
700 * @see ICompilationUnit#getPackageDeclarations()
702 public IPackageDeclaration[] getPackageDeclarations() throws JavaModelException {
703 ArrayList list = getChildrenOfType(PACKAGE_DECLARATION);
704 IPackageDeclaration[] array = new IPackageDeclaration[list.size()];
710 * @see net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit#getPackageName()
712 public char[][] getPackageName() {
717 * @see IJavaElement#getPath()
719 public IPath getPath() {
720 PackageFragmentRoot root = this.getPackageFragmentRoot();
721 if (root.isArchive()) {
722 return root.getPath();
724 return this.getParent().getPath().append(this.getElementName());
729 * 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
732 public JavaModelManager.PerWorkingCopyInfo getPerWorkingCopyInfo() {
733 return JavaModelManager.getJavaModelManager().getPerWorkingCopyInfo(this, false/* don't create */, false/* don't record usage */,
734 null/* no problem requestor needed */);
738 * @see ICompilationUnit#getPrimary()
740 public ICompilationUnit getPrimary() {
741 return (ICompilationUnit) getPrimaryElement(true);
745 * @see JavaElement#getPrimaryElement(boolean)
747 public IJavaElement getPrimaryElement(boolean checkOwner) {
748 if (checkOwner && isPrimary())
750 return new CompilationUnit((PackageFragment) getParent(), getElementName(), DefaultWorkingCopyOwner.PRIMARY);
754 * @see IJavaElement#getResource()
756 public IResource getResource() {
757 PackageFragmentRoot root = this.getPackageFragmentRoot();
758 if (root.isArchive()) {
759 return root.getResource();
761 return ((IContainer) this.getParent().getResource()).getFile(new Path(this.getElementName()));
766 * @see ISourceReference#getSource()
768 public String getSource() throws JavaModelException {
769 IBuffer buffer = getBuffer();
771 return ""; //$NON-NLS-1$
772 return buffer.getContents();
776 * @see ISourceReference#getSourceRange()
778 public ISourceRange getSourceRange() throws JavaModelException {
779 return ((CompilationUnitElementInfo) getElementInfo()).getSourceRange();
783 * @see ICompilationUnit#getType(String)
785 public IType getType(String name) {
786 return new SourceType(this, name);
790 * @see ICompilationUnit#getTypes()
792 public IType[] getTypes() throws JavaModelException {
793 ArrayList list = getChildrenOfType(TYPE);
794 IType[] array = new IType[list.size()];
802 public IResource getUnderlyingResource() throws JavaModelException {
803 if (isWorkingCopy() && !isPrimary())
805 return super.getUnderlyingResource();
809 // * @see IWorkingCopy#getSharedWorkingCopy(IProgressMonitor, IBufferFactory, IProblemRequestor)
811 //public IJavaElement getSharedWorkingCopy(IProgressMonitor pm, IBufferFactory factory, IProblemRequestor problemRequestor)
812 // throws JavaModelException {
814 // // if factory is null, default factory must be used
815 // if (factory == null) factory = this.getBufferManager().getDefaultBufferFactory();
817 // JavaModelManager manager = JavaModelManager.getJavaModelManager();
819 // // In order to be shared, working copies have to denote the same compilation unit
820 // // AND use the same buffer factory.
821 // // Assuming there is a little set of buffer factories, then use a 2 level Map cache.
822 // Map sharedWorkingCopies = manager.sharedWorkingCopies;
824 // Map perFactoryWorkingCopies = (Map) sharedWorkingCopies.get(factory);
825 // if (perFactoryWorkingCopies == null){
826 // perFactoryWorkingCopies = new HashMap();
827 // sharedWorkingCopies.put(factory, perFactoryWorkingCopies);
829 // WorkingCopy workingCopy = (WorkingCopy)perFactoryWorkingCopies.get(this);
830 // if (workingCopy != null) {
831 // workingCopy.useCount++;
833 // if (SHARED_WC_VERBOSE) {
834 // System.out.println("Incrementing use count of shared working copy " + workingCopy.toStringWithAncestors()); //$NON-NLS-1$
837 // return workingCopy;
839 // CreateWorkingCopyOperation op = new CreateWorkingCopyOperation(this, perFactoryWorkingCopies, factory, problemRequestor);
840 // runOperation(op, pm);
841 // return op.getResultElements()[0];
845 // * @see IWorkingCopy#getWorkingCopy()
847 //public IJavaElement getWorkingCopy() throws JavaModelException {
848 // return this.getWorkingCopy(null, null, null);
852 // * @see IWorkingCopy#getWorkingCopy(IProgressMonitor, IBufferFactory, IProblemRequestor)
854 //public IJavaElement getWorkingCopy(IProgressMonitor pm, IBufferFactory factory, IProblemRequestor problemRequestor) throws
855 // JavaModelException {
856 // CreateWorkingCopyOperation op = new CreateWorkingCopyOperation(this, null, factory, problemRequestor);
857 // runOperation(op, pm);
858 // return op.getResultElements()[0];
861 * @see IWorkingCopy#getSharedWorkingCopy(IProgressMonitor, IBufferFactory, IProblemRequestor)
864 public IJavaElement getSharedWorkingCopy(IProgressMonitor pm, IBufferFactory factory, IProblemRequestor problemRequestor)
865 throws JavaModelException {
867 // if factory is null, default factory must be used
869 factory = this.getBufferManager().getDefaultBufferFactory();
871 return getWorkingCopy(BufferFactoryWrapper.create(factory), problemRequestor, pm);
875 * @see IWorkingCopy#getWorkingCopy()
878 public IJavaElement getWorkingCopy() throws JavaModelException {
879 return getWorkingCopy(null);
883 * @see ICompilationUnit#getWorkingCopy(IProgressMonitor)
885 public ICompilationUnit getWorkingCopy(IProgressMonitor monitor) throws JavaModelException {
886 return getWorkingCopy(new WorkingCopyOwner() {/* non shared working copy */
887 }, null/* no problem requestor */, monitor);
891 * @see IWorkingCopy#getWorkingCopy(IProgressMonitor, IBufferFactory, IProblemRequestor)
894 public IJavaElement getWorkingCopy(IProgressMonitor monitor, IBufferFactory factory, IProblemRequestor problemRequestor)
895 throws JavaModelException {
896 return getWorkingCopy(BufferFactoryWrapper.create(factory), problemRequestor, monitor);
900 * @see ICompilationUnit#getWorkingCopy(WorkingCopyOwner, IProblemRequestor, IProgressMonitor)
902 public ICompilationUnit getWorkingCopy(WorkingCopyOwner workingCopyOwner, IProblemRequestor problemRequestor,
903 IProgressMonitor monitor) throws JavaModelException {
907 JavaModelManager manager = JavaModelManager.getJavaModelManager();
909 CompilationUnit workingCopy = new CompilationUnit((PackageFragment) getParent(), getElementName(), workingCopyOwner);
910 JavaModelManager.PerWorkingCopyInfo perWorkingCopyInfo = manager.getPerWorkingCopyInfo(workingCopy, false/* don't create */,
911 true/* record usage */, null/* not used since don't create */);
912 if (perWorkingCopyInfo != null) {
913 return perWorkingCopyInfo.getWorkingCopy(); // return existing handle instead of the one created above
915 BecomeWorkingCopyOperation op = new BecomeWorkingCopyOperation(workingCopy, problemRequestor);
916 op.runOperation(monitor);
921 * If I am not open, return true to avoid parsing.
923 * @see IParent#hasChildren()
925 public boolean hasChildren() throws JavaModelException {
927 // return getChildren().length > 0;
935 * @see Openable#hasBuffer()
937 protected boolean hasBuffer() {
942 * @see ICompilationUnit#hasResourceChanged()
944 public boolean hasResourceChanged() {
945 if (!isWorkingCopy())
948 // if resource got deleted, then #getModificationStamp() will answer IResource.NULL_STAMP, which is always different from the
951 Object info = JavaModelManager.getJavaModelManager().getInfo(this);
954 return ((CompilationUnitElementInfo) info).timestamp != getResource().getModificationStamp();
958 * @see IWorkingCopy#isBasedOn(IResource)
961 public boolean isBasedOn(IResource resource) {
962 if (!isWorkingCopy())
964 if (!getResource().equals(resource))
966 return !hasResourceChanged();
970 * @see IOpenable#isConsistent()
972 public boolean isConsistent() {
973 return JavaModelManager.getJavaModelManager().getElementsOutOfSynchWithBuffers().get(this) == null;
980 public boolean isOpen() {
981 Object info = JavaModelManager.getJavaModelManager().getInfo(this);
982 return info != null && ((CompilationUnitElementInfo) info).isOpen();
985 public boolean isPrimary() {
986 return this.owner == DefaultWorkingCopyOwner.PRIMARY;
990 * @see Openable#isSourceElement()
992 protected boolean isSourceElement() {
996 protected boolean isValidCompilationUnit() {
997 IPackageFragmentRoot root = getPackageFragmentRoot();
999 if (root.getKind() != IPackageFragmentRoot.K_SOURCE)
1001 } catch (JavaModelException e) {
1004 // IResource resource = getResource();
1005 // if (resource != null) {
1006 // char[][] inclusionPatterns = ((PackageFragmentRoot)root).fullInclusionPatternChars();
1007 // char[][] exclusionPatterns = ((PackageFragmentRoot)root).fullExclusionPatternChars();
1008 // if (ProjectPrefUtil.isExcluded(resource, inclusionPatterns, exclusionPatterns)) return false;
1010 if (!Util.isValidCompilationUnitName(getElementName()))
1016 * @see ICompilationUnit#isWorkingCopy()
1018 public boolean isWorkingCopy() {
1019 // For backward compatibility, non primary working copies are always returning true; in removal
1020 // delta, clients can still check that element was a working copy before being discarded.
1021 return !isPrimary() || getPerWorkingCopyInfo() != null;
1025 * @see IOpenable#makeConsistent(IProgressMonitor)
1027 public void makeConsistent(IProgressMonitor monitor) throws JavaModelException {
1028 makeConsistent(false/* don't create AST */, 0, monitor);
1031 public Object makeConsistent(boolean createAST, int astLevel, IProgressMonitor monitor) throws JavaModelException {
1035 // create a new info and make it the current info
1036 // (this will remove the info and its children just before storing the new infos)
1038 // ASTHolderCUInfo info = new ASTHolderCUInfo();
1039 // info.astLevel = astLevel;
1040 // openWhenClosed(info, monitor);
1041 // net.sourceforge.phpdt.core.dom.CompilationUnit result = info.ast;
1045 openWhenClosed(createElementInfo(), monitor);
1050 //public net.sourceforge.phpdt.core.dom.CompilationUnit makeConsistent(boolean createAST, int astLevel, IProgressMonitor monitor)
1051 // throws JavaModelException {
1052 // if (isConsistent()) return null;
1054 // // create a new info and make it the current info
1055 // // (this will remove the info and its children just before storing the new infos)
1057 // ASTHolderCUInfo info = new ASTHolderCUInfo();
1058 // info.astLevel = astLevel;
1059 // openWhenClosed(info, monitor);
1060 // net.sourceforge.phpdt.core.dom.CompilationUnit result = info.ast;
1064 // openWhenClosed(createElementInfo(), monitor);
1070 * @see ISourceManipulation#move(IJavaElement, IJavaElement, String, boolean, IProgressMonitor)
1072 public void move(IJavaElement container, IJavaElement sibling, String rename, boolean force, IProgressMonitor monitor)
1073 throws JavaModelException {
1074 if (container == null) {
1075 throw new IllegalArgumentException(Util.bind("operation.nullContainer")); //$NON-NLS-1$
1077 IJavaElement[] elements = new IJavaElement[] { this };
1078 IJavaElement[] containers = new IJavaElement[] { container };
1080 String[] renamings = null;
1081 if (rename != null) {
1082 renamings = new String[] { rename };
1084 getJavaModel().move(elements, containers, null, renamings, force, monitor);
1088 // * @see Openable#openBuffer(IProgressMonitor)
1090 //protected IBuffer openBuffer(IProgressMonitor pm) throws JavaModelException {
1092 // // create buffer - compilation units only use default buffer factory
1093 // BufferManager bufManager = getBufferManager();
1094 // IBuffer buffer = getBufferFactory().createBuffer(this);
1095 // if (buffer == null) return null;
1097 // // set the buffer source
1098 // if (buffer.getCharacters() == null){
1099 // IFile file = (IFile)this.getResource();
1100 // if (file == null || !file.exists()) throw newNotPresentException();
1101 // buffer.setContents(ProjectPrefUtil.getResourceContentsAsCharArray(file));
1104 // // add buffer to buffer cache
1105 // bufManager.addBuffer(buffer);
1107 // // listen to buffer changes
1108 // buffer.addBufferChangedListener(this);
1113 * @see Openable#openBuffer(IProgressMonitor, Object)
1115 protected IBuffer openBuffer(IProgressMonitor pm, Object info) throws JavaModelException {
1118 boolean isWorkingCopy = isWorkingCopy();
1119 IBuffer buffer = isWorkingCopy ? this.owner.createBuffer(this) : BufferManager.getDefaultBufferManager().createBuffer(this);
1123 // set the buffer source
1124 if (buffer.getCharacters() == null) {
1125 if (isWorkingCopy) {
1126 ICompilationUnit original;
1128 && (original = new CompilationUnit((PackageFragment) getParent(), getElementName(), DefaultWorkingCopyOwner.PRIMARY))
1130 buffer.setContents(original.getSource());
1132 IFile file = (IFile) getResource();
1133 if (file == null || !file.exists()) {
1134 // initialize buffer with empty contents
1135 buffer.setContents(CharOperation.NO_CHAR);
1137 buffer.setContents(Util.getResourceContentsAsCharArray(file));
1141 IFile file = (IFile) this.getResource();
1142 if (file == null || !file.exists())
1143 throw newNotPresentException();
1144 buffer.setContents(Util.getResourceContentsAsCharArray(file));
1148 // add buffer to buffer cache
1149 BufferManager bufManager = getBufferManager();
1150 bufManager.addBuffer(buffer);
1152 // listen to buffer changes
1153 buffer.addBufferChangedListener(this);
1159 * @see Openable#openParent
1161 protected void openParent(Object childInfo, HashMap newElements, IProgressMonitor pm) throws JavaModelException {
1163 super.openParent(childInfo, newElements, pm);
1164 } catch (JavaModelException e) {
1165 // allow parent to not exist for working copies defined outside classpath
1166 if (!isWorkingCopy() && !e.isDoesNotExist()) {
1173 * @see ICompilationUnit#reconcile()
1176 public IMarker[] reconcile() throws JavaModelException {
1177 reconcile(NO_AST, false/* don't force problem detection */, null/* use primary owner */, null/* no progress monitor */);
1182 * @see ICompilationUnit#reconcile(int, boolean, WorkingCopyOwner, IProgressMonitor)
1184 public void reconcile(boolean forceProblemDetection, IProgressMonitor monitor) throws JavaModelException {
1185 reconcile(NO_AST, forceProblemDetection, null/* use primary owner */, monitor);
1189 * @see ICompilationUnit#reconcile(int, boolean, WorkingCopyOwner, IProgressMonitor)
1192 //public net.sourceforge.phpdt.core.dom.CompilationUnit reconcile(
1193 public Object reconcile(int astLevel, boolean forceProblemDetection, WorkingCopyOwner workingCopyOwner, IProgressMonitor monitor)
1194 throws JavaModelException {
1196 if (!isWorkingCopy())
1197 return null; // Reconciling is not supported on non working copies
1198 if (workingCopyOwner == null)
1199 workingCopyOwner = DefaultWorkingCopyOwner.PRIMARY;
1201 boolean createAST = false;
1202 // if (astLevel == AST.JLS2) {
1203 // // client asking for level 2 AST; these are supported
1204 // createAST = true;
1205 // } else if (astLevel == AST.JLS3) {
1206 // // client asking for level 3 ASTs; these are not supported
1207 // // TODO (jerome) - these should also be supported in 1.5 stream
1208 // createAST = false;
1210 // // client asking for no AST (0) or unknown ast level
1211 // // either way, request denied
1212 // createAST = false;
1214 ReconcileWorkingCopyOperation op = new ReconcileWorkingCopyOperation(this, createAST, astLevel, forceProblemDetection,
1216 op.runOperation(monitor);
1222 * @see ISourceManipulation#rename(String, boolean, IProgressMonitor)
1224 public void rename(String name, boolean force, IProgressMonitor monitor) throws JavaModelException {
1226 throw new IllegalArgumentException(Util.bind("operation.nullName")); //$NON-NLS-1$
1228 IJavaElement[] elements = new IJavaElement[] { this };
1229 IJavaElement[] dests = new IJavaElement[] { this.getParent() };
1230 String[] renamings = new String[] { name };
1231 getJavaModel().rename(elements, dests, renamings, force, monitor);
1235 * @see ICompilationUnit
1237 public void restore() throws JavaModelException {
1239 if (!isWorkingCopy())
1242 CompilationUnit original = (CompilationUnit) getOriginalElement();
1243 IBuffer buffer = this.getBuffer();
1246 buffer.setContents(original.getContents());
1247 updateTimeStamp(original);
1248 makeConsistent(null);
1252 * @see ICodeAssist#codeComplete(int, ICodeCompletionRequestor)
1253 * @deprecated - use codeComplete(int, ICompletionRequestor)
1255 //public void codeComplete(int offset, final ICodeCompletionRequestor requestor) throws JavaModelException {
1257 // if (requestor == null){
1258 // codeComplete(offset, (ICompletionRequestor)null);
1263 // new ICompletionRequestor(){
1264 // public void acceptAnonymousType(char[] superTypePackageName,char[] superTypeName,char[][] parameterPackageNames,char[][]
1265 // parameterTypeNames,char[][] parameterNames,char[] completionName,int modifiers,int completionStart,int completionEnd, int
1268 // public void acceptClass(char[] packageName, char[] className, char[] completionName, int modifiers, int completionStart, int
1269 // completionEnd, int relevance) {
1270 // requestor.acceptClass(packageName, className, completionName, modifiers, completionStart, completionEnd);
1272 // public void acceptError(IProblem error) {
1273 // if (true) return; // was disabled in 1.0
1276 // IMarker marker = ResourcesPlugin.getWorkspace().getRoot().createMarker(IJavaModelMarker.TRANSIENT_PROBLEM);
1277 // marker.setAttribute(IJavaModelMarker.ID, error.getID());
1278 // marker.setAttribute(IMarker.CHAR_START, error.getSourceStart());
1279 // marker.setAttribute(IMarker.CHAR_END, error.getSourceEnd() + 1);
1280 // marker.setAttribute(IMarker.LINE_NUMBER, error.getSourceLineNumber());
1281 // marker.setAttribute(IMarker.MESSAGE, error.getMessage());
1282 // marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
1283 // requestor.acceptError(marker);
1284 // } catch(CoreException e){
1287 // public void acceptField(char[] declaringTypePackageName, char[] declaringTypeName, char[] name, char[] typePackageName, char[]
1288 // typeName, char[] completionName, int modifiers, int completionStart, int completionEnd, int relevance) {
1289 // requestor.acceptField(declaringTypePackageName, declaringTypeName, name, typePackageName, typeName, completionName, modifiers,
1290 // completionStart, completionEnd);
1292 // public void acceptInterface(char[] packageName,char[] interfaceName,char[] completionName,int modifiers,int completionStart,int
1293 // completionEnd, int relevance) {
1294 // requestor.acceptInterface(packageName, interfaceName, completionName, modifiers, completionStart, completionEnd);
1296 // public void acceptKeyword(char[] keywordName,int completionStart,int completionEnd, int relevance){
1297 // requestor.acceptKeyword(keywordName, completionStart, completionEnd);
1299 // public void acceptLabel(char[] labelName,int completionStart,int completionEnd, int relevance){
1300 // requestor.acceptLabel(labelName, completionStart, completionEnd);
1302 // public void acceptLocalVariable(char[] name,char[] typePackageName,char[] typeName,int modifiers,int completionStart,int
1303 // completionEnd, int relevance){
1306 // public void acceptMethod(char[] declaringTypePackageName,char[] declaringTypeName,char[] selector,char[][]
1307 // parameterPackageNames,char[][] parameterTypeNames,char[][] parameterNames,char[] returnTypePackageName,char[]
1308 // returnTypeName,char[] completionName,int modifiers,int completionStart,int completionEnd, int relevance){
1309 // // skip parameter names
1310 // requestor.acceptMethod(declaringTypePackageName, declaringTypeName, selector, parameterPackageNames, parameterTypeNames,
1311 // returnTypePackageName, returnTypeName, completionName, modifiers, completionStart, completionEnd);
1313 // public void acceptMethodDeclaration(char[] declaringTypePackageName,char[] declaringTypeName,char[] selector,char[][]
1314 // parameterPackageNames,char[][] parameterTypeNames,char[][] parameterNames,char[] returnTypePackageName,char[]
1315 // returnTypeName,char[] completionName,int modifiers,int completionStart,int completionEnd, int relevance){
1318 // public void acceptModifier(char[] modifierName,int completionStart,int completionEnd, int relevance){
1319 // requestor.acceptModifier(modifierName, completionStart, completionEnd);
1321 // public void acceptPackage(char[] packageName,char[] completionName,int completionStart,int completionEnd, int relevance){
1322 // requestor.acceptPackage(packageName, completionName, completionStart, completionEnd);
1324 // public void acceptType(char[] packageName,char[] typeName,char[] completionName,int completionStart,int completionEnd, int
1326 // requestor.acceptType(packageName, typeName, completionName, completionStart, completionEnd);
1328 // public void acceptVariableName(char[] typePackageName,char[] typeName,char[] name,char[] completionName,int completionStart,int
1329 // completionEnd, int relevance){
1335 // * @see JavaElement#rootedAt(IJavaProject)
1337 //public IJavaElement rootedAt(IJavaProject project) {
1339 // new CompilationUnit(
1340 // (IPackageFragment)((JavaElement)parent).rootedAt(project),
1344 * Assume that this is a working copy
1346 protected void updateTimeStamp(CompilationUnit original) throws JavaModelException {
1347 long timeStamp = ((IFile) original.getResource()).getModificationStamp();
1348 if (timeStamp == IResource.NULL_STAMP) {
1349 throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INVALID_RESOURCE));
1351 ((CompilationUnitElementInfo) getElementInfo()).timestamp = timeStamp;