aboutsummaryrefslogtreecommitdiffstats
path: root/weaver
diff options
context:
space:
mode:
authoraclement <aclement>2005-01-18 11:39:16 +0000
committeraclement <aclement>2005-01-18 11:39:16 +0000
commitfe310a4e10cf69486f54d5cf4edd4893b0a0835c (patch)
treee5b015ba92184dce33b61a686b9d7dd420403570 /weaver
parent0e14ef28ab34628b3399cccb0118362fc22114a7 (diff)
downloadaspectj-fe310a4e10cf69486f54d5cf4edd4893b0a0835c.tar.gz
aspectj-fe310a4e10cf69486f54d5cf4edd4893b0a0835c.zip
PerTypeWithin support.
Diffstat (limited to 'weaver')
-rw-r--r--weaver/src/org/aspectj/weaver/Advice.java7
-rw-r--r--weaver/src/org/aspectj/weaver/AdviceKind.java11
-rw-r--r--weaver/src/org/aspectj/weaver/AjcMemberMaker.java84
-rw-r--r--weaver/src/org/aspectj/weaver/NameMangler.java18
-rw-r--r--weaver/src/org/aspectj/weaver/PerTypeWithinTargetTypeMunger.java52
-rw-r--r--weaver/src/org/aspectj/weaver/ResolvedTypeMunger.java1
-rw-r--r--weaver/src/org/aspectj/weaver/TypeX.java3
-rw-r--r--weaver/src/org/aspectj/weaver/bcel/BcelAdvice.java3
-rw-r--r--weaver/src/org/aspectj/weaver/bcel/BcelShadow.java27
-rw-r--r--weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java40
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/PatternParser.java10
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/PerClause.java4
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/PerTypeWithin.java175
13 files changed, 430 insertions, 5 deletions
diff --git a/weaver/src/org/aspectj/weaver/Advice.java b/weaver/src/org/aspectj/weaver/Advice.java
index 11b8f69c7..a6cd8f412 100644
--- a/weaver/src/org/aspectj/weaver/Advice.java
+++ b/weaver/src/org/aspectj/weaver/Advice.java
@@ -67,6 +67,13 @@ public abstract class Advice extends ShadowMunger {
return ret;
}
+ // PTWIMPL per type within entry advice is what initializes the aspect instance in the matched type
+ public static Advice makePerTypeWithinEntry(World world, Pointcut p, ResolvedTypeX inAspect) {
+ Advice ret = world.concreteAdvice(AdviceKind.PerTypeWithinEntry,p,null,0,p);
+ ret.concreteAspect = inAspect;
+ return ret;
+ }
+
public static Advice makeSoftener(World world, Pointcut entry, TypePattern exceptionType,ResolvedTypeX inAspect,IHasSourceLocation loc) {
Advice ret = world.concreteAdvice(AdviceKind.Softener, entry, null, 0, loc);
diff --git a/weaver/src/org/aspectj/weaver/AdviceKind.java b/weaver/src/org/aspectj/weaver/AdviceKind.java
index abc560386..57851fd64 100644
--- a/weaver/src/org/aspectj/weaver/AdviceKind.java
+++ b/weaver/src/org/aspectj/weaver/AdviceKind.java
@@ -53,6 +53,8 @@ public class AdviceKind extends TypeSafeEnum {
case 12: return PerTargetEntry;
case 13: return Softener;
+
+ case 14: return PerTypeWithinEntry;
}
throw new RuntimeException("unimplemented kind: " + key);
}
@@ -75,6 +77,9 @@ public class AdviceKind extends TypeSafeEnum {
public static final AdviceKind PerTargetEntry = new AdviceKind("perTargetEntry", 12, 1, false, false);
public static final AdviceKind Softener = new AdviceKind("softener", 13, 1, false, false);
+
+ // PTWIMPL Advice representing when aspect should be initialized
+ public static final AdviceKind PerTypeWithinEntry = new AdviceKind("perTypeWithinEntry",14,1,false,false);
public static AdviceKind stringToKind(String s) {
@@ -99,8 +104,10 @@ public class AdviceKind extends TypeSafeEnum {
}
public boolean isPerEntry() {
- return this == PerCflowEntry || this == PerCflowBelowEntry ||
- this == PerThisEntry || this == PerTargetEntry;
+ return
+ this == PerCflowEntry || this == PerCflowBelowEntry ||
+ this == PerThisEntry || this == PerTargetEntry ||
+ this == PerTypeWithinEntry; // PTWIMPL Allow for PTW case
}
public boolean isPerObjectEntry() {
diff --git a/weaver/src/org/aspectj/weaver/AjcMemberMaker.java b/weaver/src/org/aspectj/weaver/AjcMemberMaker.java
index f19776f05..d285a1574 100644
--- a/weaver/src/org/aspectj/weaver/AjcMemberMaker.java
+++ b/weaver/src/org/aspectj/weaver/AjcMemberMaker.java
@@ -68,6 +68,15 @@ public class AjcMemberMaker {
"<init>",
"()V");
}
+
+ public static Member noAspectBoundExceptionInit2() {
+ return new ResolvedMember(
+ Member.METHOD,
+ NO_ASPECT_BOUND_EXCEPTION,
+ Modifier.PUBLIC,
+ "<init>",
+ "(Ljava/lang/String;Ljava/lang/Throwable;)V");
+ }
public static Member noAspectBoundExceptionInitWithCause() {
return new ResolvedMember(
@@ -129,6 +138,27 @@ public class AjcMemberMaker {
NameMangler.perObjectInterfaceField(aspectType),
TypeX.NONE);
}
+
+ // PTWIMPL ResolvedMember for aspect instance field, declared in matched type
+ public static ResolvedMember perTypeWithinField(TypeX declaringType, ResolvedTypeX aspectType) {
+ int modifiers = Modifier.PRIVATE | Modifier.STATIC;
+ if (!TypeX.SERIALIZABLE.isAssignableFrom(aspectType, aspectType.getWorld())) {
+ modifiers |= Modifier.TRANSIENT;
+ }
+ return new ResolvedMember(Member.FIELD, declaringType, modifiers,
+ aspectType, NameMangler.perTypeWithinFieldForTarget(aspectType), TypeX.NONE);
+ }
+
+ // PTWIMPL ResolvedMember for type instance field, declared in aspect
+ // (holds typename for which aspect instance exists)
+ public static ResolvedMember perTypeWithinWithinTypeField(TypeX declaringType, ResolvedTypeX aspectType) {
+ int modifiers = Modifier.PRIVATE;
+ if (!TypeX.SERIALIZABLE.isAssignableFrom(aspectType, aspectType.getWorld())) {
+ modifiers |= Modifier.TRANSIENT;
+ }
+ return new ResolvedMember(Member.FIELD, declaringType, modifiers,
+ TypeX.forSignature("Ljava/lang/String;"), NameMangler.PERTYPEWITHIN_WITHINTYPEFIELD, TypeX.NONE);
+ }
public static ResolvedMember perObjectBind(TypeX declaringType) {
@@ -139,6 +169,34 @@ public class AjcMemberMaker {
NameMangler.PEROBJECT_BIND_METHOD,
"(Ljava/lang/Object;)V");
}
+
+ // PTWIMPL ResolvedMember for getInstance() method, declared in aspect
+ public static ResolvedMember perTypeWithinGetInstance(TypeX declaringType) {
+// private static a.X ajc$getInstance(java.lang.Class) throws java/lang/Exception
+ ResolvedMember rm = new ResolvedMember(
+ Member.METHOD,
+ declaringType,
+ PRIVATE_STATIC,
+ declaringType, // return value
+ NameMangler.PERTYPEWITHIN_GETINSTANCE_METHOD,
+ new TypeX[]{TypeX.JAVA_LANG_CLASS},
+ new TypeX[]{TypeX.JAVA_LANG_EXCEPTION}
+ );
+ return rm;
+ }
+
+ public static ResolvedMember perTypeWithinCreateAspectInstance(TypeX declaringType) {
+ // public static a.X ajc$createAspectInstance(java.lang.String)
+ ResolvedMember rm = new ResolvedMember(
+ Member.METHOD,
+ declaringType,
+ PUBLIC_STATIC,
+ declaringType, // return value
+ NameMangler.PERTYPEWITHIN_CREATEASPECTINSTANCE_METHOD,
+ new TypeX[]{TypeX.forSignature("Ljava/lang/String;")},new TypeX[]{}
+ );
+ return rm;
+ }
public static TypeX perObjectInterfaceType(TypeX aspectType) {
@@ -163,8 +221,16 @@ public class AjcMemberMaker {
"(" + aspectType.getSignature() + ")V");
}
-
-
+ // PTWIMPL ResolvedMember for localAspectOf() method, declared in matched type
+ public static ResolvedMember perTypeWithinLocalAspectOf(TypeX shadowType,TypeX aspectType) {
+ return new ResolvedMember(
+ Member.METHOD,
+ shadowType,//perTypeWithinInterfaceType(aspectType),
+ Modifier.PUBLIC | Modifier.STATIC,
+ NameMangler.perTypeWithinLocalAspectOf(aspectType),
+ "()" + aspectType.getSignature());
+ }
+
public static ResolvedMember perSingletonAspectOfMethod(TypeX declaringType) {
return new ResolvedMember(Member.METHOD,
@@ -198,6 +264,20 @@ public class AjcMemberMaker {
"(Ljava/lang/Object;)Z");
};
+ // PTWIMPL ResolvedMember for aspectOf(), declared in aspect
+ public static ResolvedMember perTypeWithinAspectOfMethod(TypeX declaringType) {
+ return new ResolvedMember(Member.METHOD,
+ declaringType, PUBLIC_STATIC, "aspectOf",
+ "(Ljava/lang/Class;)" + declaringType.getSignature());
+ }
+
+ // PTWIMPL ResolvedMember for hasAspect(), declared in aspect
+ public static ResolvedMember perTypeWithinHasAspectMethod(TypeX declaringType) {
+ return new ResolvedMember(Member.METHOD,
+ declaringType, PUBLIC_STATIC, "hasAspect",
+ "(Ljava/lang/Class;)Z");
+ };
+
// -- privileged accessors
public static ResolvedMember privilegedAccessMethodForMethod(TypeX aspectType, ResolvedMember method) {
diff --git a/weaver/src/org/aspectj/weaver/NameMangler.java b/weaver/src/org/aspectj/weaver/NameMangler.java
index 6d49a45fb..1888faef8 100644
--- a/weaver/src/org/aspectj/weaver/NameMangler.java
+++ b/weaver/src/org/aspectj/weaver/NameMangler.java
@@ -37,7 +37,12 @@ public class NameMangler {
public static final String PERCFLOW_PUSH_METHOD = PREFIX + "perCflowPush";
public static final String PEROBJECT_BIND_METHOD = PREFIX + "perObjectBind";
-
+
+ // PTWIMPL Method and field names
+ public static final String PERTYPEWITHIN_GETINSTANCE_METHOD = PREFIX + "getInstance";
+ public static final String PERTYPEWITHIN_CREATEASPECTINSTANCE_METHOD = PREFIX + "createAspectInstance";
+ public static final String PERTYPEWITHIN_WITHINTYPEFIELD = PREFIX + "withinType";
+
public static final String AJC_PRE_CLINIT_NAME = PREFIX + "preClinit";
public static final String AJC_POST_CLINIT_NAME = PREFIX + "postClinit";
@@ -57,6 +62,17 @@ public class NameMangler {
}
+ // PTWIMPL method names that must include aspect type
+ public static String perTypeWithinFieldForTarget(TypeX aspectType) {
+ String s = makeName(aspectType.getNameAsIdentifier(), "ptwAspectInstance");
+ return s;
+ }
+
+ public static String perTypeWithinLocalAspectOf(TypeX aspectType) {
+ return makeName(aspectType.getNameAsIdentifier(), "localAspectOf");
+ }
+
+
public static String privilegedAccessMethodForMethod(String name, TypeX objectType, TypeX aspectType) {
return makeName("privMethod", aspectType.getNameAsIdentifier(),
diff --git a/weaver/src/org/aspectj/weaver/PerTypeWithinTargetTypeMunger.java b/weaver/src/org/aspectj/weaver/PerTypeWithinTargetTypeMunger.java
new file mode 100644
index 000000000..4da7f1116
--- /dev/null
+++ b/weaver/src/org/aspectj/weaver/PerTypeWithinTargetTypeMunger.java
@@ -0,0 +1,52 @@
+/* *******************************************************************
+ * Copyright (c) 2005
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Andy Clement initial implementation
+ * ******************************************************************/
+
+package org.aspectj.weaver;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.weaver.patterns.PerTypeWithin;
+import org.aspectj.weaver.patterns.Pointcut;
+import org.aspectj.weaver.patterns.TypePattern;
+
+// PTWIMPL Target type munger adds the localAspectOf() method
+public class PerTypeWithinTargetTypeMunger extends ResolvedTypeMunger {
+ private ResolvedMember localAspectOfMethod;
+ private TypeX aspectType;
+ private PerTypeWithin testPointcut;
+
+
+ public PerTypeWithinTargetTypeMunger(TypeX aspectType, PerTypeWithin testPointcut) {
+ super(PerTypeWithinInterface, null);
+ this.aspectType = aspectType;
+ this.testPointcut = testPointcut;
+ }
+
+
+ public void write(DataOutputStream s) throws IOException {
+ throw new RuntimeException("shouldn't be serialized");
+ }
+
+ public TypeX getAspectType() {
+ return aspectType;
+ }
+
+ public Pointcut getTestPointcut() {
+ return testPointcut;
+ }
+
+ public boolean matches(ResolvedTypeX matchType, ResolvedTypeX aspectType) {
+ return testPointcut.getTypePattern().matches(matchType,TypePattern.STATIC).alwaysTrue();
+ }
+
+}
diff --git a/weaver/src/org/aspectj/weaver/ResolvedTypeMunger.java b/weaver/src/org/aspectj/weaver/ResolvedTypeMunger.java
index f28e87535..17c87c9d3 100644
--- a/weaver/src/org/aspectj/weaver/ResolvedTypeMunger.java
+++ b/weaver/src/org/aspectj/weaver/ResolvedTypeMunger.java
@@ -224,6 +224,7 @@ public abstract class ResolvedTypeMunger {
public static final Kind PrivilegedAccess = new Kind("PrivilegedAccess", 4);
public static final Kind Parent = new Kind("Parent", 6);
+ public static final Kind PerTypeWithinInterface = new Kind("PerTypeWithinInterface",7); // PTWIMPL not serialized, used during concretization of aspects
public static final String SUPER_DISPATCH_NAME = "superDispatch";
diff --git a/weaver/src/org/aspectj/weaver/TypeX.java b/weaver/src/org/aspectj/weaver/TypeX.java
index c13349eb3..3dad1b8fa 100644
--- a/weaver/src/org/aspectj/weaver/TypeX.java
+++ b/weaver/src/org/aspectj/weaver/TypeX.java
@@ -584,6 +584,9 @@ public class TypeX implements AnnotatedElement {
public static final TypeX AT_RETENTION = forSignature("Ljava/lang/annotation/Retention;");
public static final TypeX ENUM = forSignature("Ljava/lang/Enum;");
public static final TypeX ANNOTATION = forSignature("Ljava/lang/annotation/Annotation;");
+ public static final TypeX JAVA_LANG_CLASS = forSignature("Ljava/lang/Class;");
+ public static final TypeX JAVA_LANG_EXCEPTION = forSignature("Ljava/lang/Exception;");
+ public static final TypeX JAVA_LANG_REFLECT_METHOD = forSignature("Ljava/lang/reflect/Method;");
// ---- helpers
diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelAdvice.java b/weaver/src/org/aspectj/weaver/bcel/BcelAdvice.java
index 76589720f..344602d97 100644
--- a/weaver/src/org/aspectj/weaver/bcel/BcelAdvice.java
+++ b/weaver/src/org/aspectj/weaver/bcel/BcelAdvice.java
@@ -160,6 +160,9 @@ public class BcelAdvice extends Advice {
shadow.weavePerObjectEntry(this, (BcelVar)shadow.getTargetVar());
} else if (getKind() == AdviceKind.Softener) {
shadow.weaveSoftener(this, ((ExactTypePattern)exceptionType).getType());
+ } else if (getKind() == AdviceKind.PerTypeWithinEntry) {
+ // PTWIMPL Entry to ptw is the static initialization of a type that matched the ptw type pattern
+ shadow.weavePerTypeWithinAspectInitialization(this,shadow.getEnclosingType());
} else {
throw new BCException("unimplemented kind: " + getKind());
}
diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelShadow.java b/weaver/src/org/aspectj/weaver/bcel/BcelShadow.java
index fe32b0aa6..aa03a51ab 100644
--- a/weaver/src/org/aspectj/weaver/bcel/BcelShadow.java
+++ b/weaver/src/org/aspectj/weaver/bcel/BcelShadow.java
@@ -43,6 +43,7 @@ import org.aspectj.apache.bcel.generic.LoadInstruction;
import org.aspectj.apache.bcel.generic.MULTIANEWARRAY;
import org.aspectj.apache.bcel.generic.NEW;
import org.aspectj.apache.bcel.generic.ObjectType;
+import org.aspectj.apache.bcel.generic.PUSH;
import org.aspectj.apache.bcel.generic.ReturnInstruction;
import org.aspectj.apache.bcel.generic.SWAP;
import org.aspectj.apache.bcel.generic.StoreInstruction;
@@ -1510,6 +1511,32 @@ public class BcelShadow extends Shadow {
range.insert(entryInstructions, Range.InsideBefore);
}
+
+ // PTWIMPL Create static initializer to call the aspect factory
+ /**
+ * Causes the aspect instance to be *set* for later retrievable through localAspectof()/aspectOf()
+ */
+ public void weavePerTypeWithinAspectInitialization(final BcelAdvice munger,TypeX t) {
+ final InstructionFactory fact = getFactory();
+
+ InstructionList entryInstructions = new InstructionList();
+ InstructionList entrySuccessInstructions = new InstructionList();
+
+ BcelObjectType aspectType = BcelWorld.getBcelObjectType(munger.getConcreteAspect());
+ String aspectname = munger.getConcreteAspect().getName();
+
+ String ptwField = NameMangler.perTypeWithinFieldForTarget(munger.getConcreteAspect());
+ entrySuccessInstructions.append(new PUSH(fact.getConstantPool(),t.getName()));
+
+ entrySuccessInstructions.append(fact.createInvoke(aspectname,"ajc$createAspectInstance",new ObjectType(aspectname),
+ new Type[]{new ObjectType("java.lang.String")},Constants.INVOKESTATIC));
+ entrySuccessInstructions.append(fact.createPutStatic(t.getName(),ptwField,
+ new ObjectType(aspectname)));
+
+ entryInstructions.append(entrySuccessInstructions);
+
+ range.insert(entryInstructions, Range.InsideBefore);
+ }
public void weaveCflowEntry(final BcelAdvice munger, final Member cflowField) {
diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java b/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java
index 935d2f966..d8e755a8c 100644
--- a/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java
+++ b/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java
@@ -42,6 +42,7 @@ import org.aspectj.weaver.NewFieldTypeMunger;
import org.aspectj.weaver.NewMethodTypeMunger;
import org.aspectj.weaver.NewParentTypeMunger;
import org.aspectj.weaver.PerObjectInterfaceTypeMunger;
+//import org.aspectj.weaver.PerTypeWithinTargetTypeMunger;
import org.aspectj.weaver.PrivilegedAccessMunger;
import org.aspectj.weaver.ResolvedMember;
import org.aspectj.weaver.ResolvedTypeMunger;
@@ -74,6 +75,10 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
} else if (munger.getKind() == ResolvedTypeMunger.PerObjectInterface) {
changed = mungePerObjectInterface(weaver, (PerObjectInterfaceTypeMunger)munger);
worthReporting = false;
+ } else if (munger.getKind() == ResolvedTypeMunger.PerTypeWithinInterface) {
+ // PTWIMPL Transform the target type (add the aspect instance field)
+ changed = mungePerTypeWithinTransformer(weaver);
+ worthReporting = false;
} else if (munger.getKind() == ResolvedTypeMunger.PrivilegedAccess) {
changed = mungePrivilegedAccess(weaver, (PrivilegedAccessMunger)munger);
worthReporting = false;
@@ -646,7 +651,42 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
return false;
}
}
+
+ // PTWIMPL Add field to hold aspect instance and an accessor
+ private boolean mungePerTypeWithinTransformer(BcelClassWeaver weaver) {
+ LazyClassGen gen = weaver.getLazyClassGen();
+
+ // if (couldMatch(gen.getBcelObjectType(), munger.getTestPointcut())) {
+
+ // Add (to the target type) the field that will hold the aspect instance
+ // e.g ajc$com_blah_SecurityAspect$ptwAspectInstance
+ FieldGen fg = makeFieldGen(gen, AjcMemberMaker.perTypeWithinField(gen.getType(), aspectType));
+ gen.addField(fg.getField(),getSourceLocation());
+
+ // Add an accessor for this new field, the ajc$<aspectname>$localAspectOf() method
+ // e.g. "public com_blah_SecurityAspect ajc$com_blah_SecurityAspect$localAspectOf()"
+ Type fieldType = BcelWorld.makeBcelType(aspectType);
+ LazyMethodGen mg = new LazyMethodGen(
+ Modifier.PUBLIC | Modifier.STATIC,fieldType,
+ NameMangler.perTypeWithinLocalAspectOf(aspectType),
+ new Type[0], new String[0],gen);
+ InstructionList il = new InstructionList();
+ //PTWIMPL ?? Should check if it is null and throw NoAspectBoundException
+ InstructionFactory fact = gen.getFactory();
+ il.append(fact.createFieldAccess(
+ gen.getClassName(),
+ fg.getName(),
+ fieldType, Constants.GETSTATIC));
+ il.append(InstructionFactory.createReturn(fieldType));
+ mg.getBody().insert(il);
+ gen.addMethodGen(mg);
+ return true;
+// } else {
+// return false;
+// }
+ }
+ // ??? Why do we have this method? I thought by now we would know if it matched or not
private boolean couldMatch(
BcelObjectType bcelObjectType,
Pointcut pointcut) {
diff --git a/weaver/src/org/aspectj/weaver/patterns/PatternParser.java b/weaver/src/org/aspectj/weaver/patterns/PatternParser.java
index 9b994deb8..575bcc7e1 100644
--- a/weaver/src/org/aspectj/weaver/patterns/PatternParser.java
+++ b/weaver/src/org/aspectj/weaver/patterns/PatternParser.java
@@ -51,6 +51,8 @@ public class PatternParser {
return parsePerCflow(false);
} else if (name.equals("percflowbelow")) {
return parsePerCflow(true);
+ } else if (name.equals("pertypewithin")) { // PTWIMPL Parse the pertypewithin clause
+ return parsePerTypeWithin();
} else {
return null;
}
@@ -74,6 +76,14 @@ public class PatternParser {
eat(")");
return new PerObject(entry, isThis);
}
+
+ private PerClause parsePerTypeWithin() {
+ parseIdentifier();
+ eat("(");
+ TypePattern withinTypePattern = parseTypePattern();
+ eat(")");
+ return new PerTypeWithin(withinTypePattern);
+ }
private PerClause parsePerSingleton() {
diff --git a/weaver/src/org/aspectj/weaver/patterns/PerClause.java b/weaver/src/org/aspectj/weaver/patterns/PerClause.java
index 5bff424eb..8b59094d1 100644
--- a/weaver/src/org/aspectj/weaver/patterns/PerClause.java
+++ b/weaver/src/org/aspectj/weaver/patterns/PerClause.java
@@ -18,6 +18,7 @@ import java.io.IOException;
import org.aspectj.util.TypeSafeEnum;
import org.aspectj.weaver.*;
+// PTWIMPL New kind added to this class, can be (de)serialized
public abstract class PerClause extends Pointcut {
protected ResolvedTypeX inAspect;
@@ -27,6 +28,7 @@ public abstract class PerClause extends Pointcut {
else if (kind == PERCFLOW) return PerCflow.readPerClause(s, context);
else if (kind == PEROBJECT) return PerObject.readPerClause(s, context);
else if (kind == FROMSUPER) return PerFromSuper.readPerClause(s, context);
+ else if (kind == PERTYPEWITHIN) return PerTypeWithin.readPerClause(s,context);
throw new BCException("unknown kind: " + kind);
}
@@ -49,6 +51,7 @@ public abstract class PerClause extends Pointcut {
case 2: return PERCFLOW;
case 3: return PEROBJECT;
case 4: return FROMSUPER;
+ case 5: return PERTYPEWITHIN;
}
throw new BCException("weird kind " + key);
}
@@ -62,4 +65,5 @@ public abstract class PerClause extends Pointcut {
public static final Kind PERCFLOW = new Kind("percflow", 2);
public static final Kind PEROBJECT = new Kind("perobject", 3);
public static final Kind FROMSUPER = new Kind("fromsuper", 4);
+ public static final Kind PERTYPEWITHIN = new Kind("pertypewithin",5);
}
diff --git a/weaver/src/org/aspectj/weaver/patterns/PerTypeWithin.java b/weaver/src/org/aspectj/weaver/patterns/PerTypeWithin.java
new file mode 100644
index 000000000..4e29e138b
--- /dev/null
+++ b/weaver/src/org/aspectj/weaver/patterns/PerTypeWithin.java
@@ -0,0 +1,175 @@
+/* *******************************************************************
+ * Copyright (c) 2005 IBM
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Andy Clement initial implementation
+ * ******************************************************************/
+
+package org.aspectj.weaver.patterns;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.aspectj.bridge.IMessage;
+import org.aspectj.bridge.ISourceLocation;
+import org.aspectj.bridge.Message;
+import org.aspectj.util.FuzzyBoolean;
+import org.aspectj.weaver.Advice;
+import org.aspectj.weaver.AjcMemberMaker;
+import org.aspectj.weaver.ISourceContext;
+import org.aspectj.weaver.Member;
+//import org.aspectj.weaver.PerTypeWithinTargetTypeMunger;
+import org.aspectj.weaver.PerTypeWithinTargetTypeMunger;
+import org.aspectj.weaver.ResolvedTypeMunger;
+import org.aspectj.weaver.ResolvedTypeX;
+import org.aspectj.weaver.Shadow;
+import org.aspectj.weaver.VersionedDataInputStream;
+import org.aspectj.weaver.World;
+import org.aspectj.weaver.ast.Expr;
+import org.aspectj.weaver.ast.Literal;
+import org.aspectj.weaver.ast.Test;
+
+
+// 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 Set kindSet = new HashSet(Shadow.ALL_SHADOW_KINDS);
+
+ public TypePattern getTypePattern() {
+ return typePattern;
+ }
+
+ public PerTypeWithin(TypePattern p) {
+ this.typePattern = p;
+ }
+
+ public Set couldMatchKinds() {
+ return kindSet;
+ }
+
+ // -----
+ public FuzzyBoolean fastMatch(FastMatchInfo info) {
+ if (typePattern.annotationPattern instanceof AnyAnnotationTypePattern) {
+ return isWithinType(info.getType());
+ }
+ return FuzzyBoolean.MAYBE;
+ }
+
+
+ protected FuzzyBoolean matchInternal(Shadow shadow) {
+ ResolvedTypeX enclosingType = shadow.getIWorld().resolve(shadow.getEnclosingType(),true);
+ if (enclosingType == ResolvedTypeX.MISSING) {
+ //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);
+ }
+ 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(ResolvedTypeX inAspect) {
+ PerTypeWithin ret = new PerTypeWithin(typePattern);
+ ret.copyLocationFrom(this);
+ ret.inAspect = inAspect;
+ if (inAspect.isAbstract()) return ret;
+
+
+ World world = inAspect.getWorld();
+
+ SignaturePattern sigpat = new SignaturePattern(
+ Member.STATIC_INITIALIZATION,
+ ModifiersPattern.ANY,
+ TypePattern.ANY,
+ typePattern,
+ NamePattern.ANY,
+ TypePatternList.ANY,
+ ThrowsPattern.ANY,
+ AnnotationTypePattern.ANY
+ );
+ Pointcut testPc = new KindedPointcut(Shadow.StaticInitialization,sigpat);
+ Pointcut testPc2= new WithinPointcut(typePattern);
+ // This munger will initialize the aspect instance field in the matched type
+ inAspect.crosscuttingMembers.addConcreteShadowMunger(Advice.makePerTypeWithinEntry(world, testPc, inAspect));
+
+ ResolvedTypeMunger munger = new PerTypeWithinTargetTypeMunger(inAspect, ret);
+ inAspect.crosscuttingMembers.addTypeMunger(world.concreteTypeMunger(munger, inAspect));
+ return ret;
+
+ }
+
+ 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+")";
+ }
+
+ private FuzzyBoolean isWithinType(ResolvedTypeX type) {
+ while (type != null) {
+ if (typePattern.matchesStatically(type)) {
+ return FuzzyBoolean.YES;
+ }
+ type = type.getDeclaringType();
+ }
+ return FuzzyBoolean.NO;
+ }
+}