我知道注释处理器通常用于使用注释并对它们做出反应。但是,我有一个用例,其中这种“反应”涉及添加其他注释。这可以在处理器本身内完成吗?如果是这样,如何?
我有一个自定义注释,我想在运行时使用它来显示对象属性。我希望它们以源代码顺序出现,但反射并不能保证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)
我想在属性“另一个”之前可靠地获得“第一个”属性。
我知道我可以在我的注释中添加一个排序属性并对其进行排序,但是如果需要的话,我有很多需要更新的类,所以我正在寻找一种通用方法来实现这一点,而无需修改单个注释。
我想写一个注解处理器来检查一个方法是否只在特定的地方被调用。例如:
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 的解决方案。
我尝试将一个更大的 Maven 项目从 guice 迁移到 dagger2。注释处理是使用 m2e-apt 插件集成的。如果可以提供所有注入的依赖项,则代码生成工作正常。
如果无法提供依赖项,我只会在 eclipse 中的组件接口上遇到一般编译问题。如果我在终端上使用 maven 进行编译,则会收到指向该类的详细错误,但无法提供该错误。
有没有什么技巧可以在eclipse中显示注释处理器的这个错误?如果没有这样的错误,我就没有机会找到无法提供的类。
我一直在寻找有关此事的信息,但找不到任何有用的资源。
我需要使用注释处理生成单元测试。我生成一个可以作为单元测试的类没有问题。我不知道该怎么做是将这些生成的文件放在正确的文件夹中。
默认情况下,输出将位于build/generated/source/apt/debug文件夹中,但我需要将这些文件放在build/generated/source/apt/test. 我猜。我的意思是我在注释处理之前使用过,但我从未用于生成单元测试,所以我不知道在何处或如何定位它们的正确方法是什么。
顺便说一下,我使用的是 Android Studio 2.0。
我有一个由几个 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创建一个资源文件并写入所有生成文件的类名,但是这个资源文件也是每个模块创建的。
聚合/访问来自不同模块的生成代码的最佳方法是什么?
我正在创建一个 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 会停止收集我生成的类。
我想指示我的 Kotlin 注释处理器更改生成的类的输出目录。
我想从我的 Gradle 构建脚本中更改kapt.kotlin.generated参数。我尝试了以下方法无济于事。
不起作用,路径不会改变
kapt {
arguments {
arg("kapt.kotlin.generated", new File('path'))
}
}
不起作用,路径不会改变
kapt {
javacOptions {
option("kapt.kotlin.generated", new File('path'))
}
}
不起作用,构建时出现 NullPointerException
kapt {
javacOptions {
option("-Akapt.kotlin.generated", new File('path'))
}
}
使用字符串路径而不是文件时,所有三个结果相同。
我不知所措,任何帮助将不胜感激。
在 Kotlin 1.3.30 中添加了对增量注释处理的支持:https : //blog.jetbrains.com/kotlin/2019/04/kotlin-1-3-30-released/ 根据文档:
请注意,在当前实现中,使用任何非增量注释处理器或依赖项的 ABI 的更改(到目前为止,包括修改内部声明)将导致给定模块的非增量注释处理。
我有一个带有多个注释处理器的多模块项目。其中只有一些是增量的。据我所知,有些模块仅使用增量注释处理器。
我的问题是:有没有办法检查是否发生了增量注释处理?例如,Gradle 中是否有任何特定的控制台日志表明这一点?我想确认实际上使用了增量注释处理。
背景:我有一个注释处理器,它通过扫描控制器上的弹簧注释来构建改造接口。我已将其设置为在基于 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 客户端中没有默认值。
长话短说 - 是否有一种解决方法可以让我捕获这些默认值?