0001: /*******************************************************************************
0002: * Copyright (c) 2000, 2007 IBM Corporation and others.
0003: * All rights reserved. This program and the accompanying materials
0004: * are made available under the terms of the Eclipse Public License v1.0
0005: * which accompanies this distribution, and is available at
0006: * http://www.eclipse.org/legal/epl-v10.html
0007: *
0008: * Contributors:
0009: * IBM Corporation - initial API and implementation
0010: * Alex Smirnoff (alexsmr@sympatico.ca) - part of the changes to support Java-like extension
0011: * (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=71460)
0012: *******************************************************************************/package org.eclipse.jdt.internal.core;
0013:
0014: import java.util.*;
0015:
0016: import org.eclipse.core.resources.*;
0017: import org.eclipse.core.runtime.*;
0018: import org.eclipse.jdt.core.*;
0019: import org.eclipse.jdt.core.compiler.*;
0020: import org.eclipse.jdt.core.dom.AST;
0021: import org.eclipse.jdt.internal.compiler.IProblemFactory;
0022: import org.eclipse.jdt.internal.compiler.SourceElementParser;
0023: import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
0024: import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
0025: import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
0026: import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
0027: import org.eclipse.jdt.internal.core.util.MementoTokenizer;
0028: import org.eclipse.jdt.internal.core.util.Messages;
0029: import org.eclipse.jdt.internal.core.util.Util;
0030:
0031: /**
0032: * @see ICompilationUnit
0033: */
0034: public class CompilationUnit extends Openable implements
0035: ICompilationUnit,
0036: org.eclipse.jdt.internal.compiler.env.ICompilationUnit,
0037: SuffixConstants {
0038: /**
0039: * Internal synonynm for deprecated constant AST.JSL2
0040: * to alleviate deprecation warnings.
0041: * @deprecated
0042: */
0043: /*package*/static final int JLS2_INTERNAL = AST.JLS2;
0044:
0045: private static final IImportDeclaration[] NO_IMPORTS = new IImportDeclaration[0];
0046:
0047: protected String name;
0048: public WorkingCopyOwner owner;
0049:
0050: /**
0051: * Constructs a handle to a compilation unit with the given name in the
0052: * specified package for the specified owner
0053: */
0054: public CompilationUnit(PackageFragment parent, String name,
0055: WorkingCopyOwner owner) {
0056: super (parent);
0057: this .name = name;
0058: this .owner = owner;
0059: }
0060:
0061: /*
0062: * @see ICompilationUnit#becomeWorkingCopy(IProblemRequestor, IProgressMonitor)
0063: */
0064: public void becomeWorkingCopy(IProblemRequestor problemRequestor,
0065: IProgressMonitor monitor) throws JavaModelException {
0066: JavaModelManager manager = JavaModelManager
0067: .getJavaModelManager();
0068: JavaModelManager.PerWorkingCopyInfo perWorkingCopyInfo = manager
0069: .getPerWorkingCopyInfo(this , false/*don't create*/,
0070: true /*record usage*/, null/*no problem requestor needed*/);
0071: if (perWorkingCopyInfo == null) {
0072: // close cu and its children
0073: close();
0074:
0075: BecomeWorkingCopyOperation operation = new BecomeWorkingCopyOperation(
0076: this , problemRequestor);
0077: operation.runOperation(monitor);
0078: }
0079: }
0080:
0081: /*
0082: * @see ICompilationUnit#becomeWorkingCopy(IProgressMonitor)
0083: */
0084: public void becomeWorkingCopy(IProgressMonitor monitor)
0085: throws JavaModelException {
0086: IProblemRequestor requestor = this .owner == null ? null
0087: : this .owner.getProblemRequestor(this );
0088: becomeWorkingCopy(requestor, monitor);
0089: }
0090:
0091: protected boolean buildStructure(OpenableElementInfo info,
0092: final IProgressMonitor pm, Map newElements,
0093: IResource underlyingResource) throws JavaModelException {
0094:
0095: // check if this compilation unit can be opened
0096: if (!isWorkingCopy()) { // no check is done on root kind or exclusion pattern for working copies
0097: IStatus status = validateCompilationUnit(underlyingResource);
0098: if (!status.isOK())
0099: throw newJavaModelException(status);
0100: }
0101:
0102: // prevents reopening of non-primary working copies (they are closed when they are discarded and should not be reopened)
0103: if (!isPrimary() && getPerWorkingCopyInfo() == null) {
0104: throw newNotPresentException();
0105: }
0106:
0107: CompilationUnitElementInfo unitInfo = (CompilationUnitElementInfo) info;
0108:
0109: // get buffer contents
0110: IBuffer buffer = getBufferManager().getBuffer(
0111: CompilationUnit.this );
0112: if (buffer == null) {
0113: buffer = openBuffer(pm, unitInfo); // open buffer independently from the info, since we are building the info
0114: }
0115: final char[] contents;
0116: if (buffer == null) {
0117: contents = CharOperation.NO_CHAR;
0118: } else {
0119: char[] characters = buffer.getCharacters();
0120: contents = characters == null ? CharOperation.NO_CHAR
0121: : characters;
0122: }
0123:
0124: // generate structure and compute syntax problems if needed
0125: CompilationUnitStructureRequestor requestor = new CompilationUnitStructureRequestor(
0126: this , unitInfo, newElements);
0127: JavaModelManager.PerWorkingCopyInfo perWorkingCopyInfo = getPerWorkingCopyInfo();
0128: IJavaProject project = getJavaProject();
0129:
0130: boolean createAST;
0131: boolean resolveBindings;
0132: int reconcileFlags;
0133: HashMap problems;
0134: if (info instanceof ASTHolderCUInfo) {
0135: ASTHolderCUInfo astHolder = (ASTHolderCUInfo) info;
0136: createAST = astHolder.astLevel != NO_AST;
0137: resolveBindings = astHolder.resolveBindings;
0138: reconcileFlags = astHolder.reconcileFlags;
0139: problems = astHolder.problems;
0140: } else {
0141: createAST = false;
0142: resolveBindings = false;
0143: reconcileFlags = 0;
0144: problems = null;
0145: }
0146:
0147: boolean computeProblems = perWorkingCopyInfo != null
0148: && perWorkingCopyInfo.isActive() && project != null
0149: && JavaProject.hasJavaNature(project.getProject());
0150: IProblemFactory problemFactory = new DefaultProblemFactory();
0151: Map options = project == null ? JavaCore.getOptions() : project
0152: .getOptions(true);
0153: if (!computeProblems) {
0154: // disable task tags checking to speed up parsing
0155: options.put(JavaCore.COMPILER_TASK_TAGS, ""); //$NON-NLS-1$
0156: }
0157: SourceElementParser parser = new SourceElementParser(requestor,
0158: problemFactory, new CompilerOptions(options),
0159: true/*report local declarations*/, !createAST /*optimize string literals only if not creating a DOM AST*/);
0160: parser.reportOnlyOneSyntaxError = !computeProblems;
0161: parser.setMethodsFullRecovery(true);
0162: parser
0163: .setStatementsRecovery((reconcileFlags & ICompilationUnit.ENABLE_STATEMENTS_RECOVERY) != 0);
0164:
0165: if (!computeProblems && !resolveBindings && !createAST) // disable javadoc parsing if not computing problems, not resolving and not creating ast
0166: parser.javadocParser.checkDocComment = false;
0167: requestor.parser = parser;
0168: CompilationUnitDeclaration unit = parser
0169: .parseCompilationUnit(
0170: new org.eclipse.jdt.internal.compiler.env.ICompilationUnit() {
0171: public char[] getContents() {
0172: return contents;
0173: }
0174:
0175: public char[] getMainTypeName() {
0176: return CompilationUnit.this
0177: .getMainTypeName();
0178: }
0179:
0180: public char[][] getPackageName() {
0181: return CompilationUnit.this
0182: .getPackageName();
0183: }
0184:
0185: public char[] getFileName() {
0186: return CompilationUnit.this
0187: .getFileName();
0188: }
0189: }, true /*full parse to find local elements*/);
0190:
0191: // update timestamp (might be IResource.NULL_STAMP if original does not exist)
0192: if (underlyingResource == null) {
0193: underlyingResource = getResource();
0194: }
0195: // underlying resource is null in the case of a working copy on a class file in a jar
0196: if (underlyingResource != null)
0197: unitInfo.timestamp = ((IFile) underlyingResource)
0198: .getModificationStamp();
0199:
0200: // compute other problems if needed
0201: CompilationUnitDeclaration compilationUnitDeclaration = null;
0202: try {
0203: if (computeProblems) {
0204: if (problems == null) {
0205: // report problems to the problem requestor
0206: problems = new HashMap();
0207: compilationUnitDeclaration = CompilationUnitProblemFinder
0208: .process(unit, this , contents, parser,
0209: this .owner, problems, createAST,
0210: reconcileFlags, pm);
0211: try {
0212: perWorkingCopyInfo.beginReporting();
0213: for (Iterator iteraror = problems.values()
0214: .iterator(); iteraror.hasNext();) {
0215: CategorizedProblem[] categorizedProblems = (CategorizedProblem[]) iteraror
0216: .next();
0217: if (categorizedProblems == null)
0218: continue;
0219: for (int i = 0, length = categorizedProblems.length; i < length; i++) {
0220: perWorkingCopyInfo
0221: .acceptProblem(categorizedProblems[i]);
0222: }
0223: }
0224: } finally {
0225: perWorkingCopyInfo.endReporting();
0226: }
0227: } else {
0228: // collect problems
0229: compilationUnitDeclaration = CompilationUnitProblemFinder
0230: .process(unit, this , contents, parser,
0231: this .owner, problems, createAST,
0232: reconcileFlags, pm);
0233: }
0234: }
0235:
0236: if (createAST) {
0237: int astLevel = ((ASTHolderCUInfo) info).astLevel;
0238: org.eclipse.jdt.core.dom.CompilationUnit cu = AST
0239: .convertCompilationUnit(astLevel, unit,
0240: contents, options, computeProblems,
0241: this , reconcileFlags, pm);
0242: ((ASTHolderCUInfo) info).ast = cu;
0243: }
0244: } finally {
0245: if (compilationUnitDeclaration != null) {
0246: compilationUnitDeclaration.cleanUp();
0247: }
0248: }
0249:
0250: return unitInfo.isStructureKnown();
0251: }
0252:
0253: /*
0254: * @see Openable#canBeRemovedFromCache
0255: */
0256: public boolean canBeRemovedFromCache() {
0257: if (getPerWorkingCopyInfo() != null)
0258: return false; // working copies should remain in the cache until they are destroyed
0259: return super .canBeRemovedFromCache();
0260: }
0261:
0262: /*
0263: * @see Openable#canBufferBeRemovedFromCache
0264: */
0265: public boolean canBufferBeRemovedFromCache(IBuffer buffer) {
0266: if (getPerWorkingCopyInfo() != null)
0267: return false; // working copy buffers should remain in the cache until working copy is destroyed
0268: return super .canBufferBeRemovedFromCache(buffer);
0269: }/*
0270: * @see IOpenable#close
0271: */
0272:
0273: public void close() throws JavaModelException {
0274: if (getPerWorkingCopyInfo() != null)
0275: return; // a working copy must remain opened until it is discarded
0276: super .close();
0277: }
0278:
0279: /*
0280: * @see Openable#closing
0281: */
0282: protected void closing(Object info) {
0283: if (getPerWorkingCopyInfo() == null) {
0284: super .closing(info);
0285: } // else the buffer of a working copy must remain open for the lifetime of the working copy
0286: }
0287:
0288: /**
0289: * @see ICodeAssist#codeComplete(int, ICompletionRequestor)
0290: * @deprecated
0291: */
0292: public void codeComplete(int offset, ICompletionRequestor requestor)
0293: throws JavaModelException {
0294: codeComplete(offset, requestor, DefaultWorkingCopyOwner.PRIMARY);
0295: }
0296:
0297: /**
0298: * @see ICodeAssist#codeComplete(int, ICompletionRequestor, WorkingCopyOwner)
0299: * @deprecated
0300: */
0301: public void codeComplete(int offset,
0302: ICompletionRequestor requestor,
0303: WorkingCopyOwner workingCopyOwner)
0304: throws JavaModelException {
0305: if (requestor == null) {
0306: throw new IllegalArgumentException(
0307: "Completion requestor cannot be null"); //$NON-NLS-1$
0308: }
0309: codeComplete(
0310: offset,
0311: new org.eclipse.jdt.internal.codeassist.CompletionRequestorWrapper(
0312: requestor), workingCopyOwner);
0313: }
0314:
0315: /**
0316: * @see ICodeAssist#codeComplete(int, ICodeCompletionRequestor)
0317: * @deprecated - use codeComplete(int, ICompletionRequestor)
0318: */
0319: public void codeComplete(int offset,
0320: final ICodeCompletionRequestor requestor)
0321: throws JavaModelException {
0322:
0323: if (requestor == null) {
0324: codeComplete(offset, (ICompletionRequestor) null);
0325: return;
0326: }
0327: codeComplete(offset, new ICompletionRequestor() {
0328: public void acceptAnonymousType(
0329: char[] super TypePackageName, char[] super TypeName,
0330: char[][] parameterPackageNames,
0331: char[][] parameterTypeNames,
0332: char[][] parameterNames, char[] completionName,
0333: int modifiers, int completionStart,
0334: int completionEnd, int relevance) {
0335: // ignore
0336: }
0337:
0338: public void acceptClass(char[] packageName,
0339: char[] className, char[] completionName,
0340: int modifiers, int completionStart,
0341: int completionEnd, int relevance) {
0342: requestor.acceptClass(packageName, className,
0343: completionName, modifiers, completionStart,
0344: completionEnd);
0345: }
0346:
0347: public void acceptError(IProblem error) {
0348: // was disabled in 1.0
0349: }
0350:
0351: public void acceptField(char[] declaringTypePackageName,
0352: char[] declaringTypeName, char[] fieldName,
0353: char[] typePackageName, char[] typeName,
0354: char[] completionName, int modifiers,
0355: int completionStart, int completionEnd,
0356: int relevance) {
0357: requestor.acceptField(declaringTypePackageName,
0358: declaringTypeName, fieldName, typePackageName,
0359: typeName, completionName, modifiers,
0360: completionStart, completionEnd);
0361: }
0362:
0363: public void acceptInterface(char[] packageName,
0364: char[] interfaceName, char[] completionName,
0365: int modifiers, int completionStart,
0366: int completionEnd, int relevance) {
0367: requestor.acceptInterface(packageName, interfaceName,
0368: completionName, modifiers, completionStart,
0369: completionEnd);
0370: }
0371:
0372: public void acceptKeyword(char[] keywordName,
0373: int completionStart, int completionEnd,
0374: int relevance) {
0375: requestor.acceptKeyword(keywordName, completionStart,
0376: completionEnd);
0377: }
0378:
0379: public void acceptLabel(char[] labelName,
0380: int completionStart, int completionEnd,
0381: int relevance) {
0382: requestor.acceptLabel(labelName, completionStart,
0383: completionEnd);
0384: }
0385:
0386: public void acceptLocalVariable(char[] localVarName,
0387: char[] typePackageName, char[] typeName,
0388: int modifiers, int completionStart,
0389: int completionEnd, int relevance) {
0390: // ignore
0391: }
0392:
0393: public void acceptMethod(char[] declaringTypePackageName,
0394: char[] declaringTypeName, char[] selector,
0395: char[][] parameterPackageNames,
0396: char[][] parameterTypeNames,
0397: char[][] parameterNames,
0398: char[] returnTypePackageName,
0399: char[] returnTypeName, char[] completionName,
0400: int modifiers, int completionStart,
0401: int completionEnd, int relevance) {
0402: // skip parameter names
0403: requestor.acceptMethod(declaringTypePackageName,
0404: declaringTypeName, selector,
0405: parameterPackageNames, parameterTypeNames,
0406: returnTypePackageName, returnTypeName,
0407: completionName, modifiers, completionStart,
0408: completionEnd);
0409: }
0410:
0411: public void acceptMethodDeclaration(
0412: char[] declaringTypePackageName,
0413: char[] declaringTypeName, char[] selector,
0414: char[][] parameterPackageNames,
0415: char[][] parameterTypeNames,
0416: char[][] parameterNames,
0417: char[] returnTypePackageName,
0418: char[] returnTypeName, char[] completionName,
0419: int modifiers, int completionStart,
0420: int completionEnd, int relevance) {
0421: // ignore
0422: }
0423:
0424: public void acceptModifier(char[] modifierName,
0425: int completionStart, int completionEnd,
0426: int relevance) {
0427: requestor.acceptModifier(modifierName, completionStart,
0428: completionEnd);
0429: }
0430:
0431: public void acceptPackage(char[] packageName,
0432: char[] completionName, int completionStart,
0433: int completionEnd, int relevance) {
0434: requestor.acceptPackage(packageName, completionName,
0435: completionStart, completionEnd);
0436: }
0437:
0438: public void acceptType(char[] packageName, char[] typeName,
0439: char[] completionName, int completionStart,
0440: int completionEnd, int relevance) {
0441: requestor.acceptType(packageName, typeName,
0442: completionName, completionStart, completionEnd);
0443: }
0444:
0445: public void acceptVariableName(char[] typePackageName,
0446: char[] typeName, char[] varName,
0447: char[] completionName, int completionStart,
0448: int completionEnd, int relevance) {
0449: // ignore
0450: }
0451: });
0452: }
0453:
0454: /* (non-Javadoc)
0455: * @see org.eclipse.jdt.core.ICodeAssist#codeComplete(int, org.eclipse.jdt.core.CompletionRequestor)
0456: */
0457: public void codeComplete(int offset, CompletionRequestor requestor)
0458: throws JavaModelException {
0459: codeComplete(offset, requestor, DefaultWorkingCopyOwner.PRIMARY);
0460: }
0461:
0462: /* (non-Javadoc)
0463: * @see org.eclipse.jdt.core.ICodeAssist#codeComplete(int, org.eclipse.jdt.core.CompletionRequestor, org.eclipse.jdt.core.WorkingCopyOwner)
0464: */
0465: public void codeComplete(int offset, CompletionRequestor requestor,
0466: WorkingCopyOwner workingCopyOwner)
0467: throws JavaModelException {
0468: codeComplete(
0469: this ,
0470: isWorkingCopy() ? (org.eclipse.jdt.internal.compiler.env.ICompilationUnit) getOriginalElement()
0471: : this , offset, requestor, workingCopyOwner);
0472: }
0473:
0474: /**
0475: * @see ICodeAssist#codeSelect(int, int)
0476: */
0477: public IJavaElement[] codeSelect(int offset, int length)
0478: throws JavaModelException {
0479: return codeSelect(offset, length,
0480: DefaultWorkingCopyOwner.PRIMARY);
0481: }
0482:
0483: /**
0484: * @see ICodeAssist#codeSelect(int, int, WorkingCopyOwner)
0485: */
0486: public IJavaElement[] codeSelect(int offset, int length,
0487: WorkingCopyOwner workingCopyOwner)
0488: throws JavaModelException {
0489: return super .codeSelect(this , offset, length, workingCopyOwner);
0490: }
0491:
0492: /**
0493: * @see IWorkingCopy#commit(boolean, IProgressMonitor)
0494: * @deprecated
0495: */
0496: public void commit(boolean force, IProgressMonitor monitor)
0497: throws JavaModelException {
0498: commitWorkingCopy(force, monitor);
0499: }
0500:
0501: /**
0502: * @see ICompilationUnit#commitWorkingCopy(boolean, IProgressMonitor)
0503: */
0504: public void commitWorkingCopy(boolean force,
0505: IProgressMonitor monitor) throws JavaModelException {
0506: CommitWorkingCopyOperation op = new CommitWorkingCopyOperation(
0507: this , force);
0508: op.runOperation(monitor);
0509: }
0510:
0511: /**
0512: * @see ISourceManipulation#copy(IJavaElement, IJavaElement, String, boolean, IProgressMonitor)
0513: */
0514: public void copy(IJavaElement container, IJavaElement sibling,
0515: String rename, boolean force, IProgressMonitor monitor)
0516: throws JavaModelException {
0517: if (container == null) {
0518: throw new IllegalArgumentException(
0519: Messages.operation_nullContainer);
0520: }
0521: IJavaElement[] elements = new IJavaElement[] { this };
0522: IJavaElement[] containers = new IJavaElement[] { container };
0523: String[] renamings = null;
0524: if (rename != null) {
0525: renamings = new String[] { rename };
0526: }
0527: getJavaModel().copy(elements, containers, null, renamings,
0528: force, monitor);
0529: }
0530:
0531: /**
0532: * Returns a new element info for this element.
0533: */
0534: protected Object createElementInfo() {
0535: return new CompilationUnitElementInfo();
0536: }
0537:
0538: /**
0539: * @see ICompilationUnit#createImport(String, IJavaElement, IProgressMonitor)
0540: */
0541: public IImportDeclaration createImport(String importName,
0542: IJavaElement sibling, IProgressMonitor monitor)
0543: throws JavaModelException {
0544: return createImport(importName, sibling, Flags.AccDefault,
0545: monitor);
0546: }
0547:
0548: /**
0549: * @see ICompilationUnit#createImport(String, IJavaElement, int, IProgressMonitor)
0550: * @since 3.0
0551: */
0552: public IImportDeclaration createImport(String importName,
0553: IJavaElement sibling, int flags, IProgressMonitor monitor)
0554: throws JavaModelException {
0555: CreateImportOperation op = new CreateImportOperation(
0556: importName, this , flags);
0557: if (sibling != null) {
0558: op.createBefore(sibling);
0559: }
0560: op.runOperation(monitor);
0561: return getImport(importName);
0562: }
0563:
0564: /**
0565: * @see ICompilationUnit#createPackageDeclaration(String, IProgressMonitor)
0566: */
0567: public IPackageDeclaration createPackageDeclaration(String pkg,
0568: IProgressMonitor monitor) throws JavaModelException {
0569:
0570: CreatePackageDeclarationOperation op = new CreatePackageDeclarationOperation(
0571: pkg, this );
0572: op.runOperation(monitor);
0573: return getPackageDeclaration(pkg);
0574: }
0575:
0576: /**
0577: * @see ICompilationUnit#createType(String, IJavaElement, boolean, IProgressMonitor)
0578: */
0579: public IType createType(String content, IJavaElement sibling,
0580: boolean force, IProgressMonitor monitor)
0581: throws JavaModelException {
0582: if (!exists()) {
0583: //autogenerate this compilation unit
0584: IPackageFragment pkg = (IPackageFragment) getParent();
0585: String source = ""; //$NON-NLS-1$
0586: if (!pkg.isDefaultPackage()) {
0587: //not the default package...add the package declaration
0588: String lineSeparator = Util.getLineSeparator(
0589: null/*no existing source*/, getJavaProject());
0590: source = "package " + pkg.getElementName() + ";" + lineSeparator + lineSeparator; //$NON-NLS-1$ //$NON-NLS-2$
0591: }
0592: CreateCompilationUnitOperation op = new CreateCompilationUnitOperation(
0593: pkg, this .name, source, force);
0594: op.runOperation(monitor);
0595: }
0596: CreateTypeOperation op = new CreateTypeOperation(this , content,
0597: force);
0598: if (sibling != null) {
0599: op.createBefore(sibling);
0600: }
0601: op.runOperation(monitor);
0602: return (IType) op.getResultElements()[0];
0603: }
0604:
0605: /**
0606: * @see ISourceManipulation#delete(boolean, IProgressMonitor)
0607: */
0608: public void delete(boolean force, IProgressMonitor monitor)
0609: throws JavaModelException {
0610: IJavaElement[] elements = new IJavaElement[] { this };
0611: getJavaModel().delete(elements, force, monitor);
0612: }
0613:
0614: /**
0615: * @see IWorkingCopy#destroy()
0616: * @deprecated
0617: */
0618: public void destroy() {
0619: try {
0620: discardWorkingCopy();
0621: } catch (JavaModelException e) {
0622: if (JavaModelManager.VERBOSE)
0623: e.printStackTrace();
0624: }
0625: }
0626:
0627: /*
0628: * @see ICompilationUnit#discardWorkingCopy
0629: */
0630: public void discardWorkingCopy() throws JavaModelException {
0631: // discard working copy and its children
0632: DiscardWorkingCopyOperation op = new DiscardWorkingCopyOperation(
0633: this );
0634: op.runOperation(null);
0635: }
0636:
0637: /**
0638: * Returns true if this handle represents the same Java element
0639: * as the given handle.
0640: *
0641: * @see Object#equals(java.lang.Object)
0642: */
0643: public boolean equals(Object obj) {
0644: if (!(obj instanceof CompilationUnit))
0645: return false;
0646: CompilationUnit other = (CompilationUnit) obj;
0647: return this .owner.equals(other.owner) && super .equals(obj);
0648: }
0649:
0650: public boolean exists() {
0651: // working copy always exists in the model until it is gotten rid of (even if not on classpath)
0652: if (getPerWorkingCopyInfo() != null)
0653: return true;
0654:
0655: // if not a working copy, it exists only if it is a primary compilation unit
0656: return isPrimary()
0657: && validateCompilationUnit(getResource()).isOK();
0658: }
0659:
0660: /**
0661: * @see ICompilationUnit#findElements(IJavaElement)
0662: */
0663: public IJavaElement[] findElements(IJavaElement element) {
0664: ArrayList children = new ArrayList();
0665: while (element != null
0666: && element.getElementType() != IJavaElement.COMPILATION_UNIT) {
0667: children.add(element);
0668: element = element.getParent();
0669: }
0670: if (element == null)
0671: return null;
0672: IJavaElement currentElement = this ;
0673: for (int i = children.size() - 1; i >= 0; i--) {
0674: SourceRefElement child = (SourceRefElement) children.get(i);
0675: switch (child.getElementType()) {
0676: case IJavaElement.PACKAGE_DECLARATION:
0677: currentElement = ((ICompilationUnit) currentElement)
0678: .getPackageDeclaration(child.getElementName());
0679: break;
0680: case IJavaElement.IMPORT_CONTAINER:
0681: currentElement = ((ICompilationUnit) currentElement)
0682: .getImportContainer();
0683: break;
0684: case IJavaElement.IMPORT_DECLARATION:
0685: currentElement = ((IImportContainer) currentElement)
0686: .getImport(child.getElementName());
0687: break;
0688: case IJavaElement.TYPE:
0689: switch (currentElement.getElementType()) {
0690: case IJavaElement.COMPILATION_UNIT:
0691: currentElement = ((ICompilationUnit) currentElement)
0692: .getType(child.getElementName());
0693: break;
0694: case IJavaElement.TYPE:
0695: currentElement = ((IType) currentElement)
0696: .getType(child.getElementName());
0697: break;
0698: case IJavaElement.FIELD:
0699: case IJavaElement.INITIALIZER:
0700: case IJavaElement.METHOD:
0701: currentElement = ((IMember) currentElement)
0702: .getType(child.getElementName(),
0703: child.occurrenceCount);
0704: break;
0705: }
0706: break;
0707: case IJavaElement.INITIALIZER:
0708: currentElement = ((IType) currentElement)
0709: .getInitializer(child.occurrenceCount);
0710: break;
0711: case IJavaElement.FIELD:
0712: currentElement = ((IType) currentElement)
0713: .getField(child.getElementName());
0714: break;
0715: case IJavaElement.METHOD:
0716: currentElement = ((IType) currentElement).getMethod(
0717: child.getElementName(), ((IMethod) child)
0718: .getParameterTypes());
0719: break;
0720: }
0721:
0722: }
0723: if (currentElement != null && currentElement.exists()) {
0724: return new IJavaElement[] { currentElement };
0725: } else {
0726: return null;
0727: }
0728: }
0729:
0730: /**
0731: * @see ICompilationUnit#findPrimaryType()
0732: */
0733: public IType findPrimaryType() {
0734: String typeName = Util
0735: .getNameWithoutJavaLikeExtension(getElementName());
0736: IType primaryType = getType(typeName);
0737: if (primaryType.exists()) {
0738: return primaryType;
0739: }
0740: return null;
0741: }
0742:
0743: /**
0744: * @see IWorkingCopy#findSharedWorkingCopy(IBufferFactory)
0745: * @deprecated
0746: */
0747: public IJavaElement findSharedWorkingCopy(IBufferFactory factory) {
0748:
0749: // if factory is null, default factory must be used
0750: if (factory == null)
0751: factory = this .getBufferManager().getDefaultBufferFactory();
0752:
0753: return findWorkingCopy(BufferFactoryWrapper.create(factory));
0754: }
0755:
0756: /**
0757: * @see ICompilationUnit#findWorkingCopy(WorkingCopyOwner)
0758: */
0759: public ICompilationUnit findWorkingCopy(
0760: WorkingCopyOwner workingCopyOwner) {
0761: CompilationUnit cu = new CompilationUnit(
0762: (PackageFragment) this .parent, getElementName(),
0763: workingCopyOwner);
0764: if (workingCopyOwner == DefaultWorkingCopyOwner.PRIMARY) {
0765: return cu;
0766: } else {
0767: // must be a working copy
0768: JavaModelManager.PerWorkingCopyInfo perWorkingCopyInfo = cu
0769: .getPerWorkingCopyInfo();
0770: if (perWorkingCopyInfo != null) {
0771: return perWorkingCopyInfo.getWorkingCopy();
0772: } else {
0773: return null;
0774: }
0775: }
0776: }
0777:
0778: /**
0779: * @see ICompilationUnit#getAllTypes()
0780: */
0781: public IType[] getAllTypes() throws JavaModelException {
0782: IJavaElement[] types = getTypes();
0783: int i;
0784: ArrayList allTypes = new ArrayList(types.length);
0785: ArrayList typesToTraverse = new ArrayList(types.length);
0786: for (i = 0; i < types.length; i++) {
0787: typesToTraverse.add(types[i]);
0788: }
0789: while (!typesToTraverse.isEmpty()) {
0790: IType type = (IType) typesToTraverse.get(0);
0791: typesToTraverse.remove(type);
0792: allTypes.add(type);
0793: types = type.getTypes();
0794: for (i = 0; i < types.length; i++) {
0795: typesToTraverse.add(types[i]);
0796: }
0797: }
0798: IType[] arrayOfAllTypes = new IType[allTypes.size()];
0799: allTypes.toArray(arrayOfAllTypes);
0800: return arrayOfAllTypes;
0801: }
0802:
0803: /**
0804: * @see IMember#getCompilationUnit()
0805: */
0806: public ICompilationUnit getCompilationUnit() {
0807: return this ;
0808: }
0809:
0810: /**
0811: * @see org.eclipse.jdt.internal.compiler.env.ICompilationUnit#getContents()
0812: */
0813: public char[] getContents() {
0814: IBuffer buffer = getBufferManager().getBuffer(this );
0815: if (buffer == null) {
0816: // no need to force opening of CU to get the content
0817: // also this cannot be a working copy, as its buffer is never closed while the working copy is alive
0818: try {
0819: return Util
0820: .getResourceContentsAsCharArray((IFile) getResource());
0821: } catch (JavaModelException e) {
0822: return CharOperation.NO_CHAR;
0823: }
0824: }
0825: char[] contents = buffer.getCharacters();
0826: if (contents == null) // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=129814
0827: return CharOperation.NO_CHAR;
0828: return contents;
0829: }
0830:
0831: /**
0832: * A compilation unit has a corresponding resource unless it is contained
0833: * in a jar.
0834: *
0835: * @see IJavaElement#getCorrespondingResource()
0836: */
0837: public IResource getCorrespondingResource()
0838: throws JavaModelException {
0839: PackageFragmentRoot root = getPackageFragmentRoot();
0840: if (root == null || root.isArchive()) {
0841: return null;
0842: } else {
0843: return getUnderlyingResource();
0844: }
0845: }
0846:
0847: /**
0848: * @see ICompilationUnit#getElementAt(int)
0849: */
0850: public IJavaElement getElementAt(int position)
0851: throws JavaModelException {
0852:
0853: IJavaElement e = getSourceElementAt(position);
0854: if (e == this ) {
0855: return null;
0856: } else {
0857: return e;
0858: }
0859: }
0860:
0861: public String getElementName() {
0862: return this .name;
0863: }
0864:
0865: /**
0866: * @see IJavaElement
0867: */
0868: public int getElementType() {
0869: return COMPILATION_UNIT;
0870: }
0871:
0872: /**
0873: * @see org.eclipse.jdt.internal.compiler.env.IDependent#getFileName()
0874: */
0875: public char[] getFileName() {
0876: return getPath().toString().toCharArray();
0877: }
0878:
0879: /*
0880: * @see JavaElement
0881: */
0882: public IJavaElement getHandleFromMemento(String token,
0883: MementoTokenizer memento, WorkingCopyOwner workingCopyOwner) {
0884: switch (token.charAt(0)) {
0885: case JEM_IMPORTDECLARATION:
0886: JavaElement container = (JavaElement) getImportContainer();
0887: return container.getHandleFromMemento(token, memento,
0888: workingCopyOwner);
0889: case JEM_PACKAGEDECLARATION:
0890: if (!memento.hasMoreTokens())
0891: return this ;
0892: String pkgName = memento.nextToken();
0893: JavaElement pkgDecl = (JavaElement) getPackageDeclaration(pkgName);
0894: return pkgDecl.getHandleFromMemento(memento,
0895: workingCopyOwner);
0896: case JEM_TYPE:
0897: if (!memento.hasMoreTokens())
0898: return this ;
0899: String typeName = memento.nextToken();
0900: JavaElement type = (JavaElement) getType(typeName);
0901: return type.getHandleFromMemento(memento, workingCopyOwner);
0902: }
0903: return null;
0904: }
0905:
0906: /**
0907: * @see JavaElement#getHandleMementoDelimiter()
0908: */
0909: protected char getHandleMementoDelimiter() {
0910: return JavaElement.JEM_COMPILATIONUNIT;
0911: }
0912:
0913: /**
0914: * @see ICompilationUnit#getImport(String)
0915: */
0916: public IImportDeclaration getImport(String importName) {
0917: return getImportContainer().getImport(importName);
0918: }
0919:
0920: /**
0921: * @see ICompilationUnit#getImportContainer()
0922: */
0923: public IImportContainer getImportContainer() {
0924: return new ImportContainer(this );
0925: }
0926:
0927: /**
0928: * @see ICompilationUnit#getImports()
0929: */
0930: public IImportDeclaration[] getImports() throws JavaModelException {
0931: IImportContainer container = getImportContainer();
0932: JavaModelManager manager = JavaModelManager
0933: .getJavaModelManager();
0934: Object info = manager.getInfo(container);
0935: if (info == null) {
0936: if (manager.getInfo(this ) != null)
0937: // CU was opened, but no import container, then no imports
0938: return NO_IMPORTS;
0939: else {
0940: open(null); // force opening of CU
0941: info = manager.getInfo(container);
0942: if (info == null)
0943: // after opening, if no import container, then no imports
0944: return NO_IMPORTS;
0945: }
0946: }
0947: IJavaElement[] elements = ((JavaElementInfo) info).children;
0948: int length = elements.length;
0949: IImportDeclaration[] imports = new IImportDeclaration[length];
0950: System.arraycopy(elements, 0, imports, 0, length);
0951: return imports;
0952: }
0953:
0954: /**
0955: * @see IMember#getTypeRoot()
0956: */
0957: public ITypeRoot getTypeRoot() {
0958: return this ;
0959: }
0960:
0961: /**
0962: * @see org.eclipse.jdt.internal.compiler.env.ICompilationUnit#getMainTypeName()
0963: */
0964: public char[] getMainTypeName() {
0965: return Util.getNameWithoutJavaLikeExtension(getElementName())
0966: .toCharArray();
0967: }
0968:
0969: /**
0970: * @see IWorkingCopy#getOriginal(IJavaElement)
0971: * @deprecated
0972: */
0973: public IJavaElement getOriginal(IJavaElement workingCopyElement) {
0974: // backward compatibility
0975: if (!isWorkingCopy())
0976: return null;
0977: CompilationUnit cu = (CompilationUnit) workingCopyElement
0978: .getAncestor(COMPILATION_UNIT);
0979: if (cu == null || !this .owner.equals(cu.owner)) {
0980: return null;
0981: }
0982:
0983: return workingCopyElement.getPrimaryElement();
0984: }
0985:
0986: /**
0987: * @see IWorkingCopy#getOriginalElement()
0988: * @deprecated
0989: */
0990: public IJavaElement getOriginalElement() {
0991: // backward compatibility
0992: if (!isWorkingCopy())
0993: return null;
0994:
0995: return getPrimaryElement();
0996: }
0997:
0998: /*
0999: * @see ICompilationUnit#getOwner()
1000: */
1001: public WorkingCopyOwner getOwner() {
1002: return isPrimary() || !isWorkingCopy() ? null : this .owner;
1003: }
1004:
1005: /**
1006: * @see ICompilationUnit#getPackageDeclaration(String)
1007: */
1008: public IPackageDeclaration getPackageDeclaration(String pkg) {
1009: return new PackageDeclaration(this , pkg);
1010: }
1011:
1012: /**
1013: * @see ICompilationUnit#getPackageDeclarations()
1014: */
1015: public IPackageDeclaration[] getPackageDeclarations()
1016: throws JavaModelException {
1017: ArrayList list = getChildrenOfType(PACKAGE_DECLARATION);
1018: IPackageDeclaration[] array = new IPackageDeclaration[list
1019: .size()];
1020: list.toArray(array);
1021: return array;
1022: }
1023:
1024: /**
1025: * @see org.eclipse.jdt.internal.compiler.env.ICompilationUnit#getPackageName()
1026: */
1027: public char[][] getPackageName() {
1028: PackageFragment packageFragment = (PackageFragment) getParent();
1029: if (packageFragment == null)
1030: return CharOperation.NO_CHAR_CHAR;
1031: return Util.toCharArrays(packageFragment.names);
1032: }
1033:
1034: /**
1035: * @see IJavaElement#getPath()
1036: */
1037: public IPath getPath() {
1038: PackageFragmentRoot root = getPackageFragmentRoot();
1039: if (root == null)
1040: return new Path(getElementName()); // working copy not in workspace
1041: if (root.isArchive()) {
1042: return root.getPath();
1043: } else {
1044: return getParent().getPath().append(getElementName());
1045: }
1046: }
1047:
1048: /*
1049: * Returns the per working copy info for the receiver, or null if none exist.
1050: * Note: the use count of the per working copy info is NOT incremented.
1051: */
1052: public JavaModelManager.PerWorkingCopyInfo getPerWorkingCopyInfo() {
1053: return JavaModelManager
1054: .getJavaModelManager()
1055: .getPerWorkingCopyInfo(this , false/*don't create*/,
1056: false/*don't record usage*/, null/*no problem requestor needed*/);
1057: }
1058:
1059: /*
1060: * @see ICompilationUnit#getPrimary()
1061: */
1062: public ICompilationUnit getPrimary() {
1063: return (ICompilationUnit) getPrimaryElement(true);
1064: }
1065:
1066: /*
1067: * @see JavaElement#getPrimaryElement(boolean)
1068: */
1069: public IJavaElement getPrimaryElement(boolean checkOwner) {
1070: if (checkOwner && isPrimary())
1071: return this ;
1072: return new CompilationUnit((PackageFragment) getParent(),
1073: getElementName(), DefaultWorkingCopyOwner.PRIMARY);
1074: }
1075:
1076: /**
1077: * @see IJavaElement#getResource()
1078: */
1079: public IResource getResource() {
1080: PackageFragmentRoot root = getPackageFragmentRoot();
1081: if (root == null)
1082: return null; // working copy not in workspace
1083: if (root.isArchive()) {
1084: return root.getResource();
1085: } else {
1086: return ((IContainer) getParent().getResource())
1087: .getFile(new Path(getElementName()));
1088: }
1089: }
1090:
1091: /**
1092: * @see ISourceReference#getSource()
1093: */
1094: public String getSource() throws JavaModelException {
1095: IBuffer buffer = getBuffer();
1096: if (buffer == null)
1097: return ""; //$NON-NLS-1$
1098: return buffer.getContents();
1099: }
1100:
1101: /**
1102: * @see ISourceReference#getSourceRange()
1103: */
1104: public ISourceRange getSourceRange() throws JavaModelException {
1105: return ((CompilationUnitElementInfo) getElementInfo())
1106: .getSourceRange();
1107: }
1108:
1109: /**
1110: * @see ICompilationUnit#getType(String)
1111: */
1112: public IType getType(String typeName) {
1113: return new SourceType(this , typeName);
1114: }
1115:
1116: /**
1117: * @see ICompilationUnit#getTypes()
1118: */
1119: public IType[] getTypes() throws JavaModelException {
1120: ArrayList list = getChildrenOfType(TYPE);
1121: IType[] array = new IType[list.size()];
1122: list.toArray(array);
1123: return array;
1124: }
1125:
1126: /**
1127: * @see IJavaElement
1128: */
1129: public IResource getUnderlyingResource() throws JavaModelException {
1130: if (isWorkingCopy() && !isPrimary())
1131: return null;
1132: return super .getUnderlyingResource();
1133: }
1134:
1135: /**
1136: * @see IWorkingCopy#getSharedWorkingCopy(IProgressMonitor, IBufferFactory, IProblemRequestor)
1137: * @deprecated
1138: */
1139: public IJavaElement getSharedWorkingCopy(IProgressMonitor pm,
1140: IBufferFactory factory, IProblemRequestor problemRequestor)
1141: throws JavaModelException {
1142:
1143: // if factory is null, default factory must be used
1144: if (factory == null)
1145: factory = this .getBufferManager().getDefaultBufferFactory();
1146:
1147: return getWorkingCopy(BufferFactoryWrapper.create(factory),
1148: problemRequestor, pm);
1149: }
1150:
1151: /**
1152: * @see IWorkingCopy#getWorkingCopy()
1153: * @deprecated
1154: */
1155: public IJavaElement getWorkingCopy() throws JavaModelException {
1156: return getWorkingCopy(null);
1157: }
1158:
1159: /**
1160: * @see ICompilationUnit#getWorkingCopy(IProgressMonitor)
1161: */
1162: public ICompilationUnit getWorkingCopy(IProgressMonitor monitor)
1163: throws JavaModelException {
1164: return getWorkingCopy(new WorkingCopyOwner() {/*non shared working copy*/
1165: }, null/*no problem requestor*/, monitor);
1166: }
1167:
1168: /**
1169: * @see ITypeRoot#getWorkingCopy(WorkingCopyOwner, IProgressMonitor)
1170: */
1171: public ICompilationUnit getWorkingCopy(
1172: WorkingCopyOwner workingCopyOwner, IProgressMonitor monitor)
1173: throws JavaModelException {
1174: return getWorkingCopy(workingCopyOwner, null, monitor);
1175: }
1176:
1177: /**
1178: * @see IWorkingCopy#getWorkingCopy(IProgressMonitor, IBufferFactory, IProblemRequestor)
1179: * @deprecated
1180: */
1181: public IJavaElement getWorkingCopy(IProgressMonitor monitor,
1182: IBufferFactory factory, IProblemRequestor problemRequestor)
1183: throws JavaModelException {
1184: return getWorkingCopy(BufferFactoryWrapper.create(factory),
1185: problemRequestor, monitor);
1186: }
1187:
1188: /**
1189: * @see ICompilationUnit#getWorkingCopy(WorkingCopyOwner, IProblemRequestor, IProgressMonitor)
1190: * @deprecated
1191: */
1192: public ICompilationUnit getWorkingCopy(
1193: WorkingCopyOwner workingCopyOwner,
1194: IProblemRequestor problemRequestor, IProgressMonitor monitor)
1195: throws JavaModelException {
1196: if (!isPrimary())
1197: return this ;
1198:
1199: JavaModelManager manager = JavaModelManager
1200: .getJavaModelManager();
1201:
1202: CompilationUnit workingCopy = new CompilationUnit(
1203: (PackageFragment) getParent(), getElementName(),
1204: workingCopyOwner);
1205: JavaModelManager.PerWorkingCopyInfo perWorkingCopyInfo = manager
1206: .getPerWorkingCopyInfo(workingCopy,
1207: false/*don't create*/, true/*record usage*/,
1208: null/*not used since don't create*/);
1209: if (perWorkingCopyInfo != null) {
1210: return perWorkingCopyInfo.getWorkingCopy(); // return existing handle instead of the one created above
1211: }
1212: BecomeWorkingCopyOperation op = new BecomeWorkingCopyOperation(
1213: workingCopy, problemRequestor);
1214: op.runOperation(monitor);
1215: return workingCopy;
1216: }
1217:
1218: /**
1219: * @see Openable#hasBuffer()
1220: */
1221: protected boolean hasBuffer() {
1222: return true;
1223: }
1224:
1225: /*
1226: * @see ICompilationUnit#hasResourceChanged()
1227: */
1228: public boolean hasResourceChanged() {
1229: if (!isWorkingCopy())
1230: return false;
1231:
1232: // if resource got deleted, then #getModificationStamp() will answer IResource.NULL_STAMP, which is always different from the cached
1233: // timestamp
1234: Object info = JavaModelManager.getJavaModelManager().getInfo(
1235: this );
1236: if (info == null)
1237: return false;
1238: IResource resource = getResource();
1239: if (resource == null)
1240: return false;
1241: return ((CompilationUnitElementInfo) info).timestamp != resource
1242: .getModificationStamp();
1243: }
1244:
1245: /**
1246: * @see IWorkingCopy#isBasedOn(IResource)
1247: * @deprecated
1248: */
1249: public boolean isBasedOn(IResource resource) {
1250: if (!isWorkingCopy())
1251: return false;
1252: if (!getResource().equals(resource))
1253: return false;
1254: return !hasResourceChanged();
1255: }
1256:
1257: /**
1258: * @see IOpenable#isConsistent()
1259: */
1260: public boolean isConsistent() {
1261: return !JavaModelManager.getJavaModelManager()
1262: .getElementsOutOfSynchWithBuffers().contains(this );
1263: }
1264:
1265: public boolean isPrimary() {
1266: return this .owner == DefaultWorkingCopyOwner.PRIMARY;
1267: }
1268:
1269: /**
1270: * @see Openable#isSourceElement()
1271: */
1272: protected boolean isSourceElement() {
1273: return true;
1274: }
1275:
1276: protected IStatus validateCompilationUnit(IResource resource) {
1277: IPackageFragmentRoot root = getPackageFragmentRoot();
1278: // root never null as validation is not done for working copies
1279: try {
1280: if (root.getKind() != IPackageFragmentRoot.K_SOURCE)
1281: return new JavaModelStatus(
1282: IJavaModelStatusConstants.INVALID_ELEMENT_TYPES,
1283: root);
1284: } catch (JavaModelException e) {
1285: return e.getJavaModelStatus();
1286: }
1287: if (resource != null) {
1288: char[][] inclusionPatterns = ((PackageFragmentRoot) root)
1289: .fullInclusionPatternChars();
1290: char[][] exclusionPatterns = ((PackageFragmentRoot) root)
1291: .fullExclusionPatternChars();
1292: if (Util.isExcluded(resource, inclusionPatterns,
1293: exclusionPatterns))
1294: return new JavaModelStatus(
1295: IJavaModelStatusConstants.ELEMENT_NOT_ON_CLASSPATH,
1296: this );
1297: if (!resource.isAccessible())
1298: return new JavaModelStatus(
1299: IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST,
1300: this );
1301: }
1302: IJavaProject project = getJavaProject();
1303: return JavaConventions.validateCompilationUnitName(
1304: getElementName(), project.getOption(
1305: JavaCore.COMPILER_SOURCE, true), project
1306: .getOption(JavaCore.COMPILER_COMPLIANCE, true));
1307: }
1308:
1309: /*
1310: * @see ICompilationUnit#isWorkingCopy()
1311: */
1312: public boolean isWorkingCopy() {
1313: // For backward compatibility, non primary working copies are always returning true; in removal
1314: // delta, clients can still check that element was a working copy before being discarded.
1315: return !isPrimary() || getPerWorkingCopyInfo() != null;
1316: }
1317:
1318: /**
1319: * @see IOpenable#makeConsistent(IProgressMonitor)
1320: */
1321: public void makeConsistent(IProgressMonitor monitor)
1322: throws JavaModelException {
1323: makeConsistent(NO_AST, false/*don't resolve bindings*/,
1324: 0 /* don't perform statements recovery */,
1325: null/*don't collect problems but report them*/,
1326: monitor);
1327: }
1328:
1329: public org.eclipse.jdt.core.dom.CompilationUnit makeConsistent(
1330: int astLevel, boolean resolveBindings, int reconcileFlags,
1331: HashMap problems, IProgressMonitor monitor)
1332: throws JavaModelException {
1333: if (isConsistent())
1334: return null;
1335:
1336: // create a new info and make it the current info
1337: // (this will remove the info and its children just before storing the new infos)
1338: if (astLevel != NO_AST || problems != null) {
1339: ASTHolderCUInfo info = new ASTHolderCUInfo();
1340: info.astLevel = astLevel;
1341: info.resolveBindings = resolveBindings;
1342: info.reconcileFlags = reconcileFlags;
1343: info.problems = problems;
1344: openWhenClosed(info, monitor);
1345: org.eclipse.jdt.core.dom.CompilationUnit result = info.ast;
1346: info.ast = null;
1347: return result;
1348: } else {
1349: openWhenClosed(createElementInfo(), monitor);
1350: return null;
1351: }
1352: }
1353:
1354: /**
1355: * @see ISourceManipulation#move(IJavaElement, IJavaElement, String, boolean, IProgressMonitor)
1356: */
1357: public void move(IJavaElement container, IJavaElement sibling,
1358: String rename, boolean force, IProgressMonitor monitor)
1359: throws JavaModelException {
1360: if (container == null) {
1361: throw new IllegalArgumentException(
1362: Messages.operation_nullContainer);
1363: }
1364: IJavaElement[] elements = new IJavaElement[] { this };
1365: IJavaElement[] containers = new IJavaElement[] { container };
1366:
1367: String[] renamings = null;
1368: if (rename != null) {
1369: renamings = new String[] { rename };
1370: }
1371: getJavaModel().move(elements, containers, null, renamings,
1372: force, monitor);
1373: }
1374:
1375: /**
1376: * @see Openable#openBuffer(IProgressMonitor, Object)
1377: */
1378: protected IBuffer openBuffer(IProgressMonitor pm, Object info)
1379: throws JavaModelException {
1380:
1381: // create buffer
1382: BufferManager bufManager = getBufferManager();
1383: boolean isWorkingCopy = isWorkingCopy();
1384: IBuffer buffer = isWorkingCopy ? this .owner.createBuffer(this )
1385: : BufferManager.createBuffer(this );
1386: if (buffer == null)
1387: return null;
1388:
1389: // synchronize to ensure that 2 threads are not putting 2 different buffers at the same time
1390: // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=146331
1391: synchronized (bufManager) {
1392: IBuffer existingBuffer = bufManager.getBuffer(this );
1393: if (existingBuffer != null)
1394: return existingBuffer;
1395:
1396: // set the buffer source
1397: if (buffer.getCharacters() == null) {
1398: if (isWorkingCopy) {
1399: ICompilationUnit original;
1400: if (!isPrimary()
1401: && (original = new CompilationUnit(
1402: (PackageFragment) getParent(),
1403: getElementName(),
1404: DefaultWorkingCopyOwner.PRIMARY))
1405: .isOpen()) {
1406: buffer.setContents(original.getSource());
1407: } else {
1408: IFile file = (IFile) getResource();
1409: if (file == null || !file.exists()) {
1410: // initialize buffer with empty contents
1411: buffer.setContents(CharOperation.NO_CHAR);
1412: } else {
1413: buffer
1414: .setContents(Util
1415: .getResourceContentsAsCharArray(file));
1416: }
1417: }
1418: } else {
1419: IFile file = (IFile) this .getResource();
1420: if (file == null || !file.exists())
1421: throw newNotPresentException();
1422: buffer.setContents(Util
1423: .getResourceContentsAsCharArray(file));
1424: }
1425: }
1426:
1427: // add buffer to buffer cache
1428: // note this may cause existing buffers to be removed from the buffer cache, but only primary compilation unit's buffer
1429: // can be closed, thus no call to a client's IBuffer#close() can be done in this synchronized block.
1430: bufManager.addBuffer(buffer);
1431:
1432: // listen to buffer changes
1433: buffer.addBufferChangedListener(this );
1434: }
1435: return buffer;
1436: }
1437:
1438: protected void openParent(Object childInfo, HashMap newElements,
1439: IProgressMonitor pm) throws JavaModelException {
1440: if (!isWorkingCopy())
1441: super .openParent(childInfo, newElements, pm);
1442: // don't open parent for a working copy to speed up the first becomeWorkingCopy
1443: // (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=89411)
1444: }
1445:
1446: /**
1447: * @see ICompilationUnit#reconcile()
1448: * @deprecated
1449: */
1450: public IMarker[] reconcile() throws JavaModelException {
1451: reconcile(NO_AST, false/*don't force problem detection*/,
1452: false, null/*use primary owner*/, null/*no progress monitor*/);
1453: return null;
1454: }
1455:
1456: /**
1457: * @see ICompilationUnit#reconcile(int, boolean, WorkingCopyOwner, IProgressMonitor)
1458: */
1459: public void reconcile(boolean forceProblemDetection,
1460: IProgressMonitor monitor) throws JavaModelException {
1461: reconcile(
1462: NO_AST,
1463: forceProblemDetection ? ICompilationUnit.FORCE_PROBLEM_DETECTION
1464: : 0, null/*use primary owner*/, monitor);
1465: }
1466:
1467: /**
1468: * @see ICompilationUnit#reconcile(int, boolean, WorkingCopyOwner, IProgressMonitor)
1469: * @since 3.0
1470: */
1471: public org.eclipse.jdt.core.dom.CompilationUnit reconcile(
1472: int astLevel, boolean forceProblemDetection,
1473: WorkingCopyOwner workingCopyOwner, IProgressMonitor monitor)
1474: throws JavaModelException {
1475: return reconcile(
1476: astLevel,
1477: forceProblemDetection ? ICompilationUnit.FORCE_PROBLEM_DETECTION
1478: : 0, workingCopyOwner, monitor);
1479: }
1480:
1481: /**
1482: * @see ICompilationUnit#reconcile(int, boolean, WorkingCopyOwner, IProgressMonitor)
1483: * @since 3.0
1484: */
1485: public org.eclipse.jdt.core.dom.CompilationUnit reconcile(
1486: int astLevel, boolean forceProblemDetection,
1487: boolean enableStatementsRecovery,
1488: WorkingCopyOwner workingCopyOwner, IProgressMonitor monitor)
1489: throws JavaModelException {
1490: int flags = 0;
1491: if (forceProblemDetection)
1492: flags |= ICompilationUnit.FORCE_PROBLEM_DETECTION;
1493: if (enableStatementsRecovery)
1494: flags |= ICompilationUnit.ENABLE_STATEMENTS_RECOVERY;
1495: return reconcile(astLevel, flags, workingCopyOwner, monitor);
1496: }
1497:
1498: public org.eclipse.jdt.core.dom.CompilationUnit reconcile(
1499: int astLevel, int reconcileFlags,
1500: WorkingCopyOwner workingCopyOwner, IProgressMonitor monitor)
1501: throws JavaModelException {
1502:
1503: if (!isWorkingCopy())
1504: return null; // Reconciling is not supported on non working copies
1505: if (workingCopyOwner == null)
1506: workingCopyOwner = DefaultWorkingCopyOwner.PRIMARY;
1507:
1508: PerformanceStats stats = null;
1509: if (ReconcileWorkingCopyOperation.PERF) {
1510: stats = PerformanceStats.getStats(
1511: JavaModelManager.RECONCILE_PERF, this );
1512: stats.startRun(new String(this .getFileName()));
1513: }
1514: ReconcileWorkingCopyOperation op = new ReconcileWorkingCopyOperation(
1515: this , astLevel, reconcileFlags, workingCopyOwner);
1516: JavaModelManager manager = JavaModelManager
1517: .getJavaModelManager();
1518: try {
1519: manager.cacheZipFiles(); // cache zip files for performance (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=134172)
1520: op.runOperation(monitor);
1521: } finally {
1522: manager.flushZipFiles();
1523: }
1524: if (ReconcileWorkingCopyOperation.PERF) {
1525: stats.endRun();
1526: }
1527: return op.ast;
1528: }
1529:
1530: /**
1531: * @see ISourceManipulation#rename(String, boolean, IProgressMonitor)
1532: */
1533: public void rename(String newName, boolean force,
1534: IProgressMonitor monitor) throws JavaModelException {
1535: if (newName == null) {
1536: throw new IllegalArgumentException(
1537: Messages.operation_nullName);
1538: }
1539: IJavaElement[] elements = new IJavaElement[] { this };
1540: IJavaElement[] dests = new IJavaElement[] { this .getParent() };
1541: String[] renamings = new String[] { newName };
1542: getJavaModel().rename(elements, dests, renamings, force,
1543: monitor);
1544: }
1545:
1546: /*
1547: * @see ICompilationUnit
1548: */
1549: public void restore() throws JavaModelException {
1550:
1551: if (!isWorkingCopy())
1552: return;
1553:
1554: CompilationUnit original = (CompilationUnit) getOriginalElement();
1555: IBuffer buffer = this .getBuffer();
1556: if (buffer == null)
1557: return;
1558: buffer.setContents(original.getContents());
1559: updateTimeStamp(original);
1560: makeConsistent(null);
1561: }
1562:
1563: /**
1564: * @see IOpenable
1565: */
1566: public void save(IProgressMonitor pm, boolean force)
1567: throws JavaModelException {
1568: if (isWorkingCopy()) {
1569: // no need to save the buffer for a working copy (this is a noop)
1570: reconcile(); // not simply makeConsistent, also computes fine-grain deltas
1571: // in case the working copy is being reconciled already (if not it would miss
1572: // one iteration of deltas).
1573: } else {
1574: super .save(pm, force);
1575: }
1576: }
1577:
1578: /**
1579: * Debugging purposes
1580: */
1581: protected void toStringInfo(int tab, StringBuffer buffer,
1582: Object info, boolean showResolvedInfo) {
1583: if (!isPrimary()) {
1584: buffer.append(this .tabString(tab));
1585: buffer.append("[Working copy] "); //$NON-NLS-1$
1586: toStringName(buffer);
1587: } else {
1588: if (isWorkingCopy()) {
1589: buffer.append(this .tabString(tab));
1590: buffer.append("[Working copy] "); //$NON-NLS-1$
1591: toStringName(buffer);
1592: if (info == null) {
1593: buffer.append(" (not open)"); //$NON-NLS-1$
1594: }
1595: } else {
1596: super .toStringInfo(tab, buffer, info, showResolvedInfo);
1597: }
1598: }
1599: }
1600:
1601: /*
1602: * Assume that this is a working copy
1603: */
1604: protected void updateTimeStamp(CompilationUnit original)
1605: throws JavaModelException {
1606: long timeStamp = ((IFile) original.getResource())
1607: .getModificationStamp();
1608: if (timeStamp == IResource.NULL_STAMP) {
1609: throw new JavaModelException(new JavaModelStatus(
1610: IJavaModelStatusConstants.INVALID_RESOURCE));
1611: }
1612: ((CompilationUnitElementInfo) getElementInfo()).timestamp = timeStamp;
1613: }
1614:
1615: }
|