Browse Source

test and fix for 123423: getWithinTypeName() for ptw aspects

tags/REMOVING_ASM
aclement 17 years ago
parent
commit
db68044fe8

+ 15
- 0
docs/adk15ProgGuideDB/pertypewithin.xml View File

@@ -43,6 +43,21 @@
aspect.
</para>
<para>
In addition, <literal>pertypewithin</literal> aspects have a
<literal>getWithinTypeName</literal> method that can be called
to return the package qualified name of the type for which the
aspect instance has been created.
</para>
<programlisting><![CDATA[
/**
* return the package qualified name (eg. com.foo.MyClass) of the type
* for which the aspect instance has been instantiated.
*/
public String getWithinTypeName()
]]></programlisting>
<para>
In common with the other per-clause instantiation models, the execution
of any advice declared within a <literal>pertypewithin</literal> aspect

+ 24
- 5
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AspectDeclaration.java View File

@@ -75,7 +75,7 @@ public class AspectDeclaration extends TypeDeclaration {
private AjAttribute.Aspect aspectAttribute;
public PerClause perClause;
public ResolvedMember aspectOfMethod;
//public ResolvedMember ptwGetWithinTypeMethod;
public ResolvedMember ptwGetWithinTypeNameMethod;
public ResolvedMember hasAspectMethod;


@@ -368,8 +368,7 @@ public class AspectDeclaration extends TypeDeclaration {
generatePerTypeWithinGetInstanceMethod(classFile); // private static <aspecttype> ajc$getInstance(Class c) throws Exception
generatePerTypeWithinHasAspectMethod(classFile);
generatePerTypeWithinCreateAspectInstanceMethod(classFile); // generate public static X ajc$createAspectInstance(Class forClass) {
// PTWIMPL getWithinType() would need this...
//generatePerTypeWithinGetWithinTypeMethod(classFile); // generate public Class getWithinType() {
generatePerTypeWithinGetWithinTypeNameMethod(classFile);
} else {
throw new RuntimeException("unimplemented");
}
@@ -728,6 +727,26 @@ public class AspectDeclaration extends TypeDeclaration {
}});
}
private void generatePerTypeWithinGetWithinTypeNameMethod(ClassFile classFile) {
final EclipseFactory world = EclipseFactory.fromScopeLookupEnvironment(this.scope);
// Code:
/*
Code:
Stack=1, Locals=1, Args_size=1
0: aload_0
1: getfield #14; //Field ajc$withinType:Ljava/lang/String;
4: areturn
*/
generateMethod(classFile, AjcMemberMaker.perTypeWithinGetWithinTypeNameMethod(world.fromBinding(binding),world.getWorld().isInJava5Mode()),
new BodyGenerator() {
public void generate(CodeStream codeStream) {
ExceptionLabel exc = new ExceptionLabel(codeStream,world.makeTypeBinding(UnresolvedType.JAVA_LANG_EXCEPTION));
exc.placeStart();
codeStream.aload_0();
codeStream.getfield(world.makeFieldBinding(AjcMemberMaker.perTypeWithinWithinTypeField(typeX,typeX)));
codeStream.areturn();
}});
}
// PTWIMPL Generate getInstance method
private void generatePerTypeWithinGetInstanceMethod(ClassFile classFile) {
final EclipseFactory world = EclipseFactory.fromScopeLookupEnvironment(this.scope);
@@ -1044,8 +1063,8 @@ public class AspectDeclaration extends TypeDeclaration {
// PTWIMPL Use these variants of aspectOf()/hasAspect()
aspectOfMethod = AjcMemberMaker.perTypeWithinAspectOfMethod(typeX,world.getWorld().isInJava5Mode());
hasAspectMethod = AjcMemberMaker.perTypeWithinHasAspectMethod(typeX,world.getWorld().isInJava5Mode());
//ptwGetWithinTypeMethod = AjcMemberMaker.perTypeWithinGetWithinTypeMethod(typeX,world.getWorld().isInJava5Mode());
//binding.addMethod(world.makeMethodBinding(ptwGetWithinTypeMethod));
ptwGetWithinTypeNameMethod = AjcMemberMaker.perTypeWithinGetWithinTypeNameMethod(typeX,world.getWorld().isInJava5Mode());
binding.addMethod(world.makeMethodBinding(ptwGetWithinTypeNameMethod));
} else {
throw new RuntimeException("bad per clause: " + perClause);
}

+ 1
- 1
tests/features152/synthetic/TheWholeShow.aj View File

@@ -58,7 +58,7 @@ public class TheWholeShow {
for (Method m : ms) {
if (!m.isSynthetic()) {
String name = m.getName();
if (name.equals("aspectOf") || name.equals("hasAspect")) continue;
if (name.equals("aspectOf") || name.equals("hasAspect") || name.equals("getWithinTypeName")) continue;
if ( ! (name.startsWith("ajc$before") || name.startsWith("ajc$after") || name.startsWith("ajc$around") ||
name.startsWith("ajc$interMethod$"))) {
System.err.println("Found non-synthetic method: " + m.getName() + " in " + c.getName());

+ 27
- 0
tests/features153/ptw/CaseFive.java View File

@@ -0,0 +1,27 @@
import java.lang.reflect.Method;

import org.aspectj.lang.annotation.*;
import org.aspectj.lang.*;

class AClass {}
class BClass {}
class CClass {}

@Aspect("pertypewithin(*Class)")
public class CaseFive {
public static void main(String []argv) throws Exception {
new Runner().run();
}
}

class Runner {
public void run() throws Exception {
if (Aspects14.hasAspect(CaseFive.class,AClass.class)) {
System.out.println("AClass has an aspect instance");
CaseFive instance = (CaseFive)Aspects14.aspectOf(CaseFive.class,AClass.class);
Method m = CaseFive.class.getDeclaredMethod("getWithinTypeName",null);
String s = (String)m.invoke(instance,null);
System.out.println("The aspect instance thinks it is for type name "+s);
}
}
}

+ 28
- 0
tests/features153/ptw/CaseFour.java View File

@@ -0,0 +1,28 @@
// Types in packages

package a.b;

class AClass {}
class BClass {}
class CClass {}

public aspect CaseFour pertypewithin(*Class) {
public static void main(String []argv) {
new Runner().run();
}
}

class Runner {
public void run() {
CaseFour aInstance = (CaseFour.hasAspect(AClass.class)?CaseFour.aspectOf(AClass.class):null);
CaseFour bInstance = (CaseFour.hasAspect(BClass.class)?CaseFour.aspectOf(BClass.class):null);
CaseFour cInstance = (CaseFour.hasAspect(CClass.class)?CaseFour.aspectOf(CClass.class):null);

System.out.println("BClass aspect instance gives a within type name of "+
(bInstance==null?"<null>":bInstance.getWithinTypeName()));
System.out.println("CClass aspect instance gives a within type name of "+
(cInstance==null?"<null>":cInstance.getWithinTypeName()));
System.out.println("AClass aspect instance gives a within type name of "+
(aInstance==null?"<null>":aInstance.getWithinTypeName()));
}
}

+ 22
- 0
tests/features153/ptw/CaseOne.java View File

@@ -0,0 +1,22 @@
// Types not in packages

class AClass {}
class BClass {}
class CClass {}

public aspect CaseOne pertypewithin(*Class) {
public static void main(String []argv) {
new Runner().run();
}
}

class Runner {
public void run() {
if (CaseOne.hasAspect(AClass.class)) {
System.out.println("AClass has an aspect instance");
CaseOne instance = CaseOne.aspectOf(AClass.class);
String name = instance.getWithinTypeName();
System.out.println("The aspect instance thinks it is for type name "+name);
}
}
}

+ 26
- 0
tests/features153/ptw/CaseThree.java View File

@@ -0,0 +1,26 @@
// Types not in packages - BClass won't get an aspect

class AClass {}
class BClass {}
class CClass {}

public aspect CaseThree pertypewithin(*Class && !BClass) {
public static void main(String []argv) {
new Runner().run();
}
}

class Runner {
public void run() {
CaseThree aInstance = (CaseThree.hasAspect(AClass.class)?CaseThree.aspectOf(AClass.class):null);
CaseThree bInstance = (CaseThree.hasAspect(BClass.class)?CaseThree.aspectOf(BClass.class):null);
CaseThree cInstance = (CaseThree.hasAspect(CClass.class)?CaseThree.aspectOf(CClass.class):null);

System.out.println("BClass aspect instance gives a within type name of "+
(bInstance==null?"<null>":bInstance.getWithinTypeName()));
System.out.println("CClass aspect instance gives a within type name of "+
(cInstance==null?"<null>":cInstance.getWithinTypeName()));
System.out.println("AClass aspect instance gives a within type name of "+
(aInstance==null?"<null>":aInstance.getWithinTypeName()));
}
}

+ 26
- 0
tests/features153/ptw/CaseTwo.java View File

@@ -0,0 +1,26 @@
// Types not in packages, and multiple mixed up instances

class AClass {}
class BClass {}
class CClass {}

public aspect CaseTwo pertypewithin(*Class) {
public static void main(String []argv) {
new Runner().run();
}
}

class Runner {
public void run() {
CaseTwo aInstance = (CaseTwo.hasAspect(AClass.class)?CaseTwo.aspectOf(AClass.class):null);
CaseTwo bInstance = (CaseTwo.hasAspect(BClass.class)?CaseTwo.aspectOf(BClass.class):null);
CaseTwo cInstance = (CaseTwo.hasAspect(CClass.class)?CaseTwo.aspectOf(CClass.class):null);

System.out.println("BClass aspect instance gives a within type name of "+
(bInstance==null?"<null>":bInstance.getWithinTypeName()));
System.out.println("CClass aspect instance gives a within type name of "+
(cInstance==null?"<null>":cInstance.getWithinTypeName()));
System.out.println("AClass aspect instance gives a within type name of "+
(aInstance==null?"<null>":aInstance.getWithinTypeName()));
}
}

+ 5
- 0
tests/src/org/aspectj/systemtest/ajc153/Ajc153Tests.java View File

@@ -28,6 +28,11 @@ public class Ajc153Tests extends org.aspectj.testing.XMLBasedAjcTestCase {
// public void testCFlowXMLAspectLTW_pr149096() { runTest("cflow xml concrete aspect"); }
// public void testAmbiguousBinding_pr121805() { runTest("ambiguous binding");}
// public void testNegatedAnnotationMatchingProblem_pr153464() { runTest("negated annotation matching problem");}
public void testPTWgetWithinTypeName_pr123423_1() { runTest("basic usage of getWithinTypeName");}
public void testPTWgetWithinTypeName_pr123423_2() { runTest("basic usage of getWithinTypeName - multiple types");}
public void testPTWgetWithinTypeName_pr123423_3() { runTest("basic usage of getWithinTypeName - non matching types");}
public void testPTWgetWithinTypeName_pr123423_4() { runTest("basic usage of getWithinTypeName - types in packages");}
public void testPTWgetWithinTypeName_pr123423_5() { runTest("basic usage of getWithinTypeName - annotation style");}
public void testTurningOffBcelCaching_pr160674() { runTest("turning off bcel caching");}
public void testNoIllegalStateExceptionWithGenericInnerAspect_pr156058() { runTest("no IllegalStateException with generic inner aspect"); }
public void testNoIllegalStateExceptionWithGenericInnerAspect_pr156058_2() { runTest("no IllegalStateException with generic inner aspect - 2"); }

+ 53
- 0
tests/src/org/aspectj/systemtest/ajc153/ajc153.xml View File

@@ -51,6 +51,59 @@
</compile>
</ajc-test>
<ajc-test dir="features153/ptw" title="basic usage of getWithinTypeName">
<compile files="CaseOne.java"/>
<run class="CaseOne">
<stdout>
<line text="AClass has an aspect instance"/>
<line text="The aspect instance thinks it is for type name AClass"/>
</stdout>
</run>
</ajc-test>
<ajc-test dir="features153/ptw" title="basic usage of getWithinTypeName - annotation style">
<compile files="CaseFive.java" options="-1.5"/>
<run class="CaseFive">
<stdout>
<line text="AClass has an aspect instance"/>
<line text="The aspect instance thinks it is for type name AClass"/>
</stdout>
</run>
</ajc-test>
<ajc-test dir="features153/ptw" title="basic usage of getWithinTypeName - multiple types">
<compile files="CaseTwo.java"/>
<run class="CaseTwo">
<stdout>
<line text="BClass aspect instance gives a within type name of BClass"/>
<line text="CClass aspect instance gives a within type name of CClass"/>
<line text="AClass aspect instance gives a within type name of AClass"/>
</stdout>
</run>
</ajc-test>
<ajc-test dir="features153/ptw" title="basic usage of getWithinTypeName - non matching types">
<compile files="CaseThree.java"/>
<run class="CaseThree">
<stdout>
<line text="BClass aspect instance gives a within type name of &lt;null&gt;"/>
<line text="CClass aspect instance gives a within type name of CClass"/>
<line text="AClass aspect instance gives a within type name of AClass"/>
</stdout>
</run>
</ajc-test>
<ajc-test dir="features153/ptw" title="basic usage of getWithinTypeName - types in packages">
<compile files="CaseFour.java"/>
<run class="a.b.CaseFour">
<stdout>
<line text="BClass aspect instance gives a within type name of a.b.BClass"/>
<line text="CClass aspect instance gives a within type name of a.b.CClass"/>
<line text="AClass aspect instance gives a within type name of a.b.AClass"/>
</stdout>
</run>
</ajc-test>
<ajc-test dir="bugs153/pr158126" title="annotations, call and constructors problem">
<compile files="A.java,B.java,MyAnnotation.java,MyAspect.java" options="-1.5 -showWeaveInfo">
<message kind="weave" text="Join point 'constructor-call(void B.&lt;init&gt;())' in Type 'A' (A.java:5) advised by before advice from 'MyAspect' (MyAspect.java:3)"/>

+ 14
- 0
weaver/src/org/aspectj/weaver/AjcMemberMaker.java View File

@@ -189,6 +189,20 @@ public class AjcMemberMaker {
);
return rm;
}
// PTWIMPL ResolvedMember for getWithinTypeName() method
public static ResolvedMember perTypeWithinGetWithinTypeNameMethod(UnresolvedType declaringType, boolean inJava5Mode) {
// public String getWithinTypeName()
ResolvedMemberImpl rm = new ResolvedMemberImpl(
Member.METHOD,
declaringType,
Modifier.PUBLIC,
UnresolvedType.JAVA_LANG_STRING, // return value
NameMangler.PERTYPEWITHIN_GETWITHINTYPENAME_METHOD,
UnresolvedType.NONE
);
return rm;
}

public static ResolvedMember perTypeWithinCreateAspectInstance(UnresolvedType declaringType) {
// public static a.X ajc$createAspectInstance(java.lang.String)

+ 1
- 0
weaver/src/org/aspectj/weaver/NameMangler.java View File

@@ -47,6 +47,7 @@ public class NameMangler {
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 PERTYPEWITHIN_GETWITHINTYPENAME_METHOD = "getWithinTypeName";
public static final String AJC_PRE_CLINIT_NAME = PREFIX + "preClinit";


+ 17
- 1
weaver/src/org/aspectj/weaver/bcel/BcelPerClauseAspectAdder.java View File

@@ -124,6 +124,7 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger {
generatePerTWHasAspectMethod(gen);
generatePerTWGetInstanceMethod(gen);
generatePerTWCreateAspectInstanceMethod(gen);
generatePerTWGetWithinTypeNameMethod(gen);
} else {
throw new Error("should not happen - not such kind " + kind.getName());
}
@@ -177,7 +178,7 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger {
// pr144602 - don't need to do this, PerObjectInterface munger will do it
// } else if (kind == PerClause.PEROBJECT) {
// ResolvedMember perObjectFieldInfo = AjcMemberMaker.perObjectField(aspectType, aspectType);
// classGen.addField(makeFieldGen(classGen, perObjectFieldInfo).getField(), null);
// classGen.addField(makeFieldGen(classGen, perObjectFieldInfo).(), null);
// // if lazy generation of the inner interface MayHaveAspect works on LTW (see previous note)
// // it should be done here.
} else if (kind == PerClause.PERCFLOW) {
@@ -471,6 +472,21 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger {
);
}

// Create 'public String getWithinTypeName() { return ajc$withinType;}'
private void generatePerTWGetWithinTypeNameMethod(LazyClassGen classGen) {
InstructionFactory factory = classGen.getFactory();
LazyMethodGen method = makeMethodGen(classGen, AjcMemberMaker.perTypeWithinGetWithinTypeNameMethod(aspectType,classGen.getWorld().isInJava5Mode()));
flagAsSynthetic(method, false);
classGen.addMethodGen(method);
// 0: aload_0
// 1: getfield #14; //Field ajc$withinType:Ljava/lang/String;
// 4: areturn
InstructionList il = method.getBody();
il.append(InstructionConstants.ALOAD_0);
il.append(Utility.createGet(factory, AjcMemberMaker.perTypeWithinWithinTypeField(aspectType, aspectType)));
il.append(InstructionConstants.ARETURN);
}

private void generatePerTWHasAspectMethod(LazyClassGen classGen) {
InstructionFactory factory = classGen.getFactory();
LazyMethodGen method = makeMethodGen(classGen, AjcMemberMaker.perTypeWithinHasAspectMethod(aspectType,classGen.getWorld().isInJava5Mode()));

Loading…
Cancel
Save