package org.aspectj.weaver;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.aspectj.bridge.ISourceLocation;
import org.aspectj.weaver.World.TypeMap;
import org.aspectj.weaver.patterns.Declare;
import org.aspectj.weaver.patterns.PerClause;
public class ReferenceType extends ResolvedType {
public static final ReferenceType[] EMPTY_ARRAY = new ReferenceType[0];
private final List<WeakReference<ReferenceType>> derivativeTypes = new ArrayList<WeakReference<ReferenceType>>();
ReferenceType genericType = null;
ReferenceType rawType = null;
ReferenceTypeDelegate delegate = null;
int startPos = 0;
int endPos = 0;
ResolvedMember[] parameterizedMethods = null;
ResolvedMember[] parameterizedFields = null;
ResolvedMember[] parameterizedPointcuts = null;
WeakReference<ResolvedType[]> parameterizedInterfaces = new WeakReference<ResolvedType[]>(
null);
Collection<Declare> parameterizedDeclares = null;
private ResolvedType[] annotationTypes = null;
private AnnotationAJ[] annotations = null;
private ResolvedType newSuperclass;
private ResolvedType[] newInterfaces;
public ReferenceType(String signature, World world) {
super(signature, world);
}
public ReferenceType(String signature, String signatureErasure, World world) {
super(signature, signatureErasure, world);
}
public static ReferenceType fromTypeX(UnresolvedType tx, World world) {
ReferenceType rt = new ReferenceType(tx.getErasureSignature(), world);
rt.typeKind = tx.typeKind;
return rt;
}
public ReferenceType(ResolvedType theGenericType,
ResolvedType[] theParameters, World aWorld) {
super(makeParameterizedSignature(theGenericType, theParameters),
theGenericType.signatureErasure, aWorld);
ReferenceType genericReferenceType = (ReferenceType) theGenericType;
this.typeParameters = theParameters;
this.genericType = genericReferenceType;
this.typeKind = TypeKind.PARAMETERIZED;
this.delegate = genericReferenceType.getDelegate();
genericReferenceType.addDependentType(this);
}
synchronized void addDependentType(ReferenceType dependent) {
synchronized (derivativeTypes) {
this.derivativeTypes
.add(new WeakReference<ReferenceType>(dependent));
}
}
public void checkDuplicates(ReferenceType newRt) {
synchronized (derivativeTypes) {
List<WeakReference<ReferenceType>> forRemoval = new ArrayList<WeakReference<ReferenceType>>();
for (WeakReference<ReferenceType> derivativeTypeReference : derivativeTypes) {
ReferenceType derivativeType = derivativeTypeReference.get();
if (derivativeType == null) {
forRemoval.add(derivativeTypeReference);
} else {
if (derivativeType.getTypekind() != newRt.getTypekind()) {
continue;
}
if (equal2(newRt.getTypeParameters(),
derivativeType.getTypeParameters())) {
if (TypeMap.useExpendableMap) {
throw new IllegalStateException();
}
}
}
}
derivativeTypes.removeAll(forRemoval);
}
}
private boolean equal2(UnresolvedType[] typeParameters,
UnresolvedType[] resolvedParameters) {
if (typeParameters.length != resolvedParameters.length) {
return false;
}
int len = typeParameters.length;
for (int p = 0; p < len; p++) {
if (!typeParameters[p].equals(resolvedParameters[p])) {
return false;
}
}
return true;
}
@Override
public String getSignatureForAttribute() {
if (genericType == null || typeParameters == null) {
return getSignature();
}
return makeDeclaredSignature(genericType, typeParameters);
}
public ReferenceType(UnresolvedType genericType, World world) {
super(genericType.getSignature(), world);
typeKind = TypeKind.GENERIC;
this.typeVariables = genericType.typeVariables;
}
@Override
public boolean isClass() {
return getDelegate().isClass();
}
@Override
public int getCompilerVersion() {
return getDelegate().getCompilerVersion();
}
@Override
public boolean isGenericType() {
return !isParameterizedType() && !isRawType()
&& getDelegate().isGeneric();
}
public String getGenericSignature() {
String sig = getDelegate().getDeclaredGenericSignature();
return (sig == null) ? "" : sig;
}
@Override
public AnnotationAJ[] getAnnotations() {
return getDelegate().getAnnotations();
}
@Override
public boolean hasAnnotations() {
return getDelegate().hasAnnotations();
}
@Override
public void addAnnotation(AnnotationAJ annotationX) {
if (annotations == null) {
annotations = new AnnotationAJ[] { annotationX };
} else {
AnnotationAJ[] newAnnotations = new AnnotationAJ[annotations.length + 1];
System.arraycopy(annotations, 0, newAnnotations, 1,
annotations.length);
newAnnotations[0] = annotationX;
annotations = newAnnotations;
}
addAnnotationType(annotationX.getType());
}
public boolean hasAnnotation(UnresolvedType ofType) {
boolean onDelegate = getDelegate().hasAnnotation(ofType);
if (onDelegate) {
return true;
}
if (annotationTypes != null) {
for (int i = 0; i < annotationTypes.length; i++) {
if (annotationTypes[i].equals(ofType)) {
return true;
}
}
}
return false;
}
private void addAnnotationType(ResolvedType ofType) {
if (annotationTypes == null) {
annotationTypes = new ResolvedType[1];
annotationTypes[0] = ofType;
} else {
ResolvedType[] newAnnotationTypes = new ResolvedType[annotationTypes.length + 1];
System.arraycopy(annotationTypes, 0, newAnnotationTypes, 1,
annotationTypes.length);
newAnnotationTypes[0] = ofType;
annotationTypes = newAnnotationTypes;
}
}
@Override
public ResolvedType[] getAnnotationTypes() {
if (getDelegate() == null) {
throw new BCException("Unexpected null delegate for type "
+ this.getName());
}
if (annotationTypes == null) {
return getDelegate().getAnnotationTypes();
} else {
ResolvedType[] delegateAnnotationTypes = getDelegate()
.getAnnotationTypes();
ResolvedType[] result = new ResolvedType[annotationTypes.length
+ delegateAnnotationTypes.length];
System.arraycopy(delegateAnnotationTypes, 0, result, 0,
delegateAnnotationTypes.length);
System.arraycopy(annotationTypes, 0, result,
delegateAnnotationTypes.length, annotationTypes.length);
return result;
}
}
@Override
public String getNameAsIdentifier() {
return getRawName().replace('.', '_');
}
@Override
public AnnotationAJ getAnnotationOfType(UnresolvedType ofType) {
AnnotationAJ[] axs = getDelegate().getAnnotations();
if (axs != null) {
for (int i = 0; i < axs.length; i++) {
if (axs[i].getTypeSignature().equals(ofType.getSignature())) {
return axs[i];
}
}
}
if (annotations != null) {
String searchSig = ofType.getSignature();
for (int i = 0; i < annotations.length; i++) {
if (annotations[i].getTypeSignature().equals(searchSig)) {
return annotations[i];
}
}
}
return null;
}
@Override
public boolean isAspect() {
return getDelegate().isAspect();
}
@Override
public boolean isAnnotationStyleAspect() {
return getDelegate().isAnnotationStyleAspect();
}
@Override
public boolean isEnum() {
return getDelegate().isEnum();
}
@Override
public boolean isAnnotation() {
return getDelegate().isAnnotation();
}
@Override
public boolean isAnonymous() {
return getDelegate().isAnonymous();
}
@Override
public boolean isNested() {
return getDelegate().isNested();
}
public ResolvedType getOuterClass() {
return getDelegate().getOuterClass();
}
public String getRetentionPolicy() {
return getDelegate().getRetentionPolicy();
}
@Override
public boolean isAnnotationWithRuntimeRetention() {
return getDelegate().isAnnotationWithRuntimeRetention();
}
@Override
public boolean canAnnotationTargetType() {
return getDelegate().canAnnotationTargetType();
}
@Override
public AnnotationTargetKind[] getAnnotationTargetKinds() {
return getDelegate().getAnnotationTargetKinds();
}
@Override
public boolean isCoerceableFrom(ResolvedType o) {
ResolvedType other = o.resolve(world);
if (this.isAssignableFrom(other) || other.isAssignableFrom(this)) {
return true;
}
if (this.isParameterizedType() && other.isParameterizedType()) {
return isCoerceableFromParameterizedType(other);
}
if (this.isParameterizedType() && other.isRawType()) {
return ((ReferenceType) this.getRawType()).isCoerceableFrom(other
.getGenericType());
}
if (this.isRawType() && other.isParameterizedType()) {
return this.getGenericType().isCoerceableFrom((other.getRawType()));
}
if (!this.isInterface() && !other.isInterface()) {
return false;
}
if (this.isFinal() || other.isFinal()) {
return false;
}
ResolvedMember[] a = getDeclaredMethods();
ResolvedMember[] b = other.getDeclaredMethods();
for (int ai = 0, alen = a.length; ai < alen; ai++) {
for (int bi = 0, blen = b.length; bi < blen; bi++) {
if (!b[bi].isCompatibleWith(a[ai])) {
return false;
}
}
}
return true;
}
private final boolean isCoerceableFromParameterizedType(ResolvedType other) {
if (!other.isParameterizedType()) {
return false;
}
ResolvedType myRawType = getRawType();
ResolvedType theirRawType = other.getRawType();
if (myRawType == theirRawType
|| myRawType.isCoerceableFrom(theirRawType)) {
if (getTypeParameters().length == other.getTypeParameters().length) {
ResolvedType[] myTypeParameters = getResolvedTypeParameters();
ResolvedType[] theirTypeParameters = other
.getResolvedTypeParameters();
for (int i = 0; i < myTypeParameters.length; i++) {
if (myTypeParameters[i] != theirTypeParameters[i]) {
if (myTypeParameters[i].isGenericWildcard()) {
BoundedReferenceType wildcard = (BoundedReferenceType) myTypeParameters[i];
if (!wildcard
.canBeCoercedTo(theirTypeParameters[i])) {
return false;
}
} else if (myTypeParameters[i]
.isTypeVariableReference()) {
TypeVariableReferenceType tvrt = (TypeVariableReferenceType) myTypeParameters[i];
TypeVariable tv = tvrt.getTypeVariable();
tv.resolve(world);
if (!tv.canBeBoundTo(theirTypeParameters[i])) {
return false;
}
} else if (theirTypeParameters[i]
.isTypeVariableReference()) {
TypeVariableReferenceType tvrt = (TypeVariableReferenceType) theirTypeParameters[i];
TypeVariable tv = tvrt.getTypeVariable();
tv.resolve(world);
if (!tv.canBeBoundTo(myTypeParameters[i])) {
return false;
}
} else if (theirTypeParameters[i].isGenericWildcard()) {
BoundedReferenceType wildcard = (BoundedReferenceType) theirTypeParameters[i];
if (!wildcard.canBeCoercedTo(myTypeParameters[i])) {
return false;
}
} else {
return false;
}
}
}
return true;
}
}
return false;
}
@Override
public boolean isAssignableFrom(ResolvedType other) {
return isAssignableFrom(other, false);
}
@Override
public boolean isAssignableFrom(ResolvedType other, boolean allowMissing) {
if (other.isPrimitiveType()) {
if (!world.isInJava5Mode()) {
return false;
}
if (ResolvedType.validBoxing.contains(this.getSignature()
+ other.getSignature())) {
return true;
}
}
if (this == other) {
return true;
}
if (this.getSignature().equals("Ljava/lang/Object;")) {
return true;
}
if (!isTypeVariableReference()
&& other.getSignature().equals("Ljava/lang/Object;")) {
return false;
}
boolean thisRaw = this.isRawType();
if (thisRaw && other.isParameterizedOrGenericType()) {
return isAssignableFrom(other.getRawType());
}
boolean thisGeneric = this.isGenericType();
if (thisGeneric && other.isParameterizedOrRawType()) {
return isAssignableFrom(other.getGenericType());
}
if (this.isParameterizedType()) {
if (((ReferenceType) this.getRawType()).isAssignableFrom(other)) {
boolean wildcardsAllTheWay = true;
ResolvedType[] myParameters = this.getResolvedTypeParameters();
for (int i = 0; i < myParameters.length; i++) {
if (!myParameters[i].isGenericWildcard()) {
wildcardsAllTheWay = false;
} else {
BoundedReferenceType boundedRT = (BoundedReferenceType) myParameters[i];
if (boundedRT.isExtends() || boundedRT.isSuper()) {
wildcardsAllTheWay = false;
}
}
}
if (wildcardsAllTheWay && !other.isParameterizedType()) {
return true;
}
ResolvedType[] theirParameters = other
.getResolvedTypeParameters();
boolean parametersAssignable = true;
if (myParameters.length == theirParameters.length) {
for (int i = 0; i < myParameters.length
&& parametersAssignable; i++) {
if (myParameters[i] == theirParameters[i]) {
continue;
}
ResolvedType mp = myParameters[i];
ResolvedType tp = theirParameters[i];
if (mp.isParameterizedType()
&& tp.isParameterizedType()) {
if (mp.getGenericType().equals(tp.getGenericType())) {
UnresolvedType[] mtps = mp.getTypeParameters();
UnresolvedType[] ttps = tp.getTypeParameters();
for (int ii = 0; ii < mtps.length; ii++) {
if (mtps[ii].isTypeVariableReference()
&& ttps[ii]
.isTypeVariableReference()) {
TypeVariable mtv = ((TypeVariableReferenceType) mtps[ii])
.getTypeVariable();
boolean b = mtv
.canBeBoundTo((ResolvedType) ttps[ii]);
if (!b) {
parametersAssignable = false;
break;
}
} else {
parametersAssignable = false;
break;
}
}
continue;
} else {
parametersAssignable = false;
break;
}
}
if (myParameters[i].isTypeVariableReference()
&& theirParameters[i].isTypeVariableReference()) {
TypeVariable myTV = ((TypeVariableReferenceType) myParameters[i])
.getTypeVariable();
boolean b = myTV.canBeBoundTo(theirParameters[i]);
if (!b) {
parametersAssignable = false;
break;
} else {
continue;
}
}
if (!myParameters[i].isGenericWildcard()) {
parametersAssignable = false;
break;
} else {
BoundedReferenceType wildcardType = (BoundedReferenceType) myParameters[i];
if (!wildcardType.alwaysMatches(theirParameters[i])) {
parametersAssignable = false;
break;
}
}
}
} else {
parametersAssignable = false;
}
if (parametersAssignable) {
return true;
}
}
}
if (isTypeVariableReference() && !other.isTypeVariableReference()) {
TypeVariable aVar = ((TypeVariableReference) this)
.getTypeVariable();
return aVar.resolve(world).canBeBoundTo(other);
}
if (other.isTypeVariableReference()) {
TypeVariableReferenceType otherType = (TypeVariableReferenceType) other;
if (this instanceof TypeVariableReference) {
return ((TypeVariableReference) this)
.getTypeVariable()
.resolve(world)
.canBeBoundTo(
otherType.getTypeVariable().getFirstBound()
.resolve(world));
} else {
return this.isAssignableFrom(otherType.getTypeVariable()
.getFirstBound().resolve(world));
}
}
if (allowMissing && other.isMissing()) {
return false;
}
ResolvedType[] interfaces = other.getDeclaredInterfaces();
for (ResolvedType intface : interfaces) {
boolean b;
if (thisRaw && intface.isParameterizedOrGenericType()) {
b = this.isAssignableFrom(intface.getRawType(), allowMissing);
} else {
b = this.isAssignableFrom(intface, allowMissing);
}
if (b) {
return true;
}
}
ResolvedType superclass = other.getSuperclass();
if (superclass != null) {
boolean b;
if (thisRaw && superclass.isParameterizedOrGenericType()) {
b = this.isAssignableFrom(superclass.getRawType(), allowMissing);
} else {
b = this.isAssignableFrom(superclass, allowMissing);
}
if (b) {
return true;
}
}
return false;
}
@Override
public ISourceContext getSourceContext() {
return getDelegate().getSourceContext();
}
@Override
public ISourceLocation getSourceLocation() {
ISourceContext isc = getDelegate().getSourceContext();
return isc.makeSourceLocation(new Position(startPos, endPos));
}
@Override
public boolean isExposedToWeaver() {
return (getDelegate() == null) || delegate.isExposedToWeaver();
}
@Override
public WeaverStateInfo getWeaverState() {
return getDelegate().getWeaverState();
}
@Override
public ResolvedMember[] getDeclaredFields() {
if (parameterizedFields != null) {
return parameterizedFields;
}
if (isParameterizedType() || isRawType()) {
ResolvedMember[] delegateFields = getDelegate().getDeclaredFields();
parameterizedFields = new ResolvedMember[delegateFields.length];
for (int i = 0; i < delegateFields.length; i++) {
parameterizedFields[i] = delegateFields[i].parameterizedWith(
getTypesForMemberParameterization(), this,
isParameterizedType());
}
return parameterizedFields;
} else {
return getDelegate().getDeclaredFields();
}
}
@Override
public ResolvedType[] getDeclaredInterfaces() {
ResolvedType[] interfaces = parameterizedInterfaces.get();
if (interfaces != null) {
return interfaces;
}
ResolvedType[] delegateInterfaces = getDelegate()
.getDeclaredInterfaces();
if (isRawType()) {
if (newInterfaces != null) {
throw new IllegalStateException(
"The raw type should never be accumulating new interfaces, they should be on the generic type. Type is "
+ this.getName());
}
ResolvedType[] newInterfacesFromGenericType = genericType.newInterfaces;
if (newInterfacesFromGenericType != null) {
ResolvedType[] extraInterfaces = new ResolvedType[delegateInterfaces.length
+ newInterfacesFromGenericType.length];
System.arraycopy(delegateInterfaces, 0, extraInterfaces, 0,
delegateInterfaces.length);
System.arraycopy(newInterfacesFromGenericType, 0,
extraInterfaces, delegateInterfaces.length,
newInterfacesFromGenericType.length);
delegateInterfaces = extraInterfaces;
}
} else if (newInterfaces != null) {
ResolvedType[] extraInterfaces = new ResolvedType[delegateInterfaces.length
+ newInterfaces.length];
System.arraycopy(delegateInterfaces, 0, extraInterfaces, 0,
delegateInterfaces.length);
System.arraycopy(newInterfaces, 0, extraInterfaces,
delegateInterfaces.length, newInterfaces.length);
delegateInterfaces = extraInterfaces;
}
if (isParameterizedType()) {
interfaces = new ResolvedType[delegateInterfaces.length];
for (int i = 0; i < delegateInterfaces.length; i++) {
if (delegateInterfaces[i].isParameterizedType()) {
interfaces[i] = delegateInterfaces[i].parameterize(
getMemberParameterizationMap()).resolve(world);
} else {
interfaces[i] = delegateInterfaces[i];
}
}
parameterizedInterfaces = new WeakReference<ResolvedType[]>(
interfaces);
return interfaces;
} else if (isRawType()) {
UnresolvedType[] paramTypes = getTypesForMemberParameterization();
interfaces = new ResolvedType[delegateInterfaces.length];
for (int i = 0, max = interfaces.length; i < max; i++) {
interfaces[i] = delegateInterfaces[i];
if (interfaces[i].isGenericType()) {
interfaces[i] = interfaces[i].getRawType().resolve(
getWorld());
} else if (interfaces[i].isParameterizedType()) {
UnresolvedType[] toUseForParameterization = determineThoseTypesToUse(
interfaces[i], paramTypes);
interfaces[i] = interfaces[i]
.parameterizedWith(toUseForParameterization);
}
}
parameterizedInterfaces = new WeakReference<ResolvedType[]>(
interfaces);
return interfaces;
}
if (getDelegate().isCacheable()) {
parameterizedInterfaces = new WeakReference<ResolvedType[]>(
delegateInterfaces);
}
return delegateInterfaces;
}
private UnresolvedType[] determineThoseTypesToUse(
ResolvedType parameterizedInterface, UnresolvedType[] paramTypes) {
UnresolvedType[] tParms = parameterizedInterface.getTypeParameters();
UnresolvedType[] retVal = new UnresolvedType[tParms.length];
for (int i = 0; i < tParms.length; i++) {
UnresolvedType tParm = tParms[i];
if (tParm.isTypeVariableReference()) {
TypeVariableReference tvrt = (TypeVariableReference) tParm;
TypeVariable tv = tvrt.getTypeVariable();
int rank = getRank(tv.getName());
if (rank != -1) {
retVal[i] = paramTypes[rank];
} else {
retVal[i] = tParms[i];
}
} else {
retVal[i] = tParms[i];
}
}
return retVal;
}
private int getRank(String tvname) {
TypeVariable[] thisTypesTVars = getGenericType().getTypeVariables();
for (int i = 0; i < thisTypesTVars.length; i++) {
TypeVariable tv = thisTypesTVars[i];
if (tv.getName().equals(tvname)) {
return i;
}
}
return -1;
}
@Override
public ResolvedMember[] getDeclaredMethods() {
if (parameterizedMethods != null) {
return parameterizedMethods;
}
if (isParameterizedType() || isRawType()) {
ResolvedMember[] delegateMethods = getDelegate()
.getDeclaredMethods();
UnresolvedType[] parameters = getTypesForMemberParameterization();
parameterizedMethods = new ResolvedMember[delegateMethods.length];
for (int i = 0; i < delegateMethods.length; i++) {
parameterizedMethods[i] = delegateMethods[i].parameterizedWith(
parameters, this, isParameterizedType());
}
return parameterizedMethods;
} else {
return getDelegate().getDeclaredMethods();
}
}
@Override
public ResolvedMember[] getDeclaredPointcuts() {
if (parameterizedPointcuts != null) {
return parameterizedPointcuts;
}
if (isParameterizedType()) {
ResolvedMember[] delegatePointcuts = getDelegate()
.getDeclaredPointcuts();
parameterizedPointcuts = new ResolvedMember[delegatePointcuts.length];
for (int i = 0; i < delegatePointcuts.length; i++) {
parameterizedPointcuts[i] = delegatePointcuts[i]
.parameterizedWith(getTypesForMemberParameterization(),
this, isParameterizedType());
}
return parameterizedPointcuts;
} else {
return getDelegate().getDeclaredPointcuts();
}
}
private UnresolvedType[] getTypesForMemberParameterization() {
UnresolvedType[] parameters = null;
if (isParameterizedType()) {
parameters = getTypeParameters();
} else if (isRawType()) {
TypeVariable[] tvs = getGenericType().getTypeVariables();
parameters = new UnresolvedType[tvs.length];
for (int i = 0; i < tvs.length; i++) {
parameters[i] = tvs[i].getFirstBound();
}
}
return parameters;
}
@Override
public TypeVariable[] getTypeVariables() {
if (typeVariables == null) {
typeVariables = getDelegate().getTypeVariables();
for (int i = 0; i < this.typeVariables.length; i++) {
typeVariables[i].resolve(world);
}
}
return typeVariables;
}
@Override
public PerClause getPerClause() {
PerClause pclause = getDelegate().getPerClause();
if (pclause != null && isParameterizedType()) {
Map<String, UnresolvedType> parameterizationMap = getAjMemberParameterizationMap();
pclause = (PerClause) pclause.parameterizeWith(parameterizationMap,
world);
}
return pclause;
}
@Override
public Collection<Declare> getDeclares() {
if (parameterizedDeclares != null) {
return parameterizedDeclares;
}
Collection<Declare> declares = null;
if (ajMembersNeedParameterization()) {
Collection<Declare> genericDeclares = getDelegate().getDeclares();
parameterizedDeclares = new ArrayList<Declare>();
Map<String, UnresolvedType> parameterizationMap = getAjMemberParameterizationMap();
for (Declare declareStatement : genericDeclares) {
parameterizedDeclares.add(declareStatement.parameterizeWith(
parameterizationMap, world));
}
declares = parameterizedDeclares;
} else {
declares = getDelegate().getDeclares();
}
for (Declare d : declares) {
d.setDeclaringType(this);
}
return declares;
}
@Override
public Collection<ConcreteTypeMunger> getTypeMungers() {
return getDelegate().getTypeMungers();
}
@Override
public Collection<ResolvedMember> getPrivilegedAccesses() {
return getDelegate().getPrivilegedAccesses();
}
@Override
public int getModifiers() {
return getDelegate().getModifiers();
}
WeakReference<ResolvedType> superclassReference = new WeakReference<ResolvedType>(
null);
@Override
public ResolvedType getSuperclass() {
ResolvedType ret = null;
if (newSuperclass != null) {
if (this.isParameterizedType()
&& newSuperclass.isParameterizedType()) {
return newSuperclass.parameterize(
getMemberParameterizationMap()).resolve(getWorld());
}
if (getDelegate().isCacheable()) {
superclassReference = new WeakReference<ResolvedType>(ret);
}
return newSuperclass;
}
try {
world.setTypeVariableLookupScope(this);
ret = getDelegate().getSuperclass();
} finally {
world.setTypeVariableLookupScope(null);
}
if (this.isParameterizedType() && ret.isParameterizedType()) {
ret = ret.parameterize(getMemberParameterizationMap()).resolve(
getWorld());
}
if (getDelegate().isCacheable()) {
superclassReference = new WeakReference<ResolvedType>(ret);
}
return ret;
}
public ReferenceTypeDelegate getDelegate() {
return delegate;
}
public void setDelegate(ReferenceTypeDelegate delegate) {
if (this.delegate != null
&& this.delegate.copySourceContext()
&& this.delegate.getSourceContext() != SourceContextImpl.UNKNOWN_SOURCE_CONTEXT) {
((AbstractReferenceTypeDelegate) delegate)
.setSourceContext(this.delegate.getSourceContext());
}
this.delegate = delegate;
synchronized (derivativeTypes) {
List<WeakReference<ReferenceType>> forRemoval = new ArrayList<WeakReference<ReferenceType>>();
for (WeakReference<ReferenceType> derivativeRef : derivativeTypes) {
ReferenceType derivative = derivativeRef.get();
if (derivative != null) {
derivative.setDelegate(delegate);
} else {
forRemoval.add(derivativeRef);
}
}
derivativeTypes.removeAll(forRemoval);
}
if (isRawType() && getGenericType() != null) {
ReferenceType genType = (ReferenceType) getGenericType();
if (genType.getDelegate() != delegate) {
genType.setDelegate(delegate);
}
}
clearParameterizationCaches();
ensureConsistent();
}
private void clearParameterizationCaches() {
parameterizedFields = null;
parameterizedInterfaces.clear();
parameterizedMethods = null;
parameterizedPointcuts = null;
superclassReference = new WeakReference<ResolvedType>(null);
}
public int getEndPos() {
return endPos;
}
public int getStartPos() {
return startPos;
}
public void setEndPos(int endPos) {
this.endPos = endPos;
}
public void setStartPos(int startPos) {
this.startPos = startPos;
}
@Override
public boolean doesNotExposeShadowMungers() {
return getDelegate().doesNotExposeShadowMungers();
}
public String getDeclaredGenericSignature() {
return getDelegate().getDeclaredGenericSignature();
}
public void setGenericType(ReferenceType rt) {
genericType = rt;
if (typeKind == TypeKind.SIMPLE) {
typeKind = TypeKind.RAW;
signatureErasure = signature;
if (newInterfaces != null) {
throw new IllegalStateException(
"Simple type promoted to raw, but simple type had new interfaces/superclass. Type is "
+ this.getName());
}
}
if (typeKind == TypeKind.RAW) {
genericType.addDependentType(this);
}
if (isRawType()) {
genericType.rawType = this;
}
if (this.isRawType() && rt.isRawType()) {
new RuntimeException(
"PR341926 diagnostics: Incorrect setup for a generic type, raw type should not point to raw: "
+ this.getName()).printStackTrace();
}
}
public void demoteToSimpleType() {
genericType = null;
typeKind = TypeKind.SIMPLE;
signatureErasure = null;
}
@Override
public ReferenceType getGenericType() {
if (isGenericType()) {
return this;
}
return genericType;
}
private static String makeParameterizedSignature(ResolvedType aGenericType,
ResolvedType[] someParameters) {
String rawSignature = aGenericType.getErasureSignature();
StringBuffer ret = new StringBuffer();
ret.append(PARAMETERIZED_TYPE_IDENTIFIER);
ret.append(rawSignature.substring(1, rawSignature.length() - 1));
ret.append("<");
for (int i = 0; i < someParameters.length; i++) {
ret.append(someParameters[i].getSignature());
}
ret.append(">;");
return ret.toString();
}
private static String makeDeclaredSignature(ResolvedType aGenericType,
UnresolvedType[] someParameters) {
StringBuffer ret = new StringBuffer();
String rawSig = aGenericType.getErasureSignature();
ret.append(rawSig.substring(0, rawSig.length() - 1));
ret.append("<");
for (int i = 0; i < someParameters.length; i++) {
if (someParameters[i] instanceof ReferenceType) {
ret.append(((ReferenceType) someParameters[i])
.getSignatureForAttribute());
} else if (someParameters[i] instanceof Primitive) {
ret.append(((Primitive) someParameters[i])
.getSignatureForAttribute());
} else {
throw new IllegalStateException(
"DebugFor325731: expected a ReferenceType or Primitive but was "
+ someParameters[i] + " of type "
+ someParameters[i].getClass().getName());
}
}
ret.append(">;");
return ret.toString();
}
@Override
public void ensureConsistent() {
annotations = null;
annotationTypes = null;
newSuperclass = null;
bits = 0;
newInterfaces = null;
typeVariables = null;
parameterizedInterfaces.clear();
superclassReference = new WeakReference<ResolvedType>(null);
if (getDelegate() != null) {
delegate.ensureConsistent();
}
if (isParameterizedOrRawType()) {
ReferenceType genericType = getGenericType();
if (genericType != null) {
genericType.ensureConsistent();
}
}
}
@Override
public void addParent(ResolvedType newParent) {
if (this.isRawType()) {
throw new IllegalStateException(
"The raw type should never be accumulating new interfaces, they should be on the generic type. Type is "
+ this.getName());
}
if (newParent.isClass()) {
newSuperclass = newParent;
superclassReference = new WeakReference<ResolvedType>(null);
} else {
if (newInterfaces == null) {
newInterfaces = new ResolvedType[1];
newInterfaces[0] = newParent;
} else {
ResolvedType[] existing = getDelegate().getDeclaredInterfaces();
if (existing != null) {
for (int i = 0; i < existing.length; i++) {
if (existing[i].equals(newParent)) {
return;
}
}
}
ResolvedType[] newNewInterfaces = new ResolvedType[newInterfaces.length + 1];
System.arraycopy(newInterfaces, 0, newNewInterfaces, 1,
newInterfaces.length);
newNewInterfaces[0] = newParent;
newInterfaces = newNewInterfaces;
}
if (this.isGenericType()) {
synchronized (derivativeTypes) {
for (WeakReference<ReferenceType> derivativeTypeRef : derivativeTypes) {
ReferenceType derivativeType = derivativeTypeRef.get();
if (derivativeType != null) {
derivativeType.parameterizedInterfaces.clear();
}
}
}
}
parameterizedInterfaces.clear();
}
}
private boolean equal(UnresolvedType[] typeParameters,
ResolvedType[] resolvedParameters) {
if (typeParameters.length != resolvedParameters.length) {
return false;
}
int len = typeParameters.length;
for (int p = 0; p < len; p++) {
if (!typeParameters[p].equals(resolvedParameters[p])) {
return false;
}
}
return true;
}
public ReferenceType findDerivativeType(ResolvedType[] typeParameters) {
synchronized (derivativeTypes) {
List<WeakReference<ReferenceType>> forRemoval = new ArrayList<WeakReference<ReferenceType>>();
for (WeakReference<ReferenceType> derivativeTypeRef : derivativeTypes) {
ReferenceType derivativeType = derivativeTypeRef.get();
if (derivativeType == null) {
forRemoval.add(derivativeTypeRef);
} else {
if (derivativeType.isRawType()) {
continue;
}
if (equal(derivativeType.typeParameters, typeParameters)) {
return derivativeType;
}
}
}
derivativeTypes.removeAll(forRemoval);
}
return null;
}
public boolean hasNewInterfaces() {
return newInterfaces != null;
}
}