Great now I run into another problem, spock uses groovy-all, which repackages asm. The BytecodeExpression has a MethodVisitor from asm, which is now in groovyjarjarasm.asm.MethodVisitor This compiles fine, but when the AST transforms are executed it breaks down with this exception:

Caused by: java.lang.LinkageError: loader constraint violation: loader (instance of groovy/lang/GroovyClassLoader) previously initiated loading for a different type with name "groovyjarjarasm/asm/MethodVisitor"         at org.spockframework.compiler.DeepBlockRewriter$1.visit(DeepBlockRewriter.java:190)         at org.gradle.api.internal.tasks.compile.ApiGroovyCompiler.execute(ApiGroovyCompiler.java:174)         at org.gradle.api.internal.tasks.compile.ApiGroovyCompiler.execute(ApiGroovyCompiler.java:56)         at org.gradle.api.internal.tasks.compile.daemon.AbstractDaemonCompiler$CompilerRunnable.run(AbstractDaemonCompiler.java:87)         at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:36)         at org.gradle.workers.internal.WorkerDaemonServer.execute(WorkerDaemonServer.java:46)         at org.gradle.workers.internal.WorkerDaemonServer.execute(WorkerDaemonServer.java:30)         at org.gradle.process.internal.worker.request.WorkerAction.run(WorkerAction.java:100)         at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)         at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)         at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:146)         at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:128)         at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:404)

I tried using the non-repackaged classes, but then it doesn't even compile since BytecodeExpression wants groovyjarjarasm.

Thanks

-Leo


Am 22.11.2017 um 00:49 schrieb Jochen Theodorou:
On 21.11.2017 21:43, Leonard Brünings wrote:
Hi Jochen,

your first suggestion might do the trick and if closures disappear then there will be much more that doesn't work.

We currently do something like this:


   public void replaceImplicitThis(Expression invocation) {
     if (invocation instanceof MethodCallExpression) {
       MethodCallExpression methodCallExpression = (MethodCallExpression)invocation;
       if (methodCallExpression.isImplicitThis()) {

         Expression target = referenceToCurrentClosure();
         methodCallExpression.setObjectExpression(target);
       }
     }
   }

   private MethodCallExpression referenceToCurrentClosure() {
     return new MethodCallExpression(
       new VariableExpression("this"),
       new ConstantExpression("each"),
       new ArgumentListExpression(
         new PropertyExpression(
           new ClassExpression(ClassHelper.makeWithoutCaching(Closure.class)),
           new ConstantExpression("IDENTITY")
         )
       )
     );
   }

This looks a similar to your second suggestion.

similar in that both get the current reference, yes.

Could you give me a hint on how to write a BytecodeExpersion for "ALOAD 0"? Could I just use this in place of the other MethodCallExpression from referenceToCurrentClosure?

You use it in place of referenceToCurrentClosure,yes. Something like

                        new BytecodeExpression(ClassHelper.CLOSURE) {
                            public void visit(MethodVisitor mv) {
                                mv.visitVarInsn(ALOAD, 0);
                            }
                        });

frankly this is using a feature I do not like so much and that is that Groovy handles a call on a closure instance the same way as a call from within that closure instance (well, not 100% the same, there are differences).But in this case you profit from it. Otherwise you would need a way to express the implicit this as parameter... Maybe this is actually something we should do..

bye Jochen

Reply via email to