我需要在Groovy中加载当前文件的源代码作为String(定义当前正在运行的方法的文件)。我该怎么办?
我发现的大部分答案都与获取当前文件的父目录或获取Groovy脚本的源有关。但我的代码不是脚本,它只是一个类。
答案 0 :(得分:2)
虽然我不知道“简单的单行代码,因为这是Groovy”(你的评论),但是可以使用AST转换来做到这一点。
最简单的方法是使用Annotation进行局部AST转换。您注释了您的测试类。然后,您有不同的选项可以在运行时检索源代码。我会将它添加为一个新的注释的值,然后你可以通过反射得到它。
<强>项目强>
我在github创建了一个展示广告资源库。
您应该可以通过gradle / maven直接使用它:
repositories {
maven { url 'https://jitpack.io' }
}
dependencies {
compile 'com.github.MeneDev:groovy-get-source:96746d39f3'
}
用法:
@SaveSource
class AClass {
def getCode() {
SourceCode sourceCode = this.class.getAnnotation(SourceCode)
return sourceCode.value()
}
}
必修步骤
注释:
import java.lang.annotation.ElementType
import java.lang.annotation.Retention
import java.lang.annotation.RetentionPolicy
import java.lang.annotation.Target
@Target([ElementType.TYPE])
@Retention(RetentionPolicy.CLASS)
@GroovyASTTransformationClass(classes = [SaveSourceASTTransformation])
public @interface SaveSource {
}
转型:
import groovy.transform.CompileStatic
import org.codehaus.groovy.ast.ASTNode
import org.codehaus.groovy.ast.AnnotationNode
import org.codehaus.groovy.ast.ClassNode
import org.codehaus.groovy.ast.expr.ConstantExpression
import org.codehaus.groovy.control.CompilePhase
import org.codehaus.groovy.control.SourceUnit
import org.codehaus.groovy.transform.ASTTransformation
import org.codehaus.groovy.transform.GroovyASTTransformation
@CompileStatic
@GroovyASTTransformation(phase = CompilePhase.SEMANTIC_ANALYSIS)
class SaveSourceASTTransformation implements ASTTransformation {
@Override
void visit(ASTNode[] nodes, SourceUnit sourceUnit) {
if (nodes.length < 2) {
return
}
if (!(nodes[0] instanceof AnnotationNode)) {
return
}
if (!(nodes[1] instanceof ClassNode)) {
return
}
def classNode = nodes[1] as ClassNode
def annotationNode = new AnnotationNode(new ClassNode(SourceCode))
def sourceCode = sourceUnit.source.reader.text
annotationNode.addMember("value", new ConstantExpression(sourceCode))
classNode.addAnnotation(annotationNode)
}
}
用于存储源代码的注释(注意RetentionPolicy.RUNTIME
,以便您可以在运行时读取值):
@Retention(RetentionPolicy.RUNTIME)
@interface SourceCode {
String value()
}