Example usage for org.eclipse.jdt.internal.compiler.ast FieldDeclaration FieldDeclaration

List of usage examples for org.eclipse.jdt.internal.compiler.ast FieldDeclaration FieldDeclaration

Introduction

In this page you can find the example usage for org.eclipse.jdt.internal.compiler.ast FieldDeclaration FieldDeclaration.

Prototype

public FieldDeclaration(char[] name, int sourceStart, int sourceEnd) 

Source Link

Usage

From source file:lombok.eclipse.handlers.ast.EclipseASTMaker.java

License:Open Source License

@Override
public ASTNode visitEnumConstant(final lombok.ast.EnumConstant node, final Void p) {
    final AllocationExpression allocationExpression = new AllocationExpression();
    setGeneratedByAndCopyPos(allocationExpression, source, posHintOf(node));
    allocationExpression.arguments = toArray(build(node.getArgs()), new Expression[0]);
    allocationExpression.enumConstant = new FieldDeclaration(node.getName().toCharArray(), 0, 0);
    setGeneratedByAndCopyPos(allocationExpression.enumConstant, source, posHintOf(node));
    allocationExpression.enumConstant.initialization = allocationExpression;
    allocationExpression.enumConstant.javadoc = build(node.getJavaDoc());
    return allocationExpression.enumConstant;
}

From source file:lombok.eclipse.handlers.ast.EclipseASTMaker.java

License:Open Source License

@Override
public ASTNode visitFieldDecl(final lombok.ast.FieldDecl node, final Void p) {
    final FieldDeclaration fieldDeclaration = new FieldDeclaration(node.getName().toCharArray(), 0, 0);
    setGeneratedBy(fieldDeclaration, source);
    fieldDeclaration.modifiers = modifiersFor(node.getModifiers());
    fieldDeclaration.annotations = toArray(build(node.getAnnotations()), new Annotation[0]);
    fieldDeclaration.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
    fieldDeclaration.type = build(node.getType());
    if (node.getInitialization() != null) {
        fieldDeclaration.initialization = build(node.getInitialization());
    }//from ww  w .j a  v  a  2 s  .c  o m
    fieldDeclaration.javadoc = build(node.getJavaDoc());
    return fieldDeclaration;
}

From source file:lombok.eclipse.handlers.FieldBuilder.java

License:Apache License

FieldDeclaration buildWith(EclipseNode node) {
    ASTNode source = node.get();/* w  w w .j  a v  a 2 s. c o m*/
    FieldDeclaration fieldDecl = new FieldDeclaration(name.toCharArray(), source.sourceStart, source.sourceEnd);
    setGeneratedBy(fieldDecl, source);
    fieldDecl.declarationSourceEnd = -1;
    fieldDecl.modifiers = modifiers;
    fieldDecl.type = qualifiedTypeReference(type, source);
    AllocationExpression init = new AllocationExpression();
    setGeneratedBy(init, source);
    init.type = qualifiedTypeReference(type, source);
    init.arguments = args;
    fieldDecl.initialization = init;
    return fieldDecl;
}

From source file:lombok.eclipse.handlers.HandleBuilder.java

License:Open Source License

@Override
public void handle(AnnotationValues<Builder> annotation, Annotation ast, EclipseNode annotationNode) {
    long p = (long) ast.sourceStart << 32 | ast.sourceEnd;

    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();
    List<char[]> typeArgsForToBuilder = null;

    if (builderMethodName == null)
        builderMethodName = "builder";
    if (buildMethodName == null)
        builderMethodName = "build";
    if (builderClassName == null)
        builderClassName = "";

    if (!checkName("builderMethodName", builderMethodName, annotationNode))
        return;/*w ww.ja  v a 2  s  . c  om*/
    if (!checkName("buildMethodName", buildMethodName, annotationNode))
        return;
    if (!builderClassName.isEmpty()) {
        if (!checkName("builderClassName", builderClassName, annotationNode))
            return;
    }

    EclipseNode parent = annotationNode.up();

    List<BuilderFieldData> builderFields = new ArrayList<BuilderFieldData>();
    TypeReference returnType;
    TypeParameter[] typeParams;
    TypeReference[] thrownExceptions;
    char[] nameOfStaticBuilderMethod;
    EclipseNode tdParent;

    EclipseNode fillParametersFrom = parent.get() instanceof AbstractMethodDeclaration ? parent : null;
    boolean addCleaning = false;

    if (parent.get() instanceof TypeDeclaration) {
        tdParent = parent;
        TypeDeclaration td = (TypeDeclaration) tdParent.get();

        List<EclipseNode> allFields = new ArrayList<EclipseNode>();
        @SuppressWarnings("deprecation")
        boolean valuePresent = (hasAnnotation(lombok.Value.class, parent)
                || hasAnnotation(lombok.experimental.Value.class, parent));
        for (EclipseNode fieldNode : HandleConstructor.findAllFields(tdParent)) {
            FieldDeclaration fd = (FieldDeclaration) fieldNode.get();
            // final fields with an initializer cannot be written to, so they can't be 'builderized'. Unfortunately presence of @Value makes
            // non-final fields final, but @Value's handler hasn't done this yet, so we have to do this math ourselves.
            // Value will only skip making a field final if it has an explicit @NonFinal annotation, so we check for that.
            if (fd.initialization != null && valuePresent && !hasAnnotation(NonFinal.class, fieldNode))
                continue;
            BuilderFieldData bfd = new BuilderFieldData();
            bfd.rawName = fieldNode.getName().toCharArray();
            bfd.name = removePrefixFromField(fieldNode);
            bfd.type = fd.type;
            bfd.singularData = getSingularData(fieldNode, ast);
            addObtainVia(bfd, fieldNode);
            builderFields.add(bfd);
            allFields.add(fieldNode);
        }

        new HandleConstructor().generateConstructor(tdParent, AccessLevel.PACKAGE, allFields, false, null,
                SkipIfConstructorExists.I_AM_BUILDER, null, Collections.<Annotation>emptyList(),
                annotationNode);

        returnType = namePlusTypeParamsToTypeReference(td.name, td.typeParameters, p);
        typeParams = td.typeParameters;
        thrownExceptions = null;
        nameOfStaticBuilderMethod = null;
        if (builderClassName.isEmpty())
            builderClassName = new String(td.name) + "Builder";
    } else if (parent.get() instanceof ConstructorDeclaration) {
        ConstructorDeclaration cd = (ConstructorDeclaration) parent.get();
        if (cd.typeParameters != null && cd.typeParameters.length > 0) {
            annotationNode
                    .addError("@Builder is not supported on constructors with constructor type parameters.");
            return;
        }

        tdParent = parent.up();
        TypeDeclaration td = (TypeDeclaration) tdParent.get();
        returnType = namePlusTypeParamsToTypeReference(td.name, td.typeParameters, p);
        typeParams = td.typeParameters;
        thrownExceptions = cd.thrownExceptions;
        nameOfStaticBuilderMethod = null;
        if (builderClassName.isEmpty())
            builderClassName = new String(cd.selector) + "Builder";
    } else if (parent.get() instanceof MethodDeclaration) {
        MethodDeclaration md = (MethodDeclaration) parent.get();
        tdParent = parent.up();
        if (!md.isStatic()) {
            annotationNode.addError("@Builder is only supported on types, constructors, and static methods.");
            return;
        }

        if (toBuilder) {
            final String TO_BUILDER_NOT_SUPPORTED = "@Builder(toBuilder=true) is only supported if you return your own type.";
            char[] token;
            char[][] pkg = null;
            if (md.returnType.dimensions() > 0) {
                annotationNode.addError(TO_BUILDER_NOT_SUPPORTED);
                return;
            }

            if (md.returnType instanceof SingleTypeReference) {
                token = ((SingleTypeReference) md.returnType).token;
            } else if (md.returnType instanceof QualifiedTypeReference) {
                pkg = ((QualifiedTypeReference) md.returnType).tokens;
                token = pkg[pkg.length];
                char[][] pkg_ = new char[pkg.length - 1][];
                System.arraycopy(pkg, 0, pkg_, 0, pkg_.length);
                pkg = pkg_;
            } else {
                annotationNode.addError(TO_BUILDER_NOT_SUPPORTED);
                return;
            }

            if (pkg != null && !equals(parent.getPackageDeclaration(), pkg)) {
                annotationNode.addError(TO_BUILDER_NOT_SUPPORTED);
                return;
            }

            if (tdParent == null || !equals(tdParent.getName(), token)) {
                annotationNode.addError(TO_BUILDER_NOT_SUPPORTED);
                return;
            }

            TypeParameter[] tpOnType = ((TypeDeclaration) tdParent.get()).typeParameters;
            TypeParameter[] tpOnMethod = md.typeParameters;
            TypeReference[][] tpOnRet_ = null;
            if (md.returnType instanceof ParameterizedSingleTypeReference) {
                tpOnRet_ = new TypeReference[1][];
                tpOnRet_[0] = ((ParameterizedSingleTypeReference) md.returnType).typeArguments;
            } else if (md.returnType instanceof ParameterizedQualifiedTypeReference) {
                tpOnRet_ = ((ParameterizedQualifiedTypeReference) md.returnType).typeArguments;
            }

            if (tpOnRet_ != null)
                for (int i = 0; i < tpOnRet_.length - 1; i++) {
                    if (tpOnRet_[i] != null && tpOnRet_[i].length > 0) {
                        annotationNode.addError(
                                "@Builder(toBuilder=true) is not supported if returning a type with generics applied to an intermediate.");
                        return;
                    }
                }
            TypeReference[] tpOnRet = tpOnRet_ == null ? null : tpOnRet_[tpOnRet_.length - 1];
            typeArgsForToBuilder = new ArrayList<char[]>();

            // Every typearg on this method needs to be found in the return type, but the reverse is not true.
            // We also need to 'map' them.

            if (tpOnMethod != null)
                for (TypeParameter onMethod : tpOnMethod) {
                    int pos = -1;
                    if (tpOnRet != null)
                        for (int i = 0; i < tpOnRet.length; i++) {
                            if (tpOnRet[i].getClass() != SingleTypeReference.class)
                                continue;
                            if (!Arrays.equals(((SingleTypeReference) tpOnRet[i]).token, onMethod.name))
                                continue;
                            pos = i;
                        }
                    if (pos == -1 || tpOnType == null || tpOnType.length <= 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 "
                                        + new String(onMethod.name) + " is not part of the return type.");
                        return;
                    }

                    typeArgsForToBuilder.add(tpOnType[pos].name);
                }
        }

        returnType = copyType(md.returnType, ast);
        typeParams = md.typeParameters;
        thrownExceptions = md.thrownExceptions;
        nameOfStaticBuilderMethod = md.selector;
        if (builderClassName.isEmpty()) {
            char[] token;
            if (md.returnType instanceof QualifiedTypeReference) {
                char[][] tokens = ((QualifiedTypeReference) md.returnType).tokens;
                token = tokens[tokens.length - 1];
            } else if (md.returnType instanceof SingleTypeReference) {
                token = ((SingleTypeReference) md.returnType).token;
                if (!(md.returnType instanceof ParameterizedSingleTypeReference) && typeParams != null) {
                    for (TypeParameter tp : typeParams) {
                        if (Arrays.equals(tp.name, token)) {
                            annotationNode.addError(
                                    "@Builder requires specifying 'builderClassName' if used on methods with a type parameter as return type.");
                            return;
                        }
                    }
                }
            } else {
                annotationNode.addError(
                        "Unexpected kind of return type on annotated method. Specify 'builderClassName' to solve this problem.");
                return;
            }

            if (Character.isLowerCase(token[0])) {
                char[] newToken = new char[token.length];
                System.arraycopy(token, 1, newToken, 1, token.length - 1);
                newToken[0] = Character.toTitleCase(token[0]);
                token = newToken;
            }

            builderClassName = new String(token) + "Builder";
        }
    } else {
        annotationNode.addError("@Builder is only supported on types, constructors, and static methods.");
        return;
    }

    if (fillParametersFrom != null) {
        for (EclipseNode param : fillParametersFrom.down()) {
            if (param.getKind() != Kind.ARGUMENT)
                continue;
            BuilderFieldData bfd = new BuilderFieldData();
            Argument arg = (Argument) param.get();
            bfd.rawName = arg.name;
            bfd.name = arg.name;
            bfd.type = arg.type;
            bfd.singularData = getSingularData(param, ast);
            addObtainVia(bfd, param);
            builderFields.add(bfd);
        }
    }

    EclipseNode builderType = findInnerClass(tdParent, builderClassName);
    if (builderType == null) {
        builderType = makeBuilderClass(tdParent, builderClassName, typeParams, ast);
    } else {
        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;
                EclipseSingularizer 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) {
        FieldDeclaration cleanDecl = new FieldDeclaration(CLEAN_FIELD_NAME, 0, -1);
        cleanDecl.declarationSourceEnd = -1;
        cleanDecl.modifiers = ClassFileConstants.AccPrivate;
        cleanDecl.type = TypeReference.baseTypeReference(TypeIds.T_boolean, 0);
        injectFieldAndMarkGenerated(builderType, cleanDecl);
    }

    if (constructorExists(builderType) == MemberExistsResult.NOT_EXISTS) {
        ConstructorDeclaration cd = HandleConstructor.createConstructor(AccessLevel.PACKAGE, builderType,
                Collections.<EclipseNode>emptyList(), false, null, annotationNode,
                Collections.<Annotation>emptyList());
        if (cd != null)
            injectMethod(builderType, cd);
    }

    for (BuilderFieldData bfd : builderFields) {
        makeSetterMethodsForBuilder(builderType, bfd, annotationNode, fluent, chain);
    }

    if (methodExists(buildMethodName, builderType, -1) == MemberExistsResult.NOT_EXISTS) {
        MethodDeclaration md = generateBuildMethod(buildMethodName, nameOfStaticBuilderMethod, returnType,
                builderFields, builderType, thrownExceptions, addCleaning, ast);
        if (md != null)
            injectMethod(builderType, md);
    }

    if (methodExists("toString", builderType, 0) == MemberExistsResult.NOT_EXISTS) {
        List<EclipseNode> fieldNodes = new ArrayList<EclipseNode>();
        for (BuilderFieldData bfd : builderFields) {
            fieldNodes.addAll(bfd.createdFields);
        }
        MethodDeclaration md = HandleToString.createToString(builderType, fieldNodes, true, false, ast,
                FieldAccess.ALWAYS_FIELD);
        if (md != null)
            injectMethod(builderType, md);
    }

    if (addCleaning) {
        MethodDeclaration cleanMethod = generateCleanMethod(builderFields, builderType, ast);
        if (cleanMethod != null)
            injectMethod(builderType, cleanMethod);
    }

    if (methodExists(builderMethodName, tdParent, -1) == MemberExistsResult.NOT_EXISTS) {
        MethodDeclaration md = generateBuilderMethod(builderMethodName, builderClassName, tdParent, typeParams,
                ast);
        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.");
            break;
        case NOT_EXISTS:
            TypeParameter[] tps = typeParams;
            if (typeArgsForToBuilder != null) {
                tps = new TypeParameter[typeArgsForToBuilder.size()];
                for (int i = 0; i < tps.length; i++) {
                    tps[i] = new TypeParameter();
                    tps[i].name = typeArgsForToBuilder.get(i);
                }
            }
            MethodDeclaration md = generateToBuilderMethod(toBuilderMethodName, builderClassName, tdParent, tps,
                    builderFields, fluent, ast);

            if (md != null)
                injectMethod(tdParent, md);
        }
}

From source file:lombok.eclipse.handlers.HandleBuilder.java

License:Open Source License

public void generateBuilderFields(EclipseNode builderType, List<BuilderFieldData> builderFields,
        ASTNode source) {/*from  w w  w .ja v  a  2  s.  c  o  m*/
    List<EclipseNode> existing = new ArrayList<EclipseNode>();
    for (EclipseNode child : builderType.down()) {
        if (child.getKind() == Kind.FIELD)
            existing.add(child);
    }

    top: for (BuilderFieldData bfd : builderFields) {
        if (bfd.singularData != null && bfd.singularData.getSingularizer() != null) {
            bfd.createdFields
                    .addAll(bfd.singularData.getSingularizer().generateFields(bfd.singularData, builderType));
        } else {
            for (EclipseNode exists : existing) {
                char[] n = ((FieldDeclaration) exists.get()).name;
                if (Arrays.equals(n, bfd.name)) {
                    bfd.createdFields.add(exists);
                    continue top;
                }
            }

            FieldDeclaration fd = new FieldDeclaration(bfd.name, 0, 0);
            fd.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG;
            fd.modifiers = ClassFileConstants.AccPrivate;
            fd.type = copyType(bfd.type);
            fd.traverse(new SetGeneratedByVisitor(source), (MethodScope) null);
            bfd.createdFields.add(injectFieldAndMarkGenerated(builderType, fd));
        }
    }
}

From source file:lombok.eclipse.handlers.HandleFieldNameConstants.java

License:Open Source License

private void createInnerTypeFieldNameConstants(EclipseNode typeNode, EclipseNode errorNode, ASTNode source,
        AccessLevel level, List<EclipseNode> fields, boolean asEnum, String innerTypeName) {
    if (fields.isEmpty())
        return;/*from  ww w.  ja v a  2  s  .  co  m*/

    ASTVisitor generatedByVisitor = new SetGeneratedByVisitor(source);
    TypeDeclaration parent = (TypeDeclaration) typeNode.get();
    EclipseNode fieldsType = findInnerClass(typeNode, innerTypeName);
    boolean genConstr = false, genClinit = false;
    char[] name = innerTypeName.toCharArray();
    TypeDeclaration generatedInnerType = null;
    if (fieldsType == null) {
        generatedInnerType = new TypeDeclaration(parent.compilationResult);
        generatedInnerType.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG;
        generatedInnerType.modifiers = toEclipseModifier(level) | (asEnum ? ClassFileConstants.AccEnum
                : (ClassFileConstants.AccStatic | ClassFileConstants.AccFinal));
        generatedInnerType.name = name;
        fieldsType = injectType(typeNode, generatedInnerType);
        genConstr = true;
        genClinit = asEnum;
        generatedInnerType.traverse(generatedByVisitor, ((TypeDeclaration) typeNode.get()).scope);
    } else {
        TypeDeclaration builderTypeDeclaration = (TypeDeclaration) fieldsType.get();
        if (asEnum && (builderTypeDeclaration.modifiers & ClassFileConstants.AccEnum) == 0) {
            errorNode.addError("Existing " + innerTypeName + " must be declared as an 'enum'.");
            return;
        }
        if (!asEnum && (builderTypeDeclaration.modifiers & ClassFileConstants.AccStatic) == 0) {
            errorNode.addError("Existing " + innerTypeName + " must be declared as a 'static class'.");
            return;
        }
        genConstr = constructorExists(fieldsType) == MemberExistsResult.NOT_EXISTS;
    }

    if (genConstr) {
        ConstructorDeclaration constructor = new ConstructorDeclaration(parent.compilationResult);
        constructor.selector = name;
        constructor.modifiers = ClassFileConstants.AccPrivate;
        ExplicitConstructorCall superCall = new ExplicitConstructorCall(0);
        superCall.sourceStart = source.sourceStart;
        superCall.sourceEnd = source.sourceEnd;
        superCall.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG;
        constructor.constructorCall = superCall;
        if (!asEnum)
            constructor.statements = new Statement[0];
        injectMethod(fieldsType, constructor);
    }

    if (genClinit) {
        Clinit cli = new Clinit(parent.compilationResult);
        injectMethod(fieldsType, cli);
        cli.traverse(generatedByVisitor, ((TypeDeclaration) fieldsType.get()).scope);
    }

    for (EclipseNode fieldNode : fields) {
        FieldDeclaration field = (FieldDeclaration) fieldNode.get();
        char[] fName = field.name;
        if (fieldExists(new String(fName), fieldsType) != MemberExistsResult.NOT_EXISTS)
            continue;
        int pS = source.sourceStart, pE = source.sourceEnd;
        long p = (long) pS << 32 | pE;
        FieldDeclaration constantField = new FieldDeclaration(fName, pS, pE);
        constantField.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG;
        if (asEnum) {
            AllocationExpression ac = new AllocationExpression();
            ac.enumConstant = constantField;
            ac.sourceStart = source.sourceStart;
            ac.sourceEnd = source.sourceEnd;
            constantField.initialization = ac;
            constantField.modifiers = 0;
        } else {
            constantField.type = new QualifiedTypeReference(TypeConstants.JAVA_LANG_STRING,
                    new long[] { p, p, p });
            constantField.initialization = new StringLiteral(field.name, pS, pE, 0);
            constantField.modifiers = ClassFileConstants.AccPublic | ClassFileConstants.AccStatic
                    | ClassFileConstants.AccFinal;
        }
        injectField(fieldsType, constantField);
        constantField.traverse(generatedByVisitor, ((TypeDeclaration) fieldsType.get()).initializerScope);
    }
}

From source file:lombok.eclipse.handlers.HandleLog.java

License:Open Source License

private static FieldDeclaration createField(LoggingFramework framework, Annotation source,
        ClassLiteralAccess loggingType, String logFieldName, boolean useStatic, String loggerTopic) {
    int pS = source.sourceStart, pE = source.sourceEnd;
    long p = (long) pS << 32 | pE;

    //    private static final <loggerType> log = <factoryMethod>(<parameter>);
    FieldDeclaration fieldDecl = new FieldDeclaration(logFieldName.toCharArray(), 0, -1);
    setGeneratedBy(fieldDecl, source);//from  www  .  j av a2  s. c om
    fieldDecl.declarationSourceEnd = -1;
    fieldDecl.modifiers = Modifier.PRIVATE | (useStatic ? Modifier.STATIC : 0) | Modifier.FINAL;

    fieldDecl.type = createTypeReference(framework.getLoggerTypeName(), source);

    MessageSend factoryMethodCall = new MessageSend();
    setGeneratedBy(factoryMethodCall, source);

    factoryMethodCall.receiver = createNameReference(framework.getLoggerFactoryTypeName(), source);
    factoryMethodCall.selector = framework.getLoggerFactoryMethodName().toCharArray();

    Expression parameter;
    if (loggerTopic == null || loggerTopic.trim().length() == 0) {
        parameter = framework.createFactoryParameter(loggingType, source);
    } else {
        parameter = new StringLiteral(loggerTopic.toCharArray(), pS, pE, 0);
    }

    factoryMethodCall.arguments = new Expression[] { parameter };
    factoryMethodCall.nameSourcePosition = p;
    factoryMethodCall.sourceStart = pS;
    factoryMethodCall.sourceEnd = factoryMethodCall.statementEnd = pE;

    fieldDecl.initialization = factoryMethodCall;

    return fieldDecl;
}

From source file:lombok.eclipse.handlers.HandleRelations.java

License:Open Source License

private static FieldDeclaration createField(Object anno, EclipseNode fieldNode, ASTNode source) {
    int pS = source.sourceStart, pE = source.sourceEnd;
    long p = (long) pS << 32 | pE;

    FieldDeclaration result = null;//from   w  w  w .j  av  a 2s  . c  om
    FieldDeclaration fieldDecl = (FieldDeclaration) fieldNode.get();

    String relatedFieldName = null;
    boolean isOneToOne = false;
    boolean isUnique = false;

    String baseTypeName = new String(((TypeDeclaration) fieldNode.up().get()).name);

    char[] qualifiedRelationTypeName = null;
    char[] singleRelationTypeName = null;
    TypeReference fieldType = null;
    TypeReference baseType = createTypeReference(baseTypeName.split("\\."), p);
    setGeneratedBy(baseType, source);
    TypeReference referenceType = fieldDecl.type;

    if (anno instanceof OneToOne) {
        isOneToOne = true;
        relatedFieldName = ((OneToOne) anno).field();

        qualifiedRelationTypeName = OneToOneRelation.class.getName().toCharArray();
        singleRelationTypeName = OneToOneRelation.class.getSimpleName().toCharArray();
    } else {
        relatedFieldName = ((OneToMany) anno).field();
        isUnique = ((OneToMany) anno).unique();

        if (referenceType instanceof ParameterizedSingleTypeReference) {
            referenceType = ((ParameterizedSingleTypeReference) referenceType).typeArguments[0];
        } else if (referenceType instanceof ParameterizedQualifiedTypeReference) {
            ParameterizedQualifiedTypeReference type = (ParameterizedQualifiedTypeReference) referenceType;
            referenceType = type.typeArguments[type.typeArguments.length - 1][0];
        }

        qualifiedRelationTypeName = OneToManyRelation.class.getName().toCharArray();
        singleRelationTypeName = OneToManyRelation.class.getSimpleName().toCharArray();
    }

    addImportIfNotExists((CompilationUnitDeclaration) fieldNode.top().get(), qualifiedRelationTypeName, source);

    fieldType = new ParameterizedSingleTypeReference(singleRelationTypeName,
            new TypeReference[] { baseType, referenceType }, 0, p);
    setGeneratedBy(fieldType, source);
    fieldType.sourceStart = pS;
    fieldType.sourceEnd = fieldType.statementEnd = pE;

    CompilationResult compResult = ((CompilationUnitDeclaration) fieldNode.top().get()).compilationResult;

    final TypeDeclaration typeDeclaration = new TypeDeclaration(compResult);
    setGeneratedBy(typeDeclaration, source);
    typeDeclaration.name = CharOperation.NO_CHAR;
    typeDeclaration.bits |= (ASTNode.IsAnonymousType | ASTNode.IsLocalType);
    typeDeclaration.bodyStart = source.sourceStart;
    typeDeclaration.bodyEnd = source.sourceEnd;
    typeDeclaration.declarationSourceStart = source.sourceStart;
    typeDeclaration.declarationSourceEnd = source.sourceEnd;
    typeDeclaration.methods = new AbstractMethodDeclaration[] {
            createGetReferencedKeyMethod(source, relatedFieldName, isOneToOne, baseType, referenceType,
                    compResult),
            createSetReferencedObjectMethod(fieldDecl, source, relatedFieldName, isOneToOne, isUnique, baseType,
                    referenceType, (CompilationUnitDeclaration) fieldNode.top().get()),
            createSetRelatedIdMethod(source, relatedFieldName, isOneToOne, baseType, referenceType,
                    compResult) };

    typeDeclaration.addClinit();

    QualifiedAllocationExpression allocation = new QualifiedAllocationExpression(typeDeclaration);
    setGeneratedBy(allocation, source);
    allocation.sourceStart = pS;
    allocation.sourceEnd = allocation.statementEnd = pE;
    allocation.type = fieldType;

    result = new FieldDeclaration(toUpperCase(new String(fieldDecl.name)).toCharArray(), 0, -1);
    setGeneratedBy(result, source);
    result.declarationSourceEnd = -1;
    result.type = fieldType;
    result.initialization = allocation;
    result.modifiers = ClassFileConstants.AccPrivate | ClassFileConstants.AccFinal
            | ClassFileConstants.AccStatic;

    return result;
}

From source file:lombok.eclipse.handlers.HandleSuperBuilder.java

License:Open Source License

@Override
public void handle(AnnotationValues<SuperBuilder> annotation, Annotation ast, EclipseNode annotationNode) {
    handleExperimentalFlagUsage(annotationNode, ConfigurationKeys.SUPERBUILDER_FLAG_USAGE, "@SuperBuilder");

    long p = (long) ast.sourceStart << 32 | ast.sourceEnd;

    SuperBuilder superbuilderAnnotation = annotation.getInstance();

    String builderMethodName = superbuilderAnnotation.builderMethodName();
    String buildMethodName = superbuilderAnnotation.buildMethodName();

    if (builderMethodName == null)
        builderMethodName = "builder";
    if (buildMethodName == null)
        buildMethodName = "build";

    boolean generateBuilderMethod;
    if (builderMethodName.isEmpty()) {
        generateBuilderMethod = false;//from w ww .  j av  a  2s.c om
    } else if (!checkName("builderMethodName", builderMethodName, annotationNode)) {
        return;
    } else {
        generateBuilderMethod = true;
    }
    if (!checkName("buildMethodName", buildMethodName, annotationNode))
        return;

    boolean toBuilder = superbuilderAnnotation.toBuilder();

    EclipseNode tdParent = annotationNode.up();

    java.util.List<BuilderFieldData> builderFields = new ArrayList<BuilderFieldData>();
    TypeReference returnType;
    TypeParameter[] typeParams;

    boolean addCleaning = false;

    if (!(tdParent.get() instanceof TypeDeclaration)) {
        annotationNode.addError("@SuperBuilder is only supported on types.");
        return;
    }
    TypeDeclaration td = (TypeDeclaration) tdParent.get();

    // Gather all fields of the class that should be set by the builder.
    List<EclipseNode> allFields = new ArrayList<EclipseNode>();
    List<EclipseNode> nonFinalNonDefaultedFields = null;

    boolean valuePresent = (hasAnnotation(lombok.Value.class, tdParent)
            || hasAnnotation("lombok.experimental.Value", tdParent));
    for (EclipseNode fieldNode : HandleConstructor.findAllFields(tdParent, true)) {
        FieldDeclaration fd = (FieldDeclaration) fieldNode.get();
        EclipseNode isDefault = findAnnotation(Builder.Default.class, fieldNode);
        boolean isFinal = ((fd.modifiers & ClassFileConstants.AccFinal) != 0)
                || (valuePresent && !hasAnnotation(NonFinal.class, fieldNode));

        Annotation[] copyableAnnotations = findCopyableAnnotations(fieldNode);

        BuilderFieldData bfd = new BuilderFieldData();
        bfd.rawName = fieldNode.getName().toCharArray();
        bfd.name = removePrefixFromField(fieldNode);
        bfd.annotations = copyAnnotations(fd, copyableAnnotations);
        bfd.type = fd.type;
        bfd.singularData = getSingularData(fieldNode, ast);
        bfd.originalFieldNode = fieldNode;

        if (bfd.singularData != null && isDefault != null) {
            isDefault.addError("@Builder.Default and @Singular cannot be mixed.");
            isDefault = null;
        }

        if (fd.initialization == null && isDefault != null) {
            isDefault.addWarning("@Builder.Default requires an initializing expression (' = something;').");
            isDefault = null;
        }

        if (fd.initialization != null && isDefault == null) {
            if (isFinal)
                continue;
            if (nonFinalNonDefaultedFields == null)
                nonFinalNonDefaultedFields = new ArrayList<EclipseNode>();
            nonFinalNonDefaultedFields.add(fieldNode);
        }

        if (isDefault != null) {
            bfd.nameOfDefaultProvider = prefixWith(DEFAULT_PREFIX, bfd.name);
            bfd.nameOfSetFlag = prefixWith(bfd.name, SET_PREFIX);

            MethodDeclaration md = HandleBuilder.generateDefaultProvider(bfd.nameOfDefaultProvider,
                    td.typeParameters, fieldNode, ast);
            if (md != null)
                injectMethod(tdParent, md);
        }
        addObtainVia(bfd, fieldNode);
        builderFields.add(bfd);
        allFields.add(fieldNode);
    }

    // Set the names of the builder classes.
    String builderClassName = String.valueOf(td.name) + "Builder";
    String builderImplClassName = builderClassName + "Impl";

    typeParams = td.typeParameters != null ? td.typeParameters : new TypeParameter[0];
    returnType = namePlusTypeParamsToTypeReference(td.name, typeParams, p);

    // <C, B> are the generics for our builder.
    String classGenericName = "C";
    String builderGenericName = "B";
    // If these generics' names collide with any generics on the annotated class, modify them.
    // For instance, if there are generics <B, B2, C> on the annotated class, use "C2" and "B3" for our builder.
    java.util.List<String> typeParamStrings = new ArrayList<String>();
    for (TypeParameter typeParam : typeParams)
        typeParamStrings.add(typeParam.toString());
    classGenericName = generateNonclashingNameFor(classGenericName, typeParamStrings);
    builderGenericName = generateNonclashingNameFor(builderGenericName, typeParamStrings);

    TypeReference extendsClause = td.superclass;
    TypeReference superclassBuilderClass = null;
    TypeReference[] typeArguments = new TypeReference[] {
            new SingleTypeReference(classGenericName.toCharArray(), 0),
            new SingleTypeReference(builderGenericName.toCharArray(), 0) };
    if (extendsClause instanceof QualifiedTypeReference) {
        QualifiedTypeReference qualifiedTypeReference = (QualifiedTypeReference) extendsClause;
        String superclassClassName = String.valueOf(qualifiedTypeReference.getLastToken());
        String superclassBuilderClassName = superclassClassName + "Builder";

        char[][] tokens = Arrays.copyOf(qualifiedTypeReference.tokens,
                qualifiedTypeReference.tokens.length + 1);
        tokens[tokens.length] = superclassBuilderClassName.toCharArray();
        long[] poss = new long[tokens.length];
        Arrays.fill(poss, p);

        TypeReference[] superclassTypeArgs = getTypeParametersFrom(extendsClause);

        // Every token may potentially have type args. Here, we only have
        // type args for the last token, the superclass' builder.
        TypeReference[][] typeArgsForTokens = new TypeReference[tokens.length][];
        typeArgsForTokens[typeArgsForTokens.length - 1] = mergeTypeReferences(superclassTypeArgs,
                typeArguments);

        superclassBuilderClass = new ParameterizedQualifiedTypeReference(tokens, typeArgsForTokens, 0, poss);
    } else if (extendsClause != null) {
        String superClass = String.valueOf(extendsClause.getTypeName()[0]);
        String superclassBuilderClassName = superClass + "Builder";

        char[][] tokens = new char[][] { superClass.toCharArray(), superclassBuilderClassName.toCharArray() };
        long[] poss = new long[tokens.length];
        Arrays.fill(poss, p);

        TypeReference[] superclassTypeArgs = getTypeParametersFrom(extendsClause);

        // Every token may potentially have type args. Here, we only have
        // type args for the last token, the superclass' builder.
        TypeReference[][] typeArgsForTokens = new TypeReference[tokens.length][];
        typeArgsForTokens[typeArgsForTokens.length - 1] = mergeTypeReferences(superclassTypeArgs,
                typeArguments);

        superclassBuilderClass = new ParameterizedQualifiedTypeReference(tokens, typeArgsForTokens, 0, poss);
    }
    // If there is no superclass, superclassBuilderClassExpression is still == null at this point.
    // You can use it to check whether to inherit or not.

    generateBuilderBasedConstructor(tdParent, typeParams, builderFields, annotationNode, builderClassName,
            superclassBuilderClass != null);

    // Create the abstract builder class, or reuse an existing one.
    EclipseNode builderType = findInnerClass(tdParent, builderClassName);
    if (builderType == null) {
        builderType = generateBuilderAbstractClass(tdParent, builderClassName, superclassBuilderClass,
                typeParams, ast, classGenericName, builderGenericName);
    } else {
        TypeDeclaration builderTypeDeclaration = (TypeDeclaration) builderType.get();
        if ((builderTypeDeclaration.modifiers
                & (ClassFileConstants.AccStatic | ClassFileConstants.AccAbstract)) == 0) {
            annotationNode.addError("Existing Builder must be an abstract 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;
            EclipseSingularizer singularizer = sd.getSingularizer();
            if (singularizer == null)
                continue;
            if (singularizer.checkForAlreadyExistingNodesAndGenerateError(builderType, sd)) {
                bfd.singularData = null;
            }
        }
    }

    // Check validity of @ObtainVia fields, and add check if adding cleaning for @Singular is necessary.
    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;
            }
        }
    }

    // Generate the fields in the abstract builder class that hold the values for the instance.
    generateBuilderFields(builderType, builderFields, ast);
    if (addCleaning) {
        FieldDeclaration cleanDecl = new FieldDeclaration(CLEAN_FIELD_NAME, 0, -1);
        cleanDecl.declarationSourceEnd = -1;
        cleanDecl.modifiers = ClassFileConstants.AccPrivate;
        cleanDecl.type = TypeReference.baseTypeReference(TypeIds.T_boolean, 0);
        injectFieldAndMarkGenerated(builderType, cleanDecl);
    }

    if (toBuilder) {
        // Generate $fillValuesFrom() method in the abstract builder.
        injectMethod(builderType, generateFillValuesMethod(tdParent, superclassBuilderClass != null,
                builderGenericName, classGenericName, builderClassName, typeParams));
        // Generate $fillValuesFromInstanceIntoBuilder() method in the builder implementation class.
        injectMethod(builderType,
                generateStaticFillValuesMethod(tdParent, builderClassName, typeParams, builderFields, ast));
    }

    // Generate abstract self() and build() methods in the abstract builder.
    injectMethod(builderType,
            generateAbstractSelfMethod(tdParent, superclassBuilderClass != null, builderGenericName));
    injectMethod(builderType, generateAbstractBuildMethod(tdParent, buildMethodName,
            superclassBuilderClass != null, classGenericName, ast));

    // Create the setter methods in the abstract builder.
    for (BuilderFieldData bfd : builderFields) {
        generateSetterMethodsForBuilder(builderType, bfd, annotationNode, builderGenericName);
    }

    // Create the toString() method for the abstract builder.
    if (methodExists("toString", builderType, 0) == MemberExistsResult.NOT_EXISTS) {
        List<Included<EclipseNode, ToString.Include>> fieldNodes = new ArrayList<Included<EclipseNode, ToString.Include>>();
        for (BuilderFieldData bfd : builderFields) {
            for (EclipseNode f : bfd.createdFields) {
                fieldNodes.add(new Included<EclipseNode, ToString.Include>(f, null, true));
            }
        }
        // Let toString() call super.toString() if there is a superclass, so that it also shows fields from the superclass' builder.
        MethodDeclaration md = HandleToString.createToString(builderType, fieldNodes, true,
                superclassBuilderClass != null, ast, FieldAccess.ALWAYS_FIELD);
        if (md != null) {
            injectMethod(builderType, md);
        }
    }

    if (addCleaning)
        injectMethod(builderType, generateCleanMethod(builderFields, builderType, ast));

    boolean isAbstract = (td.modifiers & ClassFileConstants.AccAbstract) != 0;
    if (isAbstract) {
        // Only non-abstract classes get the Builder implementation.
        return;
    }

    // Create the builder implementation class, or reuse an existing one.
    EclipseNode builderImplType = findInnerClass(tdParent, builderImplClassName);
    if (builderImplType == null) {
        builderImplType = generateBuilderImplClass(tdParent, builderImplClassName, builderClassName, typeParams,
                ast);
    } else {
        TypeDeclaration builderImplTypeDeclaration = (TypeDeclaration) builderImplType.get();
        if ((builderImplTypeDeclaration.modifiers & ClassFileConstants.AccAbstract) != 0
                || (builderImplTypeDeclaration.modifiers & ClassFileConstants.AccStatic) == 0) {
            annotationNode.addError("Existing BuilderImpl must be a non-abstract static inner class.");
            return;
        }
        sanityCheckForMethodGeneratingAnnotationsOnBuilderClass(builderImplType, annotationNode);
    }

    if (toBuilder) {
        // Add the toBuilder() method to the annotated class.
        switch (methodExists(TO_BUILDER_METHOD_NAME_STRING, tdParent, 0)) {
        case EXISTS_BY_USER:
            annotationNode.addWarning("Not generating toBuilder() as it already exists.");
            break;
        case NOT_EXISTS:
            injectMethod(tdParent,
                    generateToBuilderMethod(builderClassName, builderImplClassName, tdParent, typeParams, ast));
        default:
            // Should not happen.
        }
    }

    // Create the self() and build() methods in the BuilderImpl.
    injectMethod(builderImplType, generateSelfMethod(builderImplType, typeParams, p));
    if (methodExists(buildMethodName, builderImplType, -1) == MemberExistsResult.NOT_EXISTS) {
        injectMethod(builderImplType, generateBuildMethod(tdParent, buildMethodName, returnType, ast));
    }

    // Add the builder() method to the annotated class.
    if (generateBuilderMethod && methodExists(builderMethodName, tdParent, -1) != MemberExistsResult.NOT_EXISTS)
        generateBuilderMethod = false;
    if (generateBuilderMethod) {
        MethodDeclaration md = generateBuilderMethod(builderMethodName, builderClassName, builderImplClassName,
                tdParent, typeParams, ast);
        if (md != null)
            injectMethod(tdParent, md);
    }

    if (nonFinalNonDefaultedFields != null && generateBuilderMethod) {
        for (EclipseNode fieldNode : nonFinalNonDefaultedFields) {
            fieldNode.addWarning(
                    "@SuperBuilder 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.");
        }
    }
}

From source file:lombok.eclipse.handlers.HandleSuperBuilder.java

License:Open Source License

private void generateBuilderFields(EclipseNode builderType, List<BuilderFieldData> builderFields,
        ASTNode source) {//  www  .  j a v  a 2  s. c o  m
    List<EclipseNode> existing = new ArrayList<EclipseNode>();
    for (EclipseNode child : builderType.down()) {
        if (child.getKind() == Kind.FIELD)
            existing.add(child);
    }

    for (BuilderFieldData bfd : builderFields) {
        if (bfd.singularData != null && bfd.singularData.getSingularizer() != null) {
            bfd.createdFields
                    .addAll(bfd.singularData.getSingularizer().generateFields(bfd.singularData, builderType));
        } else {
            EclipseNode field = null, setFlag = null;
            for (EclipseNode exists : existing) {
                char[] n = ((FieldDeclaration) exists.get()).name;
                if (Arrays.equals(n, bfd.name))
                    field = exists;
                if (bfd.nameOfSetFlag != null && Arrays.equals(n, bfd.nameOfSetFlag))
                    setFlag = exists;
            }

            if (field == null) {
                FieldDeclaration fd = new FieldDeclaration(bfd.name, 0, 0);
                fd.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG;
                fd.modifiers = ClassFileConstants.AccPrivate;
                fd.type = copyType(bfd.type);
                fd.traverse(new SetGeneratedByVisitor(source), (MethodScope) null);
                field = injectFieldAndMarkGenerated(builderType, fd);
            }
            if (setFlag == null && bfd.nameOfSetFlag != null) {
                FieldDeclaration fd = new FieldDeclaration(bfd.nameOfSetFlag, 0, 0);
                fd.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG;
                fd.modifiers = ClassFileConstants.AccPrivate;
                fd.type = TypeReference.baseTypeReference(TypeIds.T_boolean, 0);
                fd.traverse(new SetGeneratedByVisitor(source), (MethodScope) null);
                injectFieldAndMarkGenerated(builderType, fd);
            }
            bfd.createdFields.add(field);
        }
    }
}