How do I compose two Implementations?

Viewed 64

I have an Implementation resulting from the return value of Advice#wrap(Implementation), and a FixedValue. I need to turn these into a single Implementation that does not result in a bytecode verification error.

That is:

Implementation advisedMethodCall = Advice.to(...).wrap(someMethodCall);
Implementation firstArgument = FixedValue.argument(0);
// How can I "run" advisedMethodCall followed by firstArgument?

More generally: how do I take two Implementations (that are not instances of Implementation.Composable) and compose them?

(I know from prior experiments that MethodCall achieves this with some sort of inner class named TerminationHandler, where the particular implementation in question, TerminationHandler.Simple.DROPPING, does something to the stack to allow you to compose MethodCalls. I don't know how to do something analogous with an Implementation that is not a MethodCall (e.g. one resulting from Advice#wrap(Implementation)).)

1 Answers

I'd suggest:

Advice.to(...).wrap(someMethodCall.andThen(FixedValue.argument(0))

In case that your advice needs to see the original method return value, you can always wrap Advice.to(...).wrap(someMethodCall) with another advice where you change the returned value.

Implementations work a bit different then advice in the sense that they are not meant to alter existing code. They cannot parse byte code of other implementations in contrast to Advice with decorates existing byte code. So you can write an advice that changes the return value as:

Advice.to(ReturnChangeAdvice.class).wrap(Advice.to(...).wrap(someMethodCall))
Related