diff options
Diffstat (limited to 'weaver')
-rw-r--r-- | weaver/src/org/aspectj/weaver/TypeX.java | 115 | ||||
-rw-r--r-- | weaver/src/org/aspectj/weaver/World.java | 14 | ||||
-rw-r--r-- | weaver/testsrc/org/aspectj/weaver/TypeXTestCase.java | 15 |
3 files changed, 140 insertions, 4 deletions
diff --git a/weaver/src/org/aspectj/weaver/TypeX.java b/weaver/src/org/aspectj/weaver/TypeX.java index 2b046a370..cd9e352f3 100644 --- a/weaver/src/org/aspectj/weaver/TypeX.java +++ b/weaver/src/org/aspectj/weaver/TypeX.java @@ -23,6 +23,11 @@ public class TypeX implements AnnotatedElement { * This is the bytecode string representation of this Type */ protected String signature; + + /** + * If this is a parameterized type, these are its parameters + */ + protected TypeX[] typeParameters; /** * @param signature the bytecode string representation of this Type @@ -101,7 +106,29 @@ public class TypeX implements AnnotatedElement { } return ret; } - + + /** + * Makes a parameterized type with the given name + * and parameterized type names. + */ + public static TypeX forParameterizedTypeNames(String name, String[] paramTypeNames) { + TypeX ret = TypeX.forName(name); + ret.typeParameters = new TypeX[paramTypeNames.length]; + for (int i = 0; i < paramTypeNames.length; i++) { + ret.typeParameters[i] = TypeX.forName(paramTypeNames[i]); + } + // sig for e.g. List<String> is Ljava/util/List<Ljava/lang/String;>; + StringBuffer sigAddition = new StringBuffer(); + sigAddition.append("<"); + for (int i = 0; i < ret.typeParameters.length; i++) { + sigAddition.append(ret.typeParameters[i].signature); + sigAddition.append(">"); + sigAddition.append(";"); + } + ret.signature = ret.signature + sigAddition.toString(); + return ret; + } + /** * Creates a new type array with a fresh type appended to the end. * @@ -205,6 +232,15 @@ public class TypeX implements AnnotatedElement { public String getName() { return signatureToName(signature); } + + public String getBaseName() { + String name = getName(); + if (isParameterized()) { + return name.substring(0,name.indexOf("<")); + } else { + return name; + } + } /** * Returns an array of strings representing the java langauge names of @@ -250,6 +286,14 @@ public class TypeX implements AnnotatedElement { public final boolean isArray() { return signature.startsWith("["); } + + /** + * Determines if this represents a parameterized type. + */ + public final boolean isParameterized() { + return signature.indexOf("<") != -1; + //(typeParameters != null) && (typeParameters.length > 0); + } /** * Returns a TypeX object representing the effective outermost enclosing type @@ -603,7 +647,48 @@ public class TypeX implements AnnotatedElement { case 'I': return "int"; case 'J': return "long"; case 'L': - return signature.substring(1, signature.length() - 1).replace('/', '.'); + String name = signature.substring(1, signature.length() - 1).replace('/', '.'); + if (name.indexOf("<") == -1) return name; + // signature for parameterized types is e.g. + // List<String> -> Ljava/util/List<Ljava/lang/String;>; + // Map<String,List<Integer>> -> Ljava/util/Map<java/lang/String;Ljava/util/List<Ljava/lang/Integer;>;>; + StringBuffer nameBuff = new StringBuffer(); + boolean justSeenLeftArrowChar = false; + boolean justSeenSemiColon= false; + int paramNestLevel = 0; + for (int i = 0 ; i < name.length(); i++) { + char c = name.charAt(i); + switch (c) { + case '<' : + justSeenLeftArrowChar = true; + paramNestLevel++; + nameBuff.append(c); + break; + case ';' : + justSeenSemiColon = true; + break; + case '>' : + paramNestLevel--; + nameBuff.append(c); + break; + case 'L' : + if (justSeenLeftArrowChar) { + justSeenLeftArrowChar = false; + break; + } + if (justSeenSemiColon) { + nameBuff.append(","); + } else { + nameBuff.append("L"); + } + break; + default: + justSeenSemiColon = false; + justSeenLeftArrowChar = false; + nameBuff.append(c); + } + } + return nameBuff.toString(); case 'S': return "short"; case 'V': return "void"; case 'Z': return "boolean"; @@ -631,7 +716,27 @@ public class TypeX implements AnnotatedElement { // 1) If it is already an array type, do not mess with it. if (name.charAt(0)=='[' && name.charAt(name.length()-1)==';') return name; - else return "L" + name.replace('.', '/') + ";"; + else { + if (name.indexOf("<") == -1) { + // not parameterised + return "L" + name.replace('.', '/') + ";"; + } else { + StringBuffer nameBuff = new StringBuffer(); + nameBuff.append("L"); + for (int i = 0; i < name.length(); i++) { + char c = name.charAt(i); + switch (c) { + case '.' : nameBuff.append('/'); break; + case '<' : nameBuff.append("<L"); break; + case '>' : nameBuff.append(";>"); break; + case ',' : nameBuff.append(";L"); break; + default: nameBuff.append(c); + } + } + nameBuff.append(";"); + return nameBuff.toString(); + } + } } else throw new BCException("Bad type name: " + name); @@ -721,6 +826,10 @@ public class TypeX implements AnnotatedElement { } } + public TypeX[] getTypeParameters() { + return typeParameters == null ? new TypeX[0] : typeParameters; + } + /** * Doesn't include the package */ diff --git a/weaver/src/org/aspectj/weaver/World.java b/weaver/src/org/aspectj/weaver/World.java index ca7e0a211..04ec34815 100644 --- a/weaver/src/org/aspectj/weaver/World.java +++ b/weaver/src/org/aspectj/weaver/World.java @@ -137,6 +137,11 @@ public abstract class World implements Dump.INode { dumpState_cantFindTypeExceptions.add(new RuntimeException("Can't find type "+ty.getName())); } } + if (ty.isParameterized()) { + for (int i = 0; i < ty.typeParameters.length; i++) { + ty.typeParameters[i] = resolve(ty.typeParameters[i],allowMissing); + } + } //System.out.println("ret: " + ret); typeMap.put(signature, ret); return ret; @@ -147,7 +152,14 @@ public abstract class World implements Dump.INode { return resolve(TypeX.forName(name)); } protected final ResolvedTypeX resolveObjectType(TypeX ty) { - ResolvedTypeX.Name name = new ResolvedTypeX.Name(ty.getSignature(), this); + String signature = ty.getSignature(); + if (signature.indexOf("<") != -1) { + // extract the raw type... + // XXX - might need to do more in the future to propagate full parameterized info... + signature = signature.substring(0,signature.indexOf("<")); + } + + ResolvedTypeX.Name name = new ResolvedTypeX.Name(signature, this); ResolvedTypeX.ConcreteName concreteName = resolveObjectType(name); if (concreteName == null) return ResolvedTypeX.MISSING; name.setDelegate(concreteName); diff --git a/weaver/testsrc/org/aspectj/weaver/TypeXTestCase.java b/weaver/testsrc/org/aspectj/weaver/TypeXTestCase.java index 3219b2f15..1ba812845 100644 --- a/weaver/testsrc/org/aspectj/weaver/TypeXTestCase.java +++ b/weaver/testsrc/org/aspectj/weaver/TypeXTestCase.java @@ -61,6 +61,21 @@ public class TypeXTestCase extends TestCase { assertEquals(t.getOutermostType(), TypeX.forName("java.util.Map")); assertEquals(TypeX.forName("java.util.Map").getOutermostType(), TypeX.forName("java.util.Map")); } + + public void testNameAndSigWithParameters() { + TypeX t = TypeX.forName("java.util.List<java.lang.String>"); + assertEquals(t.getName(),"java.util.List<java.lang.String>"); + assertEquals(t.getSignature(),"Ljava/util/List<Ljava/lang/String;>;"); + t = new TypeX("Ljava/util/List<Ljava/lang/String;>;"); + assertEquals(t.getName(),"java.util.List<java.lang.String>"); + assertEquals(t.getSignature(),"Ljava/util/List<Ljava/lang/String;>;"); + t = TypeX.forName("java.util.Map<java.util.String,java.util.List<java.lang.Integer>>"); + assertEquals(t.getName(),"java.util.Map<java.util.String,java.util.List<java.lang.Integer>>"); + assertEquals(t.getSignature(),"Ljava/util/Map<Ljava/util/String;Ljava/util/List<Ljava/lang/Integer;>;>;"); + t = new TypeX("Ljava/util/Map<Ljava/util/String;Ljava/util/List<Ljava/lang/Integer;>;>;"); + assertEquals(t.getName(),"java.util.Map<java.util.String,java.util.List<java.lang.Integer>>"); + assertEquals(t.getSignature(),"Ljava/util/Map<Ljava/util/String;Ljava/util/List<Ljava/lang/Integer;>;>;"); + } private void isPrimitiveTest(TypeX[] types, boolean[] isPrimitives) { for (int i = 0, len = types.length; i < len; i++) { |