diff options
author | Andy Clement <aclement@vmware.com> | 2012-03-23 16:44:03 -0700 |
---|---|---|
committer | Andy Clement <andrew.clement@gmail.com> | 2012-03-23 16:57:10 -0700 |
commit | 549d227a8ded88d708415162b36cb273ec496b77 (patch) | |
tree | 09b65c8ba108625c013df3af587ea1de367b6abc /org.aspectj.matcher/src | |
parent | 5408b2446e12432486800cf5a35795ab8d942de3 (diff) | |
download | aspectj-549d227a8ded88d708415162b36cb273ec496b77.tar.gz aspectj-549d227a8ded88d708415162b36cb273ec496b77.zip |
374745
Diffstat (limited to 'org.aspectj.matcher/src')
7 files changed, 127 insertions, 96 deletions
diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/ReferenceType.java b/org.aspectj.matcher/src/org/aspectj/weaver/ReferenceType.java index 54ac3f97b..6c9d6e98b 100644 --- a/org.aspectj.matcher/src/org/aspectj/weaver/ReferenceType.java +++ b/org.aspectj.matcher/src/org/aspectj/weaver/ReferenceType.java @@ -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 diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/ResolvedType.java b/org.aspectj.matcher/src/org/aspectj/weaver/ResolvedType.java index 7b904778f..6cf414466 100644 --- a/org.aspectj.matcher/src/org/aspectj/weaver/ResolvedType.java +++ b/org.aspectj.matcher/src/org/aspectj/weaver/ResolvedType.java @@ -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; } + } diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/TypeFactory.java b/org.aspectj.matcher/src/org/aspectj/weaver/TypeFactory.java index f22d14a0f..204418346 100644 --- a/org.aspectj.matcher/src/org/aspectj/weaver/TypeFactory.java +++ b/org.aspectj.matcher/src/org/aspectj/weaver/TypeFactory.java @@ -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); } diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/TypeVariableReferenceType.java b/org.aspectj.matcher/src/org/aspectj/weaver/TypeVariableReferenceType.java index 76c5a2458..1e867ab5e 100644 --- a/org.aspectj.matcher/src/org/aspectj/weaver/TypeVariableReferenceType.java +++ b/org.aspectj.matcher/src/org/aspectj/weaver/TypeVariableReferenceType.java @@ -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; } diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/UnresolvedType.java b/org.aspectj.matcher/src/org/aspectj/weaver/UnresolvedType.java index 19fb62908..6101f6536 100644 --- a/org.aspectj.matcher/src/org/aspectj/weaver/UnresolvedType.java +++ b/org.aspectj.matcher/src/org/aspectj/weaver/UnresolvedType.java @@ -176,7 +176,7 @@ public class UnresolvedType implements Traceable, TypeVariableDeclaringElement { * signature string. */ @Override - public final int hashCode() { + public int hashCode() { return signature.hashCode(); } diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/UnresolvedTypeVariableReferenceType.java b/org.aspectj.matcher/src/org/aspectj/weaver/UnresolvedTypeVariableReferenceType.java index 5510c29d5..fbeb47164 100644 --- a/org.aspectj.matcher/src/org/aspectj/weaver/UnresolvedTypeVariableReferenceType.java +++ b/org.aspectj.matcher/src/org/aspectj/weaver/UnresolvedTypeVariableReferenceType.java @@ -54,7 +54,6 @@ public class UnresolvedTypeVariableReferenceType extends UnresolvedType implemen foundOK = true; } tvrt = new TypeVariableReferenceType(resolvedTypeVariable, world); - tvrt.fixedUp = foundOK; } return tvrt; diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/World.java b/org.aspectj.matcher/src/org/aspectj/weaver/World.java index ba0fa3a1f..7e6116e0e 100644 --- a/org.aspectj.matcher/src/org/aspectj/weaver/World.java +++ b/org.aspectj.matcher/src/org/aspectj/weaver/World.java @@ -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); |