@@ -19,6 +19,7 @@ public class AllTestsAspectJ151 { | |||
TestSuite suite = new TestSuite("AspectJ 1.5.1 tests"); | |||
//$JUnit-BEGIN$ | |||
suite.addTest(Ajc151Tests.suite()); | |||
suite.addTest(NewarrayJoinpointTests.suite()); | |||
//$JUnit-END$ | |||
return suite; | |||
} |
@@ -60,6 +60,9 @@ public class NewarrayJoinpointTests extends XMLBasedAjcTestCase { | |||
public void testUsingItForReal() { runTest("using it for real");} | |||
public void testDifferentiatingArrayTypes() { runTest("differentiating array types");} | |||
public void testStructureModel() { runTest("structure model");} | |||
public void testOptionoff() { runTest("option deactivated - no match expected");} | |||
// | |||
public static Test suite() { |
@@ -153,5 +153,12 @@ | |||
<ajc-test dir="features151/newarrayjoinpoint" title="structure model"> | |||
<compile files="Five.java" options="-1.5 -emacssym -Xjoinpoints:arrayconstruction"/> | |||
</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> |
@@ -96,7 +96,17 @@ public class JoinPointSignatureIterator implements Iterator { | |||
// Walk up hierarchy creating one member for each type up to and including the | |||
// first defining type | |||
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); | |||
if (firstDefiningMember == null) { | |||
couldBeFurtherAsYetUndiscoveredSignatures = false; | |||
return; |
@@ -142,7 +142,29 @@ public abstract class Shadow { | |||
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() { | |||
if (isShadowForArrayConstructionJoinpoint()) { | |||
return getArgumentTypesForArrayConstructionShadow(); | |||
} | |||
if (getKind() == FieldSet) return new UnresolvedType[] { getResolvedSignature().getGenericReturnType() }; | |||
return getResolvedSignature().getGenericParameterTypes(); | |||
} |
@@ -665,6 +665,7 @@ public abstract class World implements Dump.INode { | |||
} | |||
public void setOptionalJoinpoints(String jps) { | |||
if (jps==null) return; | |||
if (jps.indexOf("arrayconstruction")!=-1) { | |||
optionalJoinpoint_ArrayConstruction = true; | |||
} |
@@ -29,6 +29,7 @@ import org.aspectj.apache.bcel.Constants; | |||
import org.aspectj.apache.bcel.classfile.Field; | |||
import org.aspectj.apache.bcel.classfile.Method; | |||
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.CPInstruction; | |||
import org.aspectj.apache.bcel.generic.ConstantPoolGen; | |||
@@ -44,8 +45,10 @@ import org.aspectj.apache.bcel.generic.InstructionList; | |||
import org.aspectj.apache.bcel.generic.InstructionTargeter; | |||
import org.aspectj.apache.bcel.generic.InvokeInstruction; | |||
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.NEW; | |||
import org.aspectj.apache.bcel.generic.NEWARRAY; | |||
import org.aspectj.apache.bcel.generic.ObjectType; | |||
import org.aspectj.apache.bcel.generic.PUTFIELD; | |||
import org.aspectj.apache.bcel.generic.PUTSTATIC; | |||
@@ -1881,7 +1884,40 @@ class BcelClassWeaver implements IClassWeaver { | |||
} else { | |||
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, | |||
// since that's what every javac type thing ever uses to start a handler, but for | |||
// now we'll do this for everybody. |
@@ -269,7 +269,8 @@ public class BcelShadow extends Shadow { | |||
// 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. | |||
if (getKind() == ConstructorCall) { | |||
deleteNewAndDup(); | |||
if (!world.isJoinpointArrayConstructionEnabled() || !this.getSignature().getDeclaringType().isArray()) | |||
deleteNewAndDup(); // no new/dup for new array construction | |||
initializeArgVars(); | |||
} else if (getKind() == PreInitialization) { // pr74952 | |||
ShadowRange range = getRange(); | |||
@@ -377,12 +378,14 @@ public class BcelShadow extends Shadow { | |||
Range.InsideBefore); | |||
} | |||
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); | |||
} | |||
} | |||
} | |||
} | |||
@@ -781,7 +784,51 @@ public class BcelShadow extends Shadow { | |||
retargetAllBranches(callHandle, r.getStart()); | |||
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( | |||
BcelWorld world, | |||
LazyMethodGen enclosingMethod, |
@@ -81,8 +81,13 @@ public class ArgsPointcut extends NameBindingPointcut { | |||
} | |||
private ResolvedType[] getArgumentsToMatchAgainst(Shadow shadow) { | |||
if (shadow.isShadowForArrayConstructionJoinpoint()) { | |||
return shadow.getArgumentTypesForArrayConstructionShadow(); | |||
} | |||
ResolvedType[] argumentsToMatchAgainst = shadow.getIWorld().resolve(shadow.getGenericArgTypes()); | |||
// special treatment for adviceexecution which may have synthetic arguments we | |||
// want to ignore. | |||
if (shadow.getKind() == Shadow.AdviceExecution) { |