diff options
author | acolyer <acolyer> | 2005-04-20 19:24:30 +0000 |
---|---|---|
committer | acolyer <acolyer> | 2005-04-20 19:24:30 +0000 |
commit | 7a639d019a9b04b3eb7af97a7a2975cbbf72e0cf (patch) | |
tree | 8bd9464cb6c1df486ab5e84d301cf82bc11fbdcb /weaver | |
parent | 1e6fae862407f7c0b49321a6c452774f91f3cd04 (diff) | |
download | aspectj-7a639d019a9b04b3eb7af97a7a2975cbbf72e0cf.tar.gz aspectj-7a639d019a9b04b3eb7af97a7a2975cbbf72e0cf.zip |
this set of commits teaches the TypeX world about parameterized types. it handles passing of parameterized types into the weaver from Eclipse, and back out again. Fixes the ITD and parameterized types issue that shows up in the examples. Much more work to be done in this area of course before M3.
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++) { |