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

Groovy-通过AST转换向脚本添加类,groovy,abstract-syntax-tree,dsl,Groovy,Abstract Syntax Tree,Dsl,我目前正在创建一个Groovy DSL,它看起来像这样: types { A "http://some.namespace.here" B "..." } testMethod(A a, B b) { ... } 用户定义了几种类型以及这些类型上的一些方法。我需要做的是在AST中创建A和B作为ClassNodes,以便Groovy可以找到它们 为此,我创建了以下AST转换: @GroovyASTTransformation(phase = CompilePhase.SEMANTI

我目前正在创建一个
Groovy DSL
,它看起来像这样:

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

testMethod(A a, B b) { ... }
用户定义了几种类型以及这些类型上的一些方法。我需要做的是在AST中创建
A
B
作为
ClassNode
s,以便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);
// ...
当我运行代码并且不引用
A
B
时,一切正常。但是,只要我使用
A
B
,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
         ^
任何帮助都将不胜感激

更新:类加载器 我正在使用一个自定义的
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);    

只是想说明一个明显的问题:您在
GroovyShell
中使用了哪个类加载器?这和你在执行DSL时使用的是同一个吗?@Keegan我更新了我的问题。我正在使用一个
URLClassLoader
,因为我在其中添加了几个jar。类加载器将当前CL作为父级。