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, net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit {
61 public WorkingCopyOwner owner;
64 * Constructs a handle to a compilation unit with the given name in the
65 * specified package for the specified owner
67 * @exception IllegalArgumentException if the name of the compilation unit
68 * does not end with ".java"
70 protected CompilationUnit(PackageFragment parent, String name, WorkingCopyOwner owner) {
75 * Accepts the given visitor onto the parsed tree of this compilation unit, after
76 * having runned the name resolution.
77 * The visitor's corresponding <code>visit</code> method is called with the
78 * corresponding parse tree. If the visitor returns <code>true</code>, this method
79 * visits this parse node's members.
81 * @param visitor the visitor
82 * @exception JavaModelException if this method fails. Reasons include:
84 * <li> This element does not exist.</li>
85 * <li> The visitor failed with this exception.</li>
88 //public void accept(IAbstractSyntaxTreeVisitor visitor) throws JavaModelException {
89 // CompilationUnitVisitor.visit(this, visitor);
92 * @see ICompilationUnit#becomeWorkingCopy(IProblemRequestor, IProgressMonitor)
94 public void becomeWorkingCopy(IProblemRequestor problemRequestor, IProgressMonitor monitor) throws JavaModelException {
95 JavaModelManager manager = JavaModelManager.getJavaModelManager();
96 JavaModelManager.PerWorkingCopyInfo perWorkingCopyInfo = manager.getPerWorkingCopyInfo(this, false/*don't create*/, true /*record usage*/, null/*no problem requestor needed*/);
97 if (perWorkingCopyInfo == null) {
98 // close cu and its children
101 BecomeWorkingCopyOperation operation = new BecomeWorkingCopyOperation(this, problemRequestor);
102 operation.runOperation(monitor);
105 //protected void buildStructure(OpenableElementInfo info, IProgressMonitor monitor) throws JavaModelException {
107 // if (monitor != null && monitor.isCanceled()) return;
109 // // remove existing (old) infos
112 // HashMap newElements = new HashMap(11);
113 // info.setIsStructureKnown(generateInfos(info, monitor, newElements, getResource()));
114 // JavaModelManager.getJavaModelManager().getElementsOutOfSynchWithBuffers().remove(this);
115 // for (Iterator iter = newElements.keySet().iterator(); iter.hasNext();) {
116 // IJavaElement key = (IJavaElement) iter.next();
117 // Object value = newElements.get(key);
118 // JavaModelManager.getJavaModelManager().putInfo(key, value);
120 // // add the info for this at the end, to ensure that a getInfo cannot reply null in case the LRU cache needs
121 // // to be flushed. Might lead to performance issues.
122 // // see PR 1G2K5S7: ITPJCORE:ALL - NPE when accessing source for a binary type
123 // JavaModelManager.getJavaModelManager().putInfo(this, info);
125 protected boolean buildStructure(OpenableElementInfo info, final IProgressMonitor pm, Map newElements, IResource underlyingResource) throws JavaModelException {
127 // check if this compilation unit can be opened
128 if (!isWorkingCopy()) { // no check is done on root kind or exclusion pattern for working copies
129 if ( // ((IPackageFragment)getParent()).getKind() == IPackageFragmentRoot.K_BINARY||
130 !isValidCompilationUnit()
131 || !underlyingResource.isAccessible()) {
132 throw newNotPresentException();
136 // prevents reopening of non-primary working copies (they are closed when they are discarded and should not be reopened)
137 if (!isPrimary() && getPerWorkingCopyInfo() == null) {
138 throw newNotPresentException();
141 CompilationUnitElementInfo unitInfo = (CompilationUnitElementInfo) info;
143 // get buffer contents
144 IBuffer buffer = getBufferManager().getBuffer(CompilationUnit.this);
145 if (buffer == null) {
146 buffer = openBuffer(pm, unitInfo); // open buffer independently from the info, since we are building the info
148 final char[] contents = buffer == null ? null : buffer.getCharacters();
150 // generate structure and compute syntax problems if needed
151 CompilationUnitStructureRequestor requestor = new CompilationUnitStructureRequestor(this, unitInfo, newElements);
152 JavaModelManager.PerWorkingCopyInfo perWorkingCopyInfo = getPerWorkingCopyInfo();
153 IJavaProject project = getJavaProject();
154 boolean computeProblems = JavaProject.hasJavaNature(project.getProject()) && perWorkingCopyInfo != null && perWorkingCopyInfo.isActive();
155 IProblemFactory problemFactory = new DefaultProblemFactory();
156 Map options = project.getOptions(true);
157 SourceElementParser parser = new SourceElementParser(
160 new CompilerOptions(options));
161 //, true/*report local declarations*/);
162 requestor.parser = parser;
163 CompilationUnitDeclaration unit = parser.parseCompilationUnit(new net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit() {
164 public char[] getContents() {
167 public char[] getMainTypeName() {
168 return CompilationUnit.this.getMainTypeName();
170 public char[][] getPackageName() {
171 return CompilationUnit.this.getPackageName();
173 public char[] getFileName() {
174 return CompilationUnit.this.getFileName();
176 }, true /*full parse to find local elements*/);
178 // update timestamp (might be IResource.NULL_STAMP if original does not exist)
179 if (underlyingResource == null) {
180 underlyingResource = getResource();
182 unitInfo.timestamp = ((IFile)underlyingResource).getModificationStamp();
184 // compute other problems if needed
185 CompilationUnitDeclaration compilationUnitDeclaration = null;
187 if (computeProblems){
188 perWorkingCopyInfo.beginReporting();
189 compilationUnitDeclaration = CompilationUnitProblemFinder.process(unit, this, contents, parser, this.owner, perWorkingCopyInfo, problemFactory, false/*don't cleanup cu*/, pm);
190 perWorkingCopyInfo.endReporting();
193 // if (info instanceof ASTHolderCUInfo) {
194 // int astLevel = ((ASTHolderCUInfo) info).astLevel;
195 // org.eclipse.jdt.core.dom.CompilationUnit cu = AST.convertCompilationUnit(astLevel, unit, contents, options, pm);
196 // ((ASTHolderCUInfo) info).ast = cu;
199 if (compilationUnitDeclaration != null) {
200 compilationUnitDeclaration.cleanUp();
204 return unitInfo.isStructureKnown();
207 // * @see ICodeAssist#codeComplete(int, ICompletionRequestor)
209 //public void codeComplete(int offset, ICompletionRequestor requestor) throws JavaModelException {
210 // codeComplete(this, isWorkingCopy() ? (org.eclipse.jdt.internal.compiler.env.ICompilationUnit) getOriginalElement() : this, offset, requestor);
213 * @see ICodeAssist#codeSelect(int, int)
215 //public IJavaElement[] codeSelect(int offset, int length) throws JavaModelException {
216 // return super.codeSelect(this, offset, length);
219 * @see IWorkingCopy#commit(boolean, IProgressMonitor)
221 public void commit(boolean force, IProgressMonitor monitor) throws JavaModelException {
222 throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, this));
225 * @see ICompilationUnit#commitWorkingCopy(boolean, IProgressMonitor)
227 public void commitWorkingCopy(boolean force, IProgressMonitor monitor) throws JavaModelException {
228 CommitWorkingCopyOperation op= new CommitWorkingCopyOperation(this, force);
229 op.runOperation(monitor);
232 * @see ISourceManipulation#copy(IJavaElement, IJavaElement, String, boolean, IProgressMonitor)
234 public void copy(IJavaElement container, IJavaElement sibling, String rename, boolean force, IProgressMonitor monitor) throws JavaModelException {
235 if (container == null) {
236 throw new IllegalArgumentException(Util.bind("operation.nullContainer")); //$NON-NLS-1$
238 IJavaElement[] elements = new IJavaElement[] {this};
239 IJavaElement[] containers = new IJavaElement[] {container};
240 String[] renamings = null;
241 if (rename != null) {
242 renamings = new String[] {rename};
244 getJavaModel().copy(elements, containers, null, renamings, force, monitor);
248 * Returns a new element info for this element.
250 protected Object createElementInfo() {
251 return new CompilationUnitElementInfo();
254 // * @see ICompilationUnit#createImport(String, IJavaElement, IProgressMonitor)
256 //public IImportDeclaration createImport(String name, IJavaElement sibling, IProgressMonitor monitor) throws JavaModelException {
257 // CreateImportOperation op = new CreateImportOperation(name, this);
258 // if (sibling != null) {
259 // op.createBefore(sibling);
261 // runOperation(op, monitor);
262 // return getImport(name);
265 * @see ICompilationUnit#createPackageDeclaration(String, IProgressMonitor)
267 public IPackageDeclaration createPackageDeclaration(String name, IProgressMonitor monitor) throws JavaModelException {
269 CreatePackageDeclarationOperation op= new CreatePackageDeclarationOperation(name, this);
270 runOperation(op, monitor);
271 return getPackageDeclaration(name);
274 // * @see ICompilationUnit#createType(String, IJavaElement, boolean, IProgressMonitor)
276 //public IType createType(String content, IJavaElement sibling, boolean force, IProgressMonitor monitor) throws JavaModelException {
278 // //autogenerate this compilation unit
279 // IPackageFragment pkg = (IPackageFragment) getParent();
280 // String source = ""; //$NON-NLS-1$
281 // if (pkg.getElementName().length() > 0) {
282 // //not the default package...add the package declaration
283 // source = "package " + pkg.getElementName() + ";" + org.eclipse.jdt.internal.compiler.util.Util.LINE_SEPARATOR + org.eclipse.jdt.internal.compiler.util.Util.LINE_SEPARATOR; //$NON-NLS-1$ //$NON-NLS-2$
285 // CreateCompilationUnitOperation op = new CreateCompilationUnitOperation(pkg, fName, source, force);
286 // runOperation(op, monitor);
288 // CreateTypeOperation op = new CreateTypeOperation(this, content, force);
289 // if (sibling != null) {
290 // op.createBefore(sibling);
292 // runOperation(op, monitor);
293 // return (IType) op.getResultElements()[0];
296 * @see ISourceManipulation#delete(boolean, IProgressMonitor)
298 public void delete(boolean force, IProgressMonitor monitor) throws JavaModelException {
299 IJavaElement[] elements= new IJavaElement[] {this};
300 getJavaModel().delete(elements, force, monitor);
303 * @see IWorkingCopy#destroy()
306 public void destroy() {
308 discardWorkingCopy();
309 } catch (JavaModelException e) {
314 * @see ICompilationUnit#discardWorkingCopy
316 public void discardWorkingCopy() throws JavaModelException {
317 // discard working copy and its children
318 DiscardWorkingCopyOperation op = new DiscardWorkingCopyOperation(this);
319 op.runOperation(null);
323 * Returns true if this handle represents the same Java element
324 * as the given handle.
326 * @see Object#equals(java.lang.Object)
328 public boolean equals(Object obj) {
329 if (!(obj instanceof CompilationUnit)) return false;
330 CompilationUnit other = (CompilationUnit)obj;
331 return this.owner.equals(other.owner) && super.equals(obj);
334 * @see JavaElement#equalsDOMNode(IDOMNode)
336 protected boolean equalsDOMNode(IDOMNode node) throws JavaModelException {
337 String name = getElementName();
338 if (node.getNodeType() == IDOMNode.COMPILATION_UNIT && name != null ) {
339 String nodeName = node.getName();
340 if (nodeName == null) return false;
341 if (name.equals(nodeName)) {
344 // iterate through all the types inside the receiver and see if one of them can fit
345 IType[] types = getTypes();
346 String typeNodeName = nodeName.substring(0, nodeName.indexOf(".java")); //$NON-NLS-1$
347 for (int i = 0, max = types.length; i < max; i++) {
348 if (types[i].getElementName().equals(typeNodeName)) {
357 * @see IWorkingCopy#findElements(IJavaElement)
359 public IJavaElement[] findElements(IJavaElement element) {
360 ArrayList children = new ArrayList();
361 while (element != null && element.getElementType() != IJavaElement.COMPILATION_UNIT) {
362 children.add(element);
363 element = element.getParent();
365 if (element == null) return null;
366 IJavaElement currentElement = this;
367 for (int i = children.size()-1; i >= 0; i--) {
368 IJavaElement child = (IJavaElement)children.get(i);
369 switch (child.getElementType()) {
370 // case IJavaElement.PACKAGE_DECLARATION:
371 // currentElement = ((ICompilationUnit)currentElement).getPackageDeclaration(child.getElementName());
373 // case IJavaElement.IMPORT_CONTAINER:
374 // currentElement = ((ICompilationUnit)currentElement).getImportContainer();
376 // case IJavaElement.IMPORT_DECLARATION:
377 // currentElement = ((IImportContainer)currentElement).getImport(child.getElementName());
379 case IJavaElement.TYPE:
380 if (currentElement.getElementType() == IJavaElement.COMPILATION_UNIT) {
381 currentElement = ((ICompilationUnit)currentElement).getType(child.getElementName());
383 currentElement = ((IType)currentElement).getType(child.getElementName());
386 // case IJavaElement.INITIALIZER:
387 // currentElement = ((IType)currentElement).getInitializer(((JavaElement)child).getOccurrenceCount());
389 case IJavaElement.FIELD:
390 currentElement = ((IType)currentElement).getField(child.getElementName());
392 case IJavaElement.METHOD:
393 return ((IType)currentElement).findMethods((IMethod)child);
397 if (currentElement != null && currentElement.exists()) {
398 return new IJavaElement[] {currentElement};
404 * @see IWorkingCopy#findPrimaryType()
406 public IType findPrimaryType() {
407 String typeName = Signature.getQualifier(this.getElementName());
408 IType primaryType= this.getType(typeName);
409 if (primaryType.exists()) {
415 * @see IWorkingCopy#findSharedWorkingCopy(IBufferFactory)
418 public IJavaElement findSharedWorkingCopy(IBufferFactory factory) {
420 // if factory is null, default factory must be used
421 if (factory == null) factory = this.getBufferManager().getDefaultBufferFactory();
423 return findWorkingCopy(BufferFactoryWrapper.create(factory));
427 * @see ICompilationUnit#findWorkingCopy(WorkingCopyOwner)
429 public ICompilationUnit findWorkingCopy(WorkingCopyOwner workingCopyOwner) {
430 CompilationUnit cu = new CompilationUnit((PackageFragment)this.parent, getElementName(), workingCopyOwner);
431 if (workingCopyOwner == DefaultWorkingCopyOwner.PRIMARY) {
434 // must be a working copy
435 JavaModelManager.PerWorkingCopyInfo perWorkingCopyInfo = cu.getPerWorkingCopyInfo();
436 if (perWorkingCopyInfo != null) {
437 return perWorkingCopyInfo.getWorkingCopy();
443 protected boolean generateInfos(OpenableElementInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) throws JavaModelException {
445 // if (getParent() instanceof JarPackageFragment) {
446 // // ignore .java files in jar
447 // throw newNotPresentException();
449 // put the info now, because getting the contents requires it
450 JavaModelManager.getJavaModelManager().putInfo(this, info);
451 CompilationUnitElementInfo unitInfo = (CompilationUnitElementInfo) info;
453 // generate structure
454 CompilationUnitStructureRequestor requestor = new CompilationUnitStructureRequestor(this, unitInfo, newElements);
455 IProblemFactory factory = new DefaultProblemFactory();
456 SourceElementParser parser = new SourceElementParser(requestor, factory, new CompilerOptions(getJavaProject().getOptions(true)));
457 // SourceElementParser parser = new SourceElementParser(requestor, factory);
458 requestor.parser = parser;
459 parser.parseCompilationUnit(this, false);
460 if (isWorkingCopy()) {
461 CompilationUnit original = (CompilationUnit) getOriginalElement();
462 // might be IResource.NULL_STAMP if original does not exist
463 unitInfo.timestamp = ((IFile) original.getResource()).getModificationStamp();
465 return unitInfo.isStructureKnown();
469 * @see ICompilationUnit#getAllTypes()
471 public IType[] getAllTypes() throws JavaModelException {
472 IJavaElement[] types = getTypes();
474 ArrayList allTypes = new ArrayList(types.length);
475 ArrayList typesToTraverse = new ArrayList(types.length);
476 for (i = 0; i < types.length; i++) {
477 typesToTraverse.add(types[i]);
479 while (!typesToTraverse.isEmpty()) {
480 IType type = (IType) typesToTraverse.get(0);
481 typesToTraverse.remove(type);
483 types = type.getTypes();
484 for (i = 0; i < types.length; i++) {
485 typesToTraverse.add(types[i]);
488 IType[] arrayOfAllTypes = new IType[allTypes.size()];
489 allTypes.toArray(arrayOfAllTypes);
490 return arrayOfAllTypes;
493 * @see IMember#getCompilationUnit()
495 public ICompilationUnit getCompilationUnit() {
499 * @see org.eclipse.jdt.internal.compiler.env.ICompilationUnit#getContents()
501 public char[] getContents() {
503 IBuffer buffer = this.getBuffer();
504 return buffer == null ? null : buffer.getCharacters();
505 } catch (JavaModelException e) {
506 return CharOperation.NO_CHAR;
510 * A compilation unit has a corresponding resource unless it is contained
513 * @see IJavaElement#getCorrespondingResource()
515 public IResource getCorrespondingResource() throws JavaModelException {
516 IPackageFragmentRoot root= (IPackageFragmentRoot)getParent().getParent();
517 if (root.isArchive()) {
520 return getUnderlyingResource();
524 * @see ICompilationUnit#getElementAt(int)
526 public IJavaElement getElementAt(int position) throws JavaModelException {
528 IJavaElement e= getSourceElementAt(position);
538 public int getElementType() {
539 return COMPILATION_UNIT;
541 public char[] getFileName(){
542 return getElementName().toCharArray();
545 * @see JavaElement#getHandleMementoDelimiter()
547 protected char getHandleMementoDelimiter() {
548 return JavaElement.JEM_COMPILATIONUNIT;
551 * @see ICompilationUnit#getImport(String)
553 public IImportDeclaration getImport(String importName) {
554 return new ImportDeclaration((ImportContainer)getImportContainer(), importName);
558 * @see ICompilationUnit#getImportContainer()
560 public ImportContainer getImportContainer() {
561 return new ImportContainer(this);
566 * @see ICompilationUnit#getImports()
568 //public IImportDeclaration[] getImports() throws JavaModelException {
569 // IImportContainer container= getImportContainer();
570 // if (container.exists()) {
571 // IJavaElement[] elements= container.getChildren();
572 // IImportDeclaration[] imprts= new IImportDeclaration[elements.length];
573 // System.arraycopy(elements, 0, imprts, 0, elements.length);
575 // } else if (!exists()) {
576 // throw newNotPresentException();
578 // return new IImportDeclaration[0];
583 * @see org.eclipse.jdt.internal.compiler.env.ICompilationUnit#getMainTypeName()
585 public char[] getMainTypeName(){
586 String name= getElementName();
588 name= name.substring(0, name.length() - 5);
589 return name.toCharArray();
593 * @see IWorkingCopy#getOriginal(IJavaElement)
596 public IJavaElement getOriginal(IJavaElement workingCopyElement) {
597 // backward compatibility
598 if (!isWorkingCopy()) return null;
599 CompilationUnit cu = (CompilationUnit)workingCopyElement.getAncestor(COMPILATION_UNIT);
600 if (cu == null || !this.owner.equals(cu.owner)) {
604 return workingCopyElement.getPrimaryElement();
607 * @see IWorkingCopy#getOriginalElement()
610 public IJavaElement getOriginalElement() {
611 // backward compatibility
612 if (!isWorkingCopy()) return null;
614 return getPrimaryElement();
617 * @see ICompilationUnit#getOwner()
619 public WorkingCopyOwner getOwner() {
620 return isPrimary() || !isWorkingCopy() ? null : this.owner;
623 * @see ICompilationUnit#getPackageDeclaration(String)
625 public IPackageDeclaration getPackageDeclaration(String name) {
626 return new PackageDeclaration(this, name);
629 * @see ICompilationUnit#getPackageDeclarations()
631 public IPackageDeclaration[] getPackageDeclarations() throws JavaModelException {
632 ArrayList list = getChildrenOfType(PACKAGE_DECLARATION);
633 IPackageDeclaration[] array= new IPackageDeclaration[list.size()];
638 * @see org.eclipse.jdt.internal.compiler.env.ICompilationUnit#getPackageName()
640 public char[][] getPackageName() {
644 * @see IJavaElement#getPath()
646 public IPath getPath() {
647 PackageFragmentRoot root = this.getPackageFragmentRoot();
648 if (root.isArchive()) {
649 return root.getPath();
651 return this.getParent().getPath().append(this.getElementName());
655 * Returns the per working copy info for the receiver, or null if none exist.
656 * Note: the use count of the per working copy info is NOT incremented.
658 public JavaModelManager.PerWorkingCopyInfo getPerWorkingCopyInfo() {
659 return JavaModelManager.getJavaModelManager().getPerWorkingCopyInfo(this, false/*don't create*/, false/*don't record usage*/, null/*no problem requestor needed*/);
662 * @see ICompilationUnit#getPrimary()
664 public ICompilationUnit getPrimary() {
665 return (ICompilationUnit)getPrimaryElement(true);
668 * @see JavaElement#getPrimaryElement(boolean)
670 public IJavaElement getPrimaryElement(boolean checkOwner) {
671 if (checkOwner && isPrimary()) return this;
672 return new CompilationUnit((PackageFragment)getParent(), getElementName(), DefaultWorkingCopyOwner.PRIMARY);
676 * @see IJavaElement#getResource()
678 public IResource getResource() {
679 PackageFragmentRoot root = this.getPackageFragmentRoot();
680 if (root.isArchive()) {
681 return root.getResource();
683 return ((IContainer)this.getParent().getResource()).getFile(new Path(this.getElementName()));
688 * @see ISourceReference#getSource()
690 public String getSource() throws JavaModelException {
691 IBuffer buffer = getBuffer();
692 if (buffer == null) return ""; //$NON-NLS-1$
693 return buffer.getContents();
696 * @see ISourceReference#getSourceRange()
698 public ISourceRange getSourceRange() throws JavaModelException {
699 return ((CompilationUnitElementInfo) getElementInfo()).getSourceRange();
702 * @see ICompilationUnit#getType(String)
704 public IType getType(String name) {
705 return new SourceType(this, name);
708 * @see ICompilationUnit#getTypes()
710 public IType[] getTypes() throws JavaModelException {
711 ArrayList list = getChildrenOfType(TYPE);
712 IType[] array= new IType[list.size()];
719 public IResource getUnderlyingResource() throws JavaModelException {
720 if (isWorkingCopy() && !isPrimary()) return null;
721 return super.getUnderlyingResource();
724 // * @see IWorkingCopy#getSharedWorkingCopy(IProgressMonitor, IBufferFactory, IProblemRequestor)
726 //public IJavaElement getSharedWorkingCopy(IProgressMonitor pm, IBufferFactory factory, IProblemRequestor problemRequestor) throws JavaModelException {
728 // // if factory is null, default factory must be used
729 // if (factory == null) factory = this.getBufferManager().getDefaultBufferFactory();
731 // JavaModelManager manager = JavaModelManager.getJavaModelManager();
733 // // In order to be shared, working copies have to denote the same compilation unit
734 // // AND use the same buffer factory.
735 // // Assuming there is a little set of buffer factories, then use a 2 level Map cache.
736 // Map sharedWorkingCopies = manager.sharedWorkingCopies;
738 // Map perFactoryWorkingCopies = (Map) sharedWorkingCopies.get(factory);
739 // if (perFactoryWorkingCopies == null){
740 // perFactoryWorkingCopies = new HashMap();
741 // sharedWorkingCopies.put(factory, perFactoryWorkingCopies);
743 // WorkingCopy workingCopy = (WorkingCopy)perFactoryWorkingCopies.get(this);
744 // if (workingCopy != null) {
745 // workingCopy.useCount++;
747 // if (SHARED_WC_VERBOSE) {
748 // System.out.println("Incrementing use count of shared working copy " + workingCopy.toStringWithAncestors()); //$NON-NLS-1$
751 // return workingCopy;
753 // CreateWorkingCopyOperation op = new CreateWorkingCopyOperation(this, perFactoryWorkingCopies, factory, problemRequestor);
754 // runOperation(op, pm);
755 // return op.getResultElements()[0];
759 // * @see IWorkingCopy#getWorkingCopy()
761 //public IJavaElement getWorkingCopy() throws JavaModelException {
762 // return this.getWorkingCopy(null, null, null);
766 // * @see IWorkingCopy#getWorkingCopy(IProgressMonitor, IBufferFactory, IProblemRequestor)
768 //public IJavaElement getWorkingCopy(IProgressMonitor pm, IBufferFactory factory, IProblemRequestor problemRequestor) throws JavaModelException {
769 // CreateWorkingCopyOperation op = new CreateWorkingCopyOperation(this, null, factory, problemRequestor);
770 // runOperation(op, pm);
771 // return op.getResultElements()[0];
774 * @see IWorkingCopy#getSharedWorkingCopy(IProgressMonitor, IBufferFactory, IProblemRequestor)
777 public IJavaElement getSharedWorkingCopy(IProgressMonitor pm, IBufferFactory factory, IProblemRequestor problemRequestor) throws JavaModelException {
779 // if factory is null, default factory must be used
780 if (factory == null) factory = this.getBufferManager().getDefaultBufferFactory();
782 return getWorkingCopy(BufferFactoryWrapper.create(factory), problemRequestor, pm);
785 * @see IWorkingCopy#getWorkingCopy()
788 public IJavaElement getWorkingCopy() throws JavaModelException {
789 return getWorkingCopy(null);
792 * @see ICompilationUnit#getWorkingCopy(IProgressMonitor)
794 public ICompilationUnit getWorkingCopy(IProgressMonitor monitor) throws JavaModelException {
795 return getWorkingCopy(new WorkingCopyOwner() {/*non shared working copy*/}, null/*no problem requestor*/, monitor);
798 * @see IWorkingCopy#getWorkingCopy(IProgressMonitor, IBufferFactory, IProblemRequestor)
801 public IJavaElement getWorkingCopy(IProgressMonitor monitor, IBufferFactory factory, IProblemRequestor problemRequestor) throws JavaModelException {
802 return getWorkingCopy(BufferFactoryWrapper.create(factory), problemRequestor, monitor);
805 * @see ICompilationUnit#getWorkingCopy(WorkingCopyOwner, IProblemRequestor, IProgressMonitor)
807 public ICompilationUnit getWorkingCopy(WorkingCopyOwner workingCopyOwner, IProblemRequestor problemRequestor, IProgressMonitor monitor) throws JavaModelException {
808 if (!isPrimary()) return this;
810 JavaModelManager manager = JavaModelManager.getJavaModelManager();
812 CompilationUnit workingCopy = new CompilationUnit((PackageFragment)getParent(), getElementName(), workingCopyOwner);
813 JavaModelManager.PerWorkingCopyInfo perWorkingCopyInfo =
814 manager.getPerWorkingCopyInfo(workingCopy, false/*don't create*/, true/*record usage*/, null/*not used since don't create*/);
815 if (perWorkingCopyInfo != null) {
816 return perWorkingCopyInfo.getWorkingCopy(); // return existing handle instead of the one created above
818 BecomeWorkingCopyOperation op = new BecomeWorkingCopyOperation(workingCopy, problemRequestor);
819 op.runOperation(monitor);
824 * If I am not open, return true to avoid parsing.
826 * @see IParent#hasChildren()
828 public boolean hasChildren() throws JavaModelException {
830 // return getChildren().length > 0;
837 * @see Openable#hasBuffer()
839 protected boolean hasBuffer() {
843 * @see ICompilationUnit#hasResourceChanged()
845 public boolean hasResourceChanged() {
846 if (!isWorkingCopy()) return false;
848 // if resource got deleted, then #getModificationStamp() will answer IResource.NULL_STAMP, which is always different from the cached
850 Object info = JavaModelManager.getJavaModelManager().getInfo(this);
851 if (info == null) return false;
852 return ((CompilationUnitElementInfo)info).timestamp != getResource().getModificationStamp();
855 * @see IWorkingCopy#isBasedOn(IResource)
858 public boolean isBasedOn(IResource resource) {
859 if (!isWorkingCopy()) return false;
860 if (!getResource().equals(resource)) return false;
861 return !hasResourceChanged();
864 * @see IOpenable#isConsistent()
866 public boolean isConsistent() {
867 return JavaModelManager.getJavaModelManager().getElementsOutOfSynchWithBuffers().get(this) == null;
874 public boolean isOpen() {
875 Object info = JavaModelManager.getJavaModelManager().getInfo(this);
876 return info != null && ((CompilationUnitElementInfo)info).isOpen();
878 public boolean isPrimary() {
879 return this.owner == DefaultWorkingCopyOwner.PRIMARY;
882 * @see Openable#isSourceElement()
884 protected boolean isSourceElement() {
887 protected boolean isValidCompilationUnit() {
888 IPackageFragmentRoot root = getPackageFragmentRoot();
890 if (root.getKind() != IPackageFragmentRoot.K_SOURCE) return false;
891 } catch (JavaModelException e) {
894 // IResource resource = getResource();
895 // if (resource != null) {
896 // char[][] inclusionPatterns = ((PackageFragmentRoot)root).fullInclusionPatternChars();
897 // char[][] exclusionPatterns = ((PackageFragmentRoot)root).fullExclusionPatternChars();
898 // if (Util.isExcluded(resource, inclusionPatterns, exclusionPatterns)) return false;
900 if (!Util.isValidCompilationUnitName(getElementName())) return false;
904 * @see ICompilationUnit#isWorkingCopy()
906 public boolean isWorkingCopy() {
907 // For backward compatibility, non primary working copies are always returning true; in removal
908 // delta, clients can still check that element was a working copy before being discarded.
909 return !isPrimary() || getPerWorkingCopyInfo() != null;
912 * @see IOpenable#makeConsistent(IProgressMonitor)
914 public void makeConsistent(IProgressMonitor monitor) throws JavaModelException {
915 makeConsistent(false/*don't create AST*/, 0, monitor);
917 public Object makeConsistent(boolean createAST, int astLevel, IProgressMonitor monitor) throws JavaModelException {
918 if (isConsistent()) return null;
920 // create a new info and make it the current info
921 // (this will remove the info and its children just before storing the new infos)
923 // ASTHolderCUInfo info = new ASTHolderCUInfo();
924 // info.astLevel = astLevel;
925 // openWhenClosed(info, monitor);
926 // org.eclipse.jdt.core.dom.CompilationUnit result = info.ast;
930 openWhenClosed(createElementInfo(), monitor);
934 //public net.sourceforge.phpdt.core.dom.CompilationUnit makeConsistent(boolean createAST, int astLevel, IProgressMonitor monitor) throws JavaModelException {
935 // if (isConsistent()) return null;
937 // // create a new info and make it the current info
938 // // (this will remove the info and its children just before storing the new infos)
940 // ASTHolderCUInfo info = new ASTHolderCUInfo();
941 // info.astLevel = astLevel;
942 // openWhenClosed(info, monitor);
943 // net.sourceforge.phpdt.core.dom.CompilationUnit result = info.ast;
947 // openWhenClosed(createElementInfo(), monitor);
953 * @see ISourceManipulation#move(IJavaElement, IJavaElement, String, boolean, IProgressMonitor)
955 public void move(IJavaElement container, IJavaElement sibling, String rename, boolean force, IProgressMonitor monitor) throws JavaModelException {
956 if (container == null) {
957 throw new IllegalArgumentException(Util.bind("operation.nullContainer")); //$NON-NLS-1$
959 IJavaElement[] elements= new IJavaElement[] {this};
960 IJavaElement[] containers= new IJavaElement[] {container};
962 String[] renamings= null;
963 if (rename != null) {
964 renamings= new String[] {rename};
966 getJavaModel().move(elements, containers, null, renamings, force, monitor);
970 // * @see Openable#openBuffer(IProgressMonitor)
972 //protected IBuffer openBuffer(IProgressMonitor pm) throws JavaModelException {
974 // // create buffer - compilation units only use default buffer factory
975 // BufferManager bufManager = getBufferManager();
976 // IBuffer buffer = getBufferFactory().createBuffer(this);
977 // if (buffer == null) return null;
979 // // set the buffer source
980 // if (buffer.getCharacters() == null){
981 // IFile file = (IFile)this.getResource();
982 // if (file == null || !file.exists()) throw newNotPresentException();
983 // buffer.setContents(Util.getResourceContentsAsCharArray(file));
986 // // add buffer to buffer cache
987 // bufManager.addBuffer(buffer);
989 // // listen to buffer changes
990 // buffer.addBufferChangedListener(this);
995 * @see Openable#openBuffer(IProgressMonitor, Object)
997 protected IBuffer openBuffer(IProgressMonitor pm, Object info) throws JavaModelException {
1000 boolean isWorkingCopy = isWorkingCopy();
1003 ? this.owner.createBuffer(this)
1004 : BufferManager.getDefaultBufferManager().createBuffer(this);
1005 if (buffer == null) return null;
1007 // set the buffer source
1008 if (buffer.getCharacters() == null) {
1009 if (isWorkingCopy) {
1010 ICompilationUnit original;
1012 && (original = new CompilationUnit((PackageFragment)getParent(), getElementName(), DefaultWorkingCopyOwner.PRIMARY)).isOpen()) {
1013 buffer.setContents(original.getSource());
1015 IFile file = (IFile)getResource();
1016 if (file == null || !file.exists()) {
1017 // initialize buffer with empty contents
1018 buffer.setContents(CharOperation.NO_CHAR);
1020 buffer.setContents(Util.getResourceContentsAsCharArray(file));
1024 IFile file = (IFile)this.getResource();
1025 if (file == null || !file.exists()) throw newNotPresentException();
1026 buffer.setContents(Util.getResourceContentsAsCharArray(file));
1030 // add buffer to buffer cache
1031 BufferManager bufManager = getBufferManager();
1032 bufManager.addBuffer(buffer);
1034 // listen to buffer changes
1035 buffer.addBufferChangedListener(this);
1040 * @see Openable#openParent
1042 protected void openParent(Object childInfo, HashMap newElements, IProgressMonitor pm) throws JavaModelException {
1044 super.openParent(childInfo, newElements, pm);
1045 } catch(JavaModelException e){
1046 // allow parent to not exist for working copies defined outside classpath
1047 if (!isWorkingCopy() && !e.isDoesNotExist()){
1054 * @see ICompilationUnit#reconcile()
1057 public IMarker[] reconcile() throws JavaModelException {
1058 reconcile(NO_AST, false/*don't force problem detection*/, null/*use primary owner*/, null/*no progress monitor*/);
1062 * @see ICompilationUnit#reconcile(int, boolean, WorkingCopyOwner, IProgressMonitor)
1064 public void reconcile(boolean forceProblemDetection, IProgressMonitor monitor) throws JavaModelException {
1065 reconcile(NO_AST, forceProblemDetection, null/*use primary owner*/, monitor);
1069 * @see ICompilationUnit#reconcile(int, boolean, WorkingCopyOwner, IProgressMonitor)
1072 //public org.eclipse.jdt.core.dom.CompilationUnit reconcile(
1073 public Object reconcile(
1075 boolean forceProblemDetection,
1076 WorkingCopyOwner workingCopyOwner,
1077 IProgressMonitor monitor)
1078 throws JavaModelException {
1080 if (!isWorkingCopy()) return null; // Reconciling is not supported on non working copies
1081 if (workingCopyOwner == null) workingCopyOwner = DefaultWorkingCopyOwner.PRIMARY;
1083 boolean createAST = false;
1084 // if (astLevel == AST.JLS2) {
1085 // // client asking for level 2 AST; these are supported
1086 // createAST = true;
1087 // } else if (astLevel == AST.JLS3) {
1088 // // client asking for level 3 ASTs; these are not supported
1089 // // TODO (jerome) - these should also be supported in 1.5 stream
1090 // createAST = false;
1092 // // client asking for no AST (0) or unknown ast level
1093 // // either way, request denied
1094 // createAST = false;
1096 ReconcileWorkingCopyOperation op = new ReconcileWorkingCopyOperation(this, createAST, astLevel, forceProblemDetection, workingCopyOwner);
1097 op.runOperation(monitor);
1103 * @see ISourceManipulation#rename(String, boolean, IProgressMonitor)
1105 public void rename(String name, boolean force, IProgressMonitor monitor) throws JavaModelException {
1107 throw new IllegalArgumentException(Util.bind("operation.nullName")); //$NON-NLS-1$
1109 IJavaElement[] elements= new IJavaElement[] {this};
1110 IJavaElement[] dests= new IJavaElement[] {this.getParent()};
1111 String[] renamings= new String[] {name};
1112 getJavaModel().rename(elements, dests, renamings, force, monitor);
1115 * Does nothing - this is not a working copy.
1117 * @see IWorkingCopy#restore()
1119 public void restore () throws JavaModelException {
1122 * @see ICodeAssist#codeComplete(int, ICodeCompletionRequestor)
1123 * @deprecated - use codeComplete(int, ICompletionRequestor)
1125 //public void codeComplete(int offset, final ICodeCompletionRequestor requestor) throws JavaModelException {
1127 // if (requestor == null){
1128 // codeComplete(offset, (ICompletionRequestor)null);
1133 // new ICompletionRequestor(){
1134 // public void acceptAnonymousType(char[] superTypePackageName,char[] superTypeName,char[][] parameterPackageNames,char[][] parameterTypeNames,char[][] parameterNames,char[] completionName,int modifiers,int completionStart,int completionEnd, int relevance){
1136 // public void acceptClass(char[] packageName, char[] className, char[] completionName, int modifiers, int completionStart, int completionEnd, int relevance) {
1137 // requestor.acceptClass(packageName, className, completionName, modifiers, completionStart, completionEnd);
1139 // public void acceptError(IProblem error) {
1140 // if (true) return; // was disabled in 1.0
1143 // IMarker marker = ResourcesPlugin.getWorkspace().getRoot().createMarker(IJavaModelMarker.TRANSIENT_PROBLEM);
1144 // marker.setAttribute(IJavaModelMarker.ID, error.getID());
1145 // marker.setAttribute(IMarker.CHAR_START, error.getSourceStart());
1146 // marker.setAttribute(IMarker.CHAR_END, error.getSourceEnd() + 1);
1147 // marker.setAttribute(IMarker.LINE_NUMBER, error.getSourceLineNumber());
1148 // marker.setAttribute(IMarker.MESSAGE, error.getMessage());
1149 // marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
1150 // requestor.acceptError(marker);
1151 // } catch(CoreException e){
1154 // public void acceptField(char[] declaringTypePackageName, char[] declaringTypeName, char[] name, char[] typePackageName, char[] typeName, char[] completionName, int modifiers, int completionStart, int completionEnd, int relevance) {
1155 // requestor.acceptField(declaringTypePackageName, declaringTypeName, name, typePackageName, typeName, completionName, modifiers, completionStart, completionEnd);
1157 // public void acceptInterface(char[] packageName,char[] interfaceName,char[] completionName,int modifiers,int completionStart,int completionEnd, int relevance) {
1158 // requestor.acceptInterface(packageName, interfaceName, completionName, modifiers, completionStart, completionEnd);
1160 // public void acceptKeyword(char[] keywordName,int completionStart,int completionEnd, int relevance){
1161 // requestor.acceptKeyword(keywordName, completionStart, completionEnd);
1163 // public void acceptLabel(char[] labelName,int completionStart,int completionEnd, int relevance){
1164 // requestor.acceptLabel(labelName, completionStart, completionEnd);
1166 // public void acceptLocalVariable(char[] name,char[] typePackageName,char[] typeName,int modifiers,int completionStart,int completionEnd, int relevance){
1169 // public void acceptMethod(char[] declaringTypePackageName,char[] declaringTypeName,char[] selector,char[][] parameterPackageNames,char[][] parameterTypeNames,char[][] parameterNames,char[] returnTypePackageName,char[] returnTypeName,char[] completionName,int modifiers,int completionStart,int completionEnd, int relevance){
1170 // // skip parameter names
1171 // requestor.acceptMethod(declaringTypePackageName, declaringTypeName, selector, parameterPackageNames, parameterTypeNames, returnTypePackageName, returnTypeName, completionName, modifiers, completionStart, completionEnd);
1173 // public void acceptMethodDeclaration(char[] declaringTypePackageName,char[] declaringTypeName,char[] selector,char[][] parameterPackageNames,char[][] parameterTypeNames,char[][] parameterNames,char[] returnTypePackageName,char[] returnTypeName,char[] completionName,int modifiers,int completionStart,int completionEnd, int relevance){
1176 // public void acceptModifier(char[] modifierName,int completionStart,int completionEnd, int relevance){
1177 // requestor.acceptModifier(modifierName, completionStart, completionEnd);
1179 // public void acceptPackage(char[] packageName,char[] completionName,int completionStart,int completionEnd, int relevance){
1180 // requestor.acceptPackage(packageName, completionName, completionStart, completionEnd);
1182 // public void acceptType(char[] packageName,char[] typeName,char[] completionName,int completionStart,int completionEnd, int relevance){
1183 // requestor.acceptType(packageName, typeName, completionName, completionStart, completionEnd);
1185 // public void acceptVariableName(char[] typePackageName,char[] typeName,char[] name,char[] completionName,int completionStart,int completionEnd, int relevance){
1191 // * @see JavaElement#rootedAt(IJavaProject)
1193 //public IJavaElement rootedAt(IJavaProject project) {
1195 // new CompilationUnit(
1196 // (IPackageFragment)((JavaElement)parent).rootedAt(project),
1200 * Assume that this is a working copy
1202 protected void updateTimeStamp(CompilationUnit original) throws JavaModelException {
1204 ((IFile) original.getResource()).getModificationStamp();
1205 if (timeStamp == IResource.NULL_STAMP) {
1206 throw new JavaModelException(
1207 new JavaModelStatus(IJavaModelStatusConstants.INVALID_RESOURCE));
1209 ((CompilationUnitElementInfo) getElementInfo()).timestamp = timeStamp;