Search in sources :

Example 66 with JCAnnotation

use of com.sun.tools.javac.tree.JCTree.JCAnnotation in project lombok by rzwitserloot.

the class HandleGetter method createGetter.

public JCMethodDecl createGetter(long access, JavacNode field, JavacTreeMaker treeMaker, JavacNode source, boolean lazy, List<JCAnnotation> onMethod) {
    JCVariableDecl fieldNode = (JCVariableDecl) field.get();
    // Remember the type; lazy will change it
    JCExpression methodType = cloneType(treeMaker, copyType(treeMaker, fieldNode), source);
    AnnotationValues<Accessors> accessors = JavacHandlerUtil.getAccessorsForField(field);
    // Generate the methodName; lazy will change the field type
    Name methodName = field.toName(toGetterName(field, accessors));
    boolean makeFinal = shouldMakeFinal(field, accessors);
    List<JCStatement> statements;
    JCTree toClearOfMarkers = null;
    int[] methodArgPos = null;
    boolean addSuppressWarningsUnchecked = false;
    if (lazy && !inNetbeansEditor(field)) {
        toClearOfMarkers = fieldNode.init;
        if (toClearOfMarkers instanceof JCMethodInvocation) {
            List<JCExpression> args = ((JCMethodInvocation) toClearOfMarkers).args;
            methodArgPos = new int[args.length()];
            for (int i = 0; i < methodArgPos.length; i++) {
                methodArgPos[i] = args.get(i).pos;
            }
        }
        statements = createLazyGetterBody(treeMaker, field, source);
        addSuppressWarningsUnchecked = LombokOptionsFactory.getDelombokOptions(field.getContext()).getFormatPreferences().generateSuppressWarnings();
    } else {
        statements = createSimpleGetterBody(treeMaker, field);
    }
    JCBlock methodBody = treeMaker.Block(0, statements);
    List<JCTypeParameter> methodGenericParams = List.nil();
    List<JCVariableDecl> parameters = List.nil();
    List<JCExpression> throwsClauses = List.nil();
    JCExpression annotationMethodDefaultValue = null;
    List<JCAnnotation> copyableAnnotations = findCopyableAnnotations(field);
    List<JCAnnotation> delegates = findDelegatesAndRemoveFromField(field);
    List<JCAnnotation> annsOnMethod = copyAnnotations(onMethod).appendList(copyableAnnotations);
    if (field.isFinal()) {
        if (getCheckerFrameworkVersion(field).generatePure())
            annsOnMethod = annsOnMethod.prepend(treeMaker.Annotation(genTypeRef(field, CheckerFrameworkVersion.NAME__PURE), List.<JCExpression>nil()));
    } else {
        if (getCheckerFrameworkVersion(field).generateSideEffectFree())
            annsOnMethod = annsOnMethod.prepend(treeMaker.Annotation(genTypeRef(field, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE), List.<JCExpression>nil()));
    }
    if (isFieldDeprecated(field))
        annsOnMethod = annsOnMethod.prepend(treeMaker.Annotation(genJavaLangTypeRef(field, "Deprecated"), List.<JCExpression>nil()));
    if (makeFinal)
        access |= Flags.FINAL;
    JCMethodDecl decl = recursiveSetGeneratedBy(treeMaker.MethodDef(treeMaker.Modifiers(access, annsOnMethod), methodName, methodType, methodGenericParams, parameters, throwsClauses, methodBody, annotationMethodDefaultValue), source);
    if (toClearOfMarkers != null)
        recursiveSetGeneratedBy(toClearOfMarkers, null);
    if (methodArgPos != null) {
        for (int i = 0; i < methodArgPos.length; i++) {
            ((JCMethodInvocation) toClearOfMarkers).args.get(i).pos = methodArgPos[i];
        }
    }
    decl.mods.annotations = decl.mods.annotations.appendList(delegates);
    if (addSuppressWarningsUnchecked) {
        ListBuffer<JCExpression> suppressions = new ListBuffer<JCExpression>();
        if (!Boolean.FALSE.equals(field.getAst().readConfiguration(ConfigurationKeys.ADD_SUPPRESSWARNINGS_ANNOTATIONS))) {
            suppressions.append(treeMaker.Literal("all"));
        }
        suppressions.append(treeMaker.Literal("unchecked"));
        addAnnotation(decl.mods, field, source, "java.lang.SuppressWarnings", treeMaker.NewArray(null, List.<JCExpression>nil(), suppressions.toList()));
    }
    copyJavadoc(field, decl, CopyJavadoc.GETTER);
    return decl;
}
Also used : JCBlock(com.sun.tools.javac.tree.JCTree.JCBlock) JCMethodDecl(com.sun.tools.javac.tree.JCTree.JCMethodDecl) ListBuffer(com.sun.tools.javac.util.ListBuffer) JCTree(com.sun.tools.javac.tree.JCTree) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement) Accessors(lombok.experimental.Accessors) JCVariableDecl(com.sun.tools.javac.tree.JCTree.JCVariableDecl) Name(com.sun.tools.javac.util.Name) JCTypeParameter(com.sun.tools.javac.tree.JCTree.JCTypeParameter) JCMethodInvocation(com.sun.tools.javac.tree.JCTree.JCMethodInvocation) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCAnnotation(com.sun.tools.javac.tree.JCTree.JCAnnotation)

Example 67 with JCAnnotation

use of com.sun.tools.javac.tree.JCTree.JCAnnotation in project lombok by rzwitserloot.

the class HandleGetter method handle.

@Override
public void handle(AnnotationValues<Getter> annotation, JCAnnotation ast, JavacNode annotationNode) {
    handleFlagUsage(annotationNode, ConfigurationKeys.GETTER_FLAG_USAGE, "@Getter");
    Collection<JavacNode> fields = annotationNode.upFromAnnotationToFields();
    deleteAnnotationIfNeccessary(annotationNode, Getter.class);
    deleteImportFromCompilationUnit(annotationNode, "lombok.AccessLevel");
    JavacNode node = annotationNode.up();
    Getter annotationInstance = annotation.getInstance();
    AccessLevel level = annotationInstance.value();
    boolean lazy = annotationInstance.lazy();
    if (lazy)
        handleFlagUsage(annotationNode, ConfigurationKeys.GETTER_LAZY_FLAG_USAGE, "@Getter(lazy=true)");
    if (level == AccessLevel.NONE) {
        if (lazy)
            annotationNode.addWarning("'lazy' does not work with AccessLevel.NONE.");
        return;
    }
    if (node == null)
        return;
    List<JCAnnotation> onMethod = unboxAndRemoveAnnotationParameter(ast, "onMethod", "@Getter(onMethod", annotationNode);
    switch(node.getKind()) {
        case FIELD:
            createGetterForFields(level, fields, annotationNode, true, lazy, onMethod);
            break;
        case TYPE:
            if (lazy)
                annotationNode.addError("'lazy' is not supported for @Getter on a type.");
            generateGetterForType(node, annotationNode, level, false, onMethod);
            break;
    }
}
Also used : JavacNode(lombok.javac.JavacNode) Getter(lombok.Getter) AccessLevel(lombok.AccessLevel) JCAnnotation(com.sun.tools.javac.tree.JCTree.JCAnnotation)

Example 68 with JCAnnotation

use of com.sun.tools.javac.tree.JCTree.JCAnnotation in project lombok by rzwitserloot.

the class HandleGetter method findDelegatesAndRemoveFromField.

public static List<JCAnnotation> findDelegatesAndRemoveFromField(JavacNode field) {
    JCVariableDecl fieldNode = (JCVariableDecl) field.get();
    List<JCAnnotation> delegates = List.nil();
    for (JCAnnotation annotation : fieldNode.mods.annotations) {
        if (typeMatches(Delegate.class, field, annotation.annotationType)) {
            delegates = delegates.append(annotation);
        }
    }
    if (!delegates.isEmpty()) {
        ListBuffer<JCAnnotation> withoutDelegates = new ListBuffer<JCAnnotation>();
        for (JCAnnotation annotation : fieldNode.mods.annotations) {
            if (!delegates.contains(annotation)) {
                withoutDelegates.append(annotation);
            }
        }
        fieldNode.mods.annotations = withoutDelegates.toList();
        field.rebuild();
    }
    return delegates;
}
Also used : ListBuffer(com.sun.tools.javac.util.ListBuffer) JCVariableDecl(com.sun.tools.javac.tree.JCTree.JCVariableDecl) JCAnnotation(com.sun.tools.javac.tree.JCTree.JCAnnotation)

Example 69 with JCAnnotation

use of com.sun.tools.javac.tree.JCTree.JCAnnotation in project lombok by rzwitserloot.

the class HandleJacksonized method handle.

@Override
public void handle(AnnotationValues<Jacksonized> annotation, JCAnnotation ast, JavacNode annotationNode) {
    handleExperimentalFlagUsage(annotationNode, ConfigurationKeys.JACKSONIZED_FLAG_USAGE, "@Jacksonized");
    JavacNode annotatedNode = annotationNode.up();
    deleteAnnotationIfNeccessary(annotationNode, Jacksonized.class);
    JavacNode tdNode;
    if (annotatedNode.getKind() != Kind.TYPE)
        // @Jacksonized on a constructor or a static factory method.
        tdNode = annotatedNode.up();
    else
        // @Jacksonized on the class.
        tdNode = annotatedNode;
    JCClassDecl td = (JCClassDecl) tdNode.get();
    JavacNode builderAnnotationNode = findAnnotation(Builder.class, annotatedNode);
    JavacNode superBuilderAnnotationNode = findAnnotation(SuperBuilder.class, annotatedNode);
    if (builderAnnotationNode == null && superBuilderAnnotationNode == null) {
        annotationNode.addWarning("@Jacksonized requires @Builder or @SuperBuilder for it to mean anything.");
        return;
    }
    if (builderAnnotationNode != null && superBuilderAnnotationNode != null) {
        annotationNode.addError("@Jacksonized cannot process both @Builder and @SuperBuilder on the same class.");
        return;
    }
    boolean isAbstract = (td.mods.flags & Flags.ABSTRACT) != 0;
    if (isAbstract) {
        annotationNode.addError("Builders on abstract classes cannot be @Jacksonized (the builder would never be used).");
        return;
    }
    AnnotationValues<Builder> builderAnnotation = builderAnnotationNode != null ? createAnnotation(Builder.class, builderAnnotationNode) : null;
    AnnotationValues<SuperBuilder> superBuilderAnnotation = superBuilderAnnotationNode != null ? createAnnotation(SuperBuilder.class, superBuilderAnnotationNode) : null;
    String setPrefix = builderAnnotation != null ? builderAnnotation.getInstance().setterPrefix() : superBuilderAnnotation.getInstance().setterPrefix();
    String buildMethodName = builderAnnotation != null ? builderAnnotation.getInstance().buildMethodName() : superBuilderAnnotation.getInstance().buildMethodName();
    JavacTreeMaker maker = annotatedNode.getTreeMaker();
    // Now lets find the generated builder class.
    String builderClassName = getBuilderClassName(annotationNode, annotatedNode, td, builderAnnotation, maker);
    JCClassDecl builderClass = null;
    for (JCTree member : td.getMembers()) {
        if (member instanceof JCClassDecl && ((JCClassDecl) member).getSimpleName().contentEquals(builderClassName)) {
            builderClass = (JCClassDecl) member;
            break;
        }
    }
    if (builderClass == null) {
        annotationNode.addError("Could not find @(Super)Builder's generated builder class for @Jacksonized processing. If there are other compiler errors, fix them first.");
        return;
    }
    // Insert @JsonDeserialize on annotated class.
    if (hasAnnotation("com.fasterxml.jackson.databind.annotation.JsonDeserialize", tdNode)) {
        annotationNode.addError("@JsonDeserialize already exists on class. Either delete @JsonDeserialize, or remove @Jacksonized and manually configure Jackson.");
        return;
    }
    JCExpression jsonDeserializeType = chainDots(annotatedNode, "com", "fasterxml", "jackson", "databind", "annotation", "JsonDeserialize");
    JCExpression builderClassExpression = namePlusTypeParamsToTypeReference(maker, tdNode, annotationNode.toName(builderClassName), false, List.<JCTypeParameter>nil());
    JCFieldAccess builderClassReference = maker.Select(builderClassExpression, annotatedNode.toName("class"));
    JCExpression assign = maker.Assign(maker.Ident(annotationNode.toName("builder")), builderClassReference);
    JCAnnotation annotationJsonDeserialize = maker.Annotation(jsonDeserializeType, List.of(assign));
    recursiveSetGeneratedBy(annotationJsonDeserialize, annotationNode);
    td.mods.annotations = td.mods.annotations.append(annotationJsonDeserialize);
    // Copy annotations from the class to the builder class.
    List<JCAnnotation> copyableAnnotations = findJacksonAnnotationsOnClass(tdNode);
    List<JCAnnotation> copiedAnnotations = copyAnnotations(copyableAnnotations);
    for (JCAnnotation anno : copiedAnnotations) {
        recursiveSetGeneratedBy(anno, annotationNode);
    }
    builderClass.mods.annotations = builderClass.mods.annotations.appendList(copiedAnnotations);
    // Insert @JsonPOJOBuilder on the builder class.
    JCExpression jsonPOJOBuilderType = chainDots(annotatedNode, "com", "fasterxml", "jackson", "databind", "annotation", "JsonPOJOBuilder");
    JCExpression withPrefixExpr = maker.Assign(maker.Ident(annotationNode.toName("withPrefix")), maker.Literal(setPrefix));
    JCExpression buildMethodNameExpr = maker.Assign(maker.Ident(annotationNode.toName("buildMethodName")), maker.Literal(buildMethodName));
    JCAnnotation annotationJsonPOJOBuilder = maker.Annotation(jsonPOJOBuilderType, List.of(withPrefixExpr, buildMethodNameExpr));
    recursiveSetGeneratedBy(annotationJsonPOJOBuilder, annotatedNode);
    builderClass.mods.annotations = builderClass.mods.annotations.append(annotationJsonPOJOBuilder);
    // @SuperBuilder? Make it package-private!
    if (superBuilderAnnotationNode != null)
        builderClass.mods.flags = builderClass.mods.flags & ~Flags.PRIVATE;
}
Also used : JCClassDecl(com.sun.tools.javac.tree.JCTree.JCClassDecl) SuperBuilder(lombok.experimental.SuperBuilder) JavacTreeMaker(lombok.javac.JavacTreeMaker) JCFieldAccess(com.sun.tools.javac.tree.JCTree.JCFieldAccess) SuperBuilder(lombok.experimental.SuperBuilder) Builder(lombok.Builder) JCTree(com.sun.tools.javac.tree.JCTree) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JavacNode(lombok.javac.JavacNode) JCAnnotation(com.sun.tools.javac.tree.JCTree.JCAnnotation)

Example 70 with JCAnnotation

use of com.sun.tools.javac.tree.JCTree.JCAnnotation in project lombok by rzwitserloot.

the class HandleSetter method handle.

@Override
public void handle(AnnotationValues<Setter> annotation, JCAnnotation ast, JavacNode annotationNode) {
    handleFlagUsage(annotationNode, ConfigurationKeys.SETTER_FLAG_USAGE, "@Setter");
    Collection<JavacNode> fields = annotationNode.upFromAnnotationToFields();
    deleteAnnotationIfNeccessary(annotationNode, Setter.class);
    deleteImportFromCompilationUnit(annotationNode, "lombok.AccessLevel");
    JavacNode node = annotationNode.up();
    AccessLevel level = annotation.getInstance().value();
    if (level == AccessLevel.NONE || node == null)
        return;
    List<JCAnnotation> onMethod = unboxAndRemoveAnnotationParameter(ast, "onMethod", "@Setter(onMethod", annotationNode);
    List<JCAnnotation> onParam = unboxAndRemoveAnnotationParameter(ast, "onParam", "@Setter(onParam", annotationNode);
    switch(node.getKind()) {
        case FIELD:
            createSetterForFields(level, fields, annotationNode, true, onMethod, onParam);
            break;
        case TYPE:
            generateSetterForType(node, annotationNode, level, false, onMethod, onParam);
            break;
    }
}
Also used : JavacNode(lombok.javac.JavacNode) AccessLevel(lombok.AccessLevel) JCAnnotation(com.sun.tools.javac.tree.JCTree.JCAnnotation)

Aggregations

JCAnnotation (com.sun.tools.javac.tree.JCTree.JCAnnotation)93 JCExpression (com.sun.tools.javac.tree.JCTree.JCExpression)64 Name (com.sun.tools.javac.util.Name)35 ListBuffer (com.sun.tools.javac.util.ListBuffer)34 JavacTreeMaker (lombok.javac.JavacTreeMaker)33 JCStatement (com.sun.tools.javac.tree.JCTree.JCStatement)29 JCVariableDecl (com.sun.tools.javac.tree.JCTree.JCVariableDecl)29 JCBlock (com.sun.tools.javac.tree.JCTree.JCBlock)28 JCTypeParameter (com.sun.tools.javac.tree.JCTree.JCTypeParameter)27 JavacNode (lombok.javac.JavacNode)27 JCTree (com.sun.tools.javac.tree.JCTree)22 JCModifiers (com.sun.tools.javac.tree.JCTree.JCModifiers)22 JCMethodDecl (com.sun.tools.javac.tree.JCTree.JCMethodDecl)21 JCPrimitiveTypeTree (com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree)14 JCFieldAccess (com.sun.tools.javac.tree.JCTree.JCFieldAccess)13 JCArrayTypeTree (com.sun.tools.javac.tree.JCTree.JCArrayTypeTree)11 JCIdent (com.sun.tools.javac.tree.JCTree.JCIdent)11 JCMethodInvocation (com.sun.tools.javac.tree.JCTree.JCMethodInvocation)11 JCAssign (com.sun.tools.javac.tree.JCTree.JCAssign)10 ArrayList (java.util.ArrayList)10