]> source.dussan.org Git - aspectj.git/commitdiff
refactored generic type handling
authoraclement <aclement>
Mon, 5 Apr 2010 19:37:06 +0000 (19:37 +0000)
committeraclement <aclement>
Mon, 5 Apr 2010 19:37:06 +0000 (19:37 +0000)
org.aspectj.matcher/src/org/aspectj/weaver/BoundedReferenceType.java
org.aspectj.matcher/src/org/aspectj/weaver/ReferenceType.java
org.aspectj.matcher/src/org/aspectj/weaver/ResolvedMemberImpl.java
org.aspectj.matcher/src/org/aspectj/weaver/TypeVariable.java
org.aspectj.matcher/src/org/aspectj/weaver/TypeVariableReferenceType.java
org.aspectj.matcher/src/org/aspectj/weaver/UnresolvedTypeVariableReferenceType.java
org.aspectj.matcher/src/org/aspectj/weaver/WildcardedUnresolvedType.java
org.aspectj.matcher/src/org/aspectj/weaver/World.java
org.aspectj.matcher/src/org/aspectj/weaver/patterns/DeclareSoft.java
org.aspectj.matcher/src/org/aspectj/weaver/patterns/ReferencePointcut.java
org.aspectj.matcher/src/org/aspectj/weaver/patterns/WildTypePattern.java

index 11796aa7ddd0cdb0a7fd33f5185be67033566d8d..a1f164e283f8bf5421c3c0f81aa2673145fc9848 100644 (file)
@@ -23,28 +23,26 @@ import java.util.Map;
  */
 public class BoundedReferenceType extends ReferenceType {
 
+       // possible kinds of BoundedReferenceType
+       public static final int UNBOUND = 0;
+       public static final int EXTENDS = 1;
+       public static final int SUPER = 2;
+
+       public int kind;
+
        private ResolvedType lowerBound;
 
        private ResolvedType upperBound;
 
        protected ReferenceType[] additionalInterfaceBounds = ReferenceType.EMPTY_ARRAY;
 
-       protected boolean isExtends = true;
-
-       protected boolean isSuper = false;
-
-       public UnresolvedType getUpperBound() {
-               return upperBound;
-       }
-
-       public UnresolvedType getLowerBound() {
-               return lowerBound;
-       }
-
        public BoundedReferenceType(ReferenceType aBound, boolean isExtends, World world) {
                super((isExtends ? "+" : "-") + aBound.signature, aBound.signatureErasure, world);
-               this.isExtends = isExtends;
-               this.isSuper = !isExtends;
+               if (isExtends) {
+                       this.kind = EXTENDS;
+               } else {
+                       this.kind = SUPER;
+               }
                if (isExtends) {
                        upperBound = aBound;
                } else {
@@ -59,48 +57,78 @@ public class BoundedReferenceType extends ReferenceType {
                this.additionalInterfaceBounds = additionalInterfaces;
        }
 
+       /**
+        * only for use when resolving GenericsWildcardTypeX or a TypeVariableReferenceType
+        */
+       protected BoundedReferenceType(String signature, String erasedSignature, World world) {
+               super(signature, erasedSignature, world);
+               if (signature.equals("*")) {
+                       // pure wildcard
+                       this.kind = UNBOUND;
+                       upperBound = world.resolve(UnresolvedType.OBJECT);
+               } else {
+                       upperBound = world.resolve(forSignature(erasedSignature));
+               }
+               setDelegate(new BoundedReferenceTypeDelegate((ReferenceType) upperBound));
+       }
+
+       /**
+        * Constructs the BoundedReferenceType representing an unbounded wildcard '?'. In this situation the signature is '*' and the
+        * erased signature is Ljava/lang/Object;
+        */
+       public BoundedReferenceType(World world) {
+               super("*", "Ljava/lang/Object;", world);
+               this.kind = UNBOUND;
+               upperBound = world.resolve(UnresolvedType.OBJECT);
+               setDelegate(new BoundedReferenceTypeDelegate((ReferenceType)upperBound));
+       }
+
+       public UnresolvedType getUpperBound() {
+               return upperBound;
+       }
+
+       public UnresolvedType getLowerBound() {
+               return lowerBound;
+       }
+
        public ReferenceType[] getAdditionalBounds() {
                return additionalInterfaceBounds;
        }
 
+       @Override
        public UnresolvedType parameterize(Map typeBindings) {
+               if (this.kind == UNBOUND) {
+                       return this;
+               }
                ReferenceType[] parameterizedAdditionalInterfaces = new ReferenceType[additionalInterfaceBounds == null ? 0
                                : additionalInterfaceBounds.length];
                for (int i = 0; i < parameterizedAdditionalInterfaces.length; i++) {
                        parameterizedAdditionalInterfaces[i] = (ReferenceType) additionalInterfaceBounds[i].parameterize(typeBindings);
                }
-               if (isExtends) {
-                       return new BoundedReferenceType((ReferenceType) getUpperBound().parameterize(typeBindings), isExtends, world,
+               if (this.kind == EXTENDS) {
+                       return new BoundedReferenceType((ReferenceType) getUpperBound().parameterize(typeBindings), true, world,
                                        parameterizedAdditionalInterfaces);
                } else {
-                       return new BoundedReferenceType((ReferenceType) getLowerBound().parameterize(typeBindings), isExtends, world,
+                       // (this.kind == SUPER)
+                       return new BoundedReferenceType((ReferenceType) getLowerBound().parameterize(typeBindings), false, world,
                                        parameterizedAdditionalInterfaces);
                }
        }
 
-       /**
-        * only for use when resolving GenericsWildcardTypeX or a TypeVariableReferenceType
-        */
-       protected BoundedReferenceType(String sig, String sigErasure, World world) {
-               super(sig, sigErasure, world);
-               upperBound = world.resolve(UnresolvedType.OBJECT);
-               setDelegate(new BoundedReferenceTypeDelegate((ReferenceType) getUpperBound()));
-       }
-
-       public ReferenceType[] getInterfaceBounds() {
-               return additionalInterfaceBounds;
-       }
-
        public boolean hasLowerBound() {
-               return getLowerBound() != null;
+               return lowerBound != null;
        }
 
        public boolean isExtends() {
-               return (isExtends && !getUpperBound().getSignature().equals("Ljava/lang/Object;"));
+               return (this.kind == EXTENDS && !getUpperBound().getSignature().equals("Ljava/lang/Object;"));
        }
 
        public boolean isSuper() {
-               return isSuper;
+               return this.kind == SUPER;
+       }
+
+       public boolean isUnbound() {
+               return this.kind == UNBOUND;
        }
 
        public boolean alwaysMatches(ResolvedType aCandidateType) {
@@ -117,8 +145,9 @@ public class BoundedReferenceType extends ReferenceType {
 
        // this "maybe matches" that
        public boolean canBeCoercedTo(ResolvedType aCandidateType) {
-               if (alwaysMatches(aCandidateType))
+               if (alwaysMatches(aCandidateType)) {
                        return true;
+               }
                if (aCandidateType.isGenericWildcard()) {
                        BoundedReferenceType boundedRT = (BoundedReferenceType) aCandidateType;
                        ResolvedType myUpperBound = (ResolvedType) getUpperBound();
@@ -147,9 +176,11 @@ public class BoundedReferenceType extends ReferenceType {
                }
        }
 
+       @Override
        public String getSimpleName() {
-               if (!isExtends() && !isSuper())
+               if (!isExtends() && !isSuper()) {
                        return "?";
+               }
                if (isExtends()) {
                        return ("? extends " + getUpperBound().getSimpleName());
                } else {
@@ -158,6 +189,7 @@ public class BoundedReferenceType extends ReferenceType {
        }
 
        // override to include additional interface bounds...
+       @Override
        public ResolvedType[] getDeclaredInterfaces() {
                ResolvedType[] interfaces = super.getDeclaredInterfaces();
                if (additionalInterfaceBounds.length > 0) {
@@ -170,6 +202,7 @@ public class BoundedReferenceType extends ReferenceType {
                }
        }
 
+       @Override
        public boolean isGenericWildcard() {
                return true;
        }
index 2e56d71d6ad22d2f592b3f2c819e8b8ded8dd658..b876ad297e864bad4372485cce9da04987aac5b0 100644 (file)
@@ -134,27 +134,27 @@ public class ReferenceType extends ResolvedType {
 
        @Override
        public boolean isClass() {
-               return delegate.isClass();
+               return getDelegate().isClass();
        }
 
        @Override
        public int getCompilerVersion() {
-               return delegate.getCompilerVersion();
+               return getDelegate().getCompilerVersion();
        }
 
        @Override
        public boolean isGenericType() {
-               return !isParameterizedType() && !isRawType() && delegate.isGeneric();
+               return !isParameterizedType() && !isRawType() && getDelegate().isGeneric();
        }
 
        public String getGenericSignature() {
-               String sig = delegate.getDeclaredGenericSignature();
+               String sig = getDelegate().getDeclaredGenericSignature();
                return (sig == null) ? "" : sig;
        }
 
        @Override
        public AnnotationAJ[] getAnnotations() {
-               return delegate.getAnnotations();
+               return getDelegate().getAnnotations();
        }
 
        @Override
@@ -172,7 +172,7 @@ public class ReferenceType extends ResolvedType {
        }
 
        public boolean hasAnnotation(UnresolvedType ofType) {
-               boolean onDelegate = delegate.hasAnnotation(ofType);
+               boolean onDelegate = getDelegate().hasAnnotation(ofType);
                if (onDelegate) {
                        return true;
                }
@@ -200,14 +200,14 @@ public class ReferenceType extends ResolvedType {
 
        @Override
        public ResolvedType[] getAnnotationTypes() {
-               if (delegate == null) {
+               if (getDelegate() == null) {
                        throw new BCException("Unexpected null delegate for type " + this.getName());
                }
                if (annotationTypes == null) {
                        // there are no extras:
-                       return delegate.getAnnotationTypes();
+                       return getDelegate().getAnnotationTypes();
                } else {
-                       ResolvedType[] delegateAnnotationTypes = delegate.getAnnotationTypes();
+                       ResolvedType[] delegateAnnotationTypes = getDelegate().getAnnotationTypes();
                        ResolvedType[] result = new ResolvedType[annotationTypes.length + delegateAnnotationTypes.length];
                        System.arraycopy(delegateAnnotationTypes, 0, result, 0, delegateAnnotationTypes.length);
                        System.arraycopy(annotationTypes, 0, result, delegateAnnotationTypes.length, annotationTypes.length);
@@ -222,7 +222,7 @@ public class ReferenceType extends ResolvedType {
 
        @Override
        public AnnotationAJ getAnnotationOfType(UnresolvedType ofType) {
-               AnnotationAJ[] axs = delegate.getAnnotations();
+               AnnotationAJ[] axs = getDelegate().getAnnotations();
                if (axs == null) {
                        if (annotations != null) {
                                String searchSig = ofType.getSignature();
@@ -244,55 +244,55 @@ public class ReferenceType extends ResolvedType {
 
        @Override
        public boolean isAspect() {
-               return delegate.isAspect();
+               return getDelegate().isAspect();
        }
 
        @Override
        public boolean isAnnotationStyleAspect() {
-               return delegate.isAnnotationStyleAspect();
+               return getDelegate().isAnnotationStyleAspect();
        }
 
        @Override
        public boolean isEnum() {
-               return delegate.isEnum();
+               return getDelegate().isEnum();
        }
 
        @Override
        public boolean isAnnotation() {
-               return delegate.isAnnotation();
+               return getDelegate().isAnnotation();
        }
 
        @Override
        public boolean isAnonymous() {
-               return delegate.isAnonymous();
+               return getDelegate().isAnonymous();
        }
 
        @Override
        public boolean isNested() {
-               return delegate.isNested();
+               return getDelegate().isNested();
        }
 
        public ResolvedType getOuterClass() {
-               return delegate.getOuterClass();
+               return getDelegate().getOuterClass();
        }
 
        public String getRetentionPolicy() {
-               return delegate.getRetentionPolicy();
+               return getDelegate().getRetentionPolicy();
        }
 
        @Override
        public boolean isAnnotationWithRuntimeRetention() {
-               return delegate.isAnnotationWithRuntimeRetention();
+               return getDelegate().isAnnotationWithRuntimeRetention();
        }
 
        @Override
        public boolean canAnnotationTargetType() {
-               return delegate.canAnnotationTargetType();
+               return getDelegate().canAnnotationTargetType();
        }
 
        @Override
        public AnnotationTargetKind[] getAnnotationTargetKinds() {
-               return delegate.getAnnotationTargetKinds();
+               return getDelegate().getAnnotationTargetKinds();
        }
 
        // true iff the statement "this = (ThisType) other" would compile
@@ -579,23 +579,23 @@ public class ReferenceType extends ResolvedType {
 
        @Override
        public ISourceContext getSourceContext() {
-               return delegate.getSourceContext();
+               return getDelegate().getSourceContext();
        }
 
        @Override
        public ISourceLocation getSourceLocation() {
-               ISourceContext isc = delegate.getSourceContext();
+               ISourceContext isc = getDelegate().getSourceContext();
                return isc.makeSourceLocation(new Position(startPos, endPos));
        }
 
        @Override
        public boolean isExposedToWeaver() {
-               return (delegate == null) || delegate.isExposedToWeaver();
+               return (getDelegate() == null) || delegate.isExposedToWeaver();
        }
 
        @Override
        public WeaverStateInfo getWeaverState() {
-               return delegate.getWeaverState();
+               return getDelegate().getWeaverState();
        }
 
        @Override
@@ -604,7 +604,7 @@ public class ReferenceType extends ResolvedType {
                        return parameterizedFields;
                }
                if (isParameterizedType() || isRawType()) {
-                       ResolvedMember[] delegateFields = delegate.getDeclaredFields();
+                       ResolvedMember[] delegateFields = getDelegate().getDeclaredFields();
                        parameterizedFields = new ResolvedMember[delegateFields.length];
                        for (int i = 0; i < delegateFields.length; i++) {
                                parameterizedFields[i] = delegateFields[i].parameterizedWith(getTypesForMemberParameterization(), this,
@@ -612,7 +612,7 @@ public class ReferenceType extends ResolvedType {
                        }
                        return parameterizedFields;
                } else {
-                       return delegate.getDeclaredFields();
+                       return getDelegate().getDeclaredFields();
                }
        }
 
@@ -626,7 +626,7 @@ public class ReferenceType extends ResolvedType {
                if (interfaces != null) {
                        return interfaces;
                }
-               ResolvedType[] delegateInterfaces = delegate.getDeclaredInterfaces();
+               ResolvedType[] delegateInterfaces = getDelegate().getDeclaredInterfaces();
                if (newInterfaces != null) {
                        // OPTIMIZE does this part of the method trigger often?
                        ResolvedType[] extraInterfaces = new ResolvedType[delegateInterfaces.length + newInterfaces.length];
@@ -670,7 +670,7 @@ public class ReferenceType extends ResolvedType {
                        parameterizedInterfaces = new WeakReference<ResolvedType[]>(interfaces);
                        return interfaces;
                }
-               if (delegate.isCacheable()) {
+               if (getDelegate().isCacheable()) {
                        parameterizedInterfaces = new WeakReference<ResolvedType[]>(delegateInterfaces);
                }
                return delegateInterfaces;
@@ -765,7 +765,7 @@ public class ReferenceType extends ResolvedType {
                        return parameterizedMethods;
                }
                if (isParameterizedType() || isRawType()) {
-                       ResolvedMember[] delegateMethods = delegate.getDeclaredMethods();
+                       ResolvedMember[] delegateMethods = getDelegate().getDeclaredMethods();
                        UnresolvedType[] parameters = getTypesForMemberParameterization();
                        parameterizedMethods = new ResolvedMember[delegateMethods.length];
                        for (int i = 0; i < delegateMethods.length; i++) {
@@ -773,7 +773,7 @@ public class ReferenceType extends ResolvedType {
                        }
                        return parameterizedMethods;
                } else {
-                       return delegate.getDeclaredMethods();
+                       return getDelegate().getDeclaredMethods();
                }
        }
 
@@ -783,7 +783,7 @@ public class ReferenceType extends ResolvedType {
                        return parameterizedPointcuts;
                }
                if (isParameterizedType()) {
-                       ResolvedMember[] delegatePointcuts = delegate.getDeclaredPointcuts();
+                       ResolvedMember[] delegatePointcuts = getDelegate().getDeclaredPointcuts();
                        parameterizedPointcuts = new ResolvedMember[delegatePointcuts.length];
                        for (int i = 0; i < delegatePointcuts.length; i++) {
                                parameterizedPointcuts[i] = delegatePointcuts[i].parameterizedWith(getTypesForMemberParameterization(), this,
@@ -791,7 +791,7 @@ public class ReferenceType extends ResolvedType {
                        }
                        return parameterizedPointcuts;
                } else {
-                       return delegate.getDeclaredPointcuts();
+                       return getDelegate().getDeclaredPointcuts();
                }
        }
 
@@ -813,7 +813,7 @@ public class ReferenceType extends ResolvedType {
        @Override
        public TypeVariable[] getTypeVariables() {
                if (this.typeVariables == null) {
-                       this.typeVariables = delegate.getTypeVariables();
+                       this.typeVariables = getDelegate().getTypeVariables();
                        for (int i = 0; i < this.typeVariables.length; i++) {
                                this.typeVariables[i].resolve(world);
                        }
@@ -823,7 +823,7 @@ public class ReferenceType extends ResolvedType {
 
        @Override
        public PerClause getPerClause() {
-               PerClause pclause = delegate.getPerClause();
+               PerClause pclause = getDelegate().getPerClause();
                if (isParameterizedType()) { // could cache the result here...
                        Map parameterizationMap = getAjMemberParameterizationMap();
                        pclause = (PerClause) pclause.parameterizeWith(parameterizationMap, world);
@@ -838,7 +838,7 @@ public class ReferenceType extends ResolvedType {
                }
                Collection<Declare> declares = null;
                if (ajMembersNeedParameterization()) {
-                       Collection<Declare> genericDeclares = delegate.getDeclares();
+                       Collection<Declare> genericDeclares = getDelegate().getDeclares();
                        parameterizedDeclares = new ArrayList<Declare>();
                        Map<String, UnresolvedType> parameterizationMap = getAjMemberParameterizationMap();
                        for (Declare declareStatement : genericDeclares) {
@@ -846,7 +846,7 @@ public class ReferenceType extends ResolvedType {
                        }
                        declares = parameterizedDeclares;
                } else {
-                       declares = delegate.getDeclares();
+                       declares = getDelegate().getDeclares();
                }
                for (Declare d : declares) {
                        d.setDeclaringType(this);
@@ -856,7 +856,7 @@ public class ReferenceType extends ResolvedType {
 
        @Override
        public Collection<ConcreteTypeMunger> getTypeMungers() {
-               return delegate.getTypeMungers();
+               return getDelegate().getTypeMungers();
        }
 
        // GENERICITDFIX
@@ -882,12 +882,12 @@ public class ReferenceType extends ResolvedType {
 
        @Override
        public Collection getPrivilegedAccesses() {
-               return delegate.getPrivilegedAccesses();
+               return getDelegate().getPrivilegedAccesses();
        }
 
        @Override
        public int getModifiers() {
-               return delegate.getModifiers();
+               return getDelegate().getModifiers();
        }
 
        WeakReference<ResolvedType> superclassReference = new WeakReference<ResolvedType>(null);
@@ -902,21 +902,21 @@ public class ReferenceType extends ResolvedType {
                        if (this.isParameterizedType() && newSuperclass.isParameterizedType()) {
                                return newSuperclass.parameterize(getMemberParameterizationMap()).resolve(getWorld());
                        }
-                       if (delegate.isCacheable()) {
+                       if (getDelegate().isCacheable()) {
                                superclassReference = new WeakReference<ResolvedType>(ret);
                        }
                        return newSuperclass;
                }
                try {
                        world.setTypeVariableLookupScope(this);
-                       ret = delegate.getSuperclass();
+                       ret = getDelegate().getSuperclass();
                } finally {
                        world.setTypeVariableLookupScope(null);
                }
                if (this.isParameterizedType() && ret.isParameterizedType()) {
                        ret = ret.parameterize(getMemberParameterizationMap()).resolve(getWorld());
                }
-               if (delegate.isCacheable()) {
+               if (getDelegate().isCacheable()) {
                        superclassReference = new WeakReference<ResolvedType>(ret);
                }
                return ret;
@@ -977,11 +977,11 @@ public class ReferenceType extends ResolvedType {
 
        @Override
        public boolean doesNotExposeShadowMungers() {
-               return delegate.doesNotExposeShadowMungers();
+               return getDelegate().doesNotExposeShadowMungers();
        }
 
        public String getDeclaredGenericSignature() {
-               return delegate.getDeclaredGenericSignature();
+               return getDelegate().getDeclaredGenericSignature();
        }
 
        public void setGenericType(ReferenceType rt) {
@@ -1048,7 +1048,7 @@ public class ReferenceType extends ResolvedType {
                newInterfaces = null;
                parameterizedInterfaces.clear();
                superclassReference = new WeakReference<ResolvedType>(null);
-               if (delegate != null) {
+               if (getDelegate() != null) {
                        delegate.ensureConsistent();
                }
        }
@@ -1063,7 +1063,7 @@ public class ReferenceType extends ResolvedType {
                                newInterfaces = new ResolvedType[1];
                                newInterfaces[0] = newParent;
                        } else {
-                               ResolvedType[] existing = delegate.getDeclaredInterfaces();
+                               ResolvedType[] existing = getDelegate().getDeclaredInterfaces();
                                if (existing != null) {
                                        for (int i = 0; i < existing.length; i++) {
                                                if (existing[i].equals(newParent)) {
index 330e2792030e725ec1f9bd58624c68a7a89cad87..2bf17db5f7172a464cf84e6a9dc4836461fd090c 100644 (file)
@@ -1022,7 +1022,7 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
                                toBuffer.append("...");
                        } else {
                                alreadyUsedTypeVars.add(aType);
-                               appendSigWithTypeVarBoundsRemoved(typeVariableRT.getUpperBound(), toBuffer, alreadyUsedTypeVars);
+                               appendSigWithTypeVarBoundsRemoved(typeVariableRT.getTypeVariable().getUpperBound(), toBuffer, alreadyUsedTypeVars);
                        }
                        // toBuffer.append("T;");
                } else if (aType.isParameterizedType()) {
index 2d599f0ef59727622a7b0085d98e384dc8f876c4..76d954b83d316f9dca8bfe6284fb5a737428d265 100644 (file)
@@ -1,13 +1,10 @@
 /* *******************************************************************
- * Copyright (c) 2005 Contributors.
+ * Copyright (c) 2005-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 
- *  
- * Contributors: 
- *   Adrian Colyer                     Initial implementation
  * ******************************************************************/
 package org.aspectj.weaver;
 
@@ -15,92 +12,82 @@ import java.io.DataOutputStream;
 import java.io.IOException;
 
 /**
- * Represents a type variable with bounds
+ * Represents a type variable with possible bounds.
+ * 
+ * @author Adrian Colyer
+ * @author Andy Clement
  */
 public class TypeVariable {
 
        public static final TypeVariable[] NONE = new TypeVariable[0];
-       /**
-        * whether or not the bounds of this type variable have been resolved
-        */
-       private boolean isResolved = false;
 
-       private boolean beingResolved = false;
-
-       /**
-        * the name of the type variable as recorded in the generic signature
-        */
+       // the name of the type variable as recorded in the generic signature
        private String name;
-
+       // index
        private int rank;
-
+       // computed as required: either ==superclass or ==superInterfaces[0] or is OBJECT
+       private UnresolvedType firstbound;
+       // the upper bound of the type variable. From the extends clause, eg. T extends Number
+       private UnresolvedType superclass;
+       // any additional upper (interface) bounds. from the extends clause, e.g. T extends Number & Comparable
+       private UnresolvedType[] superInterfaces = UnresolvedType.NONE;
        // It would be nice to push this field onto the TypeVariableDeclaringElement
        // interface (a getKind()) but at the moment we don't always guarantee
        // to set the declaring element (eclipse seems to utilise the knowledge of
        // what declared the type variable, but we dont yet...)
-       /**
-        * What kind of element declared this type variable?
-        */
-       private int declaringElementKind = UNKNOWN;
        public static final int UNKNOWN = -1;
        public static final int METHOD = 1;
        public static final int TYPE = 2;
+       // What kind of element declared this type variable?
+       private int declaringElementKind = UNKNOWN;
        private TypeVariableDeclaringElement declaringElement;
+       // whether or not the bounds of this type variable have been resolved
+       private boolean isResolved = false;
+       // Is this type variable in the process of being resolved (allows for something self-referential like Enum)
+       private boolean beingResolved = false;
 
        /**
-        * the upper bound of the type variable (default to Object). From the extends clause, eg. T extends Number.
-        */
-       private UnresolvedType upperBound = UnresolvedType.OBJECT;
-
-       /**
-        * any additional upper (interface) bounds. from the extends clause, e.g. T extends Number & Comparable
-        */
-       private UnresolvedType[] additionalInterfaceBounds = new UnresolvedType[0];
-
-       /**
-        * any lower bound. from the super clause, eg T super Foo
+        * Constructor for an unbound type variable, eg. 'T'
         */
-       private UnresolvedType lowerBound = null;
-
-       public TypeVariable(String aName) {
-               this.name = aName;
-       }
-
-       public TypeVariable(String aName, UnresolvedType anUpperBound) {
-               this(aName);
-               this.upperBound = anUpperBound;
+       public TypeVariable(String name) {
+               this.name = name;
        }
 
-       public TypeVariable(String aName, UnresolvedType anUpperBound, UnresolvedType[] someAdditionalInterfaceBounds) {
-               this(aName, anUpperBound);
-               this.additionalInterfaceBounds = someAdditionalInterfaceBounds;
+       public TypeVariable(String name, UnresolvedType anUpperBound) {
+               this(name);
+               this.superclass = anUpperBound;
        }
 
-       public TypeVariable(String aName, UnresolvedType anUpperBound, UnresolvedType[] someAdditionalInterfaceBounds,
-                       UnresolvedType aLowerBound) {
-               this(aName, anUpperBound, someAdditionalInterfaceBounds);
-               this.lowerBound = aLowerBound;
+       public TypeVariable(String name, UnresolvedType anUpperBound, UnresolvedType[] superInterfaces) {
+               this(name, anUpperBound);
+               this.superInterfaces = superInterfaces;
        }
 
-       // First bound is the first 'real' bound, this can be an interface if
-       // no class bound was specified (it will default to object)
+       /**
+        * @return the first bound, either the superclass or if non is specified the first interface or if non are specified then OBJECT
+        */
        public UnresolvedType getFirstBound() {
-               if (upperBound.equals(UnresolvedType.OBJECT) && additionalInterfaceBounds != null && additionalInterfaceBounds.length != 0) {
-                       return additionalInterfaceBounds[0];
+               if (firstbound != null) {
+                       return firstbound;
                }
-               return upperBound;
+               if (superclass == null || superclass.getSignature().equals("Ljava/lang/Object;")) {
+                       if (superInterfaces.length > 0) {
+                               firstbound = superInterfaces[0];
+                       } else {
+                               firstbound = UnresolvedType.OBJECT;
+                       }
+               } else {
+                       firstbound = superclass;
+               }
+               return firstbound;
        }
 
        public UnresolvedType getUpperBound() {
-               return upperBound;
+               return superclass;
        }
 
-       public UnresolvedType[] getAdditionalInterfaceBounds() {
-               return additionalInterfaceBounds;
-       }
-
-       public UnresolvedType getLowerBound() {
-               return lowerBound;
+       public UnresolvedType[] getSuperInterfaces() {
+               return superInterfaces;
        }
 
        public String getName() {
@@ -110,13 +97,14 @@ public class TypeVariable {
        /**
         * resolve all the bounds of this type variable
         */
-       public TypeVariable resolve(World inSomeWorld) {
+       public TypeVariable resolve(World world) {
+               if (isResolved) {
+                       return this;
+               }
                if (beingResolved) {
                        return this;
-               } // avoid spiral of death
+               }
                beingResolved = true;
-               if (isResolved)
-                       return this;
 
                TypeVariable resolvedTVar = null;
 
@@ -124,7 +112,7 @@ public class TypeVariable {
                        // resolve by finding the real type var that we refer to...
                        if (declaringElementKind == TYPE) {
                                UnresolvedType declaring = (UnresolvedType) declaringElement;
-                               ReferenceType rd = (ReferenceType) declaring.resolve(inSomeWorld);
+                               ReferenceType rd = (ReferenceType) declaring.resolve(world);
                                TypeVariable[] tVars = rd.getTypeVariables();
                                for (int i = 0; i < tVars.length; i++) {
                                        if (tVars[i].getName().equals(getName())) {
@@ -137,38 +125,42 @@ public class TypeVariable {
                                ResolvedMember declaring = (ResolvedMember) declaringElement;
                                TypeVariable[] tvrts = declaring.getTypeVariables();
                                for (int i = 0; i < tvrts.length; i++) {
-                                       if (tvrts[i].getName().equals(getName()))
+                                       if (tvrts[i].getName().equals(getName())) {
                                                resolvedTVar = tvrts[i];
-                                       // if (tvrts[i].isTypeVariableReference()) {
-                                       // TypeVariableReferenceType tvrt = (TypeVariableReferenceType) tvrts[i].resolve(inSomeWorld);
-                                       // TypeVariable tv = tvrt.getTypeVariable();
-                                       // if (tv.getName().equals(getName())) resolvedTVar = tv;
-                                       // }
+                                               // if (tvrts[i].isTypeVariableReference()) {
+                                               // TypeVariableReferenceType tvrt = (TypeVariableReferenceType) tvrts[i].resolve(inSomeWorld);
+                                               // TypeVariable tv = tvrt.getTypeVariable();
+                                               // if (tv.getName().equals(getName())) resolvedTVar = tv;
+                                               // }
+                                       }
                                }
                        }
 
                        if (resolvedTVar == null) {
+                               throw new IllegalStateException();
                                // well, this is bad... we didn't find the type variable on the member
                                // could be a separate compilation issue...
                                // should issue message, this is a workaround to get us going...
-                               resolvedTVar = this;
+                               // resolvedTVar = this;
                        }
                } else {
                        resolvedTVar = this;
                }
 
-               upperBound = resolvedTVar.upperBound;
-               lowerBound = resolvedTVar.lowerBound;
-               additionalInterfaceBounds = resolvedTVar.additionalInterfaceBounds;
+               superclass = resolvedTVar.superclass;
+               superInterfaces = resolvedTVar.superInterfaces;
 
-               upperBound = upperBound.resolve(inSomeWorld);
-               if (lowerBound != null)
-                       lowerBound = lowerBound.resolve(inSomeWorld);
-
-               if (additionalInterfaceBounds != null) {
-                       for (int i = 0; i < additionalInterfaceBounds.length; i++) {
-                               additionalInterfaceBounds[i] = additionalInterfaceBounds[i].resolve(inSomeWorld);
+               if (superclass != null) {
+                       ResolvedType rt = superclass.resolve(world);
+                       if (!superclass.isTypeVariableReference() && rt.isInterface()) {
+                               throw new IllegalStateException("Why is the type an interface? " + rt);
                        }
+                       superclass = rt;
+               }
+               firstbound = getFirstBound().resolve(world);
+
+               for (int i = 0; i < superInterfaces.length; i++) {
+                       superInterfaces[i] = superInterfaces[i].resolve(world);
                }
                isResolved = true;
                beingResolved = false;
@@ -179,30 +171,28 @@ public class TypeVariable {
         * answer true if the given type satisfies all of the bound constraints of this type variable. If type variable has not been
         * resolved then throws IllegalStateException
         */
-       public boolean canBeBoundTo(ResolvedType aCandidateType) {
-               if (!isResolved)
+       public boolean canBeBoundTo(ResolvedType candidate) {
+               if (!isResolved) {
                        throw new IllegalStateException("Can't answer binding questions prior to resolving");
+               }
 
                // wildcard can accept any binding
-               if (aCandidateType.isGenericWildcard()) { // AMC - need a more robust test!
+               if (candidate.isGenericWildcard()) {
                        return true;
                }
 
                // otherwise can be bound iff...
-               // aCandidateType is a subtype of upperBound
-               if (!isASubtypeOf(upperBound, aCandidateType)) {
+
+               // candidate is a subtype of upperBound
+               if (superclass != null && !isASubtypeOf(superclass, candidate)) {
                        return false;
                }
-               // aCandidateType is a subtype of all additionalInterfaceBounds
-               for (int i = 0; i < additionalInterfaceBounds.length; i++) {
-                       if (!isASubtypeOf(additionalInterfaceBounds[i], aCandidateType)) {
+               // candidate is a subtype of all superInterfaces
+               for (int i = 0; i < superInterfaces.length; i++) {
+                       if (!isASubtypeOf(superInterfaces[i], candidate)) {
                                return false;
                        }
                }
-               // lowerBound is a subtype of aCandidateType
-               if ((lowerBound != null) && (!isASubtypeOf(aCandidateType, lowerBound))) {
-                       return false;
-               }
                return true;
        }
 
@@ -213,18 +203,21 @@ public class TypeVariable {
        }
 
        // only used when resolving
-       public void setUpperBound(UnresolvedType aTypeX) {
-               this.upperBound = aTypeX;
-       }
-
-       // only used when resolving
-       public void setLowerBound(UnresolvedType aTypeX) {
-               this.lowerBound = aTypeX;
+       public void setUpperBound(UnresolvedType superclass) {
+               // if (isResolved) {
+               // throw new IllegalStateException("Why set this late?");
+               // }
+               this.firstbound = null;
+               this.superclass = superclass;
        }
 
        // only used when resolving
-       public void setAdditionalInterfaceBounds(UnresolvedType[] someTypeXs) {
-               this.additionalInterfaceBounds = someTypeXs;
+       public void setAdditionalInterfaceBounds(UnresolvedType[] superInterfaces) {
+               if (isResolved) {
+                       throw new IllegalStateException("Why set this late?");
+               }
+               this.firstbound = null;
+               this.superInterfaces = superInterfaces;
        }
 
        public String toDebugString() {
@@ -237,23 +230,19 @@ public class TypeVariable {
                if (!getFirstBound().getName().equals("java.lang.Object")) {
                        ret.append(" extends ");
                        ret.append(getFirstBound().getName());
-                       if (additionalInterfaceBounds != null) {
-                               for (int i = 0; i < additionalInterfaceBounds.length; i++) {
-                                       if (!getFirstBound().equals(additionalInterfaceBounds[i])) {
+                       if (superInterfaces != null) {
+                               for (int i = 0; i < superInterfaces.length; i++) {
+                                       if (!getFirstBound().equals(superInterfaces[i])) {
                                                ret.append(" & ");
-                                               ret.append(additionalInterfaceBounds[i].getName());
+                                               ret.append(superInterfaces[i].getName());
                                        }
                                }
                        }
                }
-               if (lowerBound != null) {
-                       ret.append(" super ");
-                       ret.append(lowerBound.getName());
-               }
                return ret.toString();
        }
 
-       // good enough approximation
+       @Override
        public String toString() {
                return "TypeVar " + getDisplayName();
        }
@@ -266,11 +255,11 @@ public class TypeVariable {
                StringBuffer sb = new StringBuffer();
                sb.append(name);
                sb.append(":");
-               sb.append(upperBound.getSignature());
-               if (additionalInterfaceBounds != null && additionalInterfaceBounds.length != 0) {
+               sb.append(superclass.getSignature());
+               if (superInterfaces.length != 0) {
                        sb.append(":");
-                       for (int i = 0; i < additionalInterfaceBounds.length; i++) {
-                               UnresolvedType iBound = additionalInterfaceBounds[i];
+                       for (int i = 0; i < superInterfaces.length; i++) {
+                               UnresolvedType iBound = superInterfaces[i];
                                sb.append(iBound.getSignature());
                        }
                }
@@ -284,11 +273,11 @@ public class TypeVariable {
                StringBuffer sb = new StringBuffer();
                sb.append(name);
                sb.append(":");
-               sb.append(((ResolvedType) upperBound).getSignatureForAttribute());
-               if (additionalInterfaceBounds != null && additionalInterfaceBounds.length != 0) {
+               sb.append(((ResolvedType) superclass).getSignatureForAttribute());
+               if (superInterfaces.length != 0) {
                        sb.append(":");
-                       for (int i = 0; i < additionalInterfaceBounds.length; i++) {
-                               ResolvedType iBound = (ResolvedType) additionalInterfaceBounds[i];
+                       for (int i = 0; i < superInterfaces.length; i++) {
+                               ResolvedType iBound = (ResolvedType) superInterfaces[i];
                                sb.append(iBound.getSignatureForAttribute());
                        }
                }
@@ -328,13 +317,13 @@ public class TypeVariable {
        public void write(DataOutputStream s) throws IOException {
                // name, upperbound, additionalInterfaceBounds, lowerbound
                s.writeUTF(name);
-               upperBound.write(s);
-               if (additionalInterfaceBounds == null || additionalInterfaceBounds.length == 0) {
+               superclass.write(s);
+               if (superInterfaces.length == 0) {
                        s.writeInt(0);
                } else {
-                       s.writeInt(additionalInterfaceBounds.length);
-                       for (int i = 0; i < additionalInterfaceBounds.length; i++) {
-                               UnresolvedType ibound = additionalInterfaceBounds[i];
+                       s.writeInt(superInterfaces.length);
+                       for (int i = 0; i < superInterfaces.length; i++) {
+                               UnresolvedType ibound = superInterfaces[i];
                                ibound.write(s);
                        }
                }
@@ -361,11 +350,19 @@ public class TypeVariable {
 
        public String getGenericSignature() {
                return "T" + name + ";";
-               // return "T"+getSignature();
        }
 
        public String getErasureSignature() {
                return getFirstBound().getErasureSignature();
        }
 
+       public UnresolvedType getSuperclass() {
+               return superclass;
+       }
+
+       public void setSuperclass(UnresolvedType superclass) {
+               this.firstbound = null;
+               this.superclass = superclass;
+       }
+
 }
index 06dac2a096a952c1121ede5449c24bab6a9173e0..dcd0861af42e83f150d20681990beafa2bba1aad 100644 (file)
@@ -1,24 +1,23 @@
 /* *******************************************************************
- * Copyright (c) 2005 Contributors.
+ * Copyright (c) 2005-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 
- *  
- * Contributors: 
- *   Adrian Colyer                     Initial implementation
+ * http://eclipse.org/legal/epl-v10.html
  * ******************************************************************/
 package org.aspectj.weaver;
 
-import java.io.DataOutputStream;
-import java.io.IOException;
 import java.util.Map;
 
 /**
- * Represents a type variable in a type or generic method declaration
+ * ReferenceType representing a type variable. The delegate for this reference type is the upperbound on the type variable (so
+ * Object if not otherwise specified).
+ * 
+ * @author Adrian Colyer
+ * @author Andy Clement
  */
-public class TypeVariableReferenceType extends BoundedReferenceType implements TypeVariableReference {
+public class TypeVariableReferenceType extends ReferenceType implements TypeVariableReference {
 
        private TypeVariable typeVariable;
        private boolean resolvedIfBounds = false;
@@ -29,60 +28,32 @@ public class TypeVariableReferenceType extends BoundedReferenceType implements T
        // at the right time). Wonder if we can fix it up late?
        boolean fixedUp = false;
 
-       public TypeVariableReferenceType(TypeVariable aTypeVariable, World aWorld) {
-               super(aTypeVariable.getGenericSignature(), aTypeVariable.getErasureSignature(), aWorld);
-               this.typeVariable = aTypeVariable;
-               this.isExtends = false;
-               this.isSuper = false;
+       public TypeVariableReferenceType(TypeVariable typeVariable, World world) {
+               super(typeVariable.getGenericSignature(), typeVariable.getErasureSignature(), world);
+               this.typeVariable = typeVariable;
+               // setDelegate(new BoundedReferenceTypeDelegate(backing));
+               // this.isExtends = false;
+               // this.isSuper = false;
        }
 
+       /**
+        * For a TypeVariableReferenceType the delegate is the delegate for the first bound.
+        */
+       @Override
        public ReferenceTypeDelegate getDelegate() {
-               if (delegate == null)
-                       setDelegate(new BoundedReferenceTypeDelegate((ReferenceType) typeVariable.getFirstBound()));
-               return delegate;
-       }
-
-       public UnresolvedType getUpperBound() {
-               if (typeVariable == null)
-                       return super.getUpperBound();
-               return typeVariable.getUpperBound();
-       }
-
-       public UnresolvedType getFirstBound() {
-               if (typeVariable == null)
-                       return super.getUpperBound();
-               return typeVariable.getFirstBound();
-       }
-
-       public UnresolvedType getLowerBound() {
-               return typeVariable.getLowerBound();
-       }
-
-       private void setAdditionalInterfaceBoundsFromTypeVar() {
-               if (typeVariable.getAdditionalInterfaceBounds() == null) {
-                       return;
-               } else {
-                       UnresolvedType[] ifBounds = typeVariable.getAdditionalInterfaceBounds();
-                       additionalInterfaceBounds = new ReferenceType[ifBounds.length];
-                       for (int i = 0; i < ifBounds.length; i++) {
-                               additionalInterfaceBounds[i] = (ReferenceType) ifBounds[i].resolve(getWorld());
-                       }
+               if (this.delegate == null) {
+                       setDelegate(new BoundedReferenceTypeDelegate((ReferenceType) typeVariable.getFirstBound().resolve(world)));
                }
+               return this.delegate;
        }
 
+       @Override
        public UnresolvedType parameterize(Map typeBindings) {
                UnresolvedType ut = (UnresolvedType) typeBindings.get(getName());
-               if (ut != null)
+               if (ut != null) {
                        return world.resolve(ut);
-               return this;
-       }
-
-       public ReferenceType[] getAdditionalBounds() {
-               if (!resolvedIfBounds) {
-                       setAdditionalInterfaceBoundsFromTypeVar();
-                       resolvedIfBounds = true;
                }
-               return super.getAdditionalBounds();
+               return this;
        }
 
        public TypeVariable getTypeVariable() {
@@ -90,33 +61,38 @@ public class TypeVariableReferenceType extends BoundedReferenceType implements T
                return typeVariable;
        }
 
+       @Override
        public boolean isTypeVariableReference() {
                return true;
        }
 
+       @Override
        public String toString() {
                return typeVariable.getName();
        }
 
+       @Override
        public boolean isGenericWildcard() {
                return false;
        }
 
-       // public ResolvedType resolve(World world) {
-       // return super.resolve(world);
-       // }
-
+       @Override
        public boolean isAnnotation() {
-               World world = ((ReferenceType) getUpperBound()).getWorld();
-               ResolvedType annotationType = ResolvedType.ANNOTATION.resolve(world);
-               if (getUpperBound() != null && ((ReferenceType) getUpperBound()).isAnnotation())
+               ReferenceType upper = (ReferenceType) typeVariable.getUpperBound();
+               if (upper.isAnnotation()) {
                        return true;
-               ReferenceType[] ifBounds = getAdditionalBounds();
+               }
+               World world = upper.getWorld();
+               typeVariable.resolve(world);
+               ResolvedType annotationType = ResolvedType.ANNOTATION.resolve(world);
+               UnresolvedType[] ifBounds = typeVariable.getSuperInterfaces();// AdditionalBounds();
                for (int i = 0; i < ifBounds.length; i++) {
-                       if (ifBounds[i].isAnnotation())
+                       if (((ReferenceType) ifBounds[i]).isAnnotation()) {
                                return true;
-                       if (ifBounds[i] == annotationType)
+                       }
+                       if (ifBounds[i].equals(annotationType)) {
                                return true; // annotation itself does not have the annotation flag set in Java!
+                       }
                }
                return false;
        }
@@ -125,6 +101,7 @@ public class TypeVariableReferenceType extends BoundedReferenceType implements T
         * return the signature for a *REFERENCE* to a type variable, which is simply: Tname; there is no bounds info included, that is
         * in the signature of the type variable itself
         */
+       @Override
        public String getSignature() {
                StringBuffer sb = new StringBuffer();
                sb.append("T");
@@ -133,19 +110,15 @@ public class TypeVariableReferenceType extends BoundedReferenceType implements T
                return sb.toString();
        }
 
-       public void write(DataOutputStream s) throws IOException {
-               super.write(s);
-               // TypeVariableDeclaringElement tvde = typeVariable.getDeclaringElement();
-               // if (tvde == null) {
-               // s.writeInt(TypeVariable.UNKNOWN);
-               // } else {
-               // s.writeInt(typeVariable.getDeclaringElementKind());
-               // if (typeVariable.getDeclaringElementKind() == TypeVariable.TYPE) {
-               // ((UnresolvedType)tvde).write(s);
-               // } else if (typeVariable.getDeclaringElementKind() == TypeVariable.METHOD){
-               // // it's a method
-               // ((ResolvedMember)tvde).write(s);
-               // }
-               // }
+       /**
+        * @return the name of the type variable
+        */
+       public String getTypeVariableName() {
+               return typeVariable.getName();
        }
+
+       public ReferenceType getUpperBound() {
+               return (ReferenceType) typeVariable.resolve(world).getUpperBound();
+       }
+
 }
index 64c778837a6531ca2079f2457f3c16ca83991f9d..33099b17b170c08f4b3205f93287435079d91fa2 100644 (file)
@@ -1,13 +1,10 @@
 /* *******************************************************************
- * Copyright (c) 2005 Contributors.
+ * Copyright (c) 2005-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 
- *  
- * Contributors: 
- *   Adrian Colyer                     Initial implementation
+ * http://eclipse.org/legal/epl-v10.html
  * ******************************************************************/
 package org.aspectj.weaver;
 
@@ -15,8 +12,8 @@ import java.io.DataOutputStream;
 import java.io.IOException;
 
 /**
- * @author colyer Represents a type variable encountered in the Eclipse Source world, which when resolved will turn into a
- *         TypeVariableReferenceType
+ * @author Adrian Colyer
+ * @author Andy Clement
  */
 public class UnresolvedTypeVariableReferenceType extends UnresolvedType implements TypeVariableReference {
 
@@ -39,6 +36,7 @@ public class UnresolvedTypeVariableReferenceType extends UnresolvedType implemen
                this.typeKind = TypeKind.TYPE_VARIABLE;
        }
 
+       @Override
        public ResolvedType resolve(World world) {
                TypeVariableDeclaringElement typeVariableScope = world.getTypeVariableLookupScope();
                TypeVariable resolvedTypeVariable = null;
@@ -64,6 +62,7 @@ public class UnresolvedTypeVariableReferenceType extends UnresolvedType implemen
                return tvrt;
        }
 
+       @Override
        public boolean isTypeVariableReference() {
                return true;
        }
@@ -72,11 +71,7 @@ public class UnresolvedTypeVariableReferenceType extends UnresolvedType implemen
                return typeVariable;
        }
 
-       // public String getName() {
-       // if (typeVariable == null) return "<type variable not set!>";
-       // return typeVariable.getDisplayName();
-       // }
-
+       @Override
        public String toString() {
                if (typeVariable == null) {
                        return "<type variable not set!>";
@@ -85,14 +80,17 @@ public class UnresolvedTypeVariableReferenceType extends UnresolvedType implemen
                }
        }
 
+       @Override
        public String toDebugString() {
                return typeVariable.getName();
        }
 
+       @Override
        public void write(DataOutputStream s) throws IOException {
                super.write(s);
        }
 
+       @Override
        public String getErasureSignature() {
                return typeVariable.getFirstBound().getSignature();
        }
index 23de0c3eafd085ed5d17963960d2a552df349dff..d3e609e7fea5abfd98d6917817bd2ea52e19c733 100644 (file)
@@ -23,9 +23,7 @@ public class WildcardedUnresolvedType extends UnresolvedType {
        // TODO does not cope with extra bounds '? extends A & B & C'
 
        public static final int UNBOUND = 0;
-
        public static final int EXTENDS = 1;
-
        public static final int SUPER = 2;
 
        public static final WildcardedUnresolvedType QUESTIONMARK = new WildcardedUnresolvedType("*", UnresolvedType.OBJECT, null);
@@ -41,10 +39,12 @@ public class WildcardedUnresolvedType extends UnresolvedType {
                this.typeKind = TypeKind.WILDCARD;
                this.upperBound = upperBound;
                this.lowerBound = lowerBound;
-               if (signature.charAt(0) == '-')
+               if (signature.charAt(0) == '-') {
                        boundKind = SUPER;
-               if (signature.charAt(0) == '+')
+               }
+               if (signature.charAt(0) == '+') {
                        boundKind = EXTENDS;
+               }
        }
 
        public UnresolvedType getUpperBound() {
index a16b38f72820078125547d41f452457712f146d5..2736e64e949233c3095620e7bd949cd97f49768f 100644 (file)
@@ -282,7 +282,7 @@ public abstract class World implements Dump.INode {
                        // fault in generic wildcard, can't be done earlier because of init
                        // issues
                        // TODO ought to be shared single instance representing this
-                       ResolvedType something = new BoundedReferenceType("*", "Ljava/lang/Object", this);
+                       ResolvedType something = getWildcard();
                        typeMap.put("?", something);
                        return something;
                }
@@ -316,6 +316,16 @@ public abstract class World implements Dump.INode {
                }
        }
 
+    // Only need one representation of '?' in a world - can be shared
+       private BoundedReferenceType wildcard;
+
+       private BoundedReferenceType getWildcard() {
+               if (wildcard == null) {
+                       wildcard = new BoundedReferenceType(this);
+               }
+               return wildcard;
+       }
+
        /**
         * Called when a type is resolved - enables its type hierarchy to be finished off before we proceed
         */
@@ -541,7 +551,7 @@ public abstract class World implements Dump.INode {
                        ret = new BoundedReferenceType(lowerBound, false, this);
                } else {
                        // must be ? on its own!
-                       ret = new BoundedReferenceType("*", "Ljava/lang/Object", this);
+                       ret = getWildcard();
                }
                return ret;
        }
@@ -726,6 +736,10 @@ public abstract class World implements Dump.INode {
                return crosscuttingMembersSet.getDeclareAnnotationOnMethods();
        }
 
+       // public List<DeclareTypeErrorOrWarning> getDeclareTypeEows() {
+       // return crosscuttingMembersSet.getDeclareTypeEows();
+       // }
+
        public List<DeclareSoft> getDeclareSoft() {
                return crosscuttingMembersSet.getDeclareSofts();
        }
index 9f334f2b02d739b8101cdd306db7b53a7f97e8c1..7e8d831ca50b0f7e7427f344cf848d58020900d5 100644 (file)
@@ -34,10 +34,12 @@ public class DeclareSoft extends Declare {
                this.pointcut = pointcut;
        }
 
+       @Override
        public Object accept(PatternNodeVisitor visitor, Object data) {
                return visitor.visit(this, data);
        }
 
+       @Override
        public Declare parameterizeWith(Map typeVariableBindingMap, World w) {
                DeclareSoft ret = new DeclareSoft(exception.parameterizeWith(typeVariableBindingMap, w), pointcut.parameterizeWith(
                                typeVariableBindingMap, w));
@@ -45,6 +47,7 @@ public class DeclareSoft extends Declare {
                return ret;
        }
 
+       @Override
        public String toString() {
                StringBuffer buf = new StringBuffer();
                buf.append("declare soft: ");
@@ -55,13 +58,16 @@ public class DeclareSoft extends Declare {
                return buf.toString();
        }
 
+       @Override
        public boolean equals(Object other) {
-               if (!(other instanceof DeclareSoft))
+               if (!(other instanceof DeclareSoft)) {
                        return false;
+               }
                DeclareSoft o = (DeclareSoft) other;
                return o.pointcut.equals(pointcut) && o.exception.equals(exception);
        }
 
+       @Override
        public int hashCode() {
                int result = 19;
                result = 37 * result + pointcut.hashCode();
@@ -69,6 +75,7 @@ public class DeclareSoft extends Declare {
                return result;
        }
 
+       @Override
        public void write(DataOutputStream s) throws IOException {
                s.writeByte(Declare.SOFT);
                exception.write(s);
@@ -90,6 +97,7 @@ public class DeclareSoft extends Declare {
                return exception;
        }
 
+       @Override
        public void resolve(IScope scope) {
                exception = exception.resolveBindings(scope, null, false, true);
                ResolvedType excType = exception.getExactType().resolve(scope.getWorld());
@@ -97,7 +105,8 @@ public class DeclareSoft extends Declare {
                        if (excType.isTypeVariableReference()) {
                                TypeVariableReferenceType typeVariableRT = (TypeVariableReferenceType) excType;
                                // a declare soft in a generic abstract aspect, we need to check the upper bound
-                               excType = typeVariableRT.getUpperBound().resolve(scope.getWorld());
+                               // WIBBLE
+                               excType = typeVariableRT.getTypeVariable().getFirstBound().resolve(scope.getWorld());
                        }
                        if (!scope.getWorld().getCoreType(UnresolvedType.THROWABLE).isAssignableFrom(excType)) {
                                scope.getWorld()
@@ -118,10 +127,12 @@ public class DeclareSoft extends Declare {
                pointcut = pointcut.resolve(scope);
        }
 
+       @Override
        public boolean isAdviceLike() {
                return false;
        }
 
+       @Override
        public String getNameSuffix() {
                return "soft";
        }
index d9369b9a93d661d1d00644aa8453150a7d7663d0..0cc5b9e45fbe56f169b4c087b6a38c45236b8a55 100644 (file)
@@ -138,7 +138,7 @@ public class ReferencePointcut extends Pointcut {
                        searchType = scope.getEnclosingType();
                }
                if (searchType.isTypeVariableReference()) {
-                       searchType = ((TypeVariableReference) searchType).getTypeVariable().getUpperBound().resolve(scope.getWorld());
+                       searchType = ((TypeVariableReference) searchType).getTypeVariable().getFirstBound().resolve(scope.getWorld());
                }
 
                arguments.resolveBindings(scope, bindings, true, true);
index f9c76ee7043f367f73436819599c370502d99278..42845b55d9eee2eec9af3b80788929406ea6b77b 100644 (file)
@@ -972,10 +972,7 @@ public class WildTypePattern extends TypePattern {
                        if (canCreateExactTypePattern) {
                                TypeVariable tv = tvrType.getTypeVariable();
                                if (upperBound != null) {
-                                       tv.setUpperBound(upperBound.getExactType());
-                               }
-                               if (lowerBound != null) {
-                                       tv.setLowerBound(lowerBound.getExactType());
+                                       tv.setSuperclass(upperBound.getExactType());
                                }
                                if (additionalInterfaceBounds != null) {
                                        UnresolvedType[] ifBounds = new UnresolvedType[additionalInterfaceBounds.length];