12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088 |
- /* *******************************************************************
- * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
- * All rights reserved.
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * PARC initial implementation
- * ******************************************************************/
-
-
- package org.aspectj.weaver;
-
- import java.io.DataOutputStream;
- import java.io.IOException;
- import java.lang.reflect.Modifier;
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.HashMap;
- import java.util.HashSet;
- import java.util.Iterator;
- import java.util.List;
- import java.util.Map;
- import java.util.Set;
-
- import org.aspectj.bridge.ISourceLocation;
-
- /**
- * This is the declared member, i.e. it will always correspond to an
- * actual method/... declaration
- */
-
-
-
- public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, AnnotatedElement, TypeVariableDeclaringElement, ResolvedMember {
-
- // TESTAPI - controlling whether parameter names come out in the debug string (for testing purposes)
- public static boolean showParameterNames = true;
-
- private String[] parameterNames = null;
- protected UnresolvedType[] checkedExceptions = UnresolvedType.NONE; // OPTIMIZE unpack on demand
- // private boolean isAjSynthetic = false;
- protected int start, end;
- protected ISourceContext sourceContext = null;
-
- private int bits;
- private static final int HAS_BACKING_GENERIC_MEMBER = 0x0001;
- private static final int IS_ANNOTATED_ELSEWHERE = 0x0002;
- private static final int IS_ANNOTATED_ELSEWHERE_INV = 0x0ffd;
- private static final int HAVE_CALCULATED_MY_ERASURE = 0x0004;
- private static final int HAS_ERASURE = 0x0008;
- private static final int IS_AJ_SYNTHETIC = 0x0010;
- private static final int IS_AJ_SYNTHETIC_INV = 0x0fef;
-
- protected RMMetaInfo metaInfo;
-
- protected static class RMMetaInfo {
- public ResolvedMember backingGenericMember;
- public ResolvedMember myErasure;
- }
- /**
- * if this member is a parameterized version of a member in a generic type,
- * then this field holds a reference to the member we parameterize.
- */
- // protected ResolvedMember backingGenericMember = null;
-
- protected Set annotationTypes = null;
- protected ResolvedType[][] parameterAnnotationTypes = null;
-
- // Some members are 'created' to represent other things (for example ITDs). These
- // members have their annotations stored elsewhere, and this flag indicates that is
- // the case. It is up to the caller to work out where that is!
- // Once determined the caller may choose to stash the annotations in this member...
- // private boolean isAnnotatedElsewhere = false; // this field is not serialized.
- // generic methods have type variables
- protected TypeVariable[] typeVariables;
- /** converts e.g. <T extends Number>.... List<T> to just Ljava/util/List<T;>;
- * whereas the full signature would be Ljava/util/List<T:Ljava/lang/Number;>;
- */
- private String myParameterSignatureWithBoundsRemoved = null;
- /**
- * converts e.g. <T extends Number>.... List<T> to just Ljava/util/List;
- */
- private String myParameterSignatureErasure = null;
- // private ResolvedMember myErasure = null;
- // private boolean calculatedMyErasure = false;
-
-
-
- //XXX deprecate this in favor of the constructor below
- public ResolvedMemberImpl(
- MemberKind kind,
- UnresolvedType declaringType,
- int modifiers,
- UnresolvedType returnType,
- String name,
- UnresolvedType[] parameterTypes)
- {
- super(kind, declaringType, modifiers, returnType, name, parameterTypes);
- }
-
-
-
- public ResolvedMemberImpl(
- MemberKind kind,
- UnresolvedType declaringType,
- int modifiers,
- UnresolvedType returnType,
- String name,
- UnresolvedType[] parameterTypes,
- UnresolvedType[] checkedExceptions)
- {
- super(kind, declaringType, modifiers, returnType, name, parameterTypes);
- this.checkedExceptions = checkedExceptions;
- }
-
- public ResolvedMemberImpl(
- MemberKind kind,
- UnresolvedType declaringType,
- int modifiers,
- UnresolvedType returnType,
- String name,
- UnresolvedType[] parameterTypes,
- UnresolvedType[] checkedExceptions,
- ResolvedMember backingGenericMember)
- {
- this(kind, declaringType, modifiers, returnType, name, parameterTypes,checkedExceptions);
- metaInfo= new RMMetaInfo();
- bits|=HAS_BACKING_GENERIC_MEMBER;
- metaInfo.backingGenericMember = backingGenericMember;
- if (backingGenericMember.isAjSynthetic()) bits|=IS_AJ_SYNTHETIC;
- // this.isAjSynthetic = backingGenericMember.isAjSynthetic();
- }
-
- public ResolvedMemberImpl(
- MemberKind kind,
- UnresolvedType declaringType,
- int modifiers,
- String name,
- String signature)
- {
- super(kind, declaringType, modifiers, name, signature);
- }
-
- /**
- * Compute the full set of signatures for a member. This walks up the hierarchy
- * giving the ResolvedMember in each defining type in the hierarchy. A shadowMember
- * can be created with a target type (declaring type) that does not actually define
- * the member. This is ok as long as the member is inherited in the declaring type.
- * Each declaring type in the line to the actual declaring type is added as an additional
- * signature. For example:
- *
- * class A { void foo(); }
- * class B extends A {}
- *
- * shadowMember : void B.foo()
- *
- * gives { void B.foo(), void A.foo() }
- * @param joinPointSignature
- * @param inAWorld
- */
- public static JoinPointSignature[] getJoinPointSignatures(Member joinPointSignature, World inAWorld) {
-
- // Walk up hierarchy creating one member for each type up to and including the
- // first defining type
- ResolvedType originalDeclaringType = joinPointSignature.getDeclaringType().resolve(inAWorld);
- ResolvedMemberImpl firstDefiningMember = (ResolvedMemberImpl) joinPointSignature.resolve(inAWorld);
- if (firstDefiningMember == null) {
- return new JoinPointSignature[0];
- }
- // declaringType can be unresolved if we matched a synthetic member generated by Aj...
- // should be fixed elsewhere but add this resolve call on the end for now so that we can
- // focus on one problem at a time...
- ResolvedType firstDefiningType = firstDefiningMember.getDeclaringType().resolve(inAWorld);
- if (firstDefiningType != originalDeclaringType) {
- if (joinPointSignature.getKind() == Member.CONSTRUCTOR) {
- return new JoinPointSignature[0];
- }
- // else if (shadowMember.isStatic()) {
- // return new ResolvedMember[] {firstDefiningMember};
- // }
- }
-
- List declaringTypes = new ArrayList();
- accumulateTypesInBetween(originalDeclaringType,
- firstDefiningType,
- declaringTypes);
- Set memberSignatures = new HashSet();
- for (Iterator iter = declaringTypes.iterator(); iter.hasNext();) {
- ResolvedType declaringType = (ResolvedType) iter.next();
- ResolvedMember member = firstDefiningMember.withSubstituteDeclaringType(declaringType);
- memberSignatures.add(member);
- }
-
- if (shouldWalkUpHierarchyFor(firstDefiningMember)) {
- // now walk up the hierarchy from the firstDefiningMember and include the signature for
- // every type between the firstDefiningMember and the root defining member.
- Iterator superTypeIterator = firstDefiningType.getDirectSupertypes();
- List typesAlreadyVisited = new ArrayList();
- accumulateMembersMatching(firstDefiningMember,superTypeIterator,typesAlreadyVisited,memberSignatures);
- }
-
- JoinPointSignature[] ret = new JoinPointSignature[memberSignatures.size()];
- memberSignatures.toArray(ret);
- return ret;
- }
-
- private static boolean shouldWalkUpHierarchyFor(Member aMember) {
- if (aMember.getKind() == Member.CONSTRUCTOR) return false;
- if (aMember.getKind() == Member.FIELD) return false;
- if (aMember.isStatic()) return false;
- return true;
- }
-
- /**
- * Build a list containing every type between subtype and supertype, inclusively.
- */
- private static void accumulateTypesInBetween(ResolvedType subType, ResolvedType superType, List types) {
- types.add(subType);
- if (subType == superType) {
- return;
- } else {
- for (Iterator iter = subType.getDirectSupertypes(); iter.hasNext();) {
- ResolvedType parent = (ResolvedType) iter.next();
- if (superType.isAssignableFrom(parent)) {
- accumulateTypesInBetween(parent, superType,types);
- }
- }
- }
- }
-
- /**
- * We have a resolved member, possibly with type parameter references as parameters or return
- * type. We need to find all its ancestor members. When doing this, a type parameter matches
- * regardless of bounds (bounds can be narrowed down the hierarchy).
- */
- private static void accumulateMembersMatching(
- ResolvedMemberImpl memberToMatch,
- Iterator typesToLookIn,
- List typesAlreadyVisited,
- Set foundMembers) {
- while(typesToLookIn.hasNext()) {
- ResolvedType toLookIn = (ResolvedType) typesToLookIn.next();
- if (!typesAlreadyVisited.contains(toLookIn)) {
- typesAlreadyVisited.add(toLookIn);
- ResolvedMemberImpl foundMember = (ResolvedMemberImpl) toLookIn.lookupResolvedMember(memberToMatch,true);
- if (foundMember != null && isVisibleTo(memberToMatch,foundMember)) {
- List declaringTypes = new ArrayList();
- // declaring type can be unresolved if the member can from an ITD...
- ResolvedType resolvedDeclaringType = foundMember.getDeclaringType().resolve(toLookIn.getWorld());
- accumulateTypesInBetween(toLookIn, resolvedDeclaringType, declaringTypes);
- for (Iterator iter = declaringTypes.iterator(); iter.hasNext();) {
- ResolvedType declaringType = (ResolvedType) iter.next();
- // typesAlreadyVisited.add(declaringType);
- ResolvedMember member = foundMember.withSubstituteDeclaringType(declaringType);
- foundMembers.add(member);
- }
- if (toLookIn.isParameterizedType() && foundMember.hasBackingGenericMember()) {
- foundMembers.add(new JoinPointSignature(foundMember.getBackingGenericMember(),foundMember.declaringType.resolve(toLookIn.getWorld())));
- }
- accumulateMembersMatching(foundMember,toLookIn.getDirectSupertypes(),typesAlreadyVisited,foundMembers);
- // if this was a parameterized type, look in the generic type that backs it too
- }
- }
- }
- }
-
- /**
- * Returns true if the parent member is visible to the child member
- * In the same declaring type this is always true, otherwise if parent is private
- * it is false.
- * @param childMember
- * @param parentMember
- * @return
- */
- private static boolean isVisibleTo(ResolvedMember childMember, ResolvedMember parentMember) {
- if (childMember.getDeclaringType().equals(parentMember.getDeclaringType())) return true;
- if (Modifier.isPrivate(parentMember.getModifiers())) {
- return false;
- } else {
- return true;
- }
- }
-
- // ----
-
- public final int getModifiers(World world) {
- return modifiers;
- }
- public final int getModifiers() {
- return modifiers;
- }
-
- // ----
-
-
- public final UnresolvedType[] getExceptions(World world) {
- return getExceptions();
- }
-
- public UnresolvedType[] getExceptions() {
- return checkedExceptions;
- }
-
- public ShadowMunger getAssociatedShadowMunger() {
- return null;
- }
-
- // ??? true or false?
- public boolean isAjSynthetic() {
- return (bits&IS_AJ_SYNTHETIC)!=0;
- // return isAjSynthetic;
- }
-
- protected void setAjSynthetic(boolean b) {
- if (b) bits|=IS_AJ_SYNTHETIC;
- else bits&=IS_AJ_SYNTHETIC_INV;
- // isAjSynthetic= b;
- }
-
- public boolean hasAnnotations() {
- return (annotationTypes!=null);
- }
-
- public boolean hasAnnotation(UnresolvedType ofType) {
- // The ctors don't allow annotations to be specified ... yet - but
- // that doesn't mean it is an error to call this method.
- // Normally the weaver will be working with subtypes of
- // this type - BcelField/BcelMethod
- if (annotationTypes==null) return false;
- return annotationTypes.contains(ofType);
- }
-
- public ResolvedType[] getAnnotationTypes() {
- // The ctors don't allow annotations to be specified ... yet - but
- // that doesn't mean it is an error to call this method.
- // Normally the weaver will be working with subtypes of
- // this type - BcelField/BcelMethod
- if (annotationTypes == null) return null;
- return (ResolvedType[])annotationTypes.toArray(new ResolvedType[]{});
- }
-
- public AnnotationX getAnnotationOfType(UnresolvedType ofType) {
- throw new UnsupportedOperationException("You should resolve this member and call getAnnotationOfType() on the result...");
- }
-
- public AnnotationX[] getAnnotations() {
- if ((bits&HAS_BACKING_GENERIC_MEMBER)!=0 && metaInfo.backingGenericMember!=null) return metaInfo.backingGenericMember.getAnnotations();
- // if (backingGenericMember != null) return backingGenericMember.getAnnotations();
- // return super.getAnnotations();
- throw new IllegalStateException("Unable to answer getAnnotations() for "+this.toString());
- }
-
- public void setAnnotationTypes(UnresolvedType[] annotationtypes) {
- if (annotationTypes == null) annotationTypes = new HashSet();
- for (int i = 0; i < annotationtypes.length; i++) {
- UnresolvedType typeX = annotationtypes[i];
- annotationTypes.add(typeX);
- }
- }
-
- public ResolvedType[][] getParameterAnnotationTypes() {
- if (parameterAnnotationTypes == null) return null;
- return parameterAnnotationTypes;
- }
-
- public AnnotationX[][] getParameterAnnotations() {
- if (hasBackingGenericMember()) return getBackingGenericMember().getParameterAnnotations();
- throw new IllegalStateException("Only a resolvedmember with backing generic member can answer this. Member="+toString());
- }
-
- public void addAnnotation(AnnotationX annotation) {
- // FIXME asc only allows for annotation types, not instances - should it?
- if (annotationTypes == null) annotationTypes = new HashSet();
- annotationTypes.add(annotation.getSignature());
- }
-
- public boolean isBridgeMethod() {
- return (modifiers & Constants.ACC_BRIDGE)!=0 && getKind().equals(METHOD);
- }
-
- public boolean isVarargsMethod() {
- return (modifiers & Constants.ACC_VARARGS)!=0;
- }
-
- public void setVarargsMethod() {
- modifiers = modifiers | Constants.ACC_VARARGS;
- }
-
- public boolean isSynthetic() {
- // See Bcelmethod.isSynthetic() which takes account of preJava5 Synthetic modifier
- return (modifiers & 4096)!=0; // do we know better?
- }
-
- public void write(DataOutputStream s) throws IOException {
- getKind().write(s);
- getDeclaringType().write(s);
- s.writeInt(modifiers);
- s.writeUTF(getName());
- s.writeUTF(getSignature());
- UnresolvedType.writeArray(getExceptions(), s);
-
- s.writeInt(getStart());
- s.writeInt(getEnd());
- s.writeBoolean(isVarargsMethod());
-
- // Write out any type variables...
- if (typeVariables==null) {
- s.writeInt(0);
- } else {
- s.writeInt(typeVariables.length);
- for (int i = 0; i < typeVariables.length; i++) {
- typeVariables[i].write(s);
- }
- }
- String gsig = getGenericSignature();
- if (getSignature().equals(gsig)) {
- s.writeBoolean(false);
- } else {
- s.writeBoolean(true);
- s.writeInt(parameterTypes.length);
- for (int i = 0; i < parameterTypes.length; i++) {
- UnresolvedType array_element = parameterTypes[i];
- array_element.write(s);
- }
- returnType.write(s);
- }
- }
-
- public String getGenericSignature() {
- StringBuffer sb = new StringBuffer();
- if (typeVariables!=null) {
- sb.append("<");
- for (int i = 0; i < typeVariables.length; i++) {
- sb.append(typeVariables[i].getSignature());
- }
- sb.append(">");
- }
- sb.append("(");
- for (int i = 0; i < parameterTypes.length; i++) {
- UnresolvedType array_element = parameterTypes[i];
- sb.append(array_element.getSignature());
- }
- sb.append(")");
- sb.append(returnType.getSignature());
- return sb.toString();
- }
-
- public static void writeArray(ResolvedMember[] members, DataOutputStream s) throws IOException {
- s.writeInt(members.length);
- for (int i = 0, len = members.length; i < len; i++) {
- members[i].write(s);
- }
- }
-
-
- public static ResolvedMemberImpl readResolvedMember(VersionedDataInputStream s, ISourceContext sourceContext) throws IOException {
-
- ResolvedMemberImpl m = new ResolvedMemberImpl(MemberKind.read(s), UnresolvedType.read(s), s.readInt(),
- s.readUTF(), s.readUTF());
- m.checkedExceptions = UnresolvedType.readArray(s);
-
- m.start = s.readInt();
- m.end = s.readInt();
- m.sourceContext = sourceContext;
-
-
- if (s.getMajorVersion()>=AjAttribute.WeaverVersionInfo.WEAVER_VERSION_MAJOR_AJ150) {
-
- if (s.getMajorVersion()>=AjAttribute.WeaverVersionInfo.WEAVER_VERSION_MAJOR_AJ150M4) {
- boolean isvarargs = s.readBoolean();
- if (isvarargs) m.setVarargsMethod();
- }
-
- int tvcount = s.readInt();
- if (tvcount!=0) {
- m.typeVariables = new TypeVariable[tvcount];
- for (int i=0;i<tvcount;i++) {
- m.typeVariables[i]=TypeVariable.read(s);
- m.typeVariables[i].setDeclaringElement(m);
- }
- }
- if (s.getMajorVersion()>=AjAttribute.WeaverVersionInfo.WEAVER_VERSION_MAJOR_AJ150M4) {
- boolean hasAGenericSignature = s.readBoolean();
- if (hasAGenericSignature) {
- int ps = s.readInt();
- UnresolvedType[] params = new UnresolvedType[ps];
- for (int i = 0; i < params.length; i++) {
- UnresolvedType type = params[i];
- params[i]=TypeFactory.createTypeFromSignature(s.readUTF());
- }
- UnresolvedType rt = TypeFactory.createTypeFromSignature(s.readUTF());
- m.parameterTypes = params;
- m.returnType = rt;
- }
- }
- }
- return m;
- }
-
- public static ResolvedMember[] readResolvedMemberArray(VersionedDataInputStream s, ISourceContext context) throws IOException {
- int len = s.readInt();
- ResolvedMember[] members = new ResolvedMember[len];
- for (int i=0; i < len; i++) {
- members[i] = ResolvedMemberImpl.readResolvedMember(s, context);
- }
- return members;
- }
-
-
-
- public ResolvedMember resolve(World world) {
- // make sure all the pieces of a resolvedmember really are resolved
- try {
- if (typeVariables!=null && typeVariables.length>0) {
- for (int i = 0; i < typeVariables.length; i++) {
- typeVariables[i] = typeVariables[i].resolve(world);
- }
- }
- world.setTypeVariableLookupScope(this);
- if (annotationTypes!=null) {
- Set r = new HashSet();
- for (Iterator iter = annotationTypes.iterator(); iter.hasNext();) {
- UnresolvedType element = (UnresolvedType) iter.next();
- r.add(world.resolve(element));
- }
- annotationTypes = r;
- }
- declaringType = declaringType.resolve(world);
- if (declaringType.isRawType()) declaringType = ((ReferenceType)declaringType).getGenericType();
-
-
- if (parameterTypes!=null && parameterTypes.length>0) {
- for (int i = 0; i < parameterTypes.length; i++) {
- parameterTypes[i] = parameterTypes[i].resolve(world);
- }
- }
-
- returnType = returnType.resolve(world);
-
- } finally {
- world.setTypeVariableLookupScope(null);
- }
- return this;
- }
-
- public ISourceContext getSourceContext(World world) {
- return getDeclaringType().resolve(world).getSourceContext();
- }
-
- public String[] getParameterNames() {
- return parameterNames;
- }
- public final void setParameterNames(String[] pnames) {
- parameterNames = pnames;
- }
- public final String[] getParameterNames(World world) {
- return getParameterNames();
- }
-
- public AjAttribute.EffectiveSignatureAttribute getEffectiveSignature() {
- return null;
- }
-
- public ISourceLocation getSourceLocation() {
- //System.out.println("get context: " + this + " is " + sourceContext);
- if (getSourceContext() == null) {
- //System.err.println("no context: " + this);
- return null;
- }
- return getSourceContext().makeSourceLocation(this);
- }
-
- public int getEnd() {
- return end;
- }
-
- public ISourceContext getSourceContext() {
- return sourceContext;
- }
-
- public int getStart() {
- return start;
- }
-
- public void setPosition(int sourceStart, int sourceEnd) {
- this.start = sourceStart;
- this.end = sourceEnd;
- }
-
- public void setDeclaringType(ReferenceType rt) {
- declaringType = rt;
- }
-
- public void setSourceContext(ISourceContext sourceContext) {
- this.sourceContext = sourceContext;
- }
-
- public boolean isAbstract() {
- return Modifier.isAbstract(modifiers);
- }
-
- public boolean isPublic() {
- return Modifier.isPublic(modifiers);
- }
-
- public boolean isProtected() {
- return Modifier.isProtected(modifiers);
- }
-
- public boolean isNative() {
- return Modifier.isNative(modifiers);
- }
-
- public boolean isDefault() {
- return !(isPublic() || isProtected() || isPrivate());
- }
-
- public boolean isVisible(ResolvedType fromType) {
- World world = fromType.getWorld();
- return ResolvedType.isVisible(getModifiers(), getDeclaringType().resolve(world),
- fromType);
- }
- public void setCheckedExceptions(UnresolvedType[] checkedExceptions) {
- this.checkedExceptions = checkedExceptions;
- }
-
- public void setAnnotatedElsewhere(boolean b) {
- if (b) bits|=IS_ANNOTATED_ELSEWHERE;
- else bits&=IS_ANNOTATED_ELSEWHERE_INV;
- // isAnnotatedElsewhere = b;
- }
-
- public boolean isAnnotatedElsewhere() {
- return (bits&IS_ANNOTATED_ELSEWHERE)!=0;
- // return isAnnotatedElsewhere;
- }
-
- /**
- * Get the UnresolvedType for the return type, taking generic signature into account
- */
- public UnresolvedType getGenericReturnType() {
- return getReturnType();
- }
-
- /**
- * Get the TypeXs of the parameter types, taking generic signature into account
- */
- public UnresolvedType[] getGenericParameterTypes() {
- return getParameterTypes();
- }
-
-
- public ResolvedMemberImpl parameterizedWith(UnresolvedType[] typeParameters,ResolvedType newDeclaringType, boolean isParameterized) {
- return parameterizedWith(typeParameters,newDeclaringType,isParameterized,null);
- }
-
-
- /**
- * Return a resolvedmember in which all the type variables in the signature
- * have been replaced with the given bindings.
- * The 'isParameterized' flag tells us whether we are creating a raw type
- * version or not. if (isParameterized) then List<T> will turn into
- * List<String> (for example) - if (!isParameterized) then List<T> will turn
- * into List.
- */
- public ResolvedMemberImpl parameterizedWith(UnresolvedType[] typeParameters,ResolvedType newDeclaringType, boolean isParameterized,List aliases) {
- if (//isParameterized && <-- might need this bit...
- !getDeclaringType().isGenericType()) {
- throw new IllegalStateException("Can't ask to parameterize a member of non-generic type: "+getDeclaringType()+" kind("+getDeclaringType().typeKind+")");
- }
- TypeVariable[] typeVariables = getDeclaringType().getTypeVariables();
- if (isParameterized && (typeVariables.length != typeParameters.length)) {
- throw new IllegalStateException("Wrong number of type parameters supplied");
- }
- Map typeMap = new HashMap();
- boolean typeParametersSupplied = typeParameters!=null && typeParameters.length>0;
- if (typeVariables!=null) {
- // If no 'replacements' were supplied in the typeParameters array then collapse
- // type variables to their first bound.
- for (int i = 0; i < typeVariables.length; i++) {
- UnresolvedType ut = (!typeParametersSupplied?typeVariables[i].getFirstBound():typeParameters[i]);
- typeMap.put(typeVariables[i].getName(),ut);
- }
- }
- // For ITDs on generic types that use type variables from the target type, the aliases
- // record the alternative names used throughout the ITD expression that must map to
- // the same value as the type variables real name.
- if (aliases!=null) {
- int posn = 0;
- for (Iterator iter = aliases.iterator(); iter.hasNext();) {
- String typeVariableAlias = (String) iter.next();
- typeMap.put(typeVariableAlias,(!typeParametersSupplied?typeVariables[posn].getFirstBound():typeParameters[posn]));
- posn++;
- }
- }
-
- UnresolvedType parameterizedReturnType = parameterize(getGenericReturnType(),typeMap,isParameterized);
- UnresolvedType[] parameterizedParameterTypes = new UnresolvedType[getGenericParameterTypes().length];
- UnresolvedType[] genericParameterTypes = getGenericParameterTypes();
- for (int i = 0; i < parameterizedParameterTypes.length; i++) {
- parameterizedParameterTypes[i] =
- parameterize(genericParameterTypes[i], typeMap,isParameterized);
- }
- ResolvedMemberImpl ret = new ResolvedMemberImpl(
- getKind(),
- newDeclaringType,
- getModifiers(),
- parameterizedReturnType,
- getName(),
- parameterizedParameterTypes,
- getExceptions(),
- this
- );
- ret.setTypeVariables(getTypeVariables());
- ret.setSourceContext(getSourceContext());
- ret.setPosition(getStart(),getEnd());
- ret.setParameterNames(getParameterNames());
- return ret;
- }
-
-
- /**
- * Replace occurrences of type variables in the signature with values contained in the map. The map is of the form A=String,B=Integer and
- * so a signature List<A> Foo.m(B i) {} would become List<String> Foo.m(Integer i) {}
- */
- public ResolvedMember parameterizedWith(Map m, World w) {
- // if (//isParameterized && <-- might need this bit...
- // !getDeclaringType().isGenericType()) {
- // throw new IllegalStateException("Can't ask to parameterize a member of non-generic type: "+getDeclaringType()+" kind("+getDeclaringType().typeKind+")");
- // }
- declaringType = declaringType.resolve(w);
- if (declaringType.isRawType()) declaringType = ((ResolvedType)declaringType).getGenericType();
- TypeVariable[] typeVariables = getDeclaringType().getTypeVariables();
- // if (isParameterized && (typeVariables.length != typeParameters.length)) {
- // throw new IllegalStateException("Wrong number of type parameters supplied");
- // }
- // Map typeMap = new HashMap();
- // boolean typeParametersSupplied = typeParameters!=null && typeParameters.length>0;
- // if (typeVariables!=null) {
- // // If no 'replacements' were supplied in the typeParameters array then collapse
- // // type variables to their first bound.
- // for (int i = 0; i < typeVariables.length; i++) {
- // UnresolvedType ut = (!typeParametersSupplied?typeVariables[i].getFirstBound():typeParameters[i]);
- // typeMap.put(typeVariables[i].getName(),ut);
- // }
- // }
- // // For ITDs on generic types that use type variables from the target type, the aliases
- // // record the alternative names used throughout the ITD expression that must map to
- // // the same value as the type variables real name.
- // if (aliases!=null) {
- // int posn = 0;
- // for (Iterator iter = aliases.iterator(); iter.hasNext();) {
- // String typeVariableAlias = (String) iter.next();
- // typeMap.put(typeVariableAlias,(!typeParametersSupplied?typeVariables[posn].getFirstBound():typeParameters[posn]));
- // posn++;
- // }
- // }
-
- UnresolvedType parameterizedReturnType = parameterize(getGenericReturnType(),m,true,w);
- UnresolvedType[] parameterizedParameterTypes = new UnresolvedType[getGenericParameterTypes().length];
- UnresolvedType[] genericParameterTypes = getGenericParameterTypes();
- for (int i = 0; i < parameterizedParameterTypes.length; i++) {
- parameterizedParameterTypes[i] =
- parameterize(genericParameterTypes[i], m,true,w);
- }
- ResolvedMemberImpl ret = new ResolvedMemberImpl(
- getKind(),
- declaringType,
- getModifiers(),
- parameterizedReturnType,
- getName(),
- parameterizedParameterTypes,
- getExceptions(),
- this
- );
- ret.setTypeVariables(getTypeVariables());
- ret.setSourceContext(getSourceContext());
- ret.setPosition(getStart(),getEnd());
- ret.setParameterNames(getParameterNames());
- return ret;
- }
-
- public void setTypeVariables(TypeVariable[] tvars) {
- typeVariables = tvars;
- }
-
- public TypeVariable[] getTypeVariables() {
- return typeVariables;
- }
-
- protected UnresolvedType parameterize(UnresolvedType aType, Map typeVariableMap, boolean inParameterizedType) {
- return parameterize(aType,typeVariableMap,inParameterizedType,null);
- }
-
- protected UnresolvedType parameterize(UnresolvedType aType, Map typeVariableMap, boolean inParameterizedType,World w) {
- if (aType instanceof TypeVariableReference) {
- String variableName = ((TypeVariableReference)aType).getTypeVariable().getName();
- if (!typeVariableMap.containsKey(variableName)) {
- return aType; // if the type variable comes from the method (and not the type) thats OK
- }
- return (UnresolvedType) typeVariableMap.get(variableName);
- } else if (aType.isParameterizedType()) {
- if (inParameterizedType) {
- // if (!(getDeclaringType() instanceof ResolvedType)) {
- // int stop = 1;
- // }
- if (aType instanceof UnresolvedType) {
- if (w!=null) aType = aType.resolve(w);
- else {
- aType= aType.resolve(((ResolvedType)getDeclaringType()).getWorld());
- }
- }
- return aType.parameterize(typeVariableMap);
- } else {
- return aType.getRawType();
- }
- } else if (aType.isArray()) {
- // The component type might be a type variable (pr150095)
- int dims = 1;
- String sig = aType.getSignature();
- while (sig.charAt(dims)=='[') dims++;
- UnresolvedType componentSig = UnresolvedType.forSignature(sig.substring(dims));
- UnresolvedType arrayType = ResolvedType.makeArray(parameterize(componentSig,typeVariableMap,inParameterizedType),dims);
- return arrayType;
- }
- return aType;
- }
-
-
- /**
- * If this member is defined by a parameterized super-type, return the erasure
- * of that member.
- * For example:
- * interface I<T> { T foo(T aTea); }
- * class C implements I<String> {
- * String foo(String aString) { return "something"; }
- * }
- * The resolved member for C.foo has signature String foo(String). The
- * erasure of that member is Object foo(Object) -- use upper bound of type
- * variable.
- * A type is a supertype of itself.
- */
- public ResolvedMember getErasure() {
- if ((bits&HAVE_CALCULATED_MY_ERASURE)!=0) {
- if ((bits&HAS_ERASURE)!=0) return metaInfo.myErasure;
- return null;
- // return myErasure;
- }
- bits|=HAVE_CALCULATED_MY_ERASURE;
- // if (calculatedMyErasure) return myErasure;
- // calculatedMyErasure = true;
- ResolvedType resolvedDeclaringType = (ResolvedType) getDeclaringType();
- // this next test is fast, and the result is cached.
- if (!resolvedDeclaringType.hasParameterizedSuperType()) {
- return null;
- } else {
- // we have one or more parameterized super types.
- // this member may be defined by one of them... we need to find out.
- Collection declaringTypes = this.getDeclaringTypes(resolvedDeclaringType.getWorld());
- for (Iterator iter = declaringTypes.iterator(); iter.hasNext();) {
- ResolvedType aDeclaringType = (ResolvedType) iter.next();
- if (aDeclaringType.isParameterizedType()) {
- // we've found the (a?) parameterized type that defines this member.
- // now get the erasure of it
- ResolvedMemberImpl matchingMember = (ResolvedMemberImpl) aDeclaringType.lookupMemberNoSupers(this);
- if (matchingMember != null && matchingMember.hasBackingGenericMember()) {
- ResolvedMember myErasure = matchingMember.getBackingGenericMember();
- if (myErasure!=null) {
- bits|=HAS_ERASURE;
- if (metaInfo == null) metaInfo = new RMMetaInfo();
- metaInfo.myErasure = myErasure;
- }
- return myErasure;
- }
- }
- }
- }
- return null;
- }
-
-
- public boolean hasBackingGenericMember() {
- if ((bits&HAS_BACKING_GENERIC_MEMBER)==0) return false;
- return metaInfo.backingGenericMember!=null;
- }
-
- public ResolvedMember getBackingGenericMember() {
- if ((bits&HAS_BACKING_GENERIC_MEMBER)==0) return null;
- return metaInfo.backingGenericMember;
- }
-
- /**
- * For ITDs, we use the default factory methods to build a resolved member, then alter a couple of characteristics
- * using this method - this is safe.
- */
- public void resetName(String newName) {this.name = newName;}
- public void resetKind(MemberKind newKind) {this.kind=newKind; }
- public void resetModifiers(int newModifiers) {this.modifiers=newModifiers;}
-
- public void resetReturnTypeToObjectArray() {
- returnType = UnresolvedType.OBJECTARRAY;
- }
-
- /**
- * Returns a copy of this member but with the declaring type swapped.
- * Copy only needs to be shallow.
- * @param newDeclaringType
- */
- public JoinPointSignature withSubstituteDeclaringType(ResolvedType newDeclaringType) {
- JoinPointSignature ret = new JoinPointSignature(this,newDeclaringType);
- return ret;
- }
-
- /**
- * Returns true if this member matches the other. The matching takes into account
- * name and parameter types only. When comparing parameter types, we allow any type
- * variable to match any other type variable regardless of bounds.
- */
- public boolean matches(ResolvedMember aCandidateMatch) {
- ResolvedMemberImpl candidateMatchImpl = (ResolvedMemberImpl)aCandidateMatch;
- if (!getName().equals(aCandidateMatch.getName())) return false;
- UnresolvedType[] myParameterTypes = getGenericParameterTypes();
- UnresolvedType[] candidateParameterTypes = aCandidateMatch.getGenericParameterTypes();
- if (myParameterTypes.length != candidateParameterTypes.length) return false;
- String myParameterSignature = getParameterSigWithBoundsRemoved();
- String candidateParameterSignature = candidateMatchImpl.getParameterSigWithBoundsRemoved();
- if (myParameterSignature.equals(candidateParameterSignature)) {
- return true;
- } else {
- // try erasure
- myParameterSignature = getParameterSigErasure();
- candidateParameterSignature = candidateMatchImpl.getParameterSigErasure();
- return myParameterSignature.equals(candidateParameterSignature);
- }
- }
-
-
- // does NOT produce a meaningful java signature, but does give a unique string suitable for
- // comparison.
- private String getParameterSigWithBoundsRemoved() {
- if (myParameterSignatureWithBoundsRemoved != null) return myParameterSignatureWithBoundsRemoved;
- StringBuffer sig = new StringBuffer();
- UnresolvedType[] myParameterTypes = getGenericParameterTypes();
- for (int i = 0; i < myParameterTypes.length; i++) {
- appendSigWithTypeVarBoundsRemoved(myParameterTypes[i], sig, new HashSet());
- }
- myParameterSignatureWithBoundsRemoved = sig.toString();
- return myParameterSignatureWithBoundsRemoved;
- }
-
- private String getParameterSigErasure() {
- if (myParameterSignatureErasure != null) return myParameterSignatureErasure;
- StringBuffer sig = new StringBuffer();
- UnresolvedType[] myParameterTypes = getParameterTypes();
- for (int i = 0; i < myParameterTypes.length; i++) {
- UnresolvedType thisParameter = myParameterTypes[i];
- if (thisParameter.isTypeVariableReference()) {
- sig.append(thisParameter.getUpperBound().getSignature());
- } else {
- sig.append(thisParameter.getSignature());
- }
- }
- myParameterSignatureErasure = sig.toString();
- return myParameterSignatureErasure;
- }
-
- // does NOT produce a meaningful java signature, but does give a unique string suitable for
- // comparison.
- public static void appendSigWithTypeVarBoundsRemoved(UnresolvedType aType, StringBuffer toBuffer, Set alreadyUsedTypeVars) {
- if (aType.isTypeVariableReference()) {
- // pr204505
- if (alreadyUsedTypeVars.contains(aType)) {
- toBuffer.append("...");
- } else {
- alreadyUsedTypeVars.add(aType);
- appendSigWithTypeVarBoundsRemoved(aType.getUpperBound(), toBuffer, alreadyUsedTypeVars);
- }
- // toBuffer.append("T;");
- } else if (aType.isParameterizedType()) {
- toBuffer.append(aType.getRawType().getSignature());
- toBuffer.append("<");
- for (int i = 0; i < aType.getTypeParameters().length; i++) {
- appendSigWithTypeVarBoundsRemoved(aType.getTypeParameters()[i], toBuffer, alreadyUsedTypeVars);
- }
- toBuffer.append(">;");
- } else {
- toBuffer.append(aType.getSignature());
- }
- }
-
- /**
- * Useful for writing tests, returns *everything* we know about this member.
- */
- public String toDebugString() {
- StringBuffer r = new StringBuffer();
-
- // modifiers
- int mods = modifiers;
- if ((mods & 4096)>0) mods = mods -4096; // remove synthetic (added in the ASM case but not in the BCEL case...)
- if ((mods & 512)>0) mods = mods -512; // remove interface (added in the BCEL case but not in the ASM case...)
- if ((mods & 131072)>0) mods = mods -131072; // remove deprecated (added in the ASM case but not in the BCEL case...)
- String modsStr = Modifier.toString(mods);
- if (modsStr.length()!=0) r.append(modsStr).append("("+mods+")").append(" ");
-
- // type variables
- if (typeVariables!=null && typeVariables.length>0) {
- r.append("<");
- for (int i = 0; i < typeVariables.length; i++) {
- if (i>0) r.append(",");
- TypeVariable t = typeVariables[i];
- r.append(t.toDebugString());
- }
- r.append("> ");
- }
-
- // 'declaring' type
- r.append(getGenericReturnType().toDebugString());
- r.append(' ');
-
- // name
- r.append(declaringType.getName());
- r.append('.');
- r.append(name);
-
- // parameter signature if a method
- if (kind != FIELD) {
- r.append("(");
- UnresolvedType[] params = getGenericParameterTypes();
- boolean parameterNamesExist = showParameterNames && parameterNames!=null && parameterNames.length==params.length;
- if (params.length != 0) {
- for (int i=0, len = params.length; i < len; i++) {
- if (i>0) r.append(", ");
- r.append(params[i].toDebugString());
- if (parameterNamesExist) r.append(" ").append(parameterNames[i]);
- }
- }
- r.append(")");
- }
- return r.toString();
- }
-
- public String toGenericString() {
- StringBuffer buf = new StringBuffer();
- buf.append(getGenericReturnType().getSimpleName());
- buf.append(' ');
- buf.append(declaringType.getName());
- buf.append('.');
- buf.append(name);
- if (kind != FIELD) {
- buf.append("(");
- UnresolvedType[] params = getGenericParameterTypes();
- if (params.length != 0) {
- buf.append(params[0].getSimpleName());
- for (int i=1, len = params.length; i < len; i++) {
- buf.append(", ");
- buf.append(params[i].getSimpleName());
- }
- }
- buf.append(")");
- }
- return buf.toString();
- }
-
-
-
- public TypeVariable getTypeVariableNamed(String name) {
- // Check locally...
- if (typeVariables!=null) {
- for (int i = 0; i < typeVariables.length; i++) {
- if (typeVariables[i].getName().equals(name)) return typeVariables[i];
- }
- }
- // check the declaring type!
- return declaringType.getTypeVariableNamed(name);
-
- // Do generic aspects with ITDs that share type variables with the aspect and the target type and have their own tvars cause this to be messier?
- }
-
- public void evictWeavingState() { }
-
- public String getAnnotationDefaultValue() {
- throw new UnsupportedOperationException("You should resolve this member and call getAnnotationDefaultValue() on the result...");
- }
- }
-
|