12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280 |
- /* *******************************************************************
- * Copyright (c) 2002 Contributors
- * All rights reserved.
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Public License v 2.0
- * which accompanies this distribution and is available at
- * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
- *
- * Contributors:
- * PARC initial implementation
- * Andy Clement - June 2005 - separated out from ResolvedType
- * ******************************************************************/
- 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;
-
- /**
- * A reference type represents some 'real' type, not a primitive, not an array -
- * but a real type, for example java.util.List. Each ReferenceType has a
- * delegate that is the underlying artifact - either an eclipse artifact or a
- * bcel artifact. If the type represents a raw type (i.e. there is a generic
- * form) then the genericType field is set to point to the generic type. If it
- * is for a parameterized type then the generic type is also set to point to the
- * generic form.
- */
- public class ReferenceType extends ResolvedType {
-
- public static final ReferenceType[] EMPTY_ARRAY = new ReferenceType[0];
-
- /**
- * For generic types, this list holds references to all the derived raw and
- * parameterized versions. We need this so that if the generic delegate is
- * swapped during incremental compilation, the delegate of the derivatives
- * is swapped also.
- */
- private final List<WeakReference<ReferenceType>> derivativeTypes = new ArrayList<>();
-
- /**
- * For parameterized types (or the raw type) - this field points to the
- * actual reference type from which they are derived.
- */
- ReferenceType genericType = null;
-
- ReferenceType rawType = null; // generic types have a pointer back to their
- // raw variant (prevents GC of the raw from
- // the typemap!)
-
- ReferenceTypeDelegate delegate = null;
- int startPos = 0;
- int endPos = 0;
-
- // cached values for members
- ResolvedMember[] parameterizedMethods = null;
- ResolvedMember[] parameterizedFields = null;
- ResolvedMember[] parameterizedPointcuts = null;
- WeakReference<ResolvedType[]> parameterizedInterfaces = new WeakReference<>(
- null);
- Collection<Declare> parameterizedDeclares = null;
- // Collection parameterizedTypeMungers = null;
-
- // During matching it can be necessary to temporary mark types as annotated.
- // For example
- // a declare @type may trigger a separate declare parents to match, and so
- // the annotation
- // is temporarily held against the referencetype, the annotation will be
- // properly
- // added to the class during weaving.
- private ResolvedType[] annotationTypes = null;
- private AnnotationAJ[] annotations = null;
-
- // Similarly these are temporary replacements and additions for the
- // superclass and
- // superinterfaces
- 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;
- }
-
- /**
- * Constructor used when creating a parameterized type.
- */
- 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) {
- // checkDuplicates(dependent);
- synchronized (derivativeTypes) {
- this.derivativeTypes
- .add(new WeakReference<>(dependent));
- }
- }
-
- public void checkDuplicates(ReferenceType newRt) {
- synchronized (derivativeTypes) {
- List<WeakReference<ReferenceType>> forRemoval = new ArrayList<>();
- for (WeakReference<ReferenceType> derivativeTypeReference : derivativeTypes) {
- ReferenceType derivativeType = derivativeTypeReference.get();
- if (derivativeType == null) {
- forRemoval.add(derivativeTypeReference);
- } else {
- if (derivativeType.getTypekind() != newRt.getTypekind()) {
- continue; // cannot be this one
- }
- if (equal2(newRt.getTypeParameters(),
- derivativeType.getTypeParameters())) {
- if (TypeMap.useExpendableMap) {
- throw new IllegalStateException();
- }
- }
- }
- }
- derivativeTypes.removeAll(forRemoval);
- }
- }
-
- private boolean equal2(UnresolvedType[] typeParameters,
- UnresolvedType[] resolvedParameters) {
- if (typeParameters.length != resolvedParameters.length) {
- return false;
- }
- int len = typeParameters.length;
- for (int p = 0; p < len; p++) {
- if (!typeParameters[p].equals(resolvedParameters[p])) {
- return false;
- }
- }
- return true;
- }
-
- @Override
- public String getSignatureForAttribute() {
- if (genericType == null || typeParameters == null) {
- return getSignature();
- }
- return makeDeclaredSignature(genericType, typeParameters);
- }
-
- /**
- * Create a reference type for a generic type
- */
- 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 (ResolvedType annotationType : annotationTypes) {
- if (annotationType.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) {
- // there are no extras:
- 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 (AnnotationAJ ax : axs) {
- if (ax.getTypeSignature().equals(ofType.getSignature())) {
- return ax;
- }
- }
- }
- if (annotations != null) {
- String searchSig = ofType.getSignature();
- for (AnnotationAJ annotation : annotations) {
- if (annotation.getTypeSignature().equals(searchSig)) {
- return annotation;
- }
- }
- }
- 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();
- }
-
- // true iff the statement "this = (ThisType) other" would compile
- @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;
- }
-
- // 20170927: What is the block of code for? It mentions jls5.5 which isn't on this topic (old version of jls?)
- // Some possible references: http://docs.oracle.com/javase/specs/jls/se9/jls9.pdf 5.1.6 (narrowing reference conversion)
- // On Java 9 the test GenericsTests.testAfterReturningWithWildcardVar will fail because this code below
- // used to find Set and List were the same, but now finds they are not. (so it doesn't put out the unchecked
- // conversion message). However the code "List l = (List)someSet;" still compiles on 9 - so is this code bogus?
-
- // ??? needs to be Methods, not just declared methods? JLS 5.5 unclear
- ResolvedMember[] a = getDeclaredMethods();
- ResolvedMember[] b = other.getDeclaredMethods();
- for (ResolvedMember member : a) {
- for (ResolvedMember resolvedMember : b) {
- if (!resolvedMember.isCompatibleWith(member)) {
- 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) {
- // there's a chance it can be done
- ResolvedType[] myTypeParameters = getResolvedTypeParameters();
- ResolvedType[] theirTypeParameters = other
- .getResolvedTypeParameters();
- for (int i = 0; i < myTypeParameters.length; i++) {
- if (myTypeParameters[i] != theirTypeParameters[i]) {
- // thin ice now... but List<String> may still be
- // coerceable from e.g. List<T>
- 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;
- }
- // } else {
- // // we do this walk for situations like the following:
- // // Base<T>, Sub<S,T> extends Base<S>
- // // is Sub<Y,Z> coerceable from Base<X> ???
- // for (Iterator i = getDirectSupertypes(); i.hasNext();) {
- // ReferenceType parent = (ReferenceType) i.next();
- // if (parent.isCoerceableFromParameterizedType(other))
- // return true;
- // }
- }
- return false;
- }
-
- @Override
- public boolean isAssignableFrom(ResolvedType other) {
- return isAssignableFrom(other, false);
- }
-
- // TODO rewrite this method - it is a terrible mess
-
- // true iff the statement "this = other" would compile.
- @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()) {
- // look at wildcards...
- if (((ReferenceType) this.getRawType()).isAssignableFrom(other)) {
- boolean wildcardsAllTheWay = true;
- ResolvedType[] myParameters = this.getResolvedTypeParameters();
- for (ResolvedType myParameter : myParameters) {
- if (!myParameter.isGenericWildcard()) {
- wildcardsAllTheWay = false;
- } else {
- BoundedReferenceType boundedRT = (BoundedReferenceType) myParameter;
- if (boundedRT.isExtends() || boundedRT.isSuper()) {
- wildcardsAllTheWay = false;
- }
- }
- }
- if (wildcardsAllTheWay && !other.isParameterizedType()) {
- return true;
- }
- // we have to match by parameters one at a time
- 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;
- }
- // dont do this: pr253109
- // if
- // (myParameters[i].isAssignableFrom(theirParameters[i],
- // allowMissing)) {
- // 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) {// TODO incomplete testing here
- // I think
- 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();
- // TypeVariable theirTV =
- // ((TypeVariableReferenceType)
- // theirParameters[i]).getTypeVariable();
- boolean b = myTV.canBeBoundTo(theirParameters[i]);
- if (!b) {// TODO incomplete testing here I think
- 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;
- }
- }
- }
-
- // eg this=T other=Ljava/lang/Object;
- 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));// pr171952
- // return
- // ((TypeVariableReference)this).getTypeVariable()==otherType
- // .getTypeVariable();
- } else {
- // FIXME asc should this say canBeBoundTo??
- 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();
- }
- }
-
- /**
- * Find out from the generic signature the true signature of any interfaces
- * I implement. If I am parameterized, these may then need to be
- * parameterized before returning.
- */
- @Override
- public ResolvedType[] getDeclaredInterfaces() {
- ResolvedType[] interfaces = parameterizedInterfaces.get();
- if (interfaces != null) {
- return interfaces;
- }
- ResolvedType[] delegateInterfaces = getDelegate()
- .getDeclaredInterfaces();
- if (isRawType()) {
- if (newInterfaces != null) {// debug 375777
- 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) {
- // OPTIMIZE does this part of the method trigger often?
- 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()) {
- // UnresolvedType[] paramTypes =
- // getTypesForMemberParameterization();
- interfaces = new ResolvedType[delegateInterfaces.length];
- for (int i = 0; i < delegateInterfaces.length; i++) {
- // We may have to sub/super set the set of parametertypes if the
- // implemented interface
- // needs more or less than this type does. (pr124803/pr125080)
-
- if (delegateInterfaces[i].isParameterizedType()) {
- interfaces[i] = delegateInterfaces[i].parameterize(
- getMemberParameterizationMap()).resolve(world);
- } else {
- interfaces[i] = delegateInterfaces[i];
- }
- }
- parameterizedInterfaces = new WeakReference<>(
- 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()) {
- // a generic supertype of a raw type is replaced by its raw
- // equivalent
- interfaces[i] = interfaces[i].getRawType().resolve(
- getWorld());
- } else if (interfaces[i].isParameterizedType()) {
- // a parameterized supertype collapses any type vars to
- // their upper bounds
- UnresolvedType[] toUseForParameterization = determineThoseTypesToUse(
- interfaces[i], paramTypes);
- interfaces[i] = interfaces[i]
- .parameterizedWith(toUseForParameterization);
- }
- }
- parameterizedInterfaces = new WeakReference<>(
- interfaces);
- return interfaces;
- }
- if (getDelegate().isCacheable()) {
- parameterizedInterfaces = new WeakReference<>(
- delegateInterfaces);
- }
- return delegateInterfaces;
- }
-
- /**
- * It is possible this type has multiple type variables but the interface we
- * are about to parameterize only uses a subset - this method determines the
- * subset to use by looking at the type variable names used. For example:
- * <code>
- * class Foo<T extends String,E extends Number> implements SuperInterface<T> {}
- * </code> where <code>
- * interface SuperInterface<Z> {}
- * </code> In that example, a use of the 'Foo' raw type should know that it
- * implements the SuperInterface<String>.
- */
- private UnresolvedType[] determineThoseTypesToUse(
- ResolvedType parameterizedInterface, UnresolvedType[] paramTypes) {
- // What are the type parameters for the supertype?
- UnresolvedType[] tParms = parameterizedInterface.getTypeParameters();
- UnresolvedType[] retVal = new UnresolvedType[tParms.length];
-
- // Go through the supertypes type parameters, if any of them is a type
- // variable, use the
- // real type variable on the declaring type.
-
- // it is possibly overkill to look up the type variable - ideally the
- // entry in the type parameter list for the
- // interface should be the a ref to the type variable in the current
- // type ... but I'm not 100% confident right now.
- 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());
- // -1 probably means it is a reference to a type variable on the
- // outer generic type (see pr129566)
- if (rank != -1) {
- retVal[i] = paramTypes[rank];
- } else {
- retVal[i] = tParms[i];
- }
- } else {
- retVal[i] = tParms[i];
- }
-
- }
- return retVal;
- }
-
- /**
- * Returns the position within the set of type variables for this type for
- * the specified type variable name. Returns -1 if there is no type variable
- * with the specified name.
- */
- 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()) {
- // raw type, use upper bounds of type variables on generic type
- 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 (TypeVariable typeVariable : this.typeVariables) {
- typeVariable.resolve(world);
- }
- }
- return typeVariables;
- }
-
- @Override
- public PerClause getPerClause() {
- PerClause pclause = getDelegate().getPerClause();
- if (pclause != null && isParameterizedType()) { // could cache the
- // result here...
- 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<>();
- 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<>(
- null);
-
- @Override
- public ResolvedType getSuperclass() {
- ResolvedType ret = null;// superclassReference.get();
- // if (ret != null) {
- // return ret;
- // }
- if (newSuperclass != null) {
- if (this.isParameterizedType()
- && newSuperclass.isParameterizedType()) {
- return newSuperclass.parameterize(
- getMemberParameterizationMap()).resolve(getWorld());
- }
- if (getDelegate().isCacheable()) {
- superclassReference = new WeakReference<>(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<>(ret);
- }
- return ret;
- }
-
- public ReferenceTypeDelegate getDelegate() {
- return delegate;
- }
-
- public void setDelegate(ReferenceTypeDelegate delegate) {
- // Don't copy from BcelObjectType to EclipseSourceType - the context may
- // be tidied (result null'd) after previous weaving
- 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<>();
- for (WeakReference<ReferenceType> derivativeRef : derivativeTypes) {
- ReferenceType derivative = derivativeRef.get();
- if (derivative != null) {
- derivative.setDelegate(delegate);
- } else {
- forRemoval.add(derivativeRef);
- }
- }
- derivativeTypes.removeAll(forRemoval);
- }
-
- // If we are raw, we have a generic type - we should ensure it uses the
- // same delegate
- if (isRawType() && getGenericType() != null) {
- ReferenceType genType = getGenericType();
- if (genType.getDelegate() != delegate) { // avoids circular updates
- genType.setDelegate(delegate);
- }
- }
- clearParameterizationCaches();
- ensureConsistent();
- }
-
- private void clearParameterizationCaches() {
- parameterizedFields = null;
- parameterizedInterfaces.clear();
- parameterizedMethods = null;
- parameterizedPointcuts = null;
- superclassReference = new WeakReference<>(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;
- // Should we 'promote' this reference type from simple to raw?
- // makes sense if someone is specifying that it has a generic form
- if (typeKind == TypeKind.SIMPLE) {
- typeKind = TypeKind.RAW;
- signatureErasure = signature;
- if (newInterfaces != null) { // debug 375777
- 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;
- }
-
- /**
- * a parameterized signature starts with a "P" in place of the "L", see the
- * comment on signatures in UnresolvedType.
- *
- * @param aGenericType
- * @param someParameters
- * @return
- */
- private static String makeParameterizedSignature(ResolvedType aGenericType,
- ResolvedType[] someParameters) {
- String rawSignature = aGenericType.getErasureSignature();
- StringBuilder ret = new StringBuilder();
- ret.append(PARAMETERIZED_TYPE_IDENTIFIER);
- ret.append(rawSignature.substring(1, rawSignature.length() - 1));
- ret.append("<");
- for (ResolvedType someParameter : someParameters) {
- ret.append(someParameter.getSignature());
- }
- ret.append(">;");
- return ret.toString();
- }
-
- private static String makeDeclaredSignature(ResolvedType aGenericType,
- UnresolvedType[] someParameters) {
- StringBuilder ret = new StringBuilder();
- String rawSig = aGenericType.getErasureSignature();
- ret.append(rawSig.substring(0, rawSig.length() - 1));
- ret.append("<");
- for (UnresolvedType someParameter : someParameters) {
- if (someParameter instanceof ReferenceType) {
- ret.append(((ReferenceType) someParameter)
- .getSignatureForAttribute());
- } else if (someParameter instanceof Primitive) {
- ret.append(((Primitive) someParameter)
- .getSignatureForAttribute());
- } else {
- throw new IllegalStateException(
- "DebugFor325731: expected a ReferenceType or Primitive but was "
- + someParameter + " of type "
- + someParameter.getClass().getName());
- }
- }
- ret.append(">;");
- return ret.toString();
- }
-
- @Override
- public void ensureConsistent() {
- annotations = null;
- annotationTypes = null;
- newSuperclass = null;
- bits = 0; // clears the hierarchy complete tag (amongst other things)
- newInterfaces = null;
- typeVariables = null;
- parameterizedInterfaces.clear();
- superclassReference = new WeakReference<>(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<>(null);
- } else {
- if (newInterfaces == null) {
- newInterfaces = new ResolvedType[1];
- newInterfaces[0] = newParent;
- } else {
- ResolvedType[] existing = getDelegate().getDeclaredInterfaces();
- if (existing != null) {
- for (ResolvedType resolvedType : existing) {
- if (resolvedType.equals(newParent)) {
- return; // already has this interface
- }
- }
- }
- 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;
- }
-
- /**
- * Look for a derivative type with the specified type parameters. This can
- * avoid creating an unnecessary new (duplicate) with the same information
- * in it. This method also cleans up any reference entries that have been
- * null'd by a GC.
- *
- * @param typeParameters
- * the type parameters to use when searching for the derivative
- * type.
- * @return an existing derivative type or null if there isn't one
- */
- public ReferenceType findDerivativeType(ResolvedType[] typeParameters) {
- synchronized (derivativeTypes) {
- List<WeakReference<ReferenceType>> forRemoval = new ArrayList<>();
- for (WeakReference<ReferenceType> derivativeTypeRef : derivativeTypes) {
- ReferenceType derivativeType = derivativeTypeRef.get();
- if (derivativeType == null) {
- forRemoval.add(derivativeTypeRef);
- } else {
- if (derivativeType.isRawType()) {
- continue;
- }
- if (equal(derivativeType.typeParameters, typeParameters)) {
- return derivativeType; // this escape route wont remove
- // the empty refs
- }
- }
- }
- derivativeTypes.removeAll(forRemoval);
- }
- return null;
- }
-
- public boolean hasNewInterfaces() {
- return newInterfaces != null;
- }
-
- }
|