Search in sources :

Example 11 with JCTypeParameter

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

the class JavacJavaUtilListSetSingularizer method generateSingularMethod.

void generateSingularMethod(JavacTreeMaker maker, JCExpression returnType, JCStatement returnStatement, SingularData data, JavacNode builderType, JCTree source, boolean fluent) {
    List<JCTypeParameter> typeParams = List.nil();
    List<JCExpression> thrown = List.nil();
    JCModifiers mods = maker.Modifiers(Flags.PUBLIC);
    ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>();
    statements.append(createConstructBuilderVarIfNeeded(maker, data, builderType, false, source));
    JCExpression thisDotFieldDotAdd = chainDots(builderType, "this", data.getPluralName().toString(), "add");
    JCExpression invokeAdd = maker.Apply(List.<JCExpression>nil(), thisDotFieldDotAdd, List.<JCExpression>of(maker.Ident(data.getSingularName())));
    statements.append(maker.Exec(invokeAdd));
    if (returnStatement != null)
        statements.append(returnStatement);
    JCBlock body = maker.Block(0, statements.toList());
    Name name = data.getSingularName();
    long paramFlags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, builderType.getContext());
    if (!fluent)
        name = builderType.toName(HandlerUtil.buildAccessorName("add", name.toString()));
    JCExpression paramType = cloneParamType(0, maker, data.getTypeArgs(), builderType, source);
    JCVariableDecl param = maker.VarDef(maker.Modifiers(paramFlags), data.getSingularName(), paramType, null);
    JCMethodDecl method = maker.MethodDef(mods, name, returnType, typeParams, List.of(param), thrown, body, null);
    injectMethod(builderType, method);
}
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) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement) JCVariableDecl(com.sun.tools.javac.tree.JCTree.JCVariableDecl) Name(com.sun.tools.javac.util.Name) JCTypeParameter(com.sun.tools.javac.tree.JCTree.JCTypeParameter) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCModifiers(com.sun.tools.javac.tree.JCTree.JCModifiers)

Example 12 with JCTypeParameter

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

the class JavacJavaUtilMapSingularizer method generateClearMethod.

private void generateClearMethod(JavacTreeMaker maker, JCExpression returnType, JCStatement returnStatement, SingularData data, JavacNode builderType, JCTree source) {
    JCModifiers mods = maker.Modifiers(Flags.PUBLIC);
    List<JCTypeParameter> typeParams = List.nil();
    List<JCExpression> thrown = List.nil();
    List<JCVariableDecl> params = List.nil();
    List<JCExpression> jceBlank = List.nil();
    JCExpression thisDotKeyField = chainDots(builderType, "this", data.getPluralName() + "$key");
    JCExpression thisDotKeyFieldDotClear = chainDots(builderType, "this", data.getPluralName() + "$key", "clear");
    JCExpression thisDotValueFieldDotClear = chainDots(builderType, "this", data.getPluralName() + "$value", "clear");
    JCStatement clearKeyCall = maker.Exec(maker.Apply(jceBlank, thisDotKeyFieldDotClear, jceBlank));
    JCStatement clearValueCall = maker.Exec(maker.Apply(jceBlank, thisDotValueFieldDotClear, jceBlank));
    JCExpression cond = maker.Binary(CTC_NOT_EQUAL, thisDotKeyField, maker.Literal(CTC_BOT, null));
    JCBlock clearCalls = maker.Block(0, List.of(clearKeyCall, clearValueCall));
    JCStatement ifSetCallClear = maker.If(cond, clearCalls, null);
    List<JCStatement> statements = returnStatement != null ? List.of(ifSetCallClear, returnStatement) : List.of(ifSetCallClear);
    JCBlock body = maker.Block(0, statements);
    Name methodName = builderType.toName(HandlerUtil.buildAccessorName("clear", data.getPluralName().toString()));
    JCMethodDecl method = maker.MethodDef(mods, methodName, returnType, typeParams, params, thrown, body, null);
    injectMethod(builderType, method);
}
Also used : JCTypeParameter(com.sun.tools.javac.tree.JCTree.JCTypeParameter) JCBlock(com.sun.tools.javac.tree.JCTree.JCBlock) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCMethodDecl(com.sun.tools.javac.tree.JCTree.JCMethodDecl) JCModifiers(com.sun.tools.javac.tree.JCTree.JCModifiers) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement) JCVariableDecl(com.sun.tools.javac.tree.JCTree.JCVariableDecl) Name(com.sun.tools.javac.util.Name)

Example 13 with JCTypeParameter

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

the class HandleBuilder method generateBuildMethod.

private JCMethodDecl generateBuildMethod(JavacNode tdParent, boolean isStatic, String buildName, Name builderName, JCExpression returnType, java.util.List<BuilderFieldData> builderFields, JavacNode type, List<JCExpression> thrownExceptions, JCTree source, boolean addCleaning) {
    JavacTreeMaker maker = type.getTreeMaker();
    JCExpression call;
    ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>();
    if (addCleaning) {
        JCExpression notClean = maker.Unary(CTC_NOT, maker.Select(maker.Ident(type.toName("this")), type.toName("$lombokUnclean")));
        JCStatement invokeClean = maker.Exec(maker.Apply(List.<JCExpression>nil(), maker.Ident(type.toName("$lombokClean")), List.<JCExpression>nil()));
        JCIf ifUnclean = maker.If(notClean, invokeClean, null);
        statements.append(ifUnclean);
    }
    for (BuilderFieldData bfd : builderFields) {
        if (bfd.singularData != null && bfd.singularData.getSingularizer() != null) {
            bfd.singularData.getSingularizer().appendBuildCode(bfd.singularData, type, source, statements, bfd.name);
        }
    }
    ListBuffer<JCExpression> args = new ListBuffer<JCExpression>();
    for (BuilderFieldData bfd : builderFields) {
        if (bfd.nameOfSetFlag != null) {
            statements.append(maker.VarDef(maker.Modifiers(0L), bfd.name, cloneType(maker, bfd.type, source, tdParent.getContext()), maker.Select(maker.Ident(type.toName("this")), bfd.name)));
            statements.append(maker.If(maker.Unary(CTC_NOT, maker.Ident(bfd.nameOfSetFlag)), maker.Exec(maker.Assign(maker.Ident(bfd.name), maker.Apply(typeParameterNames(maker, ((JCClassDecl) tdParent.get()).typarams), maker.Select(maker.Ident(((JCClassDecl) tdParent.get()).name), bfd.nameOfDefaultProvider), List.<JCExpression>nil()))), null));
        }
        args.append(maker.Ident(bfd.name));
    }
    if (addCleaning) {
        statements.append(maker.Exec(maker.Assign(maker.Select(maker.Ident(type.toName("this")), type.toName("$lombokUnclean")), maker.Literal(CTC_BOOLEAN, 1))));
    }
    if (builderName == null) {
        call = maker.NewClass(null, List.<JCExpression>nil(), returnType, args.toList(), null);
        statements.append(maker.Return(call));
    } else {
        ListBuffer<JCExpression> typeParams = new ListBuffer<JCExpression>();
        for (JCTypeParameter tp : ((JCClassDecl) type.get()).typarams) {
            typeParams.append(maker.Ident(tp.name));
        }
        JCExpression callee = maker.Ident(((JCClassDecl) type.up().get()).name);
        if (!isStatic)
            callee = maker.Select(callee, type.up().toName("this"));
        JCExpression fn = maker.Select(callee, builderName);
        call = maker.Apply(typeParams.toList(), fn, args.toList());
        if (returnType instanceof JCPrimitiveTypeTree && CTC_VOID.equals(typeTag(returnType))) {
            statements.append(maker.Exec(call));
        } else {
            statements.append(maker.Return(call));
        }
    }
    JCBlock body = maker.Block(0, statements.toList());
    return maker.MethodDef(maker.Modifiers(Flags.PUBLIC), type.toName(buildName), returnType, List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), thrownExceptions, body, null);
}
Also used : JCTypeParameter(com.sun.tools.javac.tree.JCTree.JCTypeParameter) JCClassDecl(com.sun.tools.javac.tree.JCTree.JCClassDecl) JCPrimitiveTypeTree(com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree) JCBlock(com.sun.tools.javac.tree.JCTree.JCBlock) JavacTreeMaker(lombok.javac.JavacTreeMaker) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCIf(com.sun.tools.javac.tree.JCTree.JCIf) ListBuffer(com.sun.tools.javac.util.ListBuffer) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement)

Example 14 with JCTypeParameter

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

the class HandleBuilder method handle.

@Override
public void handle(AnnotationValues<Builder> annotation, JCAnnotation ast, JavacNode annotationNode) {
    Builder builderInstance = annotation.getInstance();
    // These exist just to support the 'old' lombok.experimental.Builder, which had these properties. lombok.Builder no longer has them.
    boolean fluent = toBoolean(annotation.getActualExpression("fluent"), true);
    boolean chain = toBoolean(annotation.getActualExpression("chain"), true);
    String builderMethodName = builderInstance.builderMethodName();
    String buildMethodName = builderInstance.buildMethodName();
    String builderClassName = builderInstance.builderClassName();
    String toBuilderMethodName = "toBuilder";
    boolean toBuilder = builderInstance.toBuilder();
    java.util.List<Name> typeArgsForToBuilder = null;
    if (builderMethodName == null)
        builderMethodName = "builder";
    if (buildMethodName == null)
        buildMethodName = "build";
    if (builderClassName == null)
        builderClassName = "";
    if (!checkName("builderMethodName", builderMethodName, annotationNode))
        return;
    if (!checkName("buildMethodName", buildMethodName, annotationNode))
        return;
    if (!builderClassName.isEmpty()) {
        if (!checkName("builderClassName", builderClassName, annotationNode))
            return;
    }
    deleteAnnotationIfNeccessary(annotationNode, Builder.class, "lombok.experimental.Builder");
    JavacNode parent = annotationNode.up();
    java.util.List<BuilderFieldData> builderFields = new ArrayList<BuilderFieldData>();
    JCExpression returnType;
    List<JCTypeParameter> typeParams = List.nil();
    List<JCExpression> thrownExceptions = List.nil();
    Name nameOfBuilderMethod;
    JavacNode tdParent;
    JavacNode fillParametersFrom = parent.get() instanceof JCMethodDecl ? parent : null;
    boolean addCleaning = false;
    boolean isStatic = true;
    if (parent.get() instanceof JCClassDecl) {
        tdParent = parent;
        JCClassDecl td = (JCClassDecl) tdParent.get();
        ListBuffer<JavacNode> allFields = new ListBuffer<JavacNode>();
        boolean valuePresent = (hasAnnotation(lombok.Value.class, parent) || hasAnnotation("lombok.experimental.Value", parent));
        for (JavacNode fieldNode : HandleConstructor.findAllFields(tdParent, true)) {
            JCVariableDecl fd = (JCVariableDecl) fieldNode.get();
            JavacNode isDefault = findAnnotation(Builder.Default.class, fieldNode, true);
            boolean isFinal = (fd.mods.flags & Flags.FINAL) != 0 || (valuePresent && !hasAnnotation(NonFinal.class, fieldNode));
            BuilderFieldData bfd = new BuilderFieldData();
            bfd.rawName = fd.name;
            bfd.name = removePrefixFromField(fieldNode);
            bfd.type = fd.vartype;
            bfd.singularData = getSingularData(fieldNode);
            bfd.originalFieldNode = fieldNode;
            if (bfd.singularData != null && isDefault != null) {
                isDefault.addError("@Builder.Default and @Singular cannot be mixed.");
                isDefault = null;
            }
            if (fd.init == null && isDefault != null) {
                isDefault.addWarning("@Builder.Default requires an initializing expression (' = something;').");
                isDefault = null;
            }
            if (fd.init != null && isDefault == null) {
                if (isFinal)
                    continue;
                fieldNode.addWarning("@Builder will ignore the initializing expression entirely. If you want the initializing expression to serve as default, add @Builder.Default. If it is not supposed to be settable during building, make the field final.");
            }
            if (isDefault != null) {
                bfd.nameOfDefaultProvider = parent.toName("$default$" + bfd.name);
                bfd.nameOfSetFlag = parent.toName(bfd.name + "$set");
                JCMethodDecl md = generateDefaultProvider(bfd.nameOfDefaultProvider, fieldNode, td.typarams);
                recursiveSetGeneratedBy(md, ast, annotationNode.getContext());
                if (md != null)
                    injectMethod(tdParent, md);
            }
            addObtainVia(bfd, fieldNode);
            builderFields.add(bfd);
            allFields.append(fieldNode);
        }
        handleConstructor.generateConstructor(tdParent, AccessLevel.PACKAGE, List.<JCAnnotation>nil(), allFields.toList(), false, null, SkipIfConstructorExists.I_AM_BUILDER, annotationNode);
        returnType = namePlusTypeParamsToTypeReference(tdParent.getTreeMaker(), td.name, td.typarams);
        typeParams = td.typarams;
        thrownExceptions = List.nil();
        nameOfBuilderMethod = null;
        if (builderClassName.isEmpty())
            builderClassName = td.name.toString() + "Builder";
    } else if (fillParametersFrom != null && fillParametersFrom.getName().toString().equals("<init>")) {
        JCMethodDecl jmd = (JCMethodDecl) fillParametersFrom.get();
        if (!jmd.typarams.isEmpty()) {
            annotationNode.addError("@Builder is not supported on constructors with constructor type parameters.");
            return;
        }
        tdParent = parent.up();
        JCClassDecl td = (JCClassDecl) tdParent.get();
        returnType = namePlusTypeParamsToTypeReference(tdParent.getTreeMaker(), td.name, td.typarams);
        typeParams = td.typarams;
        thrownExceptions = jmd.thrown;
        nameOfBuilderMethod = null;
        if (builderClassName.isEmpty())
            builderClassName = td.name.toString() + "Builder";
    } else if (fillParametersFrom != null) {
        tdParent = parent.up();
        JCClassDecl td = (JCClassDecl) tdParent.get();
        JCMethodDecl jmd = (JCMethodDecl) fillParametersFrom.get();
        isStatic = (jmd.mods.flags & Flags.STATIC) != 0;
        JCExpression fullReturnType = jmd.restype;
        returnType = fullReturnType;
        typeParams = jmd.typarams;
        thrownExceptions = jmd.thrown;
        nameOfBuilderMethod = jmd.name;
        if (returnType instanceof JCTypeApply) {
            returnType = cloneType(tdParent.getTreeMaker(), returnType, ast, annotationNode.getContext());
        }
        if (builderClassName.isEmpty()) {
            if (returnType instanceof JCFieldAccess) {
                builderClassName = ((JCFieldAccess) returnType).name.toString() + "Builder";
            } else if (returnType instanceof JCIdent) {
                Name n = ((JCIdent) returnType).name;
                for (JCTypeParameter tp : typeParams) {
                    if (tp.name.equals(n)) {
                        annotationNode.addError("@Builder requires specifying 'builderClassName' if used on methods with a type parameter as return type.");
                        return;
                    }
                }
                builderClassName = n.toString() + "Builder";
            } else if (returnType instanceof JCPrimitiveTypeTree) {
                builderClassName = returnType.toString() + "Builder";
                if (Character.isLowerCase(builderClassName.charAt(0))) {
                    builderClassName = Character.toTitleCase(builderClassName.charAt(0)) + builderClassName.substring(1);
                }
            } else if (returnType instanceof JCTypeApply) {
                JCExpression clazz = ((JCTypeApply) returnType).clazz;
                if (clazz instanceof JCFieldAccess) {
                    builderClassName = ((JCFieldAccess) clazz).name + "Builder";
                } else if (clazz instanceof JCIdent) {
                    builderClassName = ((JCIdent) clazz).name + "Builder";
                }
            }
            if (builderClassName.isEmpty()) {
                // This shouldn't happen.
                System.err.println("Lombok bug ID#20140614-1651: javac HandleBuilder: return type to name conversion failed: " + returnType.getClass());
                builderClassName = td.name.toString() + "Builder";
            }
        }
        if (toBuilder) {
            final String TO_BUILDER_NOT_SUPPORTED = "@Builder(toBuilder=true) is only supported if you return your own type.";
            if (returnType instanceof JCArrayTypeTree) {
                annotationNode.addError(TO_BUILDER_NOT_SUPPORTED);
                return;
            }
            Name simpleName;
            String pkg;
            List<JCExpression> tpOnRet = List.nil();
            if (fullReturnType instanceof JCTypeApply) {
                tpOnRet = ((JCTypeApply) fullReturnType).arguments;
            }
            JCExpression namingType = returnType;
            if (returnType instanceof JCTypeApply)
                namingType = ((JCTypeApply) returnType).clazz;
            if (namingType instanceof JCIdent) {
                simpleName = ((JCIdent) namingType).name;
                pkg = null;
            } else if (namingType instanceof JCFieldAccess) {
                JCFieldAccess jcfa = (JCFieldAccess) namingType;
                simpleName = jcfa.name;
                pkg = unpack(jcfa.selected);
                if (pkg.startsWith("ERR:")) {
                    String err = pkg.substring(4, pkg.indexOf("__ERR__"));
                    annotationNode.addError(err);
                    return;
                }
            } else {
                annotationNode.addError("Expected a (parameterized) type here instead of a " + namingType.getClass().getName());
                return;
            }
            if (pkg != null && !parent.getPackageDeclaration().equals(pkg)) {
                annotationNode.addError(TO_BUILDER_NOT_SUPPORTED);
                return;
            }
            if (!tdParent.getName().contentEquals(simpleName)) {
                annotationNode.addError(TO_BUILDER_NOT_SUPPORTED);
                return;
            }
            List<JCTypeParameter> tpOnMethod = jmd.typarams;
            List<JCTypeParameter> tpOnType = ((JCClassDecl) tdParent.get()).typarams;
            typeArgsForToBuilder = new ArrayList<Name>();
            for (JCTypeParameter tp : tpOnMethod) {
                int pos = -1;
                int idx = -1;
                for (JCExpression tOnRet : tpOnRet) {
                    idx++;
                    if (!(tOnRet instanceof JCIdent))
                        continue;
                    if (((JCIdent) tOnRet).name != tp.name)
                        continue;
                    pos = idx;
                }
                if (pos == -1 || tpOnType.size() <= pos) {
                    annotationNode.addError("@Builder(toBuilder=true) requires that each type parameter on the static method is part of the typeargs of the return value. Type parameter " + tp.name + " is not part of the return type.");
                    return;
                }
                typeArgsForToBuilder.add(tpOnType.get(pos).name);
            }
        }
    } else {
        annotationNode.addError("@Builder is only supported on types, constructors, and methods.");
        return;
    }
    if (fillParametersFrom != null) {
        for (JavacNode param : fillParametersFrom.down()) {
            if (param.getKind() != Kind.ARGUMENT)
                continue;
            BuilderFieldData bfd = new BuilderFieldData();
            JCVariableDecl raw = (JCVariableDecl) param.get();
            bfd.name = raw.name;
            bfd.rawName = raw.name;
            bfd.type = raw.vartype;
            bfd.singularData = getSingularData(param);
            bfd.originalFieldNode = param;
            addObtainVia(bfd, param);
            builderFields.add(bfd);
        }
    }
    JavacNode builderType = findInnerClass(tdParent, builderClassName);
    if (builderType == null) {
        builderType = makeBuilderClass(isStatic, annotationNode, tdParent, builderClassName, typeParams, ast);
    } else {
        JCClassDecl builderTypeDeclaration = (JCClassDecl) builderType.get();
        if (isStatic && !builderTypeDeclaration.getModifiers().getFlags().contains(Modifier.STATIC)) {
            annotationNode.addError("Existing Builder must be a static inner class.");
            return;
        } else if (!isStatic && builderTypeDeclaration.getModifiers().getFlags().contains(Modifier.STATIC)) {
            annotationNode.addError("Existing Builder must be a non-static inner class.");
            return;
        }
        sanityCheckForMethodGeneratingAnnotationsOnBuilderClass(builderType, annotationNode);
        /* generate errors for @Singular BFDs that have one already defined node. */
        {
            for (BuilderFieldData bfd : builderFields) {
                SingularData sd = bfd.singularData;
                if (sd == null)
                    continue;
                JavacSingularizer singularizer = sd.getSingularizer();
                if (singularizer == null)
                    continue;
                if (singularizer.checkForAlreadyExistingNodesAndGenerateError(builderType, sd)) {
                    bfd.singularData = null;
                }
            }
        }
    }
    for (BuilderFieldData bfd : builderFields) {
        if (bfd.singularData != null && bfd.singularData.getSingularizer() != null) {
            if (bfd.singularData.getSingularizer().requiresCleaning()) {
                addCleaning = true;
                break;
            }
        }
        if (bfd.obtainVia != null) {
            if (bfd.obtainVia.field().isEmpty() == bfd.obtainVia.method().isEmpty()) {
                bfd.obtainViaNode.addError("The syntax is either @ObtainVia(field = \"fieldName\") or @ObtainVia(method = \"methodName\").");
                return;
            }
            if (bfd.obtainVia.method().isEmpty() && bfd.obtainVia.isStatic()) {
                bfd.obtainViaNode.addError("@ObtainVia(isStatic = true) is not valid unless 'method' has been set.");
                return;
            }
        }
    }
    generateBuilderFields(builderType, builderFields, ast);
    if (addCleaning) {
        JavacTreeMaker maker = builderType.getTreeMaker();
        JCVariableDecl uncleanField = maker.VarDef(maker.Modifiers(Flags.PRIVATE), builderType.toName("$lombokUnclean"), maker.TypeIdent(CTC_BOOLEAN), null);
        injectFieldAndMarkGenerated(builderType, uncleanField);
    }
    if (constructorExists(builderType) == MemberExistsResult.NOT_EXISTS) {
        JCMethodDecl cd = HandleConstructor.createConstructor(AccessLevel.PACKAGE, List.<JCAnnotation>nil(), builderType, List.<JavacNode>nil(), false, annotationNode);
        if (cd != null)
            injectMethod(builderType, cd);
    }
    for (BuilderFieldData bfd : builderFields) {
        makeSetterMethodsForBuilder(builderType, bfd, annotationNode, fluent, chain);
    }
    if (methodExists(buildMethodName, builderType, -1) == MemberExistsResult.NOT_EXISTS) {
        JCMethodDecl md = generateBuildMethod(tdParent, isStatic, buildMethodName, nameOfBuilderMethod, returnType, builderFields, builderType, thrownExceptions, ast, addCleaning);
        if (md != null)
            injectMethod(builderType, md);
    }
    if (methodExists("toString", builderType, 0) == MemberExistsResult.NOT_EXISTS) {
        java.util.List<JavacNode> fieldNodes = new ArrayList<JavacNode>();
        for (BuilderFieldData bfd : builderFields) {
            fieldNodes.addAll(bfd.createdFields);
        }
        JCMethodDecl md = HandleToString.createToString(builderType, fieldNodes, true, false, FieldAccess.ALWAYS_FIELD, ast);
        if (md != null)
            injectMethod(builderType, md);
    }
    if (addCleaning)
        injectMethod(builderType, generateCleanMethod(builderFields, builderType, ast));
    if (methodExists(builderMethodName, tdParent, -1) == MemberExistsResult.NOT_EXISTS) {
        JCMethodDecl md = generateBuilderMethod(isStatic, builderMethodName, builderClassName, annotationNode, tdParent, typeParams);
        recursiveSetGeneratedBy(md, ast, annotationNode.getContext());
        if (md != null)
            injectMethod(tdParent, md);
    }
    if (toBuilder) {
        switch(methodExists(toBuilderMethodName, tdParent, 0)) {
            case EXISTS_BY_USER:
                annotationNode.addWarning("Not generating toBuilder() as it already exists.");
                return;
            case NOT_EXISTS:
                List<JCTypeParameter> tps = typeParams;
                if (typeArgsForToBuilder != null) {
                    ListBuffer<JCTypeParameter> lb = new ListBuffer<JCTypeParameter>();
                    JavacTreeMaker maker = tdParent.getTreeMaker();
                    for (Name n : typeArgsForToBuilder) {
                        lb.append(maker.TypeParameter(n, List.<JCExpression>nil()));
                    }
                    tps = lb.toList();
                }
                JCMethodDecl md = generateToBuilderMethod(toBuilderMethodName, builderClassName, tdParent, tps, builderFields, fluent, ast);
                if (md != null)
                    injectMethod(tdParent, md);
        }
    }
    recursiveSetGeneratedBy(builderType.get(), ast, annotationNode.getContext());
}
Also used : JCFieldAccess(com.sun.tools.javac.tree.JCTree.JCFieldAccess) Builder(lombok.Builder) ListBuffer(com.sun.tools.javac.util.ListBuffer) ArrayList(java.util.ArrayList) JCTypeApply(com.sun.tools.javac.tree.JCTree.JCTypeApply) JavacSingularizer(lombok.javac.handlers.JavacSingularsRecipes.JavacSingularizer) Name(com.sun.tools.javac.util.Name) JCPrimitiveTypeTree(com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree) JavacNode(lombok.javac.JavacNode) JCArrayTypeTree(com.sun.tools.javac.tree.JCTree.JCArrayTypeTree) JCClassDecl(com.sun.tools.javac.tree.JCTree.JCClassDecl) JCIdent(com.sun.tools.javac.tree.JCTree.JCIdent) JCMethodDecl(com.sun.tools.javac.tree.JCTree.JCMethodDecl) JavacTreeMaker(lombok.javac.JavacTreeMaker) JCVariableDecl(com.sun.tools.javac.tree.JCTree.JCVariableDecl) JCTypeParameter(com.sun.tools.javac.tree.JCTree.JCTypeParameter) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) SingularData(lombok.javac.handlers.JavacSingularsRecipes.SingularData)

Example 15 with JCTypeParameter

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

the class HandleSetter method createSetter.

public static JCMethodDecl createSetter(long access, boolean deprecate, JavacNode field, JavacTreeMaker treeMaker, String setterName, Name booleanFieldToSet, boolean shouldReturnThis, JavacNode source, List<JCAnnotation> onMethod, List<JCAnnotation> onParam) {
    if (setterName == null)
        return null;
    JCVariableDecl fieldDecl = (JCVariableDecl) field.get();
    JCExpression fieldRef = createFieldAccessor(treeMaker, field, FieldAccess.ALWAYS_FIELD);
    JCAssign assign = treeMaker.Assign(fieldRef, treeMaker.Ident(fieldDecl.name));
    ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>();
    List<JCAnnotation> nonNulls = findAnnotations(field, NON_NULL_PATTERN);
    List<JCAnnotation> nullables = findAnnotations(field, NULLABLE_PATTERN);
    Name methodName = field.toName(setterName);
    List<JCAnnotation> annsOnParam = copyAnnotations(onParam).appendList(nonNulls).appendList(nullables);
    long flags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, field.getContext());
    JCVariableDecl param = treeMaker.VarDef(treeMaker.Modifiers(flags, annsOnParam), fieldDecl.name, fieldDecl.vartype, null);
    if (nonNulls.isEmpty()) {
        statements.append(treeMaker.Exec(assign));
    } else {
        JCStatement nullCheck = generateNullCheck(treeMaker, field, source);
        if (nullCheck != null)
            statements.append(nullCheck);
        statements.append(treeMaker.Exec(assign));
    }
    if (booleanFieldToSet != null) {
        JCAssign setBool = treeMaker.Assign(treeMaker.Ident(booleanFieldToSet), treeMaker.Literal(CTC_BOOLEAN, 1));
        statements.append(treeMaker.Exec(setBool));
    }
    JCExpression methodType = null;
    if (shouldReturnThis) {
        methodType = cloneSelfType(field);
    }
    if (methodType == null) {
        // WARNING: Do not use field.getSymbolTable().voidType - that field has gone through non-backwards compatible API changes within javac1.6.
        methodType = treeMaker.Type(Javac.createVoidType(field.getSymbolTable(), CTC_VOID));
        shouldReturnThis = false;
    }
    if (shouldReturnThis) {
        JCReturn returnStatement = treeMaker.Return(treeMaker.Ident(field.toName("this")));
        statements.append(returnStatement);
    }
    JCBlock methodBody = treeMaker.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);
    if (isFieldDeprecated(field) || deprecate) {
        annsOnMethod = annsOnMethod.prepend(treeMaker.Annotation(genJavaLangTypeRef(field, "Deprecated"), List.<JCExpression>nil()));
    }
    JCMethodDecl decl = recursiveSetGeneratedBy(treeMaker.MethodDef(treeMaker.Modifiers(access, annsOnMethod), methodName, methodType, methodGenericParams, parameters, throwsClauses, methodBody, annotationMethodDefaultValue), source.get(), field.getContext());
    copyJavadoc(field, decl, CopyJavadoc.SETTER);
    return decl;
}
Also used : JCReturn(com.sun.tools.javac.tree.JCTree.JCReturn) JCBlock(com.sun.tools.javac.tree.JCTree.JCBlock) JCMethodDecl(com.sun.tools.javac.tree.JCTree.JCMethodDecl) JCAssign(com.sun.tools.javac.tree.JCTree.JCAssign) ListBuffer(com.sun.tools.javac.util.ListBuffer) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement) JCVariableDecl(com.sun.tools.javac.tree.JCTree.JCVariableDecl) Name(com.sun.tools.javac.util.Name) JCTypeParameter(com.sun.tools.javac.tree.JCTree.JCTypeParameter) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCAnnotation(com.sun.tools.javac.tree.JCTree.JCAnnotation)

Aggregations

JCTypeParameter (com.sun.tools.javac.tree.JCTree.JCTypeParameter)44 JCExpression (com.sun.tools.javac.tree.JCTree.JCExpression)39 JCVariableDecl (com.sun.tools.javac.tree.JCTree.JCVariableDecl)34 JCBlock (com.sun.tools.javac.tree.JCTree.JCBlock)33 JCStatement (com.sun.tools.javac.tree.JCTree.JCStatement)31 Name (com.sun.tools.javac.util.Name)30 ListBuffer (com.sun.tools.javac.util.ListBuffer)27 JCModifiers (com.sun.tools.javac.tree.JCTree.JCModifiers)26 JCMethodDecl (com.sun.tools.javac.tree.JCTree.JCMethodDecl)25 JavacTreeMaker (lombok.javac.JavacTreeMaker)13 JCAnnotation (com.sun.tools.javac.tree.JCTree.JCAnnotation)12 JCClassDecl (com.sun.tools.javac.tree.JCTree.JCClassDecl)9 JavacNode (lombok.javac.JavacNode)9 JCPrimitiveTypeTree (com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree)6 JCArrayTypeTree (com.sun.tools.javac.tree.JCTree.JCArrayTypeTree)5 Type (com.sun.tools.javac.code.Type)4 ClassType (com.sun.tools.javac.code.Type.ClassType)4 JCTree (com.sun.tools.javac.tree.JCTree)4 JCReturn (com.sun.tools.javac.tree.JCTree.JCReturn)4 ClassSymbol (com.sun.tools.javac.code.Symbol.ClassSymbol)3