diff options
19 files changed, 493 insertions, 408 deletions
diff --git a/weaver/src/org/aspectj/weaver/Advice.java b/weaver/src/org/aspectj/weaver/Advice.java index 21e6ab1ee..0e70432f0 100644 --- a/weaver/src/org/aspectj/weaver/Advice.java +++ b/weaver/src/org/aspectj/weaver/Advice.java @@ -38,7 +38,7 @@ public abstract class Advice extends ShadowMunger { protected TypePattern exceptionType; // just for Softener kind public static Advice makeCflowEntry(World world, Pointcut entry, boolean isBelow, Member stackField, int nFreeVars, List innerCflowEntries, ResolvedType inAspect){ - Advice ret = world.concreteAdvice(isBelow ? AdviceKind.CflowBelowEntry : AdviceKind.CflowEntry, + Advice ret = world.createAdviceMunger(isBelow ? AdviceKind.CflowBelowEntry : AdviceKind.CflowEntry, entry, stackField, 0, entry); //0); ret.innerCflowEntries = innerCflowEntries; @@ -50,7 +50,7 @@ public abstract class Advice extends ShadowMunger { public static Advice makePerCflowEntry(World world, Pointcut entry, boolean isBelow, Member stackField, ResolvedType inAspect, List innerCflowEntries) { - Advice ret = world.concreteAdvice(isBelow ? AdviceKind.PerCflowBelowEntry : AdviceKind.PerCflowEntry, + Advice ret = world.createAdviceMunger(isBelow ? AdviceKind.PerCflowBelowEntry : AdviceKind.PerCflowEntry, entry, stackField, 0, entry); ret.innerCflowEntries = innerCflowEntries; ret.concreteAspect = inAspect; @@ -60,7 +60,7 @@ public abstract class Advice extends ShadowMunger { public static Advice makePerObjectEntry(World world, Pointcut entry, boolean isThis, ResolvedType inAspect) { - Advice ret = world.concreteAdvice(isThis ? AdviceKind.PerThisEntry : AdviceKind.PerTargetEntry, + Advice ret = world.createAdviceMunger(isThis ? AdviceKind.PerThisEntry : AdviceKind.PerTargetEntry, entry, null, 0, entry); ret.concreteAspect = inAspect; @@ -69,13 +69,13 @@ public abstract class Advice extends ShadowMunger { // PTWIMPL per type within entry advice is what initializes the aspect instance in the matched type public static Advice makePerTypeWithinEntry(World world, Pointcut p, ResolvedType inAspect) { - Advice ret = world.concreteAdvice(AdviceKind.PerTypeWithinEntry,p,null,0,p); + Advice ret = world.createAdviceMunger(AdviceKind.PerTypeWithinEntry,p,null,0,p); ret.concreteAspect = inAspect; return ret; } public static Advice makeSoftener(World world, Pointcut entry, TypePattern exceptionType,ResolvedType inAspect,IHasSourceLocation loc) { - Advice ret = world.concreteAdvice(AdviceKind.Softener, entry, null, 0, loc); + Advice ret = world.createAdviceMunger(AdviceKind.Softener, entry, null, 0, loc); ret.exceptionType = exceptionType; ret.concreteAspect = inAspect; @@ -241,7 +241,7 @@ public abstract class Advice extends ShadowMunger { p.m_ignoreUnboundBindingForNames =oldP.m_ignoreUnboundBindingForNames; } - Advice munger = world.concreteAdvice(attribute, p, signature); + Advice munger = world.createAdviceMunger(attribute, p, signature); munger.concreteAspect = fromType; //System.err.println("concretizing here " + p + " with clause " + clause); return munger; diff --git a/weaver/src/org/aspectj/weaver/AjAttribute.java b/weaver/src/org/aspectj/weaver/AjAttribute.java index 8b00f3d04..01b60c581 100644 --- a/weaver/src/org/aspectj/weaver/AjAttribute.java +++ b/weaver/src/org/aspectj/weaver/AjAttribute.java @@ -480,7 +480,7 @@ public abstract class AjAttribute { } public Advice reify(Member signature, World world) { - return world.concreteAdvice(this, pointcut, signature); + return world.createAdviceMunger(this, pointcut, signature); } public String toString() { diff --git a/weaver/src/org/aspectj/weaver/Checker.java b/weaver/src/org/aspectj/weaver/Checker.java index e84e199be..02678d535 100644 --- a/weaver/src/org/aspectj/weaver/Checker.java +++ b/weaver/src/org/aspectj/weaver/Checker.java @@ -58,8 +58,8 @@ public class Checker extends ShadowMunger { world.getMessageHandler().handleMessage(message); - if (world.xrefHandler != null) { - world.xrefHandler.addCrossReference(this.getSourceLocation(), + if (world.getCrossReferenceHandler() != null) { + world.getCrossReferenceHandler().addCrossReference(this.getSourceLocation(), shadow.getSourceLocation(), (this.isError?IRelationship.Kind.DECLARE_ERROR:IRelationship.Kind.DECLARE_WARNING),false); diff --git a/weaver/src/org/aspectj/weaver/CrosscuttingMembers.java b/weaver/src/org/aspectj/weaver/CrosscuttingMembers.java index 1d257c065..a57961db9 100644 --- a/weaver/src/org/aspectj/weaver/CrosscuttingMembers.java +++ b/weaver/src/org/aspectj/weaver/CrosscuttingMembers.java @@ -154,7 +154,7 @@ public class CrosscuttingMembers { if (typeToExpose instanceof ResolvedType) { typeToExpose = ((ResolvedType)typeToExpose).getGenericType(); } else { - typeToExpose = UnresolvedType.forSignature(typeToExpose.getRawTypeSignature()); + typeToExpose = UnresolvedType.forSignature(typeToExpose.getErasureSignature()); } } ResolvedMember member = new ResolvedMember( diff --git a/weaver/src/org/aspectj/weaver/Member.java b/weaver/src/org/aspectj/weaver/Member.java index 345d7e0a3..d84947505 100644 --- a/weaver/src/org/aspectj/weaver/Member.java +++ b/weaver/src/org/aspectj/weaver/Member.java @@ -76,7 +76,7 @@ public class Member implements Comparable, AnnotatedElement { this.name = name; this.parameterTypes = parameterTypes; if (kind == FIELD) { - this.signature = returnType.getRawTypeSignature(); + this.signature = returnType.getErasureSignature(); this.declaredSignature = returnType.getSignature(); } else { this.signature = typesToSignature(returnType, parameterTypes,true); @@ -108,11 +108,11 @@ public class Member implements Comparable, AnnotatedElement { StringBuffer buf = new StringBuffer(); buf.append("("); for (int i = 0, len = paramTypes.length; i < len; i++) { - if (paramTypes[i].isParameterizedType() && useRawTypes) buf.append(paramTypes[i].getRawTypeSignature()); + if (paramTypes[i].isParameterizedType() && useRawTypes) buf.append(paramTypes[i].getErasureSignature()); else buf.append(paramTypes[i].getSignature()); } buf.append(")"); - if (returnType.isParameterizedType() && useRawTypes) buf.append(returnType.getRawTypeSignature()); + if (returnType.isParameterizedType() && useRawTypes) buf.append(returnType.getErasureSignature()); else buf.append(returnType.getSignature()); return buf.toString(); } @@ -481,21 +481,21 @@ public class Member implements Comparable, AnnotatedElement { // ---- things we know only with resolution public int getModifiers(World world) { - return world.getModifiers(this); + return resolve(world).getModifiers(); } public UnresolvedType[] getExceptions(World world) { - return world.getExceptions(this); + return resolve(world).getExceptions(); } public final boolean isProtected(World world) { - return Modifier.isProtected(world.getModifiers(this)); + return Modifier.isProtected(resolve(world).getModifiers()); } public final boolean isStatic(World world) { - return Modifier.isStatic(world.getModifiers(this)); + return Modifier.isStatic(resolve(world).getModifiers()); } public final boolean isStrict(World world) { - return Modifier.isStrict(world.getModifiers(this)); + return Modifier.isStrict(resolve(world).getModifiers()); } public final boolean isStatic() { @@ -854,7 +854,7 @@ public class Member implements Comparable, AnnotatedElement { } public String[] getParameterNames(World world) { - return world.getParameterNames(this); + return resolve(world).getParameterNames(); } diff --git a/weaver/src/org/aspectj/weaver/ReferenceType.java b/weaver/src/org/aspectj/weaver/ReferenceType.java index de65d1d86..9ee460fce 100644 --- a/weaver/src/org/aspectj/weaver/ReferenceType.java +++ b/weaver/src/org/aspectj/weaver/ReferenceType.java @@ -41,7 +41,7 @@ public class ReferenceType extends ResolvedType { int endPos = 0; public static ReferenceType fromTypeX(UnresolvedType tx, World world) { - ReferenceType rt = new ReferenceType(tx.getRawTypeSignature(),world); + ReferenceType rt = new ReferenceType(tx.getErasureSignature(),world); rt.typeKind = tx.typeKind; return rt; } @@ -75,6 +75,22 @@ public class ReferenceType extends ResolvedType { this.delegate = genericReferenceType.getDelegate(); } + /** + * Constructor used when creating a raw type. + */ + public ReferenceType( + ResolvedType theGenericType, + World aWorld) { + super(theGenericType.getErasureSignature(), + theGenericType.getErasureSignature(), + aWorld); + ReferenceType genericReferenceType = (ReferenceType) theGenericType; + this.typeParameters = null; + this.genericType = genericReferenceType; + this.typeKind = TypeKind.RAW; + this.delegate = genericReferenceType.getDelegate(); + } + public String getSignatureForAttribute() { return makeDeclaredSignature(genericType,typeParameters); } @@ -156,7 +172,7 @@ public class ReferenceType extends ResolvedType { public final boolean isAssignableFrom(ResolvedType other) { if (other.isPrimitiveType()) { - if (!world.behaveInJava5Way) return false; + if (!world.isInJava5Mode()) return false; if (ResolvedType.validBoxing.contains(this.getSignature()+other.getSignature())) return true; } if (this == other) return true; @@ -381,7 +397,7 @@ public class ReferenceType extends ResolvedType { * @return */ private static String makeParameterizedSignature(ResolvedType aGenericType, ResolvedType[] someParameters) { - String rawSignature = aGenericType.getRawTypeSignature(); + String rawSignature = aGenericType.getErasureSignature(); String prefix = PARAMETERIZED_TYPE_IDENTIFIER + rawSignature.substring(1,rawSignature.length()-1); StringBuffer ret = new StringBuffer(); @@ -396,7 +412,7 @@ public class ReferenceType extends ResolvedType { private static String makeDeclaredSignature(ResolvedType aGenericType, UnresolvedType[] someParameters) { StringBuffer ret = new StringBuffer(); - String rawSig = aGenericType.getRawTypeSignature(); + String rawSig = aGenericType.getErasureSignature(); ret.append(rawSig.substring(0,rawSig.length()-1)); ret.append("<"); for (int i = 0; i < someParameters.length; i++) { diff --git a/weaver/src/org/aspectj/weaver/ResolvedType.java b/weaver/src/org/aspectj/weaver/ResolvedType.java index f1aa7761e..001125bb4 100644 --- a/weaver/src/org/aspectj/weaver/ResolvedType.java +++ b/weaver/src/org/aspectj/weaver/ResolvedType.java @@ -715,7 +715,7 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl } public final boolean isAssignableFrom(ResolvedType other) { if (!other.isPrimitiveType()) { - if (!world.behaveInJava5Way) return false; + if (!world.isInJava5Mode()) return false; return validBoxing.contains(this.getSignature()+other.getSignature()); } return assignTable[((Primitive)other).index][index]; @@ -1085,7 +1085,7 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl //System.err.println(" is visible"); int c = compareMemberPrecedence(sig, existingMunger.getSignature()); if (c == 0) { - c = getWorld().comparePrecedence(munger.getAspectType(), existingMunger.getAspectType()); + c = getWorld().compareByPrecedenceAndHierarchy(munger.getAspectType(), existingMunger.getAspectType()); } //System.err.println(" compare: " + c); if (c < 0) { @@ -1481,7 +1481,7 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl * Types may have pointcuts just as they have methods and fields. */ public ResolvedPointcutDefinition findPointcut(String name, World world) { - return world.findPointcut(this, name); + throw new UnsupportedOperationException("Not yet implemenented"); } /** @@ -1507,7 +1507,7 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl // version from ResolvedTypeX if (this.equals(OBJECT)) return true; - if (world.behaveInJava5Way) { + if (world.isInJava5Mode()) { if (this.isPrimitiveType()^other.isPrimitiveType()) { // If one is primitive and the other isnt if (validBoxing.contains(this.getSignature()+other.getSignature())) return true; } diff --git a/weaver/src/org/aspectj/weaver/Shadow.java b/weaver/src/org/aspectj/weaver/Shadow.java index 17e519dea..0b6186928 100644 --- a/weaver/src/org/aspectj/weaver/Shadow.java +++ b/weaver/src/org/aspectj/weaver/Shadow.java @@ -479,8 +479,8 @@ public abstract class Shadow { ShadowMunger munger = (ShadowMunger) iter.next(); munger.implementOn(this); - if (world.xrefHandler != null) { - world.xrefHandler.addCrossReference( + if (world.getCrossReferenceHandler() != null) { + world.getCrossReferenceHandler().addCrossReference( munger.getSourceLocation(), // What is being applied this.getSourceLocation(), // Where is it being applied determineRelKind(munger), // What kind of advice? diff --git a/weaver/src/org/aspectj/weaver/TypeFactory.java b/weaver/src/org/aspectj/weaver/TypeFactory.java index 8967f98a5..844442213 100644 --- a/weaver/src/org/aspectj/weaver/TypeFactory.java +++ b/weaver/src/org/aspectj/weaver/TypeFactory.java @@ -48,6 +48,20 @@ public class TypeFactory { return (ReferenceType) pType.resolve(inAWorld); } + public static ReferenceType createRawType( + ResolvedType aBaseType, + World inAWorld + ) { + if (aBaseType.isRawType()) return (ReferenceType) aBaseType; + if (!aBaseType.isGenericType()) { + if (!aBaseType.isRawType()) throw new IllegalStateException("Expecting generic type"); + } + ReferenceType rType = new ReferenceType(aBaseType,inAWorld); + rType.setSourceContext(aBaseType.getSourceContext()); + return (ReferenceType) rType.resolve(inAWorld); + } + + /** * Used by UnresolvedType.read, creates a type from a full signature. * @param signature diff --git a/weaver/src/org/aspectj/weaver/UnresolvedType.java b/weaver/src/org/aspectj/weaver/UnresolvedType.java index 5173b9368..929ae74da 100644 --- a/weaver/src/org/aspectj/weaver/UnresolvedType.java +++ b/weaver/src/org/aspectj/weaver/UnresolvedType.java @@ -338,7 +338,7 @@ public class UnresolvedType { return ret; } - public static UnresolvedType forRawTypeNames(String name) { + public static UnresolvedType forRawTypeName(String name) { UnresolvedType ret = UnresolvedType.forName(name); ret.typeKind = TypeKind.RAW; return ret; @@ -508,13 +508,13 @@ public class UnresolvedType { /** * For parameterized types, return the signature for the raw type */ - public String getRawTypeSignature() { + public String getErasureSignature() { if (signatureErasure==null) return signature; return signatureErasure; } public UnresolvedType getRawType() { - return UnresolvedType.forSignature(getRawTypeSignature()); + return UnresolvedType.forSignature(getErasureSignature()); } diff --git a/weaver/src/org/aspectj/weaver/World.java b/weaver/src/org/aspectj/weaver/World.java index 0f9ca3410..f16077487 100644 --- a/weaver/src/org/aspectj/weaver/World.java +++ b/weaver/src/org/aspectj/weaver/World.java @@ -1,5 +1,6 @@ /* ******************************************************************* * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * 2005 Contributors * All rights reserved. * This program and the accompanying materials are made available * under the terms of the Common Public License v1.0 @@ -7,10 +8,10 @@ * http://www.eclipse.org/legal/cpl-v10.html * * Contributors: - * PARC initial implementation + * PARC initial implementation + * Adrian Colyer, Andy Clement, overhaul for generics * ******************************************************************/ - package org.aspectj.weaver; import java.util.ArrayList; @@ -28,30 +29,57 @@ import org.aspectj.bridge.ISourceLocation; import org.aspectj.bridge.Message; import org.aspectj.bridge.MessageUtil; import org.aspectj.bridge.IMessage.Kind; +import org.aspectj.weaver.UnresolvedType.TypeKind; import org.aspectj.weaver.patterns.DeclarePrecedence; import org.aspectj.weaver.patterns.PerClause; import org.aspectj.weaver.patterns.Pointcut; +/** + * A World is a collection of known types and crosscutting members. + */ public abstract class World implements Dump.INode { - protected IMessageHandler messageHandler = IMessageHandler.SYSTEM_ERR; - protected ICrossReferenceHandler xrefHandler = null; + /** handler for any messages produced during resolution etc. */ + private IMessageHandler messageHandler = IMessageHandler.SYSTEM_ERR; + + /** handler for cross-reference information produced during the weaving process */ + private ICrossReferenceHandler xrefHandler = null; + /** The heart of the world, a map from type signatures to resolved types */ protected TypeMap typeMap = new TypeMap(); // Signature to ResolvedType + + /** Calculator for working out aspect precedence */ + private AspectPrecedenceCalculator precedenceCalculator; - protected CrosscuttingMembersSet crosscuttingMembersSet = new CrosscuttingMembersSet(this); + /** All of the type and shadow mungers known to us */ + private CrosscuttingMembersSet crosscuttingMembersSet = + new CrosscuttingMembersSet(this); - protected IHierarchy model = null; + /** Model holds ASM relationships */ + private IHierarchy model = null; - protected Lint lint = new Lint(this); + /** for processing Xlint messages */ + private Lint lint = new Lint(this); - protected boolean XnoInline; - protected boolean XlazyTjp; - - public boolean behaveInJava5Way = false; + /** XnoInline option setting passed down to weaver */ + private boolean XnoInline; + /** XlazyTjp option setting passed down to weaver */ + private boolean XlazyTjp; + /** When behaving in a Java 5 way autoboxing is considered */ + private boolean behaveInJava5Way = false; + + /** + * A list of RuntimeExceptions containing full stack information for every + * type we couldn't find. + */ private List dumpState_cantFindTypeExceptions = null; + /** + * Play God. + * On the first day, God created the primitive types and put them in the type + * map. + */ protected World() { super(); Dump.registerNode(this.getClass(),this); @@ -64,8 +92,12 @@ public abstract class World implements Dump.INode { typeMap.put("C", ResolvedType.CHAR); typeMap.put("Z", ResolvedType.BOOLEAN); typeMap.put("V", ResolvedType.VOID); + precedenceCalculator = new AspectPrecedenceCalculator(this); } + /** + * Dump processing when a fatal error occurs + */ public void accept (Dump.IVisitor visitor) { visitor.visitString("Shadow mungers:"); visitor.visitList(crosscuttingMembersSet.getShadowMungers()); @@ -79,17 +111,18 @@ public abstract class World implements Dump.INode { dumpState_cantFindTypeExceptions = null; } } + + // ============================================================================= + // T Y P E R E S O L U T I O N + // ============================================================================= - public ResolvedType[] resolve(UnresolvedType[] types) { - if (types == null) return new ResolvedType[0]; - int len = types.length; - ResolvedType[] ret = new ResolvedType[len]; - for (int i=0; i<len; i++) { - ret[i] = resolve(types[i]); - } - return ret; + /** + * Resolve a type that we require to be present in the world + */ + public ResolvedType resolve(UnresolvedType ty) { + return resolve(ty, false); } - + /** * Attempt to resolve a type - the source location gives you some context in which * resolution is taking place. In the case of an error where we can't find the @@ -109,197 +142,228 @@ public abstract class World implements Dump.INode { return ret; } - public ResolvedType resolve(UnresolvedType ty) { - return resolve(ty, false); - } - - // if we already have an rtx, don't re-resolve it - public ResolvedType resolve(ResolvedType ty) { - if (ty.isTypeVariableReference()) return ty; // until type variables have proper sigs... - ResolvedType resolved = typeMap.get(ty.getSignature()); - if (resolved == null) { - typeMap.put(ty.getSignature(), ty); - resolved = ty; - } - return resolved; - } - - public ResolvedType getCoreType(UnresolvedType tx) { - ResolvedType coreTy = resolve(tx,true); - if (coreTy == ResolvedType.MISSING) { - MessageUtil.error(messageHandler, - WeaverMessages.format(WeaverMessages.CANT_FIND_CORE_TYPE,tx.getName())); - } - return coreTy; - } - /** - * Attempt to resolve a type that should be a generic type. + * Convenience method for resolving an array of unresolved types + * in one hit. Useful for e.g. resolving type parameters in signatures. */ - public ResolvedType resolveTheGenericType(UnresolvedType ty, boolean allowMissing) { - // Look up the raw type by signature - String signature = ty.getRawType().getSignature(); - ResolvedType ret = (ResolvedType) typeMap.get(signature); - if (ret==null) { - ret = resolve(UnresolvedType.forSignature(signature)); - typeMap.put(signature,ret); - } - //TODO asc temporary guard - can this ever happen? - if (ret==null) throw new RuntimeException("RAW TYPE IS missing for "+ty); + public ResolvedType[] resolve(UnresolvedType[] types) { + if (types == null) return new ResolvedType[0]; - // Does the raw type know its generic form? (It will if we created the - // raw type from a source type, it won't if its been created just through - // being referenced, e.g. java.util.List - ResolvedType generic = ret.getGenericType(); - if (generic != null) { - generic.world = this; - return generic; - } - - // Fault in the generic that underpins the raw type ;) - ReferenceTypeDelegate thegen = resolveObjectType((ReferenceType)ret); - ReferenceType genericRefType = new ReferenceType( - UnresolvedType.forGenericTypeSignature(ret.getSignature(),thegen.getDeclaredGenericSignature()),this); - ((ReferenceType)ret).setGenericType(genericRefType); - genericRefType.delegate=thegen; - ((ReferenceType)ret).delegate=thegen; - return genericRefType; + ResolvedType[] ret = new ResolvedType[types.length]; + for (int i=0; i<types.length; i++) { + ret[i] = resolve(types[i]); + } + return ret; } + /** + * Resolve a type. This the hub of type resolution. The resolved type is added + * to the type map by signature. + */ public ResolvedType resolve(UnresolvedType ty, boolean allowMissing) { + + // special resolution processing for already resolved types. if (ty instanceof ResolvedType) { ResolvedType rty = (ResolvedType) ty; rty = resolve(rty); - rty.world = this; return rty; } - //System.out.println("resolve: " + ty + " world " + typeMap.keySet()); - if (ty instanceof UnresolvedTypeVariableReferenceType) { - // AMC - don't like this instanceof test, suggests some refactoring needed... - return ((UnresolvedTypeVariableReferenceType)ty).resolve(this); + + // dispatch back to the type variable reference to resolve its constituent parts + // don't do this for other unresolved types otherwise you'll end up in a loop + if (ty.isTypeVariableReference()) { + return ty.resolve(this); } + + // if we've already got a resolved type for the signature, just return it + // after updating the world String signature = ty.getSignature(); ResolvedType ret = typeMap.get(signature); if (ret != null) { ret.world = this; // Set the world for the RTX return ret; - } + } + // no existing resolved type, create one if (ty.isArray()) { - ret = new ResolvedType.Array(signature, this, resolve(ty.getComponentType(), allowMissing)); + ret = new ResolvedType.Array(signature, + this, + resolve(ty.getComponentType(), + allowMissing)); } else { - ret = resolveObjectType(ty); + ret = resolveToReferenceType(ty); if (!allowMissing && ret == ResolvedType.MISSING) { - MessageUtil.error(messageHandler, - WeaverMessages.format(WeaverMessages.CANT_FIND_TYPE,ty.getName())); - if (dumpState_cantFindTypeExceptions==null) { - dumpState_cantFindTypeExceptions = new ArrayList(); - } - dumpState_cantFindTypeExceptions.add(new RuntimeException("Can't find type "+ty.getName())); + handleRequiredMissingTypeDuringResolution(ty); } - } - if (ty.isParameterizedType()) { - for (int i = 0; i < ty.typeParameters.length; i++) { - ty.typeParameters[i] = resolve(ty.typeParameters[i],allowMissing); - } - } - //System.out.println("ret: " + ret); - // Pulling in the type may have already put the right entry in the map - if (typeMap.get(signature)==null && !ResolvedType.MISSING.equals(ret)) { + } + + // Pulling in the type may have already put the right entry in the map + if (typeMap.get(signature)==null && ret != ResolvedType.MISSING) { typeMap.put(signature, ret); } return ret; } + + /** + * We tried to resolve a type and couldn't find it... + */ + private void handleRequiredMissingTypeDuringResolution(UnresolvedType ty) { + MessageUtil.error(messageHandler, + WeaverMessages.format(WeaverMessages.CANT_FIND_TYPE,ty.getName())); + if (dumpState_cantFindTypeExceptions==null) { + dumpState_cantFindTypeExceptions = new ArrayList(); + } + dumpState_cantFindTypeExceptions.add(new RuntimeException("Can't find type "+ty.getName())); + } - //XXX helper method might be bad + /** + * Some TypeFactory operations create resolved types directly, but these won't be + * in the typeMap - this resolution process puts them there. Resolved types are + * also told their world which is needed for the special autoboxing resolved types. + */ + public ResolvedType resolve(ResolvedType ty) { + if (ty.isTypeVariableReference()) return ty; // until type variables have proper sigs... + ResolvedType resolved = typeMap.get(ty.getSignature()); + if (resolved == null) { + typeMap.put(ty.getSignature(), ty); + resolved = ty; + } + resolved.world = this; + return resolved; + } + + /** + * Convenience method for finding a type by name and resolving it in one step. + */ public ResolvedType resolve(String name) { return resolve(UnresolvedType.forName(name)); } - - /* - * Copes with parameterized types. When it sees one then it discovers the - * base type and reuses the delegate + /** + * Resolve to a ReferenceType - simple, raw, parameterized, or generic. + * Raw, parmeterized, and generic versions of a type share a delegate. */ - protected final ResolvedType resolveObjectType(UnresolvedType ty) { + private final ResolvedType resolveToReferenceType(UnresolvedType ty) { if (ty.isParameterizedType()) { - ReferenceType genericType = (ReferenceType)resolveTheGenericType(ty,false); + // ======= parameterized types ================ + ReferenceType genericType = (ReferenceType)resolveGenericTypeFor(ty,false); ReferenceType parameterizedType = TypeFactory.createParameterizedType(genericType, ty.typeParameters, this); return parameterizedType; + } else if (ty.isGenericType()) { - ReferenceType genericType = (ReferenceType)resolveTheGenericType(ty,false); + // ======= generic types ====================== + ReferenceType genericType = (ReferenceType)resolveGenericTypeFor(ty,false); return genericType; + } else { - String signature = ty.getRawTypeSignature(); - ReferenceType name = new ReferenceType(signature/*was ty.getSignature()*/, this); - ReferenceTypeDelegate concreteName = resolveObjectType(name); - if (concreteName == null) return ResolvedType.MISSING; - if (concreteName.isGeneric()) { - // During resolution we have discovered that the underlying type is in fact generic, - // so the thing we thought was a simple type is in fact a raw type. - - ReferenceType genericRefType = new ReferenceType( - UnresolvedType.forGenericTypeSignature(signature,concreteName.getDeclaredGenericSignature()),this); + // ======= simple and raw types =============== + String erasedSignature = ty.getErasureSignature(); + ReferenceType simpleOrRawType = new ReferenceType(erasedSignature, this); + ReferenceTypeDelegate delegate = resolveDelegate(simpleOrRawType); + if (delegate == null) return ResolvedType.MISSING; + + if (delegate.isGeneric()) { + // ======== raw type =========== + simpleOrRawType.typeKind = TypeKind.RAW; + ReferenceType genericType = new ReferenceType( + UnresolvedType.forGenericTypeSignature(erasedSignature,delegate.getDeclaredGenericSignature()),this); // name = ReferenceType.fromTypeX(UnresolvedType.forRawTypeNames(ty.getName()),this); - name.setDelegate(concreteName); - genericRefType.setDelegate(concreteName); - name.setGenericType(genericRefType); - return name; + simpleOrRawType.setDelegate(delegate); + genericType.setDelegate(delegate); + simpleOrRawType.setGenericType(genericType); + return simpleOrRawType; + } else { - name.setDelegate(concreteName); - return name; + // ======== simple type ========= + simpleOrRawType.setDelegate(delegate); + return simpleOrRawType; } } } - - protected abstract ReferenceTypeDelegate resolveObjectType(ReferenceType ty); - - protected final boolean isCoerceableFrom(ResolvedType type, ResolvedType other) { - return type.isCoerceableFrom(other); - } - - protected final boolean isAssignableFrom(ResolvedType type, ResolvedType other) { - return type.isAssignableFrom(other); + /** + * Attempt to resolve a type that should be a generic type. + */ + public ResolvedType resolveGenericTypeFor(UnresolvedType anUnresolvedType, boolean allowMissing) { + // Look up the raw type by signature + String rawSignature = anUnresolvedType.getRawType().getSignature(); + ResolvedType rawType = (ResolvedType) typeMap.get(rawSignature); + if (rawType==null) { + rawType = resolve(UnresolvedType.forSignature(rawSignature),false); + typeMap.put(rawSignature,rawType); + } + + // Does the raw type know its generic form? (It will if we created the + // raw type from a source type, it won't if its been created just through + // being referenced, e.g. java.util.List + ResolvedType genericType = rawType.getGenericType(); + if (genericType != null) { + genericType.world = this; + return genericType; + } else { + // Fault in the generic that underpins the raw type ;) + ReferenceTypeDelegate delegate = resolveDelegate((ReferenceType)rawType); + ReferenceType genericRefType = new ReferenceType( + UnresolvedType.forGenericTypeSignature(rawType.getSignature(),delegate.getDeclaredGenericSignature()),this); + ((ReferenceType)rawType).setGenericType(genericRefType); + genericRefType.setDelegate(delegate); + ((ReferenceType)rawType).setDelegate(delegate); + return genericRefType; + } } - public boolean needsNoConversionFrom(ResolvedType type, ResolvedType other) { - return type.needsNoConversionFrom(other); - } + /** + * Find the ReferenceTypeDelegate behind this reference type so that it can + * fulfill its contract. + */ + protected abstract ReferenceTypeDelegate resolveDelegate(ReferenceType ty); - protected final boolean isInterface(UnresolvedType type) { - return resolve(type).isInterface(); - } - - protected final ResolvedType getSuperclass(UnresolvedType type) { - return resolve(type).getSuperclass(); - } - - protected final UnresolvedType[] getDeclaredInterfaces(UnresolvedType type) { - return resolve(type).getDeclaredInterfaces(); - } - - protected final int getModifiers(UnresolvedType type) { - return resolve(type).getModifiers(); - } - - protected final ResolvedMember[] getDeclaredFields(UnresolvedType type) { - return resolve(type).getDeclaredFields(); - } - - protected final ResolvedMember[] getDeclaredMethods(UnresolvedType type) { - return resolve(type).getDeclaredMethods(); + /** + * Special resolution for "core" types like OBJECT. These are resolved just like + * any other type, but if they are not found it is more serious and we issue an + * error message immediately. + */ + public ResolvedType getCoreType(UnresolvedType tx) { + ResolvedType coreTy = resolve(tx,true); + if (coreTy == ResolvedType.MISSING) { + MessageUtil.error(messageHandler, + WeaverMessages.format(WeaverMessages.CANT_FIND_CORE_TYPE,tx.getName())); + } + return coreTy; } - protected final ResolvedMember[] getDeclaredPointcuts(UnresolvedType type) { - return resolve(type).getDeclaredPointcuts(); - } + /** + * Lookup a type by signature, if not found then build one and put it in the + * map. + */ + public ReferenceType lookupOrCreateName(UnresolvedType ty) { + String signature = ty.getSignature(); + ReferenceType ret = lookupBySignature(signature); + if (ret == null) { + ret = ReferenceType.fromTypeX(ty, this); + typeMap.put(signature, ret); + } + return ret; + } - // ---- members + /** + * Lookup a reference type in the world by its signature. Returns + * null if not found. + */ + public ReferenceType lookupBySignature(String signature) { + return (ReferenceType) typeMap.get(signature); + } + + // ============================================================================= + // T Y P E R E S O L U T I O N -- E N D + // ============================================================================= - // XXX should we worry about dealing with context and looking up access? + /** + * Member resolution is achieved by resolving the declaring type and then + * looking up the member in the resolved declaring type. + */ public ResolvedMember resolve(Member member) { ResolvedType declaring = member.getDeclaringType().resolve(this); ResolvedMember ret; @@ -313,56 +377,22 @@ public abstract class World implements Dump.INode { return declaring.lookupSyntheticMember(member); } - - protected int getModifiers(Member member) { - ResolvedMember r = resolve(member); - if (r == null) throw new BCException("bad resolve of " + member); - return r.getModifiers(); - } - - protected String[] getParameterNames(Member member) { - return resolve(member).getParameterNames(); - } - - protected UnresolvedType[] getExceptions(Member member) { - return resolve(member).getExceptions(); - } - - // ---- pointcuts - - public ResolvedPointcutDefinition findPointcut(UnresolvedType typeX, String name) { - throw new RuntimeException("not implemented yet"); - } - - /** - * Get the shadow mungers of this world. - * - * @return a list of {@link IShadowMunger}s appropriate for this world. - */ - //public abstract List getShadowMungers(); - - // ---- empty world - -// public static final World EMPTY = new World() { -// public List getShadowMungers() { return Collections.EMPTY_LIST; } -// public ResolvedType.ConcreteName resolveObjectType(ResolvedType.Name ty) { -// return null; -// } -// public Advice concreteAdvice(AjAttribute.AdviceAttribute attribute, Pointcut p, Member m) { -// throw new RuntimeException("unimplemented"); -// } -// public ConcreteTypeMunger concreteTypeMunger(ResolvedTypeMunger munger, ResolvedType aspectType) { -// throw new RuntimeException("unimplemented"); -// } -// }; + // Methods for creating various cross-cutting members... + // =========================================================== - public abstract Advice concreteAdvice( + /** + * Create an advice shadow munger from the given advice attribute + */ + public abstract Advice createAdviceMunger( AjAttribute.AdviceAttribute attribute, Pointcut pointcut, Member signature); - public final Advice concreteAdvice( + /** + * Create an advice shadow munger for the given advice kind + */ + public final Advice createAdviceMunger( AdviceKind kind, Pointcut p, Member signature, @@ -371,34 +401,40 @@ public abstract class World implements Dump.INode { { AjAttribute.AdviceAttribute attribute = new AjAttribute.AdviceAttribute(kind, p, extraParameterFlags, loc.getStart(), loc.getEnd(), loc.getSourceContext()); - return concreteAdvice(attribute, p, signature); + return createAdviceMunger(attribute, p, signature); } - - - public ConcreteTypeMunger makeCflowStackFieldAdder(ResolvedMember cflowField) { - throw new RuntimeException("unimplemented"); - } + public abstract ConcreteTypeMunger makeCflowStackFieldAdder(ResolvedMember cflowField); - public ConcreteTypeMunger makeCflowCounterFieldAdder(ResolvedMember cflowField) { - throw new RuntimeException("unimplemented"); - } + public abstract ConcreteTypeMunger makeCflowCounterFieldAdder(ResolvedMember cflowField); /** * Register a munger for perclause @AJ aspect so that we add aspectOf(..) to them as needed * @see org.aspectj.weaver.bcel.BcelWorld#makePerClauseAspect(ResolvedType, org.aspectj.weaver.patterns.PerClause.Kind) - * - * @param aspect - * @param kind - * @return */ - public ConcreteTypeMunger makePerClauseAspect(ResolvedType aspect, PerClause.Kind kind) { - throw new RuntimeException("unimplemented"); - } + public abstract ConcreteTypeMunger makePerClauseAspect(ResolvedType aspect, PerClause.Kind kind); public abstract ConcreteTypeMunger concreteTypeMunger(ResolvedTypeMunger munger, ResolvedType aspectType); /** + * Same signature as org.aspectj.util.PartialOrder.PartialComparable.compareTo + */ + public int compareByPrecedence(ResolvedType aspect1, ResolvedType aspect2) { + return precedenceCalculator.compareByPrecedence(aspect1, aspect2); + } + + /** + * compares by precedence with the additional rule that a super-aspect is + * sorted before its sub-aspects + */ + public int compareByPrecedenceAndHierarchy(ResolvedType aspect1, ResolvedType aspect2) { + return precedenceCalculator.compareByPrecedenceAndHierarchy(aspect1, aspect2); + } + + // simple property getter and setters + // =========================================================== + + /** * Nobody should hold onto a copy of this message handler, or setMessageHandler won't * work right. */ @@ -409,106 +445,38 @@ public abstract class World implements Dump.INode { public void setMessageHandler(IMessageHandler messageHandler) { this.messageHandler = messageHandler; } - - public void setXRefHandler(ICrossReferenceHandler xrefHandler) { - this.xrefHandler = xrefHandler; - } - - public void showMessage( - Kind kind, - String message, - ISourceLocation loc1, - ISourceLocation loc2) - { - if (loc1 != null) { - messageHandler.handleMessage(new Message(message, kind, null, loc1)); - if (loc2 != null) { - messageHandler.handleMessage(new Message(message, kind, null, loc2)); - } - } else { - messageHandler.handleMessage(new Message(message, kind, null, loc2)); - } - } - - - - -// public void addDeclare(ResolvedType onType, Declare declare, boolean forWeaving) { -// // this is not extensible, oh well -// if (declare instanceof DeclareErrorOrWarning) { -// ShadowMunger m = new Checker((DeclareErrorOrWarning)declare); -// onType.addShadowMunger(m); -// } else if (declare instanceof DeclareDominates) { -// declareDominates.add(declare); -// } else if (declare instanceof DeclareParents) { -// declareParents.add(declare); -// } else if (declare instanceof DeclareSoft) { -// DeclareSoft d = (DeclareSoft)declare; -// declareSoft.add(d); -// if (forWeaving) { -// ShadowMunger m = Advice.makeSoftener(this, d.getPointcut().concretize(onType, 0), d.getException()); -// onType.addShadowMunger(m); -// } -// } else { -// throw new RuntimeException("unimplemented"); -// } -// } - /** - * Same signature as org.aspectj.util.PartialOrder.PartialComparable.compareTo + * convenenience method for creating and issuing messages via the message handler */ - public int compareByDominates(ResolvedType aspect1, ResolvedType aspect2) { - //System.out.println("dom compare: " + aspect1 + " with " + aspect2); - //System.out.println(crosscuttingMembersSet.getDeclareDominates()); - - //??? We probably want to cache this result. This is order N where N is the - //??? number of dominates declares in the whole system. - //??? This method can be called a large number of times. - int order = 0; - DeclarePrecedence orderer = null; // Records the declare precedence statement that gives the first ordering - for (Iterator i = crosscuttingMembersSet.getDeclareDominates().iterator(); i.hasNext(); ) { - DeclarePrecedence d = (DeclarePrecedence)i.next(); - int thisOrder = d.compare(aspect1, aspect2); - //System.out.println("comparing: " + thisOrder + ": " + d); - if (thisOrder != 0) { - if (orderer==null) orderer = d; - if (order != 0 && order != thisOrder) { - ISourceLocation[] isls = new ISourceLocation[2]; - isls[0]=orderer.getSourceLocation(); - isls[1]=d.getSourceLocation(); - Message m = - new Message("conflicting declare precedence orderings for aspects: "+ - aspect1.getName()+" and "+aspect2.getName(),null,true,isls); - messageHandler.handleMessage(m); - // throw new BCException("conflicting dominates orders"+d.getSourceLocation()); - } else { - order = thisOrder; + public void showMessage( + Kind kind, + String message, + ISourceLocation loc1, + ISourceLocation loc2) + { + if (loc1 != null) { + messageHandler.handleMessage(new Message(message, kind, null, loc1)); + if (loc2 != null) { + messageHandler.handleMessage(new Message(message, kind, null, loc2)); } + } else { + messageHandler.handleMessage(new Message(message, kind, null, loc2)); } } - - - return order; - } - - - public int comparePrecedence(ResolvedType aspect1, ResolvedType aspect2) { - //System.err.println("compare precedence " + aspect1 + ", " + aspect2); - if (aspect1.equals(aspect2)) return 0; - - int ret = compareByDominates(aspect1, aspect2); - if (ret != 0) return ret; - - if (aspect1.isAssignableFrom(aspect2)) return -1; - else if (aspect2.isAssignableFrom(aspect1)) return +1; - return 0; + + public void setCrossReferenceHandler(ICrossReferenceHandler xrefHandler) { + this.xrefHandler = xrefHandler; } + /** + * Get the cross-reference handler for the world, may be null. + */ + public ICrossReferenceHandler getCrossReferenceHandler() { + return this.xrefHandler; + } - - public List getDeclareParents() { return crosscuttingMembersSet.getDeclareParents(); } @@ -565,63 +533,26 @@ public abstract class World implements Dump.INode { XlazyTjp = b; } - public ReferenceType lookupOrCreateName(UnresolvedType ty) { - String signature = ty.getSignature(); - ReferenceType ret = (ReferenceType)typeMap.get(signature); - if (ret == null) { - ret = ReferenceType.fromTypeX(ty, this); - typeMap.put(signature, ret); - } - return ret; - } + public void setBehaveInJava5Way(boolean b) { + behaveInJava5Way = b; + } - public ReferenceType lookupBySignature(String signature) { - return (ReferenceType) typeMap.get(signature); + public boolean isInJava5Mode() { + return behaveInJava5Way; } - -// public void clearUnexposed() { -// List toRemove = new ArrayList(); -// for (Iterator iter = typeMap.keySet().iterator(); iter.hasNext();) { -// String sig = (String) iter.next(); -// ResolvedType x = (ResolvedType) typeMap.get(sig); -// if (!x.isExposedToWeaver() && (!x.isPrimitive())) toRemove.add(sig); -// } -// for (Iterator iter = toRemove.iterator(); iter.hasNext();) { -// typeMap.remove(iter.next()); -// } -// } -// -// // for testing... -// public void dumpTypeMap() { -// int exposed = 0; -// for (Iterator iter = typeMap.keySet().iterator(); iter.hasNext();) { -// String sig = (String) iter.next(); -// ResolvedType x = (ResolvedType) typeMap.get(sig); -// if (x.isExposedToWeaver()) exposed++; -// } -// System.out.println("type map contains " + typeMap.size() + " entries, " + exposed + " exposed to weaver"); -// } -// -// public void deepDumpTypeMap() { -// for (Iterator iter = typeMap.keySet().iterator(); iter.hasNext();) { -// String sig = (String) iter.next(); -// ResolvedType x = (ResolvedType) typeMap.get(sig); -// if (! (x instanceof ResolvedType.Name)) { -// System.out.println(sig + " -> " + x.getClass().getName() + ", " + x.getClassName()); -// } else { -// ResolvedType.ConcreteName cname = ((ResolvedType.Name)x).getDelegate(); -// System.out.println(sig + " -> " + cname.getClass().getName() + ", " + cname.toString()); -// } -// } -// -// } - - // Map of types in the world, with soft links to expendable ones + /* + * Map of types in the world, with soft links to expendable ones. + * An expendable type is a reference type that is not exposed to the weaver (ie + * just pulled in for type resolution purposes). + */ protected static class TypeMap { + /** Map of types that never get thrown away */ private Map tMap = new HashMap(); + /** Map of types that may be ejected from the cache if we need space */ private Map expendableMap = new WeakHashMap(); + /** Add a new type into the map, the key is the type signature */ public ResolvedType put(String key, ResolvedType type) { if (isExpendable(type)) { return (ResolvedType) expendableMap.put(key,type); @@ -630,18 +561,23 @@ public abstract class World implements Dump.INode { } } + /** Lookup a type by its signature */ public ResolvedType get(String key) { ResolvedType ret = (ResolvedType) tMap.get(key); if (ret == null) ret = (ResolvedType) expendableMap.get(key); return ret; } + /** Remove a type from the map */ public ResolvedType remove(String key) { ResolvedType ret = (ResolvedType) tMap.remove(key); if (ret == null) ret = (ResolvedType) expendableMap.remove(key); return ret; } + /** Reference types we don't intend to weave may be ejected from + * the cache if we need the space. + */ private boolean isExpendable(ResolvedType type) { return ( (type != null) && @@ -669,8 +605,87 @@ public abstract class World implements Dump.INode { return sb.toString(); } } - - public void setBehaveInJava5Way(boolean b) { - behaveInJava5Way = b; - } + + /** + * This class is used to compute and store precedence relationships between + * aspects. + */ + private static class AspectPrecedenceCalculator { + + private World world; + private Map cachedResults; + + public AspectPrecedenceCalculator(World forSomeWorld) { + this.world = forSomeWorld; + this.cachedResults = new HashMap(); + } + + /** + * Ask every declare precedence in the world to order the two aspects. + * If more than one declare precedence gives an ordering, and the orderings + * conflict, then that's an error. + */ + public int compareByPrecedence(ResolvedType firstAspect, ResolvedType secondAspect) { + PrecedenceCacheKey key = new PrecedenceCacheKey(firstAspect,secondAspect); + if (cachedResults.containsKey(key)) { + return ((Integer) cachedResults.get(key)).intValue(); + } else { + int order = 0; + DeclarePrecedence orderer = null; // Records the declare precedence statement that gives the first ordering + for (Iterator i = world.getCrosscuttingMembersSet().getDeclareDominates().iterator(); i.hasNext(); ) { + DeclarePrecedence d = (DeclarePrecedence)i.next(); + int thisOrder = d.compare(firstAspect, secondAspect); + if (thisOrder != 0) { + if (orderer==null) orderer = d; + if (order != 0 && order != thisOrder) { + ISourceLocation[] isls = new ISourceLocation[2]; + isls[0]=orderer.getSourceLocation(); + isls[1]=d.getSourceLocation(); + Message m = + new Message("conflicting declare precedence orderings for aspects: "+ + firstAspect.getName()+" and "+secondAspect.getName(),null,true,isls); + world.getMessageHandler().handleMessage(m); + } else { + order = thisOrder; + } + } + } + cachedResults.put(key, new Integer(order)); + return order; + } + } + + public int compareByPrecedenceAndHierarchy(ResolvedType firstAspect, ResolvedType secondAspect) { + if (firstAspect.equals(secondAspect)) return 0; + + int ret = compareByPrecedence(firstAspect, secondAspect); + if (ret != 0) return ret; + + if (firstAspect.isAssignableFrom(secondAspect)) return -1; + else if (secondAspect.isAssignableFrom(firstAspect)) return +1; + + return 0; + } + + + private static class PrecedenceCacheKey { + public ResolvedType aspect1; + public ResolvedType aspect2; + + public PrecedenceCacheKey(ResolvedType a1, ResolvedType a2) { + this.aspect1 = a1; + this.aspect2 = a2; + } + + public boolean equals(Object obj) { + if (!(obj instanceof PrecedenceCacheKey)) return false; + PrecedenceCacheKey other = (PrecedenceCacheKey) obj; + return (aspect1 == other.aspect1 && aspect2 == other.aspect2); + } + + public int hashCode() { + return aspect1.hashCode() + aspect2.hashCode(); + } + } + } } diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelAdvice.java b/weaver/src/org/aspectj/weaver/bcel/BcelAdvice.java index cca258800..859531650 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelAdvice.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelAdvice.java @@ -509,7 +509,7 @@ public class BcelAdvice extends Advice { World world = concreteAspect.getWorld(); int ret = - concreteAspect.getWorld().compareByDominates( + concreteAspect.getWorld().compareByPrecedence( concreteAspect, o.concreteAspect); if (ret != 0) return ret; diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java b/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java index f0521dd69..790cefee0 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java @@ -737,7 +737,7 @@ public class BcelTypeMunger extends ConcreteTypeMunger { // pr98901 // For copying the annotations across, we have to discover the real member in the aspect // which is holding them. - if (weaver.getWorld().behaveInJava5Way && !onInterface && munger.getSignature().isPublic() && !munger.getSignature().isAbstract()) { + if (weaver.getWorld().isInJava5Mode() && !onInterface && munger.getSignature().isPublic() && !munger.getSignature().isAbstract()) { ResolvedMember realMember = getRealMemberForITDFromAspect(aspectType,dispatchMethod); if (realMember==null) throw new BCException("Couldn't find ITD holder member '"+ dispatchMethod+"' on aspect "+aspectType); diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java b/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java index 009af6499..ffda5ab9a 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java @@ -1000,7 +1000,7 @@ public class BcelWeaver implements IWeaver { // FIXME asc Should be factored out into Xlint code and done automatically for all xlint messages, ideally. // if a piece of advice hasn't matched anywhere and we are in -1.5 mode, put out a warning - if (world.behaveInJava5Way && + if (world.isInJava5Mode() && world.getLint().adviceDidNotMatch.isEnabled()) { List l = world.getCrosscuttingMembersSet().getShadowMungers(); for (Iterator iter = l.iterator(); iter.hasNext();) { diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelWorld.java b/weaver/src/org/aspectj/weaver/bcel/BcelWorld.java index 4de177e33..3cb228677 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelWorld.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelWorld.java @@ -96,7 +96,7 @@ public class BcelWorld extends World implements Repository { //this.aspectPath = new ClassPathManager(aspectPath, handler); this.classPath = new ClassPathManager(classPath, handler); setMessageHandler(handler); - setXRefHandler(xrefHandler); + setCrossReferenceHandler(xrefHandler); // Tell BCEL to use us for resolving any classes delegate = this; // TODO Alex do we need to call org.aspectj.apache.bcel.Repository.setRepository(delegate); @@ -106,7 +106,7 @@ public class BcelWorld extends World implements Repository { public BcelWorld(ClassPathManager cpm, IMessageHandler handler, ICrossReferenceHandler xrefHandler) { this.classPath = cpm; setMessageHandler(handler); - setXRefHandler(xrefHandler); + setCrossReferenceHandler(xrefHandler); // Tell BCEL to use us for resolving any classes delegate = this; // TODO Alex do we need to call org.aspectj.apache.bcel.Repository.setRepository(delegate); @@ -123,7 +123,7 @@ public class BcelWorld extends World implements Repository { public BcelWorld(ClassLoader loader, IMessageHandler handler, ICrossReferenceHandler xrefHandler) { this.classPath = null; setMessageHandler(handler); - setXRefHandler(xrefHandler); + setCrossReferenceHandler(xrefHandler); // Tell BCEL to use us for resolving any classes delegate = new ClassLoaderRepository(loader); // TODO Alex do we need to call org.aspectj.apache.bcel.Repository.setRepository(delegate); @@ -220,7 +220,7 @@ public class BcelWorld extends World implements Repository { } - protected ReferenceTypeDelegate resolveObjectType(ReferenceType ty) { + protected ReferenceTypeDelegate resolveDelegate(ReferenceType ty) { String name = ty.getName(); JavaClass jc = null; //UnwovenClassFile classFile = (UnwovenClassFile)sourceJavaClasses.get(name); @@ -275,7 +275,7 @@ public class BcelWorld extends World implements Repository { if (nameTypeX == null) { if (jc.isGeneric()) { - nameTypeX = ReferenceType.fromTypeX(UnresolvedType.forRawTypeNames(jc.getClassName()),this); + nameTypeX = ReferenceType.fromTypeX(UnresolvedType.forRawTypeName(jc.getClassName()),this); ret = makeBcelObjectType(nameTypeX, jc, true); ReferenceType genericRefType = new ReferenceType( UnresolvedType.forGenericTypeSignature(signature,ret.getDeclaredGenericSignature()),this); @@ -413,7 +413,7 @@ public class BcelWorld extends World implements Repository { return buf.toString(); } - public Advice concreteAdvice( + public Advice createAdviceMunger( AjAttribute.AdviceAttribute attribute, Pointcut pointcut, Member signature) diff --git a/weaver/src/org/aspectj/weaver/bcel/Utility.java b/weaver/src/org/aspectj/weaver/bcel/Utility.java index d83f39f17..6f1f86a58 100644 --- a/weaver/src/org/aspectj/weaver/bcel/Utility.java +++ b/weaver/src/org/aspectj/weaver/bcel/Utility.java @@ -310,7 +310,7 @@ public class Utility { throw new BCException("can't convert from " + fromType + " to " + toType); } // XXX I'm sure this test can be simpler but my brain hurts and this works - if (!toType.getWorld().behaveInJava5Way) { + if (!toType.getWorld().isInJava5Mode()) { if (toType.needsNoConversionFrom(fromType)) return; } else { if (toType.needsNoConversionFrom(fromType) && !(toType.isPrimitiveType()^fromType.isPrimitiveType())) return; @@ -347,7 +347,7 @@ public class Utility { Type.OBJECT, new Type[] { from }, Constants.INVOKESTATIC)); - } else if (toType.getWorld().behaveInJava5Way && validBoxing.get(toType.getSignature()+fromType.getSignature())!=null) { + } else if (toType.getWorld().isInJava5Mode() && validBoxing.get(toType.getSignature()+fromType.getSignature())!=null) { // XXX could optimize by using any java boxing code that may be just before the call... Type from = BcelWorld.makeBcelType(fromType); Type to = BcelWorld.makeBcelType(toType); diff --git a/weaver/src/org/aspectj/weaver/patterns/KindedPointcut.java b/weaver/src/org/aspectj/weaver/patterns/KindedPointcut.java index 25e0b0465..d4e1de80d 100644 --- a/weaver/src/org/aspectj/weaver/patterns/KindedPointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/KindedPointcut.java @@ -125,7 +125,7 @@ public class KindedPointcut extends Pointcut { if (shadow.getIWorld().getLint().noJoinpointsForBridgeMethods.isEnabled()) { ResolvedMember rm = shadow.getSignature().resolve(shadow.getIWorld()); if (rm!=null) { - int shadowModifiers = shadow.getSignature().getModifiers(shadow.getIWorld()); + int shadowModifiers = rm.getModifiers(); //shadow.getSignature().getModifiers(shadow.getIWorld()); if (ResolvedType.hasBridgeModifier(shadowModifiers)) { shadow.getIWorld().getLint().noJoinpointsForBridgeMethods.signal(new String[]{},getSourceLocation(), new ISourceLocation[]{shadow.getSourceLocation()}); @@ -189,7 +189,7 @@ public class KindedPointcut extends Pointcut { // if the method in the declaring type is *not* visible to the // exact declaring type then warning not needed. - int shadowModifiers = shadow.getSignature().getModifiers(world); + int shadowModifiers = shadow.getSignature().resolve(world).getModifiers(); if (!ResolvedType .isVisible( shadowModifiers, diff --git a/weaver/src/org/aspectj/weaver/raw types.txt b/weaver/src/org/aspectj/weaver/raw types.txt new file mode 100644 index 000000000..7cd2dccb1 --- /dev/null +++ b/weaver/src/org/aspectj/weaver/raw types.txt @@ -0,0 +1,40 @@ + +Current situation with respect to raw types... + +* We can create an unresolved type (typeKind = SIMPLE) by + UnresolvedType.forSignature or forName + +* We can create an unresolved type (typeKind = RAW) by calling + UnresolvedType.forRawTypeName + + This method is called by... + + BcelWorld.addSourceObjectType when types in jar files or on the classpath are added to + the weaver for processing. If the JavaClass is determined to be generic then a raw + UnresolvedType is built and a ReferenceType constructed from that. A BcelObjectType is + built using the Resolved raw type (and when it's generic signature is unpacked later that will + be swapped out for the generic type). Then a generic type is created, the delegates of + the generic and raw types are set to point to the BcelObjectType, and the generic type + of the raw type is set to point to the generic type. The raw type is explicitly added into + the typeMap. + + EclipseFactory.addSourceTypeBinding when adding a binding for a generic type during + completeTypeBindings. This is put into the world by calling world.lookupOrCreateName. + Then a generic type is created and the raw type's generic type is set to refer to it. + + EclipseFactory.fromBinding when processing a RawTypeBinding. A later call to resolve + is responsible for adding this to the type map. + +* World.resolve processing works as follows: + + in resolveObjectType, if the typeKind of the UnresolvedType is neither parameterized + nor generic, then a new ReferenceType is created using the rawTypeSignature of the + unresolved type. Then the delegate is created, and if this turns out to be generic then a + generic type is also built and set as the generic type of the reference type (but nothing + sets the type of the reference type to raw???). + + in resolveTheGenericType the rawTypeSignature is looked up in the typeMap. If it + is not found, then a new UnresolvedType is created forSignature, resolved (see above), + and put in the type map. The generic type is then created and set as the generic type + of the raw type. + diff --git a/weaver/testsrc/org/aspectj/weaver/bcel/WorldTestCase.java b/weaver/testsrc/org/aspectj/weaver/bcel/WorldTestCase.java index 494999562..83efcc26d 100644 --- a/weaver/testsrc/org/aspectj/weaver/bcel/WorldTestCase.java +++ b/weaver/testsrc/org/aspectj/weaver/bcel/WorldTestCase.java @@ -96,7 +96,7 @@ public class WorldTestCase extends AbstractWorldTestCase { public void testIterator() { int abstractPublic = Modifier.ABSTRACT | Modifier.PUBLIC; - ResolvedType iter = world.getCoreType(UnresolvedType.forRawTypeNames("java.util.Iterator")); + ResolvedType iter = world.getCoreType(UnresolvedType.forRawTypeName("java.util.Iterator")); modifiersTest(iter, abstractPublic | Modifier.INTERFACE); fieldsTest(iter, ResolvedMember.NONE); |