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.IJavaElement;
21 import net.sourceforge.phpdt.core.IJavaModelStatusConstants;
22 import net.sourceforge.phpdt.core.IJavaProject;
23 import net.sourceforge.phpdt.core.IMember;
24 import net.sourceforge.phpdt.core.IMethod;
25 import net.sourceforge.phpdt.core.IOpenable;
26 import net.sourceforge.phpdt.core.IPackageDeclaration;
27 import net.sourceforge.phpdt.core.IPackageFragment;
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;
55 import net.sourceforge.phpdt.internal.core.JavaModelManager;
56 //import net.sourceforge.phpdt.core.dom.AST;
57 import net.sourceforge.phpdt.internal.core.ReconcileWorkingCopyOperation;
59 import net.sourceforge.phpdt.internal.core.DiscardWorkingCopyOperation;
61 import net.sourceforge.phpdt.internal.core.CompilationUnitElementInfo;
62 import net.sourceforge.phpdt.internal.core.JavaModelStatus;
64 import net.sourceforge.phpdt.internal.core.BufferManager;
65 import net.sourceforge.phpdt.internal.core.DefaultWorkingCopyOwner;
66 import net.sourceforge.phpdt.internal.core.Openable;
68 import net.sourceforge.phpdt.internal.core.PackageFragment;
71 * @see ICompilationUnit
74 public class CompilationUnit extends Openable implements ICompilationUnit, net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit {
75 public WorkingCopyOwner owner;
78 * Constructs a handle to a compilation unit with the given name in the
79 * specified package for the specified owner
81 * @exception IllegalArgumentException if the name of the compilation unit
82 * does not end with ".java"
84 protected CompilationUnit(PackageFragment parent, String name, WorkingCopyOwner owner) {
89 * Accepts the given visitor onto the parsed tree of this compilation unit, after
90 * having runned the name resolution.
91 * The visitor's corresponding <code>visit</code> method is called with the
92 * corresponding parse tree. If the visitor returns <code>true</code>, this method
93 * visits this parse node's members.
95 * @param visitor the visitor
96 * @exception JavaModelException if this method fails. Reasons include:
98 * <li> This element does not exist.</li>
99 * <li> The visitor failed with this exception.</li>
102 //public void accept(IAbstractSyntaxTreeVisitor visitor) throws JavaModelException {
103 // CompilationUnitVisitor.visit(this, visitor);
106 * @see ICompilationUnit#becomeWorkingCopy(IProblemRequestor, IProgressMonitor)
108 public void becomeWorkingCopy(IProblemRequestor problemRequestor, IProgressMonitor monitor) throws JavaModelException {
109 JavaModelManager manager = JavaModelManager.getJavaModelManager();
110 JavaModelManager.PerWorkingCopyInfo perWorkingCopyInfo = manager.getPerWorkingCopyInfo(this, false/*don't create*/, true /*record usage*/, null/*no problem requestor needed*/);
111 if (perWorkingCopyInfo == null) {
112 // close cu and its children
115 BecomeWorkingCopyOperation operation = new BecomeWorkingCopyOperation(this, problemRequestor);
116 operation.runOperation(monitor);
119 //protected void buildStructure(OpenableElementInfo info, IProgressMonitor monitor) throws JavaModelException {
121 // if (monitor != null && monitor.isCanceled()) return;
123 // // remove existing (old) infos
126 // HashMap newElements = new HashMap(11);
127 // info.setIsStructureKnown(generateInfos(info, monitor, newElements, getResource()));
128 // JavaModelManager.getJavaModelManager().getElementsOutOfSynchWithBuffers().remove(this);
129 // for (Iterator iter = newElements.keySet().iterator(); iter.hasNext();) {
130 // IJavaElement key = (IJavaElement) iter.next();
131 // Object value = newElements.get(key);
132 // JavaModelManager.getJavaModelManager().putInfo(key, value);
134 // // add the info for this at the end, to ensure that a getInfo cannot reply null in case the LRU cache needs
135 // // to be flushed. Might lead to performance issues.
136 // // see PR 1G2K5S7: ITPJCORE:ALL - NPE when accessing source for a binary type
137 // JavaModelManager.getJavaModelManager().putInfo(this, info);
139 protected boolean buildStructure(OpenableElementInfo info, final IProgressMonitor pm, Map newElements, IResource underlyingResource) throws JavaModelException {
141 // check if this compilation unit can be opened
142 if (!isWorkingCopy()) { // no check is done on root kind or exclusion pattern for working copies
143 if ( // ((IPackageFragment)getParent()).getKind() == IPackageFragmentRoot.K_BINARY||
144 !isValidCompilationUnit()
145 || !underlyingResource.isAccessible()) {
146 throw newNotPresentException();
150 // prevents reopening of non-primary working copies (they are closed when they are discarded and should not be reopened)
151 if (!isPrimary() && getPerWorkingCopyInfo() == null) {
152 throw newNotPresentException();
155 CompilationUnitElementInfo unitInfo = (CompilationUnitElementInfo) info;
157 // get buffer contents
158 IBuffer buffer = getBufferManager().getBuffer(CompilationUnit.this);
159 if (buffer == null) {
160 buffer = openBuffer(pm, unitInfo); // open buffer independently from the info, since we are building the info
162 final char[] contents = buffer == null ? null : buffer.getCharacters();
164 // generate structure and compute syntax problems if needed
165 CompilationUnitStructureRequestor requestor = new CompilationUnitStructureRequestor(this, unitInfo, newElements);
166 JavaModelManager.PerWorkingCopyInfo perWorkingCopyInfo = getPerWorkingCopyInfo();
167 IJavaProject project = getJavaProject();
168 boolean computeProblems = JavaProject.hasJavaNature(project.getProject()) && perWorkingCopyInfo != null && perWorkingCopyInfo.isActive();
169 IProblemFactory problemFactory = new DefaultProblemFactory();
170 Map options = project.getOptions(true);
171 SourceElementParser parser = new SourceElementParser(
174 new CompilerOptions(options));
175 //, true/*report local declarations*/);
176 requestor.parser = parser;
177 CompilationUnitDeclaration unit = parser.parseCompilationUnit(new net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit() {
178 public char[] getContents() {
181 public char[] getMainTypeName() {
182 return CompilationUnit.this.getMainTypeName();
184 public char[][] getPackageName() {
185 return CompilationUnit.this.getPackageName();
187 public char[] getFileName() {
188 return CompilationUnit.this.getFileName();
190 }, true /*full parse to find local elements*/);
192 // update timestamp (might be IResource.NULL_STAMP if original does not exist)
193 if (underlyingResource == null) {
194 underlyingResource = getResource();
196 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, perWorkingCopyInfo, problemFactory, false/*don't cleanup cu*/, pm);
204 perWorkingCopyInfo.endReporting();
207 // if (info instanceof ASTHolderCUInfo) {
208 // int astLevel = ((ASTHolderCUInfo) info).astLevel;
209 // org.eclipse.jdt.core.dom.CompilationUnit cu = AST.convertCompilationUnit(astLevel, unit, contents, options, pm);
210 // ((ASTHolderCUInfo) info).ast = cu;
213 if (compilationUnitDeclaration != null) {
214 compilationUnitDeclaration.cleanUp();
218 return unitInfo.isStructureKnown();
221 // * @see ICodeAssist#codeComplete(int, ICompletionRequestor)
223 //public void codeComplete(int offset, ICompletionRequestor requestor) throws JavaModelException {
224 // codeComplete(this, isWorkingCopy() ? (org.eclipse.jdt.internal.compiler.env.ICompilationUnit) getOriginalElement() : this, offset, requestor);
227 * @see ICodeAssist#codeSelect(int, int)
229 //public IJavaElement[] codeSelect(int offset, int length) throws JavaModelException {
230 // return super.codeSelect(this, offset, length);
233 * @see IWorkingCopy#commit(boolean, IProgressMonitor)
235 public void commit(boolean force, IProgressMonitor monitor) throws JavaModelException {
236 throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, this));
239 * @see ICompilationUnit#commitWorkingCopy(boolean, IProgressMonitor)
241 public void commitWorkingCopy(boolean force, IProgressMonitor monitor) throws JavaModelException {
242 CommitWorkingCopyOperation op= new CommitWorkingCopyOperation(this, force);
243 op.runOperation(monitor);
246 * @see ISourceManipulation#copy(IJavaElement, IJavaElement, String, boolean, IProgressMonitor)
248 public void copy(IJavaElement container, IJavaElement sibling, String rename, boolean force, IProgressMonitor monitor) throws JavaModelException {
249 if (container == null) {
250 throw new IllegalArgumentException(Util.bind("operation.nullContainer")); //$NON-NLS-1$
252 IJavaElement[] elements = new IJavaElement[] {this};
253 IJavaElement[] containers = new IJavaElement[] {container};
254 String[] renamings = null;
255 if (rename != null) {
256 renamings = new String[] {rename};
258 getJavaModel().copy(elements, containers, null, renamings, force, monitor);
262 * Returns a new element info for this element.
264 protected Object createElementInfo() {
265 return new CompilationUnitElementInfo();
268 // * @see ICompilationUnit#createImport(String, IJavaElement, IProgressMonitor)
270 //public IImportDeclaration createImport(String name, IJavaElement sibling, IProgressMonitor monitor) throws JavaModelException {
271 // CreateImportOperation op = new CreateImportOperation(name, this);
272 // if (sibling != null) {
273 // op.createBefore(sibling);
275 // runOperation(op, monitor);
276 // return getImport(name);
279 * @see ICompilationUnit#createPackageDeclaration(String, IProgressMonitor)
281 public IPackageDeclaration createPackageDeclaration(String name, IProgressMonitor monitor) throws JavaModelException {
283 CreatePackageDeclarationOperation op= new CreatePackageDeclarationOperation(name, this);
284 runOperation(op, monitor);
285 return getPackageDeclaration(name);
288 // * @see ICompilationUnit#createType(String, IJavaElement, boolean, IProgressMonitor)
290 //public IType createType(String content, IJavaElement sibling, boolean force, IProgressMonitor monitor) throws JavaModelException {
292 // //autogenerate this compilation unit
293 // IPackageFragment pkg = (IPackageFragment) getParent();
294 // String source = ""; //$NON-NLS-1$
295 // if (pkg.getElementName().length() > 0) {
296 // //not the default package...add the package declaration
297 // 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$
299 // CreateCompilationUnitOperation op = new CreateCompilationUnitOperation(pkg, fName, source, force);
300 // runOperation(op, monitor);
302 // CreateTypeOperation op = new CreateTypeOperation(this, content, force);
303 // if (sibling != null) {
304 // op.createBefore(sibling);
306 // runOperation(op, monitor);
307 // return (IType) op.getResultElements()[0];
310 * @see ISourceManipulation#delete(boolean, IProgressMonitor)
312 public void delete(boolean force, IProgressMonitor monitor) throws JavaModelException {
313 IJavaElement[] elements= new IJavaElement[] {this};
314 getJavaModel().delete(elements, force, monitor);
317 * @see IWorkingCopy#destroy()
320 public void destroy() {
322 discardWorkingCopy();
323 } catch (JavaModelException e) {
328 * @see ICompilationUnit#discardWorkingCopy
330 public void discardWorkingCopy() throws JavaModelException {
331 // discard working copy and its children
332 DiscardWorkingCopyOperation op = new DiscardWorkingCopyOperation(this);
333 op.runOperation(null);
337 * Returns true if this handle represents the same Java element
338 * as the given handle.
340 * @see Object#equals(java.lang.Object)
342 public boolean equals(Object obj) {
343 if (!(obj instanceof CompilationUnit)) return false;
344 CompilationUnit other = (CompilationUnit)obj;
345 return this.owner.equals(other.owner) && super.equals(obj);
348 * @see JavaElement#equalsDOMNode(IDOMNode)
350 protected boolean equalsDOMNode(IDOMNode node) throws JavaModelException {
351 String name = getElementName();
352 if (node.getNodeType() == IDOMNode.COMPILATION_UNIT && name != null ) {
353 String nodeName = node.getName();
354 if (nodeName == null) return false;
355 if (name.equals(nodeName)) {
358 // iterate through all the types inside the receiver and see if one of them can fit
359 IType[] types = getTypes();
360 String typeNodeName = nodeName.substring(0, nodeName.indexOf(".java")); //$NON-NLS-1$
361 for (int i = 0, max = types.length; i < max; i++) {
362 if (types[i].getElementName().equals(typeNodeName)) {
371 * @see IWorkingCopy#findElements(IJavaElement)
373 public IJavaElement[] findElements(IJavaElement element) {
374 ArrayList children = new ArrayList();
375 while (element != null && element.getElementType() != IJavaElement.COMPILATION_UNIT) {
376 children.add(element);
377 element = element.getParent();
379 if (element == null) return null;
380 IJavaElement currentElement = this;
381 for (int i = children.size()-1; i >= 0; i--) {
382 IJavaElement child = (IJavaElement)children.get(i);
383 switch (child.getElementType()) {
384 // case IJavaElement.PACKAGE_DECLARATION:
385 // currentElement = ((ICompilationUnit)currentElement).getPackageDeclaration(child.getElementName());
387 // case IJavaElement.IMPORT_CONTAINER:
388 // currentElement = ((ICompilationUnit)currentElement).getImportContainer();
390 // case IJavaElement.IMPORT_DECLARATION:
391 // currentElement = ((IImportContainer)currentElement).getImport(child.getElementName());
393 case IJavaElement.TYPE:
394 if (currentElement.getElementType() == IJavaElement.COMPILATION_UNIT) {
395 currentElement = ((ICompilationUnit)currentElement).getType(child.getElementName());
397 currentElement = ((IType)currentElement).getType(child.getElementName());
400 // case IJavaElement.INITIALIZER:
401 // currentElement = ((IType)currentElement).getInitializer(((JavaElement)child).getOccurrenceCount());
403 case IJavaElement.FIELD:
404 currentElement = ((IType)currentElement).getField(child.getElementName());
406 case IJavaElement.METHOD:
407 return ((IType)currentElement).findMethods((IMethod)child);
411 if (currentElement != null && currentElement.exists()) {
412 return new IJavaElement[] {currentElement};
418 * @see IWorkingCopy#findPrimaryType()
420 public IType findPrimaryType() {
421 String typeName = Signature.getQualifier(this.getElementName());
422 IType primaryType= this.getType(typeName);
423 if (primaryType.exists()) {
429 * @see IWorkingCopy#findSharedWorkingCopy(IBufferFactory)
432 public IJavaElement findSharedWorkingCopy(IBufferFactory factory) {
434 // if factory is null, default factory must be used
435 if (factory == null) factory = this.getBufferManager().getDefaultBufferFactory();
437 return findWorkingCopy(BufferFactoryWrapper.create(factory));
441 * @see ICompilationUnit#findWorkingCopy(WorkingCopyOwner)
443 public ICompilationUnit findWorkingCopy(WorkingCopyOwner workingCopyOwner) {
444 CompilationUnit cu = new CompilationUnit((PackageFragment)this.parent, getElementName(), workingCopyOwner);
445 if (workingCopyOwner == DefaultWorkingCopyOwner.PRIMARY) {
448 // must be a working copy
449 JavaModelManager.PerWorkingCopyInfo perWorkingCopyInfo = cu.getPerWorkingCopyInfo();
450 if (perWorkingCopyInfo != null) {
451 return perWorkingCopyInfo.getWorkingCopy();
457 protected boolean generateInfos(OpenableElementInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) throws JavaModelException {
459 // if (getParent() instanceof JarPackageFragment) {
460 // // ignore .java files in jar
461 // throw newNotPresentException();
463 // put the info now, because getting the contents requires it
464 JavaModelManager.getJavaModelManager().putInfo(this, info);
465 CompilationUnitElementInfo unitInfo = (CompilationUnitElementInfo) info;
467 // generate structure
468 CompilationUnitStructureRequestor requestor = new CompilationUnitStructureRequestor(this, unitInfo, newElements);
469 IProblemFactory factory = new DefaultProblemFactory();
470 SourceElementParser parser = new SourceElementParser(requestor, factory, new CompilerOptions(getJavaProject().getOptions(true)));
471 // SourceElementParser parser = new SourceElementParser(requestor, factory);
472 requestor.parser = parser;
473 parser.parseCompilationUnit(this, false);
474 if (isWorkingCopy()) {
475 CompilationUnit original = (CompilationUnit) getOriginalElement();
476 // might be IResource.NULL_STAMP if original does not exist
477 unitInfo.timestamp = ((IFile) original.getResource()).getModificationStamp();
479 return unitInfo.isStructureKnown();
483 * @see ICompilationUnit#getAllTypes()
485 public IType[] getAllTypes() throws JavaModelException {
486 IJavaElement[] types = getTypes();
488 ArrayList allTypes = new ArrayList(types.length);
489 ArrayList typesToTraverse = new ArrayList(types.length);
490 for (i = 0; i < types.length; i++) {
491 typesToTraverse.add(types[i]);
493 while (!typesToTraverse.isEmpty()) {
494 IType type = (IType) typesToTraverse.get(0);
495 typesToTraverse.remove(type);
497 types = type.getTypes();
498 for (i = 0; i < types.length; i++) {
499 typesToTraverse.add(types[i]);
502 IType[] arrayOfAllTypes = new IType[allTypes.size()];
503 allTypes.toArray(arrayOfAllTypes);
504 return arrayOfAllTypes;
507 * @see IMember#getCompilationUnit()
509 public ICompilationUnit getCompilationUnit() {
513 * @see org.eclipse.jdt.internal.compiler.env.ICompilationUnit#getContents()
515 public char[] getContents() {
517 IBuffer buffer = this.getBuffer();
518 return buffer == null ? null : buffer.getCharacters();
519 } catch (JavaModelException e) {
520 return CharOperation.NO_CHAR;
524 * A compilation unit has a corresponding resource unless it is contained
527 * @see IJavaElement#getCorrespondingResource()
529 public IResource getCorrespondingResource() throws JavaModelException {
530 IPackageFragmentRoot root= (IPackageFragmentRoot)getParent().getParent();
531 if (root.isArchive()) {
534 return getUnderlyingResource();
538 * @see ICompilationUnit#getElementAt(int)
540 public IJavaElement getElementAt(int position) throws JavaModelException {
542 IJavaElement e= getSourceElementAt(position);
552 public int getElementType() {
553 return COMPILATION_UNIT;
555 public char[] getFileName(){
556 return getElementName().toCharArray();
559 * @see JavaElement#getHandleMementoDelimiter()
561 protected char getHandleMementoDelimiter() {
562 return JavaElement.JEM_COMPILATIONUNIT;
565 * @see ICompilationUnit#getImport(String)
567 //public IImportDeclaration getImport(String name) {
568 // return new ImportDeclaration(getImportContainer(), name);
571 // * @see ICompilationUnit#getImportContainer()
573 //public IImportContainer getImportContainer() {
574 // return new ImportContainer(this);
579 * @see ICompilationUnit#getImports()
581 //public IImportDeclaration[] getImports() throws JavaModelException {
582 // IImportContainer container= getImportContainer();
583 // if (container.exists()) {
584 // IJavaElement[] elements= container.getChildren();
585 // IImportDeclaration[] imprts= new IImportDeclaration[elements.length];
586 // System.arraycopy(elements, 0, imprts, 0, elements.length);
588 // } else if (!exists()) {
589 // throw newNotPresentException();
591 // return new IImportDeclaration[0];
596 * @see org.eclipse.jdt.internal.compiler.env.ICompilationUnit#getMainTypeName()
598 public char[] getMainTypeName(){
599 String name= getElementName();
601 name= name.substring(0, name.length() - 5);
602 return name.toCharArray();
606 * @see IWorkingCopy#getOriginal(IJavaElement)
609 public IJavaElement getOriginal(IJavaElement workingCopyElement) {
610 // backward compatibility
611 if (!isWorkingCopy()) return null;
612 CompilationUnit cu = (CompilationUnit)workingCopyElement.getAncestor(COMPILATION_UNIT);
613 if (cu == null || !this.owner.equals(cu.owner)) {
617 return workingCopyElement.getPrimaryElement();
620 * @see IWorkingCopy#getOriginalElement()
623 public IJavaElement getOriginalElement() {
624 // backward compatibility
625 if (!isWorkingCopy()) return null;
627 return getPrimaryElement();
630 * @see ICompilationUnit#getOwner()
632 public WorkingCopyOwner getOwner() {
633 return isPrimary() || !isWorkingCopy() ? null : this.owner;
636 * @see ICompilationUnit#getPackageDeclaration(String)
638 public IPackageDeclaration getPackageDeclaration(String name) {
639 return new PackageDeclaration(this, name);
642 * @see ICompilationUnit#getPackageDeclarations()
644 public IPackageDeclaration[] getPackageDeclarations() throws JavaModelException {
645 ArrayList list = getChildrenOfType(PACKAGE_DECLARATION);
646 IPackageDeclaration[] array= new IPackageDeclaration[list.size()];
651 * @see org.eclipse.jdt.internal.compiler.env.ICompilationUnit#getPackageName()
653 public char[][] getPackageName() {
657 * @see IJavaElement#getPath()
659 public IPath getPath() {
660 PackageFragmentRoot root = this.getPackageFragmentRoot();
661 if (root.isArchive()) {
662 return root.getPath();
664 return this.getParent().getPath().append(this.getElementName());
668 * Returns the per working copy info for the receiver, or null if none exist.
669 * Note: the use count of the per working copy info is NOT incremented.
671 public JavaModelManager.PerWorkingCopyInfo getPerWorkingCopyInfo() {
672 return JavaModelManager.getJavaModelManager().getPerWorkingCopyInfo(this, false/*don't create*/, false/*don't record usage*/, null/*no problem requestor needed*/);
675 * @see ICompilationUnit#getPrimary()
677 public ICompilationUnit getPrimary() {
678 return (ICompilationUnit)getPrimaryElement(true);
681 * @see JavaElement#getPrimaryElement(boolean)
683 public IJavaElement getPrimaryElement(boolean checkOwner) {
684 if (checkOwner && isPrimary()) return this;
685 return new CompilationUnit((PackageFragment)getParent(), getElementName(), DefaultWorkingCopyOwner.PRIMARY);
689 * @see IJavaElement#getResource()
691 public IResource getResource() {
692 PackageFragmentRoot root = this.getPackageFragmentRoot();
693 if (root.isArchive()) {
694 return root.getResource();
696 return ((IContainer)this.getParent().getResource()).getFile(new Path(this.getElementName()));
701 * @see ISourceReference#getSource()
703 public String getSource() throws JavaModelException {
704 IBuffer buffer = getBuffer();
705 if (buffer == null) return ""; //$NON-NLS-1$
706 return buffer.getContents();
709 * @see ISourceReference#getSourceRange()
711 public ISourceRange getSourceRange() throws JavaModelException {
712 return ((CompilationUnitElementInfo) getElementInfo()).getSourceRange();
715 * @see ICompilationUnit#getType(String)
717 public IType getType(String name) {
718 return new SourceType(this, name);
721 * @see ICompilationUnit#getTypes()
723 public IType[] getTypes() throws JavaModelException {
724 ArrayList list = getChildrenOfType(TYPE);
725 IType[] array= new IType[list.size()];
732 public IResource getUnderlyingResource() throws JavaModelException {
733 if (isWorkingCopy() && !isPrimary()) return null;
734 return super.getUnderlyingResource();
737 // * @see IWorkingCopy#getSharedWorkingCopy(IProgressMonitor, IBufferFactory, IProblemRequestor)
739 //public IJavaElement getSharedWorkingCopy(IProgressMonitor pm, IBufferFactory factory, IProblemRequestor problemRequestor) throws JavaModelException {
741 // // if factory is null, default factory must be used
742 // if (factory == null) factory = this.getBufferManager().getDefaultBufferFactory();
744 // JavaModelManager manager = JavaModelManager.getJavaModelManager();
746 // // In order to be shared, working copies have to denote the same compilation unit
747 // // AND use the same buffer factory.
748 // // Assuming there is a little set of buffer factories, then use a 2 level Map cache.
749 // Map sharedWorkingCopies = manager.sharedWorkingCopies;
751 // Map perFactoryWorkingCopies = (Map) sharedWorkingCopies.get(factory);
752 // if (perFactoryWorkingCopies == null){
753 // perFactoryWorkingCopies = new HashMap();
754 // sharedWorkingCopies.put(factory, perFactoryWorkingCopies);
756 // WorkingCopy workingCopy = (WorkingCopy)perFactoryWorkingCopies.get(this);
757 // if (workingCopy != null) {
758 // workingCopy.useCount++;
760 // if (SHARED_WC_VERBOSE) {
761 // System.out.println("Incrementing use count of shared working copy " + workingCopy.toStringWithAncestors()); //$NON-NLS-1$
764 // return workingCopy;
766 // CreateWorkingCopyOperation op = new CreateWorkingCopyOperation(this, perFactoryWorkingCopies, factory, problemRequestor);
767 // runOperation(op, pm);
768 // return op.getResultElements()[0];
772 // * @see IWorkingCopy#getWorkingCopy()
774 //public IJavaElement getWorkingCopy() throws JavaModelException {
775 // return this.getWorkingCopy(null, null, null);
779 // * @see IWorkingCopy#getWorkingCopy(IProgressMonitor, IBufferFactory, IProblemRequestor)
781 //public IJavaElement getWorkingCopy(IProgressMonitor pm, IBufferFactory factory, IProblemRequestor problemRequestor) throws JavaModelException {
782 // CreateWorkingCopyOperation op = new CreateWorkingCopyOperation(this, null, factory, problemRequestor);
783 // runOperation(op, pm);
784 // return op.getResultElements()[0];
787 * @see IWorkingCopy#getSharedWorkingCopy(IProgressMonitor, IBufferFactory, IProblemRequestor)
790 public IJavaElement getSharedWorkingCopy(IProgressMonitor pm, IBufferFactory factory, IProblemRequestor problemRequestor) throws JavaModelException {
792 // if factory is null, default factory must be used
793 if (factory == null) factory = this.getBufferManager().getDefaultBufferFactory();
795 return getWorkingCopy(BufferFactoryWrapper.create(factory), problemRequestor, pm);
798 * @see IWorkingCopy#getWorkingCopy()
801 public IJavaElement getWorkingCopy() throws JavaModelException {
802 return getWorkingCopy(null);
805 * @see ICompilationUnit#getWorkingCopy(IProgressMonitor)
807 public ICompilationUnit getWorkingCopy(IProgressMonitor monitor) throws JavaModelException {
808 return getWorkingCopy(new WorkingCopyOwner() {/*non shared working copy*/}, null/*no problem requestor*/, monitor);
811 * @see IWorkingCopy#getWorkingCopy(IProgressMonitor, IBufferFactory, IProblemRequestor)
814 public IJavaElement getWorkingCopy(IProgressMonitor monitor, IBufferFactory factory, IProblemRequestor problemRequestor) throws JavaModelException {
815 return getWorkingCopy(BufferFactoryWrapper.create(factory), problemRequestor, monitor);
818 * @see ICompilationUnit#getWorkingCopy(WorkingCopyOwner, IProblemRequestor, IProgressMonitor)
820 public ICompilationUnit getWorkingCopy(WorkingCopyOwner workingCopyOwner, IProblemRequestor problemRequestor, IProgressMonitor monitor) throws JavaModelException {
821 if (!isPrimary()) return this;
823 JavaModelManager manager = JavaModelManager.getJavaModelManager();
825 CompilationUnit workingCopy = new CompilationUnit((PackageFragment)getParent(), getElementName(), workingCopyOwner);
826 JavaModelManager.PerWorkingCopyInfo perWorkingCopyInfo =
827 manager.getPerWorkingCopyInfo(workingCopy, false/*don't create*/, true/*record usage*/, null/*not used since don't create*/);
828 if (perWorkingCopyInfo != null) {
829 return perWorkingCopyInfo.getWorkingCopy(); // return existing handle instead of the one created above
831 BecomeWorkingCopyOperation op = new BecomeWorkingCopyOperation(workingCopy, problemRequestor);
832 op.runOperation(monitor);
837 * If I am not open, return true to avoid parsing.
839 * @see IParent#hasChildren()
841 public boolean hasChildren() throws JavaModelException {
843 // return getChildren().length > 0;
850 * @see Openable#hasBuffer()
852 protected boolean hasBuffer() {
856 * @see ICompilationUnit#hasResourceChanged()
858 public boolean hasResourceChanged() {
859 if (!isWorkingCopy()) return false;
861 // if resource got deleted, then #getModificationStamp() will answer IResource.NULL_STAMP, which is always different from the cached
863 Object info = JavaModelManager.getJavaModelManager().getInfo(this);
864 if (info == null) return false;
865 return ((CompilationUnitElementInfo)info).timestamp != getResource().getModificationStamp();
868 * @see IWorkingCopy#isBasedOn(IResource)
871 public boolean isBasedOn(IResource resource) {
872 if (!isWorkingCopy()) return false;
873 if (!getResource().equals(resource)) return false;
874 return !hasResourceChanged();
877 * @see IOpenable#isConsistent()
879 public boolean isConsistent() {
880 return JavaModelManager.getJavaModelManager().getElementsOutOfSynchWithBuffers().get(this) == null;
887 public boolean isOpen() {
888 Object info = JavaModelManager.getJavaModelManager().getInfo(this);
889 return info != null && ((CompilationUnitElementInfo)info).isOpen();
891 public boolean isPrimary() {
892 return this.owner == DefaultWorkingCopyOwner.PRIMARY;
895 * @see Openable#isSourceElement()
897 protected boolean isSourceElement() {
900 protected boolean isValidCompilationUnit() {
901 IPackageFragmentRoot root = getPackageFragmentRoot();
903 if (root.getKind() != IPackageFragmentRoot.K_SOURCE) return false;
904 } catch (JavaModelException e) {
907 // IResource resource = getResource();
908 // if (resource != null) {
909 // char[][] inclusionPatterns = ((PackageFragmentRoot)root).fullInclusionPatternChars();
910 // char[][] exclusionPatterns = ((PackageFragmentRoot)root).fullExclusionPatternChars();
911 // if (Util.isExcluded(resource, inclusionPatterns, exclusionPatterns)) return false;
913 if (!Util.isValidCompilationUnitName(getElementName())) return false;
917 * @see ICompilationUnit#isWorkingCopy()
919 public boolean isWorkingCopy() {
920 // For backward compatibility, non primary working copies are always returning true; in removal
921 // delta, clients can still check that element was a working copy before being discarded.
922 return !isPrimary() || getPerWorkingCopyInfo() != null;
925 * @see IOpenable#makeConsistent(IProgressMonitor)
927 public void makeConsistent(IProgressMonitor monitor) throws JavaModelException {
928 makeConsistent(false/*don't create AST*/, 0, monitor);
930 public Object makeConsistent(boolean createAST, int astLevel, IProgressMonitor monitor) throws JavaModelException {
931 if (isConsistent()) return null;
933 // create a new info and make it the current info
934 // (this will remove the info and its children just before storing the new infos)
936 // ASTHolderCUInfo info = new ASTHolderCUInfo();
937 // info.astLevel = astLevel;
938 // openWhenClosed(info, monitor);
939 // org.eclipse.jdt.core.dom.CompilationUnit result = info.ast;
943 openWhenClosed(createElementInfo(), monitor);
947 //public net.sourceforge.phpdt.core.dom.CompilationUnit makeConsistent(boolean createAST, int astLevel, IProgressMonitor monitor) throws JavaModelException {
948 // if (isConsistent()) return null;
950 // // create a new info and make it the current info
951 // // (this will remove the info and its children just before storing the new infos)
953 // ASTHolderCUInfo info = new ASTHolderCUInfo();
954 // info.astLevel = astLevel;
955 // openWhenClosed(info, monitor);
956 // net.sourceforge.phpdt.core.dom.CompilationUnit result = info.ast;
960 // openWhenClosed(createElementInfo(), monitor);
966 * @see ISourceManipulation#move(IJavaElement, IJavaElement, String, boolean, IProgressMonitor)
968 public void move(IJavaElement container, IJavaElement sibling, String rename, boolean force, IProgressMonitor monitor) throws JavaModelException {
969 if (container == null) {
970 throw new IllegalArgumentException(Util.bind("operation.nullContainer")); //$NON-NLS-1$
972 IJavaElement[] elements= new IJavaElement[] {this};
973 IJavaElement[] containers= new IJavaElement[] {container};
975 String[] renamings= null;
976 if (rename != null) {
977 renamings= new String[] {rename};
979 getJavaModel().move(elements, containers, null, renamings, force, monitor);
983 // * @see Openable#openBuffer(IProgressMonitor)
985 //protected IBuffer openBuffer(IProgressMonitor pm) throws JavaModelException {
987 // // create buffer - compilation units only use default buffer factory
988 // BufferManager bufManager = getBufferManager();
989 // IBuffer buffer = getBufferFactory().createBuffer(this);
990 // if (buffer == null) return null;
992 // // set the buffer source
993 // if (buffer.getCharacters() == null){
994 // IFile file = (IFile)this.getResource();
995 // if (file == null || !file.exists()) throw newNotPresentException();
996 // buffer.setContents(Util.getResourceContentsAsCharArray(file));
999 // // add buffer to buffer cache
1000 // bufManager.addBuffer(buffer);
1002 // // listen to buffer changes
1003 // buffer.addBufferChangedListener(this);
1008 * @see Openable#openBuffer(IProgressMonitor, Object)
1010 protected IBuffer openBuffer(IProgressMonitor pm, Object info) throws JavaModelException {
1013 boolean isWorkingCopy = isWorkingCopy();
1016 ? this.owner.createBuffer(this)
1017 : BufferManager.getDefaultBufferManager().createBuffer(this);
1018 if (buffer == null) return null;
1020 // set the buffer source
1021 if (buffer.getCharacters() == null) {
1022 if (isWorkingCopy) {
1023 ICompilationUnit original;
1025 && (original = new CompilationUnit((PackageFragment)getParent(), getElementName(), DefaultWorkingCopyOwner.PRIMARY)).isOpen()) {
1026 buffer.setContents(original.getSource());
1028 IFile file = (IFile)getResource();
1029 if (file == null || !file.exists()) {
1030 // initialize buffer with empty contents
1031 buffer.setContents(CharOperation.NO_CHAR);
1033 buffer.setContents(Util.getResourceContentsAsCharArray(file));
1037 IFile file = (IFile)this.getResource();
1038 if (file == null || !file.exists()) throw newNotPresentException();
1039 buffer.setContents(Util.getResourceContentsAsCharArray(file));
1043 // add buffer to buffer cache
1044 BufferManager bufManager = getBufferManager();
1045 bufManager.addBuffer(buffer);
1047 // listen to buffer changes
1048 buffer.addBufferChangedListener(this);
1053 * @see Openable#openParent
1055 protected void openParent(Object childInfo, HashMap newElements, IProgressMonitor pm) throws JavaModelException {
1057 super.openParent(childInfo, newElements, pm);
1058 } catch(JavaModelException e){
1059 // allow parent to not exist for working copies defined outside classpath
1060 if (!isWorkingCopy() && !e.isDoesNotExist()){
1067 * @see ICompilationUnit#reconcile()
1070 public IMarker[] reconcile() throws JavaModelException {
1071 reconcile(NO_AST, false/*don't force problem detection*/, null/*use primary owner*/, null/*no progress monitor*/);
1075 * @see ICompilationUnit#reconcile(int, boolean, WorkingCopyOwner, IProgressMonitor)
1077 public void reconcile(boolean forceProblemDetection, IProgressMonitor monitor) throws JavaModelException {
1078 reconcile(NO_AST, forceProblemDetection, null/*use primary owner*/, monitor);
1082 * @see ICompilationUnit#reconcile(int, boolean, WorkingCopyOwner, IProgressMonitor)
1085 //public org.eclipse.jdt.core.dom.CompilationUnit reconcile(
1086 public Object reconcile(
1088 boolean forceProblemDetection,
1089 WorkingCopyOwner workingCopyOwner,
1090 IProgressMonitor monitor)
1091 throws JavaModelException {
1093 if (!isWorkingCopy()) return null; // Reconciling is not supported on non working copies
1094 if (workingCopyOwner == null) workingCopyOwner = DefaultWorkingCopyOwner.PRIMARY;
1096 boolean createAST = false;
1097 // if (astLevel == AST.JLS2) {
1098 // // client asking for level 2 AST; these are supported
1099 // createAST = true;
1100 // } else if (astLevel == AST.JLS3) {
1101 // // client asking for level 3 ASTs; these are not supported
1102 // // TODO (jerome) - these should also be supported in 1.5 stream
1103 // createAST = false;
1105 // // client asking for no AST (0) or unknown ast level
1106 // // either way, request denied
1107 // createAST = false;
1109 ReconcileWorkingCopyOperation op = new ReconcileWorkingCopyOperation(this, createAST, astLevel, forceProblemDetection, workingCopyOwner);
1110 op.runOperation(monitor);
1116 * @see ISourceManipulation#rename(String, boolean, IProgressMonitor)
1118 public void rename(String name, boolean force, IProgressMonitor monitor) throws JavaModelException {
1120 throw new IllegalArgumentException(Util.bind("operation.nullName")); //$NON-NLS-1$
1122 IJavaElement[] elements= new IJavaElement[] {this};
1123 IJavaElement[] dests= new IJavaElement[] {this.getParent()};
1124 String[] renamings= new String[] {name};
1125 getJavaModel().rename(elements, dests, renamings, force, monitor);
1128 * Does nothing - this is not a working copy.
1130 * @see IWorkingCopy#restore()
1132 public void restore () throws JavaModelException {
1135 * @see ICodeAssist#codeComplete(int, ICodeCompletionRequestor)
1136 * @deprecated - use codeComplete(int, ICompletionRequestor)
1138 //public void codeComplete(int offset, final ICodeCompletionRequestor requestor) throws JavaModelException {
1140 // if (requestor == null){
1141 // codeComplete(offset, (ICompletionRequestor)null);
1146 // new ICompletionRequestor(){
1147 // public void acceptAnonymousType(char[] superTypePackageName,char[] superTypeName,char[][] parameterPackageNames,char[][] parameterTypeNames,char[][] parameterNames,char[] completionName,int modifiers,int completionStart,int completionEnd, int relevance){
1149 // public void acceptClass(char[] packageName, char[] className, char[] completionName, int modifiers, int completionStart, int completionEnd, int relevance) {
1150 // requestor.acceptClass(packageName, className, completionName, modifiers, completionStart, completionEnd);
1152 // public void acceptError(IProblem error) {
1153 // if (true) return; // was disabled in 1.0
1156 // IMarker marker = ResourcesPlugin.getWorkspace().getRoot().createMarker(IJavaModelMarker.TRANSIENT_PROBLEM);
1157 // marker.setAttribute(IJavaModelMarker.ID, error.getID());
1158 // marker.setAttribute(IMarker.CHAR_START, error.getSourceStart());
1159 // marker.setAttribute(IMarker.CHAR_END, error.getSourceEnd() + 1);
1160 // marker.setAttribute(IMarker.LINE_NUMBER, error.getSourceLineNumber());
1161 // marker.setAttribute(IMarker.MESSAGE, error.getMessage());
1162 // marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
1163 // requestor.acceptError(marker);
1164 // } catch(CoreException e){
1167 // public void acceptField(char[] declaringTypePackageName, char[] declaringTypeName, char[] name, char[] typePackageName, char[] typeName, char[] completionName, int modifiers, int completionStart, int completionEnd, int relevance) {
1168 // requestor.acceptField(declaringTypePackageName, declaringTypeName, name, typePackageName, typeName, completionName, modifiers, completionStart, completionEnd);
1170 // public void acceptInterface(char[] packageName,char[] interfaceName,char[] completionName,int modifiers,int completionStart,int completionEnd, int relevance) {
1171 // requestor.acceptInterface(packageName, interfaceName, completionName, modifiers, completionStart, completionEnd);
1173 // public void acceptKeyword(char[] keywordName,int completionStart,int completionEnd, int relevance){
1174 // requestor.acceptKeyword(keywordName, completionStart, completionEnd);
1176 // public void acceptLabel(char[] labelName,int completionStart,int completionEnd, int relevance){
1177 // requestor.acceptLabel(labelName, completionStart, completionEnd);
1179 // public void acceptLocalVariable(char[] name,char[] typePackageName,char[] typeName,int modifiers,int completionStart,int completionEnd, int relevance){
1182 // 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){
1183 // // skip parameter names
1184 // requestor.acceptMethod(declaringTypePackageName, declaringTypeName, selector, parameterPackageNames, parameterTypeNames, returnTypePackageName, returnTypeName, completionName, modifiers, completionStart, completionEnd);
1186 // 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){
1189 // public void acceptModifier(char[] modifierName,int completionStart,int completionEnd, int relevance){
1190 // requestor.acceptModifier(modifierName, completionStart, completionEnd);
1192 // public void acceptPackage(char[] packageName,char[] completionName,int completionStart,int completionEnd, int relevance){
1193 // requestor.acceptPackage(packageName, completionName, completionStart, completionEnd);
1195 // public void acceptType(char[] packageName,char[] typeName,char[] completionName,int completionStart,int completionEnd, int relevance){
1196 // requestor.acceptType(packageName, typeName, completionName, completionStart, completionEnd);
1198 // public void acceptVariableName(char[] typePackageName,char[] typeName,char[] name,char[] completionName,int completionStart,int completionEnd, int relevance){
1204 // * @see JavaElement#rootedAt(IJavaProject)
1206 //public IJavaElement rootedAt(IJavaProject project) {
1208 // new CompilationUnit(
1209 // (IPackageFragment)((JavaElement)parent).rootedAt(project),
1213 * Assume that this is a working copy
1215 protected void updateTimeStamp(CompilationUnit original) throws JavaModelException {
1217 ((IFile) original.getResource()).getModificationStamp();
1218 if (timeStamp == IResource.NULL_STAMP) {
1219 throw new JavaModelException(
1220 new JavaModelStatus(IJavaModelStatusConstants.INVALID_RESOURCE));
1222 ((CompilationUnitElementInfo) getElementInfo()).timestamp = timeStamp;