我正在创建一个类似于此的Groovy DSL
:
types {
A "http://some.namespace.here"
B "..."
}
testMethod(A a, B b) { ... }
用户在这些类型上定义了几种类型和一些方法。我需要做的是在AST中创建A
和B
作为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);
// ...
当我运行代码并且不引用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);