【问题标题】:Custom Lombok annotation method not showing up in Method view自定义 Lombok 注释方法未显示在方法视图中
【发布时间】:2018-04-11 19:07:47
【问题描述】:

我最近开始涉足自定义 lombok 转换,并提出了一个简单地打印出 hello world 的 @HelloWorld 转换。我的单元测试通过了检查和运行 helloWorld 方法,但是,当我进入 intelliJ 中的方法视图时,它没有显示(与 lombok 创建的 getter 和 setter 不同)。谁能检查我有什么,看看我错过了什么?将不胜感激!

FWIW:我正在执行 javac 实现。

@Override
public void handle(AnnotationValues<HelloWorld> annotation, JCAnnotation ast, JavacNode annotationNode) {

    handleFlagUsage(annotationNode, HELLO_WORLD_FLAG_USAGE, "@HelloWorld");

    JavacNode parent = annotationNode.up();
    validateType(parent, annotationNode);
    validateAccessLevel(annotation, annotationNode);
    validateParent(parent, annotationNode);

    JCMethodDecl helloWorld = createHelloWorld(annotationNode);
    JavacHandlerUtil.injectMethod(parent, helloWorld);
}

void validateType(JavacNode parent, JavacNode annotationNode) {
    JCClassDecl typeDecl = null;
    if (parent.get() instanceof JCClassDecl) typeDecl = (JCClassDecl) parent.get();
    long modifiers = typeDecl == null ? 0 : typeDecl.mods.flags;
    boolean notAClass = (modifiers & (Flags.INTERFACE | Flags.ANNOTATION | Flags.ENUM)) != 0;

    if (notAClass) {
        annotationNode.addError("@HelloWorld is only supported on a class");
    }
}

void validateAccessLevel(AnnotationValues<HelloWorld> annotation, JavacNode annotationNode) {
    HelloWorld annotationInstance = annotation.getInstance();
    AccessLevel level = annotationInstance.value();

    if (level == AccessLevel.NONE) {
        annotationNode.addError("No access level");
    }
}

void validateParent(JavacNode parent, JavacNode annotationNode) {
    if (parent == null) {
        annotationNode.addError("Parent is null");
    }
}

JCMethodDecl createHelloWorld(JavacNode node) {

    JavacTreeMaker treeMaker = node.getTreeMaker();

    // Generate method type
    JCExpression methodType = treeMaker.Type(Javac.createVoidType(treeMaker, CTC_VOID));
    // Generate the methodName
    Name methodName = node.toName("helloWorld");
    // Generate statements
    List<JCStatement> statements = createHelloWorldBody(treeMaker, node);
    // Generate method body
    JCBlock methodBody = treeMaker.Block(0, statements);
    // Generate generic types
    List<JCTypeParameter> methodGenericParams = List.nil();
    // Generate method parameters
    List<JCVariableDecl> parameters = List.nil();
    // Generate throws clause
    List<JCExpression> throwsClauses = List.nil();

    JCExpression annotationMethodDefaultValue = null;

    return treeMaker.MethodDef(
                    treeMaker.Modifiers(Flags.PUBLIC),
                    methodName,
                    methodType,
                    methodGenericParams,
                    parameters,
                    throwsClauses,
                    methodBody,
                    annotationMethodDefaultValue);
}

List<JCStatement> createHelloWorldBody(JavacTreeMaker treeMaker, JavacNode field) {
    JCExpression printlnMethod = JavacHandlerUtil.chainDots(field, "System", "out", "println");
    List<JCExpression> printlnArgs = List.of(treeMaker.Literal("hello world"));
    return List.of(treeMaker.Exec(treeMaker.Apply(List.nil(), printlnMethod, printlnArgs)));
}

这是我的单元测试,显示运行良好

unit test

这是带有 getter 和 setter 但没有 helloWorld 方法的方法视图。

method view

【问题讨论】:

    标签: java annotations lombok


    【解决方案1】:

    根据上面提供的代码,您只接触了 Lombok 插件的 JAVA 编译器部分。 lombok 源代码的其他部分可以使其顺利地与 IDE-s 正确集成,例如 intellyJ 或 Eclipse。

    你肯定想在https://github.com/mplushnikov/lombok-intellij-plugin继续研究。

    使用 JRE 运行时的代码是由 JAVAC(gradle) 生成的。 intellyJ IDE 不使用该代码。

    如果您想在方法视图中查看方法,则必须为 intellyJ IDE 实现 注释处理器

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多