From: aclement Date: Sun, 12 Oct 2008 21:59:35 +0000 (+0000) Subject: splitting - move world weaver specific operations to an interface X-Git-Tag: PRE_251277~15 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=410753eaa6ed20c3e0120fc1d161bf8f6c724a3b;p=aspectj.git splitting - move world weaver specific operations to an interface --- diff --git a/weaver/src/org/aspectj/weaver/AbstractReferenceTypeDelegate.java b/weaver/src/org/aspectj/weaver/AbstractReferenceTypeDelegate.java index 70bb851eb..a4fa1139f 100644 --- a/weaver/src/org/aspectj/weaver/AbstractReferenceTypeDelegate.java +++ b/weaver/src/org/aspectj/weaver/AbstractReferenceTypeDelegate.java @@ -21,27 +21,29 @@ import org.aspectj.apache.bcel.classfile.Signature.ClassSignature; import org.aspectj.bridge.ISourceLocation; public abstract class AbstractReferenceTypeDelegate implements ReferenceTypeDelegate { - - public final static String UNKNOWN_SOURCE_FILE = ""; // Just randomly picked, happens to match BCEL javaclass default - - private String sourcefilename = UNKNOWN_SOURCE_FILE; // Sourcefilename is stored only here + + private String sourcefilename = UNKNOWN_SOURCE_FILE; + private ISourceContext sourceContext = SourceContextImpl.UNKNOWN_SOURCE_CONTEXT; + protected boolean exposedToWeaver; protected ReferenceType resolvedTypeX; - private ISourceContext sourceContext = SourceContextImpl.UNKNOWN_SOURCE_CONTEXT; protected ClassSignature cachedGenericClassTypeSignature; - public AbstractReferenceTypeDelegate(ReferenceType resolvedTypeX, boolean exposedToWeaver) { - this.resolvedTypeX = resolvedTypeX; - this.exposedToWeaver = exposedToWeaver; - } - + // Happens to match Bcel javaClass default of '' + public final static String UNKNOWN_SOURCE_FILE = ""; + + public AbstractReferenceTypeDelegate(ReferenceType resolvedTypeX, boolean exposedToWeaver) { + this.resolvedTypeX = resolvedTypeX; + this.exposedToWeaver = exposedToWeaver; + } + public final boolean isClass() { - return !isAspect() && !isInterface(); - } + return !isAspect() && !isInterface(); + } /** - * Designed to be overriden by EclipseType to disable collection of shadow mungers - * during pre-weave compilation phase + * Designed to be overriden by EclipseType to disable collection of shadow + * mungers during pre-weave compilation phase */ public boolean doesNotExposeShadowMungers() { return false; @@ -54,54 +56,52 @@ public abstract class AbstractReferenceTypeDelegate implements ReferenceTypeDele public ReferenceType getResolvedTypeX() { return resolvedTypeX; } - - - - public final String getSourcefilename() { - return sourcefilename; - } - - public final void setSourcefilename(String sourceFileName) { - this.sourcefilename = sourceFileName; - if (sourceFileName!=null && sourceFileName.equals(AbstractReferenceTypeDelegate.UNKNOWN_SOURCE_FILE)) { - this.sourcefilename = "Type '"+ getResolvedTypeX().getName()+"' (no debug info available)"; + + public final String getSourcefilename() { + return sourcefilename; + } + + public final void setSourcefilename(String sourceFileName) { + sourcefilename = sourceFileName; + if (sourceFileName != null && sourceFileName.equals(AbstractReferenceTypeDelegate.UNKNOWN_SOURCE_FILE)) { + sourcefilename = "Type '" + getResolvedTypeX().getName() + "' (no debug info available)"; } else { String pname = getResolvedTypeX().getPackageName(); if (pname != null) { - this.sourcefilename = pname.replace('.', '/') + '/' + sourceFileName; + sourcefilename = pname.replace('.', '/') + '/' + sourceFileName; } } - if (this.sourcefilename!=null && sourceContext instanceof SourceContextImpl) { - ((SourceContextImpl)sourceContext).setSourceFileName(this.sourcefilename); + if (sourcefilename != null && sourceContext instanceof SourceContextImpl) { + ((SourceContextImpl) sourceContext).setSourceFileName(sourcefilename); } - } - + } + public ISourceLocation getSourceLocation() { - return getSourceContext().makeSourceLocation(0, 0); + return getSourceContext().makeSourceLocation(0, 0); } - + public ISourceContext getSourceContext() { return sourceContext; } - + public void setSourceContext(ISourceContext isc) { - this.sourceContext = isc; + sourceContext = isc; } public Signature.ClassSignature getGenericClassTypeSignature() { - if (cachedGenericClassTypeSignature==null) { + if (cachedGenericClassTypeSignature == null) { String sig = getDeclaredGenericSignature(); - if (sig!=null) { + if (sig != null) { GenericSignatureParser parser = new GenericSignatureParser(); cachedGenericClassTypeSignature = parser.parseAsClassSignature(sig); } } return cachedGenericClassTypeSignature; } - + protected Signature.FormalTypeParameter[] getFormalTypeParametersFromOuterClass() { List typeParameters = new ArrayList(); - ReferenceType outer = (ReferenceType)getOuterClass(); + ReferenceType outer = (ReferenceType) getOuterClass(); ReferenceTypeDelegate outerDelegate = outer.getDelegate(); AbstractReferenceTypeDelegate outerObjectType = (AbstractReferenceTypeDelegate) outerDelegate; if (outerObjectType.isNested()) { @@ -112,15 +112,14 @@ public abstract class AbstractReferenceTypeDelegate implements ReferenceTypeDele } Signature.ClassSignature outerSig = outerObjectType.getGenericClassTypeSignature(); if (outerSig != null) { - for (int i = 0; i < outerSig.formalTypeParameters .length; i++) { + for (int i = 0; i < outerSig.formalTypeParameters.length; i++) { typeParameters.add(outerSig.formalTypeParameters[i]); } - } - + } + Signature.FormalTypeParameter[] ret = new Signature.FormalTypeParameter[typeParameters.size()]; typeParameters.toArray(ret); return ret; } - } \ No newline at end of file diff --git a/weaver/src/org/aspectj/weaver/Advice.java b/weaver/src/org/aspectj/weaver/Advice.java index 60a90a9c6..a2a19a339 100644 --- a/weaver/src/org/aspectj/weaver/Advice.java +++ b/weaver/src/org/aspectj/weaver/Advice.java @@ -25,7 +25,8 @@ import org.aspectj.weaver.patterns.TypePattern; public abstract class Advice extends ShadowMunger { - protected AjAttribute.AdviceAttribute attribute; // the pointcut field is ignored + protected AjAttribute.AdviceAttribute attribute; // the pointcut field is + // ignored protected AdviceKind kind; // alias of attribute.getKind() protected Member signature; @@ -34,15 +35,20 @@ public abstract class Advice extends ShadowMunger { // not necessarily declaring aspect, this is a semantics change from 1.0 protected ResolvedType concreteAspect; // null until after concretize - protected List innerCflowEntries = Collections.EMPTY_LIST; // just for cflow*Entry kinds + protected List innerCflowEntries = Collections.EMPTY_LIST; // just for + // cflow*Entry + // kinds protected int nFreeVars; // just for cflow*Entry kinds protected TypePattern exceptionType; // just for Softener kind - // if we are parameterized, these type may be different to the advice signature types + // if we are parameterized, these type may be different to the advice + // signature types protected UnresolvedType[] bindingParameterTypes; - protected List/* Lint.Kind */suppressedLintKinds = null; // based on annotations on this advice + protected List/* Lint.Kind */suppressedLintKinds = null; // based on + // annotations on + // this advice ISourceLocation lastReportedMonitorExitJoinpointLocation = null; @@ -73,7 +79,8 @@ public abstract class Advice extends ShadowMunger { return ret; } - // PTWIMPL per type within entry advice is what initializes the aspect instance in the matched type + // 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.createAdviceMunger(AdviceKind.PerTypeWithinEntry, p, null, 0, p); ret.concreteAspect = inAspect; @@ -93,12 +100,12 @@ public abstract class Advice extends ShadowMunger { public Advice(AjAttribute.AdviceAttribute attribute, Pointcut pointcut, Member signature) { super(pointcut, attribute.getStart(), attribute.getEnd(), attribute.getSourceContext()); this.attribute = attribute; - this.kind = attribute.getKind(); // alias + kind = attribute.getKind(); // alias this.signature = signature; if (signature != null) { - this.bindingParameterTypes = signature.getParameterTypes(); + bindingParameterTypes = signature.getParameterTypes(); } else { - this.bindingParameterTypes = new UnresolvedType[0]; + bindingParameterTypes = new UnresolvedType[0]; } } @@ -163,7 +170,8 @@ public abstract class Advice extends ShadowMunger { .getEnclosingType().getName()), getSourceLocation(), shadow.getSourceLocation()); return false; } else { - // System.err.println(getSignature().getReturnType() + " from " + shadow.getReturnType()); + // System.err.println(getSignature().getReturnType() + + // " from " + shadow.getReturnType()); if (getSignature().getReturnType() == ResolvedType.VOID) { if (shadow.getReturnType() != ResolvedType.VOID) { world.showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.NON_VOID_RETURN, shadow), @@ -176,7 +184,12 @@ public abstract class Advice extends ShadowMunger { ResolvedType shadowReturnType = shadow.getReturnType().resolve(world); ResolvedType adviceReturnType = getSignature().getGenericReturnType().resolve(world); - if (shadowReturnType.isParameterizedType() && adviceReturnType.isRawType()) { // Set and Set + if (shadowReturnType.isParameterizedType() && adviceReturnType.isRawType()) { // Set + // < + // Integer + // > + // and + // Set ResolvedType shadowReturnGenericType = shadowReturnType.getGenericType(); // Set ResolvedType adviceReturnGenericType = adviceReturnType.getGenericType(); // Set if (shadowReturnGenericType.isAssignableFrom(adviceReturnGenericType) @@ -186,7 +199,8 @@ public abstract class Advice extends ShadowMunger { new ISourceLocation[] { getSourceLocation() }); } } else if (!shadowReturnType.isAssignableFrom(adviceReturnType)) { - // System.err.println(this + ", " + sourceContext + ", " + start); + // System.err.println(this + ", " + sourceContext + + // ", " + start); world.showMessage(IMessage.ERROR, WeaverMessages .format(WeaverMessages.INCOMPATIBLE_RETURN_TYPE, shadow), getSourceLocation(), shadow .getSourceLocation()); @@ -202,10 +216,11 @@ public abstract class Advice extends ShadowMunger { } /** - * In after returning advice if we are binding the extra parameter to a parameterized type we may not be able to do a type-safe - * conversion. + * In after returning advice if we are binding the extra parameter to a + * parameterized type we may not be able to do a type-safe conversion. * - * @param resolvedExtraParameterType the type in the after returning declaration + * @param resolvedExtraParameterType the type in the after returning + * declaration * @param shadowReturnType the type at the shadow * @param world */ @@ -248,11 +263,11 @@ public abstract class Advice extends ShadowMunger { } public UnresolvedType[] getBindingParameterTypes() { - return this.bindingParameterTypes; + return bindingParameterTypes; } public void setBindingParameterTypes(UnresolvedType[] types) { - this.bindingParameterTypes = types; + bindingParameterTypes = types; } public static int countOnes(int bits) { @@ -344,11 +359,12 @@ public abstract class Advice extends ShadowMunger { p.m_ignoreUnboundBindingForNames = oldP.m_ignoreUnboundBindingForNames; } - Advice munger = world.createAdviceMunger(attribute, p, signature); + Advice munger = world.getWeavingSupport().createAdviceMunger(attribute, p, signature); munger.concreteAspect = fromType; - munger.bindingParameterTypes = this.bindingParameterTypes; + munger.bindingParameterTypes = bindingParameterTypes; munger.setDeclaringType(getDeclaringType()); - // System.err.println("concretizing here " + p + " with clause " + clause); + // System.err.println("concretizing here " + p + " with clause " + + // clause); return munger; } @@ -379,7 +395,8 @@ public abstract class Advice extends ShadowMunger { && ((o.signature == null) ? (signature == null) : o.signature.equals(signature)) && (AsmManager.getDefault().getHandleProvider().dependsOnLocation() ? ((o.getSourceLocation() == null) ? (getSourceLocation() == null) : o.getSourceLocation().equals(getSourceLocation())) - : true) // pr134471 - remove when handles are improved to be independent of location + : true) // pr134471 - remove when handles are improved + // to be independent of location ; } diff --git a/weaver/src/org/aspectj/weaver/AjAttribute.java b/weaver/src/org/aspectj/weaver/AjAttribute.java index 7efd52fd3..00ea0b085 100644 --- a/weaver/src/org/aspectj/weaver/AjAttribute.java +++ b/weaver/src/org/aspectj/weaver/AjAttribute.java @@ -10,7 +10,6 @@ * PARC initial implementation * ******************************************************************/ - package org.aspectj.weaver; import java.io.ByteArrayInputStream; @@ -28,16 +27,18 @@ import org.aspectj.weaver.patterns.PerClause; import org.aspectj.weaver.patterns.Pointcut; /** - * These attributes are written to and read from .class files (see the JVM spec). + * These attributes are written to and read from .class files (see the JVM + * spec). * - *

Each member or type can have a number of AjAttributes. Each - * such attribute is in 1-1 correspondence with an Unknown bcel attribute. - * Creating one of these does NOTHING to the underlying thing, so if you really - * want to add an attribute to a particular thing, well, you'd better actually do that. + *

+ * Each member or type can have a number of AjAttributes. Each such attribute is + * in 1-1 correspondence with an Unknown bcel attribute. Creating one of these + * does NOTHING to the underlying thing, so if you really want to add an + * attribute to a particular thing, well, you'd better actually do that. * * @author Erik Hilsdale * @author Jim Hugunin - */ + */ public abstract class AjAttribute { public static final String AttributePrefix = "org.aspectj.weaver"; @@ -45,10 +46,11 @@ public abstract class AjAttribute { protected abstract void write(DataOutputStream s) throws IOException; public abstract String getNameString(); + public char[] getNameChars() { return getNameString().toCharArray(); } - + /** * Just writes the contents */ @@ -57,12 +59,12 @@ public abstract class AjAttribute { ByteArrayOutputStream b0 = new ByteArrayOutputStream(); DataOutputStream s0 = new DataOutputStream(b0); write(s0); - return b0.toByteArray(); + return b0.toByteArray(); } catch (IOException e) { // shouldn't happen with ByteArrayOutputStreams throw new RuntimeException("sanity check"); } - } + } /** * Writes the full attribute, i.e. name_index, length, and contents @@ -70,40 +72,41 @@ public abstract class AjAttribute { public byte[] getAllBytes(short nameIndex) { try { byte[] bytes = getBytes(); - + ByteArrayOutputStream b0 = new ByteArrayOutputStream(); DataOutputStream s0 = new DataOutputStream(b0); - + s0.writeShort(nameIndex); s0.writeInt(bytes.length); s0.write(bytes); - return b0.toByteArray(); + return b0.toByteArray(); } catch (IOException e) { // shouldn't happen with ByteArrayOutputStreams throw new RuntimeException("sanity check"); } } - - public static AjAttribute read(AjAttribute.WeaverVersionInfo v, String name, byte[] bytes, ISourceContext context,World w) { + + public static AjAttribute read(AjAttribute.WeaverVersionInfo v, String name, byte[] bytes, ISourceContext context, World w) { try { - if (bytes == null) bytes = new byte[0]; + if (bytes == null) + bytes = new byte[0]; VersionedDataInputStream s = new VersionedDataInputStream(new ByteArrayInputStream(bytes)); s.setVersion(v); if (name.equals(Aspect.AttributeName)) { return new Aspect(PerClause.readPerClause(s, context)); } else if (name.equals(MethodDeclarationLineNumberAttribute.AttributeName)) { - return MethodDeclarationLineNumberAttribute.read(s); + return MethodDeclarationLineNumberAttribute.read(s); } else if (name.equals(WeaverState.AttributeName)) { return new WeaverState(WeaverStateInfo.read(s, context)); } else if (name.equals(WeaverVersionInfo.AttributeName)) { return WeaverVersionInfo.read(s); } else if (name.equals(AdviceAttribute.AttributeName)) { AdviceAttribute aa = AdviceAttribute.read(s, context); - aa.getPointcut().check(context,w); + aa.getPointcut().check(context, w); return aa; } else if (name.equals(PointcutDeclarationAttribute.AttributeName)) { - PointcutDeclarationAttribute pda = new PointcutDeclarationAttribute(ResolvedPointcutDefinition.read(s, context)); - pda.pointcutDef.getPointcut().check(context,w); + PointcutDeclarationAttribute pda = new PointcutDeclarationAttribute(ResolvedPointcutDefinition.read(s, context)); + pda.pointcutDef.getPointcut().check(context, w); return pda; } else if (name.equals(TypeMunger.AttributeName)) { return new TypeMunger(ResolvedTypeMunger.read(s, context)); @@ -119,47 +122,54 @@ public abstract class AjAttribute { return EffectiveSignatureAttribute.read(s, context); } else { // We have to tell the user about this... - if (w == null || w.getMessageHandler()==null) throw new BCException("unknown attribute" + name); - w.getMessageHandler().handleMessage(MessageUtil.warn("unknown attribute encountered "+name)); + if (w == null || w.getMessageHandler() == null) + throw new BCException("unknown attribute" + name); + w.getMessageHandler().handleMessage(MessageUtil.warn("unknown attribute encountered " + name)); return null; } } catch (BCException e) { - throw new BCException("malformed " + name + " attribute (length:"+bytes.length+")" + e ); + throw new BCException("malformed " + name + " attribute (length:" + bytes.length + ")" + e); } catch (IOException e) { - throw new BCException("malformed " + name + " attribute (length:"+bytes.length+")" + e ); + throw new BCException("malformed " + name + " attribute (length:" + bytes.length + ")" + e); } } - //---- + // ---- - /** Synthetic members should have NO advice put on them or on their contents. - * This attribute is currently unused as we consider all members starting - * with NameMangler.PREFIX to automatically be synthetic. As we use this we might - * find that we want multiple - * kinds of synthetic. In particular, if we want to treat the call to a synthetic getter - * (say, of an introduced field) as a field reference itself, then a method might want - * a particular kind of AjSynthetic attribute that also includes a signature of what - * it stands for. + /** + * Synthetic members should have NO advice put on them or on their contents. + * This attribute is currently unused as we consider all members starting + * with NameMangler.PREFIX to automatically be synthetic. As we use this we + * might find that we want multiple kinds of synthetic. In particular, if we + * want to treat the call to a synthetic getter (say, of an introduced + * field) as a field reference itself, then a method might want a particular + * kind of AjSynthetic attribute that also includes a signature of what it + * stands for. */ public static class AjSynthetic extends AjAttribute { public static final String AttributeName = "org.aspectj.weaver.AjSynthetic"; - + public String getNameString() { return AttributeName; } + // private ResolvedTypeMunger munger; - public AjSynthetic() {} + public AjSynthetic() { + } - public void write(DataOutputStream s) throws IOException {} + public void write(DataOutputStream s) throws IOException { + } } - + public static class TypeMunger extends AjAttribute { public static final String AttributeName = "org.aspectj.weaver.TypeMunger"; - + public String getNameString() { return AttributeName; } - private ResolvedTypeMunger munger; + + private final ResolvedTypeMunger munger; + public TypeMunger(ResolvedTypeMunger munger) { this.munger = munger; } @@ -167,54 +177,61 @@ public abstract class AjAttribute { public void write(DataOutputStream s) throws IOException { munger.write(s); } - + public ConcreteTypeMunger reify(World world, ResolvedType aspectType) { - return world.concreteTypeMunger(munger, aspectType); + return world.getWeavingSupport().concreteTypeMunger(munger, aspectType); } } public static class WeaverState extends AjAttribute { public static final String AttributeName = "org.aspectj.weaver.WeaverState"; - + public String getNameString() { return AttributeName; } - private WeaverStateInfo kind; + + private final WeaverStateInfo kind; + public WeaverState(WeaverStateInfo kind) { this.kind = kind; } + public void write(DataOutputStream s) throws IOException { kind.write(s); } - + public WeaverStateInfo reify() { return kind; } } - + public static class WeaverVersionInfo extends AjAttribute { public static final String AttributeName = "org.aspectj.weaver.WeaverVersion"; - - // If you change the format of an AspectJ class file, you have two options: - // - changing the minor version means you have not added anything that prevents - // previous versions of the weaver from operating (e.g. MethodDeclarationLineNumber attribute) - // - changing the major version means you have added something that prevents previous - // versions of the weaver from operating correctly. + + // If you change the format of an AspectJ class file, you have two + // options: + // - changing the minor version means you have not added anything that + // prevents + // previous versions of the weaver from operating (e.g. + // MethodDeclarationLineNumber attribute) + // - changing the major version means you have added something that + // prevents previous + // versions of the weaver from operating correctly. // - // The user will get a warning for any org.aspectj.weaver attributes the weaver does + // The user will get a warning for any org.aspectj.weaver attributes the + // weaver does // not recognize. - + // When we don't know ... (i.e. pre 1.2.1) public final static short WEAVER_VERSION_MAJOR_UNKNOWN = 0; public final static short WEAVER_VERSION_MINOR_UNKNOWN = 0; - - + // These are the weaver major/minor numbers for AspectJ 1.2.1 public final static short WEAVER_VERSION_MAJOR_AJ121 = 1; public final static short WEAVER_VERSION_MINOR_AJ121 = 0; - + // These are the weaver major/minor numbers for AspectJ 1.5.0 - public final static short WEAVER_VERSION_MAJOR_AJ150M4 = 3; + public final static short WEAVER_VERSION_MAJOR_AJ150M4 = 3; public final static short WEAVER_VERSION_MAJOR_AJ150 = 2; public final static short WEAVER_VERSION_MINOR_AJ150 = 0; @@ -223,120 +240,123 @@ public abstract class AjAttribute { public final static short WEAVER_VERSION_MAJOR_AJ160 = 4; public final static short WEAVER_VERSION_MINOR_AJ160 = 0; - // These are the weaver major/minor numbers for AspectJ 1.6.1 - public final static short WEAVER_VERSION_MAJOR_AJ161 = 6; // annotation value binding - public final static short WEAVER_VERSION_MINOR_AJ161 = 0; + // These are the weaver major/minor numbers for AspectJ 1.6.1 + public final static short WEAVER_VERSION_MAJOR_AJ161 = 6; // annotation + // value + // binding + public final static short WEAVER_VERSION_MINOR_AJ161 = 0; - // These are the weaver major/minor versions for *this* weaver private final static short CURRENT_VERSION_MAJOR = WEAVER_VERSION_MAJOR_AJ161; - private final static short CURRENT_VERSION_MINOR = WEAVER_VERSION_MINOR_AJ161; - - public final static WeaverVersionInfo UNKNOWN = - new WeaverVersionInfo(WEAVER_VERSION_MAJOR_UNKNOWN,WEAVER_VERSION_MINOR_UNKNOWN); - public final static WeaverVersionInfo CURRENT = - new WeaverVersionInfo(CURRENT_VERSION_MAJOR,CURRENT_VERSION_MINOR); - + private final static short CURRENT_VERSION_MINOR = WEAVER_VERSION_MINOR_AJ161; + + public final static WeaverVersionInfo UNKNOWN = new WeaverVersionInfo(WEAVER_VERSION_MAJOR_UNKNOWN, + WEAVER_VERSION_MINOR_UNKNOWN); + public final static WeaverVersionInfo CURRENT = new WeaverVersionInfo(CURRENT_VERSION_MAJOR, CURRENT_VERSION_MINOR); + // These are the versions read in from a particular class file. - private short major_version; - private short minor_version; - + private final short major_version; + private final short minor_version; + private long buildstamp = Version.NOTIME; - + public String getNameString() { return AttributeName; } // Default ctor uses the current version numbers public WeaverVersionInfo() { - this.major_version = CURRENT_VERSION_MAJOR; - this.minor_version = CURRENT_VERSION_MINOR; + major_version = CURRENT_VERSION_MAJOR; + minor_version = CURRENT_VERSION_MINOR; } - - public WeaverVersionInfo(short major,short minor) { + + public WeaverVersionInfo(short major, short minor) { major_version = major; minor_version = minor; } - + public void write(DataOutputStream s) throws IOException { s.writeShort(CURRENT_VERSION_MAJOR); s.writeShort(CURRENT_VERSION_MINOR); - s.writeLong(Version.getTime()); // build used to construct the class... + s.writeLong(Version.getTime()); // build used to construct the + // class... } - + public static WeaverVersionInfo read(VersionedDataInputStream s) throws IOException { short major = s.readShort(); short minor = s.readShort(); - WeaverVersionInfo wvi = new WeaverVersionInfo(major,minor); - if (s.getMajorVersion()>=WEAVER_VERSION_MAJOR_AJ150M4) { - long stamp = 0; + WeaverVersionInfo wvi = new WeaverVersionInfo(major, minor); + if (s.getMajorVersion() >= WEAVER_VERSION_MAJOR_AJ150M4) { + long stamp = 0; try { stamp = s.readLong(); wvi.setBuildstamp(stamp); } catch (EOFException eof) { - // didnt find that build stamp - its not the end of the world + // didnt find that build stamp - its not the end of the + // world } } return wvi; } - + public short getMajorVersion() { return major_version; } - + public short getMinorVersion() { return minor_version; } - + public static short getCurrentWeaverMajorVersion() { return CURRENT_VERSION_MAJOR; } - + public static short getCurrentWeaverMinorVersion() { return CURRENT_VERSION_MINOR; } - public void setBuildstamp(long stamp) { - this.buildstamp = stamp; + buildstamp = stamp; } - + public long getBuildstamp() { return buildstamp; } - + public String toString() { - return major_version+"."+minor_version; + return major_version + "." + minor_version; } - + public static String toCurrentVersionString() { - return CURRENT_VERSION_MAJOR+"."+CURRENT_VERSION_MINOR; + return CURRENT_VERSION_MAJOR + "." + CURRENT_VERSION_MINOR; } - + } - + public static class SourceContextAttribute extends AjAttribute { public static final String AttributeName = "org.aspectj.weaver.SourceContext"; - + public String getNameString() { return AttributeName; } - - private String sourceFileName; - private int[] lineBreaks; - + + private final String sourceFileName; + private final int[] lineBreaks; + public SourceContextAttribute(String sourceFileName, int[] lineBreaks) { this.sourceFileName = sourceFileName; this.lineBreaks = lineBreaks; } + public void write(DataOutputStream s) throws IOException { s.writeUTF(sourceFileName); FileUtil.writeIntArray(lineBreaks, s); } - + public static SourceContextAttribute read(VersionedDataInputStream s) throws IOException { return new SourceContextAttribute(s.readUTF(), FileUtil.readIntArray(s)); } + public int[] getLineBreaks() { return lineBreaks; } @@ -349,36 +369,41 @@ public abstract class AjAttribute { public static class MethodDeclarationLineNumberAttribute extends AjAttribute { public static final String AttributeName = "org.aspectj.weaver.MethodDeclarationLineNumber"; - + public String getNameString() { return AttributeName; } - - private int lineNumber; - // AV: added in 1.5 M3 thus handling cases where we don't have that information - private int offset; + private final int lineNumber; + + // AV: added in 1.5 M3 thus handling cases where we don't have that + // information + private final int offset; public MethodDeclarationLineNumberAttribute(int line, int offset) { - this.lineNumber = line; - this.offset = offset; + lineNumber = line; + this.offset = offset; + } + + public int getLineNumber() { + return lineNumber; } - - public int getLineNumber() { return lineNumber; } - public int getOffset() { return offset; } + public int getOffset() { + return offset; + } public void write(DataOutputStream s) throws IOException { s.writeInt(lineNumber); - s.writeInt(offset); + s.writeInt(offset); } - + public static MethodDeclarationLineNumberAttribute read(VersionedDataInputStream s) throws IOException { - int line = s.readInt(); - int offset = 0; - if (s.available()>0) { - offset = s.readInt(); - } + int line = s.readInt(); + int offset = 0; + if (s.available() > 0) { + offset = s.readInt(); + } return new MethodDeclarationLineNumberAttribute(line, offset); } @@ -386,132 +411,128 @@ public abstract class AjAttribute { return AttributeName + ": " + lineNumber + ":" + offset; } } - + public static class PointcutDeclarationAttribute extends AjAttribute { public static final String AttributeName = "org.aspectj.weaver.PointcutDeclaration"; - + public String getNameString() { return AttributeName; } - private ResolvedPointcutDefinition pointcutDef; + private final ResolvedPointcutDefinition pointcutDef; + public PointcutDeclarationAttribute(ResolvedPointcutDefinition pointcutDef) { this.pointcutDef = pointcutDef; } + public void write(DataOutputStream s) throws IOException { pointcutDef.write(s); } - + public ResolvedPointcutDefinition reify() { return pointcutDef; } - } + } public static class DeclareAttribute extends AjAttribute { public static final String AttributeName = "org.aspectj.weaver.Declare"; - + public String getNameString() { return AttributeName; } - private Declare declare; + private final Declare declare; + public DeclareAttribute(Declare declare) { this.declare = declare; } + public void write(DataOutputStream s) throws IOException { declare.write(s); - } - + } + public Declare getDeclare() { return declare; } - } + } public static class AdviceAttribute extends AjAttribute { public static final String AttributeName = "org.aspectj.weaver.Advice"; - + public String getNameString() { return AttributeName; } - - private AdviceKind kind; - private Pointcut pointcut; - private int extraParameterFlags; - private int start; - private int end; - private ISourceContext sourceContext; - + + private final AdviceKind kind; + private final Pointcut pointcut; + private final int extraParameterFlags; + private final int start; + private final int end; + private final ISourceContext sourceContext; + // these are only used by around advice private boolean proceedInInners; - private ResolvedMember[] proceedCallSignatures; // size == # of proceed calls in body + private ResolvedMember[] proceedCallSignatures; // size == # of proceed + // calls in body private boolean[] formalsUnchangedToProceed; // size == formals.size private UnresolvedType[] declaredExceptions; - + /** - * @param lexicalPosition must be greater than the lexicalPosition - * of any advice declared before this one in an aspect, otherwise, - * it can be any value. + * @param lexicalPosition must be greater than the lexicalPosition of + * any advice declared before this one in an aspect, + * otherwise, it can be any value. */ - public AdviceAttribute(AdviceKind kind, Pointcut pointcut, int extraArgumentFlags, - int start, int end, ISourceContext sourceContext) { + public AdviceAttribute(AdviceKind kind, Pointcut pointcut, int extraArgumentFlags, int start, int end, + ISourceContext sourceContext) { this.kind = kind; this.pointcut = pointcut; - this.extraParameterFlags = extraArgumentFlags; + extraParameterFlags = extraArgumentFlags; this.start = start; this.end = end; this.sourceContext = sourceContext; - //XXX put this back when testing works better (or fails better) - //if (kind == AdviceKind.Around) throw new IllegalArgumentException("not for around"); + // XXX put this back when testing works better (or fails better) + // if (kind == AdviceKind.Around) throw new + // IllegalArgumentException("not for around"); } - - public AdviceAttribute(AdviceKind kind, Pointcut pointcut, int extraArgumentFlags, - int start, int end, ISourceContext sourceContext, - boolean proceedInInners, ResolvedMember[] proceedCallSignatures, - boolean[] formalsUnchangedToProceed, UnresolvedType[] declaredExceptions) { + + public AdviceAttribute(AdviceKind kind, Pointcut pointcut, int extraArgumentFlags, int start, int end, + ISourceContext sourceContext, boolean proceedInInners, ResolvedMember[] proceedCallSignatures, + boolean[] formalsUnchangedToProceed, UnresolvedType[] declaredExceptions) { this.kind = kind; this.pointcut = pointcut; - this.extraParameterFlags = extraArgumentFlags; + extraParameterFlags = extraArgumentFlags; this.start = start; this.end = end; this.sourceContext = sourceContext; - - if (kind != AdviceKind.Around) throw new IllegalArgumentException("only for around"); - + + if (kind != AdviceKind.Around) + throw new IllegalArgumentException("only for around"); + this.proceedInInners = proceedInInners; this.proceedCallSignatures = proceedCallSignatures; this.formalsUnchangedToProceed = formalsUnchangedToProceed; this.declaredExceptions = declaredExceptions; } - + public static AdviceAttribute read(VersionedDataInputStream s, ISourceContext context) throws IOException { AdviceKind kind = AdviceKind.read(s); if (kind == AdviceKind.Around) { - return new AdviceAttribute( - kind, - Pointcut.read(s, context), - s.readByte(), - s.readInt(), s.readInt(), context, - s.readBoolean(), - ResolvedMemberImpl.readResolvedMemberArray(s, context), - FileUtil.readBooleanArray(s), - UnresolvedType.readArray(s)); + return new AdviceAttribute(kind, Pointcut.read(s, context), s.readByte(), s.readInt(), s.readInt(), context, s + .readBoolean(), ResolvedMemberImpl.readResolvedMemberArray(s, context), FileUtil.readBooleanArray(s), + UnresolvedType.readArray(s)); } else { - return new AdviceAttribute( - kind, - Pointcut.read(s, context), - s.readByte(), - s.readInt(), s.readInt(), context); + return new AdviceAttribute(kind, Pointcut.read(s, context), s.readByte(), s.readInt(), s.readInt(), context); } } - + public void write(DataOutputStream s) throws IOException { kind.write(s); pointcut.write(s); s.writeByte(extraParameterFlags); s.writeInt(start); s.writeInt(end); - + if (kind == AdviceKind.Around) { s.writeBoolean(proceedInInners); ResolvedMemberImpl.writeArray(proceedCallSignatures, s); @@ -519,16 +540,15 @@ public abstract class AjAttribute { UnresolvedType.writeArray(declaredExceptions, s); } } - + public Advice reify(Member signature, World world) { - return world.createAdviceMunger(this, pointcut, signature); + return world.getWeavingSupport().createAdviceMunger(this, pointcut, signature); } - + public String toString() { - return "AdviceAttribute(" + kind + ", " + pointcut + ", " + - extraParameterFlags + ", " + start+")"; + return "AdviceAttribute(" + kind + ", " + pointcut + ", " + extraParameterFlags + ", " + start + ")"; } - + public int getExtraParameterFlags() { return extraParameterFlags; } @@ -570,53 +590,57 @@ public abstract class AjAttribute { } } - + public static class Aspect extends AjAttribute { public static final String AttributeName = "org.aspectj.weaver.Aspect"; + public String getNameString() { return AttributeName; - } - private PerClause perClause; + } + + private final PerClause perClause; private IScope resolutionScope; public Aspect(PerClause perClause) { this.perClause = perClause; } - public PerClause reify(ResolvedType inAspect) { - //XXXperClause.concretize(inAspect); - return perClause; - } - - public PerClause reifyFromAtAspectJ(ResolvedType inAspect) { - perClause.resolve(resolutionScope); - return perClause; - } - + public PerClause reify(ResolvedType inAspect) { + // XXXperClause.concretize(inAspect); + return perClause; + } + + public PerClause reifyFromAtAspectJ(ResolvedType inAspect) { + perClause.resolve(resolutionScope); + return perClause; + } + public void write(DataOutputStream s) throws IOException { perClause.write(s); } public void setResolutionScope(IScope binding) { - this.resolutionScope = binding; + resolutionScope = binding; } } - + public static class PrivilegedAttribute extends AjAttribute { public static final String AttributeName = "org.aspectj.weaver.Privileged"; - + public String getNameString() { return AttributeName; } - private ResolvedMember[] accessedMembers; + private final ResolvedMember[] accessedMembers; + public PrivilegedAttribute(ResolvedMember[] accessedMembers) { this.accessedMembers = accessedMembers; } + public void write(DataOutputStream s) throws IOException { ResolvedMemberImpl.writeArray(accessedMembers, s); - } - + } + public ResolvedMember[] getAccessedMembers() { return accessedMembers; } @@ -624,41 +648,40 @@ public abstract class AjAttribute { public static PrivilegedAttribute read(VersionedDataInputStream s, ISourceContext context) throws IOException { return new PrivilegedAttribute(ResolvedMemberImpl.readResolvedMemberArray(s, context)); } - } - - + } + public static class EffectiveSignatureAttribute extends AjAttribute { public static final String AttributeName = "org.aspectj.weaver.EffectiveSignature"; - + public String getNameString() { return AttributeName; } - private ResolvedMember effectiveSignature; - private Shadow.Kind shadowKind; - private boolean weaveBody; + private final ResolvedMember effectiveSignature; + private final Shadow.Kind shadowKind; + private final boolean weaveBody; + public EffectiveSignatureAttribute(ResolvedMember effectiveSignature, Shadow.Kind shadowKind, boolean weaveBody) { this.effectiveSignature = effectiveSignature; this.shadowKind = shadowKind; this.weaveBody = weaveBody; } + public void write(DataOutputStream s) throws IOException { effectiveSignature.write(s); shadowKind.write(s); s.writeBoolean(weaveBody); - } + } public static EffectiveSignatureAttribute read(VersionedDataInputStream s, ISourceContext context) throws IOException { - return new EffectiveSignatureAttribute( - ResolvedMemberImpl.readResolvedMember(s, context), - Shadow.Kind.read(s), - s.readBoolean()); + return new EffectiveSignatureAttribute(ResolvedMemberImpl.readResolvedMember(s, context), Shadow.Kind.read(s), s + .readBoolean()); } - + public ResolvedMember getEffectiveSignature() { return effectiveSignature; } - + public String toString() { return "EffectiveSignatureAttribute(" + effectiveSignature + ", " + shadowKind + ")"; } @@ -671,7 +694,6 @@ public abstract class AjAttribute { return weaveBody; } - } - + } } diff --git a/weaver/src/org/aspectj/weaver/CrosscuttingMembers.java b/weaver/src/org/aspectj/weaver/CrosscuttingMembers.java index 98ac8caf0..9cdb78a64 100644 --- a/weaver/src/org/aspectj/weaver/CrosscuttingMembers.java +++ b/weaver/src/org/aspectj/weaver/CrosscuttingMembers.java @@ -31,11 +31,12 @@ import org.aspectj.weaver.patterns.Pointcut; import org.aspectj.weaver.patterns.PointcutRewriter; /** - * This holds on to all members that have an invasive effect outside of there own compilation unit. These members need to be all - * gathered up and in a world before any weaving can take place. + * This holds on to all members that have an invasive effect outside of there + * own compilation unit. These members need to be all gathered up and in a world + * before any weaving can take place. * - * They are also important in the compilation process and need to be gathered up before the inter-type declaration weaving stage - * (unsurprisingly). + * They are also important in the compilation process and need to be gathered up + * before the inter-type declaration weaving stage (unsurprisingly). * * All members are concrete. * @@ -58,13 +59,14 @@ public class CrosscuttingMembers { // These are like declare parents type mungers private List declareAnnotationsOnType = new ArrayList(); private List declareAnnotationsOnField = new ArrayList(); - private List declareAnnotationsOnMethods = new ArrayList(); // includes ctors + private List declareAnnotationsOnMethods = new ArrayList(); // includes + // ctors private boolean shouldConcretizeIfNeeded = true; public CrosscuttingMembers(ResolvedType inAspect, boolean shouldConcretizeIfNeeded) { this.inAspect = inAspect; - this.world = inAspect.getWorld(); + world = inAspect.getWorld(); this.shouldConcretizeIfNeeded = shouldConcretizeIfNeeded; } @@ -98,7 +100,8 @@ public class CrosscuttingMembers { public void addTypeMunger(ConcreteTypeMunger m) { if (m == null) - throw new Error("FIXME AV - should not happen or what ?");// return; //??? + throw new Error("FIXME AV - should not happen or what ?");// return; + // //??? typeMungers.add(m); } @@ -130,7 +133,8 @@ public class CrosscuttingMembers { declareParents.add(dp); } else if (declare instanceof DeclareSoft) { DeclareSoft d = (DeclareSoft) declare; - // Ordered so that during concretization we can check the related munger + // Ordered so that during concretization we can check the related + // munger ShadowMunger m = Advice.makeSoftener(world, d.getPointcut(), d.getException(), inAspect, d); m.setDeclaringType(d.getDeclaringType()); Pointcut concretePointcut = d.getPointcut().concretize(inAspect, d.getDeclaringType(), 0, m); @@ -138,10 +142,11 @@ public class CrosscuttingMembers { declareSofts.add(new DeclareSoft(d.getException(), concretePointcut)); addConcreteShadowMunger(m); } else if (declare instanceof DeclareAnnotation) { - // FIXME asc perf Possible Improvement. Investigate why this is called twice in a weave ? + // FIXME asc perf Possible Improvement. Investigate why this is + // called twice in a weave ? DeclareAnnotation da = (DeclareAnnotation) declare; if (da.getAspect() == null) - da.setAspect(this.inAspect); + da.setAspect(inAspect); if (da.isDeclareAtType()) { declareAnnotationsOnType.add(da); } else if (da.isDeclareAtField()) { @@ -181,9 +186,10 @@ public class CrosscuttingMembers { return; // dont need to bother } } - addTypeMunger(world.concreteTypeMunger(new ExposeTypeMunger(typeToExpose), inAspect)); + addTypeMunger(world.getWeavingSupport().concreteTypeMunger(new ExposeTypeMunger(typeToExpose), inAspect)); // ResolvedMember member = new ResolvedMemberImpl( - // Member.STATIC_INITIALIZATION, typeToExpose, 0, ResolvedType.VOID, "", UnresolvedType.NONE); + // Member.STATIC_INITIALIZATION, typeToExpose, 0, ResolvedType.VOID, + // "", UnresolvedType.NONE); // addTypeMunger(world.concreteTypeMunger( // new PrivilegedAccessMunger(member), inAspect)); } @@ -196,7 +202,7 @@ public class CrosscuttingMembers { private void addPrivilegedAccess(ResolvedMember member) { // System.err.println("add priv access: " + member); - addTypeMunger(world.concreteTypeMunger(new PrivilegedAccessMunger(member), inAspect)); + addTypeMunger(world.getWeavingSupport().concreteTypeMunger(new PrivilegedAccessMunger(member), inAspect)); } public Collection getCflowEntries() { @@ -214,15 +220,20 @@ public class CrosscuttingMembers { } /** - * Updates the records if something has changed. This is called at most twice, firstly whilst collecting ITDs and declares. At - * this point the CrosscuttingMembers we're comparing ourselves with doesn't know about shadowmungers. Therefore a straight - * comparison with the existing list of shadowmungers would return that something has changed even though it might not have, so - * in this first round we ignore the shadowMungers. The second time this is called is whilst we're preparing to weave. At this - * point we know everything in the system and so we're able to compare the shadowMunger list. (see bug 129163) + * Updates the records if something has changed. This is called at most + * twice, firstly whilst collecting ITDs and declares. At this point the + * CrosscuttingMembers we're comparing ourselves with doesn't know about + * shadowmungers. Therefore a straight comparison with the existing list of + * shadowmungers would return that something has changed even though it + * might not have, so in this first round we ignore the shadowMungers. The + * second time this is called is whilst we're preparing to weave. At this + * point we know everything in the system and so we're able to compare the + * shadowMunger list. (see bug 129163) * * @param other * @param careAboutShadowMungers - * @return true if something has changed since the last time this method was called, false otherwise + * @return true if something has changed since the last time this method was + * called, false otherwise */ public boolean replaceWith(CrosscuttingMembers other, boolean careAboutShadowMungers) { boolean changed = false; @@ -235,7 +246,8 @@ public class CrosscuttingMembers { } // XXX all of the below should be set equality rather than list equality - // System.err.println("old: " + shadowMungers + " new: " + other.shadowMungers); + // System.err.println("old: " + shadowMungers + " new: " + + // other.shadowMungers); if (careAboutShadowMungers) { // bug 129163: use set equality rather than list equality @@ -338,18 +350,22 @@ public class CrosscuttingMembers { otherTypeMungers.addAll(other.typeMungers); } - // initial go at equivalence logic rather than set compare (see pr133532) + // initial go at equivalence logic rather than set compare (see + // pr133532) // if (theseTypeMungers.size()!=otherTypeMungers.size()) { // changed = true; // typeMungers = other.typeMungers; // } else { // boolean foundInequality=false; - // for (Iterator iter = theseTypeMungers.iterator(); iter.hasNext() && !foundInequality;) { + // for (Iterator iter = theseTypeMungers.iterator(); iter.hasNext() && + // !foundInequality;) { // Object thisOne = (Object) iter.next(); // boolean foundInOtherSet = false; - // for (Iterator iterator = otherTypeMungers.iterator(); iterator.hasNext();) { + // for (Iterator iterator = otherTypeMungers.iterator(); + // iterator.hasNext();) { // Object otherOne = (Object) iterator.next(); - // if (thisOne instanceof ConcreteTypeMunger && otherOne instanceof ConcreteTypeMunger) { + // if (thisOne instanceof ConcreteTypeMunger && otherOne instanceof + // ConcreteTypeMunger) { // if (((ConcreteTypeMunger)thisOne).equivalentTo(otherOne)) { // foundInOtherSet=true; // } else if (thisOne.equals(otherOne)) { @@ -444,7 +460,10 @@ public class CrosscuttingMembers { PointcutRewriter pr = new PointcutRewriter(); Pointcut p = munger.getPointcut(); Pointcut newP = pr.rewrite(p); - if (p.m_ignoreUnboundBindingForNames.length != 0) {// *sigh* dirty fix for dirty hacky implementation pr149305 + if (p.m_ignoreUnboundBindingForNames.length != 0) {// *sigh* dirty fix + // for dirty hacky + // implementation + // pr149305 newP.m_ignoreUnboundBindingForNames = p.m_ignoreUnboundBindingForNames; } munger.setPointcut(newP); @@ -452,7 +471,7 @@ public class CrosscuttingMembers { } public void setPerClause(PerClause perClause) { - if (this.shouldConcretizeIfNeeded) { + if (shouldConcretizeIfNeeded) { this.perClause = perClause.concretize(inAspect); } else { this.perClause = perClause; diff --git a/weaver/src/org/aspectj/weaver/IWeavingSupport.java b/weaver/src/org/aspectj/weaver/IWeavingSupport.java new file mode 100644 index 000000000..6c5f913ba --- /dev/null +++ b/weaver/src/org/aspectj/weaver/IWeavingSupport.java @@ -0,0 +1,42 @@ +/* ******************************************************************* + * Copyright (c) 2008 Contributors + * 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: + * Andy Clement initial implementation + * ******************************************************************/ +package org.aspectj.weaver; + +import org.aspectj.weaver.patterns.PerClause; +import org.aspectj.weaver.patterns.Pointcut; + +/** + * Encapsulates operations that a world will need to support if it is actually + * going to modify bytecode rather than just match against it. {@see + * BcelWeavingSupport} + * + * @author Andy Clement + */ +public interface IWeavingSupport { + + public Advice createAdviceMunger(AjAttribute.AdviceAttribute attribute, Pointcut pointcut, Member signature); + + public abstract ConcreteTypeMunger makeCflowStackFieldAdder(ResolvedMember cflowField); + + 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) + */ + public abstract ConcreteTypeMunger makePerClauseAspect(ResolvedType aspect, PerClause.Kind kind); + + public abstract ConcreteTypeMunger concreteTypeMunger(ResolvedTypeMunger munger, ResolvedType aspectType); +} diff --git a/weaver/src/org/aspectj/weaver/World.java b/weaver/src/org/aspectj/weaver/World.java index 3e3977b67..725d762dd 100644 --- a/weaver/src/org/aspectj/weaver/World.java +++ b/weaver/src/org/aspectj/weaver/World.java @@ -37,7 +37,6 @@ import org.aspectj.bridge.IMessage.Kind; import org.aspectj.bridge.context.PinpointingMessageHandler; import org.aspectj.weaver.UnresolvedType.TypeKind; import org.aspectj.weaver.patterns.DeclarePrecedence; -import org.aspectj.weaver.patterns.PerClause; import org.aspectj.weaver.patterns.Pointcut; import org.aspectj.weaver.tools.PointcutDesignatorHandler; import org.aspectj.weaver.tools.Trace; @@ -50,10 +49,16 @@ public abstract class World implements Dump.INode { /** handler for any messages produced during resolution etc. */ private IMessageHandler messageHandler = IMessageHandler.SYSTEM_ERR; - /** handler for cross-reference information produced during the weaving process */ + /** + * handler for cross-reference information produced during the weaving + * process + */ private ICrossReferenceHandler xrefHandler = null; - /** Currently 'active' scope in which to lookup (resolve) typevariable references */ + /** + * Currently 'active' scope in which to lookup (resolve) typevariable + * references + */ private TypeVariableDeclaringElement typeVariableLookupScope; /** The heart of the world, a map from type signatures to resolved types */ @@ -87,7 +92,10 @@ public abstract class World implements Dump.INode { /** XhasMember option setting passed down to weaver */ private boolean XhasMember = false; - /** Xpinpoint controls whether we put out developer info showing the source of messages */ + /** + * Xpinpoint controls whether we put out developer info showing the source + * of messages + */ private boolean Xpinpoint = false; /** When behaving in a Java 5 way autoboxing is considered */ @@ -100,8 +108,12 @@ public abstract class World implements Dump.INode { private String targetAspectjRuntimeLevel = Constants.RUNTIME_LEVEL_DEFAULT; /** Flags for the new joinpoints that are 'optional' */ - private boolean optionalJoinpoint_ArrayConstruction = false; // Command line flag: "-Xjoinpoints:arrayconstruction" - private boolean optionalJoinpoint_Synchronization = false; // Command line flag: "-Xjoinpoints:synchronization" + private boolean optionalJoinpoint_ArrayConstruction = false; // Command line + // flag: + // "-Xjoinpoints:arrayconstruction" + private boolean optionalJoinpoint_Synchronization = false; // Command line + // flag: + // "-Xjoinpoints:synchronization" private boolean addSerialVerUID = false; @@ -124,12 +136,14 @@ public abstract class World implements Dump.INode { private long warningThreshold; /** - * A list of RuntimeExceptions containing full stack information for every type we couldn't find. + * 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. + * Play God. On the first day, God created the primitive types and put them + * in the type map. */ protected World() { super(); @@ -169,9 +183,11 @@ public abstract class World implements Dump.INode { } } - // ============================================================================= + //========================================================================== + // === // T Y P E R E S O L U T I O N - // ============================================================================= + //========================================================================== + // === /** * Resolve a type that we require to be present in the world @@ -181,8 +197,10 @@ public abstract class World implements Dump.INode { } /** - * 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 type - we can then at least report why (source location) we were trying to resolve it. + * 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 type - we can then at least report why (source location) we were + * trying to resolve it. */ public ResolvedType resolve(UnresolvedType ty, ISourceLocation isl) { ResolvedType ret = resolve(ty, true); @@ -190,9 +208,11 @@ public abstract class World implements Dump.INode { // IMessage msg = null; getLint().cantFindType.signal(WeaverMessages.format(WeaverMessages.CANT_FIND_TYPE, ty.getName()), isl); // if (isl!=null) { - // msg = MessageUtil.error(WeaverMessages.format(WeaverMessages.CANT_FIND_TYPE,ty.getName()),isl); + // msg = MessageUtil.error(WeaverMessages.format(WeaverMessages. + // CANT_FIND_TYPE,ty.getName()),isl); // } else { - // msg = MessageUtil.error(WeaverMessages.format(WeaverMessages.CANT_FIND_TYPE,ty.getName())); + // msg = MessageUtil.error(WeaverMessages.format(WeaverMessages. + // CANT_FIND_TYPE,ty.getName())); // } // messageHandler.handleMessage(msg); } @@ -200,8 +220,8 @@ public abstract class World implements Dump.INode { } /** - * Convenience method for resolving an array of unresolved types in one hit. Useful for e.g. resolving type parameters in - * signatures. + * Convenience method for resolving an array of unresolved types in one hit. + * Useful for e.g. resolving type parameters in signatures. */ public ResolvedType[] resolve(UnresolvedType[] types) { if (types == null) @@ -215,7 +235,8 @@ public abstract class World implements Dump.INode { } /** - * Resolve a type. This the hub of type resolution. The resolved type is added to the type map by signature. + * 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) { @@ -226,13 +247,16 @@ public abstract class World implements Dump.INode { return rty; } - // 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 + // 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 + // 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); @@ -240,9 +264,11 @@ public abstract class World implements Dump.INode { ret.world = this; // Set the world for the RTX return ret; } else if (signature.equals("?") || signature.equals("*")) { - // might be a problem here, not sure '?' should make it to here as a signature, the + // might be a problem here, not sure '?' should make it to here as a + // signature, the // proper signature for wildcard '?' is '*' - // fault in generic wildcard, can't be done earlier because of init issues + // fault in generic wildcard, can't be done earlier because of init + // issues // TODO ought to be shared single instance representing this ResolvedType something = new BoundedReferenceType("*", "Ljava/lang/Object", this); typeMap.put("?", something); @@ -252,7 +278,8 @@ public abstract class World implements Dump.INode { // no existing resolved type, create one if (ty.isArray()) { ResolvedType componentType = resolve(ty.getComponentType(), allowMissing); - // String brackets = signature.substring(0,signature.lastIndexOf("[")+1); + // String brackets = + // signature.substring(0,signature.lastIndexOf("[")+1); ret = new ArrayReferenceType(signature, "[" + componentType.getErasureSignature(), this, componentType); } else { ret = resolveToReferenceType(ty, allowMissing); @@ -272,14 +299,16 @@ public abstract class World implements Dump.INode { } /** - * Called when a type is resolved - enables its type hierarchy to be finished off before we proceed + * Called when a type is resolved - enables its type hierarchy to be + * finished off before we proceed */ protected void completeBinaryType(ResolvedType ret) { } /** - * Return true if the classloader relating to this world is definetly the one that will define the specified class. Return false - * otherwise or we don't know for certain. + * Return true if the classloader relating to this world is definetly the + * one that will define the specified class. Return false otherwise or we + * don't know for certain. */ public boolean isLocallyDefined(String classname) { return false; @@ -289,7 +318,8 @@ public abstract class World implements Dump.INode { * We tried to resolve a type and couldn't find it... */ private ResolvedType handleRequiredMissingTypeDuringResolution(UnresolvedType ty) { - // defer the message until someone asks a question of the type that we can't answer + // defer the message until someone asks a question of the type that we + // can't answer // just from the signature. // MessageUtil.error(messageHandler, // WeaverMessages.format(WeaverMessages.CANT_FIND_TYPE,ty.getName())); @@ -303,8 +333,10 @@ public abstract class World implements Dump.INode { } /** - * 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. + * 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()) @@ -319,7 +351,8 @@ public abstract class World implements Dump.INode { } /** - * Convenience method for finding a type by name and resolving it in one step. + * Convenience method for finding a type by name and resolving it in one + * step. */ public ResolvedType resolve(String name) { // trace.enter("resolve", this, new Object[] {name}); @@ -333,8 +366,8 @@ public abstract class World implements Dump.INode { } /** - * Resolve to a ReferenceType - simple, raw, parameterized, or generic. Raw, parameterized, and generic versions of a type share - * a delegate. + * Resolve to a ReferenceType - simple, raw, parameterized, or generic. Raw, + * parameterized, and generic versions of a type share a delegate. */ private final ResolvedType resolveToReferenceType(UnresolvedType ty, boolean allowMissing) { if (ty.isParameterizedType()) { @@ -364,13 +397,18 @@ public abstract class World implements Dump.INode { // 117854 // if (delegate == null) return ResolvedType.MISSING; if (delegate == null) - return new MissingResolvedTypeWithKnownSignature(ty.getSignature(), erasedSignature, this);// ResolvedType.MISSING; + return new MissingResolvedTypeWithKnownSignature(ty.getSignature(), erasedSignature, this);// ResolvedType + // . + // MISSING + // ; if (delegate.isGeneric() && behaveInJava5Way) { // ======== raw type =========== simpleOrRawType.typeKind = TypeKind.RAW; ReferenceType genericType = makeGenericTypeFrom(delegate, simpleOrRawType); - // name = ReferenceType.fromTypeX(UnresolvedType.forRawTypeNames(ty.getName()),this); + // name = + // ReferenceType.fromTypeX(UnresolvedType.forRawTypeNames( + // ty.getName()),this); simpleOrRawType.setDelegate(delegate); genericType.setDelegate(delegate); simpleOrRawType.setGenericType(genericType); @@ -399,13 +437,16 @@ public abstract class World implements Dump.INode { return 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 + // 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(); - // There is a special case to consider here (testGenericsBang_pr95993 highlights it) + // There is a special case to consider here (testGenericsBang_pr95993 + // highlights it) // You may have an unresolvedType for a parameterized type but it - // is backed by a simple type rather than a generic type. This occurs for + // is backed by a simple type rather than a generic type. This occurs + // for // inner types of generic types that inherit their enclosing types // type variables. if (rawType.isSimpleType() && (anUnresolvedType.typeParameters == null || anUnresolvedType.typeParameters.length == 0)) { @@ -439,11 +480,13 @@ public abstract class World implements Dump.INode { } /** - * Go from an unresolved generic wildcard (represented by UnresolvedType) to a resolved version (BoundedReferenceType). + * Go from an unresolved generic wildcard (represented by UnresolvedType) to + * a resolved version (BoundedReferenceType). */ private ReferenceType resolveGenericWildcardFor(WildcardedUnresolvedType aType) { BoundedReferenceType ret = null; - // FIXME asc doesnt take account of additional interface bounds (e.g. ? super R & Serializable - can you do that?) + // FIXME asc doesnt take account of additional interface bounds (e.g. ? + // super R & Serializable - can you do that?) if (aType.isExtends()) { ReferenceType upperBound = (ReferenceType) resolve(aType.getUpperBound()); ret = new BoundedReferenceType(upperBound, true, this); @@ -458,15 +501,18 @@ public abstract class World implements Dump.INode { } /** - * Find the ReferenceTypeDelegate behind this reference type so that it can fulfill its contract. + * Find the ReferenceTypeDelegate behind this reference type so that it can + * fulfill its contract. */ protected abstract ReferenceTypeDelegate resolveDelegate(ReferenceType ty); /** - * 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. + * 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. */ - // OPTIMIZE streamline path for core types? They are just simple types, could look straight in the typemap? + // OPTIMIZE streamline path for core types? They are just simple types, + // could look straight in the typemap? public ResolvedType getCoreType(UnresolvedType tx) { ResolvedType coreTy = resolve(tx, true); if (coreTy.isMissing()) { @@ -476,7 +522,8 @@ public abstract class World implements Dump.INode { } /** - * Lookup a type by signature, if not found then build one and put it in the map. + * 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(); @@ -489,18 +536,22 @@ public abstract class World implements Dump.INode { } /** - * Lookup a reference type in the world by its signature. Returns null if not found. + * 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 - // ============================================================================= + //========================================================================== + // === /** - * Member resolution is achieved by resolving the declaring type and then looking up the member in the resolved declaring type. + * 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); @@ -519,14 +570,13 @@ public abstract class World implements Dump.INode { return declaring.lookupSyntheticMember(member); } - // Methods for creating various cross-cutting members... - // =========================================================== + public abstract IWeavingSupport getWeavingSupport(); /** * Create an advice shadow munger from the given advice attribute */ - public abstract Advice createAdviceMunger(AjAttribute.AdviceAttribute attribute, Pointcut pointcut, Member signature); - + // public abstract Advice createAdviceMunger(AjAttribute.AdviceAttribute + // attribute, Pointcut pointcut, Member signature); /** * Create an advice shadow munger for the given advice kind */ @@ -534,24 +584,12 @@ public abstract class World implements Dump.INode { IHasSourceLocation loc) { AjAttribute.AdviceAttribute attribute = new AjAttribute.AdviceAttribute(kind, p, extraParameterFlags, loc.getStart(), loc .getEnd(), loc.getSourceContext()); - return createAdviceMunger(attribute, p, signature); + return getWeavingSupport().createAdviceMunger(attribute, p, signature); } - public abstract ConcreteTypeMunger makeCflowStackFieldAdder(ResolvedMember cflowField); - - 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) - */ - 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 + * Same signature as + * org.aspectj.util.PartialOrder.PartialComparable.compareTo */ public int compareByPrecedence(ResolvedType aspect1, ResolvedType aspect2) { return precedenceCalculator.compareByPrecedence(aspect1, aspect2); @@ -562,7 +600,8 @@ public abstract class World implements Dump.INode { } /** - * compares by precedence with the additional rule that a super-aspect is sorted before its sub-aspects + * 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); @@ -572,7 +611,8 @@ public abstract class World implements Dump.INode { // =========================================================== /** - * Nobody should hold onto a copy of this message handler, or setMessageHandler won't work right. + * Nobody should hold onto a copy of this message handler, or + * setMessageHandler won't work right. */ public IMessageHandler getMessageHandler() { return messageHandler; @@ -587,8 +627,8 @@ public abstract class World implements Dump.INode { } /** - * convenenience method for creating and issuing messages via the message handler - if you supply two locations you will get two - * messages. + * convenenience method for creating and issuing messages via the message + * handler - if you supply two locations you will get two messages. */ public void showMessage(Kind kind, String message, ISourceLocation loc1, ISourceLocation loc2) { if (loc1 != null) { @@ -609,11 +649,11 @@ public abstract class World implements Dump.INode { * Get the cross-reference handler for the world, may be null. */ public ICrossReferenceHandler getCrossReferenceHandler() { - return this.xrefHandler; + return xrefHandler; } public void setTypeVariableLookupScope(TypeVariableDeclaringElement scope) { - this.typeVariableLookupScope = scope; + typeVariableLookupScope = scope; } public TypeVariableDeclaringElement getTypeVariableLookupScope() { @@ -689,7 +729,7 @@ public abstract class World implements Dump.INode { } public void setPinpointMode(boolean b) { - this.Xpinpoint = b; + Xpinpoint = b; } public void setBehaveInJava5Way(boolean b) { @@ -697,7 +737,8 @@ public abstract class World implements Dump.INode { } /** - * Set the error and warning threashold which can be taken from CompilerOptions (see bug 129282) + * Set the error and warning threashold which can be taken from + * CompilerOptions (see bug 129282) * * @param errorThreshold * @param warningThreshold @@ -708,12 +749,13 @@ public abstract class World implements Dump.INode { } /** - * @return true if ignoring the UnusedDeclaredThrownException and false if this compiler option is set to error or warning + * @return true if ignoring the UnusedDeclaredThrownException and false if + * this compiler option is set to error or warning */ public boolean isIgnoringUnusedDeclaredThrownException() { // the 0x800000 is CompilerOptions.UnusedDeclaredThrownException // which is ASTNode.bit24 - if ((this.errorThreshold & 0x800000) != 0 || (this.warningThreshold & 0x800000) != 0) + if ((errorThreshold & 0x800000) != 0 || (warningThreshold & 0x800000) != 0) return false; return true; } @@ -752,12 +794,24 @@ public abstract class World implements Dump.INode { return extraConfiguration; } - public final static String xsetWEAVE_JAVA_PACKAGES = "weaveJavaPackages"; // default false - controls LTW - public final static String xsetWEAVE_JAVAX_PACKAGES = "weaveJavaxPackages"; // default false - controls LTW - public final static String xsetCAPTURE_ALL_CONTEXT = "captureAllContext"; // default false - public final static String xsetRUN_MINIMAL_MEMORY = "runMinimalMemory"; // default true - public final static String xsetDEBUG_STRUCTURAL_CHANGES_CODE = "debugStructuralChangesCode"; // default false - public final static String xsetDEBUG_BRIDGING = "debugBridging"; // default false + public final static String xsetWEAVE_JAVA_PACKAGES = "weaveJavaPackages"; // default + // false + // - + // controls + // LTW + public final static String xsetWEAVE_JAVAX_PACKAGES = "weaveJavaxPackages"; // default + // false + // - + // controls + // LTW + public final static String xsetCAPTURE_ALL_CONTEXT = "captureAllContext"; // default + // false + public final static String xsetRUN_MINIMAL_MEMORY = "runMinimalMemory"; // default + // true + public final static String xsetDEBUG_STRUCTURAL_CHANGES_CODE = "debugStructuralChangesCode"; // default + // false + public final static String xsetDEBUG_BRIDGING = "debugBridging"; // default + // false public final static String xsetBCEL_REPOSITORY_CACHING = "bcelRepositoryCaching"; public final static String xsetPIPELINE_COMPILATION = "pipelineCompilation"; public final static String xsetGENERATE_STACKMAPS = "generateStackMaps"; @@ -765,7 +819,9 @@ public abstract class World implements Dump.INode { public final static String xsetCOMPLETE_BINARY_TYPES = "completeBinaryTypes"; public final static String xsetCOMPLETE_BINARY_TYPES_DEFAULT = "false"; public final static String xsetBCEL_REPOSITORY_CACHING_DEFAULT = "true"; - public final static String xsetFAST_PACK_METHODS = "fastPackMethods"; // default TRUE + public final static String xsetFAST_PACK_METHODS = "fastPackMethods"; // default + + // TRUE public boolean isInJava5Mode() { return behaveInJava5Way; @@ -796,20 +852,23 @@ public abstract class World implements Dump.INode { return targetAspectjRuntimeLevel; } - // OPTIMIZE are users falling foul of not supplying -1.5 and so targetting the old runtime? + // OPTIMIZE are users falling foul of not supplying -1.5 and so targetting + // the old runtime? public boolean isTargettingAspectJRuntime12() { boolean b = false; // pr116679 if (!isInJava5Mode()) b = true; else b = getTargetAspectjRuntimeLevel().equals(org.aspectj.weaver.Constants.RUNTIME_LEVEL_12); - // System.err.println("Asked if targetting runtime 1.2 , returning: "+b); + //System.err.println("Asked if targetting runtime 1.2 , returning: "+b); return b; } /* - * Map of types in the world, can have 'references' to expendable ones which can be garbage collected to recover memory. An - * expendable type is a reference type that is not exposed to the weaver (ie just pulled in for type resolution purposes). + * Map of types in the world, can have 'references' to expendable ones which + * can be garbage collected to recover memory. 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 { @@ -818,24 +877,25 @@ public abstract class World implements Dump.INode { // Strategy for entries in the expendable map public final static int DONT_USE_REFS = 0; // Hang around forever public final static int USE_WEAK_REFS = 1; // Collected asap - public final static int USE_SOFT_REFS = 2; // Collected when short on memory + public final static int USE_SOFT_REFS = 2; // Collected when short on + // memory // SECRETAPI - Can switch to a policy of choice ;) public static int policy = USE_SOFT_REFS; // Map of types that never get thrown away - private Map /* String -> ResolvedType */tMap = new HashMap(); + private final Map /* String -> ResolvedType */tMap = new HashMap(); // Map of types that may be ejected from the cache if we need space - private Map expendableMap = Collections.synchronizedMap(new WeakHashMap()); + private final Map expendableMap = Collections.synchronizedMap(new WeakHashMap()); - private World w; + private final World w; // profiling tools... private boolean memoryProfiling = false; private int maxExpendableMapSize = -1; private int collectedTypes = 0; - private ReferenceQueue rq = new ReferenceQueue(); + private final ReferenceQueue rq = new ReferenceQueue(); private static Trace trace = TraceFactory.getTraceFactory().getTrace(World.TypeMap.class); @@ -843,20 +903,25 @@ public abstract class World implements Dump.INode { if (trace.isTraceEnabled()) trace.enter("", this, w); this.w = w; - memoryProfiling = false;// !w.getMessageHandler().isIgnoring(Message.INFO); + memoryProfiling = false;//!w.getMessageHandler().isIgnoring(Message. + // INFO); if (trace.isTraceEnabled()) trace.exit(""); } /** - * Add a new type into the map, the key is the type signature. Some types do *not* go in the map, these are ones involving - * *member* type variables. The reason is that when all you have is the signature which gives you a type variable name, you - * cannot guarantee you are using the type variable in the same way as someone previously working with a similarly named - * type variable. So, these do not go into the map: - TypeVariableReferenceType. - ParameterizedType where a member type - * variable is involved. - BoundedReferenceType when one of the bounds is a type variable. + * Add a new type into the map, the key is the type signature. Some + * types do *not* go in the map, these are ones involving *member* type + * variables. The reason is that when all you have is the signature + * which gives you a type variable name, you cannot guarantee you are + * using the type variable in the same way as someone previously working + * with a similarly named type variable. So, these do not go into the + * map: - TypeVariableReferenceType. - ParameterizedType where a member + * type variable is involved. - BoundedReferenceType when one of the + * bounds is a type variable. * - * definition: "member type variables" - a tvar declared on a generic method/ctor as opposed to those you see declared on a - * generic type. + * definition: "member type variables" - a tvar declared on a generic + * method/ctor as opposed to those you see declared on a generic type. */ public ResolvedType put(String key, ResolvedType type) { if (type.isParameterizedType() && type.isParameterizedWithTypeVariable()) { @@ -871,7 +936,8 @@ public abstract class World implements Dump.INode { System.err.println("Not putting a type variable reference type into the typemap: key=" + key + " type=" + type); return type; } - // this test should be improved - only avoid putting them in if one of the + // this test should be improved - only avoid putting them in if one + // of the // bounds is a member type variable if (type instanceof BoundedReferenceType) { if (debug) @@ -934,7 +1000,8 @@ public abstract class World implements Dump.INode { } /** - * Lookup a type by its signature, always look in the real map before the expendable map + * Lookup a type by its signature, always look in the real map before + * the expendable map */ public ResolvedType get(String key) { checkq(); @@ -981,11 +1048,13 @@ public abstract class World implements Dump.INode { // // collectTypes(expendableMap, results); // collectTypes(tMap, results); - // return (ResolvedType[]) results.toArray(new ResolvedType[results.size()]); + // return (ResolvedType[]) results.toArray(new + // ResolvedType[results.size()]); // } // // private void collectTypes(Map map, List/* ResolvedType */results) { - // for (Iterator iterator = map.keySet().iterator(); iterator.hasNext();) { + // for (Iterator iterator = map.keySet().iterator(); + // iterator.hasNext();) { // String key = (String) iterator.next(); // ResolvedType type = get(key); // if (type != null) @@ -998,28 +1067,31 @@ public abstract class World implements Dump.INode { } /** - * Reference types we don't intend to weave may be ejected from the cache if we need the space. + * Reference types we don't intend to weave may be ejected from the cache if + * we need the space. */ protected boolean isExpendable(ResolvedType type) { return (!type.equals(UnresolvedType.OBJECT) && (!type.isExposedToWeaver()) && (!type.isPrimitiveType())); } /** - * This class is used to compute and store precedence relationships between aspects. + * This class is used to compute and store precedence relationships between + * aspects. */ private static class AspectPrecedenceCalculator { - private World world; - private Map cachedResults; + private final World world; + private final Map cachedResults; public AspectPrecedenceCalculator(World forSomeWorld) { - this.world = forSomeWorld; - this.cachedResults = new HashMap(); + world = forSomeWorld; + 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. + * 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); @@ -1027,7 +1099,9 @@ public abstract class World implements Dump.INode { return ((Integer) cachedResults.get(key)).intValue(); } else { int order = 0; - DeclarePrecedence orderer = null; // Records the declare precedence statement that gives the first ordering + 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); @@ -1076,8 +1150,8 @@ public abstract class World implements Dump.INode { public ResolvedType aspect2; public PrecedenceCacheKey(ResolvedType a1, ResolvedType a2) { - this.aspect1 = a1; - this.aspect2 = a2; + aspect1 = a1; + aspect2 = a2; } public boolean equals(Object obj) { @@ -1096,12 +1170,15 @@ public abstract class World implements Dump.INode { public void validateType(UnresolvedType type) { } - // --- with java5 we can get into a recursive mess if we aren't careful when resolving types (*cough* java.lang.Enum) --- + // --- with java5 we can get into a recursive mess if we aren't careful when + // resolving types (*cough* java.lang.Enum) --- - // --- this first map is for java15 delegates which may try and recursively access the same type variables. - // --- I would rather stash this against a reference type - but we don't guarantee referencetypes are unique for + // --- this first map is for java15 delegates which may try and recursively + // access the same type variables. + // --- I would rather stash this against a reference type - but we don't + // guarantee referencetypes are unique for // so we can't :( - private Map workInProgress1 = new HashMap(); + private final Map workInProgress1 = new HashMap(); public TypeVariable[] getTypeVariablesCurrentlyBeingProcessed(Class baseClass) { return (TypeVariable[]) workInProgress1.get(baseClass); @@ -1147,7 +1224,7 @@ public abstract class World implements Dump.INode { s = p.getProperty(xsetPIPELINE_COMPILATION, xsetPIPELINE_COMPILATION_DEFAULT); shouldPipelineCompilation = s.equalsIgnoreCase("true"); - + s = p.getProperty(xsetGENERATE_STACKMAPS, "false"); shouldGenerateStackMaps = s.equalsIgnoreCase("true"); @@ -1162,7 +1239,8 @@ public abstract class World implements Dump.INode { runMinimalMemory = s.equalsIgnoreCase("true"); // if (runMinimalMemory) // getMessageHandler().handleMessage(MessageUtil.info( - // "[runMinimalMemory=true] Optimizing bcel processing (and cost of performance) to use less memory")); + // "[runMinimalMemory=true] Optimizing bcel processing (and cost of performance) to use less memory" + // )); s = p.getProperty(xsetDEBUG_STRUCTURAL_CHANGES_CODE, "false"); forDEBUG_structuralChangesCode = s.equalsIgnoreCase("true"); @@ -1189,12 +1267,12 @@ public abstract class World implements Dump.INode { ensureAdvancedConfigurationProcessed(); return shouldPipelineCompilation; } - + public boolean shouldGenerateStackMaps() { ensureAdvancedConfigurationProcessed(); return shouldGenerateStackMaps; } - + public void setIncrementalCompileCouldFollow(boolean b) { incrementalCompileCouldFollow = b; } @@ -1216,7 +1294,8 @@ public abstract class World implements Dump.INode { } /** - * Register a new pointcut designator handler with the world - this can be used by any pointcut parsers attached to the world. + * Register a new pointcut designator handler with the world - this can be + * used by any pointcut parsers attached to the world. * * @param designatorHandler handler for the new pointcut */ diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelMethod.java b/weaver/src/org/aspectj/weaver/bcel/BcelMethod.java index 79e4f76f6..149bad649 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelMethod.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelMethod.java @@ -50,7 +50,8 @@ import org.aspectj.weaver.UnresolvedType; import org.aspectj.weaver.World; import org.aspectj.weaver.bcel.BcelGenericSignatureToTypeXConverter.GenericSignatureFormatException; -public final class BcelMethod extends ResolvedMemberImpl { +//public final +class BcelMethod extends ResolvedMemberImpl { private Method method; @@ -65,7 +66,7 @@ public final class BcelMethod extends ResolvedMemberImpl { private AjAttribute.MethodDeclarationLineNumberAttribute declarationLineNumber; private AnnotationAJ[] annotations = null; private AnnotationAJ[][] parameterAnnotations = null; - private BcelObjectType bcelObjectType; + private final BcelObjectType bcelObjectType; private int bitflags; private static final int KNOW_IF_SYNTHETIC = 0x0001; @@ -89,8 +90,8 @@ public final class BcelMethod extends ResolvedMemberImpl { : METHOD), declaringType.getResolvedTypeX(), declaringType.isInterface() ? method.getModifiers() | Modifier.INTERFACE : method.getModifiers(), method.getName(), method.getSignature()); this.method = method; - this.sourceContext = declaringType.getResolvedTypeX().getSourceContext(); - this.bcelObjectType = declaringType; + sourceContext = declaringType.getResolvedTypeX().getSourceContext(); + bcelObjectType = declaringType; unpackJavaAttributes(); unpackAjAttributes(bcelObjectType.getWorld()); } @@ -431,8 +432,9 @@ public final class BcelMethod extends ResolvedMemberImpl { } /** - * A method can be parameterized if it has one or more generic parameters. A generic parameter (type variable parameter) is - * identified by the prefix "T" + * A method can be parameterized if it has one or more generic parameters. A + * generic parameter (type variable parameter) is identified by the prefix + * "T" */ public boolean canBeParameterized() { unpackGenericSignature(); @@ -445,7 +447,8 @@ public final class BcelMethod extends ResolvedMemberImpl { } /** - * Return the parameterized/generic return type or the normal return type if the method is not generic. + * Return the parameterized/generic return type or the normal return type if + * the method is not generic. */ public UnresolvedType getGenericReturnType() { unpackGenericSignature(); @@ -463,13 +466,14 @@ public final class BcelMethod extends ResolvedMemberImpl { } bitflags |= UNPACKED_GENERIC_SIGNATURE; if (!bcelObjectType.getWorld().isInJava5Mode()) { - this.genericReturnType = getReturnType(); - this.genericParameterTypes = getParameterTypes(); + genericReturnType = getReturnType(); + genericParameterTypes = getParameterTypes(); return; } String gSig = method.getGenericSignature(); if (gSig != null) { - Signature.MethodTypeSignature mSig = new GenericSignatureParser().parseAsMethodSignature(gSig);// method. + Signature.MethodTypeSignature mSig = new GenericSignatureParser().parseAsMethodSignature(gSig);// method + // . // getGenericSignature // ()); if (mSig.formalTypeParameters.length > 0) { @@ -576,8 +580,9 @@ public final class BcelMethod extends ResolvedMemberImpl { } /** - * Returns whether or not the given object is equivalent to the current one. Returns true if - * getMethod().getCode().getCodeString() are equal. Allows for different line number tables. + * Returns whether or not the given object is equivalent to the current one. + * Returns true if getMethod().getCode().getCodeString() are equal. Allows + * for different line number tables. */ // bug 154054: is similar to equals(Object) however // doesn't require implementing equals in Method and Code diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelWeavingSupport.java b/weaver/src/org/aspectj/weaver/bcel/BcelWeavingSupport.java new file mode 100644 index 000000000..37afc4bd6 --- /dev/null +++ b/weaver/src/org/aspectj/weaver/bcel/BcelWeavingSupport.java @@ -0,0 +1,62 @@ +/* ******************************************************************* + * Copyright (c) 2008 Contributors + * 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: + * Andy Clement initial implementation + * ******************************************************************/ +package org.aspectj.weaver.bcel; + +import org.aspectj.weaver.Advice; +import org.aspectj.weaver.AjAttribute; +import org.aspectj.weaver.ConcreteTypeMunger; +import org.aspectj.weaver.IWeavingSupport; +import org.aspectj.weaver.Member; +import org.aspectj.weaver.ResolvedMember; +import org.aspectj.weaver.ResolvedType; +import org.aspectj.weaver.ResolvedTypeMunger; +import org.aspectj.weaver.patterns.PerClause; +import org.aspectj.weaver.patterns.Pointcut; + +/** + * Bcel implementation of the weaving support required in a BcelWorld which will + * actually modify bytecode. + * + * @author Andy Clement + */ +public class BcelWeavingSupport implements IWeavingSupport { + + public Advice createAdviceMunger(AjAttribute.AdviceAttribute attribute, Pointcut pointcut, Member signature) { + // System.err.println("concrete advice: " + signature + " context " + + // sourceContext); + return new BcelAdvice(attribute, pointcut, signature, null); + } + + public ConcreteTypeMunger makeCflowStackFieldAdder(ResolvedMember cflowField) { + return new BcelCflowStackFieldAdder(cflowField); + } + + public ConcreteTypeMunger makeCflowCounterFieldAdder(ResolvedMember cflowField) { + return new BcelCflowCounterFieldAdder(cflowField); + } + + /** + * Register a munger for perclause @AJ aspect so that we add aspectOf(..) to + * them as needed + * + * @param aspect + * @param kind + * @return munger + */ + public ConcreteTypeMunger makePerClauseAspect(ResolvedType aspect, PerClause.Kind kind) { + return new BcelPerClauseAspectAdder(aspect, kind); + } + + public ConcreteTypeMunger concreteTypeMunger(ResolvedTypeMunger munger, ResolvedType aspectType) { + return new BcelTypeMunger(munger, aspectType); + } +} diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelWorld.java b/weaver/src/org/aspectj/weaver/bcel/BcelWorld.java index 3b66a8eec..0179887df 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelWorld.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelWorld.java @@ -39,13 +39,11 @@ import org.aspectj.apache.bcel.util.ClassPath; import org.aspectj.apache.bcel.util.NonCachingClassLoaderRepository; import org.aspectj.apache.bcel.util.Repository; import org.aspectj.bridge.IMessageHandler; -import org.aspectj.weaver.Advice; -import org.aspectj.weaver.AjAttribute; import org.aspectj.weaver.AnnotationAJ; import org.aspectj.weaver.AnnotationOnTypeMunger; import org.aspectj.weaver.BCException; -import org.aspectj.weaver.ConcreteTypeMunger; import org.aspectj.weaver.ICrossReferenceHandler; +import org.aspectj.weaver.IWeavingSupport; import org.aspectj.weaver.Member; import org.aspectj.weaver.MemberImpl; import org.aspectj.weaver.MemberKind; @@ -61,24 +59,17 @@ import org.aspectj.weaver.WeakClassLoaderReference; import org.aspectj.weaver.World; import org.aspectj.weaver.patterns.DeclareAnnotation; import org.aspectj.weaver.patterns.DeclareParents; -import org.aspectj.weaver.patterns.PerClause; -import org.aspectj.weaver.patterns.Pointcut; import org.aspectj.weaver.tools.Trace; import org.aspectj.weaver.tools.TraceFactory; public class BcelWorld extends World implements Repository { - private ClassPathManager classPath; + private final ClassPathManager classPath; protected Repository delegate; private WeakClassLoaderReference loaderRef; + private final BcelWeavingSupport bcelWeavingSupport = new BcelWeavingSupport(); - // private ClassPathManager aspectPath = null; - // private List aspectPathEntries; - - private static Trace trace = TraceFactory.getTraceFactory().getTrace( - BcelWorld.class); - - // ---- constructors + private static Trace trace = TraceFactory.getTraceFactory().getTrace(BcelWorld.class); public BcelWorld() { this(""); @@ -92,7 +83,6 @@ public class BcelWorld extends World implements Repository { List classPath = new ArrayList(); classPath.addAll(getPathEntries(cp)); classPath.addAll(getPathEntries(ClassPath.getClassPath())); - // System.err.println("classpath: " + classPath); return classPath; } @@ -107,8 +97,7 @@ public class BcelWorld extends World implements Repository { return ret; } - public BcelWorld(List classPath, IMessageHandler handler, - ICrossReferenceHandler xrefHandler) { + public BcelWorld(List classPath, IMessageHandler handler, ICrossReferenceHandler xrefHandler) { // this.aspectPath = new ClassPathManager(aspectPath, handler); this.classPath = new ClassPathManager(classPath, handler); setMessageHandler(handler); @@ -117,9 +106,8 @@ public class BcelWorld extends World implements Repository { delegate = this; } - public BcelWorld(ClassPathManager cpm, IMessageHandler handler, - ICrossReferenceHandler xrefHandler) { - this.classPath = cpm; + public BcelWorld(ClassPathManager cpm, IMessageHandler handler, ICrossReferenceHandler xrefHandler) { + classPath = cpm; setMessageHandler(handler); setCrossReferenceHandler(xrefHandler); // Tell BCEL to use us for resolving any classes @@ -133,10 +121,9 @@ public class BcelWorld extends World implements Repository { * @param handler * @param xrefHandler */ - public BcelWorld(ClassLoader loader, IMessageHandler handler, - ICrossReferenceHandler xrefHandler) { - this.classPath = null; - this.loaderRef = new WeakClassLoaderReference(loader); + public BcelWorld(ClassLoader loader, IMessageHandler handler, ICrossReferenceHandler xrefHandler) { + classPath = null; + loaderRef = new WeakClassLoaderReference(loader); setMessageHandler(handler); setCrossReferenceHandler(xrefHandler); // Tell BCEL to use us for resolving any classes @@ -210,10 +197,8 @@ public class BcelWorld extends World implements Repository { } } - public BcelObjectType buildBcelDelegate(ReferenceType resolvedTypeX, - JavaClass jc, boolean exposedToWeaver) { - BcelObjectType ret = new BcelObjectType(resolvedTypeX, jc, - exposedToWeaver); + public BcelObjectType buildBcelDelegate(ReferenceType resolvedTypeX, JavaClass jc, boolean exposedToWeaver) { + BcelObjectType ret = new BcelObjectType(resolvedTypeX, jc, exposedToWeaver); return ret; } @@ -223,25 +208,21 @@ public class BcelWorld extends World implements Repository { ensureRepositorySetup(); JavaClass jc = delegate.loadClass(name); if (trace.isTraceEnabled()) - trace.event("lookupJavaClass", this, new Object[] { name, - jc }); + trace.event("lookupJavaClass", this, new Object[] { name, jc }); return jc; } catch (ClassNotFoundException e) { if (trace.isTraceEnabled()) - trace.error("Unable to find class '" + name - + "' in repository", e); + trace.error("Unable to find class '" + name + "' in repository", e); return null; } } try { - ClassPathManager.ClassFile file = classPath.find(UnresolvedType - .forName(name)); + ClassPathManager.ClassFile file = classPath.find(UnresolvedType.forName(name)); if (file == null) return null; - ClassParser parser = new ClassParser(file.getInputStream(), file - .getPath()); + ClassParser parser = new ClassParser(file.getInputStream(), file.getPath()); JavaClass jc = parser.parse(); file.close(); @@ -253,18 +234,15 @@ public class BcelWorld extends World implements Repository { public BcelObjectType addSourceObjectType(JavaClass jc) { BcelObjectType ret = null; - String signature = UnresolvedType.forName(jc.getClassName()) - .getSignature(); + String signature = UnresolvedType.forName(jc.getClassName()).getSignature(); Object fromTheMap = typeMap.get(signature); if (fromTheMap != null && !(fromTheMap instanceof ReferenceType)) { // what on earth is it then? See pr 112243 StringBuffer exceptionText = new StringBuffer(); - exceptionText - .append("Found invalid (not a ReferenceType) entry in the type map. "); - exceptionText.append("Signature=[" + signature + "] Found=[" - + fromTheMap + "] Class=[" + fromTheMap.getClass() + "]"); + exceptionText.append("Found invalid (not a ReferenceType) entry in the type map. "); + exceptionText.append("Signature=[" + signature + "] Found=[" + fromTheMap + "] Class=[" + fromTheMap.getClass() + "]"); throw new BCException(exceptionText.toString()); } @@ -273,12 +251,10 @@ public class BcelWorld extends World implements Repository { if (nameTypeX == null) { if (jc.isGeneric() && isInJava5Mode()) { - nameTypeX = ReferenceType.fromTypeX(UnresolvedType - .forRawTypeName(jc.getClassName()), this); + nameTypeX = ReferenceType.fromTypeX(UnresolvedType.forRawTypeName(jc.getClassName()), this); ret = buildBcelDelegate(nameTypeX, jc, true); - ReferenceType genericRefType = new ReferenceType(UnresolvedType - .forGenericTypeSignature(signature, ret - .getDeclaredGenericSignature()), this); + ReferenceType genericRefType = new ReferenceType(UnresolvedType.forGenericTypeSignature(signature, ret + .getDeclaredGenericSignature()), this); nameTypeX.setDelegate(ret); genericRefType.setDelegate(ret); nameTypeX.setGenericType(genericRefType); @@ -298,26 +274,21 @@ public class BcelWorld extends World implements Repository { typeMap.remove(ty.getSignature()); } - public static Member makeFieldJoinPointSignature(LazyClassGen cg, - FieldInstruction fi) { + public static Member makeFieldJoinPointSignature(LazyClassGen cg, FieldInstruction fi) { ConstantPool cpg = cg.getConstantPool(); - return MemberImpl - .field( - fi.getClassName(cpg), - (fi.opcode == Constants.GETSTATIC || fi.opcode == Constants.PUTSTATIC) ? Modifier.STATIC - : 0, fi.getName(cpg), fi.getSignature(cpg)); + return MemberImpl.field(fi.getClassName(cpg), + (fi.opcode == Constants.GETSTATIC || fi.opcode == Constants.PUTSTATIC) ? Modifier.STATIC : 0, fi.getName(cpg), fi + .getSignature(cpg)); } - public Member makeJoinPointSignatureFromMethod(LazyMethodGen mg, - MemberKind kind) { + public Member makeJoinPointSignatureFromMethod(LazyMethodGen mg, MemberKind kind) { Member ret = mg.getMemberView(); if (ret == null) { int mods = mg.getAccessFlags(); if (mg.getEnclosingClass().isInterface()) { mods |= Modifier.INTERFACE; } - return new ResolvedMemberImpl(kind, UnresolvedType.forName(mg - .getClassName()), mods, fromBcel(mg.getReturnType()), mg + return new ResolvedMemberImpl(kind, UnresolvedType.forName(mg.getClassName()), mods, fromBcel(mg.getReturnType()), mg .getName(), fromBcel(mg.getArgumentTypes())); } else { return ret; @@ -325,18 +296,15 @@ public class BcelWorld extends World implements Repository { } - public Member makeJoinPointSignatureForMonitorEnter(LazyClassGen cg, - InstructionHandle h) { + public Member makeJoinPointSignatureForMonitorEnter(LazyClassGen cg, InstructionHandle h) { return MemberImpl.monitorEnter(); } - public Member makeJoinPointSignatureForMonitorExit(LazyClassGen cg, - InstructionHandle h) { + public Member makeJoinPointSignatureForMonitorExit(LazyClassGen cg, InstructionHandle h) { return MemberImpl.monitorExit(); } - public Member makeJoinPointSignatureForArrayConstruction(LazyClassGen cg, - InstructionHandle handle) { + public Member makeJoinPointSignatureForArrayConstruction(LazyClassGen cg, InstructionHandle handle) { Instruction i = handle.getInstruction(); ConstantPool cpg = cg.getConstantPool(); Member retval = null; @@ -346,8 +314,7 @@ public class BcelWorld extends World implements Repository { Type ot = i.getType(cpg); UnresolvedType ut = fromBcel(ot); ut = UnresolvedType.makeArray(ut, 1); - retval = MemberImpl.method(ut, Modifier.PUBLIC, ResolvedType.VOID, - "", new ResolvedType[] { ResolvedType.INT }); + retval = MemberImpl.method(ut, Modifier.PUBLIC, ResolvedType.VOID, "", new ResolvedType[] { ResolvedType.INT }); } else if (i instanceof MULTIANEWARRAY) { MULTIANEWARRAY arrayInstruction = (MULTIANEWARRAY) i; UnresolvedType ut = null; @@ -363,25 +330,20 @@ public class BcelWorld extends World implements Repository { ResolvedType[] parms = new ResolvedType[dimensions]; for (int ii = 0; ii < dimensions; ii++) parms[ii] = ResolvedType.INT; - retval = MemberImpl.method(ut, Modifier.PUBLIC, ResolvedType.VOID, - "", parms); + retval = MemberImpl.method(ut, Modifier.PUBLIC, ResolvedType.VOID, "", parms); } else if (i.opcode == Constants.NEWARRAY) { // NEWARRAY arrayInstruction = (NEWARRAY)i; Type ot = i.getType(); UnresolvedType ut = fromBcel(ot); - retval = MemberImpl.method(ut, Modifier.PUBLIC, ResolvedType.VOID, - "", new ResolvedType[] { ResolvedType.INT }); + retval = MemberImpl.method(ut, Modifier.PUBLIC, ResolvedType.VOID, "", new ResolvedType[] { ResolvedType.INT }); } else { - throw new BCException( - "Cannot create array construction signature for this non-array instruction:" - + i); + throw new BCException("Cannot create array construction signature for this non-array instruction:" + i); } return retval; } - public Member makeJoinPointSignatureForMethodInvocation(LazyClassGen cg, - InvokeInstruction ii) { + public Member makeJoinPointSignatureForMethodInvocation(LazyClassGen cg, InvokeInstruction ii) { ConstantPool cpg = cg.getConstantPool(); String name = ii.getName(cpg); String declaring = ii.getClassName(cpg); @@ -390,9 +352,8 @@ public class BcelWorld extends World implements Repository { String signature = ii.getSignature(cpg); int modifier = (ii instanceof INVOKEINTERFACE) ? Modifier.INTERFACE - : (ii.opcode == Constants.INVOKESTATIC) ? Modifier.STATIC - : (ii.opcode == Constants.INVOKESPECIAL && !name - .equals("")) ? Modifier.PRIVATE : 0; + : (ii.opcode == Constants.INVOKESTATIC) ? Modifier.STATIC : (ii.opcode == Constants.INVOKESPECIAL && !name + .equals("")) ? Modifier.PRIVATE : 0; // in Java 1.4 and after, static method call of super class within // subclass method appears @@ -401,12 +362,10 @@ public class BcelWorld extends World implements Repository { if (ii.opcode == Constants.INVOKESTATIC) { ResolvedType appearsDeclaredBy = resolve(declaring); // look for the method there - for (Iterator iterator = appearsDeclaredBy.getMethods(); iterator - .hasNext();) { + for (Iterator iterator = appearsDeclaredBy.getMethods(); iterator.hasNext();) { ResolvedMember method = (ResolvedMember) iterator.next(); if (method.isStatic()) { - if (name.equals(method.getName()) - && signature.equals(method.getSignature())) { + if (name.equals(method.getName()) && signature.equals(method.getSignature())) { // we found it declaringType = method.getDeclaringType(); break; @@ -433,48 +392,13 @@ public class BcelWorld extends World implements Repository { return buf.toString(); } - public Advice createAdviceMunger(AjAttribute.AdviceAttribute attribute, - Pointcut pointcut, Member signature) { - // System.err.println("concrete advice: " + signature + " context " + - // sourceContext); - return new BcelAdvice(attribute, pointcut, signature, null); - } - - public ConcreteTypeMunger concreteTypeMunger(ResolvedTypeMunger munger, - ResolvedType aspectType) { - return new BcelTypeMunger(munger, aspectType); - } - - public ConcreteTypeMunger makeCflowStackFieldAdder(ResolvedMember cflowField) { - return new BcelCflowStackFieldAdder(cflowField); - } - - public ConcreteTypeMunger makeCflowCounterFieldAdder( - ResolvedMember cflowField) { - return new BcelCflowCounterFieldAdder(cflowField); - } - - /** - * Register a munger for perclause @AJ aspect so that we add aspectOf(..) to - * them as needed - * - * @param aspect - * @param kind - * @return munger - */ - public ConcreteTypeMunger makePerClauseAspect(ResolvedType aspect, - PerClause.Kind kind) { - return new BcelPerClauseAspectAdder(aspect, kind); - } - /** * Retrieve a bcel delegate for an aspect - this will return NULL if the * delegate is an EclipseSourceType and not a BcelObjectType - this happens * quite often when incrementally compiling. */ public static BcelObjectType getBcelObjectType(ResolvedType concreteAspect) { - ReferenceTypeDelegate rtDelegate = ((ReferenceType) concreteAspect) - .getDelegate(); + ReferenceTypeDelegate rtDelegate = ((ReferenceType) concreteAspect).getDelegate(); if (rtDelegate instanceof BcelObjectType) { return (BcelObjectType) rtDelegate; } else { @@ -517,7 +441,6 @@ public class BcelWorld extends World implements Repository { // throw new RuntimeException("Not implemented"); } - // @Override /** * The aim of this method is to make sure a particular type is 'ok'. Some * operations on the delegate for a type modify it and this method is @@ -563,12 +486,10 @@ public class BcelWorld extends World implements Repository { // (like transform super calls) - that is done in // BcelTypeMunger.mungeNewParent() classType.addParent(newParent); - ResolvedTypeMunger newParentMunger = new NewParentTypeMunger( - newParent); + ResolvedTypeMunger newParentMunger = new NewParentTypeMunger(newParent); newParentMunger.setSourceLocation(p.getSourceLocation()); - onType.addInterTypeMunger(new BcelTypeMunger(newParentMunger, - getCrosscuttingMembersSet().findAspectDeclaringParents( - p))); + onType.addInterTypeMunger(new BcelTypeMunger(newParentMunger, getCrosscuttingMembersSet() + .findAspectDeclaringParents(p))); } } return didSomething; @@ -577,8 +498,7 @@ public class BcelWorld extends World implements Repository { /** * Apply a declare @type - return true if we change the type */ - private boolean applyDeclareAtType(DeclareAnnotation decA, - ResolvedType onType, boolean reportProblems) { + private boolean applyDeclareAtType(DeclareAnnotation decA, ResolvedType onType, boolean reportProblems) { boolean didSomething = false; if (decA.matches(onType)) { @@ -594,11 +514,9 @@ public class BcelWorld extends World implements Repository { if (isOK) { didSomething = true; - ResolvedTypeMunger newAnnotationTM = new AnnotationOnTypeMunger( - annoX); + ResolvedTypeMunger newAnnotationTM = new AnnotationOnTypeMunger(annoX); newAnnotationTM.setSourceLocation(decA.getSourceLocation()); - onType.addInterTypeMunger(new BcelTypeMunger(newAnnotationTM, - decA.getAspect().resolve(this))); + onType.addInterTypeMunger(new BcelTypeMunger(newAnnotationTM, decA.getAspect().resolve(this))); decA.copyAnnotationTo(onType); } } @@ -609,11 +527,9 @@ public class BcelWorld extends World implements Repository { * Checks for an @target() on the annotation and if found ensures it allows * the annotation to be attached to the target type that matched. */ - private boolean checkTargetOK(DeclareAnnotation decA, ResolvedType onType, - AnnotationAJ annoX) { + private boolean checkTargetOK(DeclareAnnotation decA, ResolvedType onType, AnnotationAJ annoX) { if (annoX.specifiesTarget()) { - if ((onType.isAnnotation() && !annoX.allowedOnAnnotationType()) - || (!annoX.allowedOnRegularType())) { + if ((onType.isAnnotation() && !annoX.allowedOnAnnotationType()) || (!annoX.allowedOnRegularType())) { return false; } } @@ -626,8 +542,7 @@ public class BcelWorld extends World implements Repository { // weaving. protected void weaveInterTypeDeclarations(ResolvedType onType) { - List declareParentsList = getCrosscuttingMembersSet() - .getDeclareParents(); + List declareParentsList = getCrosscuttingMembersSet().getDeclareParents(); if (onType.isRawType()) onType = onType.getGenericType(); onType.clearInterTypeMungers(); @@ -650,8 +565,7 @@ public class BcelWorld extends World implements Repository { } // Still first pass - apply all dec @type mungers - for (Iterator i = getCrosscuttingMembersSet() - .getDeclareAnnotationOnTypes().iterator(); i.hasNext();) { + for (Iterator i = getCrosscuttingMembersSet().getDeclareAnnotationOnTypes().iterator(); i.hasNext();) { DeclareAnnotation decA = (DeclareAnnotation) i.next(); boolean typeChanged = applyDeclareAtType(decA, onType, true); if (typeChanged) { @@ -659,8 +573,7 @@ public class BcelWorld extends World implements Repository { } } - while ((aParentChangeOccurred || anAnnotationChangeOccurred) - && !decpToRepeat.isEmpty()) { + while ((aParentChangeOccurred || anAnnotationChangeOccurred) && !decpToRepeat.isEmpty()) { anAnnotationChangeOccurred = aParentChangeOccurred = false; List decpToRepeatNextTime = new ArrayList(); for (Iterator iter = decpToRepeat.iterator(); iter.hasNext();) { @@ -673,8 +586,7 @@ public class BcelWorld extends World implements Repository { } } - for (Iterator iter = getCrosscuttingMembersSet() - .getDeclareAnnotationOnTypes().iterator(); iter.hasNext();) { + for (Iterator iter = getCrosscuttingMembersSet().getDeclareAnnotationOnTypes().iterator(); iter.hasNext();) { DeclareAnnotation decA = (DeclareAnnotation) iter.next(); boolean typeChanged = applyDeclareAtType(decA, onType, false); if (typeChanged) { @@ -685,4 +597,8 @@ public class BcelWorld extends World implements Repository { } } + public IWeavingSupport getWeavingSupport() { + return bcelWeavingSupport; + } + } \ No newline at end of file diff --git a/weaver/src/org/aspectj/weaver/patterns/CflowPointcut.java b/weaver/src/org/aspectj/weaver/patterns/CflowPointcut.java index 1cef7d159..8a0a09594 100644 --- a/weaver/src/org/aspectj/weaver/patterns/CflowPointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/CflowPointcut.java @@ -10,7 +10,6 @@ * PARC initial implementation * ******************************************************************/ - package org.aspectj.weaver.patterns; import java.io.DataOutputStream; @@ -41,29 +40,28 @@ import org.aspectj.weaver.WeaverMessages; import org.aspectj.weaver.World; import org.aspectj.weaver.ast.Test; - public class CflowPointcut extends Pointcut { - private Pointcut entry; // The pointcut inside the cflow() that represents the 'entry' point + private final Pointcut entry; // The pointcut inside the cflow() that + // represents the 'entry' point boolean isBelow;// Is this cflowbelow? private int[] freeVars; - - + /** - * Used to indicate that we're in the context of a cflow when concretizing if's + * Used to indicate that we're in the context of a cflow when concretizing + * if's * - * Will be removed or replaced with something better when we handle this - * as a non-error + * Will be removed or replaced with something better when we handle this as + * a non-error */ - public static final ResolvedPointcutDefinition CFLOW_MARKER = - new ResolvedPointcutDefinition(null, 0, null, UnresolvedType.NONE, Pointcut.makeMatchesNothing(Pointcut.RESOLVED)); + public static final ResolvedPointcutDefinition CFLOW_MARKER = new ResolvedPointcutDefinition(null, 0, null, + UnresolvedType.NONE, Pointcut.makeMatchesNothing(Pointcut.RESOLVED)); - public CflowPointcut(Pointcut entry, boolean isBelow, int[] freeVars) { - // System.err.println("Building cflow pointcut "+entry.toString()); + // System.err.println("Building cflow pointcut "+entry.toString()); this.entry = entry; this.isBelow = isBelow; this.freeVars = freeVars; - this.pointcutKind = CFLOW; + pointcutKind = CFLOW; } /** @@ -76,18 +74,18 @@ public class CflowPointcut extends Pointcut { public int couldMatchKinds() { return Shadow.ALL_SHADOW_KINDS_BITS; } - + // enh 76055 public Pointcut getEntry() { - return entry; + return entry; } - - public FuzzyBoolean fastMatch(FastMatchInfo type) { + + public FuzzyBoolean fastMatch(FastMatchInfo type) { return FuzzyBoolean.MAYBE; } - + protected FuzzyBoolean matchInternal(Shadow shadow) { - //??? this is not maximally efficient + // ??? this is not maximally efficient return FuzzyBoolean.MAYBE; } @@ -98,15 +96,16 @@ public class CflowPointcut extends Pointcut { FileUtil.writeIntArray(freeVars, s); writeLocation(s); } + public static Pointcut read(VersionedDataInputStream s, ISourceContext context) throws IOException { CflowPointcut ret = new CflowPointcut(Pointcut.read(s, context), s.readBoolean(), FileUtil.readIntArray(s)); ret.readLocation(context, s); return ret; } - - public Pointcut parameterizeWith(Map typeVariableMap,World w) { - CflowPointcut ret = new CflowPointcut(entry.parameterizeWith(typeVariableMap,w),isBelow,freeVars); + + public Pointcut parameterizeWith(Map typeVariableMap, World w) { + CflowPointcut ret = new CflowPointcut(entry.parameterizeWith(typeVariableMap, w), isBelow, freeVars); ret.copyLocationFrom(this); return ret; } @@ -117,29 +116,32 @@ public class CflowPointcut extends Pointcut { entry.state = RESOLVED; freeVars = new int[0]; } else { - //??? for if's sake we might need to be more careful here + // ??? for if's sake we might need to be more careful here Bindings entryBindings = new Bindings(bindings.size()); - + entry.resolveBindings(scope, entryBindings); entry.state = RESOLVED; - + freeVars = entryBindings.getUsedFormals(); - + bindings.mergeIn(entryBindings, scope); } } - + public boolean equals(Object other) { - if (!(other instanceof CflowPointcut)) return false; - CflowPointcut o = (CflowPointcut)other; - return o.entry.equals(this.entry) && o.isBelow == this.isBelow; + if (!(other instanceof CflowPointcut)) + return false; + CflowPointcut o = (CflowPointcut) other; + return o.entry.equals(entry) && o.isBelow == isBelow; + } + + public int hashCode() { + int result = 17; + result = 37 * result + entry.hashCode(); + result = 37 * result + (isBelow ? 0 : 1); + return result; } - public int hashCode() { - int result = 17; - result = 37*result + entry.hashCode(); - result = 37*result + (isBelow ? 0 : 1); - return result; - } + public String toString() { return "cflow" + (isBelow ? "below" : "") + "(" + entry + ")"; } @@ -147,46 +149,45 @@ public class CflowPointcut extends Pointcut { protected Test findResidueInternal(Shadow shadow, ExposedState state) { throw new RuntimeException("unimplemented - did concretization fail?"); } - + public Pointcut concretize1(ResolvedType inAspect, ResolvedType declaringType, IntMap bindings) { - - // the pointcut is marked as CONCRETE after returning from this + + // the pointcut is marked as CONCRETE after returning from this // call - so we can't skip concretization -// if (this.entry.state == Pointcut.SYMBOLIC) { -// // too early to concretize, return unchanged -// return this; -// } + // if (this.entry.state == Pointcut.SYMBOLIC) { + // // too early to concretize, return unchanged + // return this; + // } // Enforce rule about which designators are supported in declare if (isDeclare(bindings.getEnclosingAdvice())) { inAspect.getWorld().showMessage(IMessage.ERROR, - WeaverMessages.format(WeaverMessages.CFLOW_IN_DECLARE,isBelow?"below":""), + WeaverMessages.format(WeaverMessages.CFLOW_IN_DECLARE, isBelow ? "below" : ""), bindings.getEnclosingAdvice().getSourceLocation(), null); return Pointcut.makeMatchesNothing(Pointcut.CONCRETE); } - - //make this remap from formal positions to arrayIndices + + // make this remap from formal positions to arrayIndices IntMap entryBindings = new IntMap(); - if (freeVars!=null) { - for (int i=0, len=freeVars.length; i < len; i++) { - int freeVar = freeVars[i]; - //int formalIndex = bindings.get(freeVar); - entryBindings.put(freeVar, i); - } + if (freeVars != null) { + for (int i = 0, len = freeVars.length; i < len; i++) { + int freeVar = freeVars[i]; + // int formalIndex = bindings.get(freeVar); + entryBindings.put(freeVar, i); + } } entryBindings.copyContext(bindings); - //System.out.println(this + " bindings: " + entryBindings); - + // System.out.println(this + " bindings: " + entryBindings); + World world = inAspect.getWorld(); - + Pointcut concreteEntry; - + ResolvedType concreteAspect = bindings.getConcreteAspect(); - - CrosscuttingMembers xcut = concreteAspect.crosscuttingMembers; + + CrosscuttingMembers xcut = concreteAspect.crosscuttingMembers; Collection previousCflowEntries = xcut.getCflowEntries(); - - + entryBindings.pushEnclosingDefinition(CFLOW_MARKER); // This block concretizes the pointcut within the cflow pointcut try { @@ -198,139 +199,157 @@ public class CflowPointcut extends Pointcut { List innerCflowEntries = new ArrayList(xcut.getCflowEntries()); innerCflowEntries.removeAll(previousCflowEntries); - - // Four routes of interest through this code (did I hear someone say refactor??) - // 1) no state in the cflow - we can use a counter *and* we have seen this pointcut - // before - so use the same counter as before. - // 2) no state in the cflow - we can use a counter, but this is the first time - // we have seen this pointcut, so build the infrastructure. - // 3) state in the cflow - we need to use a stack *and* we have seen this pointcut - // before - so share the stack. - // 4) state in the cflow - we need to use a stack, but this is the first time - // we have seen this pointcut, so build the infrastructure. - - if (freeVars==null || freeVars.length == 0) { // No state, so don't use a stack, use a counter. - ResolvedMember localCflowField = null; - - Object field = getCflowfield(xcut, concreteEntry, concreteAspect, "counter"); - - // Check if we have already got a counter for this cflow pointcut - if (field != null) { - localCflowField = (ResolvedMember)field; // Use the one we already have - - } else { - - // Create a counter field in the aspect - localCflowField = new ResolvedMemberImpl(Member.FIELD,concreteAspect,Modifier.STATIC | Modifier.PUBLIC | Modifier.FINAL, - NameMangler.cflowCounter(xcut),UnresolvedType.forName(NameMangler.CFLOW_COUNTER_TYPE).getSignature()); - - // Create type munger to add field to the aspect - concreteAspect.crosscuttingMembers.addTypeMunger(world.makeCflowCounterFieldAdder(localCflowField)); - - // Create shadow munger to push stuff onto the stack - concreteAspect.crosscuttingMembers.addConcreteShadowMunger( - Advice.makeCflowEntry(world,concreteEntry,isBelow,localCflowField,freeVars==null?0:freeVars.length,innerCflowEntries,inAspect)); - - putCflowfield(xcut,concreteEntry,concreteAspect,localCflowField,"counter"); // Remember it - } - - Pointcut ret = new ConcreteCflowPointcut(localCflowField, null,true); - ret.copyLocationFrom(this); - return ret; + // Four routes of interest through this code (did I hear someone say + // refactor??) + // 1) no state in the cflow - we can use a counter *and* we have seen + // this pointcut + // before - so use the same counter as before. + // 2) no state in the cflow - we can use a counter, but this is the + // first time + // we have seen this pointcut, so build the infrastructure. + // 3) state in the cflow - we need to use a stack *and* we have seen + // this pointcut + // before - so share the stack. + // 4) state in the cflow - we need to use a stack, but this is the first + // time + // we have seen this pointcut, so build the infrastructure. + + if (freeVars == null || freeVars.length == 0) { // No state, so don't + // use a stack, use a + // counter. + ResolvedMember localCflowField = null; + + Object field = getCflowfield(xcut, concreteEntry, concreteAspect, "counter"); + + // Check if we have already got a counter for this cflow pointcut + if (field != null) { + localCflowField = (ResolvedMember) field; // Use the one we + // already have + + } else { + + // Create a counter field in the aspect + localCflowField = new ResolvedMemberImpl(Member.FIELD, concreteAspect, Modifier.STATIC | Modifier.PUBLIC + | Modifier.FINAL, NameMangler.cflowCounter(xcut), UnresolvedType.forName(NameMangler.CFLOW_COUNTER_TYPE) + .getSignature()); + + // Create type munger to add field to the aspect + concreteAspect.crosscuttingMembers.addTypeMunger(world.getWeavingSupport().makeCflowCounterFieldAdder( + localCflowField)); + + // Create shadow munger to push stuff onto the stack + concreteAspect.crosscuttingMembers.addConcreteShadowMunger(Advice.makeCflowEntry(world, concreteEntry, isBelow, + localCflowField, freeVars == null ? 0 : freeVars.length, innerCflowEntries, inAspect)); + + putCflowfield(xcut, concreteEntry, concreteAspect, localCflowField, "counter"); // Remember + // it + } + + Pointcut ret = new ConcreteCflowPointcut(localCflowField, null, true); + ret.copyLocationFrom(this); + return ret; } else { List slots = new ArrayList(); - - for (int i=0, len=freeVars.length; i < len; i++) { + + for (int i = 0, len = freeVars.length; i < len; i++) { int freeVar = freeVars[i]; - - // we don't need to keep state that isn't actually exposed to advice - //??? this means that we will store some state that we won't actually use, optimize this later - if (!bindings.hasKey(freeVar)) continue; - + + // we don't need to keep state that isn't actually exposed to + // advice + // ??? this means that we will store some state that we won't + // actually use, optimize this later + if (!bindings.hasKey(freeVar)) + continue; + int formalIndex = bindings.get(freeVar); - - // We need to look in the right place for the type of the formal. Suppose the advice looks like this: - // before(String s): somePointcut(*,s) + + // We need to look in the right place for the type of the + // formal. Suppose the advice looks like this: + // before(String s): somePointcut(*,s) // where the first argument in somePointcut is of type Number - // for free variable 0 we want to ask the pointcut for the type of its first argument, if we only - // ask the advice for the type of its first argument then we'll get the wrong type (pr86903) - + // for free variable 0 we want to ask the pointcut for the type + // of its first argument, if we only + // ask the advice for the type of its first argument then we'll + // get the wrong type (pr86903) + ResolvedPointcutDefinition enclosingDef = bindings.peekEnclosingDefinition(); ResolvedType formalType = null; - + // Is there a useful enclosing pointcut? - if (enclosingDef!=null && enclosingDef.getParameterTypes().length>0) { + if (enclosingDef != null && enclosingDef.getParameterTypes().length > 0) { formalType = enclosingDef.getParameterTypes()[freeVar].resolve(world); } else { formalType = bindings.getAdviceSignature().getParameterTypes()[formalIndex].resolve(world); } - - ConcreteCflowPointcut.Slot slot = - new ConcreteCflowPointcut.Slot(formalIndex, formalType, i); + + ConcreteCflowPointcut.Slot slot = new ConcreteCflowPointcut.Slot(formalIndex, formalType, i); slots.add(slot); } ResolvedMember localCflowField = null; - Object field = getCflowfield(xcut,concreteEntry,concreteAspect,"stack"); + Object field = getCflowfield(xcut, concreteEntry, concreteAspect, "stack"); if (field != null) { - localCflowField = (ResolvedMember)field; + localCflowField = (ResolvedMember) field; } else { - - localCflowField = new ResolvedMemberImpl( - Member.FIELD, concreteAspect, Modifier.STATIC | Modifier.PUBLIC | Modifier.FINAL, - NameMangler.cflowStack(xcut), - UnresolvedType.forName(NameMangler.CFLOW_STACK_TYPE).getSignature()); - //System.out.println("adding field to: " + inAspect + " field " + cflowField); - - // add field and initializer to inAspect - //XXX and then that info above needs to be mapped down here to help with - //XXX getting the exposed state right - concreteAspect.crosscuttingMembers.addConcreteShadowMunger( - Advice.makeCflowEntry(world, concreteEntry, isBelow, localCflowField, freeVars.length, innerCflowEntries,inAspect)); - - concreteAspect.crosscuttingMembers.addTypeMunger( - world.makeCflowStackFieldAdder(localCflowField)); - putCflowfield(xcut,concreteEntry,concreteAspect,localCflowField,"stack"); - } - Pointcut ret = new ConcreteCflowPointcut(localCflowField, slots,false); + + localCflowField = new ResolvedMemberImpl(Member.FIELD, concreteAspect, Modifier.STATIC | Modifier.PUBLIC + | Modifier.FINAL, NameMangler.cflowStack(xcut), UnresolvedType.forName(NameMangler.CFLOW_STACK_TYPE) + .getSignature()); + // System.out.println("adding field to: " + inAspect + " field " + // + cflowField); + + // add field and initializer to inAspect + // XXX and then that info above needs to be mapped down here to + // help with + // XXX getting the exposed state right + concreteAspect.crosscuttingMembers.addConcreteShadowMunger(Advice.makeCflowEntry(world, concreteEntry, isBelow, + localCflowField, freeVars.length, innerCflowEntries, inAspect)); + + concreteAspect.crosscuttingMembers.addTypeMunger(world.getWeavingSupport() + .makeCflowStackFieldAdder(localCflowField)); + putCflowfield(xcut, concreteEntry, concreteAspect, localCflowField, "stack"); + } + Pointcut ret = new ConcreteCflowPointcut(localCflowField, slots, false); ret.copyLocationFrom(this); return ret; } - + } - - - private String getKey(Pointcut p,ResolvedType a,String stackOrCounter) { - StringBuffer sb = new StringBuffer(); - sb.append(a.getName()); - sb.append("::"); - sb.append(p.toString()); - sb.append("::"); - sb.append(stackOrCounter); - return sb.toString(); + + private String getKey(Pointcut p, ResolvedType a, String stackOrCounter) { + StringBuffer sb = new StringBuffer(); + sb.append(a.getName()); + sb.append("::"); + sb.append(p.toString()); + sb.append("::"); + sb.append(stackOrCounter); + return sb.toString(); } - - private Object getCflowfield(CrosscuttingMembers xcut, Pointcut pcutkey, ResolvedType concreteAspect,String stackOrCounter) { - String key = getKey(pcutkey,concreteAspect,stackOrCounter); - Object o =null; - if (isBelow) o = xcut.getCflowBelowFields().get(key); - else o = xcut.getCflowFields().get(key); - //System.err.println("Retrieving for key "+key+" returning "+o); + + private Object getCflowfield(CrosscuttingMembers xcut, Pointcut pcutkey, ResolvedType concreteAspect, String stackOrCounter) { + String key = getKey(pcutkey, concreteAspect, stackOrCounter); + Object o = null; + if (isBelow) + o = xcut.getCflowBelowFields().get(key); + else + o = xcut.getCflowFields().get(key); + // System.err.println("Retrieving for key "+key+" returning "+o); return o; } - - private void putCflowfield(CrosscuttingMembers xcut, Pointcut pcutkey,ResolvedType concreteAspect,Object o,String stackOrCounter) { - String key = getKey(pcutkey,concreteAspect,stackOrCounter); - //System.err.println("Storing cflow field for key"+key); + + private void putCflowfield(CrosscuttingMembers xcut, Pointcut pcutkey, ResolvedType concreteAspect, Object o, + String stackOrCounter) { + String key = getKey(pcutkey, concreteAspect, stackOrCounter); + // System.err.println("Storing cflow field for key"+key); if (isBelow) { - xcut.getCflowBelowFields().put(key,o); + xcut.getCflowBelowFields().put(key, o); } else { - xcut.getCflowFields().put(key,o); + xcut.getCflowFields().put(key, o); } } - public Object accept(PatternNodeVisitor visitor, Object data) { - return visitor.visit(this, data); + public Object accept(PatternNodeVisitor visitor, Object data) { + return visitor.visit(this, data); } } diff --git a/weaver/src/org/aspectj/weaver/patterns/PerCflow.java b/weaver/src/org/aspectj/weaver/patterns/PerCflow.java index a8395fa2a..92ff54b7f 100644 --- a/weaver/src/org/aspectj/weaver/patterns/PerCflow.java +++ b/weaver/src/org/aspectj/weaver/patterns/PerCflow.java @@ -10,7 +10,6 @@ * PARC initial implementation * ******************************************************************/ - package org.aspectj.weaver.patterns; import java.io.DataOutputStream; @@ -39,133 +38,134 @@ import org.aspectj.weaver.ast.Test; import org.aspectj.weaver.bcel.BcelAccessForInlineMunger; public class PerCflow extends PerClause { - private boolean isBelow; - private Pointcut entry; - + private final boolean isBelow; + private final Pointcut entry; + public PerCflow(Pointcut entry, boolean isBelow) { this.entry = entry; this.isBelow = isBelow; } - + // ----- - + public Object accept(PatternNodeVisitor visitor, Object data) { - return visitor.visit(this,data); + return visitor.visit(this, data); } - + public int couldMatchKinds() { return Shadow.ALL_SHADOW_KINDS_BITS; } - + public FuzzyBoolean fastMatch(FastMatchInfo type) { return FuzzyBoolean.MAYBE; } - - protected FuzzyBoolean matchInternal(Shadow shadow) { - return FuzzyBoolean.YES; - } - - public void resolveBindings(IScope scope, Bindings bindings) { - // assert bindings == null; - entry.resolve(scope); - } - - public Pointcut parameterizeWith(Map typeVariableMap,World w) { - PerCflow ret = new PerCflow(entry.parameterizeWith(typeVariableMap,w),isBelow); - ret.copyLocationFrom(this); - return ret; - } - - protected Test findResidueInternal(Shadow shadow, ExposedState state) { - Expr myInstance = - Expr.makeCallExpr(AjcMemberMaker.perCflowAspectOfMethod(inAspect), - Expr.NONE, inAspect); - state.setAspectInstance(myInstance); - return Test.makeCall(AjcMemberMaker.perCflowHasAspectMethod(inAspect), Expr.NONE); - } + protected FuzzyBoolean matchInternal(Shadow shadow) { + return FuzzyBoolean.YES; + } + + public void resolveBindings(IScope scope, Bindings bindings) { + // assert bindings == null; + entry.resolve(scope); + } + + public Pointcut parameterizeWith(Map typeVariableMap, World w) { + PerCflow ret = new PerCflow(entry.parameterizeWith(typeVariableMap, w), isBelow); + ret.copyLocationFrom(this); + return ret; + } + + protected Test findResidueInternal(Shadow shadow, ExposedState state) { + Expr myInstance = Expr.makeCallExpr(AjcMemberMaker.perCflowAspectOfMethod(inAspect), Expr.NONE, inAspect); + state.setAspectInstance(myInstance); + return Test.makeCall(AjcMemberMaker.perCflowHasAspectMethod(inAspect), Expr.NONE); + } public PerClause concretize(ResolvedType inAspect) { PerCflow ret = new PerCflow(entry, isBelow); ret.inAspect = inAspect; - if (inAspect.isAbstract()) return ret; - - Member cflowStackField = new ResolvedMemberImpl( - Member.FIELD, inAspect, Modifier.STATIC|Modifier.PUBLIC|Modifier.FINAL, - UnresolvedType.forName(NameMangler.CFLOW_STACK_TYPE), NameMangler.PERCFLOW_FIELD_NAME, UnresolvedType.NONE); - + if (inAspect.isAbstract()) + return ret; + + Member cflowStackField = new ResolvedMemberImpl(Member.FIELD, inAspect, Modifier.STATIC | Modifier.PUBLIC | Modifier.FINAL, + UnresolvedType.forName(NameMangler.CFLOW_STACK_TYPE), NameMangler.PERCFLOW_FIELD_NAME, UnresolvedType.NONE); + World world = inAspect.getWorld(); - + CrosscuttingMembers xcut = inAspect.crosscuttingMembers; - + Collection previousCflowEntries = xcut.getCflowEntries(); - Pointcut concreteEntry = entry.concretize(inAspect, inAspect, 0, null); //IntMap.EMPTY); + Pointcut concreteEntry = entry.concretize(inAspect, inAspect, 0, null); // IntMap + // . + // EMPTY + // ) + // ; List innerCflowEntries = new ArrayList(xcut.getCflowEntries()); innerCflowEntries.removeAll(previousCflowEntries); - - xcut.addConcreteShadowMunger( - Advice.makePerCflowEntry(world, concreteEntry, isBelow, cflowStackField, - inAspect, innerCflowEntries)); - - //ATAJ: add a munger to add the aspectOf(..) to the @AJ aspects - if (inAspect.isAnnotationStyleAspect() && !inAspect.isAbstract()) { - inAspect.crosscuttingMembers.addLateTypeMunger( - inAspect.getWorld().makePerClauseAspect(inAspect, getKind()) - ); - } - - //ATAJ inline around advice support - don't use a late munger to allow around inling for itself - if (inAspect.isAnnotationStyleAspect() && !inAspect.getWorld().isXnoInline()) { - inAspect.crosscuttingMembers.addTypeMunger(new BcelAccessForInlineMunger(inAspect)); - } + + xcut.addConcreteShadowMunger(Advice.makePerCflowEntry(world, concreteEntry, isBelow, cflowStackField, inAspect, + innerCflowEntries)); + + // ATAJ: add a munger to add the aspectOf(..) to the @AJ aspects + if (inAspect.isAnnotationStyleAspect() && !inAspect.isAbstract()) { + inAspect.crosscuttingMembers.addLateTypeMunger(inAspect.getWorld().getWeavingSupport().makePerClauseAspect(inAspect, + getKind())); + } + + // ATAJ inline around advice support - don't use a late munger to allow + // around inling for itself + if (inAspect.isAnnotationStyleAspect() && !inAspect.getWorld().isXnoInline()) { + inAspect.crosscuttingMembers.addTypeMunger(new BcelAccessForInlineMunger(inAspect)); + } return ret; } - public void write(DataOutputStream s) throws IOException { - PERCFLOW.write(s); - entry.write(s); - s.writeBoolean(isBelow); - writeLocation(s); - } - + public void write(DataOutputStream s) throws IOException { + PERCFLOW.write(s); + entry.write(s); + s.writeBoolean(isBelow); + writeLocation(s); + } + public static PerClause readPerClause(VersionedDataInputStream s, ISourceContext context) throws IOException { PerCflow ret = new PerCflow(Pointcut.read(s, context), s.readBoolean()); ret.readLocation(context, s); return ret; } - + public PerClause.Kind getKind() { return PERCFLOW; } - - public Pointcut getEntry(){ + + public Pointcut getEntry() { return entry; } - + public String toString() { return "percflow(" + inAspect + " on " + entry + ")"; } - + public String toDeclarationString() { - if (isBelow) return "percflowbelow(" + entry + ")"; + if (isBelow) + return "percflowbelow(" + entry + ")"; return "percflow(" + entry + ")"; } - - public boolean equals(Object other) { - if (!(other instanceof PerCflow)) return false; - PerCflow pc = (PerCflow)other; - return (pc.isBelow && isBelow) - && ((pc.inAspect == null) ? (inAspect == null) : pc.inAspect.equals(inAspect)) - && ((pc.entry == null) ? (entry == null) : pc.entry.equals(entry)); - } - - public int hashCode() { - int result = 17; - result = 37*result + (isBelow?0:1); - result = 37*result + ((inAspect == null) ? 0 : inAspect.hashCode()); - result = 37*result + ((entry == null) ? 0 : entry.hashCode()); - return result; - } - + + public boolean equals(Object other) { + if (!(other instanceof PerCflow)) + return false; + PerCflow pc = (PerCflow) other; + return (pc.isBelow && isBelow) && ((pc.inAspect == null) ? (inAspect == null) : pc.inAspect.equals(inAspect)) + && ((pc.entry == null) ? (entry == null) : pc.entry.equals(entry)); + } + + public int hashCode() { + int result = 17; + result = 37 * result + (isBelow ? 0 : 1); + result = 37 * result + ((inAspect == null) ? 0 : inAspect.hashCode()); + result = 37 * result + ((entry == null) ? 0 : entry.hashCode()); + return result; + } + } diff --git a/weaver/src/org/aspectj/weaver/patterns/PerObject.java b/weaver/src/org/aspectj/weaver/patterns/PerObject.java index c22973492..51bee7152 100644 --- a/weaver/src/org/aspectj/weaver/patterns/PerObject.java +++ b/weaver/src/org/aspectj/weaver/patterns/PerObject.java @@ -10,7 +10,6 @@ * PARC initial implementation * ******************************************************************/ - package org.aspectj.weaver.patterns; import java.io.DataOutputStream; @@ -33,158 +32,157 @@ import org.aspectj.weaver.ast.Var; import org.aspectj.weaver.bcel.BcelAccessForInlineMunger; public class PerObject extends PerClause { - private boolean isThis; - private Pointcut entry; - + private final boolean isThis; + private final Pointcut entry; + private static final int thisKindSet; private static final int targetKindSet; - + static { int thisFlags = Shadow.ALL_SHADOW_KINDS_BITS; int targFlags = Shadow.ALL_SHADOW_KINDS_BITS; for (int i = 0; i < Shadow.SHADOW_KINDS.length; i++) { Shadow.Kind kind = Shadow.SHADOW_KINDS[i]; - if (kind.neverHasThis()) thisFlags-=kind.bit; - if (kind.neverHasTarget()) targFlags-=kind.bit; + if (kind.neverHasThis()) + thisFlags -= kind.bit; + if (kind.neverHasTarget()) + targFlags -= kind.bit; } thisKindSet = thisFlags; - targetKindSet=targFlags; + targetKindSet = targFlags; } - + public PerObject(Pointcut entry, boolean isThis) { this.entry = entry; this.isThis = isThis; } public Object accept(PatternNodeVisitor visitor, Object data) { - return visitor.visit(this,data); + return visitor.visit(this, data); } - + public int couldMatchKinds() { return isThis ? thisKindSet : targetKindSet; } - + // ----- public FuzzyBoolean fastMatch(FastMatchInfo type) { return FuzzyBoolean.MAYBE; } - - protected FuzzyBoolean matchInternal(Shadow shadow) { - //System.err.println("matches " + this + " ? " + shadow + ", " + shadow.hasTarget()); - //??? could probably optimize this better by testing could match - if (isThis) return FuzzyBoolean.fromBoolean(shadow.hasThis()); - else return FuzzyBoolean.fromBoolean(shadow.hasTarget()); - } - - public void resolveBindings(IScope scope, Bindings bindings) { - // assert bindings == null; - entry.resolve(scope); - } - - public Pointcut parameterizeWith(Map typeVariableMap,World w) { - PerObject ret = new PerObject(entry.parameterizeWith(typeVariableMap,w),isThis); - ret.copyLocationFrom(this); - return ret; - } - - private Var getVar(Shadow shadow) { - return isThis ? shadow.getThisVar() : shadow.getTargetVar(); - } - - protected Test findResidueInternal(Shadow shadow, ExposedState state) { - Expr myInstance = - Expr.makeCallExpr(AjcMemberMaker.perObjectAspectOfMethod(inAspect), - new Expr[] {getVar(shadow)}, inAspect); - state.setAspectInstance(myInstance); - return Test.makeCall(AjcMemberMaker.perObjectHasAspectMethod(inAspect), - new Expr[] { getVar(shadow) }); - } + protected FuzzyBoolean matchInternal(Shadow shadow) { + // System.err.println("matches " + this + " ? " + shadow + ", " + + // shadow.hasTarget()); + // ??? could probably optimize this better by testing could match + if (isThis) + return FuzzyBoolean.fromBoolean(shadow.hasThis()); + else + return FuzzyBoolean.fromBoolean(shadow.hasTarget()); + } + + public void resolveBindings(IScope scope, Bindings bindings) { + // assert bindings == null; + entry.resolve(scope); + } + + public Pointcut parameterizeWith(Map typeVariableMap, World w) { + PerObject ret = new PerObject(entry.parameterizeWith(typeVariableMap, w), isThis); + ret.copyLocationFrom(this); + return ret; + } + private Var getVar(Shadow shadow) { + return isThis ? shadow.getThisVar() : shadow.getTargetVar(); + } + + protected Test findResidueInternal(Shadow shadow, ExposedState state) { + Expr myInstance = Expr.makeCallExpr(AjcMemberMaker.perObjectAspectOfMethod(inAspect), new Expr[] { getVar(shadow) }, + inAspect); + state.setAspectInstance(myInstance); + return Test.makeCall(AjcMemberMaker.perObjectHasAspectMethod(inAspect), new Expr[] { getVar(shadow) }); + } public PerClause concretize(ResolvedType inAspect) { PerObject ret = new PerObject(entry, isThis); - + ret.inAspect = inAspect; - if (inAspect.isAbstract()) return ret; - - + if (inAspect.isAbstract()) + return ret; + World world = inAspect.getWorld(); - + Pointcut concreteEntry = entry.concretize(inAspect, inAspect, 0, null); - //concreteEntry = new AndPointcut(this, concreteEntry); - //concreteEntry.state = Pointcut.CONCRETE; - inAspect.crosscuttingMembers.addConcreteShadowMunger( - Advice.makePerObjectEntry(world, concreteEntry, isThis, inAspect)); - - // FIXME AV - don't use lateMunger here due to test "inheritance, around advice and abstract pointcuts" - // see #75442 thread. Issue with weaving order. - ResolvedTypeMunger munger = - new PerObjectInterfaceTypeMunger(inAspect, concreteEntry); - inAspect.crosscuttingMembers.addLateTypeMunger(world.concreteTypeMunger(munger, inAspect)); - - //ATAJ: add a munger to add the aspectOf(..) to the @AJ aspects - if (inAspect.isAnnotationStyleAspect() && !inAspect.isAbstract()) { - inAspect.crosscuttingMembers.addLateTypeMunger( - inAspect.getWorld().makePerClauseAspect(inAspect, getKind()) - ); - } - - //ATAJ inline around advice support - don't use a late munger to allow around inling for itself - if (inAspect.isAnnotationStyleAspect() && !inAspect.getWorld().isXnoInline()) { - inAspect.crosscuttingMembers.addTypeMunger(new BcelAccessForInlineMunger(inAspect)); - } + // concreteEntry = new AndPointcut(this, concreteEntry); + // concreteEntry.state = Pointcut.CONCRETE; + inAspect.crosscuttingMembers.addConcreteShadowMunger(Advice.makePerObjectEntry(world, concreteEntry, isThis, inAspect)); + + // FIXME AV - don't use lateMunger here due to test + // "inheritance, around advice and abstract pointcuts" + // see #75442 thread. Issue with weaving order. + ResolvedTypeMunger munger = new PerObjectInterfaceTypeMunger(inAspect, concreteEntry); + inAspect.crosscuttingMembers.addLateTypeMunger(world.getWeavingSupport().concreteTypeMunger(munger, inAspect)); + + // ATAJ: add a munger to add the aspectOf(..) to the @AJ aspects + if (inAspect.isAnnotationStyleAspect() && !inAspect.isAbstract()) { + inAspect.crosscuttingMembers.addLateTypeMunger(inAspect.getWorld().getWeavingSupport().makePerClauseAspect(inAspect, + getKind())); + } + + // ATAJ inline around advice support - don't use a late munger to allow + // around inling for itself + if (inAspect.isAnnotationStyleAspect() && !inAspect.getWorld().isXnoInline()) { + inAspect.crosscuttingMembers.addTypeMunger(new BcelAccessForInlineMunger(inAspect)); + } return ret; } - public void write(DataOutputStream s) throws IOException { - PEROBJECT.write(s); - entry.write(s); - s.writeBoolean(isThis); - writeLocation(s); - } - + public void write(DataOutputStream s) throws IOException { + PEROBJECT.write(s); + entry.write(s); + s.writeBoolean(isThis); + writeLocation(s); + } + public static PerClause readPerClause(VersionedDataInputStream s, ISourceContext context) throws IOException { PerClause ret = new PerObject(Pointcut.read(s, context), s.readBoolean()); ret.readLocation(context, s); return ret; } - + public PerClause.Kind getKind() { return PEROBJECT; } - public boolean isThis() { - return isThis; - } + public boolean isThis() { + return isThis; + } public String toString() { - return "per" + (isThis ? "this" : "target") + - "(" + entry + ")"; + return "per" + (isThis ? "this" : "target") + "(" + entry + ")"; } - + public String toDeclarationString() { return toString(); } - + public Pointcut getEntry() { return entry; } - - public boolean equals(Object other) { - if (!(other instanceof PerObject)) return false; - PerObject pc = (PerObject)other; - return (pc.isThis && isThis) - && ((pc.inAspect == null) ? (inAspect == null) : pc.inAspect.equals(inAspect)) - && ((pc.entry == null) ? (entry == null) : pc.entry.equals(entry)); - } - - public int hashCode() { - int result = 17; - result = 37*result + (isThis?0:1); - result = 37*result + ((inAspect == null) ? 0 : inAspect.hashCode()); - result = 37*result + ((entry == null) ? 0 : entry.hashCode()); - return result; - } + + public boolean equals(Object other) { + if (!(other instanceof PerObject)) + return false; + PerObject pc = (PerObject) other; + return (pc.isThis && isThis) && ((pc.inAspect == null) ? (inAspect == null) : pc.inAspect.equals(inAspect)) + && ((pc.entry == null) ? (entry == null) : pc.entry.equals(entry)); + } + + public int hashCode() { + int result = 17; + result = 37 * result + (isThis ? 0 : 1); + result = 37 * result + ((inAspect == null) ? 0 : inAspect.hashCode()); + result = 37 * result + ((entry == null) ? 0 : entry.hashCode()); + return result; + } } diff --git a/weaver/src/org/aspectj/weaver/patterns/PerSingleton.java b/weaver/src/org/aspectj/weaver/patterns/PerSingleton.java index 065a82777..3e5a97023 100644 --- a/weaver/src/org/aspectj/weaver/patterns/PerSingleton.java +++ b/weaver/src/org/aspectj/weaver/patterns/PerSingleton.java @@ -10,7 +10,6 @@ * PARC initial implementation * ******************************************************************/ - package org.aspectj.weaver.patterns; import java.io.DataOutputStream; @@ -32,15 +31,15 @@ import org.aspectj.weaver.bcel.BcelAccessForInlineMunger; public class PerSingleton extends PerClause { - private ResolvedMember perSingletonAspectOfMethod; + private ResolvedMember perSingletonAspectOfMethod; public PerSingleton() { } public Object accept(PatternNodeVisitor visitor, Object data) { - return visitor.visit(this,data); + return visitor.visit(this, data); } - + public int couldMatchKinds() { return Shadow.ALL_SHADOW_KINDS_BITS; } @@ -48,126 +47,128 @@ public class PerSingleton extends PerClause { public FuzzyBoolean fastMatch(FastMatchInfo type) { return FuzzyBoolean.YES; } - - protected FuzzyBoolean matchInternal(Shadow shadow) { - return FuzzyBoolean.YES; - } - - public void resolveBindings(IScope scope, Bindings bindings) { - // this method intentionally left blank - } - - public Pointcut parameterizeWith(Map typeVariableMap,World w) { - return this; - } - - - public Test findResidueInternal(Shadow shadow, ExposedState state) { - // TODO: the commented code is for slow Aspects.aspectOf() style - keep or remove - // - // Expr myInstance = - // Expr.makeCallExpr(AjcMemberMaker.perSingletonAspectOfMethod(inAspect), - // Expr.NONE, inAspect); - // - // state.setAspectInstance(myInstance); - // - // // we have no test - // // a NoAspectBoundException will be thrown if we need an instance of this - // // aspect before we are bound - // return Literal.TRUE; -// if (!Ajc5MemberMaker.isSlowAspect(inAspect)) { - if (perSingletonAspectOfMethod==null) { - // Build this just once - perSingletonAspectOfMethod = AjcMemberMaker.perSingletonAspectOfMethod(inAspect); - } - Expr myInstance = Expr.makeCallExpr(perSingletonAspectOfMethod, Expr.NONE, inAspect); - - state.setAspectInstance(myInstance); - - // we have no test - // a NoAspectBoundException will be thrown if we need an instance of this - // aspect before we are bound - return Literal.TRUE; -// } else { -// CallExpr callAspectOf =Expr.makeCallExpr( -// Ajc5MemberMaker.perSingletonAspectOfMethod(inAspect), -// new Expr[]{ -// Expr.makeStringConstantExpr(inAspect.getName(), inAspect), -// //FieldGet is using ResolvedType and I don't need that here -// new FieldGetOn(Member.ajClassField, shadow.getEnclosingType()) -// }, -// inAspect -// ); -// Expr castedCallAspectOf = new CastExpr(callAspectOf, inAspect.getName()); -// state.setAspectInstance(castedCallAspectOf); -// return Literal.TRUE; -// } - } + + protected FuzzyBoolean matchInternal(Shadow shadow) { + return FuzzyBoolean.YES; + } + + public void resolveBindings(IScope scope, Bindings bindings) { + // this method intentionally left blank + } + + public Pointcut parameterizeWith(Map typeVariableMap, World w) { + return this; + } + + public Test findResidueInternal(Shadow shadow, ExposedState state) { + // TODO: the commented code is for slow Aspects.aspectOf() style - keep + // or remove + // + // Expr myInstance = + //Expr.makeCallExpr(AjcMemberMaker.perSingletonAspectOfMethod(inAspect), + // Expr.NONE, inAspect); + // + // state.setAspectInstance(myInstance); + // + // // we have no test + // // a NoAspectBoundException will be thrown if we need an instance of + // this + // // aspect before we are bound + // return Literal.TRUE; + // if (!Ajc5MemberMaker.isSlowAspect(inAspect)) { + if (perSingletonAspectOfMethod == null) { + // Build this just once + perSingletonAspectOfMethod = AjcMemberMaker.perSingletonAspectOfMethod(inAspect); + } + Expr myInstance = Expr.makeCallExpr(perSingletonAspectOfMethod, Expr.NONE, inAspect); + + state.setAspectInstance(myInstance); + + // we have no test + // a NoAspectBoundException will be thrown if we need an instance of + // this + // aspect before we are bound + return Literal.TRUE; + // } else { + // CallExpr callAspectOf =Expr.makeCallExpr( + // Ajc5MemberMaker.perSingletonAspectOfMethod(inAspect), + // new Expr[]{ + // Expr.makeStringConstantExpr(inAspect.getName(), inAspect), + // //FieldGet is using ResolvedType and I don't need that here + // new FieldGetOn(Member.ajClassField, shadow.getEnclosingType()) + // }, + // inAspect + // ); + // Expr castedCallAspectOf = new CastExpr(callAspectOf, + // inAspect.getName()); + // state.setAspectInstance(castedCallAspectOf); + // return Literal.TRUE; + // } + } public PerClause concretize(ResolvedType inAspect) { PerSingleton ret = new PerSingleton(); - ret.copyLocationFrom(this); + ret.copyLocationFrom(this); ret.inAspect = inAspect; - //ATAJ: add a munger to add the aspectOf(..) to the @AJ aspects - if (inAspect.isAnnotationStyleAspect() && !inAspect.isAbstract()) { - //TODO will those change be ok if we add a serializable aspect ? - // dig: "can't be Serializable/Cloneable unless -XserializableAspects" - if (getKind()==SINGLETON) { // pr149560 - inAspect.crosscuttingMembers.addTypeMunger( - inAspect.getWorld().makePerClauseAspect(inAspect, getKind()) - ); - } else { - inAspect.crosscuttingMembers.addLateTypeMunger( - inAspect.getWorld().makePerClauseAspect(inAspect, getKind()) - ); - } - } - - //ATAJ inline around advice support - if (inAspect.isAnnotationStyleAspect() && !inAspect.getWorld().isXnoInline()) { - inAspect.crosscuttingMembers.addTypeMunger(new BcelAccessForInlineMunger(inAspect)); - } - - return ret; - } - - public void write(DataOutputStream s) throws IOException { - SINGLETON.write(s); - writeLocation(s); - } - + // ATAJ: add a munger to add the aspectOf(..) to the @AJ aspects + if (inAspect.isAnnotationStyleAspect() && !inAspect.isAbstract()) { + // TODO will those change be ok if we add a serializable aspect ? + // dig: + // "can't be Serializable/Cloneable unless -XserializableAspects" + if (getKind() == SINGLETON) { // pr149560 + inAspect.crosscuttingMembers.addTypeMunger(inAspect.getWorld().getWeavingSupport().makePerClauseAspect(inAspect, + getKind())); + } else { + inAspect.crosscuttingMembers.addLateTypeMunger(inAspect.getWorld().getWeavingSupport().makePerClauseAspect( + inAspect, getKind())); + } + } + + // ATAJ inline around advice support + if (inAspect.isAnnotationStyleAspect() && !inAspect.getWorld().isXnoInline()) { + inAspect.crosscuttingMembers.addTypeMunger(new BcelAccessForInlineMunger(inAspect)); + } + + return ret; + } + + public void write(DataOutputStream s) throws IOException { + SINGLETON.write(s); + writeLocation(s); + } + public static PerClause readPerClause(VersionedDataInputStream s, ISourceContext context) throws IOException { PerSingleton ret = new PerSingleton(); ret.readLocation(context, s); return ret; } - - + public PerClause.Kind getKind() { return SINGLETON; } - + public String toString() { return "persingleton(" + inAspect + ")"; } - + public String toDeclarationString() { return ""; } - public boolean equals(Object other) { - if (!(other instanceof PerSingleton)) return false; - PerSingleton pc = (PerSingleton)other; - return ((pc.inAspect == null) ? (inAspect == null) : pc.inAspect.equals(inAspect)); - } - - public int hashCode() { - int result = 17; - result = 37*result + ((inAspect == null) ? 0 : inAspect.hashCode()); - return result; - } - + public boolean equals(Object other) { + if (!(other instanceof PerSingleton)) + return false; + PerSingleton pc = (PerSingleton) other; + return ((pc.inAspect == null) ? (inAspect == null) : pc.inAspect.equals(inAspect)); + } + + public int hashCode() { + int result = 17; + result = 37 * result + ((inAspect == null) ? 0 : inAspect.hashCode()); + return result; + } + } diff --git a/weaver/src/org/aspectj/weaver/patterns/PerTypeWithin.java b/weaver/src/org/aspectj/weaver/patterns/PerTypeWithin.java index ad9f00381..df7e4085a 100644 --- a/weaver/src/org/aspectj/weaver/patterns/PerTypeWithin.java +++ b/weaver/src/org/aspectj/weaver/patterns/PerTypeWithin.java @@ -35,37 +35,36 @@ import org.aspectj.weaver.ast.Literal; import org.aspectj.weaver.ast.Test; import org.aspectj.weaver.bcel.BcelAccessForInlineMunger; - // PTWIMPL Represents a parsed pertypewithin() public class PerTypeWithin extends PerClause { private TypePattern typePattern; - + // Any shadow could be considered within a pertypewithin() type pattern private static final int kindSet = Shadow.ALL_SHADOW_KINDS_BITS; - + public TypePattern getTypePattern() { return typePattern; } - + public PerTypeWithin(TypePattern p) { - this.typePattern = p; + typePattern = p; } public Object accept(PatternNodeVisitor visitor, Object data) { - return visitor.visit(this,data); + return visitor.visit(this, data); } - + public int couldMatchKinds() { return kindSet; } - - public Pointcut parameterizeWith(Map typeVariableMap,World w) { - PerTypeWithin ret = new PerTypeWithin(typePattern.parameterizeWith(typeVariableMap,w)); + + public Pointcut parameterizeWith(Map typeVariableMap, World w) { + PerTypeWithin ret = new PerTypeWithin(typePattern.parameterizeWith(typeVariableMap, w)); ret.copyLocationFrom(this); return ret; } - + // ----- public FuzzyBoolean fastMatch(FastMatchInfo info) { if (typePattern.annotationPattern instanceof AnyAnnotationTypePattern) { @@ -73,133 +72,138 @@ public class PerTypeWithin extends PerClause { } return FuzzyBoolean.MAYBE; } - - protected FuzzyBoolean matchInternal(Shadow shadow) { - ResolvedType enclosingType = shadow.getIWorld().resolve(shadow.getEnclosingType(),true); - if (enclosingType.isMissing()) { - //PTWIMPL ?? Add a proper message - IMessage msg = new Message( - "Cant find type pertypewithin matching...", - shadow.getSourceLocation(),true,new ISourceLocation[]{getSourceLocation()}); - shadow.getIWorld().getMessageHandler().handleMessage(msg); - } - - // See pr106554 - we can't put advice calls in an interface when the advice is defined - // in a pertypewithin aspect - the JPs only exist in the static initializer and can't - // call the localAspectOf() method. - if (enclosingType.isInterface()) return FuzzyBoolean.NO; - - typePattern.resolve(shadow.getIWorld()); - return isWithinType(enclosingType); - } - - public void resolveBindings(IScope scope, Bindings bindings) { - typePattern = typePattern.resolveBindings(scope, bindings, false, false); - } - - protected Test findResidueInternal(Shadow shadow, ExposedState state) { -// Member ptwField = AjcMemberMaker.perTypeWithinField(shadow.getEnclosingType(),inAspect); - - Expr myInstance = - Expr.makeCallExpr(AjcMemberMaker.perTypeWithinLocalAspectOf(shadow.getEnclosingType(),inAspect/*shadow.getEnclosingType()*/), - Expr.NONE,inAspect); - state.setAspectInstance(myInstance); - - // this worked at one point - //Expr myInstance = Expr.makeFieldGet(ptwField,shadow.getEnclosingType().resolve(shadow.getIWorld()));//inAspect); - //state.setAspectInstance(myInstance); - - -// return Test.makeFieldGetCall(ptwField,null,Expr.NONE); - // cflowField, cflowCounterIsValidMethod, Expr.NONE - - // This is what is in the perObject variant of this ... -// Expr myInstance = -// Expr.makeCallExpr(AjcMemberMaker.perTypeWithinAspectOfMethod(inAspect), -// new Expr[] {getVar(shadow)}, inAspect); -// state.setAspectInstance(myInstance); -// return Test.makeCall(AjcMemberMaker.perTypeWithinHasAspectMethod(inAspect), -// new Expr[] { getVar(shadow) }); -// - - - return match(shadow).alwaysTrue()?Literal.TRUE:Literal.FALSE; - } - + + protected FuzzyBoolean matchInternal(Shadow shadow) { + ResolvedType enclosingType = shadow.getIWorld().resolve(shadow.getEnclosingType(), true); + if (enclosingType.isMissing()) { + // PTWIMPL ?? Add a proper message + IMessage msg = new Message("Cant find type pertypewithin matching...", shadow.getSourceLocation(), true, + new ISourceLocation[] { getSourceLocation() }); + shadow.getIWorld().getMessageHandler().handleMessage(msg); + } + + // See pr106554 - we can't put advice calls in an interface when the + // advice is defined + // in a pertypewithin aspect - the JPs only exist in the static + // initializer and can't + // call the localAspectOf() method. + if (enclosingType.isInterface()) + return FuzzyBoolean.NO; + + typePattern.resolve(shadow.getIWorld()); + return isWithinType(enclosingType); + } + + public void resolveBindings(IScope scope, Bindings bindings) { + typePattern = typePattern.resolveBindings(scope, bindings, false, false); + } + + protected Test findResidueInternal(Shadow shadow, ExposedState state) { + // Member ptwField = + // AjcMemberMaker.perTypeWithinField(shadow.getEnclosingType + // (),inAspect); + + Expr myInstance = Expr.makeCallExpr(AjcMemberMaker.perTypeWithinLocalAspectOf(shadow.getEnclosingType(), inAspect/* + * shadow. + * getEnclosingType + * ( + * ) + */), + Expr.NONE, inAspect); + state.setAspectInstance(myInstance); + + // this worked at one point + // Expr myInstance = + // Expr.makeFieldGet(ptwField,shadow.getEnclosingType() + // .resolve(shadow.getIWorld()));//inAspect); + // state.setAspectInstance(myInstance); + + // return Test.makeFieldGetCall(ptwField,null,Expr.NONE); + // cflowField, cflowCounterIsValidMethod, Expr.NONE + + // This is what is in the perObject variant of this ... + // Expr myInstance = + //Expr.makeCallExpr(AjcMemberMaker.perTypeWithinAspectOfMethod(inAspect) + // , + // new Expr[] {getVar(shadow)}, inAspect); + // state.setAspectInstance(myInstance); + // return + // Test.makeCall(AjcMemberMaker.perTypeWithinHasAspectMethod(inAspect), + // new Expr[] { getVar(shadow) }); + // + + return match(shadow).alwaysTrue() ? Literal.TRUE : Literal.FALSE; + } public PerClause concretize(ResolvedType inAspect) { PerTypeWithin ret = new PerTypeWithin(typePattern); ret.copyLocationFrom(this); ret.inAspect = inAspect; - if (inAspect.isAbstract()) return ret; - - + if (inAspect.isAbstract()) + return ret; + World world = inAspect.getWorld(); - - SignaturePattern sigpat = new SignaturePattern( - Member.STATIC_INITIALIZATION, - ModifiersPattern.ANY, - TypePattern.ANY, - TypePattern.ANY,//typePattern, - NamePattern.ANY, - TypePatternList.ANY, - ThrowsPattern.ANY, - AnnotationTypePattern.ANY - ); - - Pointcut staticInitStar = new KindedPointcut(Shadow.StaticInitialization,sigpat); - Pointcut withinTp= new WithinPointcut(typePattern); - Pointcut andPcut = new AndPointcut(staticInitStar,withinTp); - // We want the pointcut to be 'staticinitialization(*) && within(' - - // we *cannot* shortcut this to staticinitialization() because it + + SignaturePattern sigpat = new SignaturePattern(Member.STATIC_INITIALIZATION, ModifiersPattern.ANY, TypePattern.ANY, + TypePattern.ANY,// typePattern, + NamePattern.ANY, TypePatternList.ANY, ThrowsPattern.ANY, AnnotationTypePattern.ANY); + + Pointcut staticInitStar = new KindedPointcut(Shadow.StaticInitialization, sigpat); + Pointcut withinTp = new WithinPointcut(typePattern); + Pointcut andPcut = new AndPointcut(staticInitStar, withinTp); + // We want the pointcut to be 'staticinitialization(*) && + // within(' - + // we *cannot* shortcut this to staticinitialization() + // because it // doesnt mean the same thing. - // This munger will initialize the aspect instance field in the matched type + // This munger will initialize the aspect instance field in the matched + // type inAspect.crosscuttingMembers.addConcreteShadowMunger(Advice.makePerTypeWithinEntry(world, andPcut, inAspect)); - + ResolvedTypeMunger munger = new PerTypeWithinTargetTypeMunger(inAspect, ret); - inAspect.crosscuttingMembers.addTypeMunger(world.concreteTypeMunger(munger, inAspect)); + inAspect.crosscuttingMembers.addTypeMunger(world.getWeavingSupport().concreteTypeMunger(munger, inAspect)); - //ATAJ: add a munger to add the aspectOf(..) to the @AJ aspects - if (inAspect.isAnnotationStyleAspect() && !inAspect.isAbstract()) { - inAspect.crosscuttingMembers.addLateTypeMunger( - inAspect.getWorld().makePerClauseAspect(inAspect, getKind()) - ); - } + // ATAJ: add a munger to add the aspectOf(..) to the @AJ aspects + if (inAspect.isAnnotationStyleAspect() && !inAspect.isAbstract()) { + inAspect.crosscuttingMembers.addLateTypeMunger(inAspect.getWorld().getWeavingSupport().makePerClauseAspect(inAspect, + getKind())); + } - //ATAJ inline around advice support - don't use a late munger to allow around inling for itself - if (inAspect.isAnnotationStyleAspect() && !inAspect.getWorld().isXnoInline()) { - inAspect.crosscuttingMembers.addTypeMunger(new BcelAccessForInlineMunger(inAspect)); - } + // ATAJ inline around advice support - don't use a late munger to allow + // around inling for itself + if (inAspect.isAnnotationStyleAspect() && !inAspect.getWorld().isXnoInline()) { + inAspect.crosscuttingMembers.addTypeMunger(new BcelAccessForInlineMunger(inAspect)); + } return ret; - + + } + + public void write(DataOutputStream s) throws IOException { + PERTYPEWITHIN.write(s); + typePattern.write(s); + writeLocation(s); } - public void write(DataOutputStream s) throws IOException { - PERTYPEWITHIN.write(s); - typePattern.write(s); - writeLocation(s); - } - public static PerClause readPerClause(VersionedDataInputStream s, ISourceContext context) throws IOException { PerClause ret = new PerTypeWithin(TypePattern.read(s, context)); ret.readLocation(context, s); return ret; } - + public PerClause.Kind getKind() { return PERTYPEWITHIN; } - + public String toString() { - return "pertypewithin("+typePattern+")"; + return "pertypewithin(" + typePattern + ")"; } - + public String toDeclarationString() { return toString(); } - + private FuzzyBoolean isWithinType(ResolvedType type) { while (type != null) { if (typePattern.matchesStatically(type)) { @@ -209,19 +213,20 @@ public class PerTypeWithin extends PerClause { } return FuzzyBoolean.NO; } - - public boolean equals(Object other) { - if (!(other instanceof PerTypeWithin)) return false; - PerTypeWithin pc = (PerTypeWithin)other; - return ((pc.inAspect == null) ? (inAspect == null) : pc.inAspect.equals(inAspect)) - && ((pc.typePattern == null) ? (typePattern == null) : pc.typePattern.equals(typePattern)); - } - - public int hashCode() { - int result = 17; - result = 37*result + ((inAspect == null) ? 0 : inAspect.hashCode()); - result = 37*result + ((typePattern == null) ? 0 : typePattern.hashCode()); - return result; - } - + + public boolean equals(Object other) { + if (!(other instanceof PerTypeWithin)) + return false; + PerTypeWithin pc = (PerTypeWithin) other; + return ((pc.inAspect == null) ? (inAspect == null) : pc.inAspect.equals(inAspect)) + && ((pc.typePattern == null) ? (typePattern == null) : pc.typePattern.equals(typePattern)); + } + + public int hashCode() { + int result = 17; + result = 37 * result + ((inAspect == null) ? 0 : inAspect.hashCode()); + result = 37 * result + ((typePattern == null) ? 0 : typePattern.hashCode()); + return result; + } + } diff --git a/weaver/src/org/aspectj/weaver/reflect/ReflectionWorld.java b/weaver/src/org/aspectj/weaver/reflect/ReflectionWorld.java index fc4a9d561..24b098e3c 100644 --- a/weaver/src/org/aspectj/weaver/reflect/ReflectionWorld.java +++ b/weaver/src/org/aspectj/weaver/reflect/ReflectionWorld.java @@ -15,47 +15,43 @@ import org.aspectj.bridge.AbortException; import org.aspectj.bridge.IMessage; import org.aspectj.bridge.IMessageHandler; import org.aspectj.util.LangUtil; -import org.aspectj.weaver.Advice; import org.aspectj.weaver.BCException; -import org.aspectj.weaver.ConcreteTypeMunger; -import org.aspectj.weaver.Member; +import org.aspectj.weaver.IWeavingSupport; import org.aspectj.weaver.ReferenceType; import org.aspectj.weaver.ReferenceTypeDelegate; -import org.aspectj.weaver.ResolvedMember; import org.aspectj.weaver.ResolvedType; -import org.aspectj.weaver.ResolvedTypeMunger; import org.aspectj.weaver.UnresolvedType; import org.aspectj.weaver.WeakClassLoaderReference; import org.aspectj.weaver.World; -import org.aspectj.weaver.AjAttribute.AdviceAttribute; -import org.aspectj.weaver.patterns.Pointcut; -import org.aspectj.weaver.patterns.PerClause.Kind; /** - * A ReflectionWorld is used solely for purposes of type resolution based on - * the runtime classpath (java.lang.reflect). It does not support weaving operations + * A ReflectionWorld is used solely for purposes of type resolution based on the + * runtime classpath (java.lang.reflect). It does not support weaving operations * (creation of mungers etc..). - * + * */ public class ReflectionWorld extends World implements IReflectionWorld { private WeakClassLoaderReference classLoaderReference; private AnnotationFinder annotationFinder; - + private ReflectionWorld() { -// super(); -// this.setMessageHandler(new ExceptionBasedMessageHandler()); -// setBehaveInJava5Way(LangUtil.is15VMOrGreater()); -// this.classLoaderReference = new WeakClassLoaderReference(ReflectionWorld.class.getClassLoader()); -// this.annotationFinder = makeAnnotationFinderIfAny(classLoaderReference.getClassLoader(), this); + // super(); + // this.setMessageHandler(new ExceptionBasedMessageHandler()); + // setBehaveInJava5Way(LangUtil.is15VMOrGreater()); + // this.classLoaderReference = new + // WeakClassLoaderReference(ReflectionWorld.class.getClassLoader()); + // this.annotationFinder = + // makeAnnotationFinderIfAny(classLoaderReference.getClassLoader(), + // this); } - + public ReflectionWorld(ClassLoader aClassLoader) { super(); this.setMessageHandler(new ExceptionBasedMessageHandler()); setBehaveInJava5Way(LangUtil.is15VMOrGreater()); - this.classLoaderReference = new WeakClassLoaderReference(aClassLoader); - this.annotationFinder = makeAnnotationFinderIfAny(classLoaderReference.getClassLoader(), this); + classLoaderReference = new WeakClassLoaderReference(aClassLoader); + annotationFinder = makeAnnotationFinderIfAny(classLoaderReference.getClassLoader(), this); } public static AnnotationFinder makeAnnotationFinderIfAny(ClassLoader loader, World world) { @@ -67,88 +63,44 @@ public class ReflectionWorld extends World implements IReflectionWorld { annotationFinder.setClassLoader(loader); annotationFinder.setWorld(world); } - } catch(ClassNotFoundException ex) { + } catch (ClassNotFoundException ex) { // must be on 1.4 or earlier - } catch(IllegalAccessException ex) { + } catch (IllegalAccessException ex) { // not so good - throw new BCException("AspectJ internal error",ex); - } catch(InstantiationException ex) { - throw new BCException("AspectJ internal error",ex); + throw new BCException("AspectJ internal error", ex); + } catch (InstantiationException ex) { + throw new BCException("AspectJ internal error", ex); } return annotationFinder; } - + public ClassLoader getClassLoader() { - return this.classLoaderReference.getClassLoader(); + return classLoaderReference.getClassLoader(); } - + public AnnotationFinder getAnnotationFinder() { - return this.annotationFinder; + return annotationFinder; } - - /* (non-Javadoc) - * @see org.aspectj.weaver.reflect.IReflectionWorld#resolve(java.lang.Class) - */ + public ResolvedType resolve(Class aClass) { return resolve(this, aClass); } - + public static ResolvedType resolve(World world, Class aClass) { - // classes that represent arrays return a class name that is the signature of the array type, ho-hum... + // classes that represent arrays return a class name that is the + // signature of the array type, ho-hum... String className = aClass.getName(); if (aClass.isArray()) { - return world.resolve(UnresolvedType.forSignature(className.replace('.','/'))); - } - else{ + return world.resolve(UnresolvedType.forSignature(className.replace('.', '/'))); + } else { return world.resolve(className); - } - } - - /* (non-Javadoc) - * @see org.aspectj.weaver.World#resolveDelegate(org.aspectj.weaver.ReferenceType) - */ - protected ReferenceTypeDelegate resolveDelegate(ReferenceType ty) { - return ReflectionBasedReferenceTypeDelegateFactory.createDelegate(ty, this, this.classLoaderReference.getClassLoader()); - } - - /* (non-Javadoc) - * @see org.aspectj.weaver.World#createAdviceMunger(org.aspectj.weaver.AjAttribute.AdviceAttribute, org.aspectj.weaver.patterns.Pointcut, org.aspectj.weaver.Member) - */ - public Advice createAdviceMunger(AdviceAttribute attribute, - Pointcut pointcut, Member signature) { - throw new UnsupportedOperationException("Cannot create advice munger in ReflectionWorld"); - } - - /* (non-Javadoc) - * @see org.aspectj.weaver.World#makeCflowStackFieldAdder(org.aspectj.weaver.ResolvedMember) - */ - public ConcreteTypeMunger makeCflowStackFieldAdder(ResolvedMember cflowField) { - throw new UnsupportedOperationException("Cannot create cflow stack in ReflectionWorld"); - } - - /* (non-Javadoc) - * @see org.aspectj.weaver.World#makeCflowCounterFieldAdder(org.aspectj.weaver.ResolvedMember) - */ - public ConcreteTypeMunger makeCflowCounterFieldAdder( - ResolvedMember cflowField) { - throw new UnsupportedOperationException("Cannot create cflow counter in ReflectionWorld"); + } } - /* (non-Javadoc) - * @see org.aspectj.weaver.World#makePerClauseAspect(org.aspectj.weaver.ResolvedType, org.aspectj.weaver.patterns.PerClause.Kind) - */ - public ConcreteTypeMunger makePerClauseAspect(ResolvedType aspect, Kind kind) { - throw new UnsupportedOperationException("Cannot create per clause in ReflectionWorld"); + protected ReferenceTypeDelegate resolveDelegate(ReferenceType ty) { + return ReflectionBasedReferenceTypeDelegateFactory.createDelegate(ty, this, classLoaderReference.getClassLoader()); } - /* (non-Javadoc) - * @see org.aspectj.weaver.World#concreteTypeMunger(org.aspectj.weaver.ResolvedTypeMunger, org.aspectj.weaver.ResolvedType) - */ - public ConcreteTypeMunger concreteTypeMunger(ResolvedTypeMunger munger, - ResolvedType aspectType) { - throw new UnsupportedOperationException("Cannot create type munger in ReflectionWorld"); - } - public static class ReflectionWorldException extends RuntimeException { private static final long serialVersionUID = -3432261918302793005L; @@ -157,7 +109,7 @@ public class ReflectionWorld extends World implements IReflectionWorld { super(message); } } - + private static class ExceptionBasedMessageHandler implements IMessageHandler { public boolean handleMessage(IMessage message) throws AbortException { @@ -179,7 +131,11 @@ public class ReflectionWorld extends World implements IReflectionWorld { public void ignore(org.aspectj.bridge.IMessage.Kind kind) { // empty } - + + } + + public IWeavingSupport getWeavingSupport() { + return null; } }