public Argument extraArgument;
public AdviceKind kind;
-
private int extraArgumentFlags = 0;
public MethodBinding proceedMethodBinding;
+ public boolean proceedInInners;
+ public ResolvedMember[] proceedCallSignatures;
+ public boolean[] formalsUnchangedToProceed;
+ public TypeX[] declaredExceptions;
+
+
public AdviceDeclaration(CompilationResult result, AdviceKind kind) {
super(result);
this.returnType = TypeReference.baseTypeReference(T_void, 0);
}
public AjAttribute makeAttribute() {
- return new AjAttribute.AdviceAttribute(kind, pointcutDesignator.getPointcut(),
- extraArgumentFlags, sourceStart, sourceEnd, null);
+ if (kind == AdviceKind.Around) {
+ return new AjAttribute.AdviceAttribute(kind, pointcutDesignator.getPointcut(),
+ extraArgumentFlags, sourceStart, sourceEnd, null,
+ proceedInInners, proceedCallSignatures, formalsUnchangedToProceed,
+ declaredExceptions);
+ } else {
+ return new AjAttribute.AdviceAttribute(kind, pointcutDesignator.getPointcut(),
+ extraArgumentFlags, sourceStart, sourceEnd, null);
+ }
}
public void resolveStatements(ClassScope upperScope) {
if (kind == AdviceKind.Around && binding != null) {
+ //XXX set these correctly
+ proceedInInners = false;
+ proceedCallSignatures = new ResolvedMember[0];
+ formalsUnchangedToProceed = new boolean[baseArgumentCount];
+ declaredExceptions = new TypeX[0];
+
+
ReferenceBinding[] exceptions =
new ReferenceBinding[] { upperScope.getJavaLangThrowable() };
proceedMethodBinding = new MethodBinding(Modifier.STATIC,
public class EclipseAdvice extends Advice {
- public EclipseAdvice(
- AdviceKind kind,
- Pointcut pointcut,
- Member signature,
- int extraParameterFlags,
- int start, int end, ISourceContext context) {
+ public EclipseAdvice(AjAttribute.AdviceAttribute attribute, Pointcut pointcut, Member signature) {
- super(kind, pointcut, signature, extraParameterFlags, start, end, context);
+ super(attribute, pointcut, signature);
}
setMessageHandler(handler);
}
- public Advice concreteAdvice(AdviceKind kind, Pointcut p, Member m, int extraMods,
- int start, int end, ISourceContext context)
+ public Advice concreteAdvice(
+ AjAttribute.AdviceAttribute attribute,
+ Pointcut pointcut,
+ Member signature)
{
- return new EclipseAdvice(kind, p, m, extraMods, start, end, context);
+ //System.err.println("concrete advice: " + signature + " context " + sourceContext);
+ return new EclipseAdvice(attribute, pointcut, signature);
}
public ConcreteTypeMunger concreteTypeMunger(
public abstract class Advice extends ShadowMunger {
- protected AdviceKind kind;
+ AjAttribute.AdviceAttribute attribute; // the pointcut field is ignored
+
+ protected AdviceKind kind; // alias of attribute.getKind()
protected Member signature;
- protected int extraParameterFlags;
- protected int lexicalPosition;
// not necessarily declaring aspect, this is a semantics change from 1.0
protected ResolvedTypeX concreteAspect; // null until after concretize
}
- public Advice(AdviceKind kind, Pointcut pointcut, Member signature,
- int extraParameterFlags, int start, int end, ISourceContext sourceContext)
+ public Advice(AjAttribute.AdviceAttribute attribute, Pointcut pointcut, Member signature)
{
- super(pointcut, start, end, sourceContext);
- this.kind = kind;
+ super(pointcut, attribute.getStart(), attribute.getEnd(), attribute.getSourceContext());
+ this.attribute = attribute;
+ this.kind = attribute.getKind(); // alias
this.signature = signature;
- this.extraParameterFlags = extraParameterFlags;
- this.lexicalPosition = start; //XXX should go away
}
}
public boolean hasExtraParameter() {
- return (extraParameterFlags & ExtraArgument) != 0;
+ return (getExtraParameterFlags() & ExtraArgument) != 0;
+ }
+
+ protected int getExtraParameterFlags() {
+ return attribute.getExtraParameterFlags();
}
protected int getExtraParameterCount() {
- return countOnes(extraParameterFlags & ParameterMask);
+ return countOnes(getExtraParameterFlags() & ParameterMask);
}
public static int countOnes(int bits) {
}
public int getBaseParameterCount() {
- return signature.getParameterTypes().length - getExtraParameterCount();
+ return getSignature().getParameterTypes().length - getExtraParameterCount();
}
public TypeX getExtraParameterType() {
}
protected String extraParametersToString() {
- if (extraParameterFlags == 0) {
+ if (getExtraParameterFlags() == 0) {
return "";
} else {
- return "(extraFlags: " + extraParameterFlags + ")";
+ return "(extraFlags: " + getExtraParameterFlags() + ")";
}
}
p.state = Pointcut.CONCRETE;
}
- Advice munger = world.concreteAdvice(kind, p, signature, extraParameterFlags, start, end, sourceContext);
+ Advice munger = world.concreteAdvice(attribute, p, signature);
munger.concreteAspect = fromType;
//System.err.println("concretizing here " + p + " with clause " + clause);
return munger;
public boolean equals(Object other) {
if (! (other instanceof Advice)) return false;
Advice o = (Advice) other;
- return o.kind == kind && o.pointcut.equals(pointcut) && o.signature.equals(signature) &&
- o.extraParameterFlags == extraParameterFlags;
+ return o.attribute.equals(attribute)
+ && o.pointcut.equals(pointcut)
+ && o.signature.equals(signature);
}
private volatile int hashCode = 0;
public int hashCode() {
public static final int ParameterMask = 0xf;
public static final int CanInline = 0x40;
-
+
+
+ // for testing only
public void setLexicalPosition(int lexicalPosition) {
- this.lexicalPosition = lexicalPosition;
+ start = lexicalPosition;
}
public ResolvedTypeX getConcreteAspect() {
}
public void write(DataOutputStream s) throws IOException {
s.writeUTF(sourceFileName);
- FileUtil.writeIntArray(s, lineBreaks);
+ FileUtil.writeIntArray(lineBreaks, s);
}
public static SourceContextAttribute read(DataInputStream s) throws IOException {
private AdviceKind kind;
private Pointcut pointcut;
- private int extraArgumentFlags;
+ private int extraParameterFlags;
private int start;
private int end;
private ISourceContext sourceContext;
+ // these are only used by around advice
+ private boolean proceedInInners;
+ private ResolvedMember[] proceedCallSignatures; // size == # of proceed calls in body
+ private boolean[] formalsUnchangedToProceed; // size == formals.size
+ private TypeX[] 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.
*/
- 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;
+ 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");
+ }
+
+ public AdviceAttribute(AdviceKind kind, Pointcut pointcut, int extraArgumentFlags,
+ int start, int end, ISourceContext sourceContext,
+ boolean proceedInInners, ResolvedMember[] proceedCallSignatures,
+ boolean[] formalsUnchangedToProceed, TypeX[] declaredExceptions) {
this.kind = kind;
this.pointcut = pointcut;
- this.extraArgumentFlags = extraArgumentFlags;
+ this.extraParameterFlags = extraArgumentFlags;
this.start = start;
this.end = end;
this.sourceContext = sourceContext;
+
+ 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(DataInputStream s, ISourceContext context) throws IOException {
- return new AdviceAttribute(
- AdviceKind.read(s),
- Pointcut.read(s, context),
- s.readByte(),
- s.readInt(), s.readInt(), context);
+ 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(),
+ ResolvedMember.readResolvedMemberArray(s, context),
+ FileUtil.readBooleanArray(s),
+ TypeX.readArray(s));
+ } else {
+ 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(extraArgumentFlags);
+ s.writeByte(extraParameterFlags);
s.writeInt(start);
s.writeInt(end);
+
+ if (kind == AdviceKind.Around) {
+ s.writeBoolean(proceedInInners);
+ ResolvedMember.writeArray(proceedCallSignatures, s);
+ FileUtil.writeBooleanArray(formalsUnchangedToProceed, s);
+ TypeX.writeArray(declaredExceptions, s);
+ }
}
+
public Advice reify(Member signature, World world) {
- return world.concreteAdvice(kind, pointcut, signature, extraArgumentFlags, start, end, sourceContext);
+ return world.concreteAdvice(this, pointcut, signature);
}
public String toString() {
return "AdviceAttribute(" + kind + ", " + pointcut + ", " +
- extraArgumentFlags + ", " + start+")";
+ extraParameterFlags + ", " + start+")";
}
- public int getExtraArgumentFlags() {
- return extraArgumentFlags;
+ public int getExtraParameterFlags() {
+ return extraParameterFlags;
}
public AdviceKind getKind() {
return pointcut;
}
+ public TypeX[] getDeclaredExceptions() {
+ return declaredExceptions;
+ }
+
+ public boolean[] getFormalsUnchangedToProceed() {
+ return formalsUnchangedToProceed;
+ }
+
+ public ResolvedMember[] getProceedCallSignatures() {
+ return proceedCallSignatures;
+ }
+
+ public boolean isProceedInInners() {
+ return proceedInInners;
+ }
+
+ public int getEnd() {
+ return end;
+ }
+
+ public ISourceContext getSourceContext() {
+ return sourceContext;
+ }
+
+ public int getStart() {
+ return start;
+ }
+
}
public static class Aspect extends AjAttribute {
this.accessedMembers = accessedMembers;
}
public void write(DataOutputStream s) throws IOException {
- s.writeInt(accessedMembers.length);
- for (int i = 0, len = accessedMembers.length; i < len; i++) {
- accessedMembers[i].write(s);
- }
+ ResolvedMember.writeArray(accessedMembers, s);
}
public ResolvedMember[] getAccessedMembers() {
}
public static PrivilegedAttribute read(DataInputStream s, ISourceContext context) throws IOException {
- int len = s.readInt();
- ResolvedMember[] members = new ResolvedMember[len];
- for (int i=0; i < len; i++) {
- members[i] = ResolvedMember.readResolvedMember(s, context);
- }
- return new PrivilegedAttribute(members);
+ return new PrivilegedAttribute(ResolvedMember.readResolvedMemberArray(s, context));
}
}
}
public Member getAdviceSignature() {
- if (enclosingAdvice instanceof Advice) return ((Advice)enclosingAdvice).signature;
+ if (enclosingAdvice instanceof Advice) return ((Advice)enclosingAdvice).getSignature();
else return null;
}
s.writeInt(modifiers);
s.writeUTF(getName());
s.writeUTF(getSignature());
- TypeX.write(getExceptions(), s);
+ TypeX.writeArray(getExceptions(), s);
s.writeInt(getStart());
s.writeInt(getEnd());
}
+
+ public static void writeArray(ResolvedMember[] members, DataOutputStream s) throws IOException {
+ s.writeInt(members.length);
+ for (int i = 0, len = members.length; i < len; i++) {
+ members[i].write(s);
+ }
+ }
+
public static ResolvedMember readResolvedMember(DataInputStream s, ISourceContext sourceContext) throws IOException {
ResolvedMember m = new ResolvedMember(Kind.read(s), TypeX.read(s), s.readInt(), s.readUTF(), s.readUTF());
return m;
}
+ public static ResolvedMember[] readResolvedMemberArray(DataInputStream s, ISourceContext context) throws IOException {
+ int len = s.readInt();
+ ResolvedMember[] members = new ResolvedMember[len];
+ for (int i=0; i < len; i++) {
+ members[i] = ResolvedMember.readResolvedMember(s, context);
+ }
+ return members;
+ }
+
+
+
public ResolvedMember resolve(World world) {
return this;
}
getDeclaringType().write(s);
s.writeInt(getModifiers());
s.writeUTF(getName());
- TypeX.write(getParameterTypes(), s);
+ TypeX.writeArray(getParameterTypes(), s);
pointcut.write(s);
}
}
}
- public static void write(TypeX[] types, DataOutputStream s) throws IOException {
+ public static void writeArray(TypeX[] types, DataOutputStream s) throws IOException {
int len = types.length;
s.writeShort(len);
for (int i=0; i < len; i++) {
public ResolvedTypeX resolveObjectType(TypeX ty) {
return ResolvedTypeX.MISSING;
}
- public Advice concreteAdvice(AdviceKind kind, Pointcut p, Member m, int extraMods,
- int start, int end, ISourceContext context) {
+ public Advice concreteAdvice(AjAttribute.AdviceAttribute attribute, Pointcut p, Member m) {
throw new RuntimeException("unimplemented");
}
public ConcreteTypeMunger concreteTypeMunger(ResolvedTypeMunger munger, ResolvedTypeX aspectType) {
public abstract Advice concreteAdvice(
- AdviceKind kind,
- Pointcut p,
- Member signature,
- int extraParameterFlags,
- int start, int end, ISourceContext context);
+ AjAttribute.AdviceAttribute attribute,
+ Pointcut pointcut,
+ Member signature);
public final Advice concreteAdvice(
AdviceKind kind,
int extraParameterFlags,
IHasSourceLocation loc)
{
- return concreteAdvice(kind, p, signature, extraParameterFlags, loc.getStart(), loc.getEnd(), loc.getSourceContext());
+ AjAttribute.AdviceAttribute attribute =
+ new AjAttribute.AdviceAttribute(kind, p, extraParameterFlags, loc.getStart(), loc.getEnd(), loc.getSourceContext());
+ return concreteAdvice(attribute, p, signature);
}
private Test pointcutTest;
private ExposedState exposedState;
+ public BcelAdvice(
+ AjAttribute.AdviceAttribute attribute,
+ Pointcut pointcut,
+ Member signature,
+ ResolvedTypeX concreteAspect)
+ {
+ super(attribute, pointcut, signature);
+ this.concreteAspect = concreteAspect;
+ }
+
+ // !!! only used for testing
public BcelAdvice(AdviceKind kind, Pointcut pointcut, Member signature,
int extraArgumentFlags,
int start, int end, ISourceContext sourceContext, ResolvedTypeX concreteAspect)
{
- super(kind, pointcut, signature, extraArgumentFlags, start, end, sourceContext);
- this.concreteAspect = concreteAspect;
+ this(new AjAttribute.AdviceAttribute(kind, pointcut, extraArgumentFlags, start, end, sourceContext),
+ pointcut, signature, concreteAspect);
}
// ---- implementations of ShadowMunger's methods
pointcutTest = getPointcut().findResidue(shadow, exposedState);
// make sure thisJoinPoint parameters are initialized
- if ((extraParameterFlags & ThisJoinPointStaticPart) != 0) {
+ if ((getExtraParameterFlags() & ThisJoinPointStaticPart) != 0) {
((BcelShadow)shadow).getThisJoinPointStaticPartVar();
}
- if ((extraParameterFlags & ThisJoinPoint) != 0) {
+ if ((getExtraParameterFlags() & ThisJoinPoint) != 0) {
((BcelShadow)shadow).getThisJoinPointVar();
}
- if ((extraParameterFlags & ThisEnclosingJoinPointStaticPart) != 0) {
+ if ((getExtraParameterFlags() & ThisEnclosingJoinPointStaticPart) != 0) {
((BcelShadow)shadow).getThisEnclosingJoinPointStaticPartVar();
}
}
// handle thisJoinPoint parameters
// these need to be in that same order as parameters in
// org.aspectj.ajdt.internal.compiler.ast.AdviceDeclaration
- if ((extraParameterFlags & ThisJoinPointStaticPart) != 0) {
+ if ((getExtraParameterFlags() & ThisJoinPointStaticPart) != 0) {
shadow.getThisJoinPointStaticPartBcelVar().appendLoad(il, fact);
}
- if ((extraParameterFlags & ThisJoinPoint) != 0) {
+ if ((getExtraParameterFlags() & ThisJoinPoint) != 0) {
shadow.getThisJoinPointBcelVar().appendLoad(il, fact);
}
- if ((extraParameterFlags & ThisEnclosingJoinPointStaticPart) != 0) {
+ if ((getExtraParameterFlags() & ThisEnclosingJoinPointStaticPart) != 0) {
shadow.getThisEnclosingJoinPointStaticPartBcelVar().appendLoad(il, fact);
}
if (declaringAspect == o_declaringAspect) {
if (kind.isAfter() || o.kind.isAfter()) {
- return this.lexicalPosition < o.lexicalPosition ? -1: +1;
+ return this.getStart() < o.getStart() ? -1: +1;
} else {
- return this.lexicalPosition < o.lexicalPosition ? +1: -1;
+ return this.getStart()< o.getStart() ? +1: -1;
}
} else if (declaringAspect.isAssignableFrom(o_declaringAspect)) {
return -1;
Pointcut p =
pointcut.resolve(new SimpleScope(this, bindings));
- return concreteAdvice(kind, p, m, extraFlag, 0, 0, null);
+ return new BcelAdvice(kind, p, m, extraFlag, 0, 0, null, null);
}
private String[] parseIds(String str) {
}
public Advice concreteAdvice(
- AdviceKind kind,
- Pointcut p,
- Member signature,
- int extraParameterFlags,
- int start, int end, ISourceContext sourceContext)
+ AjAttribute.AdviceAttribute attribute,
+ Pointcut pointcut,
+ Member signature)
{
//System.err.println("concrete advice: " + signature + " context " + sourceContext);
- return new BcelAdvice(kind, p, signature, extraParameterFlags, start, end, sourceContext, null);
+ return new BcelAdvice(attribute, pointcut, signature, null);
}
public ConcreteTypeMunger concreteTypeMunger(
s.writeByte(Pointcut.CFLOW);
entry.write(s);
s.writeBoolean(isBelow);
- FileUtil.writeIntArray(s, freeVars);
+ FileUtil.writeIntArray(freeVars, s);
writeLocation(s);
}
public static Pointcut read(DataInputStream s, ISourceContext context) throws IOException {
s.writeInt(dim);
//??? storing this information with every type pattern is wasteful of .class
// file size. Storing it on enclosing types would be more efficient
- FileUtil.writeStringArray(s, knownMatches);
- FileUtil.writeStringArray(s, importedPrefixes);
+ FileUtil.writeStringArray(knownMatches, s);
+ FileUtil.writeStringArray(importedPrefixes, s);
writeLocation(s);
}
public FuzzyBoolean match(Shadow shadow) {
TypeX enclosingType = shadow.getEnclosingType();
+// if (shadow.getKind() == Shadow.FieldSet) {
+// System.err.println("within?" + type + " matches " + enclosingType + " on " + shadow);
+// }
+
while (enclosingType != null) {
if (type.matchesStatically(shadow.getIWorld().resolve(enclosingType))) {
return FuzzyBoolean.YES;
));
ShadowMunger pp =
- world.concreteAdvice(
+ new BcelAdvice(
AdviceKind.Before,
rp,
Member.method(
Member.typesToSignature(
ResolvedTypeX.VOID,
TypeX.forNames(formalTypes))),
- 0, -1, -1, null);
+ 0, -1, -1, null, null);
ResolvedTypeX inAspect = world.resolve("Aspect");
CrosscuttingMembers xcut = new CrosscuttingMembers(inAspect);