Groovy中当前文件的源代码

时间:2018-04-24 08:43:15

标签: groovy

我需要在Groovy中加载当前文件的源代码作为String(定义当前正在运行的方法的文件)。我该怎么办?

我发现的大部分答案都与获取当前文件的父目录或获取Groovy脚本的源有关。但我的代码不是脚本,它只是一个类。

1 个答案:

答案 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()
}