From: Andy Clement Date: Fri, 23 Mar 2012 23:44:03 +0000 (-0700) Subject: 374745 X-Git-Tag: V1_7_0RC1~20 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=549d227a8ded88d708415162b36cb273ec496b77;p=aspectj.git 374745 --- diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseFactory.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseFactory.java index c9c078c81..ae2d2d04e 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseFactory.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseFactory.java @@ -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; } 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 derivativeTypes = new HashSet(); + private final List> derivativeTypes = new ArrayList>(); /** * 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(dependent)); + } + + public void checkDuplicates(ReferenceType newRt) { + List> forRemoval = new ArrayList>(); + for (WeakReference 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 @@ -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 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> forRemoval = new ArrayList>(); + for (WeakReference 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 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> forRemoval = new ArrayList>(); + for (WeakReference 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);