如何从注释处理器中获取 class 代码作为字符串?

How to get the class code as String from Annotation Processor?

我有一个基本的注释处理器

@SupportedAnnotationTypes("example.Annotation")
public class Processor extends AbstractProcessor {
    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        for (TypeElement annotation : annotations) {
            Set<? extends Element> elementsAnnotatedWith = roundEnv.getElementsAnnotatedWith(annotation);
            for (Element element : elementsAnnotatedWith) {
                TypeElement typeElement = (TypeElement) element;
                // Here, typeElement.getQualifiedName() is accessible, but not the code nor file path.
            }
        }
        return false;
    }
}

此注释只能用于 classes。我知道目标 class 未编译,因此无法进行反射访问,但我想将 class 代码作为字符串以我自己的方式解析,而不是使用此 API.

可能吗?我知道我可以获得合格的名称,但是在哪里可以找到该文件?

一个TypeElement的源码可以这样加载:

private String loadSource(TypeElement typeElement) throws IOException {
    final FileObject source = processingEnv.getFiler().getResource(
        StandardLocation.SOURCE_PATH,
        ((PackageElement) typeElement.getEnclosingElement()).getQualifiedName(),
        typeElement.getSimpleName() + ".java");
    
    try (Reader reader = source.openReader(true)) {
        final StringBuilder builder = new StringBuilder();
        final char[] buf = new char[1024];
        int read;
        while ((read = reader.read(buf)) != -1) {
            builder.append(buf, 0, read);
        }
        return builder.toString();
    }
}

测试的Processorjar包含一个META-INF/services/javax.annotation.processing.Processor文件,不需要指定-process选项:

  • 马文:好的
  • Gradle : 需要额外配置,假设 src/main/java 是源目录
tasks.withType(JavaCompile) {
    configure(options) {
        options.setSourcepath(project.files('src/main/java'))
    }
}
  • 命令行:添加-sourcepath选项:

javac -cp path/to/processor.jar -sourcepath path/to/sources path/to/JavaFile.java