return node;
}
}
public void weaveAroundClosure(BcelAdvice munger, boolean hasDynamicTest) {
InstructionFactory fact = getFactory();
enclosingMethod.setCanInline(false);
int linenumber = getSourceLine();
// MOVE OUT ALL THE INSTRUCTIONS IN MY SHADOW INTO ANOTHER METHOD!
LazyMethodGen callbackMethod = extractShadowInstructionsIntoNewMethod(NameMangler.aroundShadowMethodName(getSignature(),
getEnclosingClass().getNewGeneratedNameTag()), 0, munger.getSourceLocation(), new ArrayList<String>());
BcelVar[] adviceVars = munger.getExposedStateAsBcelVars(true);
String closureClassName = NameMangler.makeClosureClassName(getEnclosingClass().getType(), getEnclosingClass()
.getNewGeneratedNameTag());
Member constructorSig = new MemberImpl(Member.CONSTRUCTOR, UnresolvedType.forName(closureClassName), 0, "<init>",
"([Ljava/lang/Object;)V");
BcelVar closureHolder = null;
// This is not being used currently since getKind() == preinitializaiton
// cannot happen in around advice
if (getKind() == PreInitialization) {
closureHolder = genTempVar(AjcMemberMaker.AROUND_CLOSURE_TYPE);
}
InstructionList closureInstantiation = makeClosureInstantiation(constructorSig, closureHolder);
/* LazyMethodGen constructor = */
makeClosureClassAndReturnConstructor(closureClassName, callbackMethod, makeProceedArgumentMap(adviceVars));
InstructionList returnConversionCode;
if (getKind() == PreInitialization) {
returnConversionCode = new InstructionList();
BcelVar stateTempVar = genTempVar(UnresolvedType.OBJECTARRAY);
closureHolder.appendLoad(returnConversionCode, fact);
returnConversionCode.append(Utility.createInvoke(fact, world, AjcMemberMaker.aroundClosurePreInitializationGetter()));
stateTempVar.appendStore(returnConversionCode, fact);
Type[] stateTypes = getSuperConstructorParameterTypes();
returnConversionCode.append(InstructionConstants.ALOAD_0); // put "this" back on the stack
for (int i = 0, len = stateTypes.length; i < len; i++) {
UnresolvedType bcelTX = BcelWorld.fromBcel(stateTypes[i]);
ResolvedType stateRTX = world.resolve(bcelTX, true);
if (stateRTX.isMissing()) {
world.getLint().cantFindType.signal(new String[] { WeaverMessages.format(
WeaverMessages.CANT_FIND_TYPE_DURING_AROUND_WEAVE_PREINIT, bcelTX.getClassName()) },
getSourceLocation(), new ISourceLocation[] { munger.getSourceLocation() });
// IMessage msg = new Message(
// WeaverMessages.format(WeaverMessages.CANT_FIND_TYPE_DURING_AROUND_WEAVE_PREINIT,bcelTX.getClassName()),
// "",IMessage.ERROR,getSourceLocation(),null,
// new ISourceLocation[]{ munger.getSourceLocation()});
// world.getMessageHandler().handleMessage(msg);
}
stateTempVar.appendConvertableArrayLoad(returnConversionCode, fact, i, stateRTX);
}
} else {
// pr226201
Member mungerSignature = munger.getSignature();
if (munger.getSignature() instanceof ResolvedMember) {
if (((ResolvedMember) mungerSignature).hasBackingGenericMember()) {
mungerSignature = ((ResolvedMember) mungerSignature).getBackingGenericMember();
}
}
UnresolvedType returnType = mungerSignature.getReturnType();
returnConversionCode = Utility.createConversion(getFactory(), BcelWorld.makeBcelType(returnType), callbackMethod
.getReturnType(), world.isInJava5Mode());
if (!isFallsThrough()) {
returnConversionCode.append(InstructionFactory.createReturn(callbackMethod.getReturnType()));
}
}
// initialize the bit flags for this shadow
int bitflags = 0x000000;
if (getKind().isTargetSameAsThis()) {
bitflags |= 0x010000;
}
if (hasThis()) {
bitflags |= 0x001000;
}
if (bindsThis(munger)) {
bitflags |= 0x000100;
}
if (hasTarget()) {
bitflags |= 0x000010;
}
if (bindsTarget(munger)) {
bitflags |= 0x000001;
}
// ATAJ for @AJ aspect we need to link the closure with the joinpoint instance
if (munger.getConcreteAspect() != null && munger.getConcreteAspect().isAnnotationStyleAspect()
&& munger.getDeclaringAspect() != null && munger.getDeclaringAspect().resolve(world).isAnnotationStyleAspect()) {
// stick the bitflags on the stack and call the variant of linkClosureAndJoinPoint that takes an int
closureInstantiation.append(fact.createConstant(Integer.valueOf(bitflags)));
closureInstantiation.append(Utility.createInvoke(getFactory(), getWorld(), new MemberImpl(Member.METHOD, UnresolvedType
.forName("org.aspectj.runtime.internal.AroundClosure"), Modifier.PUBLIC, "linkClosureAndJoinPoint",
"(I)Lorg/aspectj/lang/ProceedingJoinPoint;")));
}