Compilation error when mocking Groovy class
import spock.lang.Specification
class T extends Specification {
def t() {
given:
def a = Spy(A)
}
}
class A {}
The execution reports the following error:
Groovyc: While compiling [tests of spock-mockable-static]: BUG! exception in phase 'canonicalization' in source unit '/Users/xxx/workspace/spock-mockable-static/src/test/groovy/T.groovy' ClassNode#getTypeClass for A called before the type class is set
at org.codehaus.groovy.ast.ClassNode.getTypeClass(ClassNode.java:1465)
at org.codehaus.groovy.ast.ClassNode.getTypeClass(ClassNode.java:1459)
at java.util.Optional.map(Optional.java:215)
at io.github.joke.spockmockable.ast.visitors.MockVisitor$Visitor.extractClass(MockVisitor.java:88)
at java.util.Optional.flatMap(Optional.java:241)
at io.github.joke.spockmockable.ast.visitors.MockVisitor$Visitor.visitClassExpression(MockVisitor.java:59)
at org.codehaus.groovy.ast.expr.ClassExpression.visit(ClassExpression.java:36)
at org.codehaus.groovy.ast.GroovyCodeVisitor.lambda$visitListOfExpressions$0(GroovyCodeVisitor.java:209)
at java.util.ArrayList.forEach(ArrayList.java:1259)
at org.codehaus.groovy.ast.GroovyCodeVisitor.visitListOfExpressions(GroovyCodeVisitor.java:209)
at org.codehaus.groovy.ast.CodeVisitorSupport.visitTupleExpression(CodeVisitorSupport.java:249)
at org.codehaus.groovy.ast.CodeVisitorSupport.visitArgumentlistExpression(CodeVisitorSupport.java:367)
at org.codehaus.groovy.ast.expr.ArgumentListExpression.visit(ArgumentListExpression.java:75)
at io.github.joke.spockmockable.ast.visitors.MockVisitor$Visitor.visitMethodCallExpression(MockVisitor.java:51)
at io.github.joke.spockmockable.ast.visitors.MockVisitor.visit(MockVisitor.java:37)
at io.github.joke.spockmockable.ast.visitors.SpecificationVisitor$Visitor.visitMethodCallExpression(SpecificationVisitor.java:37)
at org.codehaus.groovy.ast.expr.MethodCallExpression.visit(MethodCallExpression.java:77)
at org.codehaus.groovy.ast.CodeVisitorSupport.visitBinaryExpression(CodeVisitorSupport.java:202)
at org.codehaus.groovy.ast.CodeVisitorSupport.visitDeclarationExpression(CodeVisitorSupport.java:335)
at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitDeclarationExpression(ClassCodeVisitorSupport.java:154)
at org.codehaus.groovy.ast.expr.DeclarationExpression.visit(DeclarationExpression.java:89)
at org.codehaus.groovy.ast.CodeVisitorSupport.visitExpressionStatement(CodeVisitorSupport.java:117)
at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitExpressionStatement(ClassCodeVisitorSupport.java:204)
at org.codehaus.groovy.ast.stmt.ExpressionStatement.visit(ExpressionStatement.java:41)
at org.codehaus.groovy.ast.CodeVisitorSupport.visitBlockStatement(CodeVisitorSupport.java:86)
at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitBlockStatement(ClassCodeVisitorSupport.java:168)
at org.codehaus.groovy.ast.stmt.BlockStatement.visit(BlockStatement.java:70)
at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitClassCodeContainer(ClassCodeVisitorSupport.java:142)
at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitConstructorOrMethod(ClassCodeVisitorSupport.java:115)
at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitMethod(ClassCodeVisitorSupport.java:110)
at org.codehaus.groovy.ast.ClassNode.visitMethods(ClassNode.java:1131)
at org.codehaus.groovy.ast.ClassNode.visitContents(ClassNode.java:1124)
at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitClass(ClassCodeVisitorSupport.java:52)
at io.github.joke.spockmockable.ast.visitors.SpecificationVisitor.visit(SpecificationVisitor.java:24)
at io.github.joke.spockmockable.ast.SpecificationProcessor.process(SpecificationProcessor.java:14)
at io.github.joke.spockmockable.ast.SourceUnitProcessor.lambda$process$1(SourceUnitProcessor.java:22)
at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175)
at java.util.LinkedList$LLSpliterator.forEachRemaining(LinkedList.java:1235)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472)
at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:485)
at io.github.joke.spockmockable.ast.SourceUnitProcessor.process(SourceUnitProcessor.java:22)
at io.github.joke.spockmockable.ast.Processor.analyze(Processor.java:21)
at io.github.joke.spockmockable.ast.MockableASTTransformation.visit(MockableASTTransformation.java:34)
at org.codehaus.groovy.transform.ASTTransformationVisitor.lambda$addPhaseOperationsForGlobalTransforms$5(ASTTransformationVisitor.java:377)
at org.codehaus.groovy.control.CompilationUnit$ISourceUnitOperation.doPhaseOperation(CompilationUnit.java:896)
at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:692)
at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:666)
at org.jetbrains.groovy.compiler.rt.GroovyCompilerWrapper.compile(GroovyCompilerWrapper.java:48)
at org.jetbrains.groovy.compiler.rt.DependentGroovycRunner.runGroovyc(DependentGroovycRunner.java:120)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.jetbrains.groovy.compiler.rt.GroovycRunner.intMain2(GroovycRunner.java:80)
at org.jetbrains.groovy.compiler.rt.GroovycRunner.intMain(GroovycRunner.java:40)
at org.jetbrains.groovy.compiler.rt.GroovycRunner.main(GroovycRunner.java:19)
Hi @hellsof
could you provide a more detailed example? I can reproduce the error but I'm entirely sure about what you are actually trying to do in the first place. If I create a groovy class in the compile scope (main) everything works fine.
Are you really trying to spy a class with is placed alongside your test classes?
There is no specific application scenario for the time being. When writing a demo program, this exception is reported, but no relevant records are found, and this problem is accidentally discovered when it is about to give up.
@hellsof It has something to do with the compile time groovy transformation for this extension. I'll take a closer look today.
Regards Joke
Coming across this issue as well when using thrown with my custom Exception class in Groovy. Here's a short test case example:
class FooException extends RuntimeException {}
def exceptionThrower() { throw new FooException() }
def "Test"() {
when:
exceptionThrower()
then:
thrown(FooException)
}
This fails compilation (error below). If you swap thrown(FooException) by thrown(RuntimeException) compilation and test pass.
Caused by: BUG! exception in phase 'canonicalization' in source unit 'xxxxx/Test.groovy' ClassNode#getTypeClass for xxxxx.Test$FooException called before the type class is set
at io.github.joke.spockmockable.ast.visitors.MockVisitor$Visitor.extractClass(MockVisitor.java:88)
at io.github.joke.spockmockable.ast.visitors.MockVisitor$Visitor.visitClassExpression(MockVisitor.java:59)
at io.github.joke.spockmockable.ast.visitors.MockVisitor$Visitor.visitMethodCallExpression(MockVisitor.java:51)
at io.github.joke.spockmockable.ast.visitors.MockVisitor.visit(MockVisitor.java:37)
at io.github.joke.spockmockable.ast.visitors.SpecificationVisitor$Visitor.visitMethodCallExpression(SpecificationVisitor.java:37)
at io.github.joke.spockmockable.ast.visitors.SpecificationVisitor.visit(SpecificationVisitor.java:24)
at io.github.joke.spockmockable.ast.SpecificationProcessor.process(SpecificationProcessor.java:14)
at io.github.joke.spockmockable.ast.SourceUnitProcessor.lambda$process$1(SourceUnitProcessor.java:22)
at io.github.joke.spockmockable.ast.SourceUnitProcessor.process(SourceUnitProcessor.java:22)
at io.github.joke.spockmockable.ast.Processor.analyze(Processor.java:21)
at io.github.joke.spockmockable.ast.MockableASTTransformation.visit(MockableASTTransformation.java:34)
at org.gradle.api.internal.tasks.compile.ApiGroovyCompiler.execute(ApiGroovyCompiler.java:271)
at org.gradle.api.internal.tasks.compile.ApiGroovyCompiler.execute(ApiGroovyCompiler.java:64)
at org.gradle.api.internal.tasks.compile.GroovyCompilerFactory$DaemonSideCompiler.execute(GroovyCompilerFactory.java:97)
at org.gradle.api.internal.tasks.compile.GroovyCompilerFactory$DaemonSideCompiler.execute(GroovyCompilerFactory.java:76)
at org.gradle.api.internal.tasks.compile.daemon.AbstractDaemonCompiler$CompilerWorkAction.execute(AbstractDaemonCompiler.java:135)
at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:63)
at org.gradle.workers.internal.AbstractClassLoaderWorker$1.create(AbstractClassLoaderWorker.java:49)
at org.gradle.workers.internal.AbstractClassLoaderWorker$1.create(AbstractClassLoaderWorker.java:43)
at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:100)
at org.gradle.workers.internal.AbstractClassLoaderWorker.executeInClassLoader(AbstractClassLoaderWorker.java:43)
at org.gradle.workers.internal.IsolatedClassloaderWorker.run(IsolatedClassloaderWorker.java:49)
at org.gradle.workers.internal.IsolatedClassloaderWorker.run(IsolatedClassloaderWorker.java:30)
at org.gradle.workers.internal.WorkerDaemonServer.run(WorkerDaemonServer.java:87)
at org.gradle.workers.internal.WorkerDaemonServer.run(WorkerDaemonServer.java:56)
at org.gradle.process.internal.worker.request.WorkerAction$1.call(WorkerAction.java:138)
at org.gradle.process.internal.worker.child.WorkerLogEventListener.withWorkerLoggingProtocol(WorkerLogEventListener.java:41)
at org.gradle.process.internal.worker.request.WorkerAction.run(WorkerAction.java:135)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:182)
at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:164)
at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:414)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:49)