代码置换与注释处理器(Code replacement with an annotation pro

2019-06-21 12:12发布

我试图写一个注解处理器插入一个类的方法和字段...和文档是如此稀少。 我不是越来越远,我不知道如果我正确地接近它。

处理环境提供了一个Filer具有创建新的源文件和类文件的便利方法的对象。 那些做工精细,但后来我试图找出如何读取现有的源文件和所有它提供的是“的getResource”。 所以在我的处理器来实现我做这个:

@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
    try {
        for (TypeElement te : annotations) {
            for (Element element : roundEnv.getElementsAnnotatedWith(te)) {
                FileObject in_file = processingEnv.getFiler().getResource(
                    StandardLocation.SOURCE_PATH, "",
                    element.asType().toString().replace(".", "/") + ".java");

                FileObject out_file = processingEnv.getFiler().getResource(
                    StandardLocation.SOURCE_OUTPUT, "",
                    element.asType().toString().replace(".", "/") + ".java");

                //if (out_file.getLastModified() >= in_file.getLastModified()) continue;

                CharSequence data = in_file.getCharContent(false);

                data = transform(data); // run the macro processor

                JavaFileObject out_file2 = processingEnv.getFiler().createSourceFile(
                    element.asType().toString(), element);
                Writer w = out_file2.openWriter();
                w.append(data);
                w.close();
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
        processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage());
    }
    return true;
}

我的第一个困惑是我不禁觉得element.asType().toString().replace(".", "/") + ".java" (获取限定的类型名称,并将其转换成一个包,源文件路径)不是解决这个问题的好办法。 该API的其余部分是这样过来的工程,但似乎并没有成为检索原始源代码,一个方便的方法。

真正的问题是,那么编译器被自发地在输出目录的第二个源文件不高兴(“错误:重复类”),现在我卡住了。

我已经写的这个休息 - 宏词法和语法分析器和诸如此类的东西,计算一些数据并插入字段值和方法 - 但它的编译器之外的第一步工作。 除了一个事实,即原始文件不能有.java扩展(防止编译器看到他们),这很好地工作。 后来我听说,注释可以做的代码生成,我认为将是更合适的,方便的,但我不能找到它太多指导。

Answer 1:

注解处理器背后的意图是允许开发者添加新的类,而不是取代现有的类。 话虽这么说,有一个允许您将代码添加到现有的类的错误。 龙目岛项目已利用这getter和setter(除其他事项外)添加到您的编译的Java类。

我已采取的办法“替换”方法/字段是无论是从延伸或委托给输入类。 这使您可以覆盖/转移到目标类中调用。

因此,如果这是你的输入类:

InputImpl.java:

public class InputImpl implmements Input{
    public void foo(){
        System.out.println("foo");
    }
    public void bar(){
        System.out.println("bar");
    }
}

您可以生成以下为“替换”吧:

InputReplacementImpl.java:

public class InputReplacementImpl implmements Input{

    private Input delegate;

    //setup delegate....

    public void foo(){
        System.out.println("foo replacement");
    }
    public void bar(){
        delegate.bar();
    }
}

这引出了一个问题,你是如何引用InputReplacementImpl而不是InputImpl 。 您可以生成更多的代码进行包装或直接拨打预计将生成的代码的构造。

我真的不知道你的问题是什么,但我希望这揭示了你的问题的一些情况。



文章来源: Code replacement with an annotation processor