Search in sources :

Example 76 with JCAnnotation

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

the class HandleBuilder method makePrefixedSetterMethodForBuilder.

private void makePrefixedSetterMethodForBuilder(BuilderJob job, BuilderFieldData bfd, boolean deprecate, String prefix) {
    JavacNode fieldNode = bfd.createdFields.get(0);
    String setterPrefix = !prefix.isEmpty() ? prefix : job.oldFluent ? "" : "set";
    String setterName = HandlerUtil.buildAccessorName(job.sourceNode, setterPrefix, bfd.name.toString());
    Name setterName_ = job.builderType.toName(setterName);
    for (JavacNode child : job.builderType.down()) {
        if (child.getKind() != Kind.METHOD)
            continue;
        JCMethodDecl methodDecl = (JCMethodDecl) child.get();
        Name existingName = methodDecl.name;
        if (existingName.equals(setterName_) && !isTolerate(fieldNode, methodDecl))
            return;
    }
    JavacTreeMaker maker = fieldNode.getTreeMaker();
    List<JCAnnotation> methodAnns = JavacHandlerUtil.findCopyableToSetterAnnotations(bfd.originalFieldNode);
    JCMethodDecl newMethod = HandleSetter.createSetter(toJavacModifier(job.accessInners), deprecate, fieldNode, maker, setterName, bfd.name, bfd.nameOfSetFlag, job.oldChain, job.sourceNode, methodAnns, bfd.annotations);
    recursiveSetGeneratedBy(newMethod, job.sourceNode);
    if (job.sourceNode.up().getKind() == Kind.METHOD) {
        copyJavadocFromParam(bfd.originalFieldNode.up(), newMethod, bfd.name.toString());
    } else {
        copyJavadoc(bfd.originalFieldNode, newMethod, CopyJavadoc.SETTER, true);
    }
    injectMethod(job.builderType, newMethod);
}
Also used : JCMethodDecl(com.sun.tools.javac.tree.JCTree.JCMethodDecl) JavacTreeMaker(lombok.javac.JavacTreeMaker) JavacNode(lombok.javac.JavacNode) ToString(lombok.ToString) JCAnnotation(com.sun.tools.javac.tree.JCTree.JCAnnotation) Name(com.sun.tools.javac.util.Name)

Example 77 with JCAnnotation

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

the class JavacAST method buildLocalVar.

private JavacNode buildLocalVar(JCVariableDecl local, Kind kind) {
    if (setAndGetAsHandled(local))
        return null;
    List<JavacNode> childNodes = new ArrayList<JavacNode>();
    for (JCAnnotation annotation : local.mods.annotations) addIfNotNull(childNodes, buildAnnotation(annotation, true));
    addIfNotNull(childNodes, buildTypeUse(local.vartype));
    addIfNotNull(childNodes, buildExpression(local.init));
    return putInMap(new JavacNode(this, local, childNodes, kind));
}
Also used : ArrayList(java.util.ArrayList) JCAnnotation(com.sun.tools.javac.tree.JCTree.JCAnnotation)

Example 78 with JCAnnotation

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

the class HandleVal method endVisitLocal.

@SuppressWarnings("deprecation")
@Override
public void endVisitLocal(JavacNode localNode, JCVariableDecl local) {
    JCTree typeTree = local.vartype;
    if (typeTree == null)
        return;
    String typeTreeToString = typeTree.toString();
    JavacNode typeNode = localNode.getNodeFor(typeTree);
    if (!(eq(typeTreeToString, "val") || eq(typeTreeToString, "var")))
        return;
    boolean isVal = typeMatches(val.class, localNode, typeTree);
    boolean isVar = typeMatches(var.class, localNode, typeTree);
    if (!(isVal || isVar))
        return;
    if (isVal)
        handleFlagUsage(localNode, ConfigurationKeys.VAL_FLAG_USAGE, "val");
    if (isVar)
        handleFlagUsage(localNode, ConfigurationKeys.VAR_FLAG_USAGE, "var");
    JCTree parentRaw = localNode.directUp().get();
    if (isVal && parentRaw instanceof JCForLoop) {
        localNode.addError("'val' is not allowed in old-style for loops");
        return;
    }
    if (parentRaw instanceof JCForLoop && ((JCForLoop) parentRaw).getInitializer().size() > 1) {
        localNode.addError("'var' is not allowed in old-style for loops if there is more than 1 initializer");
        return;
    }
    JCExpression rhsOfEnhancedForLoop = null;
    if (local.init == null) {
        if (parentRaw instanceof JCEnhancedForLoop) {
            JCEnhancedForLoop efl = (JCEnhancedForLoop) parentRaw;
            if (efl.var == local)
                rhsOfEnhancedForLoop = efl.expr;
        }
    }
    final String annotation = typeTreeToString;
    if (rhsOfEnhancedForLoop == null && local.init == null) {
        localNode.addError("'" + annotation + "' on a local variable requires an initializer expression");
        return;
    }
    if (local.init instanceof JCNewArray && ((JCNewArray) local.init).elemtype == null) {
        localNode.addError("'" + annotation + "' is not compatible with array initializer expressions. Use the full form (new int[] { ... } instead of just { ... })");
        return;
    }
    if (localNode.shouldDeleteLombokAnnotations()) {
        JavacHandlerUtil.deleteImportFromCompilationUnit(localNode, val.class.getName());
        JavacHandlerUtil.deleteImportFromCompilationUnit(localNode, lombok.experimental.var.class.getName());
        JavacHandlerUtil.deleteImportFromCompilationUnit(localNode, var.class.getName());
    }
    if (isVal)
        local.mods.flags |= Flags.FINAL;
    if (!localNode.shouldDeleteLombokAnnotations()) {
        JCAnnotation valAnnotation = recursiveSetGeneratedBy(localNode.getTreeMaker().Annotation(local.vartype, List.<JCExpression>nil()), typeNode);
        local.mods.annotations = local.mods.annotations == null ? List.of(valAnnotation) : local.mods.annotations.append(valAnnotation);
    }
    if (localNode.getSourceVersion() >= 10) {
        local.vartype = null;
        localNode.getAst().setChanged();
        return;
    }
    if (JavacResolution.platformHasTargetTyping()) {
        local.vartype = localNode.getAst().getTreeMaker().Ident(localNode.getAst().toName("___Lombok_VAL_Attrib__"));
    } else {
        local.vartype = JavacResolution.createJavaLangObject(localNode.getAst());
    }
    Type type;
    try {
        if (rhsOfEnhancedForLoop == null) {
            if (local.init.type == null) {
                if (isVar && local.init instanceof JCLiteral && ((JCLiteral) local.init).value == null) {
                    localNode.addError("variable initializer is 'null'");
                }
                JavacResolution resolver = new JavacResolution(localNode.getContext());
                try {
                    type = ((JCExpression) resolver.resolveMethodMember(localNode).get(local.init)).type;
                } catch (RuntimeException e) {
                    System.err.println("Exception while resolving: " + localNode + "(" + localNode.getFileName() + ")");
                    throw e;
                }
            } else {
                type = local.init.type;
                if (type.isErroneous()) {
                    try {
                        JavacResolution resolver = new JavacResolution(localNode.getContext());
                        local.type = Symtab.instance(localNode.getContext()).unknownType;
                        type = ((JCExpression) resolver.resolveMethodMember(localNode).get(local.init)).type;
                    } catch (RuntimeException e) {
                        System.err.println("Exception while resolving: " + localNode + "(" + localNode.getFileName() + ")");
                        throw e;
                    }
                }
            }
        } else {
            if (rhsOfEnhancedForLoop.type == null) {
                JavacResolution resolver = new JavacResolution(localNode.getContext());
                type = ((JCExpression) resolver.resolveMethodMember(localNode.directUp()).get(rhsOfEnhancedForLoop)).type;
            } else {
                type = rhsOfEnhancedForLoop.type;
            }
        }
        try {
            JCExpression replacement;
            if (rhsOfEnhancedForLoop != null) {
                Type componentType = JavacResolution.ifTypeIsIterableToComponent(type, localNode.getAst());
                if (componentType == null)
                    replacement = JavacResolution.createJavaLangObject(localNode.getAst());
                else
                    replacement = JavacResolution.typeToJCTree(componentType, localNode.getAst(), false);
            } else {
                replacement = JavacResolution.typeToJCTree(type, localNode.getAst(), false);
            }
            if (replacement != null) {
                local.vartype = replacement;
            } else {
                local.vartype = JavacResolution.createJavaLangObject(localNode.getAst());
            }
            localNode.getAst().setChanged();
        } catch (JavacResolution.TypeNotConvertibleException e) {
            localNode.addError("Cannot use '" + annotation + "' here because initializer expression does not have a representable type: " + e.getMessage());
            local.vartype = JavacResolution.createJavaLangObject(localNode.getAst());
        }
    } catch (RuntimeException e) {
        local.vartype = JavacResolution.createJavaLangObject(localNode.getAst());
        throw e;
    } finally {
        recursiveSetGeneratedBy(local.vartype, typeNode);
    }
}
Also used : lombok.val(lombok.val) JavacResolution(lombok.javac.JavacResolution) lombok.var(lombok.var) JCTree(com.sun.tools.javac.tree.JCTree) JCForLoop(com.sun.tools.javac.tree.JCTree.JCForLoop) Type(com.sun.tools.javac.code.Type) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JavacNode(lombok.javac.JavacNode) JCEnhancedForLoop(com.sun.tools.javac.tree.JCTree.JCEnhancedForLoop) JCLiteral(com.sun.tools.javac.tree.JCTree.JCLiteral) JCNewArray(com.sun.tools.javac.tree.JCTree.JCNewArray) JCAnnotation(com.sun.tools.javac.tree.JCTree.JCAnnotation)

Example 79 with JCAnnotation

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

the class HandleWith method createWith.

public JCMethodDecl createWith(long access, JavacNode field, JavacTreeMaker maker, JavacNode source, List<JCAnnotation> onMethod, List<JCAnnotation> onParam, boolean makeAbstract) {
    String withName = toWithName(field);
    if (withName == null)
        return null;
    JCVariableDecl fieldDecl = (JCVariableDecl) field.get();
    List<JCAnnotation> copyableAnnotations = findCopyableAnnotations(field);
    Name methodName = field.toName(withName);
    JCExpression returnType = cloneSelfType(field);
    JCBlock methodBody = null;
    long flags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, field.getContext());
    List<JCAnnotation> annsOnParam = copyAnnotations(onParam).appendList(copyableAnnotations);
    JCExpression pType = cloneType(maker, fieldDecl.vartype, source);
    JCVariableDecl param = maker.VarDef(maker.Modifiers(flags, annsOnParam), fieldDecl.name, pType, null);
    if (!makeAbstract) {
        ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>();
        JCExpression selfType = cloneSelfType(field);
        if (selfType == null)
            return null;
        ListBuffer<JCExpression> args = new ListBuffer<JCExpression>();
        for (JavacNode child : field.up().down()) {
            if (child.getKind() != Kind.FIELD)
                continue;
            JCVariableDecl childDecl = (JCVariableDecl) child.get();
            // Skip fields that start with $
            if (childDecl.name.toString().startsWith("$"))
                continue;
            long fieldFlags = childDecl.mods.flags;
            // Skip static fields.
            if ((fieldFlags & Flags.STATIC) != 0)
                continue;
            // Skip initialized final fields.
            if (((fieldFlags & Flags.FINAL) != 0) && childDecl.init != null)
                continue;
            if (child.get() == field.get()) {
                args.append(maker.Ident(fieldDecl.name));
            } else {
                args.append(createFieldAccessor(maker, child, FieldAccess.ALWAYS_FIELD));
            }
        }
        JCNewClass newClass = maker.NewClass(null, List.<JCExpression>nil(), selfType, args.toList(), null);
        JCExpression identityCheck = maker.Binary(CTC_EQUAL, createFieldAccessor(maker, field, FieldAccess.ALWAYS_FIELD), maker.Ident(fieldDecl.name));
        JCConditional conditional = maker.Conditional(identityCheck, maker.Ident(field.toName("this")), newClass);
        JCReturn returnStatement = maker.Return(conditional);
        if (!hasNonNullAnnotations(field)) {
            statements.append(returnStatement);
        } else {
            JCStatement nullCheck = generateNullCheck(maker, field, source);
            if (nullCheck != null)
                statements.append(nullCheck);
            statements.append(returnStatement);
        }
        methodBody = maker.Block(0, statements.toList());
    }
    List<JCTypeParameter> methodGenericParams = List.nil();
    List<JCVariableDecl> parameters = List.of(param);
    List<JCExpression> throwsClauses = List.nil();
    JCExpression annotationMethodDefaultValue = null;
    List<JCAnnotation> annsOnMethod = copyAnnotations(onMethod);
    CheckerFrameworkVersion checkerFramework = getCheckerFrameworkVersion(source);
    if (checkerFramework.generateSideEffectFree())
        annsOnMethod = annsOnMethod.prepend(maker.Annotation(genTypeRef(source, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE), List.<JCExpression>nil()));
    if (isFieldDeprecated(field))
        annsOnMethod = annsOnMethod.prepend(maker.Annotation(genJavaLangTypeRef(field, "Deprecated"), List.<JCExpression>nil()));
    if (makeAbstract)
        access |= Flags.ABSTRACT;
    AnnotationValues<Accessors> accessors = JavacHandlerUtil.getAccessorsForField(field);
    boolean makeFinal = shouldMakeFinal(field, accessors);
    if (makeFinal)
        access |= Flags.FINAL;
    JCMethodDecl decl = recursiveSetGeneratedBy(maker.MethodDef(maker.Modifiers(access, annsOnMethod), methodName, returnType, methodGenericParams, parameters, throwsClauses, methodBody, annotationMethodDefaultValue), source);
    copyJavadoc(field, decl, CopyJavadoc.WITH);
    return decl;
}
Also used : JCReturn(com.sun.tools.javac.tree.JCTree.JCReturn) ListBuffer(com.sun.tools.javac.util.ListBuffer) JCConditional(com.sun.tools.javac.tree.JCTree.JCConditional) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement) Accessors(lombok.experimental.Accessors) Name(com.sun.tools.javac.util.Name) JavacNode(lombok.javac.JavacNode) JCNewClass(com.sun.tools.javac.tree.JCTree.JCNewClass) JCAnnotation(com.sun.tools.javac.tree.JCTree.JCAnnotation) JCBlock(com.sun.tools.javac.tree.JCTree.JCBlock) JCMethodDecl(com.sun.tools.javac.tree.JCTree.JCMethodDecl) JCVariableDecl(com.sun.tools.javac.tree.JCTree.JCVariableDecl) JCTypeParameter(com.sun.tools.javac.tree.JCTree.JCTypeParameter) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) CheckerFrameworkVersion(lombok.core.configuration.CheckerFrameworkVersion)

Example 80 with JCAnnotation

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

the class JavacHandlerUtil method findAnnotationsInList.

/**
 * Searches the given field node for annotations that are in the given list, and returns those.
 */
private static List<JCAnnotation> findAnnotationsInList(JavacNode node, java.util.List<String> annotationsToFind) {
    JCAnnotation anno = null;
    String annoName = null;
    for (JavacNode child : node.down()) {
        if (child.getKind() == Kind.ANNOTATION) {
            if (anno != null) {
                annoName = "";
                break;
            }
            JCAnnotation annotation = (JCAnnotation) child.get();
            annoName = annotation.annotationType.toString();
            anno = annotation;
        }
    }
    if (annoName == null)
        return List.nil();
    if (!annoName.isEmpty()) {
        for (String bn : annotationsToFind) if (typeMatches(bn, node, anno.annotationType))
            return List.of(anno);
    }
    ListBuffer<JCAnnotation> result = new ListBuffer<JCAnnotation>();
    for (JavacNode child : node.down()) {
        if (child.getKind() == Kind.ANNOTATION) {
            JCAnnotation annotation = (JCAnnotation) child.get();
            boolean match = false;
            if (!match)
                for (String bn : annotationsToFind) if (typeMatches(bn, node, annotation.annotationType)) {
                    result.append(annotation);
                    break;
                }
        }
    }
    return result.toList();
}
Also used : JavacNode(lombok.javac.JavacNode) ListBuffer(com.sun.tools.javac.util.ListBuffer) 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