summaryrefslogtreecommitdiffstats
path: root/weaver
diff options
context:
space:
mode:
Diffstat (limited to 'weaver')
-rw-r--r--weaver/src/org/aspectj/weaver/TypeX.java115
-rw-r--r--weaver/src/org/aspectj/weaver/World.java14
-rw-r--r--weaver/testsrc/org/aspectj/weaver/TypeXTestCase.java15
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++) {