diff options
author | aclement <aclement> | 2006-07-06 07:58:43 +0000 |
---|---|---|
committer | aclement <aclement> | 2006-07-06 07:58:43 +0000 |
commit | d0c299daf6a8ac2e52c33ab4140257fbd60712dd (patch) | |
tree | f5ec513efb76b75d58131dd2c2b9fb3b92967cc6 /asm | |
parent | d16403655828b58d1ffbdb8d9ab4457c097bd746 (diff) | |
download | aspectj-d0c299daf6a8ac2e52c33ab4140257fbd60712dd.tar.gz aspectj-d0c299daf6a8ac2e52c33ab4140257fbd60712dd.zip |
last patches for 141730
Diffstat (limited to 'asm')
4 files changed, 253 insertions, 24 deletions
diff --git a/asm/src/org/aspectj/asm/AsmManager.java b/asm/src/org/aspectj/asm/AsmManager.java index e28cedf48..baa3225bf 100644 --- a/asm/src/org/aspectj/asm/AsmManager.java +++ b/asm/src/org/aspectj/asm/AsmManager.java @@ -71,18 +71,17 @@ public class AsmManager { // } protected AsmManager() { - hierarchy = new AspectJElementHierarchy(); -// List relationships = new ArrayList(); - mapper = new RelationshipMap(hierarchy); - handleProvider = new OptimizedFullPathHandleProvider(); + handleProvider = new OptimizedFullPathHandleProvider(); + createNewASM(); } public void createNewASM() { hierarchy = new AspectJElementHierarchy(); mapper = new RelationshipMap(hierarchy); + // call initialize on the handleProvider when we create a new ASM + // to give handleProviders the chance to reset any state + handleProvider.initialize(); } - - public IHierarchy getHierarchy() { return hierarchy; @@ -490,10 +489,6 @@ public class AsmManager { //===================== DELTA PROCESSING CODE ============== start ==========// - private String getFilename(String hid) { - return getHandleProvider().getFileForHandle(hid); - } - /** * Removes the hierarchy structure for the specified files from the structure model. * Returns true if it deleted anything @@ -515,7 +510,7 @@ public class AsmManager { fw.write("Deleting "+progElem+" node for file "+fileForCompilation+"\n"); } removeNode(progElem); - deletedNodes.add(getFilename(progElem.getHandleIdentifier())); + deletedNodes.add(getCanonicalFilePath(progElem.getSourceLocation().getSourceFile())); if (!model.removeFromFileMap(correctedPath.toString())) throw new RuntimeException("Whilst repairing model, couldn't remove entry for file: "+correctedPath.toString()+" from the filemap"); modelModified = true; @@ -557,7 +552,7 @@ public class AsmManager { fw.write("Deleting "+progElem+" node for file "+fileForCompilation+"\n"); } removeNode(progElem); - deletedNodes.add(getFilename(progElem.getHandleIdentifier())); + deletedNodes.add(getCanonicalFilePath(progElem.getSourceLocation().getSourceFile())); if (!model.removeFromFileMap(correctedPath.toString())) throw new RuntimeException("Whilst repairing model, couldn't remove entry for file: "+correctedPath.toString()+" from the filemap"); modelModified = true; diff --git a/asm/src/org/aspectj/asm/IElementHandleProvider.java b/asm/src/org/aspectj/asm/IElementHandleProvider.java index 3e5ef9570..79cd6bfab 100644 --- a/asm/src/org/aspectj/asm/IElementHandleProvider.java +++ b/asm/src/org/aspectj/asm/IElementHandleProvider.java @@ -60,4 +60,18 @@ public interface IElementHandleProvider { public int getOffSetForHandle(String handle); + // See pr134471 + /** + * @return true if the handles produced by the provider + * depend on ISourceLocations and false otherwise + */ + public boolean dependsOnLocation(); + + /** + * Initializes handle provider state. + * + * The initializer is invoked when a new ASM is + * created on a full build. + */ + public void initialize(); } diff --git a/asm/src/org/aspectj/asm/internal/AspectJElementHierarchy.java b/asm/src/org/aspectj/asm/internal/AspectJElementHierarchy.java index cb483acd0..e0bb070dd 100644 --- a/asm/src/org/aspectj/asm/internal/AspectJElementHierarchy.java +++ b/asm/src/org/aspectj/asm/internal/AspectJElementHierarchy.java @@ -406,7 +406,8 @@ public class AspectJElementHierarchy implements IHierarchy { Set k = handleMap.keySet(); for (Iterator iter = k.iterator(); iter.hasNext();) { String handle = (String) iter.next(); - if (deletedFiles.contains(getFilename(handle))) forRemoval.add(handle); + IProgramElement ipe = (IProgramElement)handleMap.get(handle); + if (deletedFiles.contains(getCanonicalFilePath(ipe)))forRemoval.add(handle); } for (Iterator iter = forRemoval.iterator(); iter.hasNext();) { String handle = (String) iter.next(); @@ -415,31 +416,37 @@ public class AspectJElementHierarchy implements IHierarchy { forRemoval.clear(); k = typeMap.keySet(); for (Iterator iter = k.iterator(); iter.hasNext();) { - String element = (String) iter.next(); - IProgramElement ipe = (IProgramElement)typeMap.get(element); - if (deletedFiles.contains(getFilename(ipe.getHandleIdentifier()))) forRemoval.add(element); + String typeName = (String) iter.next(); + IProgramElement ipe = (IProgramElement)typeMap.get(typeName); + if (deletedFiles.contains(getCanonicalFilePath(ipe))) forRemoval.add(typeName); } for (Iterator iter = forRemoval.iterator(); iter.hasNext();) { - String handle = (String) iter.next(); - typeMap.remove(handle); + String typeName = (String) iter.next(); + typeMap.remove(typeName); } forRemoval.clear(); k = fileMap.keySet(); for (Iterator iter = k.iterator(); iter.hasNext();) { - String element = (String) iter.next(); - IProgramElement ipe = (IProgramElement)fileMap.get(element); - if (deletedFiles.contains(getFilename(ipe.getHandleIdentifier()))) forRemoval.add(element); + String filePath = (String) iter.next(); + IProgramElement ipe = (IProgramElement)fileMap.get(filePath); + if (deletedFiles.contains(getCanonicalFilePath(ipe))) forRemoval.add(filePath); } for (Iterator iter = forRemoval.iterator(); iter.hasNext();) { - String handle = (String) iter.next(); - fileMap.remove(handle); + String filePath = (String) iter.next(); + fileMap.remove(filePath); } - } private String getFilename(String hid) { return AsmManager.getDefault().getHandleProvider().getFileForHandle(hid); } + + private String getCanonicalFilePath(IProgramElement ipe) { + if (ipe.getSourceLocation() != null) { + return AsmManager.getDefault().getCanonicalFilePath(ipe.getSourceLocation().getSourceFile()); + } + return ""; + } } diff --git a/asm/src/org/aspectj/asm/internal/JDTLikeHandleProvider.java b/asm/src/org/aspectj/asm/internal/JDTLikeHandleProvider.java new file mode 100644 index 000000000..e7912f7be --- /dev/null +++ b/asm/src/org/aspectj/asm/internal/JDTLikeHandleProvider.java @@ -0,0 +1,213 @@ +/******************************************************************** + * Copyright (c) 2006 Contributors. All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://eclipse.org/legal/epl-v10.html + * + * Contributors: IBM Corporation - initial API and implementation + * Helen Hawkins - initial version + *******************************************************************/ +package org.aspectj.asm.internal; + +import java.io.File; +import java.util.Iterator; +import java.util.List; + +import org.aspectj.asm.AsmManager; +import org.aspectj.asm.IElementHandleProvider; +import org.aspectj.asm.IProgramElement; +import org.aspectj.bridge.ISourceLocation; +import org.aspectj.util.CharOperation; +import org.aspectj.util.NameConvertor; + +/** + * Creates JDT-like handles, for example + * + * method with string argument: <tjp{Demo.java[Demo~main~\[QString; + * method with generic argument: <pkg{MyClass.java[MyClass~myMethod~QList\<QString;>; + * an aspect: <pkg*A1.aj}A1 + * advice with Integer arg: <pkg*A8.aj}A8&afterReturning&QInteger; + * method call: <pkg*A10.aj[C~m1?method-call(void pkg.C.m2()) + * + */ +public class JDTLikeHandleProvider implements IElementHandleProvider { + + // Need to keep our own count of the number of initializers + // because this information cannot be gained from the ipe. + private int initializerCounter = 0; + + private char[] empty = new char[]{}; + private char[] countDelim = new char[]{HandleProviderDelimiter.COUNT.getDelimiter()}; + + private String backslash = "\\"; + private String emptyString = ""; + + public String createHandleIdentifier(IProgramElement ipe) { + + // AjBuildManager.setupModel --> top of the tree is either + // <root> or the .lst file + if (ipe == null || + (ipe.getKind().equals(IProgramElement.Kind.FILE_JAVA) + && ipe.getName().equals("<root>"))) { + return ""; + } else if (ipe.getHandleIdentifier(false) != null) { + // have already created the handle for this ipe + // therefore just return it + return ipe.getHandleIdentifier(); + } else if (ipe.getKind().equals(IProgramElement.Kind.FILE_LST)) { + String configFile = AsmManager.getDefault().getHierarchy().getConfigFile(); + int start = configFile.lastIndexOf(File.separator); + int end = configFile.lastIndexOf(".lst"); + String fileName = configFile.substring(start + 1,end); + ipe.setHandleIdentifier(fileName); + return fileName; + } + IProgramElement parent = ipe.getParent(); + if (parent != null && + parent.getKind().equals(IProgramElement.Kind.IMPORT_REFERENCE)) { + // want to miss out '#import declaration' in the handle + parent = ipe.getParent().getParent(); + } + + StringBuffer handle = new StringBuffer(); + // add the handle for the parent + handle.append(createHandleIdentifier(parent)); + // add the correct delimiter for this ipe + handle.append(HandleProviderDelimiter.getDelimiter(ipe)); + // add the name and any parameters unless we're an initializer + // (initializer's names are '...') + if (!ipe.getKind().equals(IProgramElement.Kind.INITIALIZER)) { + handle.append(ipe.getName() + getParameters(ipe)); + } + // add the count, for example '!2' if its the second ipe of its + // kind in the aspect + handle.append(getCount(ipe)); + + ipe.setHandleIdentifier(handle.toString()); + return handle.toString(); + } + + private String getParameters(IProgramElement ipe) { + if (ipe.getParameterSignatures() == null || ipe.getParameterSignatures().isEmpty()) return ""; + StringBuffer sb = new StringBuffer(); + List parameterTypes = ipe.getParameterSignatures(); + for (Iterator iter = parameterTypes.iterator(); iter.hasNext();) { + char[] element = (char[]) iter.next(); + sb.append(HandleProviderDelimiter.getDelimiter(ipe)); + if (element[0] == HandleProviderDelimiter.TYPE.getDelimiter()) { + // its an array + sb.append(HandleProviderDelimiter.ESCAPE.getDelimiter()); + sb.append(HandleProviderDelimiter.TYPE.getDelimiter()); + sb.append(NameConvertor.getTypeName( + CharOperation.subarray(element,1,element.length))); + } else if (element[0] == NameConvertor.PARAMETERIZED) { + // its a parameterized type + sb.append(NameConvertor.createShortName(element)); + } else { + sb.append(NameConvertor.getTypeName(element)); + } + } + return sb.toString(); + } + + private char[] getCount(IProgramElement ipe) { + char[] byteCodeName = ipe.getBytecodeName().toCharArray(); + if (ipe.getKind().isDeclare()) { + int index = CharOperation.lastIndexOf('_',byteCodeName); + if (index != -1) { + return convertCount(CharOperation.subarray(byteCodeName, + index+1,byteCodeName.length)); + } + } else if (ipe.getKind().equals(IProgramElement.Kind.ADVICE)) { + int lastDollar = CharOperation.lastIndexOf('$',byteCodeName); + if (lastDollar != -1) { + char[] upToDollar = CharOperation.subarray(byteCodeName,0,lastDollar); + int secondToLastDollar = CharOperation.lastIndexOf('$',upToDollar); + if (secondToLastDollar != -1) { + return convertCount(CharOperation.subarray(upToDollar, + secondToLastDollar+1,upToDollar.length)); + } + } + } else if (ipe.getKind().equals(IProgramElement.Kind.INITIALIZER)) { + return String.valueOf(++initializerCounter).toCharArray(); + } + return empty; + } + + /** + * Only returns the count if it's not equal to 1 + */ + private char[] convertCount(char[] c) { + if ((c.length == 1 && c[0] != ' ' && c[0] != '1') || c.length > 1) { + return CharOperation.concat(countDelim,c); + } + return empty; + } + + public String getFileForHandle(String handle) { + IProgramElement node = AsmManager.getDefault().getHierarchy().getElement(handle); + if (node != null) { + return AsmManager.getDefault().getCanonicalFilePath(node.getSourceLocation().getSourceFile()); + } else if (handle.charAt(0) == HandleProviderDelimiter.ASPECT_CU.getDelimiter() + || handle.charAt(0) == HandleProviderDelimiter.COMPILATIONUNIT.getDelimiter()) { + // it's something like *MyAspect.aj or {MyClass.java. In other words + // it's a file node that's been created with no children and no parent + return backslash + handle.substring(1); + } + return emptyString; + } + + public int getLineNumberForHandle(String handle) { + IProgramElement node = AsmManager.getDefault().getHierarchy().getElement(handle); + if (node != null) { + return node.getSourceLocation().getLine(); + } else if (handle.charAt(0) == HandleProviderDelimiter.ASPECT_CU.getDelimiter() + || handle.charAt(0) == HandleProviderDelimiter.COMPILATIONUNIT.getDelimiter()) { + // it's something like *MyAspect.aj or {MyClass.java. In other words + // it's a file node that's been created with no children and no parent + return 1; + } + return -1; + } + + public int getOffSetForHandle(String handle) { + IProgramElement node = AsmManager.getDefault().getHierarchy().getElement(handle); + if (node != null) { + return node.getSourceLocation().getOffset(); + } else if (handle.charAt(0) == HandleProviderDelimiter.ASPECT_CU.getDelimiter() + || handle.charAt(0) == HandleProviderDelimiter.COMPILATIONUNIT.getDelimiter()) { + // it's something like *MyAspect.aj or {MyClass.java. In other words + // it's a file node that's been created with no children and no parent + return 0; + } + return -1; + } + + public String createHandleIdentifier(ISourceLocation location) { + IProgramElement node = AsmManager.getDefault().getHierarchy().findElementForSourceLine(location); + if (node != null) { + return createHandleIdentifier(node); + } + return null; + } + + public String createHandleIdentifier(File sourceFile, int line, int column, int offset) { + IProgramElement node = AsmManager.getDefault().getHierarchy().findElementForOffSet(sourceFile.getAbsolutePath(),line,offset); + if (node != null) { + return createHandleIdentifier(node); + } + return null; + } + + public boolean dependsOnLocation() { + // handles are independent of soureLocations therefore return false + return false; + } + + public void initialize() { + // reset the initializer count. This ensures we return the + // same handle as JDT for initializers. + initializerCounter = 0; + } +} |