虽然我不知道“使用 Groovy 来实现这一点的简单单行”(您的评论),但可以使用 AST 转换来做到这一点。
最简单的方法是使用注释进行本地 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()
}