Index: src/org/aspectj/asm/AsmManager.java
===================================================================
RCS file: /cvsroot/tools/org.aspectj/modules/asm/src/org/aspectj/asm/AsmManager.java,v
--- src/org/aspectj/asm/AsmManager.java 7 Apr 2009 01:31:04 -0000 1.46
+++ src/org/aspectj/asm/AsmManager.java 13 Aug 2009 15:42:13 -0000
@@ -83,9 +83,11 @@
// below to the AjState for a compilation and recover it if switching
// between projects.
protected IHierarchy hierarchy;
-
- /* Map from String > String - it maps absolute paths for
- * inpath dirs/jars to workspace relative paths suitable for handle inclusion */
+
+ /*
+ * Map from String > String - it maps absolute paths for inpath dirs/jars to workspace relative paths suitable for handle
+ * inclusion
+ */
protected Map inpathMap;
private IRelationshipMap mapper;
private IElementHandleProvider handleProvider;
@@ -654,16 +656,16 @@
}
- private String getTypeNameFromHandle(String handle,Map cache) {
- String typename = (String)cache.get(handle);
- if (typename!=null) {
+ private String getTypeNameFromHandle(String handle, Map cache) {
+ String typename = (String) cache.get(handle);
+ if (typename != null) {
return typename;
}
// inpath handle - but for which type?
// let's do it the slow way, we can optimize this with a cache perhaps
int hasPackage = handle.indexOf('<');
- int typeLocation = handle.indexOf('[');
- if (typeLocation==-1) {
+ int typeLocation = handle.indexOf('[');
+ if (typeLocation == -1) {
typeLocation = handle.indexOf('}');
}
if (typeLocation == -1) {
@@ -671,15 +673,16 @@
return "";
}
StringBuffer qualifiedTypeNameFromHandle = new StringBuffer();
- if (hasPackage!=-1) {
- qualifiedTypeNameFromHandle.append(handle.substring(hasPackage+1,handle.indexOf('(',hasPackage)));
+ if (hasPackage != -1) {
+ qualifiedTypeNameFromHandle.append(handle.substring(hasPackage + 1, handle.indexOf('(', hasPackage)));
qualifiedTypeNameFromHandle.append('.');
}
- qualifiedTypeNameFromHandle.append(handle.substring(typeLocation+1));
+ qualifiedTypeNameFromHandle.append(handle.substring(typeLocation + 1));
typename = qualifiedTypeNameFromHandle.toString();
- cache.put(handle,typename);
+ cache.put(handle, typename);
return typename;
}
+
/**
* two kinds of relationships
*
@@ -726,7 +729,7 @@
if (isPhantomHandle(hid)) {
// inpath handle - but for which type?
// TODO promote cache for reuse during one whole model update
- if (!getTypeNameFromHandle(hid,handleToTypenameCache).equals(typename)) {
+ if (!getTypeNameFromHandle(hid, handleToTypenameCache).equals(typename)) {
continue;
}
}
@@ -805,7 +808,7 @@
// they need removing
for (Iterator targetsIter = targets.iterator(); targetsIter.hasNext();) {
String targethid = (String) targetsIter.next();
- if (isPhantomHandle(hid) && !getTypeNameFromHandle(hid,handleToTypenameCache).equals(typename)) {
+ if (isPhantomHandle(hid) && !getTypeNameFromHandle(hid, handleToTypenameCache).equals(typename)) {
continue;
}
// Does this point to the same type?
@@ -910,13 +913,13 @@
}
return (type.equals(containingType));
}
-
+
/**
* @param handle a JDT like handle, following the form described in AsmRelationshipProvider.findOrFakeUpNode
* @return true if the handle contains ';' - the char indicating that it is a phantom handle
*/
private boolean isPhantomHandle(String handle) {
- return handle.indexOf(HandleProviderDelimiter.PHANTOM.getDelimiter())!=-1;
+ return handle.indexOf(HandleProviderDelimiter.PHANTOM.getDelimiter()) != -1;
}
/**
@@ -1307,7 +1310,208 @@
}
public String getHandleElementForInpath(String binaryPath) {
- return (String)inpathMap.get(new File(binaryPath));
+ return (String) inpathMap.get(new File(binaryPath));
+ }
+
+ private List pieces = new ArrayList();
+
+ private Object intern(String substring) {
+ int lastIdx = -1;
+ if ((lastIdx = substring.lastIndexOf('/')) != -1) {
+ String pkg = substring.substring(0, lastIdx);
+ String type = substring.substring(lastIdx + 1);
+ pkg = internOneThing(pkg);
+ type = internOneThing(type);
+ return new String[] { pkg, type };
+ } else {
+ return internOneThing(substring);
+ }
}
+ private String internOneThing(String substring) {
+ // simple name
+ for (int p = 0, max = pieces.size(); p < max; p++) {
+ String s = (String) pieces.get(p);
+ if (s.equals(substring)) {
+ return s;
+ }
+ }
+ pieces.add(substring);
+ return substring;
+ }
+
+ /**
+ * What we can rely on:
+ * - it is a method signature of the form (La/B;Lc/D;)LFoo;
+ * - there are no generics
+ *
+ * What we must allow for: - may use primitive refs (single chars rather than L)
+ */
+/*
+ public List compress(String s) {
+ int openParen = 0;
+ int closeParen = s.indexOf(')');
+ int pos = 1;
+ List compressed = new ArrayList();
+ // do the parens
+ while (pos < closeParen) {
+ char ch = s.charAt(pos);
+ if (ch == 'L') {
+ int idx = s.indexOf(';', pos);
+ compressed.add(intern(s.substring(pos + 1, idx)));
+ pos = idx + 1;
+ } else if (ch == '[') {
+ int x = pos;
+ while (s.charAt(++pos) == '[')
+ ;
+ // now pos will point at something not an array
+ compressed.add(intern(s.substring(x, pos))); // intern the [[[[[[
+ char ch2 = s.charAt(pos);
+ if (ch2 == 'L') {
+ int idx = s.indexOf(';', pos);
+ compressed.add(intern(s.substring(pos + 1, idx)));
+ pos = idx + 1;
+ } else if (ch2 == 'T') {
+ int idx = s.indexOf(';');
+ compressed.add(intern(s.substring(pos, idx + 1))); // should be TT;
+ pos = idx + 1;
+ } else {
+ compressed.add(toCharacter(s.charAt(pos)));
+ pos++;
+ }
+ } else {
+ // it is a primitive ref (SVBCZJ)
+ compressed.add(toCharacter(ch));
+ pos++;
+ }
+ }
+ // do the return type
+ pos++;
+ char ch = s.charAt(pos);
+ if (ch == 'L') {
+ int idx = s.indexOf(';', pos);
+ compressed.add(intern(s.substring(pos, idx)));
+ } else if (ch == '[') {
+ int x = pos;
+ while (s.charAt(++pos) == '[')
+ ;
+ // now pos will point at something not an array
+ compressed.add(intern(s.substring(x, pos))); // intern the [[[[[[
+ char ch2 = s.charAt(pos);
+ if (ch2 == 'L') {
+ int idx = s.indexOf(';', pos);
+ compressed.add(intern(s.substring(pos + 1, idx)));
+ pos = idx + 1;
+ } else if (ch2 == 'T') {
+ int idx = s.indexOf(';');
+ compressed.add(intern(s.substring(pos, idx + 1))); // should be TT;
+ pos = idx + 2;
+ } else {
+ compressed.add(toCharacter(s.charAt(pos)));
+ pos++;
+ }
+ } else {
+ // it is a primitive ref (SVBCZJ)
+ compressed.add(new Character(ch));
+ }
+ return compressed;
+
+ // char delimiter = '/';
+ // int pos = -1;
+ // List compressed = new ArrayList();
+ // int start = 0;
+ // while ((pos = s.indexOf(delimiter, start)) != -1) {
+ // String part = s.substring(start, pos);
+ // int alreadyRecorded = pieces.indexOf(part);
+ // if (alreadyRecorded != -1) {
+ // compressed.add(new Integer(alreadyRecorded));
+ // } else {
+ // compressed.add(new Integer(pieces.size()));
+ // pieces.add(part);
+ // }
+ // start = pos + 1;
+ // }
+ // // last piece
+ // String part = s.substring(start, s.length());
+ // int alreadyRecorded = pieces.indexOf(part);
+ // if (alreadyRecorded != -1) {
+ // compressed.add(youkirtyounew Integer(alreadyRecorded));
+ // } else {
+ // compressed.add(new Integer(pieces.size()));
+ // pieces.add(part);
+ // }
+ // return compressed;
+ }
+
+ static final Character charB = new Character('B');
+ static final Character charS = new Character('S');
+ static final Character charI = new Character('I');
+ static final Character charF = new Character('F');
+ static final Character charD = new Character('D');
+ static final Character charJ = new Character('J');
+ static final Character charC = new Character('C');
+ static final Character charV = new Character('V');
+ static final Character charZ = new Character('Z');
+
+ private Character toCharacter(char ch) {
+ switch (ch) {
+ case 'B':
+ return charB;
+ case 'S':
+ return charS;
+ case 'I':
+ return charI;
+ case 'F':
+ return charF;
+ case 'D':
+ return charD;
+ case 'J':
+ return charJ;
+ case 'C':
+ return charC;
+ case 'V':
+ return charV;
+ case 'Z':
+ return charZ;
+ default:
+ throw new IllegalStateException(new Character(ch).toString());
+ }
+ }
+
+ public String decompress(List refs, char delimiter) {
+ StringBuilder result = new StringBuilder();
+ result.append("(");
+ for (int i = 0, max = refs.size() - 1; i < max; i++) {
+ result.append(unintern(refs.get(i)));
+ }
+ result.append(")");
+ result.append(unintern(refs.get(refs.size() - 1)));
+ return result.toString();
+ }
+
+ private String unintern(Object o) {
+ if (o instanceof Character) {
+ return ((Character) o).toString();
+ } else if (o instanceof String[]) {
+ String[] strings = (String[]) o;
+ StringBuilder sb = new StringBuilder();
+ sb.append('L');
+ sb.append(strings[0]).append('/').append(strings[1]);
+ sb.append(';');
+ return sb.toString();
+ } else { // String
+ String so = (String) o;
+ if (so.endsWith(";")) {
+ // will be TT;
+ return so;
+ } else {
+ StringBuilder sb = new StringBuilder();
+ sb.append('L');
+ sb.append(so);
+ sb.append(';');
+ return sb.toString();
+ }
+ }
+ }
+ */
}
Index: src/org/aspectj/asm/internal/ProgramElement.java
===================================================================
RCS file: /cvsroot/tools/org.aspectj/modules/asm/src/org/aspectj/asm/internal/ProgramElement.java,v
--- src/org/aspectj/asm/internal/ProgramElement.java 11 Jun 2009 22:53:41 -0000 1.47
+++ src/org/aspectj/asm/internal/ProgramElement.java 13 Aug 2009 15:42:13 -0000
@@ -305,12 +305,6 @@
return s;
}
- public String getBytecodeSignature() {
- String s = (String) kvpairs.get("bytecodeSignature");
- // if (s==null) return UNDEFINED;
- return s;
- }
-
public void setBytecodeName(String s) {
if (kvpairs == Collections.EMPTY_MAP)
kvpairs = new HashMap();
@@ -318,9 +312,36 @@
}
public void setBytecodeSignature(String s) {
- if (kvpairs == Collections.EMPTY_MAP)
- kvpairs = new HashMap();
+ initMap();
+ // Different kinds of format here. The one worth compressing starts with a '(':
+ // (La/b/c/D;Le/f/g/G;)Ljava/lang/String;
+ // maybe want to avoid generics initially.
+ // boolean worthCompressing = s.charAt(0) == '(' && s.indexOf('<') == -1 && s.indexOf('P') == -1; // starts parentheses and
+ // no
+ // // generics
+ // if (worthCompressing) {
+ // kvpairs.put("bytecodeSignatureCompressed", asm.compress(s));
+ // } else {
kvpairs.put("bytecodeSignature", s);
+ // }
+ }
+
+ public String getBytecodeSignature() {
+ String s = (String) kvpairs.get("bytecodeSignature");
+ // if (s == null) {
+ // List compressed = (List) kvpairs.get("bytecodeSignatureCompressed");
+ // if (compressed != null) {
+ // return asm.decompress(compressed, '/');
+ // }
+ // }
+ // if (s==null) return UNDEFINED;
+ return s;
+ }
+
+ private void initMap() {
+ if (kvpairs == Collections.EMPTY_MAP) {
+ kvpairs = new HashMap();
+ }
}
public String getSourceSignature() {
@@ -549,22 +570,24 @@
}
public String getHandleIdentifier(boolean create) {
+ String h = null;
if (null == handle && create) {
if (asm == null && name.equals("")) {
- handle = "";
+ h = "";
} else {
try {
- handle = asm.getHandleProvider().createHandleIdentifier(this);
+ h = asm.getHandleProvider().createHandleIdentifier(this);
} catch (ArrayIndexOutOfBoundsException aioobe) {
throw new RuntimeException("AIOOBE whilst building handle for " + this, aioobe);
}
}
}
- return handle;
+ setHandleIdentifier(h);
+ return h;
}
public void setHandleIdentifier(String handle) {
- this.handle = handle;
+ // this.handle = handle;
}
public List getParameterNames() {
Index: src/org/aspectj/asm/internal/JDTLikeHandleProvider.java
===================================================================
RCS file: /cvsroot/tools/org.aspectj/modules/asm/src/org/aspectj/asm/internal/JDTLikeHandleProvider.java,v
--- src/org/aspectj/asm/internal/JDTLikeHandleProvider.java 27 Jul 2009 17:27:25 -0000 1.25
+++ src/org/aspectj/asm/internal/JDTLikeHandleProvider.java 13 Aug 2009 15:42:13 -0000
@@ -31,10 +31,6 @@
private final AsmManager asm;
- // 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 static final char[] empty = new char[] {};
private static final char[] countDelim = new char[] { HandleProviderDelimiter.COUNT.getDelimiter() };
@@ -46,7 +42,6 @@
}
public String createHandleIdentifier(IProgramElement ipe) {
-
// AjBuildManager.setupModel --> top of the tree is either
// or the .lst file
if (ipe == null || (ipe.getKind().equals(IProgramElement.Kind.FILE_JAVA) && ipe.getName().equals(""))) {
@@ -284,7 +279,74 @@
return CharOperation.concat(countDelim, new Integer(count).toString().toCharArray());
}
} else if (ipe.getKind().equals(IProgramElement.Kind.INITIALIZER)) {
- return String.valueOf(++initializerCounter).toCharArray();
+ // return String.valueOf(++initializerCounter).toCharArray();
+ // Look at any peer advice
+ int count = 1;
+ List kids = ipe.getParent().getChildren();
+ String ipeSig = ipe.getBytecodeSignature();
+ // remove return type from the signature - it should not be included in the comparison
+ int idx = 0;
+ if (ipeSig != null && ((idx = ipeSig.indexOf(")")) != -1)) {
+ ipeSig = ipeSig.substring(0, idx);
+ }
+ if (ipeSig != null) {
+ if (ipeSig.indexOf("Lorg/aspectj/lang") != -1) {
+ if (ipeSig.endsWith("Lorg/aspectj/lang/JoinPoint$StaticPart;")) {
+ ipeSig = ipeSig.substring(0, ipeSig.lastIndexOf("Lorg/aspectj/lang/JoinPoint$StaticPart;"));
+ }
+ if (ipeSig.endsWith("Lorg/aspectj/lang/JoinPoint;")) {
+ ipeSig = ipeSig.substring(0, ipeSig.lastIndexOf("Lorg/aspectj/lang/JoinPoint;"));
+ }
+ if (ipeSig.endsWith("Lorg/aspectj/lang/JoinPoint$StaticPart;")) {
+ ipeSig = ipeSig.substring(0, ipeSig.lastIndexOf("Lorg/aspectj/lang/JoinPoint$StaticPart;"));
+ }
+ }
+ }
+ for (Iterator iterator = kids.iterator(); iterator.hasNext();) {
+ IProgramElement object = (IProgramElement) iterator.next();
+ if (object.equals(ipe)) {
+ break;
+ }
+ if (object.getKind() == ipe.getKind()) {
+ if (object.getName().equals(ipe.getName())) {
+ String sig1 = object.getBytecodeSignature();
+ if (sig1 != null && (idx = sig1.indexOf(")")) != -1) {
+ sig1 = sig1.substring(0, idx);
+ }
+ // this code needs a speed overhaul... and some proper tests
+ // Two static parts because one may be enclosing jpsp (269522)
+ if (sig1 != null) {
+ if (sig1.indexOf("Lorg/aspectj/lang") != -1) {
+ if (sig1.endsWith("Lorg/aspectj/lang/JoinPoint$StaticPart;")) {
+ sig1 = sig1.substring(0, sig1.lastIndexOf("Lorg/aspectj/lang/JoinPoint$StaticPart;"));
+ }
+ if (sig1.endsWith("Lorg/aspectj/lang/JoinPoint;")) {
+ sig1 = sig1.substring(0, sig1.lastIndexOf("Lorg/aspectj/lang/JoinPoint;"));
+ }
+ if (sig1.endsWith("Lorg/aspectj/lang/JoinPoint$StaticPart;")) {
+ sig1 = sig1.substring(0, sig1.lastIndexOf("Lorg/aspectj/lang/JoinPoint$StaticPart;"));
+ }
+ }
+ }
+
+ if (sig1 == null && ipeSig == null || (sig1 != null && sig1.equals(ipeSig))) {
+ String existingHandle = object.getHandleIdentifier();
+ int suffixPosition = existingHandle.indexOf('!');
+ if (suffixPosition != -1) {
+ count = new Integer(existingHandle.substring(suffixPosition + 1)).intValue() + 1;
+ } else {
+ if (count == 1) {
+ count = 2;
+ }
+ }
+ }
+ }
+ }
+ }
+ // if (count > 1) {
+ return new Integer(count).toString().toCharArray();
+ // return CharOperation.concat(countDelim, new Integer(count).toString().toCharArray());
+ // }
} else if (ipe.getKind().equals(IProgramElement.Kind.CODE)) {
int index = CharOperation.lastIndexOf('!', byteCodeName);
if (index != -1) {
@@ -421,6 +483,6 @@
public void initialize() {
// reset the initializer count. This ensures we return the
// same handle as JDT for initializers.
- initializerCounter = 0;
+ // initializerCounter = 0;
}
}
Index: src/org/aspectj/asm/internal/CharOperation.java
===================================================================
RCS file: /cvsroot/tools/org.aspectj/modules/asm/src/org/aspectj/asm/internal/CharOperation.java,v
--- src/org/aspectj/asm/internal/CharOperation.java 4 Sep 2008 19:08:10 -0000 1.3
+++ src/org/aspectj/asm/internal/CharOperation.java 13 Aug 2009 15:42:13 -0000
@@ -16,6 +16,10 @@
*/
public class CharOperation {
+ public static final char[][] NO_CHAR_CHAR = new char[0][];
+
+ public static final char[] NO_CHAR = new char[0];
+
/**
* Taken from org.aspectj.org.eclipse.jdt.core.compiler.CharOperation
*/
@@ -34,6 +38,44 @@
return result;
}
+ public static final char[][] subarray(char[][] array, int start, int end) {
+ if (end == -1)
+ end = array.length;
+ if (start > end)
+ return null;
+ if (start < 0)
+ return null;
+ if (end > array.length)
+ return null;
+
+ char[][] result = new char[end - start][];
+ System.arraycopy(array, start, result, 0, end - start);
+ return result;
+ }
+
+ public static final char[][] splitOn(char divider, char[] array) {
+ int length = array == null ? 0 : array.length;
+ if (length == 0)
+ return NO_CHAR_CHAR;
+
+ int wordCount = 1;
+ for (int i = 0; i < length; i++)
+ if (array[i] == divider)
+ wordCount++;
+ char[][] split = new char[wordCount][];
+ int last = 0, currentWord = 0;
+ for (int i = 0; i < length; i++) {
+ if (array[i] == divider) {
+ split[currentWord] = new char[i - last];
+ System.arraycopy(array, last, split[currentWord++], 0, i - last);
+ last = i + 1;
+ }
+ }
+ split[currentWord] = new char[length - last];
+ System.arraycopy(array, last, split[currentWord], 0, length - last);
+ return split;
+ }
+
/**
* Taken from org.aspectj.org.eclipse.jdt.core.compiler.CharOperation
*/
@@ -88,6 +130,67 @@
return true;
}
+ final static public String toString(char[][] array) {
+ char[] result = concatWith(array, '.');
+ return new String(result);
+ }
+
+ public static final char[] concatWith(char[][] array, char separator) {
+ int length = array == null ? 0 : array.length;
+ if (length == 0)
+ return CharOperation.NO_CHAR;
+
+ int size = length - 1;
+ int index = length;
+ while (--index >= 0) {
+ if (array[index].length == 0)
+ size--;
+ else
+ size += array[index].length;
+ }
+ if (size <= 0)
+ return CharOperation.NO_CHAR;
+ char[] result = new char[size];
+ index = length;
+ while (--index >= 0) {
+ length = array[index].length;
+ if (length > 0) {
+ System.arraycopy(array[index], 0, result, (size -= length), length);
+ if (--size >= 0)
+ result[size] = separator;
+ }
+ }
+ return result;
+ }
+
+ public static final int hashCode(char[] array) {
+ int length = array.length;
+ int hash = length == 0 ? 31 : array[0];
+ if (length < 8) {
+ for (int i = length; --i > 0;)
+ hash = (hash * 31) + array[i];
+ } else {
+ // 8 characters is enough to compute a decent hash code, don't waste time examining every character
+ for (int i = length - 1, last = i > 16 ? i - 16 : 0; i > last; i -= 2)
+ hash = (hash * 31) + array[i];
+ }
+ return hash & 0x7FFFFFFF;
+ }
+
+ public static final boolean equals(char[][] first, char[][] second) {
+ if (first == second)
+ return true;
+ if (first == null || second == null)
+ return false;
+ if (first.length != second.length)
+ return false;
+
+ for (int i = first.length; --i >= 0;)
+ if (!equals(first[i], second[i]))
+ return false;
+ return true;
+ }
+
/**
* Taken from org.aspectj.org.eclipse.jdt.core.compiler.CharOperation
*/