*/
private void openAroundAdvice(LazyMethodGen aroundAdvice) {
InstructionHandle curr = aroundAdvice.getBody().getStart();
InstructionHandle end = aroundAdvice.getBody().getEnd();
ConstantPool cpg = aroundAdvice.getEnclosingClass().getConstantPool();
InstructionFactory factory = aroundAdvice.getEnclosingClass().getFactory();
boolean realizedCannotInline = false;
while (curr != end) {
if (realizedCannotInline) {
// we know we cannot inline this advice so no need for futher handling
break;
}
InstructionHandle next = curr.getNext();
Instruction inst = curr.getInstruction();
// open-up method call
if ((inst instanceof InvokeInstruction)) {
InvokeInstruction invoke = (InvokeInstruction) inst;
ResolvedType callee = aspectGen.getWorld().resolve(UnresolvedType.forName(invoke.getClassName(cpg)));
// look in the whole method list and not just declared for super calls and alike
List<ResolvedMember> methods = callee.getMethodsWithoutIterator(false, true, false);
for (ResolvedMember resolvedMember : methods) {
if (invoke.getName(cpg).equals(resolvedMember.getName())
&& invoke.getSignature(cpg).equals(resolvedMember.getSignature()) && !resolvedMember.isPublic()) {
if ("<init>".equals(invoke.getName(cpg))) {
// skipping open up for private constructor
// can occur when aspect new a private inner type
// too complex to handle new + dup + .. + invokespecial here.
aroundAdvice.setCanInline(false);
realizedCannotInline = true;
} else {
// specific handling for super.foo() calls, where foo is non public
ResolvedType memberType = aspectGen.getWorld().resolve(resolvedMember.getDeclaringType());
if (!aspectType.equals(memberType) && memberType.isAssignableFrom(aspectType)) {
// old test was...
// if (aspectType.getSuperclass() != null
// && aspectType.getSuperclass().getName().equals(resolvedMember.getDeclaringType().getName())) {
ResolvedMember accessor = createOrGetInlineAccessorForSuperDispatch(resolvedMember);
InvokeInstruction newInst = factory.createInvoke(aspectType.getName(), accessor.getName(),
BcelWorld.makeBcelType(accessor.getReturnType()),
BcelWorld.makeBcelTypes(accessor.getParameterTypes()), Constants.INVOKEVIRTUAL);
curr.setInstruction(newInst);
} else {
ResolvedMember accessor = createOrGetInlineAccessorForMethod(resolvedMember);
InvokeInstruction newInst = factory.createInvoke(aspectType.getName(), accessor.getName(),
BcelWorld.makeBcelType(accessor.getReturnType()),
BcelWorld.makeBcelTypes(accessor.getParameterTypes()), Constants.INVOKESTATIC);
curr.setInstruction(newInst);
}
}
break;// ok we found a matching callee member and swapped the instruction with the accessor
}
}
} else if (inst instanceof FieldInstruction) {
FieldInstruction invoke = (FieldInstruction) inst;
ResolvedType callee = aspectGen.getWorld().resolve(UnresolvedType.forName(invoke.getClassName(cpg)));
for (int i = 0; i < callee.getDeclaredJavaFields().length; i++) {
ResolvedMember resolvedMember = callee.getDeclaredJavaFields()[i];
if (invoke.getName(cpg).equals(resolvedMember.getName())
&& invoke.getSignature(cpg).equals(resolvedMember.getSignature()) && !resolvedMember.isPublic()) {
final ResolvedMember accessor;
if ((inst.opcode == Constants.GETFIELD) || (inst.opcode == Constants.GETSTATIC)) {
accessor = createOrGetInlineAccessorForFieldGet(resolvedMember);
} else {
accessor = createOrGetInlineAccessorForFieldSet(resolvedMember);
}
InvokeInstruction newInst = factory.createInvoke(aspectType.getName(), accessor.getName(),
BcelWorld.makeBcelType(accessor.getReturnType()),
BcelWorld.makeBcelTypes(accessor.getParameterTypes()), Constants.INVOKESTATIC);
curr.setInstruction(newInst);
break;// ok we found a matching callee member and swapped the instruction with the accessor