TestSuite suite = new TestSuite("AspectJ 1.5.1 tests"); | TestSuite suite = new TestSuite("AspectJ 1.5.1 tests"); | ||||
//$JUnit-BEGIN$ | //$JUnit-BEGIN$ | ||||
suite.addTest(Ajc151Tests.suite()); | suite.addTest(Ajc151Tests.suite()); | ||||
suite.addTest(NewarrayJoinpointTests.suite()); | |||||
//$JUnit-END$ | //$JUnit-END$ | ||||
return suite; | return suite; | ||||
} | } |
public void testUsingItForReal() { runTest("using it for real");} | public void testUsingItForReal() { runTest("using it for real");} | ||||
public void testDifferentiatingArrayTypes() { runTest("differentiating array types");} | public void testDifferentiatingArrayTypes() { runTest("differentiating array types");} | ||||
public void testStructureModel() { runTest("structure model");} | public void testStructureModel() { runTest("structure model");} | ||||
public void testOptionoff() { runTest("option deactivated - no match expected");} | |||||
// | // | ||||
public static Test suite() { | public static Test suite() { |
<ajc-test dir="features151/newarrayjoinpoint" title="structure model"> | <ajc-test dir="features151/newarrayjoinpoint" title="structure model"> | ||||
<compile files="Five.java" options="-1.5 -emacssym -Xjoinpoints:arrayconstruction"/> | <compile files="Five.java" options="-1.5 -emacssym -Xjoinpoints:arrayconstruction"/> | ||||
</ajc-test> | </ajc-test> | ||||
<ajc-test dir="features151/newarrayjoinpoint" title="option deactivated - no match expected"> | |||||
<compile files="One.java" options="-1.5 -showWeaveInfo"> | |||||
<message kind="warning" line="9" text="advice defined in X has not been applied [Xlint:adviceDidNotMatch]"/> | |||||
</compile> | |||||
</ajc-test> | |||||
</suite> | </suite> |
// Walk up hierarchy creating one member for each type up to and including the | // Walk up hierarchy creating one member for each type up to and including the | ||||
// first defining type | // first defining type | ||||
ResolvedType originalDeclaringType = signaturesOfMember.getDeclaringType().resolve(world); | ResolvedType originalDeclaringType = signaturesOfMember.getDeclaringType().resolve(world); | ||||
if (world.isJoinpointArrayConstructionEnabled() && originalDeclaringType.isArray()) { // Aha, this must be the array constructor call join point - a 'special'... | |||||
Member m = signaturesOfMember; | |||||
ResolvedMember rm = new ResolvedMemberImpl(m.getKind(),m.getDeclaringType(),m.getModifiers(),m.getReturnType(),m.getName(),m.getParameterTypes()); | |||||
discoveredSignatures.add(new JoinPointSignature(rm,originalDeclaringType)); | |||||
couldBeFurtherAsYetUndiscoveredSignatures = false; | |||||
return; | |||||
} | |||||
firstDefiningMember = (ResolvedMemberImpl) signaturesOfMember.resolve(world); | firstDefiningMember = (ResolvedMemberImpl) signaturesOfMember.resolve(world); | ||||
if (firstDefiningMember == null) { | if (firstDefiningMember == null) { | ||||
couldBeFurtherAsYetUndiscoveredSignatures = false; | couldBeFurtherAsYetUndiscoveredSignatures = false; | ||||
return; | return; |
return getSignature().getParameterTypes(); | return getSignature().getParameterTypes(); | ||||
} | } | ||||
public boolean isShadowForArrayConstructionJoinpoint() { | |||||
return (getKind()==ConstructorCall && signature.getDeclaringType().isArray()); | |||||
} | |||||
// will return the right length array of ints depending on how many dimensions the array has | |||||
public ResolvedType[] getArgumentTypesForArrayConstructionShadow() { | |||||
String s = signature.getDeclaringType().getSignature(); | |||||
int pos = s.indexOf("["); | |||||
int dims = 1; | |||||
while (pos<s.length()) { | |||||
pos++; | |||||
if (pos<s.length()) dims+=(s.charAt(pos)=='['?1:0); | |||||
} | |||||
if (dims==1) return new ResolvedType[]{ResolvedType.INT}; | |||||
ResolvedType[] someInts = new ResolvedType[dims]; | |||||
for (int i = 0; i < dims;i++) someInts[i] = ResolvedType.INT; | |||||
return someInts; | |||||
} | |||||
public UnresolvedType[] getGenericArgTypes() { | public UnresolvedType[] getGenericArgTypes() { | ||||
if (isShadowForArrayConstructionJoinpoint()) { | |||||
return getArgumentTypesForArrayConstructionShadow(); | |||||
} | |||||
if (getKind() == FieldSet) return new UnresolvedType[] { getResolvedSignature().getGenericReturnType() }; | if (getKind() == FieldSet) return new UnresolvedType[] { getResolvedSignature().getGenericReturnType() }; | ||||
return getResolvedSignature().getGenericParameterTypes(); | return getResolvedSignature().getGenericParameterTypes(); | ||||
} | } |
} | } | ||||
public void setOptionalJoinpoints(String jps) { | public void setOptionalJoinpoints(String jps) { | ||||
if (jps==null) return; | |||||
if (jps.indexOf("arrayconstruction")!=-1) { | if (jps.indexOf("arrayconstruction")!=-1) { | ||||
optionalJoinpoint_ArrayConstruction = true; | optionalJoinpoint_ArrayConstruction = true; | ||||
} | } |
import org.aspectj.apache.bcel.classfile.Field; | import org.aspectj.apache.bcel.classfile.Field; | ||||
import org.aspectj.apache.bcel.classfile.Method; | import org.aspectj.apache.bcel.classfile.Method; | ||||
import org.aspectj.apache.bcel.classfile.annotation.Annotation; | import org.aspectj.apache.bcel.classfile.annotation.Annotation; | ||||
import org.aspectj.apache.bcel.generic.ANEWARRAY; | |||||
import org.aspectj.apache.bcel.generic.BranchInstruction; | import org.aspectj.apache.bcel.generic.BranchInstruction; | ||||
import org.aspectj.apache.bcel.generic.CPInstruction; | import org.aspectj.apache.bcel.generic.CPInstruction; | ||||
import org.aspectj.apache.bcel.generic.ConstantPoolGen; | import org.aspectj.apache.bcel.generic.ConstantPoolGen; | ||||
import org.aspectj.apache.bcel.generic.InstructionTargeter; | import org.aspectj.apache.bcel.generic.InstructionTargeter; | ||||
import org.aspectj.apache.bcel.generic.InvokeInstruction; | import org.aspectj.apache.bcel.generic.InvokeInstruction; | ||||
import org.aspectj.apache.bcel.generic.LocalVariableInstruction; | import org.aspectj.apache.bcel.generic.LocalVariableInstruction; | ||||
import org.aspectj.apache.bcel.generic.MULTIANEWARRAY; | |||||
import org.aspectj.apache.bcel.generic.MethodGen; | import org.aspectj.apache.bcel.generic.MethodGen; | ||||
import org.aspectj.apache.bcel.generic.NEW; | import org.aspectj.apache.bcel.generic.NEW; | ||||
import org.aspectj.apache.bcel.generic.NEWARRAY; | |||||
import org.aspectj.apache.bcel.generic.ObjectType; | import org.aspectj.apache.bcel.generic.ObjectType; | ||||
import org.aspectj.apache.bcel.generic.PUTFIELD; | import org.aspectj.apache.bcel.generic.PUTFIELD; | ||||
import org.aspectj.apache.bcel.generic.PUTSTATIC; | import org.aspectj.apache.bcel.generic.PUTSTATIC; | ||||
} else { | } else { | ||||
matchInvokeInstruction(mg, ih, ii, enclosingShadow, shadowAccumulator); | matchInvokeInstruction(mg, ih, ii, enclosingShadow, shadowAccumulator); | ||||
} | } | ||||
} | |||||
} else if (world.isJoinpointArrayConstructionEnabled() && | |||||
(i instanceof NEWARRAY || i instanceof ANEWARRAY || i instanceof MULTIANEWARRAY)) { | |||||
if (canMatch(Shadow.ConstructorCall)) { | |||||
boolean debug = false; | |||||
if (debug) System.err.println("Found new array instruction: "+i); | |||||
if (i instanceof ANEWARRAY) { | |||||
ANEWARRAY arrayInstruction = (ANEWARRAY)i; | |||||
ObjectType arrayType = arrayInstruction.getLoadClassType(clazz.getConstantPoolGen()); | |||||
if (debug) System.err.println("Array type is "+arrayType); | |||||
BcelShadow ctorCallShadow = BcelShadow.makeArrayConstructorCall(world,mg,ih,enclosingShadow); | |||||
match(ctorCallShadow,shadowAccumulator); | |||||
} else if (i instanceof NEWARRAY) { | |||||
NEWARRAY arrayInstruction = (NEWARRAY)i; | |||||
Type arrayType = arrayInstruction.getType(); | |||||
if (debug) System.err.println("Array type is "+arrayType); | |||||
BcelShadow ctorCallShadow = BcelShadow.makeArrayConstructorCall(world,mg,ih,enclosingShadow); | |||||
match(ctorCallShadow,shadowAccumulator); | |||||
} else if (i instanceof MULTIANEWARRAY) { | |||||
MULTIANEWARRAY arrayInstruction = (MULTIANEWARRAY)i; | |||||
ObjectType arrayType = arrayInstruction.getLoadClassType(clazz.getConstantPoolGen()); | |||||
if (debug) System.err.println("Array type is "+arrayType); | |||||
BcelShadow ctorCallShadow = BcelShadow.makeArrayConstructorCall(world,mg,ih,enclosingShadow); | |||||
match(ctorCallShadow,shadowAccumulator); | |||||
} | |||||
} | |||||
// see pr77166 if you are thinking about implementing this | |||||
// } else if (i instanceof AALOAD ) { | |||||
// AALOAD arrayLoad = (AALOAD)i; | |||||
// Type arrayType = arrayLoad.getType(clazz.getConstantPoolGen()); | |||||
// BcelShadow arrayLoadShadow = BcelShadow.makeArrayLoadCall(world,mg,ih,enclosingShadow); | |||||
// match(arrayLoadShadow,shadowAccumulator); | |||||
// } else if (i instanceof AASTORE) { | |||||
// // ... magic required | |||||
} | |||||
// performance optimization... we only actually care about ASTORE instructions, | // performance optimization... we only actually care about ASTORE instructions, | ||||
// since that's what every javac type thing ever uses to start a handler, but for | // since that's what every javac type thing ever uses to start a handler, but for | ||||
// now we'll do this for everybody. | // now we'll do this for everybody. |
// this up, every ShadowRange would have three instructionHandle points, the start of | // this up, every ShadowRange would have three instructionHandle points, the start of | ||||
// the arg-setup code, the start of the running code, and the end of the running code. | // the arg-setup code, the start of the running code, and the end of the running code. | ||||
if (getKind() == ConstructorCall) { | if (getKind() == ConstructorCall) { | ||||
deleteNewAndDup(); | |||||
if (!world.isJoinpointArrayConstructionEnabled() || !this.getSignature().getDeclaringType().isArray()) | |||||
deleteNewAndDup(); // no new/dup for new array construction | |||||
initializeArgVars(); | initializeArgVars(); | ||||
} else if (getKind() == PreInitialization) { // pr74952 | } else if (getKind() == PreInitialization) { // pr74952 | ||||
ShadowRange range = getRange(); | ShadowRange range = getRange(); | ||||
Range.InsideBefore); | Range.InsideBefore); | ||||
} | } | ||||
if (getKind() == ConstructorCall) { | if (getKind() == ConstructorCall) { | ||||
range.insert((Instruction) InstructionFactory.createDup(1), Range.InsideBefore); | |||||
range.insert( | |||||
fact.createNew( | |||||
(ObjectType) BcelWorld.makeBcelType( | |||||
getSignature().getDeclaringType())), | |||||
Range.InsideBefore); | |||||
if (!world.isJoinpointArrayConstructionEnabled() || !this.getSignature().getDeclaringType().isArray()) { | |||||
range.insert((Instruction) InstructionFactory.createDup(1), Range.InsideBefore); | |||||
range.insert( | |||||
fact.createNew( | |||||
(ObjectType) BcelWorld.makeBcelType( | |||||
getSignature().getDeclaringType())), | |||||
Range.InsideBefore); | |||||
} | |||||
} | } | ||||
} | } | ||||
} | } | ||||
retargetAllBranches(callHandle, r.getStart()); | retargetAllBranches(callHandle, r.getStart()); | ||||
return s; | return s; | ||||
} | } | ||||
public static BcelShadow makeArrayConstructorCall(BcelWorld world,LazyMethodGen enclosingMethod,InstructionHandle arrayInstruction,BcelShadow enclosingShadow) { | |||||
final InstructionList body = enclosingMethod.getBody(); | |||||
Member sig = world.makeJoinPointSignatureForArrayConstruction(enclosingMethod.getEnclosingClass(),arrayInstruction); | |||||
BcelShadow s = | |||||
new BcelShadow( | |||||
world, | |||||
ConstructorCall, | |||||
sig, | |||||
enclosingMethod, | |||||
enclosingShadow); | |||||
ShadowRange r = new ShadowRange(body); | |||||
r.associateWithShadow(s); | |||||
r.associateWithTargets( | |||||
Range.genStart(body, arrayInstruction), | |||||
Range.genEnd(body, arrayInstruction)); | |||||
retargetAllBranches(arrayInstruction, r.getStart()); | |||||
return s; | |||||
} | |||||
// see pr77166 | |||||
// public static BcelShadow makeArrayLoadCall( | |||||
// BcelWorld world, | |||||
// LazyMethodGen enclosingMethod, | |||||
// InstructionHandle arrayInstruction, | |||||
// BcelShadow enclosingShadow) | |||||
// { | |||||
// final InstructionList body = enclosingMethod.getBody(); | |||||
// Member sig = world.makeJoinPointSignatureForArrayLoad(enclosingMethod.getEnclosingClass(),arrayInstruction); | |||||
// BcelShadow s = | |||||
// new BcelShadow( | |||||
// world, | |||||
// MethodCall, | |||||
// sig, | |||||
// enclosingMethod, | |||||
// enclosingShadow); | |||||
// ShadowRange r = new ShadowRange(body); | |||||
// r.associateWithShadow(s); | |||||
// r.associateWithTargets( | |||||
// Range.genStart(body, arrayInstruction), | |||||
// Range.genEnd(body, arrayInstruction)); | |||||
// retargetAllBranches(arrayInstruction, r.getStart()); | |||||
// return s; | |||||
// } | |||||
public static BcelShadow makeMethodCall( | public static BcelShadow makeMethodCall( | ||||
BcelWorld world, | BcelWorld world, | ||||
LazyMethodGen enclosingMethod, | LazyMethodGen enclosingMethod, |
} | } | ||||
private ResolvedType[] getArgumentsToMatchAgainst(Shadow shadow) { | private ResolvedType[] getArgumentsToMatchAgainst(Shadow shadow) { | ||||
if (shadow.isShadowForArrayConstructionJoinpoint()) { | |||||
return shadow.getArgumentTypesForArrayConstructionShadow(); | |||||
} | |||||
ResolvedType[] argumentsToMatchAgainst = shadow.getIWorld().resolve(shadow.getGenericArgTypes()); | ResolvedType[] argumentsToMatchAgainst = shadow.getIWorld().resolve(shadow.getGenericArgTypes()); | ||||
// special treatment for adviceexecution which may have synthetic arguments we | // special treatment for adviceexecution which may have synthetic arguments we | ||||
// want to ignore. | // want to ignore. | ||||
if (shadow.getKind() == Shadow.AdviceExecution) { | if (shadow.getKind() == Shadow.AdviceExecution) { |