Skip to content

Instantly share code, notes, and snippets.

@melix
Created January 11, 2012 17:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save melix/1595639 to your computer and use it in GitHub Desktop.
Save melix/1595639 to your computer and use it in GitHub Desktop.
Direct method calls with vargs throws AIOBE
package groovy.bugs
import org.codehaus.groovy.ast.ClassCodeVisitorSupport
import org.codehaus.groovy.control.SourceUnit
import org.codehaus.groovy.ast.expr.MethodCallExpression
import org.codehaus.groovy.ast.MethodNode
import org.codehaus.groovy.control.CompilerConfiguration
import org.codehaus.groovy.control.customizers.CompilationCustomizer
import org.codehaus.groovy.control.CompilePhase
import org.codehaus.groovy.classgen.GeneratorContext
import org.codehaus.groovy.ast.ClassNode
class DirectMethodCallWithVargsTest extends GroovyTestCase {
void testDirectMethodCallWithVargs() {
def config = new CompilerConfiguration()
config.addCompilationCustomizers(
new MyCustomizer()
)
GroovyShell shell = new GroovyShell(config)
shell.evaluate '''
def foo(String... args) {
(args as List).join(',')
}
assert foo('1','2','3') == '1,2,3'
'''
}
private static class MyCustomizer extends CompilationCustomizer {
MyCustomizer() {
super(CompilePhase.CANONICALIZATION)
}
@Override
void call(final SourceUnit source, final GeneratorContext context, final ClassNode classNode) {
def visitor = new MethodCallVisitor(source)
classNode.methods.each { visitor.visitMethod(it) }
visitor.visitClass(classNode)
}
}
private static class MethodCallVisitor extends ClassCodeVisitorSupport {
private final SourceUnit unit
private MethodNode fooMethod
MethodCallVisitor(SourceUnit source) {
unit = source
}
@Override
protected SourceUnit getSourceUnit() {
return unit
}
@Override
void visitMethod(final MethodNode node) {
super.visitMethod(node)
if (node.name=='foo') {
fooMethod = node
}
}
@Override
void visitMethodCallExpression(final MethodCallExpression call) {
super.visitMethodCallExpression(call)
if (call.methodAsString=='foo') {
call.methodTarget = fooMethod
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment