如何从javac插件正确生成错误

时间:2018-01-16 17:31:00

标签: java javac

我试图创建一个javac插件,它会为测试类做一些简单的源验证。基本上我想确保这段代码无效:

@RunWith(Parameterized.class)
class Test {
}

即。 RunWith注释不得包含Parameterized值。我能够达到检测这一点但我不确定如何正确地产生错误;我希望编译失败并出现错误。当然,我可以抛出一个例外,但这看起来并不正确。

我跟随http://www.baeldung.com/java-build-compiler-plugin的优秀例子。我的代码目前看起来像这样:

public class EnsureCorrectRunsWithPlugin implements Plugin {

  public static final String NAME = "MyPlugin";

  private Context context;

  public String getName() {
    return NAME;
  }

  public void init(JavacTask task, String... args) {
    context = ((BasicJavacTask) task).getContext();
    log("Hello from " + getName());

    task.addTaskListener(new TaskListener() {
      public void started(TaskEvent e) {
        // no-op
      }

      public void finished(TaskEvent e) {
        if (e.getKind() != TaskEvent.Kind.PARSE) {
          return;
        }

        e.getCompilationUnit().accept(new TreeScanner<Void, Void>() {
          @Override
          public Void visitAnnotation(AnnotationTree annotation, Void aVoid) {
            if (annotation.getAnnotationType().toString().equals(RunWith.class.getSimpleName())) {
              log("visiting annotation: " + annotation.getAnnotationType());

              List<? extends ExpressionTree> args = annotation.getArguments();
              for (ExpressionTree arg : args) {
                log("  value: " + arg.toString());

                if (arg.toString().equals(Parameterized.class.getSimpleName())) {
                  // Produce an error here...
                }
              }
            }
            return super.visitAnnotation(annotation, aVoid);
          }

          @Override
          public Void visitClass(ClassTree node, Void aVoid) {
            log("visiting class: " + node);
            return super.visitClass(node, aVoid);
          }
        }, null);
      }
    });
  }

  private void log(String message) {
    Log.instance(context).printRawLines(Log.WriterKind.NOTICE, message);
  }
}

感谢任何指导。

1 个答案:

答案 0 :(得分:0)

您可以使用Trees.printMessage输出错误消息。第一个参数控制它是警告还是错误,Kind.Error将产生错误。

因此,假设您将Trees隐藏到变量trees中,您可以执行以下操作:

this.trees.printMessage(Kind.Error, "Error from JavaC plugin", tree, compilationUnitTree)

第三个变量tree表示错误范围。