コード例 #1
0
        private void WriteDiagnosticScope(CodeWriter writer, Diagnostic diagnostic, CodeWriterDelegate inner)
        {
            var scopeVariable = new CodeWriterDeclaration("scope");

            writer.Line($"using var {scopeVariable:D} = {ClientDiagnosticsField}.CreateScope({diagnostic.ScopeName:L});");
            foreach (DiagnosticAttribute diagnosticScopeAttributes in diagnostic.Attributes)
            {
                writer.Append($"{scopeVariable}.AddAttribute({diagnosticScopeAttributes.Name:L},");
                writer.WriteReferenceOrConstant(diagnosticScopeAttributes.Value);
                writer.Line($");");
            }

            writer.Line($"{scopeVariable}.Start();");

            using (writer.Scope($"try"))
            {
                inner(writer);
            }

            using (writer.Scope($"catch ({typeof(Exception)} e)"))
            {
                writer.Line($"{scopeVariable}.Failed(e);");
                writer.Line($"throw;");
            }
        }
コード例 #2
0
        public static void DeserializeImplementation(this CodeWriter writer, TypeProvider implementation, CodeWriterDelegate element)
        {
            switch (implementation)
            {
            case ObjectType objectType:
                writer.Append($"{implementation.Type}.Deserialize{objectType.Declaration.Name}({element})");
                break;

            case EnumType clientEnum when clientEnum.IsExtendable:
                writer.Append($"new {implementation.Type}(");
                DeserializeFrameworkTypeValue(writer, element, clientEnum.BaseType.FrameworkType, SerializationFormat.Default);
                writer.Append($")");
                break;

            case EnumType clientEnum when !clientEnum.IsExtendable:
                DeserializeFrameworkTypeValue(writer, element, clientEnum.BaseType.FrameworkType, SerializationFormat.Default);
                writer.Append($".To{clientEnum.Declaration.Name}()");
                break;
            }
        }
コード例 #3
0
        private static void DeserializeFrameworkTypeValue(CodeWriter writer, CodeWriterDelegate element, Type frameworkType, SerializationFormat serializationFormat)
        {
            bool includeFormat = false;

            writer.Append($"{element}.");

            if (frameworkType == typeof(JsonElement))
            {
                writer.AppendRaw("Clone");
            }
            if (frameworkType == typeof(object))
            {
                writer.AppendRaw("GetObject");
            }
            if (frameworkType == typeof(bool))
            {
                writer.AppendRaw("GetBoolean");
            }
            if (frameworkType == typeof(char))
            {
                writer.AppendRaw("GetChar");
            }
            if (frameworkType == typeof(short))
            {
                writer.AppendRaw("GetInt16");
            }
            if (frameworkType == typeof(int))
            {
                writer.AppendRaw("GetInt32");
            }
            if (frameworkType == typeof(long))
            {
                writer.AppendRaw("GetInt64");
            }
            if (frameworkType == typeof(float))
            {
                writer.AppendRaw("GetSingle");
            }
            if (frameworkType == typeof(double))
            {
                writer.AppendRaw("GetDouble");
            }
            if (frameworkType == typeof(decimal))
            {
                writer.AppendRaw("GetDecimal");
            }
            if (frameworkType == typeof(string))
            {
                writer.AppendRaw("GetString");
            }
            if (frameworkType == typeof(Guid))
            {
                writer.AppendRaw("GetGuid");
            }

            if (frameworkType == typeof(byte[]))
            {
                writer.AppendRaw("GetBytesFromBase64");
                includeFormat = true;
            }

            if (frameworkType == typeof(DateTimeOffset))
            {
                writer.AppendRaw("GetDateTimeOffset");
                includeFormat = true;
            }

            if (frameworkType == typeof(TimeSpan))
            {
                writer.AppendRaw("GetTimeSpan");
                includeFormat = true;
            }

            writer.AppendRaw("(");

            if (includeFormat && serializationFormat.ToFormatSpecifier() is string formatString)
            {
                writer.Literal(formatString);
            }

            writer.AppendRaw(")");
        }
コード例 #4
0
        private static void DeserializeValue(this CodeWriter writer, JsonValueSerialization serialization, CodeWriterDelegate element)
        {
            writer.UseNamespace(typeof(JsonElementExtensions).Namespace !);

            if (serialization.Type.IsFrameworkType)
            {
                DeserializeFrameworkTypeValue(writer, element, serialization.Type.FrameworkType, serialization.Format);
            }
            else
            {
                writer.DeserializeImplementation(serialization.Type.Implementation, element);
            }
        }
コード例 #5
0
 public static void DeserializeValue(this CodeWriter writer, JsonSerialization serialization, CodeWriterDelegate value, Action <CodeWriter, CodeWriterDelegate> valueCallback)
 {
     writer.DeserializeIntoVariableMayBeObject(
         serialization,
         valueCallback,
         value);
 }
コード例 #6
0
        private static void DeserializeIntoVariable(this CodeWriter writer, JsonSerialization serialization, Action <CodeWriter, CodeWriterDelegate> valueCallback, CodeWriterDelegate element)
        {
            switch (serialization)
            {
            case JsonArraySerialization array:
                var arrayVariable = new CodeWriterDeclaration("array");
                writer.Line($"{array.Type} {arrayVariable:D} = new {array.Type}();");

                var collectionItemVariable = new CodeWriterDeclaration("item");
                using (writer.Scope($"foreach (var {collectionItemVariable:D} in {element}.EnumerateArray())"))
                {
                    writer.DeserializeValue(
                        array.ValueSerialization,
                        w => w.Append($"{collectionItemVariable}"),
                        (w, returnValue) => writer.Append($"{arrayVariable}.Add({returnValue});"));
                }

                valueCallback(writer, w => w.Append(arrayVariable));
                return;

            case JsonDictionarySerialization dictionary:
                var dictionaryVariable = new CodeWriterDeclaration("dictionary");
                writer.Line($"{dictionary.Type} {dictionaryVariable:D} = new {dictionary.Type}();");

                var dictionaryItemVariable = new CodeWriterDeclaration("property");
                using (writer.Scope($"foreach (var {dictionaryItemVariable:D} in {element}.EnumerateObject())"))
                {
                    writer.DeserializeValue(
                        dictionary.ValueSerialization,
                        w => w.Append($"{dictionaryItemVariable}.Value"),
                        (w, returnValue) => writer.Append($"{dictionaryVariable}.Add({dictionaryItemVariable}.Name, {returnValue});"));
                }

                valueCallback(writer, w => w.Append(dictionaryVariable));
                return;

            case JsonValueSerialization valueSerialization:
                valueCallback(writer, w => w.DeserializeValue(valueSerialization, element));
                return;
            }
        }
コード例 #7
0
        private static void DeserializeIntoVariableWithNullHandling(this CodeWriter writer, JsonSerialization serialization, Action <CodeWriter, CodeWriterDelegate> valueCallback, CodeWriterDelegate element)
        {
            CSharpType?type = null;

            switch (serialization)
            {
            case JsonArraySerialization array:
                type = array.Type;
                break;

            case JsonDictionarySerialization dictionary:
                type = dictionary.Type;
                break;

            case JsonValueSerialization valueSerialization:
                type = valueSerialization.Type;
                break;
            }

            if (type != null && (type.IsNullable || !type.IsValueType))
            {
                using (writer.Scope($"if ({element}.ValueKind == {typeof(JsonValueKind)}.Null)"))
                {
                    valueCallback(writer, w => w.Append($"null"));
                }
                using (writer.Scope($"else"))
                {
                    writer.DeserializeIntoVariable(serialization, valueCallback, element);
                }
            }
            else
            {
                writer.DeserializeIntoVariable(serialization, valueCallback, element);
            }
        }
コード例 #8
0
        private static void DeserializeIntoVariableMayBeObject(this CodeWriter writer,
                                                               JsonSerialization serialization,
                                                               Action <CodeWriter, CodeWriterDelegate> valueCallback,
                                                               CodeWriterDelegate element,
                                                               Dictionary <ObjectTypeProperty, CodeWriterDeclaration>?propertyVariables = null)
        {
            if (serialization is JsonObjectSerialization obj)
            {
                var itemVariable = new CodeWriterDeclaration("property");

                if (propertyVariables == null)
                {
                    // this is the first level of object hierarchy
                    // collect all properties and initialize the dictionary
                    propertyVariables = new Dictionary <ObjectTypeProperty, CodeWriterDeclaration>();

                    CollectProperties(propertyVariables, obj);

                    foreach (var variable in propertyVariables)
                    {
                        var objectTypeProperty = variable.Key;
                        writer.Line($"{objectTypeProperty.Declaration.Type} {variable.Value:D} = default;");
                    }
                }

                var dictionaryVariable = new CodeWriterDeclaration("additionalPropertiesDictionary");

                var objAdditionalProperties = obj.AdditionalProperties;
                if (objAdditionalProperties != null)
                {
                    writer.Line($"{objAdditionalProperties.Type} {dictionaryVariable:D} = default;");
                }

                using (writer.Scope($"foreach (var {itemVariable:D} in {element}.EnumerateObject())"))
                {
                    foreach (JsonPropertySerialization property in obj.Properties)
                    {
                        CSharpType?type = property.Property?.Declaration.Type;

                        bool hasNullableType = type != null && type.IsNullable;

                        void WriteNullCheck()
                        {
                            using (writer.Scope($"if ({itemVariable.ActualName}.Value.ValueKind == {typeof(JsonValueKind)}.Null)"))
                            {
                                writer.Append($"continue;");
                            }
                        }

                        writer.Append($"if({itemVariable.ActualName}.NameEquals({property.Name:L}))");
                        using (writer.Scope())
                        {
                            if (hasNullableType)
                            {
                                WriteNullCheck();
                            }

                            if (property.Property != null)
                            {
                                // Reading a property value
                                writer.DeserializeIntoVariable(
                                    property.ValueSerialization,
                                    (w, v) => w.Line($"{propertyVariables[property.Property]} = {v};"),
                                    w => w.Append($"{itemVariable.ActualName}.Value"));
                            }
                            else
                            {
                                // Reading a nested object
                                writer.DeserializeIntoVariableMayBeObject(
                                    property.ValueSerialization,
                                    (w, v) => { },
                                    w => w.Append($"{itemVariable.ActualName}.Value"),
                                    propertyVariables);
                            }

                            writer.Line($"continue;");
                        }
                    }

                    if (objAdditionalProperties != null)
                    {
                        writer.Line($"{dictionaryVariable} ??= new {objAdditionalProperties.Type}();");
                        writer.DeserializeValue(
                            objAdditionalProperties.ValueSerialization,
                            w => w.Append($"{itemVariable}.Value"),
                            (w, v) => w.Line($"{dictionaryVariable}.Add({itemVariable}.Name, {v});"));
                    }
                }

                if (objAdditionalProperties != null)
                {
                    writer.Line($"{propertyVariables[objAdditionalProperties.Property]} = {dictionaryVariable};");
                }

                if (obj.Type != null)
                {
                    var initializers = new List <ObjectPropertyInitializer>();
                    foreach (var variable in propertyVariables)
                    {
                        var property = variable.Key;

                        initializers.Add(new ObjectPropertyInitializer(
                                             property,
                                             new Reference(variable.Value.ActualName, property.Declaration.Type)));
                    }

                    valueCallback(writer,
                                  w => w.WriteInitialization((ObjectType)obj.Type.Implementation, initializers));
                }
            }
            else
            {
                writer.DeserializeIntoVariableWithNullHandling(serialization, valueCallback, element);
            }
        }
コード例 #9
0
        public static void ToSerializeCall(this CodeWriter writer, JsonSerialization serialization, CodeWriterDelegate name, CodeWriterDelegate?writerName = null)
        {
            writerName ??= w => w.AppendRaw("writer");

            switch (serialization)
            {
            case JsonArraySerialization array:
                writer.Line($"{writerName}.WriteStartArray();");
                var collectionItemVariable = new CodeWriterDeclaration("item");

                using (writer.Scope($"foreach (var {collectionItemVariable:D} in {name})"))
                {
                    writer.ToSerializeCall(
                        array.ValueSerialization,
                        w => w.Append(collectionItemVariable),
                        writerName);
                }

                writer.Line($"{writerName}.WriteEndArray();");
                return;

            case JsonDictionarySerialization dictionary:
                writer.Line($"{writerName}.WriteStartObject();");
                var dictionaryItemVariable = new CodeWriterDeclaration("item");

                using (writer.Scope($"foreach (var {dictionaryItemVariable:D} in {name})"))
                {
                    writer.Line($"{writerName}.WritePropertyName({dictionaryItemVariable}.Key);");
                    writer.ToSerializeCall(
                        dictionary.ValueSerialization,
                        w => w.Append($"{dictionaryItemVariable}.Value"),
                        writerName);
                }

                writer.Line($"{writerName}.WriteEndObject();");
                return;

            case JsonObjectSerialization obj:
                writer.Line($"{writerName}.WriteStartObject();");

                foreach (JsonPropertySerialization property in obj.Properties)
                {
                    bool hasNullableType  = property.Property?.Declaration.Type.IsNullable == true;
                    bool emptyAsUndefined = property.Property?.EmptyAsUndefined == true;

                    CodeWriter.CodeWriterScope?scope = default;
                    if (hasNullableType || emptyAsUndefined)
                    {
                        var propertyName = property.Property !.Declaration.Name;
                        writer.Append($"if (");
                        if (hasNullableType)
                        {
                            writer.Append($"{propertyName} != null");
                        }

                        if (emptyAsUndefined)
                        {
                            if (hasNullableType)
                            {
                                writer.Append($" && ");
                            }
                            writer.UseNamespace(typeof(Enumerable).Namespace !);
                            writer.Append($"{propertyName}.Any()");
                        }
                        writer.Append($")");
                        scope = writer.Scope();
                    }

                    using (scope)
                    {
                        writer.Line($"{writerName}.WritePropertyName({property.Name:L});");
                        writer.ToSerializeCall(
                            property.ValueSerialization,
                            w => w.Append($"{property.Property?.Declaration.Name}"));
                    }
                }

                if (obj.AdditionalProperties != null)
                {
                    var itemVariable = new CodeWriterDeclaration("item");

                    using (writer.Scope($"foreach (var {itemVariable:D} in {obj.AdditionalProperties.Property.Declaration.Name})"))
                    {
                        writer.Line($"{writerName}.WritePropertyName({itemVariable}.Key);");
                        writer.ToSerializeCall(
                            obj.AdditionalProperties.ValueSerialization,
                            w => w.Append($"{itemVariable}.Value"),
                            writerName);
                    }
                }

                writer.Line($"{writerName}.WriteEndObject();");
                return;

            case JsonValueSerialization valueSerialization:
                writer.UseNamespace(typeof(Utf8JsonWriterExtensions).Namespace !);

                if (valueSerialization.Type.IsFrameworkType)
                {
                    var frameworkType = valueSerialization.Type.FrameworkType;

                    if (frameworkType == typeof(JsonElement))
                    {
                        writer.Line($"{name}.WriteTo({writerName});");
                        return;
                    }

                    bool writeFormat = false;

                    writer.Append($"{writerName}.");
                    if (frameworkType == typeof(decimal) ||
                        frameworkType == typeof(double) ||
                        frameworkType == typeof(float) ||
                        frameworkType == typeof(long) ||
                        frameworkType == typeof(int) ||
                        frameworkType == typeof(short))
                    {
                        writer.AppendRaw("WriteNumberValue");
                    }
                    else if (frameworkType == typeof(object))
                    {
                        writer.AppendRaw("WriteObjectValue");
                    }
                    else if (frameworkType == typeof(string) ||
                             frameworkType == typeof(char) ||
                             frameworkType == typeof(Guid))
                    {
                        writer.AppendRaw("WriteStringValue");
                    }
                    else if (frameworkType == typeof(bool))
                    {
                        writer.AppendRaw("WriteBooleanValue");
                    }
                    else if (frameworkType == typeof(byte[]))
                    {
                        writer.AppendRaw("WriteBase64StringValue");
                        writeFormat = true;
                    }
                    else if (frameworkType == typeof(DateTimeOffset) ||
                             frameworkType == typeof(DateTime) ||
                             frameworkType == typeof(TimeSpan))
                    {
                        if (valueSerialization.Format == SerializationFormat.DateTime_Unix)
                        {
                            writer.AppendRaw("WriteNumberValue");
                        }
                        else
                        {
                            writer.AppendRaw("WriteStringValue");
                        }
                        writeFormat = true;
                    }

                    writer.Append($"({name}")
                    .AppendNullableValue(valueSerialization.Type);

                    if (writeFormat && valueSerialization.Format.ToFormatSpecifier() is string formatString)
                    {
                        writer.Append($", {formatString:L}");
                    }

                    writer.LineRaw(");");
                    return;
                }

                switch (valueSerialization.Type.Implementation)
                {
                case ObjectType _:
                    writer.Line($"{writerName}.WriteObjectValue({name});");
                    return;

                case EnumType clientEnum:
                    writer.Append($"{writerName}.WriteStringValue({name}")
                    .AppendNullableValue(valueSerialization.Type)
                    .AppendEnumToString(clientEnum)
                    .Line($");");
                    return;
                }

                throw new NotSupportedException();

            default:
                throw new NotSupportedException();
            }
        }
コード例 #10
0
        public static void ToSerializeCall(this CodeWriter writer, XmlElementSerialization serialization, CodeWriterDelegate name, CodeWriterDelegate?writerName = null, CodeWriterDelegate?nameHint = null)
        {
            writerName ??= w => w.AppendRaw("writer");

            switch (serialization)
            {
            case XmlArraySerialization array:

                if (array.Wrapped)
                {
                    writer.Line($"{writerName}.WriteStartElement({array.Name:L});");
                }

                var itemVariable = new CodeWriterDeclaration("item");

                using (writer.Scope($"foreach (var {itemVariable:D} in {name})"))
                {
                    writer.ToSerializeCall(
                        array.ValueSerialization,
                        w => w.Append($"{itemVariable}"),
                        writerName);
                }

                if (array.Wrapped)
                {
                    writer.Line($"{writerName}.WriteEndElement();");
                }

                break;

            case XmlDictionarySerialization dictionarySerialization:
                var pairVariable = new CodeWriterDeclaration("pair");
                using (writer.Scope($"foreach (var {pairVariable:D} in {name})"))
                {
                    writer.ToSerializeCall(
                        dictionarySerialization.ValueSerialization,
                        w => w.Append($"{pairVariable}.Value"),
                        writerName);
                }

                break;

            case XmlObjectSerialization objectSerialization:
                if (nameHint != null)
                {
                    writer.Line($"{writerName}.WriteStartElement({nameHint} ?? {objectSerialization.Name:L});");
                }
                else
                {
                    writer.Line($"{writerName}.WriteStartElement({objectSerialization.Name:L});");
                }

                CodeWriter.CodeWriterScope?CheckPropertyForNull(ObjectTypeProperty objectTypeProperty)
                {
                    return(objectTypeProperty.Declaration.Type.IsNullable ? writer.Scope($"if ({objectTypeProperty.Declaration.Name} != null)") : default);
                }

                foreach (XmlObjectAttributeSerialization property in objectSerialization.Attributes)
                {
                    using (CheckPropertyForNull(property.Property))
                    {
                        writer.Line($"{writerName}.WriteStartAttribute({property.Name:L});");
                        writer.ToSerializeValueCall(
                            w => w.Append($"{property.Property.Declaration.Name}"),
                            writerName,
                            property.ValueSerialization);
                        writer.Line($"{writerName}.WriteEndAttribute();");
                    }
                }

                foreach (XmlObjectElementSerialization property in objectSerialization.Elements)
                {
                    using (CheckPropertyForNull(property.Property))
                    {
                        writer.ToSerializeCall(
                            property.ValueSerialization,
                            w => w.Append($"{property.Property.Declaration.Name}"));
                    }
                }

                foreach (XmlObjectArraySerialization property in objectSerialization.EmbeddedArrays)
                {
                    using (CheckPropertyForNull(property.Property))
                    {
                        writer.ToSerializeCall(
                            property.ArraySerialization,
                            w => w.Append($"{property.Property.Declaration.Name}"));
                    }
                }

                writer.Line($"{writerName}.WriteEndElement();");
                return;
コード例 #11
0
 public SerializationData(CodeWriterDelegate write, CSharpType type)
 {
     Write = write;
     Type  = type;
 }
コード例 #12
0
        private static void WriteSerializeContent(CodeWriter writer, CodeWriterDeclaration request, ObjectSerialization bodySerialization, CodeWriterDelegate valueDelegate)
        {
            switch (bodySerialization)
            {
            case JsonSerialization jsonSerialization:
            {
                var content = new CodeWriterDeclaration("content");

                writer.Line($"using var {content:D} = new {typeof(Utf8JsonRequestContent)}();");
                writer.ToSerializeCall(
                    jsonSerialization,
                    valueDelegate,
                    writerName: w => w.Append($"{content}.{nameof(Utf8JsonRequestContent.JsonWriter)}"));
                writer.Line($"{request}.Content = {content};");
                break;
            }

            case XmlElementSerialization xmlSerialization:
            {
                var content = new CodeWriterDeclaration("content");

                writer.Line($"using var {content:D} = new {typeof(XmlWriterContent)}();");
                writer.ToSerializeCall(
                    xmlSerialization,
                    valueDelegate,
                    writerName: w => w.Append($"{content}.{nameof(XmlWriterContent.XmlWriter)}"));
                writer.Line($"{request}.Content = {content};");
                break;
            }

            default:
                throw new NotImplementedException(bodySerialization.ToString());
            }
        }