Search in sources :

Example 46 with ThisReference

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

the class HandleBuilder method generateCleanMethod.

private MethodDeclaration generateCleanMethod(BuilderJob job) {
    List<Statement> statements = new ArrayList<Statement>();
    for (BuilderFieldData bfd : job.builderFields) {
        if (bfd.singularData != null && bfd.singularData.getSingularizer() != null) {
            bfd.singularData.getSingularizer().appendCleaningCode(bfd.singularData, job.builderType, statements);
        }
    }
    FieldReference thisUnclean = new FieldReference(CLEAN_FIELD_NAME, 0);
    thisUnclean.receiver = new ThisReference(0, 0);
    statements.add(new Assignment(thisUnclean, new FalseLiteral(0, 0), 0));
    MethodDeclaration decl = job.createNewMethodDeclaration();
    decl.selector = CLEAN_METHOD_NAME;
    decl.modifiers = ClassFileConstants.AccPrivate;
    decl.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
    decl.returnType = TypeReference.baseTypeReference(TypeIds.T_void, 0);
    decl.statements = statements.toArray(new Statement[0]);
    decl.traverse(new SetGeneratedByVisitor(job.source), (ClassScope) null);
    return decl;
}
Also used : Assignment(org.eclipse.jdt.internal.compiler.ast.Assignment) FieldReference(org.eclipse.jdt.internal.compiler.ast.FieldReference) Statement(org.eclipse.jdt.internal.compiler.ast.Statement) ReturnStatement(org.eclipse.jdt.internal.compiler.ast.ReturnStatement) IfStatement(org.eclipse.jdt.internal.compiler.ast.IfStatement) MethodDeclaration(org.eclipse.jdt.internal.compiler.ast.MethodDeclaration) AbstractMethodDeclaration(org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration) ArrayList(java.util.ArrayList) QualifiedThisReference(org.eclipse.jdt.internal.compiler.ast.QualifiedThisReference) ThisReference(org.eclipse.jdt.internal.compiler.ast.ThisReference) FalseLiteral(org.eclipse.jdt.internal.compiler.ast.FalseLiteral)

Example 47 with ThisReference

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

the class HandleBuilder method generateToBuilderMethod.

private MethodDeclaration generateToBuilderMethod(BuilderJob job, TypeParameter[] typeParameters, String prefix) {
    int pS = job.source.sourceStart, pE = job.source.sourceEnd;
    long p = job.getPos();
    MethodDeclaration out = job.createNewMethodDeclaration();
    out.selector = TO_BUILDER_METHOD_NAME;
    out.modifiers = toEclipseModifier(job.accessOuters);
    out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
    out.returnType = job.createBuilderTypeReference();
    if (job.checkerFramework.generateUnique()) {
        int len = out.returnType.getTypeName().length;
        out.returnType.annotations = new Annotation[len][];
        out.returnType.annotations[len - 1] = new Annotation[] { generateNamedAnnotation(job.source, CheckerFrameworkVersion.NAME__UNIQUE) };
    }
    AllocationExpression invoke = new AllocationExpression();
    invoke.type = job.createBuilderTypeReference();
    Expression receiver = invoke;
    List<Statement> preStatements = null;
    List<Statement> postStatements = null;
    for (BuilderFieldData bfd : job.builderFields) {
        String setterName = new String(bfd.name);
        String setterPrefix = !prefix.isEmpty() ? prefix : job.oldFluent ? "" : "set";
        if (!setterPrefix.isEmpty())
            setterName = HandlerUtil.buildAccessorName(job.sourceNode, setterPrefix, setterName);
        MessageSend ms = new MessageSend();
        Expression[] tgt = new Expression[bfd.singularData == null ? 1 : 2];
        if (bfd.obtainVia == null || !bfd.obtainVia.field().isEmpty()) {
            char[] fieldName = bfd.obtainVia == null ? bfd.rawName : bfd.obtainVia.field().toCharArray();
            for (int i = 0; i < tgt.length; i++) {
                FieldReference fr = new FieldReference(fieldName, 0);
                fr.receiver = new ThisReference(0, 0);
                tgt[i] = fr;
            }
        } else {
            String obtainName = bfd.obtainVia.method();
            boolean obtainIsStatic = bfd.obtainVia.isStatic();
            MessageSend obtainExpr = new MessageSend();
            if (obtainIsStatic) {
                if (typeParameters != null && typeParameters.length > 0) {
                    obtainExpr.typeArguments = new TypeReference[typeParameters.length];
                    for (int j = 0; j < typeParameters.length; j++) {
                        obtainExpr.typeArguments[j] = new SingleTypeReference(typeParameters[j].name, 0);
                    }
                }
                obtainExpr.receiver = generateNameReference(job.parentType, 0);
            } else {
                obtainExpr.receiver = new ThisReference(0, 0);
            }
            obtainExpr.selector = obtainName.toCharArray();
            if (obtainIsStatic)
                obtainExpr.arguments = new Expression[] { new ThisReference(0, 0) };
            for (int i = 0; i < tgt.length; i++) tgt[i] = new SingleNameReference(bfd.name, 0L);
            // javac appears to cache the type of JCMethodInvocation expressions based on position, meaning, if you have 2 ObtainVia-based method invokes on different types, you get bizarre type mismatch errors.
            // going via a local variable declaration solves the problem. We copy this behaviour
            // for ecj so we match what javac's handler does.
            LocalDeclaration ld = new LocalDeclaration(bfd.name, 0, 0);
            ld.modifiers = ClassFileConstants.AccFinal;
            ld.type = EclipseHandlerUtil.copyType(bfd.type, job.source);
            ld.initialization = obtainExpr;
            if (preStatements == null)
                preStatements = new ArrayList<Statement>();
            preStatements.add(ld);
        }
        ms.selector = setterName.toCharArray();
        if (bfd.singularData == null) {
            ms.arguments = tgt;
            ms.receiver = receiver;
            receiver = ms;
        } else {
            ms.arguments = new Expression[] { tgt[1] };
            ms.receiver = new SingleNameReference(BUILDER_TEMP_VAR, p);
            EqualExpression isNotNull = new EqualExpression(tgt[0], new NullLiteral(pS, pE), OperatorIds.NOT_EQUAL);
            if (postStatements == null)
                postStatements = new ArrayList<Statement>();
            postStatements.add(new IfStatement(isNotNull, ms, pS, pE));
        }
    }
    int preSs = preStatements == null ? 0 : preStatements.size();
    int postSs = postStatements == null ? 0 : postStatements.size();
    if (postSs > 0) {
        out.statements = new Statement[preSs + postSs + 2];
        for (int i = 0; i < preSs; i++) out.statements[i] = preStatements.get(i);
        for (int i = 0; i < postSs; i++) out.statements[preSs + 1 + i] = postStatements.get(i);
        LocalDeclaration b = new LocalDeclaration(BUILDER_TEMP_VAR, pS, pE);
        out.statements[preSs] = b;
        b.modifiers |= ClassFileConstants.AccFinal;
        b.type = job.createBuilderTypeReference();
        b.type.sourceStart = pS;
        b.type.sourceEnd = pE;
        b.initialization = receiver;
        out.statements[preSs + postSs + 1] = new ReturnStatement(new SingleNameReference(BUILDER_TEMP_VAR, p), pS, pE);
    } else {
        out.statements = new Statement[preSs + 1];
        for (int i = 0; i < preSs; i++) out.statements[i] = preStatements.get(i);
        out.statements[preSs] = new ReturnStatement(receiver, pS, pE);
    }
    createRelevantNonNullAnnotation(job.parentType, out);
    out.traverse(new SetGeneratedByVisitor(job.source), ((TypeDeclaration) job.parentType.get()).scope);
    return out;
}
Also used : LocalDeclaration(org.eclipse.jdt.internal.compiler.ast.LocalDeclaration) FieldReference(org.eclipse.jdt.internal.compiler.ast.FieldReference) MethodDeclaration(org.eclipse.jdt.internal.compiler.ast.MethodDeclaration) AbstractMethodDeclaration(org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration) Statement(org.eclipse.jdt.internal.compiler.ast.Statement) ReturnStatement(org.eclipse.jdt.internal.compiler.ast.ReturnStatement) IfStatement(org.eclipse.jdt.internal.compiler.ast.IfStatement) ArrayList(java.util.ArrayList) EqualExpression(org.eclipse.jdt.internal.compiler.ast.EqualExpression) ToString(lombok.ToString) QualifiedThisReference(org.eclipse.jdt.internal.compiler.ast.QualifiedThisReference) ThisReference(org.eclipse.jdt.internal.compiler.ast.ThisReference) SingleNameReference(org.eclipse.jdt.internal.compiler.ast.SingleNameReference) MessageSend(org.eclipse.jdt.internal.compiler.ast.MessageSend) IfStatement(org.eclipse.jdt.internal.compiler.ast.IfStatement) QualifiedAllocationExpression(org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression) AllocationExpression(org.eclipse.jdt.internal.compiler.ast.AllocationExpression) Expression(org.eclipse.jdt.internal.compiler.ast.Expression) QualifiedAllocationExpression(org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression) UnaryExpression(org.eclipse.jdt.internal.compiler.ast.UnaryExpression) AllocationExpression(org.eclipse.jdt.internal.compiler.ast.AllocationExpression) EqualExpression(org.eclipse.jdt.internal.compiler.ast.EqualExpression) ParameterizedSingleTypeReference(org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference) SingleTypeReference(org.eclipse.jdt.internal.compiler.ast.SingleTypeReference) ReturnStatement(org.eclipse.jdt.internal.compiler.ast.ReturnStatement) NullLiteral(org.eclipse.jdt.internal.compiler.ast.NullLiteral)

Example 48 with ThisReference

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

the class HandleConstructor method createConstructor.

@SuppressWarnings("deprecation")
public static ConstructorDeclaration createConstructor(AccessLevel level, EclipseNode type, Collection<EclipseNode> fieldsToParam, boolean forceDefaults, 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;
    List<EclipseNode> fieldsToDefault = fieldsNeedingBuilderDefaults(type, fieldsToParam);
    List<EclipseNode> fieldsToExplicit = forceDefaults ? fieldsNeedingExplicitDefaults(type, fieldsToParam) : Collections.<EclipseNode>emptyList();
    boolean addConstructorProperties;
    if (fieldsToParam.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 : fieldsToParam) {
        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 = 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);
        long fieldPos = (((long) field.sourceStart) << 32) | field.sourceEnd;
        Argument parameter = new Argument(fieldName, fieldPos, copyType(field.type, source), Modifier.FINAL);
        Annotation[] copyableAnnotations = findCopyableAnnotations(fieldNode);
        if (hasNonNullAnnotations(fieldNode)) {
            Statement nullCheck = generateNullCheck(parameter, sourceNode, null);
            if (nullCheck != null)
                nullChecks.add(nullCheck);
        }
        parameter.annotations = copyAnnotations(source, copyableAnnotations);
        params.add(parameter);
    }
    for (EclipseNode fieldNode : fieldsToExplicit) {
        FieldDeclaration field = (FieldDeclaration) fieldNode.get();
        char[] rawName = field.name;
        FieldReference thisX = new FieldReference(rawName, p);
        int s = (int) (p >> 32);
        int e = (int) p;
        thisX.receiver = new ThisReference(s, e);
        Expression assignmentExpr = getDefaultExpr(field.type, s, e);
        Assignment assignment = new Assignment(thisX, assignmentExpr, (int) p);
        assignment.sourceStart = (int) (p >> 32);
        assignment.sourceEnd = assignment.statementEnd = (int) (p >> 32);
        assigns.add(assignment);
    }
    for (EclipseNode fieldNode : fieldsToDefault) {
        FieldDeclaration field = (FieldDeclaration) fieldNode.get();
        char[] rawName = field.name;
        FieldReference thisX = new FieldReference(rawName, p);
        int s = (int) (p >> 32);
        int e = (int) p;
        thisX.receiver = new ThisReference(s, e);
        MessageSend inv = new MessageSend();
        inv.sourceStart = source.sourceStart;
        inv.sourceEnd = source.sourceEnd;
        inv.receiver = new SingleNameReference(((TypeDeclaration) type.get()).name, 0L);
        inv.selector = prefixWith(DEFAULT_PREFIX, removePrefixFromField(fieldNode));
        Assignment assignment = new Assignment(thisX, inv, (int) p);
        assignment.sourceStart = (int) (p >> 32);
        assignment.sourceEnd = assignment.statementEnd = (int) (p >> 32);
        assigns.add(assignment);
    }
    nullChecks.addAll(assigns);
    constructor.statements = nullChecks.isEmpty() ? null : nullChecks.toArray(new Statement[0]);
    constructor.arguments = params.isEmpty() ? null : params.toArray(new Argument[0]);
    /* Generate annotations that must  be put on the generated method, and attach them. */
    {
        Annotation[] constructorProperties = null;
        if (addConstructorProperties && !isLocalType(type))
            constructorProperties = createConstructorProperties(source, fieldsToParam);
        constructor.annotations = copyAnnotations(source, onConstructor.toArray(new Annotation[0]), constructorProperties);
    }
    constructor.traverse(new SetGeneratedByVisitor(source), typeDeclaration.scope);
    return constructor;
}
Also used : Argument(org.eclipse.jdt.internal.compiler.ast.Argument) ArrayList(java.util.ArrayList) SingleNameReference(org.eclipse.jdt.internal.compiler.ast.SingleNameReference) FieldDeclaration(org.eclipse.jdt.internal.compiler.ast.FieldDeclaration) Assignment(org.eclipse.jdt.internal.compiler.ast.Assignment) ExplicitConstructorCall(org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall) MessageSend(org.eclipse.jdt.internal.compiler.ast.MessageSend) ConstructorDeclaration(org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration) ASTNode(org.eclipse.jdt.internal.compiler.ast.ASTNode) FieldReference(org.eclipse.jdt.internal.compiler.ast.FieldReference) Statement(org.eclipse.jdt.internal.compiler.ast.Statement) ReturnStatement(org.eclipse.jdt.internal.compiler.ast.ReturnStatement) ThisReference(org.eclipse.jdt.internal.compiler.ast.ThisReference) SingleMemberAnnotation(org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation) Annotation(org.eclipse.jdt.internal.compiler.ast.Annotation) Expression(org.eclipse.jdt.internal.compiler.ast.Expression) AllocationExpression(org.eclipse.jdt.internal.compiler.ast.AllocationExpression) EclipseNode(lombok.eclipse.EclipseNode) TypeDeclaration(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration)

Example 49 with ThisReference

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

the class HandleSuperBuilder method generateFillValuesMethod.

/**
 * Generates a <code>$fillValuesFrom()</code> method in the abstract builder class that looks
 * like this:
 * <pre>
 * protected B $fillValuesFrom(final C instance) {
 *     super.$fillValuesFrom(instance);
 *     Foobar.FoobarBuilder.$fillValuesFromInstanceIntoBuilder(instance, this);
 *     return self();
 * }
 * </pre>
 */
private MethodDeclaration generateFillValuesMethod(SuperBuilderJob job, boolean inherited, String builderGenericName, String classGenericName) {
    MethodDeclaration out = job.createNewMethodDeclaration();
    out.selector = FILL_VALUES_METHOD_NAME;
    out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
    out.modifiers = ClassFileConstants.AccProtected;
    if (inherited)
        out.annotations = new Annotation[] { makeMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, job.parentType.get()) };
    out.returnType = new SingleTypeReference(builderGenericName.toCharArray(), 0);
    TypeReference builderType = new SingleTypeReference(classGenericName.toCharArray(), 0);
    out.arguments = new Argument[] { new Argument(INSTANCE_VARIABLE_NAME, 0, builderType, Modifier.FINAL) };
    List<Statement> body = new ArrayList<Statement>();
    if (inherited) {
        // Call super.
        MessageSend callToSuper = new MessageSend();
        callToSuper.receiver = new SuperReference(0, 0);
        callToSuper.selector = FILL_VALUES_METHOD_NAME;
        callToSuper.arguments = new Expression[] { new SingleNameReference(INSTANCE_VARIABLE_NAME, 0) };
        body.add(callToSuper);
    }
    // Call the builder implemention's helper method that actually fills the values from the instance.
    MessageSend callStaticFillValuesMethod = new MessageSend();
    callStaticFillValuesMethod.receiver = generateNameReference(job.parentType, job.builderAbstractClassNameArr, 0);
    callStaticFillValuesMethod.selector = FILL_VALUES_STATIC_METHOD_NAME;
    callStaticFillValuesMethod.arguments = new Expression[] { new SingleNameReference(INSTANCE_VARIABLE_NAME, 0), new ThisReference(0, 0) };
    body.add(callStaticFillValuesMethod);
    // Return self().
    MessageSend returnCall = new MessageSend();
    returnCall.receiver = ThisReference.implicitThis();
    returnCall.selector = SELF_METHOD_NAME;
    body.add(new ReturnStatement(returnCall, 0, 0));
    out.statements = body.isEmpty() ? null : body.toArray(new Statement[0]);
    return out;
}
Also used : Argument(org.eclipse.jdt.internal.compiler.ast.Argument) MethodDeclaration(org.eclipse.jdt.internal.compiler.ast.MethodDeclaration) AbstractMethodDeclaration(org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration) Statement(org.eclipse.jdt.internal.compiler.ast.Statement) ReturnStatement(org.eclipse.jdt.internal.compiler.ast.ReturnStatement) IfStatement(org.eclipse.jdt.internal.compiler.ast.IfStatement) ArrayList(java.util.ArrayList) ThisReference(org.eclipse.jdt.internal.compiler.ast.ThisReference) SingleNameReference(org.eclipse.jdt.internal.compiler.ast.SingleNameReference) MarkerAnnotation(org.eclipse.jdt.internal.compiler.ast.MarkerAnnotation) Annotation(org.eclipse.jdt.internal.compiler.ast.Annotation) SuperReference(org.eclipse.jdt.internal.compiler.ast.SuperReference) MessageSend(org.eclipse.jdt.internal.compiler.ast.MessageSend) ParameterizedSingleTypeReference(org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference) SingleTypeReference(org.eclipse.jdt.internal.compiler.ast.SingleTypeReference) ReturnStatement(org.eclipse.jdt.internal.compiler.ast.ReturnStatement) 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)

Example 50 with ThisReference

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

the class HandleSuperBuilder method generateBuilderBasedConstructor.

/**
 * Generates a constructor that has a builder as the only parameter.
 * The values from the builder are used to initialize the fields of new instances.
 *
 * @param callBuilderBasedSuperConstructor
 *            If {@code true}, the constructor will explicitly call a super
 *            constructor with the builder as argument. Requires
 *            {@code builderClassAsParameter != null}.
 */
private void generateBuilderBasedConstructor(BuilderJob job, boolean callBuilderBasedSuperConstructor) {
    TypeDeclaration typeDeclaration = ((TypeDeclaration) job.parentType.get());
    long p = job.getPos();
    ConstructorDeclaration constructor = new ConstructorDeclaration(((CompilationUnitDeclaration) job.parentType.top().get()).compilationResult);
    constructor.modifiers = toEclipseModifier(AccessLevel.PROTECTED);
    constructor.selector = typeDeclaration.name;
    if (callBuilderBasedSuperConstructor) {
        constructor.constructorCall = new ExplicitConstructorCall(ExplicitConstructorCall.Super);
        constructor.constructorCall.arguments = new Expression[] { new SingleNameReference(BUILDER_VARIABLE_NAME, p) };
    } else {
        constructor.constructorCall = new ExplicitConstructorCall(ExplicitConstructorCall.ImplicitSuper);
    }
    constructor.constructorCall.sourceStart = job.source.sourceStart;
    constructor.constructorCall.sourceEnd = job.source.sourceEnd;
    constructor.thrownExceptions = null;
    constructor.typeParameters = null;
    constructor.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
    constructor.bodyStart = constructor.declarationSourceStart = constructor.sourceStart = job.source.sourceStart;
    constructor.bodyEnd = constructor.declarationSourceEnd = constructor.sourceEnd = job.source.sourceEnd;
    TypeReference[] wildcards = new TypeReference[] { new Wildcard(Wildcard.UNBOUND), new Wildcard(Wildcard.UNBOUND) };
    TypeReference builderType = generateParameterizedTypeReference(job.parentType, job.builderClassNameArr, false, mergeToTypeReferences(job.typeParams, wildcards), p);
    constructor.arguments = new Argument[] { new Argument(BUILDER_VARIABLE_NAME, p, builderType, Modifier.FINAL) };
    List<Statement> statements = new ArrayList<Statement>();
    for (BuilderFieldData fieldNode : job.builderFields) {
        FieldReference fieldInThis = new FieldReference(fieldNode.rawName, p);
        int s = (int) (p >> 32);
        int e = (int) p;
        fieldInThis.receiver = new ThisReference(s, e);
        Expression assignmentExpr;
        if (fieldNode.singularData != null && fieldNode.singularData.getSingularizer() != null) {
            fieldNode.singularData.getSingularizer().appendBuildCode(fieldNode.singularData, job.parentType, statements, fieldNode.builderFieldName, BUILDER_VARIABLE_NAME_STRING);
            assignmentExpr = new SingleNameReference(fieldNode.builderFieldName, p);
        } else {
            char[][] variableInBuilder = new char[][] { BUILDER_VARIABLE_NAME, fieldNode.builderFieldName };
            long[] positions = new long[] { p, p };
            assignmentExpr = new QualifiedNameReference(variableInBuilder, positions, s, e);
        }
        Statement assignment = new Assignment(fieldInThis, assignmentExpr, (int) p);
        // In case of @Builder.Default, set the value to the default if it was NOT set in the builder.
        if (fieldNode.nameOfSetFlag != null) {
            char[][] setVariableInBuilder = new char[][] { BUILDER_VARIABLE_NAME, fieldNode.nameOfSetFlag };
            long[] positions = new long[] { p, p };
            QualifiedNameReference setVariableInBuilderRef = new QualifiedNameReference(setVariableInBuilder, positions, s, e);
            MessageSend defaultMethodCall = new MessageSend();
            defaultMethodCall.sourceStart = job.source.sourceStart;
            defaultMethodCall.sourceEnd = job.source.sourceEnd;
            defaultMethodCall.receiver = generateNameReference(job.parentType, 0L);
            defaultMethodCall.selector = fieldNode.nameOfDefaultProvider;
            defaultMethodCall.typeArguments = typeParameterNames(((TypeDeclaration) job.parentType.get()).typeParameters);
            Statement defaultAssignment = new Assignment(fieldInThis, defaultMethodCall, (int) p);
            IfStatement ifBlockForDefault = new IfStatement(setVariableInBuilderRef, assignment, defaultAssignment, s, e);
            statements.add(ifBlockForDefault);
        } else {
            statements.add(assignment);
        }
        if (hasNonNullAnnotations(fieldNode.originalFieldNode)) {
            Statement nullCheck = generateNullCheck((FieldDeclaration) fieldNode.originalFieldNode.get(), job.sourceNode, null);
            if (nullCheck != null)
                statements.add(nullCheck);
        }
    }
    constructor.statements = statements.isEmpty() ? null : statements.toArray(new Statement[0]);
    if (job.checkerFramework.generateSideEffectFree()) {
        constructor.annotations = new Annotation[] { generateNamedAnnotation(job.source, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE) };
    }
    constructor.traverse(new SetGeneratedByVisitor(job.source), typeDeclaration.scope);
    injectMethod(job.parentType, constructor);
}
Also used : BuilderFieldData(lombok.eclipse.handlers.HandleBuilder.BuilderFieldData) 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) IfStatement(org.eclipse.jdt.internal.compiler.ast.IfStatement) ArrayList(java.util.ArrayList) ThisReference(org.eclipse.jdt.internal.compiler.ast.ThisReference) SingleNameReference(org.eclipse.jdt.internal.compiler.ast.SingleNameReference) Assignment(org.eclipse.jdt.internal.compiler.ast.Assignment) ExplicitConstructorCall(org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall) MessageSend(org.eclipse.jdt.internal.compiler.ast.MessageSend) IfStatement(org.eclipse.jdt.internal.compiler.ast.IfStatement) Wildcard(org.eclipse.jdt.internal.compiler.ast.Wildcard) Expression(org.eclipse.jdt.internal.compiler.ast.Expression) ConditionalExpression(org.eclipse.jdt.internal.compiler.ast.ConditionalExpression) AllocationExpression(org.eclipse.jdt.internal.compiler.ast.AllocationExpression) EqualExpression(org.eclipse.jdt.internal.compiler.ast.EqualExpression) ConstructorDeclaration(org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration) 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) TypeDeclaration(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) QualifiedNameReference(org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference)

Aggregations

ThisReference (org.eclipse.jdt.internal.compiler.ast.ThisReference)56 MethodDeclaration (org.eclipse.jdt.internal.compiler.ast.MethodDeclaration)44 Statement (org.eclipse.jdt.internal.compiler.ast.Statement)43 FieldReference (org.eclipse.jdt.internal.compiler.ast.FieldReference)38 IfStatement (org.eclipse.jdt.internal.compiler.ast.IfStatement)38 MessageSend (org.eclipse.jdt.internal.compiler.ast.MessageSend)37 ReturnStatement (org.eclipse.jdt.internal.compiler.ast.ReturnStatement)37 ArrayList (java.util.ArrayList)31 SingleNameReference (org.eclipse.jdt.internal.compiler.ast.SingleNameReference)31 TypeReference (org.eclipse.jdt.internal.compiler.ast.TypeReference)27 Annotation (org.eclipse.jdt.internal.compiler.ast.Annotation)26 QualifiedTypeReference (org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference)26 Expression (org.eclipse.jdt.internal.compiler.ast.Expression)22 Argument (org.eclipse.jdt.internal.compiler.ast.Argument)21 EqualExpression (org.eclipse.jdt.internal.compiler.ast.EqualExpression)20 Assignment (org.eclipse.jdt.internal.compiler.ast.Assignment)16 NullLiteral (org.eclipse.jdt.internal.compiler.ast.NullLiteral)16 AbstractMethodDeclaration (org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration)15 AllocationExpression (org.eclipse.jdt.internal.compiler.ast.AllocationExpression)15 EclipseNode (lombok.eclipse.EclipseNode)13