标签: annotation-processing

使用 Java Annotation Processor 添加注解

我知道注释处理器通常用于使用注释并对它们做出反应。但是,我有一个用例,其中这种“反应”涉及添加其他注释。这可以在处理器本身内完成吗?如果是这样,如何?

java annotations annotation-processing

5
推荐指数
1
解决办法
1333
查看次数

如何按源顺序获取方法

我有一个自定义注释,我想在运行时使用它来显示对象属性。我希望它们以源代码顺序出现,但反射并不能保证Class.getMethods().

有没有办法通过反射或通过注释处理来按源顺序获取方法(如果涉及多个继承级别,至少每个类)?

举个例子,假设我有一个界面 Property

package test;

public @interface Property {
    public String name();
}
Run Code Online (Sandbox Code Playgroud)

和一个使用该注释的类

package test;

public class MyObject {
    @Property(name = "First")
    public void getFirst() {}

    @Property(name = "Another")
    public void getAnother() {}
}
Run Code Online (Sandbox Code Playgroud)

我想在属性“另一个”之前可靠地获得“第一个”属性。

我知道我可以在我的注释中添加一个排序属性并对其进行排序,但是如果需要的话,我有很多需要更新的类,所以我正在寻找一种通用方法来实现这一点,而无需修改单个注释。

java annotations annotation-processing

5
推荐指数
1
解决办法
1303
查看次数

解析注解处理器中的方法调用

我想写一个注解处理器来检查一个方法是否只在特定的地方被调用。例如:

interface Command {
    @MustOnlyBeCalledByWorker
    void execute();
}

class Worker {
    void work(Command cmd) {
        cmd.execute(); // This is ok for the annotation processor
    }
}
class Hacker {
    void work(Command cmd) {
        cmd.execute(); // annotation processor gives an error
    }
}
Run Code Online (Sandbox Code Playgroud)

我已经有一个注释处理器,@SupportedAnnotationTypes("*")它使用 Compiler Tree API 来获取所有MethodInvocationTrees。

我认为从那里,我可以获得被调用方法的声明。

现在我可以轻松获取方法名称和参数表达式。

但是说我也想区分execute()具有相同数量参数的重载方法。我需要自己处理整个重载决议吗?我认为这也意味着手动解析所有参数的静态类型,在某些情况下甚至是其他方法的类型参数。

所以这是我的问题:如何获得潜在重载方法的正确声明?也许我能以某种方式把它弄出来JavacTask?

我正在使用 IntelliJ IDEA 14 和 Oracle 的 Java 8 编译器。目前支持语言级别 7 就足够了,但首选支持 Java 8 的解决方案。

java annotation-processing java-8

5
推荐指数
0
解决办法
781
查看次数

Dagger2 Maven Eclipse 集成

我尝试将一个更大的 Maven 项目从 guice 迁移到 dagger2。注释处理是使用 m2e-apt 插件集成的。如果可以提供所有注入的依赖项,则代码生成工作正常。

如果无法提供依赖项,我只会在 eclipse 中的组件接口上遇到一般编译问题。如果我在终端上使用 maven 进行编译,则会收到指向该类的详细错误,但无法提供该错误。

有没有什么技巧可以在eclipse中显示注释处理器的这个错误?如果没有这样的错误,我就没有机会找到无法提供的类。

eclipse maven annotation-processing dagger dagger-2

5
推荐指数
0
解决办法
164
查看次数

使用注解处理生成单元测试

我一直在寻找有关此事的信息,但找不到任何有用的资源。

我需要使用注释处理生成单元测试。我生成一个可以作为单元测试的类没有问题。我不知道该怎么做是将这些生成的文件放在正确的文件夹中。

默认情况下,输出将位于build/generated/source/apt/debug文件夹中,但我需要将这些文件放在build/generated/source/apt/test. 我猜。我的意思是我在注释处理之前使用过,但我从未用于生成单元测试,所以我不知道在何处或如何定位它们的正确方法是什么。

顺便说一下,我使用的是 Android Studio 2.0。

java junit annotation-processing android-studio

5
推荐指数
1
解决办法
1173
查看次数

来自不同降压模块的注释处理器的汇总输出

我有一个由几个 BUCK 模块组成的项目。每个模块使用相同的注释处理器为每个注释类生成单个文件。为简单起见,对于每个带注释的类:

package com.myproject.module1;

@Marker
public class SomeFoo {
  // ... code ...
}
Run Code Online (Sandbox Code Playgroud)

将在同一个包中生成一个类:

package com.myproject.module1;

@Generated
public class SomeFoo$$Marker {
  // ... generated code ...
}
Run Code Online (Sandbox Code Playgroud)

假设我有两个这样的模块:module1和module2

最后,我有一个 module3依赖于上述两个模块的。

该模块包含另一个注释:

package com.myproject.module3;

@MarkerCollector
public class Bar {
}
Run Code Online (Sandbox Code Playgroud)

我正在尝试使用相同的注释处理器(也可以是一个单独的处理器)来生成一个引用所有先前生成的文件的类(由于类标记为@Marker.

问题是注释处理器分别为每个模块运行,当在模块 3 中运行时,注释处理器不会“看到”其他模块中生成的文件。

我尝试使用注释处理器Filer创建一个资源文件并写入所有生成文件的类名,但是这个资源文件也是每个模块创建的。

聚合/访问来自不同模块的生成代码的最佳方法是什么?

java annotations annotation-processing buck

5
推荐指数
1
解决办法
373
查看次数

在 Annotation Processor 中指定生成类的路径

我正在创建一个 Android 应用程序。我使用 AbstractProcessor 从 Annotated 类和 Velocity 模板生成我自己的类。

这是生成源文件的方法。

  private void createSourceFile(String className, String packageName, 
                  VelocityContext context, Template template) throws IOException {

     final JavaFileObject javaFileObject = 
         processingEnv.getFiler().createSourceFile(packageName + "." + className);

     processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "creating file: " + javaFileObject.toUri());
     final Writer writer = javaFileObject.openWriter();
     if (DEBUGGING) {
        processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "applying velocity template: " + template.getName());
     }
     template.merge(context, writer);
     writer.close();
  }
Run Code Online (Sandbox Code Playgroud)

我的问题是

我可以为生成的类指定一个目录吗?

现在它们在build/source/apt文件夹中,我想在另一个源文件夹中生成它们,以使它们在开发过程中可见。现在我DexFile用来查找这些类,但是在带有 InstanseRun 的新 AndroidStudio 中,或者当我使用 Kotlin 或任何其他随机情况时,DexFile 会停止收集我生成的类。

java android velocity annotations annotation-processing

5
推荐指数
0
解决办法
413
查看次数

更改 KAPT 类生成路径

我想指示我的 Kotlin 注释处理器更改生成的类的输出目录。

我想从我的 Gradle 构建脚本中更改kapt.kotlin.generated参数。我尝试了以下方法无济于事。

  1. 不起作用,路径不会改变

    kapt { arguments { arg("kapt.kotlin.generated", new File('path')) } }

  2. 不起作用,路径不会改变

    kapt { javacOptions { option("kapt.kotlin.generated", new File('path')) } }

  3. 不起作用,构建时出现 NullPointerException

    kapt { javacOptions { option("-Akapt.kotlin.generated", new File('path')) } }

使用字符串路径而不是文件时,所有三个结果相同。

我不知所措,任何帮助将不胜感激。

annotations gradle annotation-processing kotlin kapt

5
推荐指数
1
解决办法
394
查看次数

检查 kapt 是否使用增量注释处理

在 Kotlin 1.3.30 中添加了对增量注释处理的支持:https : //blog.jetbrains.com/kotlin/2019/04/kotlin-1-3-30-released/ 根据文档:

请注意,在当前实现中,使用任何非增量注释处理器或依赖项的 ABI 的更改(到目前为止,包括修改内部声明)将导致给定模块的非增量注释处理。

我有一个带有多个注释处理器的多模块项目。其中只有一些是增量的。据我所知,有些模块仅使用增量注释处理器。

我的问题是:有没有办法检查是否发生了增量注释处理?例如,Gradle 中是否有任何特定的控制台日志表明这一点?我想确认实际上使用了增量注释处理。

android gradle annotation-processing kotlin kapt

5
推荐指数
1
解决办法
6131
查看次数

在注解处理阶段获取kotlin fun参数的默认值

背景:我有一个注释处理器,它通过扫描控制器上的弹簧注释来构建改造接口。我已将其设置为在基于 kotlin 或基于 Java 的 Spring 应用程序中工作,并且它可以生成 kotlin 或 Java 改造客户端接口。

问题:当针对基于 kotlin 的 spring 应用程序运行它时,有没有办法在控制器函数上获取默认值,无论是反射还是通过其他方式?

例如控制器功能看起来像

@RequestMapping("/foo")
fun getSomething(@RequestParameter foo: String = "bar") {
...

}
Run Code Online (Sandbox Code Playgroud)

我希望能够生成一个看起来像的改造接口方法

fun getSomething(@Header foo: String = "bar")
Run Code Online (Sandbox Code Playgroud)

我知道引擎盖下的编译器实际上为 jvm 创建了多个覆盖方法:https : //discuss.kotlinlang.org/t/retrieve-default-parameter-value-via-reflection/7314

但我想知道是否有办法在注释处理阶段捕获这些默认值,或者我是否只需要在生成的 kotlin 客户端中没有默认值。

长话短说 - 是否有一种解决方法可以让我捕获这些默认值?

annotation-processing kotlin

5
推荐指数
1
解决办法
998
查看次数