]> source.dussan.org Git - aspectj.git/commitdiff
stateless jdtlikehandleprovider so handles can optionally be cached now. Currently...
authoraclement <aclement>
Tue, 25 Aug 2009 17:02:22 +0000 (17:02 +0000)
committeraclement <aclement>
Tue, 25 Aug 2009 17:02:22 +0000 (17:02 +0000)
asm/src/org/aspectj/asm/AsmManager.java
asm/src/org/aspectj/asm/internal/JDTLikeHandleProvider.java
asm/src/org/aspectj/asm/internal/ProgramElement.java

index 423158951226ad251142543a67450fe18cf87be1..0423fa1f7972ef9551dc83f346b9d31bb4795bbc 100644 (file)
@@ -83,9 +83,11 @@ public class AsmManager implements IStructureModel {
        // 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 @@ public class AsmManager implements IStructureModel {
 
        }
 
-       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 @@ public class AsmManager implements IStructureModel {
                        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 @@ public class AsmManager implements IStructureModel {
                        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 @@ public class AsmManager implements IStructureModel {
                                        // 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 @@ public class AsmManager implements IStructureModel {
                }
                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 class AsmManager implements IStructureModel {
        }
 
        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: <br>
+        * - it is a method signature of the form (La/B;Lc/D;)LFoo;<br>
+        * - there are no generics<br>
+        * 
+        * 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 2954f2780ad297fff0ab87101ef2b7dab220f139..8ab5a5af2f128e66f8ad32c42929a2de3ebdc92d 100644 (file)
@@ -31,10 +31,6 @@ public class JDTLikeHandleProvider implements IElementHandleProvider {
 
        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 class JDTLikeHandleProvider implements IElementHandleProvider {
        }
 
        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>"))) {
@@ -284,7 +279,74 @@ public class JDTLikeHandleProvider implements IElementHandleProvider {
                                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) {
@@ -419,8 +481,6 @@ public class JDTLikeHandleProvider implements IElementHandleProvider {
        }
 
        public void initialize() {
-               // reset the initializer count. This ensures we return the
-               // same handle as JDT for initializers.
-               initializerCounter = 0;
+               // nop
        }
 }
index e9e6a9fb28b246f1bd58bea0b984f60f00d77fb5..812518b09258fb39d18e49cfef002adff8da4e1b 100644 (file)
@@ -305,12 +305,6 @@ public class ProgramElement implements IProgramElement {
                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 class ProgramElement implements IProgramElement {
        }
 
        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() {
@@ -566,18 +587,20 @@ public class ProgramElement implements IProgramElement {
        }
 
        public String getHandleIdentifier(boolean create) {
+               String h = handle;
                if (null == handle && create) {
                        if (asm == null && name.equals("<build to view structure>")) {
-                               handle = "<build to view structure>";
+                               h = "<build to view structure>";
                        } 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) {