package org.aspectj.weaver;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Set;
import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.ISourceLocation;
import org.aspectj.bridge.Message;
import org.aspectj.bridge.MessageUtil;
import org.aspectj.util.FuzzyBoolean;
import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;
import org.aspectj.weaver.Iterators.Getter;
import org.aspectj.weaver.patterns.Declare;
import org.aspectj.weaver.patterns.PerClause;
public abstract class ResolvedType extends UnresolvedType implements AnnotatedElement {
public static final ResolvedType[] EMPTY_RESOLVED_TYPE_ARRAY = new ResolvedType[0];
public static final String PARAMETERIZED_TYPE_IDENTIFIER = "P";
public ResolvedType[] temporaryAnnotationTypes;
private ResolvedType[] resolvedTypeParams;
private String binaryPath;
protected World world;
protected int bits;
private static int AnnotationBitsInitialized = 0x0001;
private static int AnnotationMarkedInherited = 0x0002;
private static int MungersAnalyzed = 0x0004;
private static int HasParentMunger = 0x0008;
private static int TypeHierarchyCompleteBit = 0x0010;
private static int GroovyObjectInitialized = 0x0020;
private static int IsGroovyObject = 0x0040;
private static int IsPrivilegedBitInitialized = 0x0080;
private static int IsPrivilegedAspect = 0x0100;
protected ResolvedType(String signature, World world) {
super(signature);
this.world = world;
}
protected ResolvedType(String signature, String signatureErasure, World world) {
super(signature, signatureErasure);
this.world = world;
}
@Override
public int getSize() {
return 1;
}
public final Iterator<ResolvedType> getDirectSupertypes() {
Iterator<ResolvedType> interfacesIterator = Iterators.array(getDeclaredInterfaces());
ResolvedType superclass = getSuperclass();
if (superclass == null) {
return interfacesIterator;
} else {
return Iterators.snoc(interfacesIterator, superclass);
}
}
public abstract ResolvedMember[] getDeclaredFields();
public abstract ResolvedMember[] getDeclaredMethods();
public abstract ResolvedType[] getDeclaredInterfaces();
public abstract ResolvedMember[] getDeclaredPointcuts();
public boolean isCacheable() {
return true;
}
public abstract ResolvedType getSuperclass();
public abstract int getModifiers();
public boolean canBeSeenBy(ResolvedType from) {
int targetMods = getModifiers();
if (Modifier.isPublic(targetMods)) {
return true;
}
if (Modifier.isPrivate(targetMods)) {
return false;
}
return getPackageName().equals(from.getPackageName());
}
public boolean isMissing() {
return false;
}
public static boolean isMissing(UnresolvedType unresolved) {
if (unresolved instanceof ResolvedType) {
ResolvedType resolved = (ResolvedType) unresolved;
return resolved.isMissing();
} else {
return (unresolved == MISSING);
}
}
@Override
public ResolvedType[] getAnnotationTypes() {
return EMPTY_RESOLVED_TYPE_ARRAY;
}
@Override
public AnnotationAJ getAnnotationOfType(UnresolvedType ofType) {
return null;
}
protected static Set<String> validBoxing = new HashSet<String>();
static {
validBoxing.add("Ljava/lang/Byte;B");
validBoxing.add("Ljava/lang/Character;C");
validBoxing.add("Ljava/lang/Double;D");
validBoxing.add("Ljava/lang/Float;F");
validBoxing.add("Ljava/lang/Integer;I");
validBoxing.add("Ljava/lang/Long;J");
validBoxing.add("Ljava/lang/Short;S");
validBoxing.add("Ljava/lang/Boolean;Z");
validBoxing.add("BLjava/lang/Byte;");
validBoxing.add("CLjava/lang/Character;");
validBoxing.add("DLjava/lang/Double;");
validBoxing.add("FLjava/lang/Float;");
validBoxing.add("ILjava/lang/Integer;");
validBoxing.add("JLjava/lang/Long;");
validBoxing.add("SLjava/lang/Short;");
validBoxing.add("ZLjava/lang/Boolean;");
}
public ResolvedType getResolvedComponentType() {
return null;
}
public World getWorld() {
return world;
}
@Override
public boolean equals(Object other) {
if (other instanceof ResolvedType) {
return this == other;
} else {
return super.equals(other);
}
}
public Iterator<ResolvedMember> getFields() {
final Iterators.Filter<ResolvedType> dupFilter = Iterators.dupFilter();
Iterators.Getter<ResolvedType, ResolvedType> typeGetter = new Iterators.Getter<ResolvedType, ResolvedType>() {
@Override
public Iterator<ResolvedType> get(ResolvedType o) {
return dupFilter.filter(o.getDirectSupertypes());
}
};
return Iterators.mapOver(Iterators.recur(this, typeGetter), FieldGetterInstance);
}
public Iterator<ResolvedMember> getMethods(boolean wantGenerics, boolean wantDeclaredParents) {
return Iterators.mapOver(getHierarchy(wantGenerics, wantDeclaredParents), MethodGetterInstance);
}
public Iterator<ResolvedMember> getMethodsIncludingIntertypeDeclarations(boolean wantGenerics, boolean wantDeclaredParents) {
return Iterators.mapOver(getHierarchy(wantGenerics, wantDeclaredParents), MethodGetterWithItdsInstance);
}
private static class MethodGetter implements Iterators.Getter<ResolvedType, ResolvedMember> {
@Override
public Iterator<ResolvedMember> get(ResolvedType type) {
return Iterators.array(type.getDeclaredMethods());
}
}
private static class PointcutGetter implements Iterators.Getter<ResolvedType, ResolvedMember> {
@Override
public Iterator<ResolvedMember> get(ResolvedType o) {
return Iterators.array(o.getDeclaredPointcuts());
}
}
private static class MethodGetterIncludingItds implements Iterators.Getter<ResolvedType, ResolvedMember> {
@Override
public Iterator<ResolvedMember> get(ResolvedType type) {
ResolvedMember[] methods = type.getDeclaredMethods();
if (type.interTypeMungers != null) {
int additional = 0;
for (ConcreteTypeMunger typeTransformer : type.interTypeMungers) {
ResolvedMember rm = typeTransformer.getSignature();
if (rm != null) {
additional++;
}
}
if (additional > 0) {
ResolvedMember[] methods2 = new ResolvedMember[methods.length + additional];
System.arraycopy(methods, 0, methods2, 0, methods.length);
additional = methods.length;
for (ConcreteTypeMunger typeTransformer : type.interTypeMungers) {
ResolvedMember rm = typeTransformer.getSignature();
if (rm != null) {
methods2[additional++] = typeTransformer.getSignature();
}
}
methods = methods2;
}
}
return Iterators.array(methods);
}
}
private static class FieldGetter implements Iterators.Getter<ResolvedType, ResolvedMember> {
@Override
public Iterator<ResolvedMember> get(ResolvedType type) {
return Iterators.array(type.getDeclaredFields());
}
}
private final static MethodGetter MethodGetterInstance = new MethodGetter();
private final static MethodGetterIncludingItds MethodGetterWithItdsInstance = new MethodGetterIncludingItds();
private final static PointcutGetter PointcutGetterInstance = new PointcutGetter();
private final static FieldGetter FieldGetterInstance = new FieldGetter();
public Iterator<ResolvedType> getHierarchy() {
return getHierarchy(false, false);
}
public Iterator<ResolvedType> getHierarchy(final boolean wantGenerics, final boolean wantDeclaredParents) {
final Iterators.Getter<ResolvedType, ResolvedType> interfaceGetter = new Iterators.Getter<ResolvedType, ResolvedType>() {
List<String> alreadySeen = new ArrayList<String>();
@Override
public Iterator<ResolvedType> get(ResolvedType type) {
ResolvedType[] interfaces = type.getDeclaredInterfaces();
if (!wantDeclaredParents && type.hasNewParentMungers()) {
List<Integer> forRemoval = new ArrayList<Integer>();
for (ConcreteTypeMunger munger : type.interTypeMungers) {
if (munger.getMunger() != null) {
ResolvedTypeMunger m = munger.getMunger();
if (m.getKind() == ResolvedTypeMunger.Parent) {
ResolvedType newType = ((NewParentTypeMunger) m).getNewParent();
if (!wantGenerics && newType.isParameterizedOrGenericType()) {
newType = newType.getRawType();
}
for (int ii = 0; ii < interfaces.length; ii++) {
ResolvedType iface = interfaces[ii];
if (!wantGenerics && iface.isParameterizedOrGenericType()) {
iface = iface.getRawType();
}
if (newType.getSignature().equals(iface.getSignature())) {
forRemoval.add(ii);
}
}
}
}
}
if (forRemoval.size() > 0) {
ResolvedType[] interfaces2 = new ResolvedType[interfaces.length - forRemoval.size()];
int p = 0;
for (int ii = 0; ii < interfaces.length; ii++) {
if (!forRemoval.contains(ii)) {
interfaces2[p++] = interfaces[ii];
}
}
interfaces = interfaces2;
}
}
return new Iterators.ResolvedTypeArrayIterator(interfaces, alreadySeen, wantGenerics);
}
};
if (this.isInterface()) {
return new SuperInterfaceWalker(interfaceGetter, this);
} else {
SuperInterfaceWalker superInterfaceWalker = new SuperInterfaceWalker(interfaceGetter);
Iterator<ResolvedType> superClassesIterator = new SuperClassWalker(this, superInterfaceWalker, wantGenerics);
return Iterators.append1(superClassesIterator, superInterfaceWalker);
}
}
public List<ResolvedMember> getMethodsWithoutIterator(boolean includeITDs, boolean allowMissing, boolean genericsAware) {
List<ResolvedMember> methods = new ArrayList<ResolvedMember>();
Set<String> knowninterfaces = new HashSet<String>();
addAndRecurse(knowninterfaces, methods, this, includeITDs, allowMissing, genericsAware);
return methods;
}
public List<ResolvedType> getHierarchyWithoutIterator(boolean includeITDs, boolean allowMissing, boolean genericsAware) {
List<ResolvedType> types = new ArrayList<ResolvedType>();
Set<String> visited = new HashSet<String>();
recurseHierarchy(visited, types, this, includeITDs, allowMissing, genericsAware);
return types;
}
private void addAndRecurse(Set<String> knowninterfaces, List<ResolvedMember> collector, ResolvedType resolvedType,
boolean includeITDs, boolean allowMissing, boolean genericsAware) {
collector.addAll(Arrays.asList(resolvedType.getDeclaredMethods()));
if (includeITDs && resolvedType.interTypeMungers != null) {
for (ConcreteTypeMunger typeTransformer : interTypeMungers) {
ResolvedMember rm = typeTransformer.getSignature();
if (rm != null) {
collector.add(typeTransformer.getSignature());
}
}
}
if (!resolvedType.isInterface() && !resolvedType.equals(ResolvedType.OBJECT)) {
ResolvedType superType = resolvedType.getSuperclass();
if (superType != null && !superType.isMissing()) {
if (!genericsAware && superType.isParameterizedOrGenericType()) {
superType = superType.getRawType();
}
addAndRecurse(knowninterfaces, collector, superType, includeITDs, allowMissing, genericsAware);
}
}
ResolvedType[] interfaces = resolvedType.getDeclaredInterfaces();
for (int i = 0; i < interfaces.length; i++) {
ResolvedType iface = interfaces[i];
if (!genericsAware && iface.isParameterizedOrGenericType()) {
iface = iface.getRawType();
}
boolean shouldSkip = false;
for (int j = 0; j < resolvedType.interTypeMungers.size(); j++) {
ConcreteTypeMunger munger = resolvedType.interTypeMungers.get(j);
if (munger.getMunger() != null && munger.getMunger().getKind() == ResolvedTypeMunger.Parent
&& ((NewParentTypeMunger) munger.getMunger()).getNewParent().equals(iface)
) {
shouldSkip = true;
break;
}
}
if (!shouldSkip && !knowninterfaces.contains(iface.getSignature())) {
knowninterfaces.add(iface.getSignature());
if (allowMissing && iface.isMissing()) {
if (iface instanceof MissingResolvedTypeWithKnownSignature) {
((MissingResolvedTypeWithKnownSignature) iface).raiseWarningOnMissingInterfaceWhilstFindingMethods();
}
} else {
addAndRecurse(knowninterfaces, collector, iface, includeITDs, allowMissing, genericsAware);
}
}
}
}
private void recurseHierarchy(Set<String> knowninterfaces, List<ResolvedType> collector, ResolvedType resolvedType,
boolean includeITDs, boolean allowMissing, boolean genericsAware) {
collector.add(resolvedType);
if (!resolvedType.isInterface() && !resolvedType.equals(ResolvedType.OBJECT)) {
ResolvedType superType = resolvedType.getSuperclass();
if (superType != null && !superType.isMissing()) {
if (!genericsAware && (superType.isParameterizedType() || superType.isGenericType())) {
superType = superType.getRawType();
}
recurseHierarchy(knowninterfaces, collector, superType, includeITDs, allowMissing, genericsAware);
}
}
ResolvedType[] interfaces = resolvedType.getDeclaredInterfaces();
for (int i = 0; i < interfaces.length; i++) {
ResolvedType iface = interfaces[i];
if (!genericsAware && (iface.isParameterizedType() || iface.isGenericType())) {
iface = iface.getRawType();
}
boolean shouldSkip = false;
for (int j = 0; j < resolvedType.interTypeMungers.size(); j++) {
ConcreteTypeMunger munger = resolvedType.interTypeMungers.get(j);
if (munger.getMunger() != null && munger.getMunger().getKind() == ResolvedTypeMunger.Parent
&& ((NewParentTypeMunger) munger.getMunger()).getNewParent().equals(iface)
) {
shouldSkip = true;
break;
}
}
if (!shouldSkip && !knowninterfaces.contains(iface.getSignature())) {
knowninterfaces.add(iface.getSignature());
if (allowMissing && iface.isMissing()) {
if (iface instanceof MissingResolvedTypeWithKnownSignature) {
((MissingResolvedTypeWithKnownSignature) iface).raiseWarningOnMissingInterfaceWhilstFindingMethods();
}
} else {
recurseHierarchy(knowninterfaces, collector, iface, includeITDs, allowMissing, genericsAware);
}
}
}
}
public ResolvedType[] getResolvedTypeParameters() {
if (resolvedTypeParams == null) {
resolvedTypeParams = world.resolve(typeParameters);
}
return resolvedTypeParams;
}
public ResolvedMember lookupField(Member field) {
Iterator<ResolvedMember> i = getFields();
while (i.hasNext()) {
ResolvedMember resolvedMember = i.next();
if (matches(resolvedMember, field)) {
return resolvedMember;
}
if (resolvedMember.hasBackingGenericMember() && field.getName().equals(resolvedMember.getName())) {
if (matches(resolvedMember.getBackingGenericMember(), field)) {
return resolvedMember;
}
}
}
return null;
}
public ResolvedMember lookupMethod(Member m) {
List<ResolvedType> typesTolookat = new ArrayList<ResolvedType>();
typesTolookat.add(this);
int pos = 0;
while (pos < typesTolookat.size()) {
ResolvedType type = typesTolookat.get(pos++);
if (!type.isMissing()) {
ResolvedMember[] methods = type.getDeclaredMethods();
if (methods != null) {
for (int i = 0; i < methods.length; i++) {
ResolvedMember method = methods[i];
if (matches(method, m)) {
return method;
}
if (method.hasBackingGenericMember() && m.getName().equals(method.getName())) {
if (matches(method.getBackingGenericMember(), m)) {
return method;
}
}
}
}
}
ResolvedType superclass = type.getSuperclass();
if (superclass != null) {
typesTolookat.add(superclass);
}
ResolvedType[] superinterfaces = type.getDeclaredInterfaces();
if (superinterfaces != null) {
for (int i = 0; i < superinterfaces.length; i++) {
ResolvedType interf = superinterfaces[i];
if (!typesTolookat.contains(interf)) {
typesTolookat.add(interf);
}
}
}
}
return null;
}
public ResolvedMember lookupMethodInITDs(Member member) {
for (ConcreteTypeMunger typeTransformer : interTypeMungers) {
if (matches(typeTransformer.getSignature(), member)) {
return typeTransformer.getSignature();
}
}
return null;
}
private ResolvedMember lookupMember(Member m, ResolvedMember[] a) {
for (int i = 0; i < a.length; i++) {
ResolvedMember f = a[i];
if (matches(f, m)) {
return f;
}
}
return null;
}
public ResolvedMember lookupResolvedMember(ResolvedMember aMember, boolean allowMissing, boolean eraseGenerics) {
Iterator<ResolvedMember> toSearch = null;
ResolvedMember found = null;
if ((aMember.getKind() == Member.METHOD) || (aMember.getKind() == Member.CONSTRUCTOR)) {
toSearch = getMethodsIncludingIntertypeDeclarations(!eraseGenerics, true);
} else if (aMember.getKind()==Member.ADVICE) {
return null;
} else {
assert aMember.getKind() == Member.FIELD;
toSearch = getFields();
}
while (toSearch.hasNext()) {
ResolvedMember candidate = toSearch.next();
if (eraseGenerics) {
if (candidate.hasBackingGenericMember()) {
candidate = candidate.getBackingGenericMember();
}
}
if (candidate.matches(aMember, eraseGenerics)) {
found = candidate;
break;
}
}
return found;
}
public static boolean matches(Member m1, Member m2) {
if (m1 == null) {
return m2 == null;
}
if (m2 == null) {
return false;
}
boolean equalNames = m1.getName().equals(m2.getName());
if (!equalNames) {
return false;
}
boolean equalSignatures = m1.getSignature().equals(m2.getSignature());
if (equalSignatures) {
return true;
}
boolean equalCovariantSignatures = m1.getParameterSignature().equals(m2.getParameterSignature());
if (equalCovariantSignatures) {
return true;
}
return false;
}
public static boolean conflictingSignature(Member m1, Member m2) {
return conflictingSignature(m1,m2,true);
}
public static boolean conflictingSignature(Member m1, Member m2, boolean v2itds) {
if (m1 == null || m2 == null) {
return false;
}
if (!m1.getName().equals(m2.getName())) {
return false;
}
if (m1.getKind() != m2.getKind()) {
return false;
}
if (m1.getKind() == Member.FIELD) {
if (v2itds) {
if (m1.getDeclaringType().equals(m2.getDeclaringType())) {
return true;
}
} else {
return m1.getDeclaringType().equals(m2.getDeclaringType());
}
} else if (m1.getKind() == Member.POINTCUT) {
return true;
}
UnresolvedType[] p1 = m1.getGenericParameterTypes();
UnresolvedType[] p2 = m2.getGenericParameterTypes();
if (p1 == null) {
p1 = m1.getParameterTypes();
}
if (p2 == null) {
p2 = m2.getParameterTypes();
}
int n = p1.length;
if (n != p2.length) {
return false;
}
for (int i = 0; i < n; i++) {
if (!p1[i].equals(p2[i])) {
return false;
}
}
return true;
}
public Iterator<ResolvedMember> getPointcuts() {
final Iterators.Filter<ResolvedType> dupFilter = Iterators.dupFilter();
Iterators.Getter<ResolvedType, ResolvedType> typeGetter = new Iterators.Getter<ResolvedType, ResolvedType>() {
@Override
public Iterator<ResolvedType> get(ResolvedType o) {
return dupFilter.filter(o.getDirectSupertypes());
}
};
return Iterators.mapOver(Iterators.recur(this, typeGetter), PointcutGetterInstance);
}
public ResolvedPointcutDefinition findPointcut(String name) {
for (Iterator<ResolvedMember> i = getPointcuts(); i.hasNext();) {
ResolvedPointcutDefinition f = (ResolvedPointcutDefinition) i.next();
if (f != null && name.equals(f.getName())) {
return f;
}
}
if (!getOutermostType().equals(this)) {
ResolvedType outerType = getOutermostType().resolve(world);
ResolvedPointcutDefinition rpd = outerType.findPointcut(name);
return rpd;
}
return null;
}
public CrosscuttingMembers crosscuttingMembers;
public CrosscuttingMembers collectCrosscuttingMembers(boolean shouldConcretizeIfNeeded) {
crosscuttingMembers = new CrosscuttingMembers(this, shouldConcretizeIfNeeded);
if (getPerClause() == null) {
return crosscuttingMembers;
}
crosscuttingMembers.setPerClause(getPerClause());
crosscuttingMembers.addShadowMungers(collectShadowMungers());
crosscuttingMembers.addTypeMungers(getTypeMungers());
crosscuttingMembers.addDeclares(collectDeclares(!this.doesNotExposeShadowMungers()));
crosscuttingMembers.addPrivilegedAccesses(getPrivilegedAccesses());
return crosscuttingMembers;
}
public final List<Declare> collectDeclares(boolean includeAdviceLike) {
if (!this.isAspect()) {
return Collections.emptyList();
}
List<Declare> ret = new ArrayList<Declare>();
if (!this.isAbstract()) {
final Iterators.Filter<ResolvedType> dupFilter = Iterators.dupFilter();
Iterators.Getter<ResolvedType, ResolvedType> typeGetter = new Iterators.Getter<ResolvedType, ResolvedType>() {
@Override
public Iterator<ResolvedType> get(ResolvedType o) {
return dupFilter.filter((o).getDirectSupertypes());
}
};
Iterator<ResolvedType> typeIterator = Iterators.recur(this, typeGetter);
while (typeIterator.hasNext()) {
ResolvedType ty = typeIterator.next();
for (Iterator<Declare> i = ty.getDeclares().iterator(); i.hasNext();) {
Declare dec = i.next();
if (dec.isAdviceLike()) {
if (includeAdviceLike) {
ret.add(dec);
}
} else {
ret.add(dec);
}
}
}
}
return ret;
}
private final List<ShadowMunger> collectShadowMungers() {
if (!this.isAspect() || this.isAbstract() || this.doesNotExposeShadowMungers()) {
return Collections.emptyList();
}
List<ShadowMunger> acc = new ArrayList<ShadowMunger>();
final Iterators.Filter<ResolvedType> dupFilter = Iterators.dupFilter();
Iterators.Getter<ResolvedType, ResolvedType> typeGetter = new Iterators.Getter<ResolvedType, ResolvedType>() {
@Override
public Iterator<ResolvedType> get(ResolvedType o) {
return dupFilter.filter((o).getDirectSupertypes());
}
};
Iterator<ResolvedType> typeIterator = Iterators.recur(this, typeGetter);
while (typeIterator.hasNext()) {
ResolvedType ty = typeIterator.next();
acc.addAll(ty.getDeclaredShadowMungers());
}
return acc;
}
public void addParent(ResolvedType newParent) {
}
protected boolean doesNotExposeShadowMungers() {
return false;
}
public PerClause getPerClause() {
return null;
}
public Collection<Declare> getDeclares() {
return Collections.emptyList();
}
public Collection<ConcreteTypeMunger> getTypeMungers() {
return Collections.emptyList();
}
public Collection<ResolvedMember> getPrivilegedAccesses() {
return Collections.emptyList();
}
public final boolean isInterface() {
return Modifier.isInterface(getModifiers());
}
public final boolean isAbstract() {
return Modifier.isAbstract(getModifiers());
}
public boolean isClass() {
return false;
}
public boolean isAspect() {
return false;
}
public boolean isAnnotationStyleAspect() {
return false;
}
public boolean isEnum() {
return false;
}
public boolean isAnnotation() {
return false;
}
public boolean isAnonymous() {
return false;
}
public boolean isNested() {
return false;
}
public ResolvedType getOuterClass() {
return null;
}
public void addAnnotation(AnnotationAJ annotationX) {
throw new RuntimeException("ResolvedType.addAnnotation() should never be called");
}
public AnnotationAJ[] getAnnotations() {
throw new RuntimeException("ResolvedType.getAnnotations() should never be called");
}
public boolean hasAnnotations() {
throw new RuntimeException("ResolvedType.getAnnotations() should never be called");
}
public boolean canAnnotationTargetType() {
return false;
}
public AnnotationTargetKind[] getAnnotationTargetKinds() {
return null;
}
public boolean isAnnotationWithRuntimeRetention() {
return false;
}
public boolean isSynthetic() {
return signature.indexOf("$ajc") != -1;
}
public final boolean isFinal() {
return Modifier.isFinal(getModifiers());
}
protected Map<String, UnresolvedType> getMemberParameterizationMap() {
if (!isParameterizedType()) {
return Collections.emptyMap();
}
TypeVariable[] tvs = getGenericType().getTypeVariables();
Map<String, UnresolvedType> parameterizationMap = new HashMap<String, UnresolvedType>();
if (tvs.length != typeParameters.length) {
world.getMessageHandler()
.handleMessage(
new Message("Mismatch when building parameterization map. For type '" + this.signature +
"' expecting "+tvs.length+":["+toString(tvs)+"] type parameters but found "+typeParameters.length+
":["+toString(typeParameters)+"]", "",
IMessage.ERROR, getSourceLocation(), null,
new ISourceLocation[] { getSourceLocation() }));
} else {
for (int i = 0; i < tvs.length; i++) {
parameterizationMap.put(tvs[i].getName(), typeParameters[i]);
}
}
return parameterizationMap;
}
private String toString(UnresolvedType[] typeParameters) {
StringBuilder s = new StringBuilder();
for (UnresolvedType tv: typeParameters) {
s.append(tv.getSignature()).append(" ");
}
return s.toString().trim();
}
private String toString(TypeVariable[] tvs) {
StringBuilder s = new StringBuilder();
for (TypeVariable tv: tvs) {
s.append(tv.getName()).append(" ");
}
return s.toString().trim();
}
public List<ShadowMunger> getDeclaredAdvice() {
List<ShadowMunger> l = new ArrayList<ShadowMunger>();
ResolvedMember[] methods = getDeclaredMethods();
if (isParameterizedType()) {
methods = getGenericType().getDeclaredMethods();
}
Map<String, UnresolvedType> typeVariableMap = getAjMemberParameterizationMap();
for (int i = 0, len = methods.length; i < len; i++) {
ShadowMunger munger = methods[i].getAssociatedShadowMunger();
if (munger != null) {
if (ajMembersNeedParameterization()) {
munger = munger.parameterizeWith(this, typeVariableMap);
if (munger instanceof Advice) {
Advice advice = (Advice) munger;
UnresolvedType[] ptypes = methods[i].getGenericParameterTypes();
UnresolvedType[] newPTypes = new UnresolvedType[ptypes.length];
for (int j = 0; j < ptypes.length; j++) {
if (ptypes[j] instanceof TypeVariableReferenceType) {
TypeVariableReferenceType tvrt = (TypeVariableReferenceType) ptypes[j];
if (typeVariableMap.containsKey(tvrt.getTypeVariable().getName())) {
newPTypes[j] = typeVariableMap.get(tvrt.getTypeVariable().getName());
} else {
newPTypes[j] = ptypes[j];
}
} else {
newPTypes[j] = ptypes[j];
}
}
advice.setBindingParameterTypes(newPTypes);
}
}
munger.setDeclaringType(this);
l.add(munger);
}
}
return l;
}
public List<ShadowMunger> getDeclaredShadowMungers() {
return getDeclaredAdvice();
}
public ResolvedMember[] getDeclaredJavaFields() {
return filterInJavaVisible(getDeclaredFields());
}
public ResolvedMember[] getDeclaredJavaMethods() {
return filterInJavaVisible(getDeclaredMethods());
}
private ResolvedMember[] filterInJavaVisible(ResolvedMember[] ms) {
List<ResolvedMember> l = new ArrayList<ResolvedMember>();
for (int i = 0, len = ms.length; i < len; i++) {
if (!ms[i].isAjSynthetic() && ms[i].getAssociatedShadowMunger() == null) {
l.add(ms[i]);
}
}
return l.toArray(new ResolvedMember[l.size()]);
}
public abstract ISourceContext getSourceContext();
public static final ResolvedType[] NONE = new ResolvedType[0];
public static final ResolvedType[] EMPTY_ARRAY = NONE;
public static final Missing MISSING = new Missing();
public static ResolvedType makeArray(ResolvedType type, int dim) {
if (dim == 0) {
return type;
}
ResolvedType array = new ArrayReferenceType("[" + type.getSignature(), "[" + type.getErasureSignature(), type.getWorld(),
type);
return makeArray(array, dim - 1);
}
static class Primitive extends ResolvedType {
private final int size;
private final int index;
Primitive(String signature, int size, int index) {
super(signature, null);
this.size = size;
this.index = index;
this.typeKind = TypeKind.PRIMITIVE;
}
@Override
public final int getSize() {
return size;
}
@Override
public final int getModifiers() {
return Modifier.PUBLIC | Modifier.FINAL;
}
@Override
public final boolean isPrimitiveType() {
return true;
}
@Override
public boolean hasAnnotation(UnresolvedType ofType) {
return false;
}
@Override
public final boolean isAssignableFrom(ResolvedType other) {
if (!other.isPrimitiveType()) {
if (!world.isInJava5Mode()) {
return false;
}
return validBoxing.contains(this.getSignature() + other.getSignature());
}
return assignTable[((Primitive) other).index][index];
}
@Override
public final boolean isAssignableFrom(ResolvedType other, boolean allowMissing) {
return isAssignableFrom(other);
}
@Override
public final boolean isCoerceableFrom(ResolvedType other) {
if (this == other) {
return true;
}
if (!other.isPrimitiveType()) {
return false;
}
if (index > 6 || ((Primitive) other).index > 6) {
return false;
}
return true;
}
@Override
public ResolvedType resolve(World world) {
if (this.world != world) {
throw new IllegalStateException();
}
this.world = world;
return super.resolve(world);
}
@Override
public final boolean needsNoConversionFrom(ResolvedType other) {
if (!other.isPrimitiveType()) {
return false;
}
return noConvertTable[((Primitive) other).index][index];
}
private static final boolean[][] assignTable = {
{ true, true, true, true, true, true, true, false, false },
{ false, true, true, true, true, true, false, false, false },
{ false, false, true, false, false, false, false, false, false },
{ false, false, true, true, false, false, false, false, false },
{ false, false, true, true, true, true, false, false, false },
{ false, false, true, true, false, true, false, false, false },
{ false, false, true, true, true, true, true, false, false },
{ false, false, false, false, false, false, false, true, false },
{ false, false, false, false, false, false, false, false, true },
};
private static final boolean[][] noConvertTable = {
{ true, true, false, false, true, false, true, false, false },
{ false, true, false, false, true, false, false, false, false },
{ false, false, true, false, false, false, false, false, false },
{ false, false, false, true, false, false, false, false, false },
{ false, false, false, false, true, false, false, false, false },
{ false, false, false, false, false, true, false, false, false },
{ false, false, false, false, true, false, true, false, false },
{ false, false, false, false, false, false, false, true, false },
{ false, false, false, false, false, false, false, false, true },
};
@Override
public final ResolvedMember[] getDeclaredFields() {
return ResolvedMember.NONE;
}
@Override
public final ResolvedMember[] getDeclaredMethods() {
return ResolvedMember.NONE;
}
@Override
public final ResolvedType[] getDeclaredInterfaces() {
return ResolvedType.NONE;
}
@Override
public final ResolvedMember[] getDeclaredPointcuts() {
return ResolvedMember.NONE;
}
@Override
public final ResolvedType getSuperclass() {
return null;
}
@Override
public ISourceContext getSourceContext() {
return null;
}
}
static class Missing extends ResolvedType {
Missing() {
super(MISSING_NAME, null);
}
@Override
public final String getName() {
return MISSING_NAME;
}
@Override
public final boolean isMissing() {
return true;
}
@Override
public boolean hasAnnotation(UnresolvedType ofType) {
return false;
}
@Override
public final ResolvedMember[] getDeclaredFields() {
return ResolvedMember.NONE;
}
@Override
public final ResolvedMember[] getDeclaredMethods() {
return ResolvedMember.NONE;
}
@Override
public final ResolvedType[] getDeclaredInterfaces() {
return ResolvedType.NONE;
}
@Override
public final ResolvedMember[] getDeclaredPointcuts() {
return ResolvedMember.NONE;
}
@Override
public final ResolvedType getSuperclass() {
return null;
}
@Override
public final int getModifiers() {
return 0;
}
@Override
public final boolean isAssignableFrom(ResolvedType other) {
return false;
}
@Override
public final boolean isAssignableFrom(ResolvedType other, boolean allowMissing) {
return false;
}
@Override
public final boolean isCoerceableFrom(ResolvedType other) {
return false;
}
@Override
public boolean needsNoConversionFrom(ResolvedType other) {
return false;
}
@Override
public ISourceContext getSourceContext() {
return null;
}
}
public ResolvedMember lookupMemberNoSupers(Member member) {
ResolvedMember ret = lookupDirectlyDeclaredMemberNoSupers(member);
if (ret == null && interTypeMungers != null) {
for (ConcreteTypeMunger tm : interTypeMungers) {
if (matches(tm.getSignature(), member)) {
return tm.getSignature();
}
}
}
return ret;
}
public ResolvedMember lookupMemberWithSupersAndITDs(Member member) {
ResolvedMember ret = lookupMemberNoSupers(member);
if (ret != null) {
return ret;
}
ResolvedType supert = getSuperclass();
while (ret == null && supert != null) {
ret = supert.lookupMemberNoSupers(member);
if (ret == null) {
supert = supert.getSuperclass();
}
}
return ret;
}
public ResolvedMember lookupDirectlyDeclaredMemberNoSupers(Member member) {
ResolvedMember ret;
if (member.getKind() == Member.FIELD) {
ret = lookupMember(member, getDeclaredFields());
} else {
ret = lookupMember(member, getDeclaredMethods());
}
return ret;
}
public ResolvedMember lookupMemberIncludingITDsOnInterfaces(Member member) {
return lookupMemberIncludingITDsOnInterfaces(member, this);
}
private ResolvedMember lookupMemberIncludingITDsOnInterfaces(Member member, ResolvedType onType) {
ResolvedMember ret = onType.lookupMemberNoSupers(member);
if (ret != null) {
return ret;
} else {
ResolvedType superType = onType.getSuperclass();
if (superType != null) {
ret = lookupMemberIncludingITDsOnInterfaces(member, superType);
}
if (ret == null) {
ResolvedType[] superInterfaces = onType.getDeclaredInterfaces();
for (int i = 0; i < superInterfaces.length; i++) {
ret = superInterfaces[i].lookupMethodInITDs(member);
if (ret != null) {
return ret;
}
}
}
}
return ret;
}
protected List<ConcreteTypeMunger> interTypeMungers = new ArrayList<ConcreteTypeMunger>();
public List<ConcreteTypeMunger> getInterTypeMungers() {
return interTypeMungers;
}
public List<ConcreteTypeMunger> getInterTypeParentMungers() {
List<ConcreteTypeMunger> l = new ArrayList<ConcreteTypeMunger>();
for (ConcreteTypeMunger element : interTypeMungers) {
if (element.getMunger() instanceof NewParentTypeMunger) {
l.add(element);
}
}
return l;
}
public List<ConcreteTypeMunger> getInterTypeMungersIncludingSupers() {
ArrayList<ConcreteTypeMunger> ret = new ArrayList<ConcreteTypeMunger>();
collectInterTypeMungers(ret);
return ret;
}
public List<ConcreteTypeMunger> getInterTypeParentMungersIncludingSupers() {
ArrayList<ConcreteTypeMunger> ret = new ArrayList<ConcreteTypeMunger>();
collectInterTypeParentMungers(ret);
return ret;
}
private void collectInterTypeParentMungers(List<ConcreteTypeMunger> collector) {
for (Iterator<ResolvedType> iter = getDirectSupertypes(); iter.hasNext();) {
ResolvedType superType = iter.next();
superType.collectInterTypeParentMungers(collector);
}
collector.addAll(getInterTypeParentMungers());
}
protected void collectInterTypeMungers(List<ConcreteTypeMunger> collector) {
for (Iterator<ResolvedType> iter = getDirectSupertypes(); iter.hasNext();) {
ResolvedType superType = iter.next();
if (superType == null) {
throw new BCException("UnexpectedProblem: a supertype in the hierarchy for " + this.getName() + " is null");
}
superType.collectInterTypeMungers(collector);
}
outer: for (Iterator<ConcreteTypeMunger> iter1 = collector.iterator(); iter1.hasNext();) {
ConcreteTypeMunger superMunger = iter1.next();
if (superMunger.getSignature() == null) {
continue;
}
if (!superMunger.getSignature().isAbstract()) {
continue;
}
for (ConcreteTypeMunger myMunger : getInterTypeMungers()) {
if (conflictingSignature(myMunger.getSignature(), superMunger.getSignature())) {
iter1.remove();
continue outer;
}
}
if (!superMunger.getSignature().isPublic()) {
continue;
}
for (Iterator<ResolvedMember> iter = getMethods(true, true); iter.hasNext();) {
ResolvedMember method = iter.next();
if (conflictingSignature(method, superMunger.getSignature())) {
iter1.remove();
continue outer;
}
}
}
collector.addAll(getInterTypeMungers());
}
public void checkInterTypeMungers() {
if (isAbstract()) {
return;
}
boolean itdProblem = false;
for (ConcreteTypeMunger munger : getInterTypeMungersIncludingSupers()) {
itdProblem = checkAbstractDeclaration(munger) || itdProblem;
}
if (itdProblem) {
return;
}
for (ConcreteTypeMunger munger : getInterTypeMungersIncludingSupers()) {
if (munger.getSignature() != null && munger.getSignature().isAbstract() && munger.getMunger().getKind()!=ResolvedTypeMunger.PrivilegedAccess) {
if (munger.getMunger().getKind() == ResolvedTypeMunger.MethodDelegate2) {
} else {
world.getMessageHandler()
.handleMessage(
new Message("must implement abstract inter-type declaration: " + munger.getSignature(), "",
IMessage.ERROR, getSourceLocation(), null,
new ISourceLocation[] { getMungerLocation(munger) }));
}
}
}
}
private boolean checkAbstractDeclaration(ConcreteTypeMunger munger) {
if (munger.getMunger() != null && (munger.getMunger() instanceof NewMethodTypeMunger)) {
ResolvedMember itdMember = munger.getSignature();
ResolvedType onType = itdMember.getDeclaringType().resolve(world);
if (onType.isInterface() && itdMember.isAbstract() && !itdMember.isPublic()) {
world.getMessageHandler().handleMessage(
new Message(WeaverMessages.format(WeaverMessages.ITD_ABSTRACT_MUST_BE_PUBLIC_ON_INTERFACE,
munger.getSignature(), onType), "", Message.ERROR, getSourceLocation(), null,
new ISourceLocation[] { getMungerLocation(munger) }));
return true;
}
}
return false;
}
private ISourceLocation getMungerLocation(ConcreteTypeMunger munger) {
ISourceLocation sloc = munger.getSourceLocation();
if (sloc == null) {
sloc = munger.getAspectType().getSourceLocation();
}
return sloc;
}
public ResolvedType getDeclaringType() {
if (isArray()) {
return null;
}
if (isNested() || isAnonymous()) {
return getOuterClass();
}
return null;
}
public static boolean isVisible(int modifiers, ResolvedType targetType, ResolvedType fromType) {
if (Modifier.isPublic(modifiers)) {
return true;
} else if (Modifier.isPrivate(modifiers)) {
return targetType.getOutermostType().equals(fromType.getOutermostType());
} else if (Modifier.isProtected(modifiers)) {
return samePackage(targetType, fromType) || targetType.isAssignableFrom(fromType);
} else {
return samePackage(targetType, fromType);
}
}
private static boolean samePackage(ResolvedType targetType, ResolvedType fromType) {
String p1 = targetType.getPackageName();
String p2 = fromType.getPackageName();
if (p1 == null) {
return p2 == null;
}
if (p2 == null) {
return false;
}
return p1.equals(p2);
}
private boolean genericTypeEquals(ResolvedType other) {
ResolvedType rt = other;
if (rt.isParameterizedType() || rt.isRawType()) {
rt.getGenericType();
}
if (((isParameterizedType() || isRawType()) && getGenericType().equals(rt)) || (this.equals(other))) {
return true;
}
return false;
}
public ResolvedType discoverActualOccurrenceOfTypeInHierarchy(ResolvedType lookingFor) {
if (!lookingFor.isGenericType()) {
throw new BCException("assertion failed: method should only be called with generic type, but " + lookingFor + " is "
+ lookingFor.typeKind);
}
if (this.equals(ResolvedType.OBJECT)) {
return null;
}
if (genericTypeEquals(lookingFor)) {
return this;
}
ResolvedType superT = getSuperclass();
if (superT.genericTypeEquals(lookingFor)) {
return superT;
}
ResolvedType[] superIs = getDeclaredInterfaces();
for (int i = 0; i < superIs.length; i++) {
ResolvedType superI = superIs[i];
if (superI.genericTypeEquals(lookingFor)) {
return superI;
}
ResolvedType checkTheSuperI = superI.discoverActualOccurrenceOfTypeInHierarchy(lookingFor);
if (checkTheSuperI != null) {
return checkTheSuperI;
}
}
return superT.discoverActualOccurrenceOfTypeInHierarchy(lookingFor);
}
public ConcreteTypeMunger fillInAnyTypeParameters(ConcreteTypeMunger munger) {
boolean debug = false;
ResolvedMember member = munger.getSignature();
if (munger.isTargetTypeParameterized()) {
if (debug) {
System.err.println("Processing attempted parameterization of " + munger + " targetting type " + this);
}
if (debug) {
System.err.println(" This type is " + this + " (" + typeKind + ")");
}
if (debug) {
System.err.println(" Signature that needs parameterizing: " + member);
}
ResolvedType onTypeResolved = world.resolve(member.getDeclaringType());
ResolvedType onType = onTypeResolved.getGenericType();
if (onType == null) {
getWorld().getMessageHandler().handleMessage(
MessageUtil.error("The target type for the intertype declaration is not generic",
munger.getSourceLocation()));
return munger;
}
member.resolve(world);
if (debug) {
System.err.println(" Actual target ontype: " + onType + " (" + onType.typeKind + ")");
}
ResolvedType actualTarget = discoverActualOccurrenceOfTypeInHierarchy(onType);
if (actualTarget == null) {
throw new BCException("assertion failed: asked " + this + " for occurrence of " + onType + " in its hierarchy??");
}
if (!actualTarget.isGenericType()) {
if (debug) {
System.err.println("Occurrence in " + this + " is actually " + actualTarget + " (" + actualTarget.typeKind
+ ")");
}
}
munger = munger.parameterizedFor(actualTarget);
if (debug) {
System.err.println("New sig: " + munger.getSignature());
}
if (debug) {
System.err.println("=====================================");
}
}
return munger;
}
public void addInterTypeMunger(ConcreteTypeMunger munger, boolean isDuringCompilation) {
ResolvedMember sig = munger.getSignature();
bits = (bits & ~MungersAnalyzed);
if (sig == null || munger.getMunger() == null || munger.getMunger().getKind() == ResolvedTypeMunger.PrivilegedAccess) {
interTypeMungers.add(munger);
return;
}
munger = fillInAnyTypeParameters(munger);
sig = munger.getSignature();
if (sig.getKind() == Member.METHOD) {
if (clashesWithExistingMember(munger, getMethods(true, false))) {
return;
}
if (this.isInterface()) {
if (clashesWithExistingMember(munger, Arrays.asList(world.getCoreType(OBJECT).getDeclaredMethods()).iterator())) {
return;
}
}
} else if (sig.getKind() == Member.FIELD) {
if (clashesWithExistingMember(munger, Arrays.asList(getDeclaredFields()).iterator())) {
return;
}
if (!isDuringCompilation) {
ResolvedTypeMunger thisRealMunger = munger.getMunger();
if (thisRealMunger instanceof NewFieldTypeMunger) {
NewFieldTypeMunger newFieldTypeMunger = (NewFieldTypeMunger) thisRealMunger;
if (newFieldTypeMunger.version == NewFieldTypeMunger.VersionTwo) {
String thisRealMungerSignatureName = newFieldTypeMunger.getSignature().getName();
for (ConcreteTypeMunger typeMunger : interTypeMungers) {
if (typeMunger.getMunger() instanceof NewFieldTypeMunger) {
if (typeMunger.getSignature().getKind() == Member.FIELD) {
NewFieldTypeMunger existing = (NewFieldTypeMunger) typeMunger.getMunger();
if (existing.getSignature().getName().equals(thisRealMungerSignatureName)
&& existing.version == NewFieldTypeMunger.VersionTwo
&& existing.getSignature().getDeclaringType()
.equals(newFieldTypeMunger.getSignature().getDeclaringType())) {
StringBuffer sb = new StringBuffer();
sb.append("Cannot handle two aspects both attempting to use new style ITDs for the same named field ");
sb.append("on the same target type. Please recompile at least one aspect with '-Xset:itdVersion=1'.");
sb.append(" Aspects involved: " + munger.getAspectType().getName() + " and "
+ typeMunger.getAspectType().getName() + ".");
sb.append(" Field is named '" + existing.getSignature().getName() + "'");
getWorld().getMessageHandler().handleMessage(
new Message(sb.toString(), getSourceLocation(), true));
return;
}
}
}
}
}
}
}
} else {
if (clashesWithExistingMember(munger, Arrays.asList(getDeclaredMethods()).iterator())) {
return;
}
}
boolean needsAdding =true;
boolean needsToBeAddedEarlier =false;
for (Iterator<ConcreteTypeMunger> i = interTypeMungers.iterator(); i.hasNext();) {
ConcreteTypeMunger existingMunger = i.next();
boolean v2itds = munger.getSignature().getKind()== Member.FIELD && (munger.getMunger() instanceof NewFieldTypeMunger) && ((NewFieldTypeMunger)munger.getMunger()).version==NewFieldTypeMunger.VersionTwo;
if (conflictingSignature(existingMunger.getSignature(), munger.getSignature(),v2itds)) {
if (isVisible(munger.getSignature().getModifiers(), munger.getAspectType(), existingMunger.getAspectType())) {
int c = compareMemberPrecedence(sig, existingMunger.getSignature());
if (c == 0) {
c = getWorld().compareByPrecedenceAndHierarchy(munger.getAspectType(), existingMunger.getAspectType());
}
if (c < 0) {
checkLegalOverride(munger.getSignature(), existingMunger.getSignature(), 0x11, null);
needsAdding = false;
if (munger.getSignature().getKind()== Member.FIELD && munger.getSignature().getDeclaringType().resolve(world).isInterface() && ((NewFieldTypeMunger)munger.getMunger()).version==NewFieldTypeMunger.VersionTwo) {
needsAdding=true;
}
break;
} else if (c > 0) {
checkLegalOverride(existingMunger.getSignature(), munger.getSignature(), 0x11, null);
if (existingMunger.getSignature().getKind()==Member.FIELD &&
existingMunger.getSignature().getDeclaringType().resolve(world).isInterface()
&& ((NewFieldTypeMunger)existingMunger.getMunger()).version==NewFieldTypeMunger.VersionTwo) {
needsToBeAddedEarlier=true;
} else {
i.remove();
}
break;
} else {
interTypeConflictError(munger, existingMunger);
interTypeConflictError(existingMunger, munger);
return;
}
}
}
}
if (needsAdding) {
if (!needsToBeAddedEarlier) {
interTypeMungers.add(munger);
} else {
interTypeMungers.add(0,munger);
}
}
}
private boolean clashesWithExistingMember(ConcreteTypeMunger typeTransformer, Iterator<ResolvedMember> existingMembers) {
ResolvedMember typeTransformerSignature = typeTransformer.getSignature();
ResolvedTypeMunger rtm = typeTransformer.getMunger();
boolean v2itds = true;
if (rtm instanceof NewFieldTypeMunger && ((NewFieldTypeMunger)rtm).version==NewFieldTypeMunger.VersionOne) {
v2itds = false;
}
while (existingMembers.hasNext()) {
ResolvedMember existingMember = existingMembers.next();
if (existingMember.isBridgeMethod()) {
continue;
}
if (conflictingSignature(existingMember, typeTransformerSignature,v2itds)) {
if (isVisible(existingMember.getModifiers(), this, typeTransformer.getAspectType())) {
int c = compareMemberPrecedence(typeTransformerSignature, existingMember);
if (c < 0) {
ResolvedType typeTransformerTargetType = typeTransformerSignature.getDeclaringType().resolve(world);
if (typeTransformerTargetType.isInterface()) {
ResolvedType existingMemberType = existingMember.getDeclaringType().resolve(world);
if ((rtm instanceof NewMethodTypeMunger) && !typeTransformerTargetType.equals(existingMemberType)) {
if (Modifier.isPrivate(typeTransformerSignature.getModifiers()) &&
Modifier.isPublic(existingMember.getModifiers())) {
world.getMessageHandler().handleMessage(new Message("private intertype declaration '"+typeTransformerSignature.toString()+"' clashes with public member '"+existingMember.toString()+"'",existingMember.getSourceLocation(),true));
}
}
}
checkLegalOverride(typeTransformerSignature, existingMember, 0x10, typeTransformer.getAspectType());
return true;
} else if (c > 0) {
checkLegalOverride(existingMember, typeTransformerSignature, 0x01, typeTransformer.getAspectType());
continue;
} else {
boolean sameReturnTypes = (existingMember.getReturnType().equals(typeTransformerSignature.getReturnType()));
if (sameReturnTypes) {
boolean isDuplicateOfPreviousITD = false;
ResolvedType declaringRt = existingMember.getDeclaringType().resolve(world);
WeaverStateInfo wsi = declaringRt.getWeaverState();
if (wsi != null) {
List<ConcreteTypeMunger> mungersAffectingThisType = wsi.getTypeMungers(declaringRt);
if (mungersAffectingThisType != null) {
for (Iterator<ConcreteTypeMunger> iterator = mungersAffectingThisType.iterator(); iterator
.hasNext() && !isDuplicateOfPreviousITD;) {
ConcreteTypeMunger ctMunger = iterator.next();
if (ctMunger.getSignature().equals(existingMember)
&& ctMunger.aspectType.equals(typeTransformer.getAspectType())) {
isDuplicateOfPreviousITD = true;
}
}
}
}
if (!isDuplicateOfPreviousITD) {
if (!(typeTransformerSignature.getName().equals("<init>") && existingMember.isDefaultConstructor())) {
String aspectName = typeTransformer.getAspectType().getName();
ISourceLocation typeTransformerLocation = typeTransformer.getSourceLocation();
ISourceLocation existingMemberLocation = existingMember.getSourceLocation();
String msg = WeaverMessages.format(WeaverMessages.ITD_MEMBER_CONFLICT, aspectName,
existingMember);
getWorld().getMessageHandler().handleMessage(new Message(msg, typeTransformerLocation, true));
if (existingMemberLocation != null) {
getWorld().getMessageHandler()
.handleMessage(new Message(msg, existingMemberLocation, true));
}
return true;
}
}
}
}
} else if (isDuplicateMemberWithinTargetType(existingMember, this, typeTransformerSignature)) {
getWorld().getMessageHandler().handleMessage(
MessageUtil.error(WeaverMessages.format(WeaverMessages.ITD_MEMBER_CONFLICT, typeTransformer
.getAspectType().getName(), existingMember), typeTransformer.getSourceLocation()));
return true;
}
}
}
return false;
}
private boolean isDuplicateMemberWithinTargetType(ResolvedMember existingMember, ResolvedType targetType,
ResolvedMember itdMember) {
if ((existingMember.isAbstract() || itdMember.isAbstract())) {
return false;
}
UnresolvedType declaringType = existingMember.getDeclaringType();
if (!targetType.equals(declaringType)) {
return false;
}
if (Modifier.isPrivate(itdMember.getModifiers())) {
return false;
}
if (itdMember.isPublic()) {
return true;
}
if (!targetType.getPackageName().equals(itdMember.getDeclaringType().getPackageName())) {
return false;
}
return true;
}
public boolean checkLegalOverride(ResolvedMember parent, ResolvedMember child, int transformerPosition, ResolvedType aspectType) {
if (Modifier.isFinal(parent.getModifiers())) {
if (transformerPosition == 0x10 && aspectType != null) {
ResolvedType nonItdDeclaringType = child.getDeclaringType().resolve(world);
WeaverStateInfo wsi = nonItdDeclaringType.getWeaverState();
if (wsi != null) {
List<ConcreteTypeMunger> transformersOnThisType = wsi.getTypeMungers(nonItdDeclaringType);
if (transformersOnThisType != null) {
for (ConcreteTypeMunger transformer : transformersOnThisType) {
if (transformer.aspectType.equals(aspectType)) {
if (parent.equalsApartFromDeclaringType(transformer.getSignature())) {
return true;
}
}
}
}
}
}
world.showMessage(Message.ERROR, WeaverMessages.format(WeaverMessages.CANT_OVERRIDE_FINAL_MEMBER, parent),
child.getSourceLocation(), null);
return false;
}
boolean incompatibleReturnTypes = false;
if (world.isInJava5Mode() && parent.getKind() == Member.METHOD) {
ResolvedType rtParentReturnType = parent.resolve(world).getGenericReturnType().resolve(world);
ResolvedType rtChildReturnType = child.resolve(world).getGenericReturnType().resolve(world);
incompatibleReturnTypes = !rtParentReturnType.isAssignableFrom(rtChildReturnType);
} else {
ResolvedType rtParentReturnType = parent.resolve(world).getGenericReturnType().resolve(world);
ResolvedType rtChildReturnType = child.resolve(world).getGenericReturnType().resolve(world);
incompatibleReturnTypes = !rtParentReturnType.equals(rtChildReturnType);
}
if (incompatibleReturnTypes) {
world.showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.ITD_RETURN_TYPE_MISMATCH, parent, child),
child.getSourceLocation(), parent.getSourceLocation());
return false;
}
if (parent.getKind() == Member.POINTCUT) {
UnresolvedType[] pTypes = parent.getParameterTypes();
UnresolvedType[] cTypes = child.getParameterTypes();
if (!Arrays.equals(pTypes, cTypes)) {
world.showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.ITD_PARAM_TYPE_MISMATCH, parent, child),
child.getSourceLocation(), parent.getSourceLocation());
return false;
}
}
if (isMoreVisible(parent.getModifiers(), child.getModifiers())) {
world.showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.ITD_VISIBILITY_REDUCTION, parent, child),
child.getSourceLocation(), parent.getSourceLocation());
return false;
}
ResolvedType[] childExceptions = world.resolve(child.getExceptions());
ResolvedType[] parentExceptions = world.resolve(parent.getExceptions());
ResolvedType runtimeException = world.resolve("java.lang.RuntimeException");
ResolvedType error = world.resolve("java.lang.Error");
outer: for (int i = 0, leni = childExceptions.length; i < leni; i++) {
if (runtimeException.isAssignableFrom(childExceptions[i])) {
continue;
}
if (error.isAssignableFrom(childExceptions[i])) {
continue;
}
for (int j = 0, lenj = parentExceptions.length; j < lenj; j++) {
if (parentExceptions[j].isAssignableFrom(childExceptions[i])) {
continue outer;
}
}
return false;
}
boolean parentStatic = Modifier.isStatic(parent.getModifiers());
boolean childStatic = Modifier.isStatic(child.getModifiers());
if (parentStatic && !childStatic) {
world.showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.ITD_OVERRIDDEN_STATIC, child, parent),
child.getSourceLocation(), null);
return false;
} else if (childStatic && !parentStatic) {
world.showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.ITD_OVERIDDING_STATIC, child, parent),
child.getSourceLocation(), null);
return false;
}
return true;
}
private int compareMemberPrecedence(ResolvedMember m1, ResolvedMember m2) {
if (Modifier.isProtected(m2.getModifiers()) && m2.getName().charAt(0) == 'c') {
UnresolvedType declaring = m2.getDeclaringType();
if (declaring != null) {
if (declaring.getName().equals("java.lang.Object") && m2.getName().equals("clone")) {
return +1;
}
}
}
if (Modifier.isAbstract(m1.getModifiers())) {
return -1;
}
if (Modifier.isAbstract(m2.getModifiers())) {
return +1;
}
if (m1.getDeclaringType().equals(m2.getDeclaringType())) {
return 0;
}
ResolvedType t1 = m1.getDeclaringType().resolve(world);
ResolvedType t2 = m2.getDeclaringType().resolve(world);
if (t1.isAssignableFrom(t2)) {
return -1;
}
if (t2.isAssignableFrom(t1)) {
return +1;
}
return 0;
}
public static boolean isMoreVisible(int m1, int m2) {
if (Modifier.isPrivate(m1)) {
return false;
}
if (isPackage(m1)) {
return Modifier.isPrivate(m2);
}
if (Modifier.isProtected(m1)) {
return (Modifier.isPrivate(m2) || isPackage(m2));
}
if (Modifier.isPublic(m1)) {
return !Modifier.isPublic(m2);
}
throw new RuntimeException("bad modifier: " + m1);
}
private static boolean isPackage(int i) {
return (0 == (i & (Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED)));
}
private void interTypeConflictError(ConcreteTypeMunger m1, ConcreteTypeMunger m2) {
getWorld().showMessage(
IMessage.ERROR,
WeaverMessages.format(WeaverMessages.ITD_CONFLICT, m1.getAspectType().getName(), m2.getSignature(), m2
.getAspectType().getName()), m2.getSourceLocation(), getSourceLocation());
}
public ResolvedMember lookupSyntheticMember(Member member) {
for (ConcreteTypeMunger m : interTypeMungers) {
ResolvedMember ret = m.getMatchingSyntheticMember(member);
if (ret != null) {
return ret;
}
}
if (world.isJoinpointArrayConstructionEnabled() && this.isArray()) {
if (member.getKind() == Member.CONSTRUCTOR) {
ResolvedMemberImpl ret = new ResolvedMemberImpl(Member.CONSTRUCTOR, this, Modifier.PUBLIC, UnresolvedType.VOID,
"<init>", world.resolve(member.getParameterTypes()));
int count = ret.getParameterTypes().length;
String[] paramNames = new String[count];
for (int i = 0; i < count; i++) {
paramNames[i] = new StringBuffer("dim").append(i).toString();
}
ret.setParameterNames(paramNames);
return ret;
}
}
return null;
}
static class SuperClassWalker implements Iterator<ResolvedType> {
private ResolvedType curr;
private SuperInterfaceWalker iwalker;
private boolean wantGenerics;
public SuperClassWalker(ResolvedType type, SuperInterfaceWalker iwalker, boolean genericsAware) {
this.curr = type;
this.iwalker = iwalker;
this.wantGenerics = genericsAware;
}
@Override
public boolean hasNext() {
return curr != null;
}
@Override
public ResolvedType next() {
ResolvedType ret = curr;
if (!wantGenerics && ret.isParameterizedOrGenericType()) {
ret = ret.getRawType();
}
iwalker.push(ret);
curr = curr.getSuperclass();
return ret;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
}
static class SuperInterfaceWalker implements Iterator<ResolvedType> {
private Getter<ResolvedType, ResolvedType> ifaceGetter;
Iterator<ResolvedType> delegate = null;
public Queue<ResolvedType> toPersue = new LinkedList<ResolvedType>();
public Set<ResolvedType> visited = new HashSet<ResolvedType>();
SuperInterfaceWalker(Iterators.Getter<ResolvedType, ResolvedType> ifaceGetter) {
this.ifaceGetter = ifaceGetter;
}
SuperInterfaceWalker(Iterators.Getter<ResolvedType, ResolvedType> ifaceGetter, ResolvedType interfaceType) {
this.ifaceGetter = ifaceGetter;
this.delegate = Iterators.one(interfaceType);
}
@Override
public boolean hasNext() {
if (delegate == null || !delegate.hasNext()) {
if (toPersue.isEmpty()) {
return false;
}
do {
ResolvedType next = toPersue.remove();
visited.add(next);
delegate = ifaceGetter.get(next);
} while (!delegate.hasNext() && !toPersue.isEmpty());
}
return delegate.hasNext();
}
public void push(ResolvedType ret) {
toPersue.add(ret);
}
@Override
public ResolvedType next() {
ResolvedType next = delegate.next();
if (visited.add(next)) {
toPersue.add(next);
}
return next;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
}
public void clearInterTypeMungers() {
if (isRawType()) {
ResolvedType genericType = getGenericType();
if (genericType.isRawType()) {
System.err.println("DebugFor341926: Type " + this.getName() + " has an incorrect generic form");
} else {
genericType.clearInterTypeMungers();
}
}
interTypeMungers = new ArrayList<ConcreteTypeMunger>();
}
public boolean isTopmostImplementor(ResolvedType interfaceType) {
boolean b = true;
if (isInterface()) {
b = false;
} else if (!interfaceType.isAssignableFrom(this, true)) {
b = false;
} else {
ResolvedType superclass = this.getSuperclass();
if (superclass.isMissing()) {
b = true;
} else if (interfaceType.isAssignableFrom(superclass, true)) {
b = false;
}
}
return b;
}
public ResolvedType getTopmostImplementor(ResolvedType interfaceType) {
if (isInterface()) {
return null;
}
if (!interfaceType.isAssignableFrom(this)) {
return null;
}
ResolvedType higherType = this.getSuperclass().getTopmostImplementor(interfaceType);
if (higherType != null) {
return higherType;
}
return this;
}
public List<ResolvedMember> getExposedPointcuts() {
List<ResolvedMember> ret = new ArrayList<ResolvedMember>();
if (getSuperclass() != null) {
ret.addAll(getSuperclass().getExposedPointcuts());
}
for (ResolvedType type : getDeclaredInterfaces()) {
addPointcutsResolvingConflicts(ret, Arrays.asList(type.getDeclaredPointcuts()), false);
}
addPointcutsResolvingConflicts(ret, Arrays.asList(getDeclaredPointcuts()), true);
for (ResolvedMember member : ret) {
ResolvedPointcutDefinition inherited = (ResolvedPointcutDefinition) member;
if (inherited != null && inherited.isAbstract()) {
if (!this.isAbstract()) {
getWorld().showMessage(IMessage.ERROR,
WeaverMessages.format(WeaverMessages.POINCUT_NOT_CONCRETE, inherited, this.getName()),
inherited.getSourceLocation(), this.getSourceLocation());
}
}
}
return ret;
}
private void addPointcutsResolvingConflicts(List<ResolvedMember> acc, List<ResolvedMember> added, boolean isOverriding) {
for (Iterator<ResolvedMember> i = added.iterator(); i.hasNext();) {
ResolvedPointcutDefinition toAdd = (ResolvedPointcutDefinition) i.next();
for (Iterator<ResolvedMember> j = acc.iterator(); j.hasNext();) {
ResolvedPointcutDefinition existing = (ResolvedPointcutDefinition) j.next();
if (toAdd == null || existing == null || existing == toAdd) {
continue;
}
UnresolvedType pointcutDeclaringTypeUT = existing.getDeclaringType();
if (pointcutDeclaringTypeUT != null) {
ResolvedType pointcutDeclaringType = pointcutDeclaringTypeUT.resolve(getWorld());
if (!isVisible(existing.getModifiers(), pointcutDeclaringType, this)) {
if (existing.isAbstract() && conflictingSignature(existing, toAdd)) {
getWorld().showMessage(
IMessage.ERROR,
WeaverMessages.format(WeaverMessages.POINTCUT_NOT_VISIBLE, existing.getDeclaringType()
.getName() + "." + existing.getName() + "()", this.getName()),
toAdd.getSourceLocation(), null);
j.remove();
}
continue;
}
}
if (conflictingSignature(existing, toAdd)) {
if (isOverriding) {
checkLegalOverride(existing, toAdd, 0x00, null);
j.remove();
} else {
getWorld().showMessage(
IMessage.ERROR,
WeaverMessages.format(WeaverMessages.CONFLICTING_INHERITED_POINTCUTS,
this.getName() + toAdd.getSignature()), existing.getSourceLocation(),
toAdd.getSourceLocation());
j.remove();
}
}
}
acc.add(toAdd);
}
}
public ISourceLocation getSourceLocation() {
return null;
}
public boolean isExposedToWeaver() {
return false;
}
public WeaverStateInfo getWeaverState() {
return null;
}
public ReferenceType getGenericType() {
return null;
}
@Override
public ResolvedType getRawType() {
return super.getRawType().resolve(world);
}
public ResolvedType parameterizedWith(UnresolvedType[] typeParameters) {
if (!(isGenericType() || isParameterizedType())) {
return this;
}
return TypeFactory.createParameterizedType(this.getGenericType(), typeParameters, getWorld());
}
@Override
public UnresolvedType parameterize(Map<String, UnresolvedType> typeBindings) {
if (!isParameterizedType()) {
return this;
}
boolean workToDo = false;
for (int i = 0; i < typeParameters.length; i++) {
if (typeParameters[i].isTypeVariableReference() || (typeParameters[i] instanceof BoundedReferenceType) || typeParameters[i].isParameterizedType()) {
workToDo = true;
}
}
if (!workToDo) {
return this;
} else {
UnresolvedType[] newTypeParams = new UnresolvedType[typeParameters.length];
for (int i = 0; i < newTypeParams.length; i++) {
newTypeParams[i] = typeParameters[i];
if (newTypeParams[i].isTypeVariableReference()) {
TypeVariableReferenceType tvrt = (TypeVariableReferenceType) newTypeParams[i];
UnresolvedType binding = typeBindings.get(tvrt.getTypeVariable().getName());
if (binding != null) {
newTypeParams[i] = binding;
}
} else if (newTypeParams[i] instanceof BoundedReferenceType) {
BoundedReferenceType brType = (BoundedReferenceType) newTypeParams[i];
newTypeParams[i] = brType.parameterize(typeBindings);
} else if (newTypeParams[i].isParameterizedType()) {
newTypeParams[i] = newTypeParams[i].parameterize(typeBindings);
}
}
return TypeFactory.createParameterizedType(getGenericType(), newTypeParams, getWorld());
}
}
public boolean isException() {
return (world.getCoreType(UnresolvedType.JL_EXCEPTION).isAssignableFrom(this));
}
public boolean isCheckedException() {
if (!isException()) {
return false;
}
if (world.getCoreType(UnresolvedType.RUNTIME_EXCEPTION).isAssignableFrom(this)) {
return false;
}
return true;
}
public final boolean isConvertableFrom(ResolvedType other) {
if (this.equals(OBJECT)) {
return true;
}
if (world.isInJava5Mode()) {
if (this.isPrimitiveType() ^ other.isPrimitiveType()) {
if (validBoxing.contains(this.getSignature() + other.getSignature())) {
return true;
}
}
}
if (this.isPrimitiveType() || other.isPrimitiveType()) {
return this.isAssignableFrom(other);
}
return this.isCoerceableFrom(other);
}
public abstract boolean isAssignableFrom(ResolvedType other);
public abstract boolean isAssignableFrom(ResolvedType other, boolean allowMissing);
public abstract boolean isCoerceableFrom(ResolvedType other);
public boolean needsNoConversionFrom(ResolvedType o) {
return isAssignableFrom(o);
}
public String getSignatureForAttribute() {
return signature;
}
private FuzzyBoolean parameterizedWithTypeVariable = FuzzyBoolean.MAYBE;
public boolean isParameterizedWithTypeVariable() {
if (parameterizedWithTypeVariable == FuzzyBoolean.MAYBE) {
if (typeParameters == null || typeParameters.length == 0) {
parameterizedWithTypeVariable = FuzzyBoolean.NO;
return false;
}
for (int i = 0; i < typeParameters.length; i++) {
ResolvedType aType = (ResolvedType) typeParameters[i];
if (aType.isTypeVariableReference()
) {
parameterizedWithTypeVariable = FuzzyBoolean.YES;
return true;
}
if (aType.isParameterizedType()) {
boolean b = aType.isParameterizedWithTypeVariable();
if (b) {
parameterizedWithTypeVariable = FuzzyBoolean.YES;
return true;
}
}
if (aType.isGenericWildcard()) {
BoundedReferenceType boundedRT = (BoundedReferenceType) aType;
if (boundedRT.isExtends()) {
boolean b = false;
UnresolvedType upperBound = boundedRT.getUpperBound();
if (upperBound.isParameterizedType()) {
b = ((ResolvedType) upperBound).isParameterizedWithTypeVariable();
} else if (upperBound.isTypeVariableReference()
&& ((TypeVariableReference) upperBound).getTypeVariable().getDeclaringElementKind() == TypeVariable.METHOD) {
b = true;
}
if (b) {
parameterizedWithTypeVariable = FuzzyBoolean.YES;
return true;
}
}
if (boundedRT.isSuper()) {
boolean b = false;
UnresolvedType lowerBound = boundedRT.getLowerBound();
if (lowerBound.isParameterizedType()) {
b = ((ResolvedType) lowerBound).isParameterizedWithTypeVariable();
} else if (lowerBound.isTypeVariableReference()
&& ((TypeVariableReference) lowerBound).getTypeVariable().getDeclaringElementKind() == TypeVariable.METHOD) {
b = true;
}
if (b) {
parameterizedWithTypeVariable = FuzzyBoolean.YES;
return true;
}
}
}
}
parameterizedWithTypeVariable = FuzzyBoolean.NO;
}
return parameterizedWithTypeVariable.alwaysTrue();
}
protected boolean ajMembersNeedParameterization() {
if (isParameterizedType()) {
return true;
}
ResolvedType superclass = getSuperclass();
if (superclass != null && !superclass.isMissing()) {
return superclass.ajMembersNeedParameterization();
}
return false;
}
protected Map<String, UnresolvedType> getAjMemberParameterizationMap() {
Map<String, UnresolvedType> myMap = getMemberParameterizationMap();
if (myMap.isEmpty()) {
if (getSuperclass() != null) {
return getSuperclass().getAjMemberParameterizationMap();
}
}
return myMap;
}
public void setBinaryPath(String binaryPath) {
this.binaryPath = binaryPath;
}
public String getBinaryPath() {
return binaryPath;
}
public void ensureConsistent() {
}
public boolean isInheritedAnnotation() {
ensureAnnotationBitsInitialized();
return (bits & AnnotationMarkedInherited) != 0;
}
private void ensureAnnotationBitsInitialized() {
if ((bits & AnnotationBitsInitialized) == 0) {
bits |= AnnotationBitsInitialized;
if (hasAnnotation(UnresolvedType.AT_INHERITED)) {
bits |= AnnotationMarkedInherited;
}
}
}
private boolean hasNewParentMungers() {
if ((bits & MungersAnalyzed) == 0) {
bits |= MungersAnalyzed;
for (ConcreteTypeMunger munger : interTypeMungers) {
ResolvedTypeMunger resolvedTypeMunger = munger.getMunger();
if (resolvedTypeMunger != null && resolvedTypeMunger.getKind() == ResolvedTypeMunger.Parent) {
bits |= HasParentMunger;
}
}
}
return (bits & HasParentMunger) != 0;
}
public void tagAsTypeHierarchyComplete() {
if (isParameterizedOrRawType()) {
ReferenceType genericType = this.getGenericType();
genericType.tagAsTypeHierarchyComplete();
return;
}
bits |= TypeHierarchyCompleteBit;
}
public boolean isTypeHierarchyComplete() {
if (isParameterizedOrRawType()) {
return this.getGenericType().isTypeHierarchyComplete();
}
return (bits & TypeHierarchyCompleteBit) != 0;
}
public int getCompilerVersion() {
return WeaverVersionInfo.getCurrentWeaverMajorVersion();
}
public boolean isPrimitiveArray() {
return false;
}
public boolean isGroovyObject() {
if ((bits & GroovyObjectInitialized) == 0) {
ResolvedType[] intfaces = getDeclaredInterfaces();
boolean done = false;
if (intfaces != null) {
for (ResolvedType intface : intfaces) {
if (intface.getName().equals("groovy.lang.GroovyObject")) {
bits |= IsGroovyObject;
done = true;
break;
}
}
}
if (!done) {
if (getSuperclass().getName().equals("groovy.lang.GroovyObjectSupport")) {
bits |= IsGroovyObject;
}
}
bits |= GroovyObjectInitialized;
}
return (bits & IsGroovyObject) != 0;
}
public boolean isPrivilegedAspect() {
if ((bits & IsPrivilegedBitInitialized) == 0) {
AnnotationAJ privilegedAnnotation = getAnnotationOfType(UnresolvedType.AJC_PRIVILEGED);
if (privilegedAnnotation != null) {
bits |= IsPrivilegedAspect;
}
bits |= IsPrivilegedBitInitialized;
}
return (bits & IsPrivilegedAspect) != 0;
}
}