| /******************************************************************************* |
| * Copyright (c) 2004 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Common Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/cpl-v10.html |
| * |
| * Contributors: |
| * Luzius Meisser - initial implementation |
| * Sian January - added eager parsing support |
| *******************************************************************************/ |
| package org.eclipse.ajdt.core.javaelements; |
| |
| import java.lang.reflect.Constructor; |
| import java.lang.reflect.InvocationTargetException; |
| import java.util.HashMap; |
| import java.util.Map; |
| |
| import org.aspectj.ajdt.internal.compiler.lookup.AjLookupEnvironment; |
| import org.aspectj.asm.IProgramElement; |
| import org.aspectj.org.eclipse.jdt.core.compiler.IProblem; |
| import org.aspectj.org.eclipse.jdt.internal.compiler.IProblemFactory; |
| import org.aspectj.org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; |
| import org.aspectj.org.eclipse.jdt.internal.compiler.impl.CompilerOptions; |
| import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope; |
| import org.aspectj.org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory; |
| import org.eclipse.ajdt.codeconversion.ConversionOptions; |
| import org.eclipse.ajdt.codeconversion.JavaCompatibleBuffer; |
| import org.eclipse.ajdt.internal.contentassist.ProposalRequestorFilter; |
| import org.eclipse.ajdt.internal.contentassist.ProposalRequestorWrapper; |
| import org.eclipse.ajdt.internal.core.AJWorkingCopyOwner; |
| import org.eclipse.ajdt.internal.parserbridge.AJCompilationUnitDeclarationWrapper; |
| import org.eclipse.ajdt.parserbridge.AJCompilationUnitProblemFinder; |
| import org.eclipse.ajdt.parserbridge.AJCompilationUnitStructureRequestor; |
| import org.eclipse.ajdt.parserbridge.AJSourceElementParser; |
| import org.eclipse.ajdt.parserbridge.AJSourceElementParser2; |
| import org.eclipse.core.resources.IContainer; |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IFolder; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.jdt.core.CompletionRequestor; |
| import org.eclipse.jdt.core.IBuffer; |
| import org.eclipse.jdt.core.ICompilationUnit; |
| import org.eclipse.jdt.core.IJavaElement; |
| import org.eclipse.jdt.core.IJavaModelStatusConstants; |
| import org.eclipse.jdt.core.IJavaProject; |
| import org.eclipse.jdt.core.IPackageFragmentRoot; |
| import org.eclipse.jdt.core.IProblemRequestor; |
| import org.eclipse.jdt.core.ISourceRange; |
| import org.eclipse.jdt.core.IType; |
| import org.eclipse.jdt.core.JavaCore; |
| import org.eclipse.jdt.core.JavaModelException; |
| import org.eclipse.jdt.core.WorkingCopyOwner; |
| import org.eclipse.jdt.core.dom.AST; |
| import org.eclipse.jdt.internal.compiler.problem.DefaultProblem; |
| import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities; |
| import org.eclipse.jdt.internal.core.BecomeWorkingCopyOperation; |
| import org.eclipse.jdt.internal.core.BufferManager; |
| import org.eclipse.jdt.internal.core.CompilationUnit; |
| import org.eclipse.jdt.internal.core.JavaElement; |
| import org.eclipse.jdt.internal.core.JavaModelManager; |
| import org.eclipse.jdt.internal.core.JavaModelStatus; |
| import org.eclipse.jdt.internal.core.JavaProject; |
| import org.eclipse.jdt.internal.core.OpenableElementInfo; |
| import org.eclipse.jdt.internal.core.PackageFragment; |
| import org.eclipse.jdt.internal.core.SourceType; |
| import org.eclipse.jdt.internal.core.util.MementoTokenizer; |
| |
| |
| /** |
| * An ICompilationUnit for .aj files. |
| * |
| * In order to obtain better interoperability with jdt, AJCompilationUnits pretend |
| * to have java syntax compatible contents. To get the real contents, |
| * requestOriginalContentMode() |
| * must be called before getting the Buffer. Please make sure to call |
| * discardOriginalContentMode() |
| * afterwards to get back into non-original mode. |
| * |
| * @author Luzius Meisser |
| */ |
| public class AJCompilationUnit extends CompilationUnit{ |
| |
| int originalContentMode = 0; |
| private IFile ajFile; |
| protected JavaCompatibleBuffer javaCompBuffer; |
| |
| |
| |
| public boolean isInOriginalContentMode(){ |
| return originalContentMode > 0; |
| } |
| |
| public void requestOriginalContentMode(){ |
| originalContentMode++; |
| } |
| |
| public void discardOriginalContentMode(){ |
| originalContentMode--; |
| } |
| |
| public AJCompilationUnit(IFile ajFile){ |
| super(CompilationUnitTools.getParentPackage(ajFile), ajFile.getName(), AJWorkingCopyOwner.INSTANCE); |
| this.ajFile = ajFile; |
| } |
| |
| /** |
| * @param fragment |
| * @param elementName |
| * @param workingCopyOwner |
| */ |
| public AJCompilationUnit(PackageFragment fragment, String elementName, WorkingCopyOwner workingCopyOwner) { |
| super(fragment, elementName, workingCopyOwner); |
| if(fragment.getResource() instanceof IProject) { |
| IProject p = (IProject)fragment.getResource(); |
| this.ajFile = (IFile)p.findMember(elementName); |
| } else { |
| IFolder f = (IFolder)fragment.getResource(); |
| this.ajFile = (IFile)f.findMember(elementName); |
| } |
| } |
| |
| public Object getElementInfo() throws JavaModelException{ |
| Object info = super.getElementInfo(); |
| return info; |
| } |
| |
| public char[] getMainTypeName(){ |
| String elementName = name; |
| //remove the .aj |
| elementName = elementName.substring(0, elementName.length() - 3); |
| return elementName.toCharArray(); |
| } |
| |
| /* Eclispe 3.1M3: prior to this we overrode isValidCompilationUnit, but now we need to |
| * override validateCompilationUnit, otherwise the check for valid name will fail on |
| * .aj files |
| */ |
| protected IStatus validateCompilationUnit(IResource resource) { |
| IPackageFragmentRoot root = getPackageFragmentRoot(); |
| try { |
| if (!(resource.getProject().exists()) || root.getKind() != IPackageFragmentRoot.K_SOURCE) |
| return new JavaModelStatus(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, root); |
| } catch (JavaModelException e) { |
| return e.getJavaModelStatus(); |
| } |
| return JavaModelStatus.OK_STATUS; |
| } |
| |
| public IResource getResource(){ |
| return ajFile; |
| } |
| |
| /* |
| * needs to return real path for organize imports |
| */ |
| public IPath getPath() { |
| return ajFile.getFullPath(); |
| } |
| |
| public IResource getUnderlyingResource() throws JavaModelException { |
| return ajFile; |
| } |
| |
| protected void generateInfos(Object info, HashMap newElements, IProgressMonitor monitor) throws JavaModelException { |
| if (!(info instanceof AJCompilationUnitInfo)){ |
| info = new AJCompilationUnitInfo(); |
| } |
| super.generateInfos(info, newElements, monitor); |
| } |
| |
| |
| protected boolean buildStructure(OpenableElementInfo info, final IProgressMonitor pm, Map newElements, IResource underlyingResource) throws JavaModelException { |
| |
| this.requestOriginalContentMode(); |
| |
| AJCompilationUnitInfo unitInfo; |
| try { |
| // check if this compilation unit can be opened |
| if (!isWorkingCopy()) { // no check is done on root kind or exclusion pattern for working copies |
| IStatus status = validateCompilationUnit(underlyingResource); |
| if (!status.isOK()) throw newJavaModelException(status); |
| } |
| |
| // prevents reopening of non-primary working copies (they are closed when they are discarded and should not be reopened) |
| if (!isPrimary() && getPerWorkingCopyInfo() == null) { |
| throw newNotPresentException(); |
| } |
| |
| unitInfo = (AJCompilationUnitInfo) info; |
| |
| // get buffer contents |
| IBuffer buffer = getBufferManager().getBuffer(AJCompilationUnit.this); |
| if (buffer == null) { |
| buffer = openBuffer(pm, unitInfo); // open buffer independently from the info, since we are building the info |
| } |
| final char[] contents = buffer == null ? null : buffer.getCharacters(); |
| |
| // generate structure and compute syntax problems if needed |
| AJCompilationUnitStructureRequestor requestor = new AJCompilationUnitStructureRequestor(this, unitInfo, newElements); |
| JavaModelManager.PerWorkingCopyInfo perWorkingCopyInfo = getPerWorkingCopyInfo(); |
| IJavaProject project = getJavaProject(); |
| boolean computeProblems = JavaProject.hasJavaNature(project.getProject()) && perWorkingCopyInfo != null && perWorkingCopyInfo.isActive(); |
| IProblemFactory problemFactory = new DefaultProblemFactory(); |
| Map options = project.getOptions(true); |
| AJSourceElementParser parser = new AJSourceElementParser( |
| requestor, |
| problemFactory, |
| new CompilerOptions(options), |
| true/*report local declarations*/); |
| parser.reportOnlyOneSyntaxError = !computeProblems; |
| |
| //we need to set the source already here so the requestor can init |
| //its jdt version of the parser (see requestor.setParser) |
| parser.scanner.source = contents; |
| requestor.setParser(parser); |
| |
| CompilationUnitDeclaration unit = parser.parseCompilationUnit(new org.aspectj.org.eclipse.jdt.internal.compiler.env.ICompilationUnit() { |
| public char[] getContents() { |
| return contents; |
| } |
| public char[] getMainTypeName() { |
| return AJCompilationUnit.this.getMainTypeName(); |
| } |
| public char[][] getPackageName() { |
| return AJCompilationUnit.this.getPackageName(); |
| } |
| public char[] getFileName() { |
| return AJCompilationUnit.this.getFileName(); |
| } |
| }, true /*full parse to find local elements*/); |
| |
| |
| // update timestamp (might be IResource.NULL_STAMP if original does not exist) |
| if (underlyingResource == null) { |
| underlyingResource = getResource(); |
| } |
| unitInfo.setTimestamp(((IFile)underlyingResource).getModificationStamp()); |
| |
| // compute other problems if needed |
| org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration compilationUnitDeclaration = null; |
| try { |
| if (computeProblems){ |
| perWorkingCopyInfo.beginReporting(); |
| |
| AJCompilationUnitDeclarationWrapper ajcudw = new AJCompilationUnitDeclarationWrapper(unit, this); |
| AJCompilationUnitStructureRequestor ajcusr = new AJCompilationUnitStructureRequestor(this, (AJCompilationUnitInfo)getElementInfo(), null); |
| AJSourceElementParser2 parser2 = new AJSourceElementParser2(ajcusr, new org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory(), new org.eclipse.jdt.internal.compiler.impl.CompilerOptions(options), true); |
| |
| AjLookupEnvironment le = |
| new AjLookupEnvironment(null, new CompilerOptions(options), null, null); |
| unit.scope = new CompilationUnitScope(unit, le); |
| compilationUnitDeclaration = AJCompilationUnitProblemFinder.process(ajcudw, this, contents, parser2, null, perWorkingCopyInfo, new org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory(), false/*don't cleanup cu*/, null); |
| |
| // provisional -- only reports syntax errors |
| IProblem[] problems = unit.compilationResult.problems; |
| if (problems != null){ |
| for (int i = 0; i < problems.length; i++) { |
| IProblem problem = problems[i]; |
| if (problem == null) |
| continue; |
| perWorkingCopyInfo.acceptProblem(new DefaultProblem( |
| problem.getOriginatingFileName(), |
| problem.getMessage(), |
| problem.getID(), |
| problem.getArguments(), |
| problem.isError()?ProblemSeverities.Error:ProblemSeverities.Warning, |
| problem.getSourceStart(), |
| problem.getSourceEnd(), |
| problem.getSourceLineNumber())); |
| } |
| } |
| perWorkingCopyInfo.endReporting(); |
| |
| } |
| |
| if (info instanceof ASTHolderAJCUInfo && compilationUnitDeclaration != null) { |
| |
| int astLevel = ((ASTHolderAJCUInfo) info).astLevel; |
| org.eclipse.jdt.core.dom.CompilationUnit cu = AST.convertCompilationUnit(astLevel, compilationUnitDeclaration, contents, options, computeProblems, (CompilationUnit)perWorkingCopyInfo.getWorkingCopy(), pm); |
| ((ASTHolderAJCUInfo) info).ast = cu; |
| } |
| } finally { |
| if (compilationUnitDeclaration != null) { |
| compilationUnitDeclaration.cleanUp(); |
| } |
| } |
| } finally { |
| this.discardOriginalContentMode(); |
| } |
| |
| return unitInfo.isStructureKnown(); |
| |
| } |
| |
| public boolean isPrimary() { |
| return this.owner == AJWorkingCopyOwner.INSTANCE; |
| } |
| |
| protected Object createElementInfo() { |
| return new AJCompilationUnitInfo(); |
| } |
| |
| |
| public org.eclipse.jdt.core.dom.CompilationUnit makeConsistent(int astLevel, boolean resolveBindings, HashMap problems, IProgressMonitor monitor) throws JavaModelException { |
| if (isConsistent()) return null; |
| |
| // create a new info and make it the current info |
| // (this will remove the info and its children just before storing the new infos) |
| if (astLevel != NO_AST || problems != null) { |
| ASTHolderAJCUInfo info = new ASTHolderAJCUInfo(); |
| info.astLevel = astLevel; |
| info.resolveBindings = resolveBindings; |
| info.problems = problems; |
| openWhenClosed(info, monitor); |
| org.eclipse.jdt.core.dom.CompilationUnit result = info.ast; |
| info.ast = null; |
| return result; |
| } else { |
| openWhenClosed(createElementInfo(), monitor); |
| return null; |
| } |
| } |
| |
| /** |
| * @see ICompilationUnit#getWorkingCopy(WorkingCopyOwner, IProblemRequestor, IProgressMonitor) |
| */ |
| public ICompilationUnit getWorkingCopy(WorkingCopyOwner workingCopyOwner, IProblemRequestor problemRequestor, IProgressMonitor monitor) throws JavaModelException { |
| if (!isPrimary()) return this; |
| |
| JavaModelManager manager = JavaModelManager.getJavaModelManager(); |
| |
| CompilationUnit workingCopy = new AJCompilationUnit((PackageFragment)getParent(), getElementName(), workingCopyOwner); |
| JavaModelManager.PerWorkingCopyInfo perWorkingCopyInfo = |
| manager.getPerWorkingCopyInfo(workingCopy, false/*don't create*/, true/*record usage*/, null/*not used since don't create*/); |
| if (perWorkingCopyInfo != null) { |
| return perWorkingCopyInfo.getWorkingCopy(); // return existing handle instead of the one created above |
| } |
| BecomeWorkingCopyOperation op = new BecomeWorkingCopyOperation(workingCopy, problemRequestor); |
| op.runOperation(monitor); |
| return workingCopy; |
| } |
| |
| //used by package explorer |
| public IJavaElement[] getChildren() throws JavaModelException{ |
| return super.getChildren(); |
| } |
| |
| //used for code completion and similar tasks (super forwards to getChildren) |
| public IType[] getTypes() throws JavaModelException { |
| return super.getTypes(); |
| } |
| |
| public IBuffer getBuffer() throws JavaModelException { |
| return convertBuffer(super.getBuffer()); |
| } |
| |
| /* |
| * copied from super, but changed to remove the extension, instead of |
| * calling Util.getNameWithoutJavaLikeExtension(). We can remove this if we |
| * register .aj as a java like extension. |
| */ |
| public IType findPrimaryType() { |
| String typeName = getElementName(); |
| // remove the .aj |
| typeName = typeName.substring(0, typeName.lastIndexOf('.')); |
| IType primaryType = getType(typeName); |
| if (primaryType.exists()) { |
| return primaryType; |
| } |
| return null; |
| } |
| |
| public IBuffer convertBuffer(IBuffer buf) { |
| if (isInOriginalContentMode() || (buf == null)) |
| return buf; |
| |
| if (javaCompBuffer == null){ |
| BufferManager bm = BufferManager.getDefaultBufferManager(); |
| IBuffer myBuffer = bm.createBuffer(this); |
| javaCompBuffer = new JavaCompatibleBuffer(buf, myBuffer); |
| } else { |
| if (buf != javaCompBuffer) |
| javaCompBuffer.reinitialize(buf); |
| } |
| |
| return javaCompBuffer; |
| } |
| |
| // copied from super, but changed to use an AJReconcileWorkingCopyOperation |
| public org.eclipse.jdt.core.dom.CompilationUnit reconcile(int astLevel, |
| boolean forceProblemDetection, WorkingCopyOwner workingCopyOwner, |
| IProgressMonitor monitor) throws JavaModelException { |
| if (!isWorkingCopy()) return null; // Reconciling is not supported on non working copies |
| if (workingCopyOwner == null) workingCopyOwner = AJWorkingCopyOwner.INSTANCE; |
| |
| boolean createAST = false; |
| if (astLevel == AST.JLS2) { |
| // client asking for level 2 AST; these are supported |
| createAST = true; |
| } else if (astLevel == AST.JLS3) { |
| // client asking for level 3 ASTs; these are supported |
| createAST = true; |
| } else { |
| // client asking for no AST (0) or unknown ast level |
| // either way, request denied |
| createAST = false; |
| } |
| AJReconcileWorkingCopyOperation op = new AJReconcileWorkingCopyOperation(this, createAST, astLevel, forceProblemDetection, workingCopyOwner); |
| op.runOperation(monitor); |
| return op.ast; |
| } |
| |
| public IJavaElement[] codeSelect(int offset, int length, |
| WorkingCopyOwner workingCopyOwner) throws JavaModelException { |
| IJavaElement[] res = super.codeSelect(offset, length, workingCopyOwner); |
| return res; |
| } |
| |
| //unfortunately, the following three methods do not seem to get called at all |
| //how could we make these refactoring operations work? (related bug: 74426) |
| public void move(IJavaElement container, IJavaElement sibling, |
| String rename, boolean force, IProgressMonitor monitor) |
| throws JavaModelException { |
| // TODO make move work for .aj files |
| super.move(container, sibling, rename, force, monitor); |
| } |
| public void rename(String newName, boolean force, IProgressMonitor monitor) |
| throws JavaModelException { |
| // TODO make rename work for .aj files |
| super.rename(newName, force, monitor); |
| } |
| |
| public void delete(boolean force, IProgressMonitor monitor) |
| throws JavaModelException { |
| super.delete(force, monitor); |
| } |
| |
| |
| protected void closeBuffer() { |
| if (javaCompBuffer != null){ |
| javaCompBuffer.close(); |
| javaCompBuffer = null; |
| } |
| super.closeBuffer(); |
| } |
| |
| private static final String moveCuUpdateCreator = "org.eclipse.jdt.internal.corext.refactoring.reorg.MoveCuUpdateCreator"; //$NON-NLS-1$ |
| private static final int lenOfMoveCuUpdateCreator = moveCuUpdateCreator.length(); |
| |
| public IType[] getAllTypes() throws JavaModelException { |
| //tell MoveCuUpdateCreator that we do not contain any Types, otherwise it tries to find |
| //them using java search which will cause an ugly exception |
| String caller = (new RuntimeException()).getStackTrace()[1].getClassName(); |
| if ((lenOfMoveCuUpdateCreator == caller.length()) && moveCuUpdateCreator.equals(caller)) |
| return new IType[0]; |
| return super.getAllTypes(); |
| } |
| |
| /** |
| * Hook for code completion support for AspectJ content. |
| * |
| * A description of how code completion works in AJDT can be found in bug 74419. |
| * |
| * (non-Javadoc) |
| * @see org.eclipse.jdt.internal.core.Openable#codeComplete(org.eclipse.jdt.internal.compiler.env.ICompilationUnit, org.eclipse.jdt.internal.compiler.env.ICompilationUnit, int, org.eclipse.jdt.core.CompletionRequestor, org.eclipse.jdt.core.WorkingCopyOwner) |
| */ |
| protected void codeComplete(org.eclipse.jdt.internal.compiler.env.ICompilationUnit cu, org.eclipse.jdt.internal.compiler.env.ICompilationUnit unitToSkip, int position, CompletionRequestor requestor, WorkingCopyOwner owner) throws JavaModelException { |
| ConversionOptions myConversionOptions; int pos; |
| |
| if(javaCompBuffer == null) { |
| convertBuffer(super.getBuffer()); |
| } |
| ConversionOptions optionsBefore = javaCompBuffer.getConversionOptions(); |
| |
| //check if inside intertype method declaration |
| char[] targetType = isInIntertypeMethodDeclaration(position, this); |
| if (targetType != null){ |
| |
| //we are inside an intertype method declaration -> simulate context switch to target class |
| myConversionOptions = ConversionOptions.getCodeCompletionOptionWithContextSwitch(position, targetType); |
| javaCompBuffer.setConversionOptions(myConversionOptions); |
| pos = javaCompBuffer.translatePositionToFake(position); |
| // we call codeComplete twice in this case to combine the context specific completions with the |
| // completions for things like local variables. |
| super.codeComplete(cu, unitToSkip, pos, requestor, owner); |
| //set up proposal filter to filter away all the proposals that would be wrong because of context switch |
| requestor = new ProposalRequestorFilter(requestor, javaCompBuffer); |
| ((ProposalRequestorFilter)requestor).setAcceptMemberMode(false); |
| } else { |
| requestor = new ProposalRequestorWrapper(requestor, javaCompBuffer); |
| } |
| myConversionOptions = ConversionOptions.CODE_COMPLETION; |
| |
| javaCompBuffer.setConversionOptions(myConversionOptions); |
| pos = javaCompBuffer.translatePositionToFake(position); |
| super.codeComplete(cu, unitToSkip, pos, requestor, owner); |
| javaCompBuffer.setConversionOptions(optionsBefore); |
| |
| } |
| |
| //return null if outside intertype method declaration or the name of the target type otherwise |
| private char[] isInIntertypeMethodDeclaration(int pos, JavaElement elem) throws JavaModelException{ |
| IJavaElement[] elems = elem.getChildren(); |
| for (int i = 0; i < elems.length; i++) { |
| IJavaElement element = elems[i]; |
| if (element instanceof IntertypeElement){ |
| if (((IAspectJElement)element).getAJKind() == IProgramElement.Kind.INTER_TYPE_METHOD){ |
| ISourceRange range = ((IntertypeElement)element).getSourceRange(); |
| if ((pos >= range.getOffset()) && (pos < range.getOffset() + range.getLength())) |
| return ((IntertypeElement)element).getTargetType(); |
| } |
| } |
| char[] res = isInIntertypeMethodDeclaration(pos, (JavaElement)element); |
| if (res != null) |
| return res; |
| } |
| return null; |
| } |
| |
| |
| // hack: need to use protected constructor in SourceType |
| private JavaElement getType(JavaElement type, String typeName) { |
| try { |
| Constructor cons = SourceType.class.getDeclaredConstructor(new Class[]{JavaElement.class,String.class}); |
| cons.setAccessible(true); |
| Object obj = cons.newInstance(new Object[]{type,typeName}); |
| return (JavaElement)obj; |
| } catch (SecurityException e) { |
| } catch (NoSuchMethodException e) { |
| } catch (IllegalArgumentException e) { |
| } catch (InstantiationException e) { |
| } catch (IllegalAccessException e) { |
| } catch (InvocationTargetException e) { |
| } |
| return null; |
| } |
| |
| /* |
| * @see JavaElement |
| */ |
| public IJavaElement getHandleFromMemento(String token, MementoTokenizer memento, WorkingCopyOwner workingCopyOwner) { |
| JavaElement type = this; |
| // need to handle types ourselves, because they may contain inner aspects |
| // (or inner classes containing inner aspects etc) |
| while ((token.charAt(0) == AspectElement.JEM_ASPECT_TYPE) || |
| (token.charAt(0) == JavaElement.JEM_TYPE)) { |
| if (!memento.hasMoreTokens()) return type; |
| String typeName = memento.nextToken(); |
| if (token.charAt(0) == AspectElement.JEM_ASPECT_TYPE) { |
| type = new AspectElement(type, typeName); |
| } else if (token.charAt(0) == JavaElement.JEM_TYPE) { |
| type = getType(type,typeName); |
| if (type == null) type = (JavaElement)getType(typeName); |
| } |
| if (!memento.hasMoreTokens()) return type; |
| token = memento.nextToken(); |
| } |
| return type.getHandleFromMemento(token, memento, workingCopyOwner); |
| } |
| |
| /** |
| * @see JavaElement#getHandleMementoDelimiter() |
| */ |
| protected char getHandleMementoDelimiter() { |
| return AspectElement.JEM_ASPECT_CU; |
| } |
| |
| public String getHandleIdentifier() { |
| final String deletionClass = "org.eclipse.jdt.internal.corext.refactoring.changes.DeleteSourceManipulationChange"; //$NON-NLS-1$ |
| String callerName = (new RuntimeException()).getStackTrace()[1] |
| .getClassName(); |
| // are we being called in the context of a delete operation? |
| if (callerName.equals(deletionClass)) { |
| // neeed to perform the delete ourselves (bug 74426) |
| IResource res = getResource(); |
| IContainer parent = res.getParent(); |
| boolean isProject = (parent.getType() == IResource.PROJECT); |
| if ((parent.getType() == IResource.FOLDER) || isProject) { |
| IProject project = null; |
| IFolder folder = null; |
| if (isProject) { |
| project = (IProject) parent; |
| } else { |
| folder = (IFolder) parent; |
| } |
| String newName = CompilationUnitTools |
| .convertAJToJavaFileName(res.getName()); |
| IFile dummyFile = isProject ? project.getFile(newName) : folder.getFile(newName); |
| while (dummyFile.exists()) { |
| newName = newName.substring(0, newName.lastIndexOf('.')) |
| .concat("9").concat(".java"); //$NON-NLS-1$ //$NON-NLS-2$ |
| dummyFile = isProject ? project.getFile(newName) : folder.getFile(newName); |
| } |
| try { |
| // create an empty file |
| dummyFile.create(null, false, null); |
| |
| // this avoids exceptions caused by clients responding |
| // to the file creation |
| dummyFile.setTeamPrivateMember(true); |
| |
| // delete the real .aj file |
| res.delete(true, null); |
| } catch (CoreException e) { |
| } |
| ICompilationUnit dummyUnit = JavaCore |
| .createCompilationUnitFrom(dummyFile); |
| return dummyUnit.getHandleIdentifier(); |
| } |
| } |
| return super.getHandleIdentifier(); |
| } |
| |
| } |