Groovy - 通过AST转换将类添加到脚本

时间:2015-08-16 16:15:46

标签: groovy abstract-syntax-tree dsl

我正在创建一个类似于此的Groovy DSL

types {
   A "http://some.namespace.here"
   B "..."
}

testMethod(A a, B b) { ... }

用户在这些类型上定义了几种类型和一些方法。我需要做的是在AST中创建AB作为ClassNode,以便Groovy可以找到它们。

为此,我创建了以下AST转换:

@GroovyASTTransformation(phase = CompilePhase.SEMANTIC_ANALYSIS)
class GenerateClassesTransformer implements ASTTransformation  {

    @Override
    public void visit(ASTNode[] nodes, SourceUnit source) {

        ClassNode a = createClass("A")
        ClassNode b = createClass("b")

        ModuleNode module = sourceUnit.getAST()
        module.addClass(a)
        module.addClass(b)
        module.getClasses().each {
            println "class: " + it
        }

    }

    private ClassNode createClass(String className) {

        new AstBuilder().buildFromSpec {
            classNode(className, ClassNode.ACC_PUBLIC) {
                classNode Object
                interfaces { classNode GroovyObject }
                mixins { }
            }
        }.first()

    }

}

然后我将AST转换添加到Groovy shell:

CompilerConfiguration cc = new CompilerConfiguration();
cc.setScriptBaseClass("groovy.util.DelegatingScript");
cc.addCompilationCustomizers(new ASTTransformationCustomizer(new GenerateClassesTransformer()));
GroovyShell sh = new GroovyShell(loader, binding, cc);
// ...

当我运行代码并且不引用AB时,一切正常。但是,只要我使用AB,Groovy就无法找到类(尽管它们在AST上)。相反,我得到:

org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
C:\...\test.groovy: 23: unable to resolve class A
 @ line 23, column 6.
   A a = null
         ^

非常感谢任何帮助!

更新:ClassLoader

我正在使用自定义URLClassLoader,因为我在类路径中添加了几个JAR

URL[] urls = this.getExtraJarUrls(); // read JARs from a directory relative to the DSL script
ClassLoader base = Launcher.class.getClassLoader();
loader = new URLClassLoader(urls, base);    

0 个答案:

没有答案