简体   繁体   English

使用注释处理器向类型添加属性

[英]Adding an attribute to a type with an annotation processor

I am trying to write an annotation processor that is supposed to run during compilation. 我正在尝试编写一个应该在编译期间运行的注释处理器。 It will first check, if a specific field (int id) will exists in a given class (after compilation) and if not, is supposed to add this field (if possible with an initial value of -1. I think I have the TypeElement which is to be edited. Can I for example insert a string in a line within the class file? 如果特定字段(int id)将存在于给定的类中(编译后),它将首先检查是否应该添加此字段(如果可能的话,初始值为-1。我认为我有TypeElement哪个是要编辑的。例如我可以在类文件中的一行中插入一个字符串吗?

processingEnd.getFilter().getResource(...) seems to give me the file, but I am not sure how to do this and specify the parameters correctly. processingEnd.getFilter().getResource(...)似乎给了我文件,但我不知道如何做到这一点并正确指定参数。 I can get a read and write stream, but I am not entirely sure if i can simply 'insert' what I want at some line within the class. 我可以得到一个读写流,但我不能完全确定我是否可以简单地在类中的某些行“插入”我想要的内容。

@Override
public boolean process(Set<? extends TypeElement> set,
                       RoundEnvironment round) {
    if (!set.contains(DBStorable.class)) {
        return false;
    }
    Set<? extends Element> elements =
            round.getElementsAnnotatedWith(DBStorable.class);
    for (Element element : elements) {
        if (element.getKind() == ElementKind.CLASS) {
            // edit processed class to include id field.
            TypeElement processedType = (TypeElement) element;
            boolean found = false;
            for (Element subElement : processedType.getEnclosedElements()) {
                if (subElement.getKind() == ElementKind.FIELD
                        && subElement.getSimpleName().equals("id")) {
                    found = true;
                    break;
                }
            }
            if (!found) {
                // This is where I don't get on...
                JavaFileObject javaFile = processingEnv.getFiler().getResource(
                        Location, // <- not sure how to get this.
                        processingEnv.getElementUtils().getPackageOf(processedType),
                        processedType.getSimpleName()); // <- is this the right value?

                // ... tbc
            }
        }
    }
    // TODO Auto-generated method stub
    return true;
}

You are not supposed to change any classes during processing. 您不应该在处理过程中更改任何类。 Check the documentation of the Filer class: 查看Filer类的文档:

In general, processors must not knowingly attempt to overwrite existing files that were not generated by some processor. 通常,处理器不得故意尝试覆盖某些处理器未生成的现有文件。

You can however create subclasses that override the existing methods or add new properties: 但是,您可以创建覆盖现有方法或添加新属性的子类:

Note that some of the effect of overwriting a file can be achieved by using a decorator-style pattern. 请注意,通过使用装饰器样式模式可以实现覆盖文件的一些效果。 Instead of modifying a class directly, the class is designed so that either its superclass is generated by annotation processing or subclasses of the class are generated by annotation processing. 不是直接修改类,而是设计类,以便通过注释处理生成其超类,或者通过注释处理生成类的子类。 If the subclasses are generated, the parent class may be designed to use factories instead of public constructors so that only subclass instances would be presented to clients of the parent class. 如果生成了子类,则可以将父类设计为使用工厂而不是公共构造函数,以便仅将子类实例呈现给父类的客户端。

If that is not an option for you, keep looking for other tools or workarounds. 如果这不是您的选择,请继续寻找其他工具或解决方法。 For example, there may be be some solutions for you in this question: Plugging in to Java compilers 例如,在这个问题中可能会有一些解决方案: 插入Java编译器

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM