aboutsummaryrefslogtreecommitdiffstats
path: root/org.aspectj.matcher/src
diff options
context:
space:
mode:
authorAndy Clement <aclement@vmware.com>2012-03-23 16:44:03 -0700
committerAndy Clement <andrew.clement@gmail.com>2012-03-23 16:57:10 -0700
commit549d227a8ded88d708415162b36cb273ec496b77 (patch)
tree09b65c8ba108625c013df3af587ea1de367b6abc /org.aspectj.matcher/src
parent5408b2446e12432486800cf5a35795ab8d942de3 (diff)
downloadaspectj-549d227a8ded88d708415162b36cb273ec496b77.tar.gz
aspectj-549d227a8ded88d708415162b36cb273ec496b77.zip
374745
Diffstat (limited to 'org.aspectj.matcher/src')
-rw-r--r--org.aspectj.matcher/src/org/aspectj/weaver/ReferenceType.java175
-rw-r--r--org.aspectj.matcher/src/org/aspectj/weaver/ResolvedType.java3
-rw-r--r--org.aspectj.matcher/src/org/aspectj/weaver/TypeFactory.java11
-rw-r--r--org.aspectj.matcher/src/org/aspectj/weaver/TypeVariableReferenceType.java28
-rw-r--r--org.aspectj.matcher/src/org/aspectj/weaver/UnresolvedType.java2
-rw-r--r--org.aspectj.matcher/src/org/aspectj/weaver/UnresolvedTypeVariableReferenceType.java1
-rw-r--r--org.aspectj.matcher/src/org/aspectj/weaver/World.java3
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);