private static bool TryAddBuildMethod(GeneratorExecutionContext context,
                                              ClassDefinition classDefinition,
                                              ref ClassDeclarationSyntax builderClass)
        {
            var objectType            = classDefinition.TypeSyntax;
            var buildMethodStatements = new List <StatementSyntax>();

            var propertiesSetViaConstructor = new List <PropertyDefinition>();

            if (!GetCreationExpression(context, classDefinition, objectType, propertiesSetViaConstructor,
                                       buildMethodStatements, out ObjectCreationExpressionSyntax creationExpression))
            {
                return(false);
            }

            var buildingInstanceIdentifier = Identifier("instance");

            buildMethodStatements.Add(CreateLocalVariable(buildingInstanceIdentifier, creationExpression));
            buildMethodStatements.AddRange(classDefinition.Properties.Except(propertiesSetViaConstructor)
                                           .Select(property => GetNullableArgument(property, buildingInstanceIdentifier)));
            buildMethodStatements.Add(ReturnStatement(IdentifierName(buildingInstanceIdentifier)));
            builderClass = builderClass.AddPublicMethod(objectType, "Build", buildMethodStatements);

            return(true);
        }
        private static ClassDeclarationSyntax CreateWithMethod(
            ClassDefinition builder,
            ClassDeclarationSyntax builderClass,
            PropertyDefinition propertyDefinition)
        {
            var lowerCamelParameterName = propertyDefinition.PropertyName.ToCamelCase();
            var upperCamelParameterName = propertyDefinition.PropertyName.ToPascalCase();

            var localBuilderIdentifier = Identifier("mutatedBuilder");

            builderClass = builderClass.AddPublicMethod(ParseTypeName(builder.Name),
                                                        "With" + upperCamelParameterName,
                                                        Parameter(Identifier(lowerCamelParameterName)).WithType(propertyDefinition.TypeSyntax),
                                                        CreateLocalVariable(builder, localBuilderIdentifier),
                                                        AssignLocalVariable(localBuilderIdentifier, propertyDefinition,
                                                                            IdentifierName(lowerCamelParameterName)),
                                                        ReturnStatement(IdentifierName(localBuilderIdentifier)));

            return(builderClass);
        }
        private static ClassDeclarationSyntax CreateWithoutMethod(
            ClassDefinition builder,
            ClassDeclarationSyntax builderClass,
            PropertyDefinition propertyDefinition)
        {
            if (!propertyDefinition.IsNullable && !(propertyDefinition.TypeSyntax is NullableTypeSyntax))
            {
                return(builderClass);
            }

            var upperCamelParameterName = propertyDefinition.PropertyName.ToPascalCase();

            var localBuilderIdentifier = Identifier("mutatedBuilder");

            builderClass = builderClass.AddPublicMethod(ParseTypeName(builder.Name),
                                                        "Without" + upperCamelParameterName,
                                                        CreateLocalVariable(builder, localBuilderIdentifier),
                                                        AssignLocalVariable(localBuilderIdentifier, propertyDefinition,
                                                                            LiteralExpression(NullLiteralExpression)),
                                                        ReturnStatement(IdentifierName(localBuilderIdentifier)));

            return(builderClass);
        }