1
@GenerateInterface class A {}

@GenerateInterface class B {
  void setA(IA a) {}
}

我的注释处理器应该生成这些接口:

interface IA {}

interface IB {
  void setA(IA a);
}

B使用正确的导入语句编译得很好。IB但是,错过了参数IA a。我使用javapoet生成接口。编译方法参数的代码:

method.getParameters().forEach(p -> {
  ParameterSpec.Builder parameterBuilder = ParameterSpec.builder(
      TypeName.get(p.asType()),
      p.getSimpleName().toString(),
      p.getModifiers().toArray(new Modifier[p.getModifiers().size()]));
  p.getAnnotationMirrors().stream()
      .map(AnnotationSpec::get)
      .forEach(parameterBuilder::addAnnotation);
  methodBuilder.addParameter(parameterBuilder.build());
});

method是一个ExecutableElementp.asType()仅包含简单的名称IA。此时,IA可能尚未生成,因此没有可用的完全限定名称。

目前,我为每个带注释的类一个一个地生成接口。据我了解,我首先需要一个所有带注释的类及其派生接口名称的列表。然后,当我遇到尚未生成类型的参数时,从上面的列表中获取完全限定名称以插入正确的导入语句。

有没有聪明的方法来做到这一点?我至少可以将尚未编译的类型与已编译的类型区分开来吗?

编辑:完整代码

4

1 回答 1

1

我正在为我的Kripton 持久性库开发一个注释处理器,我有一个类似的问题。我的问题类似但不一样:在我生成的类中,我引用了在同一轮中生成的其他生成类。

我应用的解决方案只是手动“生成” TypeName。在我的注释处理器中,我使用了一个特定的类,你可以在这里找到它的来源。

Kripton 将为 Android 平台生成实现基于 SQLite 的 DAO 模式的类。当我生成我的数据源时,我需要引用将在同一轮中生成的 DAO 类。为此并避免同样的问题,我生成了关联的 TypeName。您可以在BindDataSourceBuilderbuildDataSource类的方法上看到这一点。

希望这些信息对您仍然有用。

于 2018-07-09T00:36:05.850 回答