Search in sources :

Example 31 with FieldDeclaration

use of org.eclipse.jdt.internal.compiler.ast.FieldDeclaration in project lombok by rzwitserloot.

the class EclipseHandlerUtil method findGetter.

private static GetterMethod findGetter(EclipseNode field) {
    FieldDeclaration fieldDeclaration = (FieldDeclaration) field.get();
    boolean forceBool = FieldDeclaration_booleanLazyGetter.get(fieldDeclaration);
    TypeReference fieldType = fieldDeclaration.type;
    boolean isBoolean = forceBool || isBoolean(fieldType);
    EclipseNode typeNode = field.up();
    for (String potentialGetterName : toAllGetterNames(field, isBoolean)) {
        for (EclipseNode potentialGetter : typeNode.down()) {
            if (potentialGetter.getKind() != Kind.METHOD)
                continue;
            if (!(potentialGetter.get() instanceof MethodDeclaration))
                continue;
            MethodDeclaration method = (MethodDeclaration) potentialGetter.get();
            if (!potentialGetterName.equalsIgnoreCase(new String(method.selector)))
                continue;
            /**
             * static getX() methods don't count.
             */
            if ((method.modifiers & ClassFileConstants.AccStatic) != 0)
                continue;
            /**
             * Nor do getters with a non-empty parameter list.
             */
            if (method.arguments != null && method.arguments.length > 0)
                continue;
            return new GetterMethod(method.selector, method.returnType);
        }
    }
    // Check if the field has a @Getter annotation.
    boolean hasGetterAnnotation = false;
    for (EclipseNode child : field.down()) {
        if (child.getKind() == Kind.ANNOTATION && annotationTypeMatches(Getter.class, child)) {
            AnnotationValues<Getter> ann = createAnnotation(Getter.class, child);
            // Definitely WONT have a getter.
            if (ann.getInstance().value() == AccessLevel.NONE)
                return null;
            hasGetterAnnotation = true;
        }
    }
    if (!hasGetterAnnotation && HandleGetter.fieldQualifiesForGetterGeneration(field)) {
        // Check if the class has @Getter or @Data annotation.
        EclipseNode containingType = field.up();
        if (containingType != null)
            for (EclipseNode child : containingType.down()) {
                if (child.getKind() == Kind.ANNOTATION && annotationTypeMatches(Data.class, child))
                    hasGetterAnnotation = true;
                if (child.getKind() == Kind.ANNOTATION && annotationTypeMatches(Getter.class, child)) {
                    AnnotationValues<Getter> ann = createAnnotation(Getter.class, child);
                    // Definitely WONT have a getter.
                    if (ann.getInstance().value() == AccessLevel.NONE)
                        return null;
                    hasGetterAnnotation = true;
                }
            }
    }
    if (hasGetterAnnotation) {
        String getterName = toGetterName(field, isBoolean);
        if (getterName == null)
            return null;
        return new GetterMethod(getterName.toCharArray(), fieldType);
    }
    return null;
}
Also used : MethodDeclaration(org.eclipse.jdt.internal.compiler.ast.MethodDeclaration) AbstractMethodDeclaration(org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration) Getter(lombok.Getter) AnnotationValues(lombok.core.AnnotationValues) EclipseNode(lombok.eclipse.EclipseNode) TypeReference(org.eclipse.jdt.internal.compiler.ast.TypeReference) ParameterizedSingleTypeReference(org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference) QualifiedTypeReference(org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference) ArrayQualifiedTypeReference(org.eclipse.jdt.internal.compiler.ast.ArrayQualifiedTypeReference) ArrayTypeReference(org.eclipse.jdt.internal.compiler.ast.ArrayTypeReference) ParameterizedQualifiedTypeReference(org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference) SingleTypeReference(org.eclipse.jdt.internal.compiler.ast.SingleTypeReference) FieldDeclaration(org.eclipse.jdt.internal.compiler.ast.FieldDeclaration)

Example 32 with FieldDeclaration

use of org.eclipse.jdt.internal.compiler.ast.FieldDeclaration in project lombok by rzwitserloot.

the class EclipseHandlerUtil method injectField.

/**
 * Inserts a field into an existing type. The type must represent a {@code TypeDeclaration}.
 */
public static EclipseNode injectField(EclipseNode type, FieldDeclaration field) {
    TypeDeclaration parent = (TypeDeclaration) type.get();
    if (parent.fields == null) {
        parent.fields = new FieldDeclaration[1];
        parent.fields[0] = field;
    } else {
        int size = parent.fields.length;
        FieldDeclaration[] newArray = new FieldDeclaration[size + 1];
        System.arraycopy(parent.fields, 0, newArray, 0, size);
        int index = 0;
        for (; index < size; index++) {
            FieldDeclaration f = newArray[index];
            if (isEnumConstant(f) || isGenerated(f))
                continue;
            break;
        }
        System.arraycopy(newArray, index, newArray, index + 1, size - index);
        newArray[index] = field;
        parent.fields = newArray;
    }
    if (isEnumConstant(field) || (field.modifiers & Modifier.STATIC) != 0) {
        if (!hasClinit(parent)) {
            parent.addClinit();
        }
    }
    return type.add(field, Kind.FIELD);
}
Also used : TypeDeclaration(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) FieldDeclaration(org.eclipse.jdt.internal.compiler.ast.FieldDeclaration)

Example 33 with FieldDeclaration

use of org.eclipse.jdt.internal.compiler.ast.FieldDeclaration in project lombok by rzwitserloot.

the class HandleBuilder method generateBuilderFields.

public void generateBuilderFields(EclipseNode builderType, List<BuilderFieldData> builderFields, ASTNode source) {
    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);
        }
    }
}
Also used : ArrayList(java.util.ArrayList) EclipseNode(lombok.eclipse.EclipseNode) FieldDeclaration(org.eclipse.jdt.internal.compiler.ast.FieldDeclaration)

Example 34 with FieldDeclaration

use of org.eclipse.jdt.internal.compiler.ast.FieldDeclaration in project lombok by rzwitserloot.

the class HandleBuilder method handle.

@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;
    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;
    boolean isStatic = true;
    if (parent.get() instanceof TypeDeclaration) {
        tdParent = parent;
        TypeDeclaration td = (TypeDeclaration) tdParent.get();
        List<EclipseNode> allFields = new ArrayList<EclipseNode>();
        boolean valuePresent = (hasAnnotation(lombok.Value.class, parent) || hasAnnotation("lombok.experimental.Value", parent));
        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));
            BuilderFieldData bfd = new BuilderFieldData();
            bfd.rawName = fieldNode.getName().toCharArray();
            bfd.name = removePrefixFromField(fieldNode);
            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;
                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 = prefixWith(DEFAULT_PREFIX, bfd.name);
                bfd.nameOfSetFlag = prefixWith(bfd.name, SET_PREFIX);
                MethodDeclaration md = generateDefaultProvider(bfd.nameOfDefaultProvider, td.typeParameters, fieldNode, ast);
                if (md != null)
                    injectMethod(tdParent, md);
            }
            addObtainVia(bfd, fieldNode);
            builderFields.add(bfd);
            allFields.add(fieldNode);
        }
        handleConstructor.generateConstructor(tdParent, AccessLevel.PACKAGE, allFields, false, null, SkipIfConstructorExists.I_AM_BUILDER, 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();
        isStatic = md.isStatic();
        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[]>();
            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 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);
            bfd.originalFieldNode = param;
            addObtainVia(bfd, param);
            builderFields.add(bfd);
        }
    }
    EclipseNode builderType = findInnerClass(tdParent, builderClassName);
    if (builderType == null) {
        builderType = makeBuilderClass(isStatic, tdParent, builderClassName, typeParams, ast);
    } else {
        TypeDeclaration builderTypeDeclaration = (TypeDeclaration) builderType.get();
        if (isStatic && (builderTypeDeclaration.modifiers & ClassFileConstants.AccStatic) == 0) {
            annotationNode.addError("Existing Builder must be a static inner class.");
            return;
        } else if (!isStatic && (builderTypeDeclaration.modifiers & ClassFileConstants.AccStatic) != 0) {
            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;
                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, 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(tdParent, isStatic, 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(isStatic, 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);
        }
}
Also used : TypeParameter(org.eclipse.jdt.internal.compiler.ast.TypeParameter) Argument(org.eclipse.jdt.internal.compiler.ast.Argument) Builder(lombok.Builder) ArrayList(java.util.ArrayList) FieldDeclaration(org.eclipse.jdt.internal.compiler.ast.FieldDeclaration) ConstructorDeclaration(org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration) QualifiedTypeReference(org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference) ParameterizedQualifiedTypeReference(org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference) ParameterizedSingleTypeReference(org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference) EclipseSingularizer(lombok.eclipse.handlers.EclipseSingularsRecipes.EclipseSingularizer) TypeReference(org.eclipse.jdt.internal.compiler.ast.TypeReference) ParameterizedSingleTypeReference(org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference) QualifiedTypeReference(org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference) ParameterizedQualifiedTypeReference(org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference) SingleTypeReference(org.eclipse.jdt.internal.compiler.ast.SingleTypeReference) MethodDeclaration(org.eclipse.jdt.internal.compiler.ast.MethodDeclaration) AbstractMethodDeclaration(org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration) ParameterizedQualifiedTypeReference(org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference) ParameterizedSingleTypeReference(org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference) SingleTypeReference(org.eclipse.jdt.internal.compiler.ast.SingleTypeReference) SingularData(lombok.eclipse.handlers.EclipseSingularsRecipes.SingularData) EclipseNode(lombok.eclipse.EclipseNode) AbstractMethodDeclaration(org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration) TypeDeclaration(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration)

Example 35 with FieldDeclaration

use of org.eclipse.jdt.internal.compiler.ast.FieldDeclaration in project lombok by rzwitserloot.

the class HandleConstructor method createConstructor.

@SuppressWarnings("deprecation")
public static ConstructorDeclaration createConstructor(AccessLevel level, EclipseNode type, Collection<EclipseNode> fields, boolean allToDefault, EclipseNode sourceNode, List<Annotation> onConstructor) {
    ASTNode source = sourceNode.get();
    TypeDeclaration typeDeclaration = ((TypeDeclaration) type.get());
    long p = (long) source.sourceStart << 32 | source.sourceEnd;
    boolean isEnum = (((TypeDeclaration) type.get()).modifiers & ClassFileConstants.AccEnum) != 0;
    if (isEnum)
        level = AccessLevel.PRIVATE;
    boolean addConstructorProperties;
    if (fields.isEmpty()) {
        addConstructorProperties = false;
    } else {
        Boolean v = type.getAst().readConfiguration(ConfigurationKeys.ANY_CONSTRUCTOR_ADD_CONSTRUCTOR_PROPERTIES);
        addConstructorProperties = v != null ? v.booleanValue() : Boolean.FALSE.equals(type.getAst().readConfiguration(ConfigurationKeys.ANY_CONSTRUCTOR_SUPPRESS_CONSTRUCTOR_PROPERTIES));
    }
    ConstructorDeclaration constructor = new ConstructorDeclaration(((CompilationUnitDeclaration) type.top().get()).compilationResult);
    constructor.modifiers = toEclipseModifier(level);
    constructor.selector = typeDeclaration.name;
    constructor.constructorCall = new ExplicitConstructorCall(ExplicitConstructorCall.ImplicitSuper);
    constructor.constructorCall.sourceStart = source.sourceStart;
    constructor.constructorCall.sourceEnd = source.sourceEnd;
    constructor.thrownExceptions = null;
    constructor.typeParameters = null;
    constructor.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
    constructor.bodyStart = constructor.declarationSourceStart = constructor.sourceStart = source.sourceStart;
    constructor.bodyEnd = constructor.declarationSourceEnd = constructor.sourceEnd = source.sourceEnd;
    constructor.arguments = null;
    List<Argument> params = new ArrayList<Argument>();
    List<Statement> assigns = new ArrayList<Statement>();
    List<Statement> nullChecks = new ArrayList<Statement>();
    for (EclipseNode fieldNode : fields) {
        FieldDeclaration field = (FieldDeclaration) fieldNode.get();
        char[] rawName = field.name;
        char[] fieldName = removePrefixFromField(fieldNode);
        FieldReference thisX = new FieldReference(rawName, p);
        int s = (int) (p >> 32);
        int e = (int) p;
        thisX.receiver = new ThisReference(s, e);
        Expression assignmentExpr = allToDefault ? getDefaultExpr(field.type, s, e) : new SingleNameReference(fieldName, p);
        Assignment assignment = new Assignment(thisX, assignmentExpr, (int) p);
        assignment.sourceStart = (int) (p >> 32);
        assignment.sourceEnd = assignment.statementEnd = (int) (p >> 32);
        assigns.add(assignment);
        if (!allToDefault) {
            long fieldPos = (((long) field.sourceStart) << 32) | field.sourceEnd;
            Argument parameter = new Argument(fieldName, fieldPos, copyType(field.type, source), Modifier.FINAL);
            Annotation[] nonNulls = findAnnotations(field, NON_NULL_PATTERN);
            Annotation[] nullables = findAnnotations(field, NULLABLE_PATTERN);
            if (nonNulls.length != 0) {
                Statement nullCheck = generateNullCheck(parameter, sourceNode);
                if (nullCheck != null)
                    nullChecks.add(nullCheck);
            }
            parameter.annotations = copyAnnotations(source, nonNulls, nullables);
            params.add(parameter);
        }
    }
    nullChecks.addAll(assigns);
    constructor.statements = nullChecks.isEmpty() ? null : nullChecks.toArray(new Statement[nullChecks.size()]);
    constructor.arguments = params.isEmpty() ? null : params.toArray(new Argument[params.size()]);
    /* Generate annotations that must  be put on the generated method, and attach them. */
    {
        Annotation[] constructorProperties = null;
        if (!allToDefault && addConstructorProperties && !isLocalType(type)) {
            constructorProperties = createConstructorProperties(source, fields);
        }
        constructor.annotations = copyAnnotations(source, onConstructor.toArray(new Annotation[0]), constructorProperties);
    }
    constructor.traverse(new SetGeneratedByVisitor(source), typeDeclaration.scope);
    return constructor;
}
Also used : FieldReference(org.eclipse.jdt.internal.compiler.ast.FieldReference) Argument(org.eclipse.jdt.internal.compiler.ast.Argument) Statement(org.eclipse.jdt.internal.compiler.ast.Statement) ReturnStatement(org.eclipse.jdt.internal.compiler.ast.ReturnStatement) ArrayList(java.util.ArrayList) ThisReference(org.eclipse.jdt.internal.compiler.ast.ThisReference) SingleNameReference(org.eclipse.jdt.internal.compiler.ast.SingleNameReference) FieldDeclaration(org.eclipse.jdt.internal.compiler.ast.FieldDeclaration) SingleMemberAnnotation(org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation) Annotation(org.eclipse.jdt.internal.compiler.ast.Annotation) Assignment(org.eclipse.jdt.internal.compiler.ast.Assignment) ExplicitConstructorCall(org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall) Expression(org.eclipse.jdt.internal.compiler.ast.Expression) AllocationExpression(org.eclipse.jdt.internal.compiler.ast.AllocationExpression) ConstructorDeclaration(org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration) ASTNode(org.eclipse.jdt.internal.compiler.ast.ASTNode) EclipseNode(lombok.eclipse.EclipseNode) TypeDeclaration(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration)

Aggregations

FieldDeclaration (org.eclipse.jdt.internal.compiler.ast.FieldDeclaration)40 EclipseNode (lombok.eclipse.EclipseNode)21 MethodDeclaration (org.eclipse.jdt.internal.compiler.ast.MethodDeclaration)17 TypeDeclaration (org.eclipse.jdt.internal.compiler.ast.TypeDeclaration)17 ArrayList (java.util.ArrayList)15 TypeReference (org.eclipse.jdt.internal.compiler.ast.TypeReference)11 Expression (org.eclipse.jdt.internal.compiler.ast.Expression)10 QualifiedTypeReference (org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference)10 ReturnStatement (org.eclipse.jdt.internal.compiler.ast.ReturnStatement)10 AbstractMethodDeclaration (org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration)7 Annotation (org.eclipse.jdt.internal.compiler.ast.Annotation)7 SingleNameReference (org.eclipse.jdt.internal.compiler.ast.SingleNameReference)7 Statement (org.eclipse.jdt.internal.compiler.ast.Statement)7 ASTNode (org.eclipse.jdt.internal.compiler.ast.ASTNode)6 AllocationExpression (org.eclipse.jdt.internal.compiler.ast.AllocationExpression)6 Argument (org.eclipse.jdt.internal.compiler.ast.Argument)6 ArrayTypeReference (org.eclipse.jdt.internal.compiler.ast.ArrayTypeReference)4 Assignment (org.eclipse.jdt.internal.compiler.ast.Assignment)4 EqualExpression (org.eclipse.jdt.internal.compiler.ast.EqualExpression)4 MessageSend (org.eclipse.jdt.internal.compiler.ast.MessageSend)4