@@ -22,12 +22,10 @@ import org.aspectj.bridge.ISourceLocation; | |||
import org.aspectj.weaver.AjAttribute.EffectiveSignatureAttribute; | |||
/** | |||
* @author colyer Instances of this class are created by | |||
* ResolvedMember.getSignatures() when collating all of the signatures | |||
* for a member. We need to create entries in the set for the "gaps" in | |||
* the hierarchy. For example: | |||
* @author colyer Instances of this class are created by ResolvedMember.getSignatures() when collating all of the signatures for a | |||
* member. We need to create entries in the set for the "gaps" in the hierarchy. For example: | |||
* | |||
* class A { void foo(); } | |||
* class A { void foo(); } | |||
* | |||
* class B extends A {} | |||
* | |||
@@ -35,8 +33,7 @@ import org.aspectj.weaver.AjAttribute.EffectiveSignatureAttribute; | |||
* | |||
* has signatures: | |||
* | |||
* B.foo() AND A.foo() B.foo() will be created as a | |||
* ResolvedMemberWithSubstituteDeclaringType | |||
* B.foo() AND A.foo() B.foo() will be created as a ResolvedMemberWithSubstituteDeclaringType | |||
* | |||
* Oh for a JDK 1.4 dynamic proxy.... we have to run on 1.3 :( | |||
*/ | |||
@@ -206,18 +203,14 @@ public class JoinPointSignature implements ResolvedMember { | |||
return realMember.getGenericParameterTypes(); | |||
} | |||
public ResolvedMemberImpl parameterizedWith( | |||
UnresolvedType[] typeParameters, ResolvedType newDeclaringType, | |||
public ResolvedMemberImpl parameterizedWith(UnresolvedType[] typeParameters, ResolvedType newDeclaringType, | |||
boolean isParameterized) { | |||
return realMember.parameterizedWith(typeParameters, newDeclaringType, | |||
isParameterized); | |||
return realMember.parameterizedWith(typeParameters, newDeclaringType, isParameterized); | |||
} | |||
public ResolvedMemberImpl parameterizedWith( | |||
UnresolvedType[] typeParameters, ResolvedType newDeclaringType, | |||
public ResolvedMemberImpl parameterizedWith(UnresolvedType[] typeParameters, ResolvedType newDeclaringType, | |||
boolean isParameterized, List aliases) { | |||
return realMember.parameterizedWith(typeParameters, newDeclaringType, | |||
isParameterized, aliases); | |||
return realMember.parameterizedWith(typeParameters, newDeclaringType, isParameterized, aliases); | |||
} | |||
public void setTypeVariables(TypeVariable[] types) { | |||
@@ -232,8 +225,8 @@ public class JoinPointSignature implements ResolvedMember { | |||
return realMember.getTypeVariableNamed(name); | |||
} | |||
public boolean matches(ResolvedMember aCandidateMatch) { | |||
return realMember.matches(aCandidateMatch); | |||
public boolean matches(ResolvedMember aCandidateMatch, boolean ignoreGenerics) { | |||
return realMember.matches(aCandidateMatch, ignoreGenerics); | |||
} | |||
public ResolvedMember resolve(World world) { | |||
@@ -309,8 +302,7 @@ public class JoinPointSignature implements ResolvedMember { | |||
} | |||
public Collection getDeclaringTypes(World world) { | |||
throw new UnsupportedOperationException( | |||
"Adrian doesn't think you should be calling this..."); | |||
throw new UnsupportedOperationException("Adrian doesn't think you should be calling this..."); | |||
} | |||
public Iterator getJoinPointSignatures(World world) { | |||
@@ -375,8 +367,7 @@ public class JoinPointSignature implements ResolvedMember { | |||
} | |||
public int hashCode() { | |||
return 17 + (37 * realMember.hashCode()) | |||
+ (37 * substituteDeclaringType.hashCode()); | |||
return 17 + (37 * realMember.hashCode()) + (37 * substituteDeclaringType.hashCode()); | |||
} | |||
public boolean hasBackingGenericMember() { |
@@ -21,27 +21,27 @@ import java.util.NoSuchElementException; | |||
import java.util.Set; | |||
/** | |||
* Iterates over the signatures of a join point, calculating new signatures | |||
* lazily to minimize processing and to avoid unneccessary "can't find type" | |||
* errors. Iterator can be cached and reused by calling the "reset" method | |||
* between iterations. | |||
* Iterates over the signatures of a join point, calculating new signatures lazily to minimize processing and to avoid unneccessary | |||
* "can't find type" errors. Iterator can be cached and reused by calling the "reset" method between iterations. | |||
*/ | |||
public class JoinPointSignatureIterator implements Iterator { | |||
private Member signaturesOfMember; | |||
private ResolvedMember firstDefiningMember; | |||
ResolvedType firstDefiningType; | |||
private World world; | |||
private List /*JoinPointSignature*/ discoveredSignatures = new ArrayList(); | |||
private List /* JoinPointSignature */discoveredSignatures = new ArrayList(); | |||
private List additionalSignatures = Collections.EMPTY_LIST; | |||
private Iterator discoveredSignaturesIterator = null; | |||
private Iterator superTypeIterator = null; | |||
private boolean isProxy = false; | |||
private Set visitedSuperTypes = new HashSet(); | |||
private List /*SearchPair*/ yetToBeProcessedSuperMembers = null;//new ArrayList(); | |||
private List /* SearchPair */yetToBeProcessedSuperMembers = null;// new ArrayList(); | |||
private boolean iteratingOverDiscoveredSignatures = true; | |||
private boolean couldBeFurtherAsYetUndiscoveredSignatures = true; | |||
private final static UnresolvedType jlrProxy = UnresolvedType.forSignature("Ljava/lang/reflect/Proxy;"); | |||
/** | |||
* | |||
*/ | |||
@@ -49,7 +49,8 @@ public class JoinPointSignatureIterator implements Iterator { | |||
this.signaturesOfMember = joinPointSignature; | |||
this.world = inAWorld; | |||
addSignaturesUpToFirstDefiningMember(); | |||
if (!shouldWalkUpHierarchy()) couldBeFurtherAsYetUndiscoveredSignatures = false; | |||
if (!shouldWalkUpHierarchy()) | |||
couldBeFurtherAsYetUndiscoveredSignatures = false; | |||
} | |||
public void reset() { | |||
@@ -57,22 +58,28 @@ public class JoinPointSignatureIterator implements Iterator { | |||
additionalSignatures.clear(); | |||
iteratingOverDiscoveredSignatures = true; | |||
} | |||
/* (non-Javadoc) | |||
/* | |||
* (non-Javadoc) | |||
* | |||
* @see java.util.Iterator#hasNext() | |||
*/ | |||
public boolean hasNext() { | |||
if (iteratingOverDiscoveredSignatures && discoveredSignaturesIterator.hasNext()) { | |||
return true; | |||
} else if (couldBeFurtherAsYetUndiscoveredSignatures) { | |||
if (additionalSignatures.size() > 0) return true; | |||
else return findSignaturesFromSupertypes(); | |||
if (additionalSignatures.size() > 0) | |||
return true; | |||
else | |||
return findSignaturesFromSupertypes(); | |||
} else { | |||
return false; | |||
} | |||
} | |||
/* (non-Javadoc) | |||
/* | |||
* (non-Javadoc) | |||
* | |||
* @see java.util.Iterator#next() | |||
*/ | |||
public Object next() { | |||
@@ -86,166 +93,197 @@ public class JoinPointSignatureIterator implements Iterator { | |||
throw new NoSuchElementException(); | |||
} | |||
/* (non-Javadoc) | |||
/* | |||
* (non-Javadoc) | |||
* | |||
* @see java.util.Iterator#remove() | |||
*/ | |||
public void remove() { | |||
throw new UnsupportedOperationException("can't remove from JoinPointSignatureIterator"); | |||
} | |||
private void addSignaturesUpToFirstDefiningMember() { | |||
// Walk up hierarchy creating one member for each type up to and including the | |||
// first defining type | |||
ResolvedType originalDeclaringType = signaturesOfMember.getDeclaringType().resolve(world); | |||
if (world.isJoinpointArrayConstructionEnabled() && originalDeclaringType.isArray()) { // Aha, this must be the array constructor call join point - a 'special'... | |||
Member m = signaturesOfMember; | |||
ResolvedMember rm = new ResolvedMemberImpl(m.getKind(),m.getDeclaringType(),m.getModifiers(),m.getReturnType(),m.getName(),m.getParameterTypes()); | |||
discoveredSignatures.add(new JoinPointSignature(rm,originalDeclaringType)); | |||
couldBeFurtherAsYetUndiscoveredSignatures = false; | |||
return; | |||
} | |||
firstDefiningMember = signaturesOfMember.resolve(world); | |||
if (firstDefiningMember == null) { | |||
couldBeFurtherAsYetUndiscoveredSignatures = false; | |||
return; | |||
} | |||
// declaringType can be unresolved if we matched a synthetic member generated by Aj... | |||
// should be fixed elsewhere but add this resolve call on the end for now so that we can | |||
// focus on one problem at a time... | |||
firstDefiningType = firstDefiningMember.getDeclaringType().resolve(world); | |||
if (firstDefiningType != originalDeclaringType) { | |||
if (signaturesOfMember.getKind() == Member.CONSTRUCTOR) { | |||
return; | |||
} | |||
} | |||
List declaringTypes = new ArrayList(); | |||
accumulateTypesInBetween(originalDeclaringType, | |||
firstDefiningType, | |||
declaringTypes); | |||
for (Iterator iter = declaringTypes.iterator(); iter.hasNext();) { | |||
// Walk up hierarchy creating one member for each type up to and including the | |||
// first defining type | |||
ResolvedType originalDeclaringType = signaturesOfMember.getDeclaringType().resolve(world); | |||
ResolvedType superType = originalDeclaringType.getSuperclass(); | |||
if (superType != null && superType.equals(jlrProxy)) { | |||
// Proxy types are generated without any regard to generics (pr268419) and so the member walking | |||
// should also ignore them | |||
isProxy = true; | |||
} | |||
if (world.isJoinpointArrayConstructionEnabled() && originalDeclaringType.isArray()) { // Aha, this must be the array | |||
// constructor call join point - a | |||
// 'special'... | |||
Member m = signaturesOfMember; | |||
ResolvedMember rm = new ResolvedMemberImpl(m.getKind(), m.getDeclaringType(), m.getModifiers(), m.getReturnType(), m | |||
.getName(), m.getParameterTypes()); | |||
discoveredSignatures.add(new JoinPointSignature(rm, originalDeclaringType)); | |||
couldBeFurtherAsYetUndiscoveredSignatures = false; | |||
return; | |||
} | |||
firstDefiningMember = signaturesOfMember.resolve(world); | |||
if (firstDefiningMember == null) { | |||
couldBeFurtherAsYetUndiscoveredSignatures = false; | |||
return; | |||
} | |||
// declaringType can be unresolved if we matched a synthetic member generated by Aj... | |||
// should be fixed elsewhere but add this resolve call on the end for now so that we can | |||
// focus on one problem at a time... | |||
firstDefiningType = firstDefiningMember.getDeclaringType().resolve(world); | |||
if (firstDefiningType != originalDeclaringType) { | |||
if (signaturesOfMember.getKind() == Member.CONSTRUCTOR) { | |||
return; | |||
} | |||
} | |||
List declaringTypes = new ArrayList(); | |||
accumulateTypesInBetween(originalDeclaringType, firstDefiningType, declaringTypes); | |||
for (Iterator iter = declaringTypes.iterator(); iter.hasNext();) { | |||
ResolvedType declaringType = (ResolvedType) iter.next(); | |||
ResolvedMember member = ((ResolvedMemberImpl)firstDefiningMember).withSubstituteDeclaringType(declaringType); | |||
ResolvedMember member = ((ResolvedMemberImpl) firstDefiningMember).withSubstituteDeclaringType(declaringType); | |||
discoveredSignatures.add(member); | |||
} | |||
} | |||
/** | |||
* Build a list containing every type between subtype and supertype, inclusively. | |||
*/ | |||
private void accumulateTypesInBetween(ResolvedType subType, ResolvedType superType, List types) { | |||
types.add(subType); | |||
if (subType == superType) { | |||
return; | |||
} else { | |||
for (Iterator iter = subType.getDirectSupertypes(); iter.hasNext();) { | |||
/** | |||
* Build a list containing every type between subtype and supertype, inclusively. | |||
*/ | |||
private void accumulateTypesInBetween(ResolvedType subType, ResolvedType superType, List types) { | |||
types.add(subType); | |||
if (subType == superType) { | |||
return; | |||
} else { | |||
for (Iterator iter = subType.getDirectSupertypes(); iter.hasNext();) { | |||
ResolvedType parent = (ResolvedType) iter.next(); | |||
if (superType.isAssignableFrom(parent,true)) { | |||
accumulateTypesInBetween(parent, superType,types); | |||
if (superType.isAssignableFrom(parent, true)) { | |||
accumulateTypesInBetween(parent, superType, types); | |||
} | |||
} | |||
} | |||
} | |||
private boolean shouldWalkUpHierarchy() { | |||
if (signaturesOfMember.getKind() == Member.CONSTRUCTOR) return false; | |||
if (signaturesOfMember.getKind() == Member.FIELD) return false; | |||
if (signaturesOfMember.isStatic()) return false; | |||
return true; | |||
} | |||
private boolean findSignaturesFromSupertypes() { | |||
iteratingOverDiscoveredSignatures = false; | |||
if (superTypeIterator == null) { | |||
superTypeIterator = firstDefiningType.getDirectSupertypes(); | |||
} | |||
if (superTypeIterator.hasNext()) { | |||
ResolvedType superType = (ResolvedType) superTypeIterator.next(); | |||
if (visitedSuperTypes.contains(superType)) { | |||
return findSignaturesFromSupertypes(); | |||
} else { | |||
// we haven't looked in this type yet | |||
visitedSuperTypes.add(superType); | |||
if (superType.isMissing()) { | |||
// issue a warning, stop looking for join point signatures in this line | |||
warnOnMissingType(superType); | |||
return findSignaturesFromSupertypes(); | |||
} | |||
ResolvedMemberImpl foundMember = (ResolvedMemberImpl) superType.lookupResolvedMember(firstDefiningMember,true); | |||
if (foundMember != null && isVisibleTo(firstDefiningMember,foundMember)) { | |||
} | |||
} | |||
private boolean shouldWalkUpHierarchy() { | |||
if (signaturesOfMember.getKind() == Member.CONSTRUCTOR) | |||
return false; | |||
if (signaturesOfMember.getKind() == Member.FIELD) | |||
return false; | |||
if (signaturesOfMember.isStatic()) | |||
return false; | |||
return true; | |||
} | |||
private boolean findSignaturesFromSupertypes() { | |||
iteratingOverDiscoveredSignatures = false; | |||
if (superTypeIterator == null) { | |||
superTypeIterator = firstDefiningType.getDirectSupertypes(); | |||
} | |||
if (superTypeIterator.hasNext()) { | |||
ResolvedType superType = (ResolvedType) superTypeIterator.next(); | |||
if (isProxy && (superType.isGenericType() || superType.isParameterizedType())) { | |||
superType = (ResolvedType) superType.getRawType(); | |||
} | |||
if (visitedSuperTypes.contains(superType)) { | |||
return findSignaturesFromSupertypes(); | |||
} else { | |||
// we haven't looked in this type yet | |||
visitedSuperTypes.add(superType); | |||
if (superType.isMissing()) { | |||
// issue a warning, stop looking for join point signatures in this line | |||
warnOnMissingType(superType); | |||
return findSignaturesFromSupertypes(); | |||
} | |||
ResolvedMemberImpl foundMember = (ResolvedMemberImpl) superType.lookupResolvedMember(firstDefiningMember, true, | |||
isProxy); | |||
if (foundMember != null && isVisibleTo(firstDefiningMember, foundMember)) { | |||
List declaringTypes = new ArrayList(); | |||
// declaring type can be unresolved if the member can from an ITD... | |||
ResolvedType resolvedDeclaringType = foundMember.getDeclaringType().resolve(world); | |||
accumulateTypesInBetween(superType, resolvedDeclaringType, declaringTypes); | |||
for (Iterator iter = declaringTypes.iterator(); iter.hasNext();) { | |||
for (Iterator iter = declaringTypes.iterator(); iter.hasNext();) { | |||
ResolvedType declaringType = (ResolvedType) iter.next(); | |||
ResolvedMember member = foundMember.withSubstituteDeclaringType(declaringType); | |||
discoveredSignatures.add(member); // for next time we are reset | |||
if (additionalSignatures==Collections.EMPTY_LIST) additionalSignatures=new ArrayList(); | |||
additionalSignatures.add(member); // for this time | |||
} | |||
ResolvedMember member = null; | |||
if (isProxy) { | |||
if (declaringType.isGenericType() || declaringType.isParameterizedType()) { | |||
declaringType = (ResolvedType) declaringType.getRawType(); | |||
} | |||
member = foundMember.withSubstituteDeclaringType(declaringType); | |||
} else { | |||
member = foundMember.withSubstituteDeclaringType(declaringType); | |||
} | |||
discoveredSignatures.add(member); // for next time we are reset | |||
if (additionalSignatures == Collections.EMPTY_LIST) | |||
additionalSignatures = new ArrayList(); | |||
additionalSignatures.add(member); // for this time | |||
} | |||
// if this was a parameterized type, look in the generic type that backs it too | |||
if (superType.isParameterizedType() && (foundMember.backingGenericMember != null)) { | |||
ResolvedMember member =new JoinPointSignature(foundMember.backingGenericMember,foundMember.declaringType.resolve(world)); | |||
discoveredSignatures.add(member); // for next time we are reset | |||
if (additionalSignatures==Collections.EMPTY_LIST) additionalSignatures=new ArrayList(); | |||
additionalSignatures.add(member); // for this time | |||
if (!isProxy && superType.isParameterizedType() && (foundMember.backingGenericMember != null)) { | |||
ResolvedMember member = new JoinPointSignature(foundMember.backingGenericMember, foundMember.declaringType | |||
.resolve(world)); | |||
discoveredSignatures.add(member); // for next time we are reset | |||
if (additionalSignatures == Collections.EMPTY_LIST) | |||
additionalSignatures = new ArrayList(); | |||
additionalSignatures.add(member); // for this time | |||
} | |||
if (yetToBeProcessedSuperMembers == null) { | |||
yetToBeProcessedSuperMembers = new ArrayList(); | |||
} | |||
if (yetToBeProcessedSuperMembers==null) yetToBeProcessedSuperMembers=new ArrayList(); | |||
yetToBeProcessedSuperMembers.add(new SearchPair(foundMember,superType)); | |||
yetToBeProcessedSuperMembers.add(new SearchPair(foundMember, superType)); | |||
return true; | |||
} else { | |||
return findSignaturesFromSupertypes(); | |||
} | |||
} | |||
} | |||
if (yetToBeProcessedSuperMembers!=null && !yetToBeProcessedSuperMembers.isEmpty()) { | |||
SearchPair nextUp = (SearchPair) yetToBeProcessedSuperMembers.remove(0); | |||
firstDefiningType = nextUp.type; | |||
firstDefiningMember = nextUp.member; | |||
superTypeIterator = null; | |||
return findSignaturesFromSupertypes(); | |||
} | |||
couldBeFurtherAsYetUndiscoveredSignatures = false; | |||
return false; | |||
} | |||
/** | |||
* Returns true if the parent member is visible to the child member | |||
* In the same declaring type this is always true, otherwise if parent is private | |||
* it is false. | |||
* @param childMember | |||
* @param parentMember | |||
* @return | |||
*/ | |||
private boolean isVisibleTo(ResolvedMember childMember, ResolvedMember parentMember) { | |||
if (childMember.getDeclaringType().equals(parentMember.getDeclaringType())) return true; | |||
if (Modifier.isPrivate(parentMember.getModifiers())) { | |||
return false; | |||
} else { | |||
return true; | |||
} | |||
} | |||
private void warnOnMissingType(ResolvedType missing) { | |||
if (missing instanceof MissingResolvedTypeWithKnownSignature) { | |||
// which it should be... | |||
MissingResolvedTypeWithKnownSignature mrt = (MissingResolvedTypeWithKnownSignature) missing; | |||
mrt.raiseWarningOnJoinPointSignature(signaturesOfMember.toString()); | |||
} | |||
} | |||
private static class SearchPair { | |||
public ResolvedMember member; | |||
public ResolvedType type; | |||
public SearchPair(ResolvedMember member, ResolvedType type) { | |||
this.member = member; | |||
this.type = type; | |||
} | |||
} | |||
} | |||
} | |||
if (yetToBeProcessedSuperMembers != null && !yetToBeProcessedSuperMembers.isEmpty()) { | |||
SearchPair nextUp = (SearchPair) yetToBeProcessedSuperMembers.remove(0); | |||
firstDefiningType = nextUp.type; | |||
firstDefiningMember = nextUp.member; | |||
superTypeIterator = null; | |||
return findSignaturesFromSupertypes(); | |||
} | |||
couldBeFurtherAsYetUndiscoveredSignatures = false; | |||
return false; | |||
} | |||
/** | |||
* Returns true if the parent member is visible to the child member In the same declaring type this is always true, otherwise if | |||
* parent is private it is false. | |||
* | |||
* @param childMember | |||
* @param parentMember | |||
* @return | |||
*/ | |||
private boolean isVisibleTo(ResolvedMember childMember, ResolvedMember parentMember) { | |||
if (childMember.getDeclaringType().equals(parentMember.getDeclaringType())) | |||
return true; | |||
if (Modifier.isPrivate(parentMember.getModifiers())) { | |||
return false; | |||
} else { | |||
return true; | |||
} | |||
} | |||
private void warnOnMissingType(ResolvedType missing) { | |||
if (missing instanceof MissingResolvedTypeWithKnownSignature) { | |||
// which it should be... | |||
MissingResolvedTypeWithKnownSignature mrt = (MissingResolvedTypeWithKnownSignature) missing; | |||
mrt.raiseWarningOnJoinPointSignature(signaturesOfMember.toString()); | |||
} | |||
} | |||
private static class SearchPair { | |||
public ResolvedMember member; | |||
public ResolvedType type; | |||
public SearchPair(ResolvedMember member, ResolvedType type) { | |||
this.member = member; | |||
this.type = type; | |||
} | |||
} | |||
} |
@@ -20,8 +20,7 @@ import java.util.Map; | |||
import org.aspectj.bridge.ISourceLocation; | |||
public interface ResolvedMember extends Member, AnnotatedElement, | |||
TypeVariableDeclaringElement { | |||
public interface ResolvedMember extends Member, AnnotatedElement, TypeVariableDeclaringElement { | |||
public static final ResolvedMember[] NONE = new ResolvedMember[0]; | |||
@@ -119,14 +118,12 @@ public interface ResolvedMember extends Member, AnnotatedElement, | |||
public ResolvedMember getBackingGenericMember(); | |||
/** | |||
* Get the UnresolvedType for the return type, taking generic signature into | |||
* account | |||
* Get the UnresolvedType for the return type, taking generic signature into account | |||
*/ | |||
public UnresolvedType getGenericReturnType(); | |||
/** | |||
* Get the TypeXs of the parameter types, taking generic signature into | |||
* account | |||
* Get the TypeXs of the parameter types, taking generic signature into account | |||
*/ | |||
public UnresolvedType[] getGenericParameterTypes(); | |||
@@ -137,16 +134,14 @@ public interface ResolvedMember extends Member, AnnotatedElement, | |||
// version or not | |||
// if isParameterized List<T> will turn into List<String> (for example), | |||
// but if !isParameterized List<T> will turn into List. | |||
public ResolvedMemberImpl parameterizedWith( | |||
UnresolvedType[] typeParameters, ResolvedType newDeclaringType, | |||
public ResolvedMemberImpl parameterizedWith(UnresolvedType[] typeParameters, ResolvedType newDeclaringType, | |||
boolean isParameterized); | |||
// this variant allows for aliases for type variables (i.e. allowing them to | |||
// have another name) | |||
// this is used for processing ITDs that share type variables with their | |||
// target generic type | |||
public ResolvedMemberImpl parameterizedWith( | |||
UnresolvedType[] typeParameters, ResolvedType newDeclaringType, | |||
public ResolvedMemberImpl parameterizedWith(UnresolvedType[] typeParameters, ResolvedType newDeclaringType, | |||
boolean isParameterized, List aliases); | |||
public void setTypeVariables(TypeVariable[] types); | |||
@@ -170,12 +165,10 @@ public interface ResolvedMember extends Member, AnnotatedElement, | |||
// public ResolvedMember getErasure(); | |||
/** | |||
* Returns true if this member matches the other. The matching takes into | |||
* account name and parameter types only. When comparing parameter types, we | |||
* allow any type variable to match any other type variable regardless of | |||
* bounds. | |||
* Returns true if this member matches the other. The matching takes into account name and parameter types only. When comparing | |||
* parameter types, we allow any type variable to match any other type variable regardless of bounds. | |||
*/ | |||
public boolean matches(ResolvedMember aCandidateMatch); | |||
public boolean matches(ResolvedMember aCandidateMatch, boolean ignoreGenerics); | |||
public void resetName(String newName); | |||
@@ -188,4 +181,5 @@ public interface ResolvedMember extends Member, AnnotatedElement, | |||
public void evictWeavingState(); | |||
public ResolvedMember parameterizedWith(Map m, World w); | |||
} |
@@ -139,7 +139,7 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno | |||
// member. | |||
Iterator superTypeIterator = firstDefiningType.getDirectSupertypes(); | |||
List typesAlreadyVisited = new ArrayList(); | |||
accumulateMembersMatching(firstDefiningMember, superTypeIterator, typesAlreadyVisited, memberSignatures); | |||
accumulateMembersMatching(firstDefiningMember, superTypeIterator, typesAlreadyVisited, memberSignatures, false); | |||
} | |||
JoinPointSignature[] ret = new JoinPointSignature[memberSignatures.size()]; | |||
@@ -179,12 +179,13 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno | |||
* ancestor members. When doing this, a type parameter matches regardless of bounds (bounds can be narrowed down the hierarchy). | |||
*/ | |||
private static void accumulateMembersMatching(ResolvedMemberImpl memberToMatch, Iterator typesToLookIn, | |||
List typesAlreadyVisited, Set foundMembers) { | |||
List typesAlreadyVisited, Set foundMembers, boolean ignoreGenerics) { | |||
while (typesToLookIn.hasNext()) { | |||
ResolvedType toLookIn = (ResolvedType) typesToLookIn.next(); | |||
if (!typesAlreadyVisited.contains(toLookIn)) { | |||
typesAlreadyVisited.add(toLookIn); | |||
ResolvedMemberImpl foundMember = (ResolvedMemberImpl) toLookIn.lookupResolvedMember(memberToMatch, true); | |||
ResolvedMemberImpl foundMember = (ResolvedMemberImpl) toLookIn.lookupResolvedMember(memberToMatch, true, | |||
ignoreGenerics); | |||
if (foundMember != null && isVisibleTo(memberToMatch, foundMember)) { | |||
List declaringTypes = new ArrayList(); | |||
// declaring type can be unresolved if the member can from | |||
@@ -197,11 +198,12 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno | |||
ResolvedMember member = foundMember.withSubstituteDeclaringType(declaringType); | |||
foundMembers.add(member); | |||
} | |||
if (toLookIn.isParameterizedType() && (foundMember.backingGenericMember != null)) { | |||
if (!ignoreGenerics && toLookIn.isParameterizedType() && (foundMember.backingGenericMember != null)) { | |||
foundMembers.add(new JoinPointSignature(foundMember.backingGenericMember, foundMember.declaringType | |||
.resolve(toLookIn.getWorld()))); | |||
} | |||
accumulateMembersMatching(foundMember, toLookIn.getDirectSupertypes(), typesAlreadyVisited, foundMembers); | |||
accumulateMembersMatching(foundMember, toLookIn.getDirectSupertypes(), typesAlreadyVisited, foundMembers, | |||
ignoreGenerics); | |||
// if this was a parameterized type, look in the generic | |||
// type that backs it too | |||
} | |||
@@ -911,24 +913,57 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno | |||
* Returns true if this member matches the other. The matching takes into account name and parameter types only. When comparing | |||
* parameter types, we allow any type variable to match any other type variable regardless of bounds. | |||
*/ | |||
public boolean matches(ResolvedMember aCandidateMatch) { | |||
public boolean matches(ResolvedMember aCandidateMatch, boolean ignoreGenerics) { | |||
// if (this.getName().equals("get")) { | |||
// System.out.println("In RMI.matches() this=" + this + " candidate=" + aCandidateMatch); | |||
// } | |||
ResolvedMemberImpl candidateMatchImpl = (ResolvedMemberImpl) aCandidateMatch; | |||
if (!getName().equals(aCandidateMatch.getName())) | |||
if (!getName().equals(aCandidateMatch.getName())) { | |||
return false; | |||
} | |||
UnresolvedType[] myParameterTypes = getGenericParameterTypes(); | |||
UnresolvedType[] candidateParameterTypes = aCandidateMatch.getGenericParameterTypes(); | |||
if (myParameterTypes.length != candidateParameterTypes.length) | |||
if (myParameterTypes.length != candidateParameterTypes.length) { | |||
return false; | |||
String myParameterSignature = getParameterSigWithBoundsRemoved(); | |||
String candidateParameterSignature = candidateMatchImpl.getParameterSigWithBoundsRemoved(); | |||
if (myParameterSignature.equals(candidateParameterSignature)) { | |||
return true; | |||
} | |||
boolean b = false; | |||
/* if (ignoreGenerics) { | |||
String myParameterSignature = getParameterSigWithBoundsRemoved(); | |||
String candidateParameterSignature = candidateMatchImpl.getParameterSigWithBoundsRemoved(); | |||
if (myParameterSignature.equals(candidateParameterSignature)) { | |||
b = true; | |||
} else { | |||
myParameterSignature = (hasBackingGenericMember() ? backingGenericMember.getParameterSignatureErased() | |||
: getParameterSignatureErased()); | |||
candidateParameterSignature = (candidateMatchImpl.hasBackingGenericMember() ? candidateMatchImpl.backingGenericMember | |||
.getParameterSignatureErased() | |||
: candidateMatchImpl.getParameterSignatureErased()); | |||
// System.out.println("my psig = " + myParameterSignature); | |||
// System.out.println("can psig = " + candidateParameterSignature); | |||
b = myParameterSignature.equals(candidateParameterSignature); | |||
} | |||
} else { | |||
// try erasure | |||
myParameterSignature = getParameterSignatureErased(); | |||
candidateParameterSignature = candidateMatchImpl.getParameterSignatureErased(); | |||
return myParameterSignature.equals(candidateParameterSignature); | |||
*/ | |||
String myParameterSignature = getParameterSigWithBoundsRemoved(); | |||
String candidateParameterSignature = candidateMatchImpl.getParameterSigWithBoundsRemoved(); | |||
if (myParameterSignature.equals(candidateParameterSignature)) { | |||
b = true; | |||
} else { | |||
// try erasure | |||
myParameterSignature = getParameterSignatureErased(); | |||
candidateParameterSignature = candidateMatchImpl.getParameterSignatureErased(); | |||
// myParameterSignature = (hasBackingGenericMember() ? backingGenericMember.getParameterSignatureErased() | |||
// : getParameterSignatureErased()); | |||
// candidateParameterSignature = (candidateMatchImpl.hasBackingGenericMember() ? | |||
// candidateMatchImpl.backingGenericMember | |||
// .getParameterSignatureErased() : candidateMatchImpl.getParameterSignatureErased()); | |||
// System.out.println("my psig = " + myParameterSignature); | |||
// System.out.println("can psig = " + candidateParameterSignature); | |||
b = myParameterSignature.equals(candidateParameterSignature); | |||
// } | |||
} | |||
// System.out.println("Checking param signatures: " + b); | |||
return b; | |||
} | |||
/** |
@@ -251,48 +251,53 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl | |||
public List getMethodsWithoutIterator(boolean includeITDs, boolean allowMissing) { | |||
List methods = new ArrayList(); | |||
Set knowninterfaces = new HashSet(); | |||
addAndRecurse(knowninterfaces, methods, this, includeITDs, allowMissing); | |||
addAndRecurse(knowninterfaces, methods, this, includeITDs, allowMissing, false); | |||
return methods; | |||
} | |||
private void addAndRecurse(Set knowninterfaces, List collector, ResolvedType rtx, boolean includeITDs, boolean allowMissing) { | |||
collector.addAll(Arrays.asList(rtx.getDeclaredMethods())); // Add the | |||
// methods | |||
// declared | |||
// on this | |||
// type | |||
public List getMethodsWithoutIterator(boolean includeITDs, boolean allowMissing, boolean genericsAware) { | |||
List methods = new ArrayList(); | |||
Set knowninterfaces = new HashSet(); | |||
addAndRecurse(knowninterfaces, methods, this, includeITDs, allowMissing, genericsAware); | |||
return methods; | |||
} | |||
private void addAndRecurse(Set knowninterfaces, List collector, ResolvedType resolvedType, boolean includeITDs, | |||
boolean allowMissing, boolean genericsAware) { | |||
// Add the methods declared on this type | |||
collector.addAll(Arrays.asList(resolvedType.getDeclaredMethods())); | |||
// now add all the inter-typed members too | |||
if (includeITDs && rtx.interTypeMungers != null) { | |||
if (includeITDs && resolvedType.interTypeMungers != null) { | |||
for (Iterator i = interTypeMungers.iterator(); i.hasNext();) { | |||
ConcreteTypeMunger tm = (ConcreteTypeMunger) i.next(); | |||
ResolvedMember rm = tm.getSignature(); | |||
if (rm != null) { // new parent type munger can have null | |||
// signature... | |||
if (rm != null) { // new parent type munger can have null signature | |||
collector.add(tm.getSignature()); | |||
} | |||
} | |||
} | |||
if (!rtx.equals(ResolvedType.OBJECT)) { | |||
ResolvedType superType = rtx.getSuperclass(); | |||
if (!resolvedType.equals(ResolvedType.OBJECT)) { | |||
ResolvedType superType = resolvedType.getSuperclass(); | |||
if (superType != null && !superType.isMissing()) { | |||
addAndRecurse(knowninterfaces, collector, superType, includeITDs, allowMissing); // Recurse if we aren't at | |||
// the top | |||
if (genericsAware && superType.isParameterizedType()) { | |||
superType = (ResolvedType) superType.getRawType(); | |||
} | |||
// Recurse if we are not at the top | |||
addAndRecurse(knowninterfaces, collector, superType, includeITDs, allowMissing, genericsAware); | |||
} | |||
} | |||
ResolvedType[] interfaces = rtx.getDeclaredInterfaces(); // Go through | |||
// the | |||
// interfaces | |||
// on the | |||
// way back | |||
// down | |||
// Go through the interfaces on the way back down | |||
ResolvedType[] interfaces = resolvedType.getDeclaredInterfaces(); | |||
for (int i = 0; i < interfaces.length; i++) { | |||
ResolvedType iface = interfaces[i]; | |||
if (!genericsAware && iface.isParameterizedType()) { | |||
iface = (ResolvedType) iface.getRawType(); | |||
} | |||
// we need to know if it is an interface from Parent kind munger | |||
// as those are used for @AJ ITD and we precisely want to skip those | |||
boolean shouldSkip = false; | |||
for (int j = 0; j < rtx.interTypeMungers.size(); j++) { | |||
ConcreteTypeMunger munger = (ConcreteTypeMunger) rtx.interTypeMungers.get(j); | |||
for (int j = 0; j < resolvedType.interTypeMungers.size(); j++) { | |||
ConcreteTypeMunger munger = (ConcreteTypeMunger) resolvedType.interTypeMungers.get(j); | |||
if (munger.getMunger() != null && munger.getMunger().getKind() == ResolvedTypeMunger.Parent | |||
&& ((NewParentTypeMunger) munger.getMunger()).getNewParent().equals(iface) // pr171953 | |||
) { | |||
@@ -301,17 +306,15 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl | |||
} | |||
} | |||
if (!shouldSkip && !knowninterfaces.contains(iface)) { // Dont do | |||
// interfaces | |||
// more than | |||
// once | |||
// Do not do interfaces more than once | |||
if (!shouldSkip && !knowninterfaces.contains(iface)) { | |||
knowninterfaces.add(iface); | |||
if (allowMissing && iface.isMissing()) { | |||
if (iface instanceof MissingResolvedTypeWithKnownSignature) { | |||
((MissingResolvedTypeWithKnownSignature) iface).raiseWarningOnMissingInterfaceWhilstFindingMethods(); | |||
} | |||
} else { | |||
addAndRecurse(knowninterfaces, collector, iface, includeITDs, allowMissing); | |||
addAndRecurse(knowninterfaces, collector, iface, includeITDs, allowMissing, genericsAware); | |||
} | |||
} | |||
} | |||
@@ -433,19 +436,25 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl | |||
* into account parameters which are type variables - which clearly an unresolved Member cannot do since it does not know | |||
* anything about type variables. | |||
*/ | |||
public ResolvedMember lookupResolvedMember(ResolvedMember aMember, boolean allowMissing) { | |||
public ResolvedMember lookupResolvedMember(ResolvedMember aMember, boolean allowMissing, boolean ignoreGenerics) { | |||
Iterator toSearch = null; | |||
ResolvedMember found = null; | |||
if ((aMember.getKind() == Member.METHOD) || (aMember.getKind() == Member.CONSTRUCTOR)) { | |||
toSearch = getMethodsWithoutIterator(true, allowMissing).iterator(); | |||
toSearch = getMethodsWithoutIterator(true, allowMissing, !ignoreGenerics).iterator(); | |||
} else { | |||
if (aMember.getKind() != Member.FIELD) | |||
throw new IllegalStateException("I didn't know you would look for members of kind " + aMember.getKind()); | |||
toSearch = getFields(); | |||
} | |||
while (toSearch.hasNext()) { | |||
ResolvedMemberImpl candidate = (ResolvedMemberImpl) toSearch.next(); | |||
if (candidate.matches(aMember)) { | |||
ResolvedMember candidate = (ResolvedMemberImpl) toSearch.next(); | |||
if (ignoreGenerics) { | |||
if (candidate.hasBackingGenericMember()) { | |||
candidate = candidate.getBackingGenericMember(); | |||
} | |||
} | |||
if (candidate.matches(aMember, ignoreGenerics)) { | |||
found = candidate; | |||
break; | |||
} |