]> source.dussan.org Git - aspectj.git/commitdiff
320358: type signature changes
authoraclement <aclement>
Fri, 30 Jul 2010 03:51:56 +0000 (03:51 +0000)
committeraclement <aclement>
Fri, 30 Jul 2010 03:51:56 +0000 (03:51 +0000)
15 files changed:
org.aspectj.matcher/src/org/aspectj/weaver/AjcMemberMaker.java
org.aspectj.matcher/src/org/aspectj/weaver/ConcreteTypeMunger.java
org.aspectj.matcher/src/org/aspectj/weaver/MemberImpl.java
org.aspectj.matcher/src/org/aspectj/weaver/MemberUtils.java [new file with mode: 0644]
org.aspectj.matcher/src/org/aspectj/weaver/NewFieldTypeMunger.java
org.aspectj.matcher/src/org/aspectj/weaver/NewMethodTypeMunger.java
org.aspectj.matcher/src/org/aspectj/weaver/ResolvedMemberImpl.java
org.aspectj.matcher/src/org/aspectj/weaver/ResolvedType.java
org.aspectj.matcher/src/org/aspectj/weaver/ResolvedTypeMunger.java
org.aspectj.matcher/src/org/aspectj/weaver/TypeFactory.java
org.aspectj.matcher/src/org/aspectj/weaver/UnresolvedType.java
org.aspectj.matcher/src/org/aspectj/weaver/UnresolvedTypeVariableReferenceType.java
org.aspectj.matcher/src/org/aspectj/weaver/patterns/WildAnnotationTypePattern.java
org.aspectj.matcher/testsrc/org/aspectj/weaver/MatcherModuleTests.java
org.aspectj.matcher/testsrc/org/aspectj/weaver/TypeFactoryTests.java [new file with mode: 0644]

index 1e533918d83c7df9072a9cf0466fcd4e746a3208..918572bcda45a76435e05365f53381e27d5695c7 100644 (file)
@@ -109,7 +109,7 @@ public class AjcMemberMaker {
                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);
        }
 
@@ -126,7 +126,7 @@ public class AjcMemberMaker {
        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;
        }
 
@@ -134,7 +134,7 @@ public class AjcMemberMaker {
        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;
        }
index a51de77c956a198e2d14c696955925aebe88cbfc..8f86876225574fdae329f309d17280022383db6c 100644 (file)
@@ -69,14 +69,16 @@ public abstract class ConcreteTypeMunger implements PartialOrder.PartialComparab
        }
 
        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);
        }
 
@@ -119,8 +121,9 @@ public abstract class ConcreteTypeMunger implements PartialOrder.PartialComparab
         * </code>
         */
        public boolean isTargetTypeParameterized() {
-               if (munger == null)
+               if (munger == null) {
                        return false;
+               }
                return munger.sharesTypeVariablesWithGenericType();
        }
 
@@ -131,12 +134,13 @@ public abstract class ConcreteTypeMunger implements PartialOrder.PartialComparab
        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()
index 64ae458d21ed94bcbc9ea55afc3d77cc2baa9abc..fda448d5e88d575e5468c352106135a3d70c58b5 100644 (file)
@@ -381,17 +381,13 @@ public class MemberImpl implements Member {
        }
 
        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;
        }
 
diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/MemberUtils.java b/org.aspectj.matcher/src/org/aspectj/weaver/MemberUtils.java
new file mode 100644 (file)
index 0000000..201eb75
--- /dev/null
@@ -0,0 +1,25 @@
+/* *******************************************************************
+ * 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>");
+       }
+
+}
index bb2cacbb1389664cd769a8a0d28a47052bb4bb49..ed8afc1e079f151926d05603ec5a1e674d0cc2c6 100644 (file)
@@ -128,7 +128,7 @@ public class NewFieldTypeMunger extends ResolvedTypeMunger {
                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());
index da5c3b1f4853b5486a7d80cdf897248e4816d554..a6e0ffce7b3ef456405b38eec2b5116e96d62fd3 100644 (file)
@@ -69,9 +69,9 @@ public class NewMethodTypeMunger extends ResolvedTypeMunger {
        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) {
@@ -138,7 +138,7 @@ public class NewMethodTypeMunger extends ResolvedTypeMunger {
                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());
index 963490118fc8af0c0a916f47fb0aa7ee94cc626a..749a9bbffa84548fa21ab9ae9b4c685220faaf71 100644 (file)
@@ -1039,17 +1039,13 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
         * 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;
        }
 
index 0bdb6953e1d774d7d8f58225fbde54432d4f50c5..b500076e8543537d3a2b2e09b210e41872884abc 100644 (file)
@@ -2499,7 +2499,7 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
         * @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));
        }
 
        /**
index e08fe2f2eec6ca06e912958ff71451b0dbe3e366..2ba3cbc36f8a0b577b54c5dda66eb6339e4f3487 100644 (file)
@@ -488,7 +488,7 @@ public abstract class ResolvedTypeMunger {
                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());
        }
 
index 7cdbe230b67c66f4a513c5ddad8a56907b4f99ca..c81e23133bd7f146aebdd0dc942d52ea301c71a9 100644 (file)
@@ -69,7 +69,7 @@ public class TypeFactory {
         * 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) {
@@ -132,6 +132,15 @@ public class TypeFactory {
                                        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
@@ -185,6 +194,54 @@ public class TypeFactory {
                } 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);
        }
@@ -224,16 +281,18 @@ public class TypeFactory {
 
        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--;
@@ -260,7 +319,11 @@ public class TypeFactory {
                                        }
                                }
                        }
-                       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()];
index 992e38548146ac7b6bc46e71a83d490313fb811b..1193eff17004063c503f67494d83c5ef1000ddbe 100644 (file)
@@ -19,66 +19,22 @@ import java.io.IOException;
 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;");
@@ -91,10 +47,10 @@ public class UnresolvedType implements Traceable, TypeVariableDeclaringElement {
        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;");
@@ -106,18 +62,20 @@ public class UnresolvedType implements Traceable, TypeVariableDeclaringElement {
        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)
@@ -129,12 +87,6 @@ public class UnresolvedType implements Traceable, TypeVariableDeclaringElement {
         */
        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
         */
@@ -198,7 +150,7 @@ public class UnresolvedType implements Traceable, TypeVariableDeclaringElement {
        }
 
        /**
-        * 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) {
@@ -237,7 +189,7 @@ public class UnresolvedType implements Traceable, TypeVariableDeclaringElement {
                }
        }
 
-       // ---- 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.
@@ -246,15 +198,6 @@ public class UnresolvedType implements Traceable, TypeVariableDeclaringElement {
                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:
@@ -398,7 +341,7 @@ public class UnresolvedType implements Traceable, TypeVariableDeclaringElement {
         * 
         * </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>
         * 
@@ -413,6 +356,7 @@ public class UnresolvedType implements Traceable, TypeVariableDeclaringElement {
         * @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;
@@ -740,51 +684,49 @@ public class UnresolvedType implements Traceable, TypeVariableDeclaringElement {
        }
 
        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;
@@ -835,40 +777,27 @@ public class UnresolvedType implements Traceable, TypeVariableDeclaringElement {
                }
        }
 
+       /**
+        * 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('.', '_');
        }
@@ -883,42 +812,10 @@ public class UnresolvedType implements Traceable, TypeVariableDeclaringElement {
                }
        }
 
-       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;
        }
@@ -973,4 +870,70 @@ public class UnresolvedType implements Traceable, TypeVariableDeclaringElement {
        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());
+       }
 }
index 2dcbbd91a3980bd4ecf90fea8eead112f88d3458..5510c29d5220b97479097ec26bfc93de728a4206 100644 (file)
@@ -8,7 +8,6 @@
  * ******************************************************************/
 package org.aspectj.weaver;
 
-
 /**
  * @author Adrian Colyer
  * @author Andy Clement
@@ -23,13 +22,14 @@ public class UnresolvedTypeVariableReferenceType extends UnresolvedType implemen
        }
 
        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;
        }
index 8934a7512a946d09c1bd335dfc4e8678c12ca324..56492c3f29c0aef14a49065180ed7ce8c11c05d2 100644 (file)
@@ -181,7 +181,7 @@ public class WildAnnotationTypePattern extends AnnotationTypePattern {
                                                } 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);
index 5b646c5df18235d1721a2efad273fb08494dbe17..234e387de05cad1eb377427b87874d25219af447 100644 (file)
@@ -33,6 +33,7 @@ public class MatcherModuleTests extends TestCase {
                suite.addTestSuite(ReflectionWorldSpecificTest.class);
                suite.addTestSuite(ReflectionWorldBasicTest.class);
                suite.addTestSuite(ReflectionWorldPointcutExpressionTests.class);
+               suite.addTestSuite(TypeFactoryTests.class);
                suite.addTest(PatternsTests.suite());
                return suite;
        }
diff --git a/org.aspectj.matcher/testsrc/org/aspectj/weaver/TypeFactoryTests.java b/org.aspectj.matcher/testsrc/org/aspectj/weaver/TypeFactoryTests.java
new file mode 100644 (file)
index 0000000..40fed41
--- /dev/null
@@ -0,0 +1,76 @@
+/* *******************************************************************
+ * 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
+       }
+}