]> source.dussan.org Git - aspectj.git/commitdiff
374745
authorAndy Clement <aclement@vmware.com>
Fri, 23 Mar 2012 23:44:03 +0000 (16:44 -0700)
committerAndy Clement <andrew.clement@gmail.com>
Fri, 23 Mar 2012 23:57:10 +0000 (16:57 -0700)
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseFactory.java
org.aspectj.matcher/src/org/aspectj/weaver/ReferenceType.java
org.aspectj.matcher/src/org/aspectj/weaver/ResolvedType.java
org.aspectj.matcher/src/org/aspectj/weaver/TypeFactory.java
org.aspectj.matcher/src/org/aspectj/weaver/TypeVariableReferenceType.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/World.java

index c9c078c81e16de6abbf3d5bf5bdb038a4e307a5a..ae2d2d04eeec6721e39dce6e4e0547332296ad86 100644 (file)
@@ -1073,55 +1073,55 @@ public class EclipseFactory {
                TypeDeclaration decl = binding.scope.referenceContext;
 
                // Deal with the raw/basic type to give us an entry in the world type map
-               UnresolvedType simpleTx = null;
+               UnresolvedType unresolvedRawType = null;
                if (binding.isGenericType()) {
-                       simpleTx = UnresolvedType.forRawTypeName(getName(binding));
+                       unresolvedRawType = UnresolvedType.forRawTypeName(getName(binding));
                } else if (binding.isLocalType()) {
                        LocalTypeBinding ltb = (LocalTypeBinding) binding;
                        if (ltb.constantPoolName() != null && ltb.constantPoolName().length > 0) {
-                               simpleTx = UnresolvedType.forSignature(new String(binding.signature()));
+                               unresolvedRawType = UnresolvedType.forSignature(new String(binding.signature()));
                        } else {
-                               simpleTx = UnresolvedType.forName(getName(binding));
+                               unresolvedRawType = UnresolvedType.forName(getName(binding));
                        }
                } else {
-                       simpleTx = UnresolvedType.forName(getName(binding));
+                       unresolvedRawType = UnresolvedType.forName(getName(binding));
                }
 
-               ReferenceType name = getWorld().lookupOrCreateName(simpleTx);
+               ReferenceType resolvedRawType = getWorld().lookupOrCreateName(unresolvedRawType);
 
                // A type can change from simple > generic > simple across a set of compiles. We need
                // to ensure the entry in the typemap is promoted and demoted correctly. The call
                // to setGenericType() below promotes a simple to a raw. This call demotes it back
                // to simple
                // pr125405
-               if (!binding.isRawType() && !binding.isGenericType() && name.getTypekind() == TypeKind.RAW) {
-                       name.demoteToSimpleType();
+               if (!binding.isRawType() && !binding.isGenericType() && resolvedRawType.getTypekind() == TypeKind.RAW) {
+                       resolvedRawType.demoteToSimpleType();
                }
 
-               EclipseSourceType t = new EclipseSourceType(name, this, binding, decl, unit);
+               EclipseSourceType t = new EclipseSourceType(resolvedRawType, this, binding, decl, unit);
 
                // For generics, go a bit further - build a typex for the generic type
                // give it the same delegate and link it to the raw type
                if (binding.isGenericType()) {
-                       UnresolvedType complexTx = fromBinding(binding); // fully aware of any generics info
-                       ResolvedType cName = world.resolve(complexTx, true);
+                       UnresolvedType unresolvedGenericType = fromBinding(binding); // fully aware of any generics info
+                       ResolvedType resolvedGenericType = world.resolve(unresolvedGenericType, true);
                        ReferenceType complexName = null;
-                       if (!cName.isMissing()) {
-                               complexName = (ReferenceType) cName;
+                       if (!resolvedGenericType.isMissing()) {
+                               complexName = (ReferenceType) resolvedGenericType;
                                complexName = (ReferenceType) complexName.getGenericType();
                                if (complexName == null) {
-                                       complexName = new ReferenceType(complexTx, world);
+                                       complexName = new ReferenceType(unresolvedGenericType, world);
                                }
                        } else {
-                               complexName = new ReferenceType(complexTx, world);
+                               complexName = new ReferenceType(unresolvedGenericType, world);
                        }
-                       name.setGenericType(complexName);
+                       resolvedRawType.setGenericType(complexName);
                        complexName.setDelegate(t);
                }
 
-               name.setDelegate(t);
+               resolvedRawType.setDelegate(t);
                if (decl instanceof AspectDeclaration) {
-                       ((AspectDeclaration) decl).typeX = name;
+                       ((AspectDeclaration) decl).typeX = resolvedRawType;
                        ((AspectDeclaration) decl).concreteName = t;
                }
 
index 54ac3f97b0ea6667f1a091a7e80ec9f7ffa2bd1e..6c9d6e98b9abfbcb015774eb5a2ba8fd1dfd0e8c 100644 (file)
@@ -15,11 +15,11 @@ package org.aspectj.weaver;
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.HashSet;
+import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
 import org.aspectj.bridge.ISourceLocation;
+import org.aspectj.weaver.World.TypeMap;
 import org.aspectj.weaver.patterns.Declare;
 import org.aspectj.weaver.patterns.PerClause;
 
@@ -37,7 +37,7 @@ public class ReferenceType extends ResolvedType {
         * For generic types, this list holds references to all the derived raw and parameterized versions. We need this so that if the
         * generic delegate is swapped during incremental compilation, the delegate of the derivatives is swapped also.
         */
-       private final Set<ReferenceType> derivativeTypes = new HashSet<ReferenceType>();
+       private final List<WeakReference<ReferenceType>> derivativeTypes = new ArrayList<WeakReference<ReferenceType>>();
 
        /**
         * For parameterized types (or the raw type) - this field points to the actual reference type from which they are derived.
@@ -68,7 +68,6 @@ public class ReferenceType extends ResolvedType {
        private ResolvedType newSuperclass;
        private ResolvedType[] newInterfaces;
 
-       // ??? should set delegate before any use
        public ReferenceType(String signature, World world) {
                super(signature, world);
        }
@@ -96,24 +95,42 @@ public class ReferenceType extends ResolvedType {
                genericReferenceType.addDependentType(this);
        }
 
-       /**
-        * Constructor used when creating a raw type.
-        */
-       // public ReferenceType(
-       // ResolvedType theGenericType,
-       // World aWorld) {
-       // super(theGenericType.getErasureSignature(),
-       // theGenericType.getErasureSignature(),
-       // aWorld);
-       // ReferenceType genericReferenceType = (ReferenceType) theGenericType;
-       // this.typeParameters = null;
-       // this.genericType = genericReferenceType;
-       // this.typeKind = TypeKind.RAW;
-       // this.delegate = genericReferenceType.getDelegate();
-       // genericReferenceType.addDependentType(this);
-       // }
        synchronized void addDependentType(ReferenceType dependent) {
-               this.derivativeTypes.add(dependent);
+//             checkDuplicates(dependent);
+               this.derivativeTypes.add(new WeakReference<ReferenceType>(dependent));
+       }
+                       
+       public void checkDuplicates(ReferenceType newRt) {
+         List<WeakReference<ReferenceType>> forRemoval = new ArrayList<WeakReference<ReferenceType>>();
+         for (WeakReference<ReferenceType> derivativeTypeReference: derivativeTypes) {
+                 ReferenceType derivativeType = derivativeTypeReference.get();
+                 if (derivativeType==null) {
+                         forRemoval.add(derivativeTypeReference);
+                 } else {
+                         if (derivativeType.getTypekind()!=newRt.getTypekind()) {
+                                 continue; // cannot be this one
+                         }
+                         if (equal2(newRt.getTypeParameters(),derivativeType.getTypeParameters())) {
+                                 if (TypeMap.useExpendableMap) {
+                                         throw new IllegalStateException();
+                                 }
+                         }
+                 }
+         }
+         derivativeTypes.removeAll(forRemoval);
+       }
+       
+       private boolean equal2(UnresolvedType[] typeParameters, UnresolvedType[] resolvedParameters) {
+               if (typeParameters.length!=resolvedParameters.length)  {
+                       return false;
+               }
+               int len = typeParameters.length;
+               for (int p=0;p<len;p++) {
+                       if (!typeParameters[p].equals(resolvedParameters[p])) {
+                               return false;
+                       }
+               }
+               return true;
        }
 
        @Override
@@ -160,8 +177,7 @@ public class ReferenceType extends ResolvedType {
        @Override
        public void addAnnotation(AnnotationAJ annotationX) {
                if (annotations == null) {
-                       annotations = new AnnotationAJ[1];
-                       annotations[0] = annotationX;
+                       annotations = new AnnotationAJ[]{annotationX};
                } else {
                        AnnotationAJ[] newAnnotations = new AnnotationAJ[annotations.length + 1];
                        System.arraycopy(annotations, 0, newAnnotations, 1, annotations.length);
@@ -686,31 +702,6 @@ public class ReferenceType extends ResolvedType {
                return delegateInterfaces;
        }
 
-       // private String toString(ResolvedType[] delegateInterfaces) {
-       // StringBuffer sb = new StringBuffer();
-       // if (delegateInterfaces != null) {
-       // for (ResolvedType rt : delegateInterfaces) {
-       // sb.append(rt).append(" ");
-       // }
-       // }
-       // return sb.toString();
-       // }
-
-       /**
-        * Locates the named type variable in the list of those on this generic type and returns the type parameter from the second list
-        * supplied. Returns null if it can't be found
-        */
-       // private UnresolvedType findTypeParameterInList(String name,
-       // TypeVariable[] tvarsOnThisGenericType, UnresolvedType[]
-       // paramTypes) {
-       // int position = -1;
-       // for (int i = 0; i < tvarsOnThisGenericType.length; i++) {
-       // TypeVariable tv = tvarsOnThisGenericType[i];
-       // if (tv.getName().equals(name)) position = i;
-       // }
-       // if (position == -1 ) return null;
-       // return paramTypes[position];
-       // }
        /**
         * It is possible this type has multiple type variables but the interface we are about to parameterize only uses a subset - this
         * method determines the subset to use by looking at the type variable names used. For example: <code>
@@ -821,13 +812,13 @@ public class ReferenceType extends ResolvedType {
 
        @Override
        public TypeVariable[] getTypeVariables() {
-               if (this.typeVariables == null) {
-                       this.typeVariables = getDelegate().getTypeVariables();
+               if (typeVariables == null) {
+                       typeVariables = getDelegate().getTypeVariables();
                        for (int i = 0; i < this.typeVariables.length; i++) {
-                               this.typeVariables[i].resolve(world);
+                               typeVariables[i].resolve(world);
                        }
                }
-               return this.typeVariables;
+               return typeVariables;
        }
 
        @Override
@@ -868,27 +859,6 @@ public class ReferenceType extends ResolvedType {
                return getDelegate().getTypeMungers();
        }
 
-       // GENERICITDFIX
-       // // Map parameterizationMap = getAjMemberParameterizationMap();
-       //
-       // // if (parameterizedTypeMungers != null) return parameterizedTypeMungers;
-       // Collection ret = null;
-       // if (ajMembersNeedParameterization()) {
-       // Collection genericDeclares = delegate.getTypeMungers();
-       // parameterizedTypeMungers = new ArrayList();
-       // Map parameterizationMap = getAjMemberParameterizationMap();
-       // for (Iterator iter = genericDeclares.iterator(); iter.hasNext();) {
-       // ConcreteTypeMunger munger = (ConcreteTypeMunger)iter.next();
-       // parameterizedTypeMungers.add(munger.parameterizeWith(parameterizationMap,
-       // world));
-       // }
-       // ret = parameterizedTypeMungers;
-       // } else {
-       // ret = delegate.getTypeMungers();
-       // }
-       // return ret;
-       // }
-
        @Override
        public Collection<ResolvedMember> getPrivilegedAccesses() {
                return getDelegate().getPrivilegedAccesses();
@@ -943,9 +913,16 @@ public class ReferenceType extends ResolvedType {
                        ((AbstractReferenceTypeDelegate) delegate).setSourceContext(this.delegate.getSourceContext());
                }
                this.delegate = delegate;
-               for (ReferenceType dependent : derivativeTypes) {
-                       dependent.setDelegate(delegate);
+               List<WeakReference<ReferenceType>> forRemoval = new ArrayList<WeakReference<ReferenceType>>();
+               for (WeakReference<ReferenceType> derivativeRef : derivativeTypes) {
+                       ReferenceType derivative = derivativeRef.get();
+                       if (derivative!=null) {
+                               derivative.setDelegate(delegate);
+                       } else {
+                               forRemoval.add(derivativeRef);
+                       }
                }
+               derivativeTypes.removeAll(forRemoval);
 
                // If we are raw, we have a generic type - we should ensure it uses the
                // same delegate
@@ -1098,11 +1075,55 @@ public class ReferenceType extends ResolvedType {
                                newInterfaces = newNewInterfaces;
                        }
                        if (this.isGenericType()) {
-                               for (ReferenceType derivativeType : derivativeTypes) {
-                                       derivativeType.parameterizedInterfaces.clear();
+                               for (WeakReference<ReferenceType> derivativeTypeRef : derivativeTypes) {
+                                       ReferenceType derivativeType = derivativeTypeRef.get();
+                                       if (derivativeType!=null) {
+                                               derivativeType.parameterizedInterfaces.clear();
+                                       }
                                }
                        }
                        parameterizedInterfaces.clear();
                }
        }
+
+       private boolean equal(UnresolvedType[] typeParameters, ResolvedType[] resolvedParameters) {
+               if (typeParameters.length!=resolvedParameters.length)  {
+                       return false;
+               }
+               int len = typeParameters.length;
+               for (int p=0;p<len;p++) {
+                       if (!typeParameters[p].equals(resolvedParameters[p])) {
+                               return false;
+                       }
+               }
+               return true;
+       }
+       
+       /**
+        * Look for a derivative type with the specified type parameters.  This can avoid creating an
+        * unnecessary new (duplicate) with the same information in it.  This method also cleans up
+        * any reference entries that have been null'd by a GC.
+        * 
+        * @param typeParameters the type parameters to use when searching for the derivative type.
+        * @return an existing derivative type or null if there isn't one
+        */
+       public ReferenceType findDerivativeType(ResolvedType[] typeParameters) {
+               List<WeakReference<ReferenceType>> forRemoval = new ArrayList<WeakReference<ReferenceType>>();
+               for (WeakReference<ReferenceType> derivativeTypeRef: derivativeTypes) {
+                       ReferenceType derivativeType = derivativeTypeRef.get();
+                       if (derivativeType==null) {
+                               forRemoval.add(derivativeTypeRef);
+                       } else {
+                               if (derivativeType.isRawType()) {
+                                       continue;
+                               }
+                               if (equal(derivativeType.typeParameters,typeParameters)) {
+                                       return derivativeType; // this escape route wont remove the empty refs
+                               }
+                       }
+               }
+               derivativeTypes.removeAll(forRemoval);
+               return null;
+       }
+
 }
\ No newline at end of file
index 7b904778f1f891b857c8e03e70a8142cb18d714b..6cf414466eda41cd8bddda4240d5a2557b5342cb 100644 (file)
@@ -172,7 +172,7 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
        // ---- things from object
 
        @Override
-       public final boolean equals(Object other) {
+       public boolean equals(Object other) {
                if (other instanceof ResolvedType) {
                        return this == other;
                } else {
@@ -2793,4 +2793,5 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
                }
                return (bits & IsGroovyObject) != 0;
        }
+
 }
index f22d14a0f2608cc16fd479f71fdae5b0361fbd17..204418346eb5a88880d24c0cd14ed552b6547fa9 100644 (file)
@@ -40,7 +40,16 @@ public class TypeFactory {
                        } // else if someTypeParameters is null, then the base type is allowed to be non-generic, it's an inner
                }
                ResolvedType[] resolvedParameters = inAWorld.resolve(someTypeParameters);
-               ReferenceType pType = new ReferenceType(baseType, resolvedParameters, inAWorld);
+               
+               ReferenceType existingType = ((ReferenceType)baseType).findDerivativeType(resolvedParameters);
+               
+               ReferenceType pType = null;
+               
+               if (existingType!=null) {
+                       pType = existingType;
+               } else {
+                       pType =new ReferenceType(baseType, resolvedParameters, inAWorld);
+               }
                // pType.setSourceContext(aBaseType.getSourceContext());
                return (ReferenceType) pType.resolve(inAWorld);
        }
index 76c5a2458b9aae064baf944d960d41daf1d86261..1e867ab5e09f5f45f05c19da378a9888084b0ac6 100644 (file)
@@ -1,5 +1,5 @@
 /* *******************************************************************
- * Copyright (c) 2005-2010 Contributors.
+ * Copyright (c) 2005-2012 Contributors.
  * All rights reserved. 
  * This program and the accompanying materials are made available 
  * under the terms of the Eclipse Public License v1.0 
@@ -11,7 +11,7 @@ package org.aspectj.weaver;
 import java.util.Map;
 
 /**
- * ReferenceType representing a type variable. The delegate for this reference type is the upperbound on the type variable (so
+ * ReferenceType pointing to 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
@@ -21,18 +21,22 @@ public class TypeVariableReferenceType extends ReferenceType implements TypeVari
 
        private TypeVariable typeVariable;
 
-       // If 'fixedUp' then the type variable in here is a reference to the real one that may
-       // exist either on a member or a type. Not fixedUp means that we unpacked a generic
-       // signature and weren't able to fix it up during resolution (didn't quite know enough
-       // at the right time). Wonder if we can fix it up late?
-       boolean fixedUp = 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;
+       }
+       
+       @Override
+       public boolean equals(Object other) {
+               if (other instanceof TypeVariableReferenceType) {
+                       return typeVariable==((TypeVariableReferenceType)other).typeVariable;
+               }
+               return false;
+       }
+       
+       @Override
+       public int hashCode() {
+               return typeVariable.hashCode();
        }
 
        /**
@@ -68,8 +72,6 @@ public class TypeVariableReferenceType extends ReferenceType implements TypeVari
        }
 
        public TypeVariable getTypeVariable() {
-               // if (!fixedUp)
-               // throw new BCException("ARGH"); // fix it up now?
                return typeVariable;
        }
 
index 19fb6290800cdb683ace30b3985886fe4a802ae0..6101f6536ddcac621daa6a1281cd78b4ffb56188 100644 (file)
@@ -176,7 +176,7 @@ public class UnresolvedType implements Traceable, TypeVariableDeclaringElement {
         * signature string.
         */
        @Override
-       public final int hashCode() {
+       public int hashCode() {
                return signature.hashCode();
        }
 
index 5510c29d5220b97479097ec26bfc93de728a4206..fbeb471641d4bb698e2ac1656368e333f161688c 100644 (file)
@@ -54,7 +54,6 @@ public class UnresolvedTypeVariableReferenceType extends UnresolvedType implemen
                                foundOK = true;
                        }
                        tvrt = new TypeVariableReferenceType(resolvedTypeVariable, world);
-                       tvrt.fixedUp = foundOK;
                }
 
                return tvrt;
index ba0fa3a1fd8d170808b1d290ff21aaf40b537beb..7e6116e0e229057611bd4d329d3129f2bbf8ee1b 100644 (file)
@@ -548,7 +548,6 @@ public abstract class World implements Dump.INode {
 
                if (genericType != null) {
                        genericType.world = this;
-                       ((ReferenceType) genericType).addDependentType((ReferenceType) rawType);
                        return genericType;
                } else {
                        // Fault in the generic that underpins the raw type ;)
@@ -1302,7 +1301,7 @@ public abstract class World implements Dump.INode {
 
                /**
                 * Lookup a type by its signature, always look in the real map before the expendable map
-                */
+                */ 
                public ResolvedType get(String key) {
                        checkq();
                        ResolvedType ret = tMap.get(key);