if (!isSerializableAspect(aspectType)) {
modifiers |= Modifier.TRANSIENT;
}
- return new ResolvedMemberImpl(Member.FIELD, declaringType, modifiers, UnresolvedType.JAVA_LANG_STRING,
+ return new ResolvedMemberImpl(Member.FIELD, declaringType, modifiers, UnresolvedType.JL_STRING,
NameMangler.PERTYPEWITHIN_WITHINTYPEFIELD, UnresolvedType.NONE);
}
public static ResolvedMember perTypeWithinGetInstance(UnresolvedType declaringType) {
// private static a.X ajc$getInstance(java.lang.Class)
ResolvedMemberImpl rm = new ResolvedMemberImpl(Member.METHOD, declaringType, PRIVATE_STATIC, declaringType, // return value
- NameMangler.PERTYPEWITHIN_GETINSTANCE_METHOD, new UnresolvedType[] { UnresolvedType.JAVA_LANG_CLASS });
+ NameMangler.PERTYPEWITHIN_GETINSTANCE_METHOD, new UnresolvedType[] { UnresolvedType.JL_CLASS });
return rm;
}
public static ResolvedMember perTypeWithinGetWithinTypeNameMethod(UnresolvedType declaringType, boolean inJava5Mode) {
// public String getWithinTypeName()
ResolvedMemberImpl rm = new ResolvedMemberImpl(Member.METHOD, declaringType, Modifier.PUBLIC,
- UnresolvedType.JAVA_LANG_STRING, // return value
+ UnresolvedType.JL_STRING, // return value
NameMangler.PERTYPEWITHIN_GETWITHINTYPENAME_METHOD, UnresolvedType.NONE);
return rm;
}
}
public ISourceLocation getSourceLocation() {
- if (munger == null)
+ if (munger == null) {
return null;
+ }
return munger.getSourceLocation(); // XXX
}
public boolean matches(ResolvedType onType) {
- if (munger == null)
+ if (munger == null) {
throw new RuntimeException("huh: " + this);
+ }
return munger.matches(onType, aspectType);
}
* </code>
*/
public boolean isTargetTypeParameterized() {
- if (munger == null)
+ if (munger == null) {
return false;
+ }
return munger.sharesTypeVariablesWithGenericType();
}
public abstract ConcreteTypeMunger parameterizedFor(ResolvedType targetType);
public boolean isLateMunger() {
- if (munger == null)
+ if (munger == null) {
return false;
+ }
return munger.isLateMunger();
}
- public abstract ConcreteTypeMunger parameterizeWith(Map parameterizationMap, World world);
+ public abstract ConcreteTypeMunger parameterizeWith(Map<String, UnresolvedType> parameterizationMap, World world);
/**
* Some type mungers are created purely to help with the implementation of shadow mungers. For example to support the cflow()
}
public String getParameterSignature() {
- if (paramSignature != null) {
- return paramSignature;
- }
- StringBuffer sb = new StringBuffer();
- sb.append("(");
- for (int i = 0; i < parameterTypes.length; i++) {
- UnresolvedType tx = parameterTypes[i];
- sb.append(tx.getSignature());
+ if (paramSignature == null) {
+ StringBuilder sb = new StringBuilder("(");
+ for (UnresolvedType parameterType : parameterTypes) {
+ sb.append(parameterType.getSignature());
+ }
+ paramSignature = sb.append(")").toString();
}
- sb.append(")");
- paramSignature = sb.toString();
return paramSignature;
}
--- /dev/null
+/* *******************************************************************
+ * Copyright (c) 2010 Contributors
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Andy Clement, SpringSource
+ * ******************************************************************/
+package org.aspectj.weaver;
+
+/**
+ * Common utility methods for members.
+ *
+ * @author Andy Clement
+ */
+public class MemberUtils {
+
+ public static boolean isConstructor(ResolvedMember member) {
+ return member.getName().equals("<init>");
+ }
+
+}
return nftm;
}
- public ResolvedTypeMunger parameterizeWith(Map m, World w) {
+ public ResolvedTypeMunger parameterizeWith(Map<String, UnresolvedType> m, World w) {
ResolvedMember parameterizedSignature = getSignature().parameterizedWith(m, w);
NewFieldTypeMunger nftm = new NewFieldTypeMunger(parameterizedSignature, getSuperMethodsCalled(), typeVariableAliases);
nftm.setDeclaredSignature(getSignature());
public static ResolvedTypeMunger readMethod(VersionedDataInputStream s, ISourceContext context) throws IOException {
ISourceLocation sloc = null;
ResolvedMemberImpl rmImpl = ResolvedMemberImpl.readResolvedMember(s, context);
- Set superMethodsCalled = readSuperMethodsCalled(s);
+ Set<ResolvedMember> superMethodsCalled = readSuperMethodsCalled(s);
sloc = readSourceLocation(s);
- List typeVarAliases = readInTypeAliases(s);
+ List<String> typeVarAliases = readInTypeAliases(s);
ResolvedTypeMunger munger = new NewMethodTypeMunger(rmImpl, superMethodsCalled, typeVarAliases);
if (sloc != null) {
return result;
}
- public ResolvedTypeMunger parameterizeWith(Map m, World w) {
+ public ResolvedTypeMunger parameterizeWith(Map<String, UnresolvedType> m, World w) {
ResolvedMember parameterizedSignature = getSignature().parameterizedWith(m, w);
NewMethodTypeMunger nmtm = new NewMethodTypeMunger(parameterizedSignature, getSuperMethodsCalled(), typeVariableAliases);
nmtm.setDeclaredSignature(getSignature());
* getParam
*/
public String getParameterSignatureErased() {
- if (myParameterSignatureErasure != null) {
- return myParameterSignatureErasure;
- }
- StringBuffer sig = new StringBuffer();
- UnresolvedType[] myParameterTypes = getParameterTypes();
- for (int i = 0; i < myParameterTypes.length; i++) {
- UnresolvedType thisParameter = myParameterTypes[i];
- // type vars will be erased to first bound
- sig.append(thisParameter.getErasureSignature());
+ if (myParameterSignatureErasure == null) {
+ StringBuilder sig = new StringBuilder();
+ for (UnresolvedType parameter : getParameterTypes()) {
+ sig.append(parameter.getErasureSignature());
+ }
+ myParameterSignatureErasure = sig.toString();
}
- myParameterSignatureErasure = sig.toString();
return myParameterSignatureErasure;
}
* @return true if assignable to java.lang.Exception
*/
public boolean isException() {
- return (world.getCoreType(UnresolvedType.JAVA_LANG_EXCEPTION).isAssignableFrom(this));
+ return (world.getCoreType(UnresolvedType.JL_EXCEPTION).isAssignableFrom(this));
}
/**
return false;
}
- public ResolvedTypeMunger parameterizeWith(Map m, World w) {
+ public ResolvedTypeMunger parameterizeWith(Map<String, UnresolvedType> m, World w) {
throw new BCException("Dont call parameterizeWith() on a type munger of this kind: " + this.getClass());
}
* Creates a sensible unresolvedtype from some signature, for example: signature = LIGuard<TT;>; bound = toString=IGuard<T>
* sig=PIGuard<TT;>; sigErasure=LIGuard; kind=parameterized
*/
- private static UnresolvedType convertSigToType(String aSignature) {
+ static UnresolvedType convertSigToType(String aSignature) {
UnresolvedType bound = null;
int startOfParams = aSignature.indexOf('<');
if (startOfParams == -1) {
endOfParams = locateMatchingEndAngleBracket(lastType, startOfParams);
typeParams = createTypeParams(lastType.substring(startOfParams + 1, endOfParams));
}
+ StringBuilder s = new StringBuilder();
+ int firstAngleBracket = signature.indexOf('<');
+ s.append("P").append(signature.substring(1, firstAngleBracket));
+ s.append('<');
+ for (UnresolvedType typeParameter : typeParams) {
+ s.append(typeParameter.getSignature());
+ }
+ s.append(">;");
+ signature = s.toString();//'P' + signature.substring(1);
return new UnresolvedType(signature, signatureErasure, typeParams);
}
// can't replace above with convertSigToType - leads to stackoverflow
} else if (firstChar == '@') {
// missing type
return ResolvedType.MISSING;
+ } else if (firstChar == 'L') {
+ // only an issue if there is also an angle bracket
+ int leftAngleBracket = signature.indexOf('<');
+
+ if (leftAngleBracket == -1) {
+ return new UnresolvedType(signature);
+ } else {
+ int endOfParams = locateMatchingEndAngleBracket(signature, leftAngleBracket);
+ StringBuffer erasureSig = new StringBuffer(signature);
+ erasureSig.setCharAt(0, 'L');
+ while (leftAngleBracket != -1) {
+ erasureSig.delete(leftAngleBracket, endOfParams + 1);
+ leftAngleBracket = locateFirstBracket(erasureSig);
+ if (leftAngleBracket != -1) {
+ endOfParams = locateMatchingEndAngleBracket(erasureSig, leftAngleBracket);
+ }
+ }
+
+ String signatureErasure = erasureSig.toString();
+
+ // TODO should consider all the intermediate parameterizations as well!
+ // the type parameters of interest are only those that apply to the 'last type' in the signature
+ // if the signature is 'PMyInterface<String>$MyOtherType;' then there are none...
+ String lastType = null;
+ int nestedTypePosition = signature.indexOf("$", endOfParams); // don't look for $ INSIDE the parameters
+ if (nestedTypePosition != -1) {
+ lastType = signature.substring(nestedTypePosition + 1);
+ } else {
+ lastType = new String(signature);
+ }
+ leftAngleBracket = lastType.indexOf("<");
+ UnresolvedType[] typeParams = UnresolvedType.NONE;
+ if (leftAngleBracket != -1) {
+ endOfParams = locateMatchingEndAngleBracket(lastType, leftAngleBracket);
+ typeParams = createTypeParams(lastType.substring(leftAngleBracket + 1, endOfParams));
+ }
+ StringBuilder s = new StringBuilder();
+ int firstAngleBracket = signature.indexOf('<');
+ s.append("P").append(signature.substring(1, firstAngleBracket));
+ s.append('<');
+ for (UnresolvedType typeParameter : typeParams) {
+ s.append(typeParameter.getSignature());
+ }
+ s.append(">;");
+ signature = s.toString();//'P' + signature.substring(1);
+ return new UnresolvedType(signature, signatureErasure, typeParams);
+ }
+
}
return new UnresolvedType(signature);
}
private static UnresolvedType[] createTypeParams(String typeParameterSpecification) {
String remainingToProcess = typeParameterSpecification;
- List types = new ArrayList();
+ List<UnresolvedType> types = new ArrayList<UnresolvedType>();
while (remainingToProcess.length() != 0) {
int endOfSig = 0;
int anglies = 0;
+ boolean hadAnglies = false;
boolean sigFound = false; // OPTIMIZE can this be done better?
for (endOfSig = 0; (endOfSig < remainingToProcess.length()) && !sigFound; endOfSig++) {
char thisChar = remainingToProcess.charAt(endOfSig);
switch (thisChar) {
case '<':
anglies++;
+ hadAnglies = true;
break;
case '>':
anglies--;
}
}
}
- types.add(createTypeFromSignature(remainingToProcess.substring(0, endOfSig)));
+ String forProcessing = remainingToProcess.substring(0, endOfSig);
+ if (hadAnglies && forProcessing.charAt(0) == 'L') {
+ forProcessing = "P" + forProcessing.substring(1);
+ }
+ types.add(createTypeFromSignature(forProcessing));
remainingToProcess = remainingToProcess.substring(endOfSig);
}
UnresolvedType[] typeParams = new UnresolvedType[types.size()];
import java.util.Map;
import org.aspectj.util.GenericSignature;
-import org.aspectj.util.GenericSignature.ClassSignature;
import org.aspectj.util.GenericSignatureParser;
+import org.aspectj.util.GenericSignature.ClassSignature;
import org.aspectj.weaver.tools.Traceable;
/**
- * A UnresolvedType represents a type to the weaver. It has a basic signature that knows nothing about type variables, type
- * parameters, etc.. UnresolvedTypes are resolved in some World (a repository of types). When a UnresolvedType is resolved it turns
- * into a ResolvedType which may be a primitive type, or a ReferenceType. ReferenceTypes may refer to simple, generic, parameterized
- * or type-variable based reference types. A ReferenceType is backed by a delegate that provides information about the type based on
- * some repository (currently either BCEL or an EclipseSourceType, but in the future we probably need to support java.lang.reflect
- * based delegates too).
- *
+ * A UnresolvedType represents a type to the weaver. UnresolvedTypes are resolved in some World (a type repository). When a
+ * UnresolvedType is resolved it turns into a ResolvedType which may be a primitive type, or a ReferenceType. ReferenceTypes may
+ * refer to simple, generic, parameterized or type-variable based reference types. A ReferenceType is backed by a delegate that
+ * provides information about the type based on some repository (for example an Eclipse based delegate, a bytecode based delegate or
+ * a reflection based delegate).
+ * <p>
* Every UnresolvedType has a signature, the unique key for the type in the world.
- *
- *
- * TypeXs are fully aware of their complete type information (there is no erasure in the UnresolvedType world). To achieve this, the
- * signature of TypeXs combines the basic Java signature and the generic signature information into one complete signature.
- *
- * The format of a UnresolvedType signature is as follows:
- *
- * a simple (non-generic, non-parameterized) type has the as its signature the Java signature. e.g. Ljava/lang/String;
- *
- * a generic type has signature: TypeParamsOpt ClassSig SuperClassSig SuperIntfListOpt
- *
- * following the Generic signature grammar in the JVM spec., but with the addition of the ClassSignature (which is not in the
- * generic signature). In addition type variable names are replaced by a simple number which represents their declaration order in
- * the type declaration.
- *
- * e.g. public class Foo<T extends Number> would have signature: <1:Ljava/lang/Number>Lorg.xyz.Foo;Ljava/lang/Object;
- *
- * A parameterized type is a distinct type in the world with its own signature following the grammar:
- *
- * TypeParamsOpt ClassSig<ParamSigList>;
- *
- * but with the L for the class sig replaced by "P". For example List<String> has signature
- *
- * Pjava/util/List<Ljava/lang/String>;
- *
- * and List<T> in the following class : class Foo<T> { List<T> lt; }
- *
- * has signature: <1:>Pjava/util/List<T1;>;
- *
- * A typex that represents a type variable has its own unique signature, following the grammar for a FormalTypeParameter in the JVM
- * spec.
- *
- * A generic typex has its true signature and also an erasure signature. Both of these are keys pointing to the same UnresolvedType
- * in the world. For example List has signature:
- *
- * <1:>Ljava/util/List;Ljava/lang/Object;
- *
- * and the erasure signature
- *
- * Ljava/util/List;
- *
- * Generics wildcards introduce their own special signatures for type parameters. The wildcard ? has signature * The wildcard ?
- * extends Foo has signature +LFoo; The wildcard ? super Foo has signature -LFoo;
*/
public class UnresolvedType implements Traceable, TypeVariableDeclaringElement {
- // common types referred to by the weaver
+ // common type structures
public static final UnresolvedType[] NONE = new UnresolvedType[0];
public static final UnresolvedType OBJECT = forSignature("Ljava/lang/Object;");
public static final UnresolvedType OBJECTARRAY = forSignature("[Ljava/lang/Object;");
public static final UnresolvedType AT_RETENTION = forSignature("Ljava/lang/annotation/Retention;");
public static final UnresolvedType ENUM = forSignature("Ljava/lang/Enum;");
public static final UnresolvedType ANNOTATION = forSignature("Ljava/lang/annotation/Annotation;");
- public static final UnresolvedType JAVA_LANG_CLASS = forSignature("Ljava/lang/Class;");
+ public static final UnresolvedType JL_CLASS = forSignature("Ljava/lang/Class;");
public static final UnresolvedType JAVA_LANG_CLASS_ARRAY = forSignature("[Ljava/lang/Class;");
- public static final UnresolvedType JAVA_LANG_STRING = forSignature("Ljava/lang/String;");
- public static final UnresolvedType JAVA_LANG_EXCEPTION = forSignature("Ljava/lang/Exception;");
+ public static final UnresolvedType JL_STRING = forSignature("Ljava/lang/String;");
+ public static final UnresolvedType JL_EXCEPTION = forSignature("Ljava/lang/Exception;");
public static final UnresolvedType JAVA_LANG_REFLECT_METHOD = forSignature("Ljava/lang/reflect/Method;");
public static final UnresolvedType JAVA_LANG_REFLECT_FIELD = forSignature("Ljava/lang/reflect/Field;");
public static final UnresolvedType JAVA_LANG_REFLECT_CONSTRUCTOR = forSignature("Ljava/lang/reflect/Constructor;");
public static final UnresolvedType JOINPOINT_STATICPART = forSignature("Lorg/aspectj/lang/JoinPoint$StaticPart;");
public static final UnresolvedType JOINPOINT_ENCLOSINGSTATICPART = forSignature("Lorg/aspectj/lang/JoinPoint$EnclosingStaticPart;");
- // this doesn't belong here and will get moved to ResolvedType later in the refactoring
+ // A type is considered missing if we have a signature for it but cannot find the delegate
public static final String MISSING_NAME = "@missing@";
// OPTIMIZE I dont think you can ask something unresolved what kind of type it is, how can it always know? Push down into
- // resolvedtype
- // that will force references to resolvedtypes to be correct rather than relying on unresolvedtypes to answer questions
+ // resolvedtype that will force references to resolvedtypes to be correct rather than relying on unresolvedtypes to answer questions
protected TypeKind typeKind = TypeKind.SIMPLE; // what kind of type am I?
+ protected String signature;
+
/**
- * THE SIGNATURE - see the comments above for how this is defined
+ * The erasure of the signature. Contains only the Java signature of the type with all supertype, superinterface, type variable,
+ * and parameter information removed.
*/
- protected String signature;
+ protected String signatureErasure;
/**
* Calculated on first request - the package name (java.lang for type java.lang.String)
*/
private String className;
- /**
- * The erasure of the signature. Contains only the Java signature of the type with all supertype, superinterface, type variable,
- * and parameter information removed.
- */
- protected String signatureErasure;
-
/**
* Iff isParameterized(), then these are the type parameters
*/
}
/**
- * Equality is checked based on the underlying signature. {@link ResolvedType} objects' equals is by reference.
+ * Equality is checked based on the underlying signature.
*/
@Override
public boolean equals(Object other) {
}
}
- // ---- Things we can do without a world
+ // The operations supported by an UnresolvedType are those that do not require a world
/**
* This is the size of this type as used in JVM.
return 1;
}
- public static UnresolvedType makeArray(UnresolvedType base, int dims) {
- StringBuffer sig = new StringBuffer();
- for (int i = 0; i < dims; i++) {
- sig.append("[");
- }
- sig.append(base.getSignature());
- return UnresolvedType.forSignature(sig.toString());
- }
-
/**
* NOTE: Use forSignature() if you can, it'll be cheaper ! Constructs a UnresolvedType for a java language type name. For
* example:
*
* </blockquote>
*
- * Types may equivalently be produced by this or by {@link #forName(String)}.
+ * Types may equivalently be produced by this or by {@link #forName(String)}. This method should not be passed P signatures.
*
* <blockquote>
*
* @return a type object represnting that JVM bytecode signature.
*/
public static UnresolvedType forSignature(String signature) {
+ assert !(signature.startsWith("L") && signature.indexOf("<") != -1);
switch (signature.charAt(0)) {
case 'B':
return ResolvedType.BYTE;
}
private static String nameToSignature(String name) {
- if (name.equals("byte")) {
- return "B";
- }
- if (name.equals("char")) {
- return "C";
- }
- if (name.equals("double")) {
- return "D";
- }
- if (name.equals("float")) {
- return "F";
- }
- if (name.equals("int")) {
- return "I";
- }
- if (name.equals("long")) {
- return "J";
- }
- if (name.equals("short")) {
- return "S";
- }
- if (name.equals("boolean")) {
- return "Z";
- }
- if (name.equals("void")) {
- return "V";
- }
- if (name.equals("?")) {
- return name;
+ int len = name.length();
+ if (len < 8) {
+ if (name.equals("byte")) {
+ return "B";
+ }
+ if (name.equals("char")) {
+ return "C";
+ }
+ if (name.equals("double")) {
+ return "D";
+ }
+ if (name.equals("float")) {
+ return "F";
+ }
+ if (name.equals("int")) {
+ return "I";
+ }
+ if (name.equals("long")) {
+ return "J";
+ }
+ if (name.equals("short")) {
+ return "S";
+ }
+ if (name.equals("boolean")) {
+ return "Z";
+ }
+ if (name.equals("void")) {
+ return "V";
+ }
+ if (name.equals("?")) {
+ return name;
+ }
}
if (name.endsWith("[]")) {
return "[" + nameToSignature(name.substring(0, name.length() - 2));
}
- if (name.length() != 0) {
- // lots more tests could be made here...
-
+ if (len != 0) {
// check if someone is calling us with something that is a signature already
- if (name.charAt(0) == '[') {
- throw new BCException("Do not call nameToSignature with something that looks like a signature (descriptor): '"
- + name + "'");
- }
+ assert name.charAt(0) != '[';
if (name.indexOf("<") == -1) {
- // not parameterised
- return "L" + name.replace('.', '/') + ";";
+ // not parameterized
+ return new StringBuilder("L").append(name.replace('.', '/')).append(';').toString();
} else {
StringBuffer nameBuff = new StringBuffer();
int nestLevel = 0;
}
}
+ /**
+ * Write out an UnresolvedType - the signature should be enough.
+ */
public final void write(CompressingDataOutputStream s) throws IOException {
s.writeUTF(getSignature());
}
+ /**
+ * Read in an UnresolvedType - just read the signature and rebuild the UnresolvedType.
+ */
public static UnresolvedType read(DataInputStream s) throws IOException {
String sig = s.readUTF();
if (sig.equals(MISSING_NAME)) {
return ResolvedType.MISSING;
} else {
- UnresolvedType ret = UnresolvedType.forSignature(sig);
- return ret;
+ // TODO isn't it a shame to build these (this method is expensive) and then chuck them away on resolution?
+ // TODO review callers and see if they are immediately resolving it, maybe we can do something more optimal if they are
+ return UnresolvedType.forSignature(sig);
}
}
- public static void writeArray(UnresolvedType[] types, CompressingDataOutputStream s) throws IOException {
- int len = types.length;
- s.writeShort(len);
- for (int i = 0; i < len; i++) {
- types[i].write(s);
- }
- }
-
- public static UnresolvedType[] readArray(DataInputStream s) throws IOException {
- int len = s.readShort();
- if (len == 0) {
- return UnresolvedType.NONE;
- }
- UnresolvedType[] types = new UnresolvedType[len];
- for (int i = 0; i < len; i++) {
- types[i] = UnresolvedType.read(s);
- }
- return types;
- }
-
public String getNameAsIdentifier() {
return getName().replace('.', '_');
}
}
}
- public String getPackageName() {
- if (packageName == null) {
- String name = getName();
- if (name.indexOf("<") != -1) {
- name = name.substring(0, name.indexOf("<"));
- }
- int index = name.lastIndexOf('.');
- if (index == -1) {
- packageName = "";
- } else {
- packageName = name.substring(0, index);
- }
- }
- return packageName;
- }
-
public UnresolvedType[] getTypeParameters() {
return typeParameters == null ? UnresolvedType.NONE : typeParameters;
}
- /**
- * Doesn't include the package
- */
- public String getClassName() {
- if (className == null) {
- String name = getName();
- int index = name.lastIndexOf('.');
- if (index == -1) {
- className = name;
- } else {
- className = name.substring(index + 1);
- }
- }
- return className;
- }
-
public TypeVariable[] getTypeVariables() {
return typeVariables;
}
public UnresolvedType parameterize(Map<String, UnresolvedType> typeBindings) {
throw new UnsupportedOperationException("unable to parameterize unresolved type: " + signature);
}
+
+ /**
+ * @return the class name (does not include the package name)
+ */
+ public String getClassName() {
+ if (className == null) {
+ String name = getName();
+ int index = name.lastIndexOf('.');
+ if (index == -1) {
+ className = name;
+ } else {
+ className = name.substring(index + 1);
+ }
+ }
+ return className;
+ }
+
+ /**
+ * @return the package name (no class name included)
+ */
+ public String getPackageName() {
+ if (packageName == null) {
+ String name = getName();
+ if (name.indexOf("<") != -1) {
+ name = name.substring(0, name.indexOf("<"));
+ }
+ int index = name.lastIndexOf('.');
+ if (index == -1) {
+ packageName = "";
+ } else {
+ packageName = name.substring(0, index);
+ }
+ }
+ return packageName;
+ }
+
+ // TODO these move to a TypeUtils class
+
+ public static void writeArray(UnresolvedType[] types, CompressingDataOutputStream stream) throws IOException {
+ int len = types.length;
+ stream.writeShort(len);
+ for (UnresolvedType type : types) {
+ type.write(stream);
+ }
+ }
+
+ public static UnresolvedType[] readArray(DataInputStream s) throws IOException {
+ int len = s.readShort();
+ if (len == 0) {
+ return UnresolvedType.NONE;
+ }
+ UnresolvedType[] types = new UnresolvedType[len];
+ for (int i = 0; i < len; i++) {
+ types[i] = UnresolvedType.read(s);
+ }
+ return types;
+ }
+
+ public static UnresolvedType makeArray(UnresolvedType base, int dims) {
+ StringBuffer sig = new StringBuffer();
+ for (int i = 0; i < dims; i++) {
+ sig.append("[");
+ }
+ sig.append(base.getSignature());
+ return UnresolvedType.forSignature(sig.toString());
+ }
}
* ******************************************************************/
package org.aspectj.weaver;
-
/**
* @author Adrian Colyer
* @author Andy Clement
}
public UnresolvedTypeVariableReferenceType(TypeVariable aTypeVariable) {
- super(aTypeVariable.getFirstBound().getSignature());
+ super("T" + aTypeVariable.getName() + ";", aTypeVariable.getFirstBound().getErasureSignature());//aTypeVariable.getFirstBound().getSignature());
this.typeVariable = aTypeVariable;
}
// only used when resolving circular refs...
public void setTypeVariable(TypeVariable aTypeVariable) {
this.signature = "T" + aTypeVariable.getName() + ";"; // aTypeVariable.getUpperBound().getSignature();
+ this.signatureErasure = aTypeVariable.getFirstBound().getErasureSignature();
this.typeVariable = aTypeVariable;
this.typeKind = TypeKind.TYPE_VARIABLE;
}
} else {
throw new RuntimeException("Not implemented for " + t);
}
- } else if (t.equals(ResolvedType.JAVA_LANG_STRING)) {
+ } else if (t.equals(ResolvedType.JL_STRING)) {
// nothing to do, it will be OK
} else {
throw new RuntimeException("Compiler limitation: annotation value support not implemented for type " + t);
suite.addTestSuite(ReflectionWorldSpecificTest.class);
suite.addTestSuite(ReflectionWorldBasicTest.class);
suite.addTestSuite(ReflectionWorldPointcutExpressionTests.class);
+ suite.addTestSuite(TypeFactoryTests.class);
suite.addTest(PatternsTests.suite());
return suite;
}
--- /dev/null
+/* *******************************************************************
+ * Copyright (c) 2010 Contributors.
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://eclipse.org/legal/epl-v10.html
+ * ******************************************************************/
+package org.aspectj.weaver;
+
+import junit.framework.TestCase;
+
+/**
+ * Check signature to type mapping.
+ *
+ * @author Andy Clement
+ */
+public class TypeFactoryTests extends TestCase {
+
+ public void testParameterizedSig() {
+ UnresolvedType t = null;
+ t = UnresolvedType.forSignature("Pjava/util/List<Ljava/lang/String;>;");
+ assertEquals("Ljava/util/List;", t.getErasureSignature());
+ assertEquals("Ljava/lang/String;", t.getTypeParameters()[0].signature);
+ assertEquals("Ljava/lang/String;", t.getTypeParameters()[0].signatureErasure);
+ assertEquals("Pjava/util/List<Ljava/lang/String;>;", t.getSignature());
+
+ t = TypeFactory.createTypeFromSignature("Ljava/util/List<Ljava/lang/String;>;");
+ assertEquals("Ljava/util/List;", t.getErasureSignature());
+ assertEquals("Ljava/lang/String;", t.getTypeParameters()[0].signature);
+ assertEquals("Ljava/lang/String;", t.getTypeParameters()[0].signatureErasure);
+ assertEquals("Pjava/util/List<Ljava/lang/String;>;", t.getSignature());
+
+ t = UnresolvedType.forName("java.util.List<java.lang.String>");
+ assertEquals("Ljava/util/List;", t.getErasureSignature());
+ assertEquals("Ljava/lang/String;", t.getTypeParameters()[0].signature);
+ assertEquals("Ljava/lang/String;", t.getTypeParameters()[0].signatureErasure);
+ assertEquals("Pjava/util/List<Ljava/lang/String;>;", t.getSignature());
+
+ t = UnresolvedType.forSignature("Pjava/util/Map<TS;Pjava/util/List<Ljava/lang/String;>;>;");
+ assertEquals("Ljava/util/Map;", t.getErasureSignature());
+ assertEquals("TS;", t.getTypeParameters()[0].signature);
+ assertEquals("Ljava/lang/Object;", t.getTypeParameters()[0].signatureErasure);
+ assertEquals("S", ((UnresolvedTypeVariableReferenceType) t.getTypeParameters()[0]).getTypeVariable().getName());
+ assertEquals("Pjava/util/Map<TS;Pjava/util/List<Ljava/lang/String;>;>;", t.getSignature());
+ assertEquals("Pjava/util/List<Ljava/lang/String;>;", t.getTypeParameters()[1].signature);
+ assertEquals("Ljava/util/List;", t.getTypeParameters()[1].signatureErasure);
+
+ t = UnresolvedType.forSignature("Pjava/util/List<+Pnl/ZoekFoo<TS;Pnl/ZoekCopy<TS;>;>;>;");
+ assertEquals("Ljava/util/List;", t.getErasureSignature());
+ WildcardedUnresolvedType wut = (WildcardedUnresolvedType) t.getTypeParameters()[0];
+ assertEquals("+Pnl/ZoekFoo<TS;Pnl/ZoekCopy<TS;>;>;", wut.signature);
+ assertEquals("Lnl/ZoekFoo;", wut.signatureErasure);
+ assertTrue(wut.isExtends());
+ assertEquals("Pnl/ZoekFoo<TS;Pnl/ZoekCopy<TS;>;>;", wut.getUpperBound().signature);
+ assertEquals("Lnl/ZoekFoo;", wut.getUpperBound().signatureErasure);
+ UnresolvedTypeVariableReferenceType tvar = (UnresolvedTypeVariableReferenceType) wut.getUpperBound().getTypeParameters()[0];
+ assertEquals("Pnl/ZoekFoo<TS;Pnl/ZoekCopy<TS;>;>;", wut.getUpperBound().signature);
+ assertEquals("Lnl/ZoekFoo;", wut.getUpperBound().signatureErasure);
+ assertEquals("S", tvar.getTypeVariable().getName());
+ UnresolvedType t2 = wut.getUpperBound().getTypeParameters()[1];
+ assertEquals("Pnl/ZoekCopy<TS;>;", t2.getSignature());
+ assertEquals("Lnl/ZoekCopy;", t2.getErasureSignature());
+
+ // // t = UnresolvedType.forSignature("Ljava/util/List<+Lnl/ZoekFoo<TS;Lnl/ZoekCopy<TS;>;>;>;");
+ // t = TypeFactory.createTypeFromSignature("Ljava/util/List<+Lnl/ZoekFoo<TS;Lnl/ZoekCopy<TS;>;>;>;");
+ // System.out.println(t.getSignature());
+ //
+ // t = TypeFactory.createTypeFromSignature("Ljava/util/List<Lnl/ZoekFoo<Ljava/lang/String;>;>;");
+ // System.out.println(t.getSignature()); // Pjava/util/List<Lnl/ZoekFoo<Ljava/lang/String;>;>;
+
+ // TODO should be able to cope with nested parameterizations
+ // Foo<String>.Bar<List<Map<String,Integer>>>
+ // both components Foo and Bar of that are parameterized
+ }
+}