标签: annotation-processing

如何判断 TypeElement 是否间接实现接口

方法getInterfaces()TypeElement返回元素直接实现的接口。有没有一种简单的方法来查找给定的接口是否TypeElement间接实现了给定的接口?

也就是说,我有一个TypeElement,我想知道它是否来自给定的接口。

java annotation-processing

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

如何检查注释处理器中的方法参数类型?

使用纯反射,这很容易,但注释处理器世界似乎有所不同。我如何从TypeMirror返回者getParameterTypes()转到String.class

在我的注释处理器中,我想检查当前访问的方法是否具有完全相同的形式:

public boolean someName(String input)
Run Code Online (Sandbox Code Playgroud)

我可以检查原始返回类型,但String参数会出现问题:

private void processAnnotation(Element method, Messager msg) {
    final MyAnnotation ann = method.getAnnotation(MyAnnotation.class);
    if (method.getKind() != ElementKind.METHOD) {
      error("annotation only for methods", method);
    }
    Set<Modifier> modifiers = method.getModifiers();
    if(!modifiers.contains(Modifier.PUBLIC)) {
      error("annotated Element must be public", method);
    }
    if(modifiers.contains(Modifier.STATIC)) {
      error("annotated Element must not be static", method);
    }
    ExecutableType emeth = (ExecutableType)method.asType();
    if(!emeth.getReturnType().getKind().equals(TypeKind.BOOLEAN)) {
      error("annotated Element must have return type boolean", method);
    }
    if(emeth.getParameterTypes().size() != …
Run Code Online (Sandbox Code Playgroud)

java reflection annotation-processing

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

如何使用 Java8 获取 VariableElement 的类型注释和属性值?

考虑以下代码:

public class SimpleTest {

    private Map<@JSON Integer,Map<@Frozen Integer,@Enumerated(value = Enumerated.Encoding.NAME, test = "123") String>> map;
}
Run Code Online (Sandbox Code Playgroud)

使用最新的 JDK8 API 用于注释处理,如何从 VariableElement访问注释列表(@JSON@Frozen@Enumerated)及其相应的属性(@Enumerated的值和测试)?

final VariableElement mapElm = els.stream().filter(x -> x.getSimpleName().contentEquals("map")).findFirst().get();
???
???
Run Code Online (Sandbox Code Playgroud)

我尝试了很多技巧,例如mapElm.getTypeArguments().get(0)@Json Integer我从未成功获得注释@JSON ...

编辑:通过访问 JDK 的内部类,我可以访问这些注释,但它对 impl 更改非常hacky 和敏感,我想知道是否有更好的方法

public static class SimpleEntityCodecFactoryTest {

    private Map<@JSON Integer,Map<@Frozen Integer,@Enumerated(value = Enumerated.Encoding.NAME, test = "123") String>> map;
}

final TypeElement typeElement = elementUtils.getTypeElement(SimpleEntityCodecFactoryTest.class.getCanonicalName());
final List<VariableElement> els = ElementFilter.fieldsIn(typeElement.getEnclosedElements()); …
Run Code Online (Sandbox Code Playgroud)

java annotation-processing

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

Gradle 不首先处理注释处理器

我在 Gradle 构建方面遇到问题。在我的项目中,我使用自己制作的注释处理器。该处理器在最后一轮处理中生成一些源文件。在生成的文件中,有一个类(Revolver)被项目代码引用。问题是 Gradle 似乎同时启动注释处理器和编译。这会产生错误,因为生成的类尚未准备好,因此未找到。

为了验证这一点,我添加了一些调试日志记录。

Note: Starting Revolver Injector generation
Note: Starting Revolver Component Provider generation
Note: Starting Revolver Injector generation
Note: Starting Revolver Component Provider generation
E:\workspace\Android Studio\fix-in-produzione\branches\videocurriculum-client-android\app\src\main\java\co\aurasphere\videocurriculum\view\activity\NetworkBaseActivity.java:14: error: cannot find symbol
import co.aurasphere.revolver.Revolver;
                         ^
 symbol:   class Revolver
 location: package co.aurasphere.revolver
Note: Starting Revolver Injector generation
warning: File for type 'co.aurasphere.revolver.Revolver' created in the last round will not be subject to annotation processing.
Note: Starting Revolver Component Provider generation
warning: File for type 'co.aurasphere.revolver.RevolverComponentProvider' created in the last …
Run Code Online (Sandbox Code Playgroud)

android build gradle annotation-processing

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

Android注释处理器从不同模块访问带注释的类

我有一个包含 2 个模块的 Android Studio 项目:A 和 B。(这里不包括注释处理器和注释模块)

B 取决于 A。

B 是 Android 库模块,A 是简单的 Java 库模块。我的模块 B 上还有一个注释处理器。

我面临的问题是:

我想根据放置在两个模块- A 和 B 中的注释文件生成一些代码。问题来自注释处理器的工作方式 - 仅适用于源代码文件 *.java - 不适用于已编译的 *.class 文件。不幸的是,在 B 的编译过程中,注释处理器无法访问 A 中的那些源文件...

我能够想到的唯一一件事是,作为一种解决方案,即使是一个丑陋的解决方案,是将模块 A 中带注释的类的文件夹作为源集包含到模块 B 中。这样我就可以让模块 B 访问这些模块编译期间的文件。

sourceSets {
    main {
        java {
            srcDirs = ['src/main/java', '../module_A/src/main/java/path/to/annotated/classes/folder']
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这解决了问题 - 现在注释处理器可以访问两个模块中的所有注释类,但是......

不幸的是,它引入了另一个问题......模块 A 中的那些带注释的类现在被编译了两次。它们包含在模块 A 的 JAR 文件和模块 B 的 AAR 文件中。

问题 1:是否有另一种方法可以从 B 上运行的注释处理器访问模块 A 的源文件???(据我所知,答案是否定的,但检查......) …

java android annotations annotation-processing android-gradle-plugin

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

IntelliJ 不选取生成的 .class 文件

我已经实现了一个 AnnotationProcessor,它拾取带有字符串参数的类注释。字符串参数是特定于域的语言中的表达式,注释处理器将使用它来编译类文件。

我创建了一个小型测试项目来尝试一下。我看到的行为是这样的:

  1. 我可以使用maven成功构建项目
  2. 我可以从 intellij 中成功运行该项目
  3. 尽管项目在 intellij 中运行,但生成的类在编辑器中无法识别(“无法解析类 '...'”),并且 Intelli-sense 也不起作用。

我尝试查找问题并发现:

  • 正在生成的类文件正在 target/classes/package/name/KlassName.class 中创建(这是 Filer::createClassFile 方法选择的位置,但我希望它会转到某个单独的目录) 。

  • 如果我在注释处理期间创建一个java源文件(使用Filer::createSourceFile),intellij将没有问题。但是,我不能这样做,因为编译器是一个确实必须直接创建类的库。

我对解决方案可能是什么样子有两种猜测:

  1. 此问题可能源于 intellij 在编辑器窗口中进行类型检查时未查看目标/类内部。
  2. 类文件应该在单独的目录中生成。如果是这样,解决这个问题的设置是什么?

我使用intellij IDEA 2016.2.1和intellij IDEA 2017.2 EAP重现了这个问题。

java compiler-construction intellij-idea maven annotation-processing

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

Java注释处理器:检查TypeMirror是否实现特定的通用接口

我正在编写注释处理器,我需要检查特定是否TypeMirror实现特定接口。Java 注解处理器:检查 TypeMirror 是否实现特定接口这一问题为非泛型接口提供了答案。但它不适用于通用接口,例如String正在实现Comparable<String>- 并且使用 isAssignable 的代码不起作用。

此代码按预期工作:

TypeMirror tm = elementUtil.getTypeElement("java.lang.String").asType();
TypeMirror serializable = elementUtil.getTypeElement("java.io.Serializable").asType();
boolean isSerializable = typeUtil.isAssignable(tm, serializable);
//here isSerializable is true
Run Code Online (Sandbox Code Playgroud)

但这段代码没有:

TypeMirror tm = elementUtil.getTypeElement("java.lang.String").asType();
TypeMirror comparable = elementUtil.getTypeElement("java.lang.Comparable").asType();
boolean isComparable = typeUtil.isAssignable(tm, comparable);
//here isComparable is false
Run Code Online (Sandbox Code Playgroud)

我认为原因是,“可比较”的 TypeElement 是用 String 作为通用参数定义的,但我不知道如何解决它。

java generics annotations annotation-processing

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

如何从注释处理器中的嵌套注释读取 Class[] 值

我正在尝试使用Java注释处理工具生成一些代码,我有嵌套注释,其中父注释值是子注释的数组,子注释值是类的数组。

注释:

public @interface ParentAnnotation {
    ChildAnnotation[] value();
}
public @interface ChildAnnotation {
    Class<?>[] value();
}
Run Code Online (Sandbox Code Playgroud)

用法:

@ParentAnnotation(
{
      @ChildAnnotation({Foo.class, Bar.class}),
      @ChildAnnotation({Goo.class, Doo.class})
})
public class Sample{
}
Run Code Online (Sandbox Code Playgroud)

使用我的子类型调用value()注释Processor失败,并出现以下异常:

Error:java: error while creating source file javax.lang.model.type.MirroredTypeException: Attempt to access Class object for TypeMirror org.dominokit.samples.layout.shared.extension.LayoutEvent
    at com.sun.tools.javac.model.AnnotationProxyMaker$MirroredTypeExceptionProxy.generateException(AnnotationProxyMaker.java:308)
    at sun.reflect.annotation.AnnotationInvocationHandler.invoke(AnnotationInvocationHandler.java:84)
    at com.sun.proxy.$Proxy28.value(Unknown Source)
    at org.dominokit.domino.apt.client.processors.module.client.presenters.PresenterProxySourceWriter.generateFireActivationEvent(PresenterProxySourceWriter.java:238)
    at org.dominokit.domino.apt.client.processors.module.client.presenters.PresenterProxySourceWriter.asTypeBuilder(PresenterProxySourceWriter.java:64)
    at org.dominokit.domino.apt.client.processors.module.client.presenters.PresenterProxyProcessingStep.generateProxy(PresenterProxyProcessingStep.java:66)
    at org.dominokit.domino.apt.client.processors.module.client.presenters.PresenterProxyProcessingStep.process(PresenterProxyProcessingStep.java:53)
    at org.dominokit.domino.apt.client.processors.module.client.presenters.PresenterProxyProcessor.process(PresenterProxyProcessor.java:61)
    at com.sun.tools.javac.processing.JavacProcessingEnvironment.callProcessor(JavacProcessingEnvironment.java:794)
    at com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:705)
    at com.sun.tools.javac.processing.JavacProcessingEnvironment.access$1800(JavacProcessingEnvironment.java:91)
    at com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1035)
    at com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1176)
    at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1170)
    at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:856)
    at …
Run Code Online (Sandbox Code Playgroud)

java annotation-processing annotation-processor

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

如何在 IntelliJ 增量构建中获取带有注释的所有元素?

我正在编写一个注释处理器,它需要收集当前模块中带有特定注释的所有类,并编写一个引用每个类的类。

为了简化一点,给出这些源文件:

src/main/java/org/example/A.java
@Annotation
class A {}
Run Code Online (Sandbox Code Playgroud) src/main/java/org/example/B.java
@Annotation
class B {}
Run Code Online (Sandbox Code Playgroud)

我想生成一个类:

目标/生成源/org/example/Module.java
class Module {
  String getModuleClasses() {
    return Arrays.asList(
      "org.example.A",
      "org.example.B"
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

这在 Maven 中有效,但是当我修改 class 时A,IntelliJ 为我的注释处理器提供了 aRoundEnvironment作为A单个根元素。

我知道 Gradle 通过将所有与注释匹配的源的假值传递给注释处理器来支持聚合注释处理器的RoundEnvironment增量编译,但 IntelliJ 似乎没有任何类似的东西。(也许 Gradle 项目除外?)

当 IntelliJ 仅编译 class 时,找到这两个类的最佳方法是什么A

也许注释器可以保留带注释的类的列表:在第一轮中从资源文件中读取列表,在每一轮中从列表中删除根元素并添加到带注释的列表元素中,然后将列表写回资源文件进入最后一轮?

java intellij-idea annotation-processing

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

Resource IDs will be non final in AGP 7.0

I have an annotation processing library that generates RecyclerView adapters in compile time.

I'm currently rebuilding it from the ground up with many changes and improvements, but while testing, I received a warning stating:

Resource IDs will be non-final in Android Gradle Plugin version 7.0, avoid using them as annotation attributes

This is a problem because it means I won't be able to use R.layout variables in annotations.

I currently use it to associate the layout file's integer value with …

android annotation-processing android-gradle-plugin

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