示例#1
0
        public static CodeWriter WriteInitialization(this CodeWriter writer, ObjectType objectType, IEnumerable <ObjectPropertyInitializer> initializers)
        {
            ObjectPropertyInitializer?FindInitializerForParameter(ObjectTypeConstructor constructor, Parameter constructorParameter)
            {
                var property = constructor.FindPropertyInitializedByParameter(constructorParameter);

                return(initializers.SingleOrDefault(i => i.Property == property));
            }

            // Checks if constructor parameters can be satisfied by the provided initializer list
            List <ObjectPropertyInitializer>?TryGetParameters(ObjectTypeConstructor constructor)
            {
                List <ObjectPropertyInitializer> constructorInitializers = new List <ObjectPropertyInitializer>();

                foreach (var constructorParameter in constructor.Parameters)
                {
                    var objectPropertyInitializer = FindInitializerForParameter(constructor, constructorParameter);
                    if (objectPropertyInitializer == null)
                    {
                        return(null);
                    }

                    constructorInitializers.Add(objectPropertyInitializer);
                }

                return(constructorInitializers);
            }

            // Find longest satisfiable ctor
            List <ObjectPropertyInitializer>?selectedCtorInitializers = null;

            foreach (var constructor in objectType.Constructors)
            {
                var newInitializers = TryGetParameters(constructor);
                if (newInitializers != null &&
                    newInitializers.Count > (selectedCtorInitializers?.Count ?? -1))
                {
                    selectedCtorInitializers = newInitializers;
                }
            }

            Debug.Assert(selectedCtorInitializers != null);

            writer.Append($"new {objectType.Type}(");
            foreach (var initializer in selectedCtorInitializers)
            {
                writer.WriteReferenceOrConstant(initializer.Value);
                writer.WriteConversion(initializer.Value.Type, initializer.Property.Declaration.Type);
                writer.Append($", ");
            }
            writer.RemoveTrailingComma();
            writer.Append($")");

            // Find properties that would have to be initialized via property initializers
            var restOfInitializers = initializers.Except(selectedCtorInitializers).ToArray();

            if (restOfInitializers.Any())
            {
                using (writer.Scope($"", newLine: false))
                {
                    foreach (var propertyInitializer in restOfInitializers)
                    {
                        writer.Append($"{propertyInitializer.Property.Declaration.Name} = ")
                        .WriteReferenceOrConstant(propertyInitializer.Value);

                        writer.WriteConversion(propertyInitializer.Value.Type, propertyInitializer.Property.Declaration.Type);

                        writer.Line($",");
                    }

                    writer.RemoveTrailingComma();
                }
            }

            return(writer);
        }