Example #1
0
        private string GenerateBody(GeneratorExecutionContext context, TypeDeclarationSyntax tds, bool utcDateTime, List <string> externalInheritances, string ns)
        {
            var body = new List <string>();

            var members = context.ParseMembers(tds, false, externalInheritances, out bool isPositionalRecord);

            if (!context.CancellationToken.IsCancellationRequested)
            {
                var arrayPropertyType = typeof(ArrayPropertyAttribute);

                foreach (var member in members)
                {
                    var(symbol, typeSymbol, nullable) = member;

                    // Object field name
                    var fieldName = symbol.Name;

                    // Field type name
                    var typeName = typeSymbol.GetTypeName(nullable, ns);

                    // ArrayProperty attribute data
                    var arrayData = symbol.GetAttributeData(arrayPropertyType.FullName);

                    // Value part
                    string valuePart;

                    if (typeSymbol.IsSimpleType())
                    {
                        valuePart = $@"(await reader.GetValueAsync<{typeName}>(""{fieldName}"", names))";

                        if (utcDateTime && typeSymbol.Name == "DateTime")
                        {
                            valuePart = $"LocalizationUtils.SetUtcKind{valuePart}";
                        }
                        else if (typeSymbol.Name == "String" && !nullable)
                        {
                            valuePart += "!";
                        }
                    }
                    else if (typeSymbol.TypeKind == TypeKind.Enum)
                    {
                        // Enum item type
                        var enumSymbol = (INamedTypeSymbol)typeSymbol;
                        var enumType   = enumSymbol.EnumUnderlyingType?.Name ?? "Byte";
                        valuePart = $@"({typeName})(await reader.GetValueAsync<{enumType}>(""{fieldName}"", names))";
                    }
                    else if (typeSymbol.TypeKind == TypeKind.Array)
                    {
                        // Array type
                        var arraySymbol    = (IArrayTypeSymbol)typeSymbol;
                        var itemTypeSymbol = arraySymbol.ElementType;
                        if (!itemTypeSymbol.IsSimpleType())
                        {
                            continue;
                        }

                        // Splitter
                        var splitter = Extensions.CharToString(arrayData?.GetValue <char?>("Splitter") ?? ',');

                        var arrayType = itemTypeSymbol.Name;
                        if (arrayType.Equals("String"))
                        {
                            valuePart = $@"StringUtils.AsEnumerable(await reader.GetValueAsync<string>(""{fieldName}"", names), '{splitter}').ToArray()";
                        }
                        else
                        {
                            valuePart = $@"StringUtils.AsEnumerable<{arrayType}>(await reader.GetValueAsync<string>(""{fieldName}"", names), '{splitter}').ToArray()";
                        }
                    }
                    else if (typeSymbol.IsList())
                    {
                        // Item type
                        var listSymbol     = (INamedTypeSymbol)typeSymbol;
                        var itemTypeSymbol = listSymbol.TypeArguments[0];
                        if (!itemTypeSymbol.IsSimpleType())
                        {
                            continue;
                        }

                        // Splitter
                        var splitter = Extensions.CharToString(arrayData?.GetValue <char?>("Splitter") ?? ',');

                        var listType = itemTypeSymbol.Name;
                        if (listType.Equals("String"))
                        {
                            valuePart = $@"StringUtils.AsEnumerable(await reader.GetValueAsync<string>(""{fieldName}"", names), '{splitter}').ToList()";
                        }
                        else
                        {
                            valuePart = $@"StringUtils.AsEnumerable<{listType}>(await reader.GetValueAsync<string>(""{fieldName}"", names), '{splitter}').ToList()";
                        }
                    }
                    else
                    {
                        continue;
                    }

                    if (isPositionalRecord)
                    {
                        body.Add($@"{fieldName}: {valuePart}");
                    }
                    else
                    {
                        body.Add($@"{fieldName} = {valuePart}");
                    }
                }
            }

            // Limitation: When inheritanted, please keep the same style
            // Define constructor for Positional Record
            if (isPositionalRecord)
            {
                return("(" + string.Join(",\n", body) + ")");
            }

            return("{\n" + string.Join(",\n", body) + "\n}");
        }
Example #2
0
        private IEnumerable <string> GenerateBody(GeneratorExecutionContext context, TypeDeclarationSyntax tds, bool ignoreNull, bool snakeCase, List <string> externalInheritances)
        {
            var body = new List <string>();

            var members = context.ParseMembers(tds, true, externalInheritances, out _);

            if (!context.CancellationToken.IsCancellationRequested)
            {
                var propertyType    = typeof(PropertyAttribute);
                var ignoreName      = nameof(PropertyAttribute.Ignore);
                var isAnsiName      = nameof(PropertyAttribute.IsAnsi);
                var fixedLengthName = nameof(PropertyAttribute.FixedLength);
                var lengthName      = nameof(PropertyAttribute.Length);
                var nameField       = nameof(PropertyAttribute.Name);
                var typeNameField   = nameof(PropertyAttribute.TypeName);

                foreach (var member in members)
                {
                    var(symbol, typeSymbol, nullable) = member;

                    // Attribute data
                    var attributeData = symbol.GetAttributeData(propertyType.FullName);

                    // Ignore it?
                    var ignore = attributeData?.GetValue <bool?>(ignoreName) ?? false;
                    if (ignore)
                    {
                        continue;
                    }

                    // Is ansi, not unicode
                    var isAnsi      = attributeData?.GetValue <bool?>(isAnsiName);
                    var fixedLength = attributeData?.GetValue <bool?>(fixedLengthName);
                    var length      = attributeData?.GetValue <int?>(lengthName);

                    // Object field name
                    var fieldName = symbol.Name;

                    // Parameter name
                    var name = attributeData?.GetValue <string>(nameField);
                    if (string.IsNullOrEmpty(name))
                    {
                        name = snakeCase ? fieldName.ToSnakeCase() : fieldName;
                    }

                    // Data type name
                    var typeName = attributeData?.GetValue <string>(typeNameField);

                    // Line parts
                    string valuePart;

                    // Is dbstring
                    bool isDbString = false;

                    if (typeSymbol.IsSimpleType())
                    {
                        // Default type name from member's type
                        if (typeName == null || typeName == string.Empty)
                        {
                            typeName = typeSymbol.Name;
                        }

                        // String case
                        if (typeName.Equals("String"))
                        {
                            isDbString = true;
                            valuePart  = $"{fieldName}.ToDbString({isAnsi.ToCode()}, {length.ToIntCode()}, {fixedLength.ToCode()})";
                        }
                        else
                        {
                            valuePart = fieldName;
                        }
                    }
                    else if (typeSymbol.TypeKind == TypeKind.Enum)
                    {
                        // Enum item type
                        if (typeName == null || typeName == string.Empty)
                        {
                            var enumSymbol = (INamedTypeSymbol)typeSymbol;
                            typeName = enumSymbol.EnumUnderlyingType?.Name;
                            if (typeName == null)
                            {
                                typeName = "Byte";
                            }
                        }

                        valuePart = $"({typeName}){fieldName}";
                    }
                    else if (typeSymbol.TypeKind == TypeKind.Array)
                    {
                        // Array type
                        var arraySymbol    = (IArrayTypeSymbol)typeSymbol;
                        var itemTypeSymbol = arraySymbol.ElementType;
                        if (!itemTypeSymbol.IsSimpleType())
                        {
                            continue;
                        }
                        var itemDbType = GetDbType(itemTypeSymbol, isAnsi);

                        isDbString = true;

                        if (string.IsNullOrEmpty(typeName))
                        {
                            // String
                            valuePart = $"app.DB.ListToParameter({fieldName}, {itemDbType}, {length.ToIntCode()}, (type) => SqlServerUtils.GetListCommand(type, app.BuildCommandName))";
                        }
                        else
                        {
                            // SQL Server TVP
                            valuePart = $"SqlServerUtils.ListToIdRecords({fieldName}, {itemDbType}, {length.ToIntCode()}).AsTableValuedParameter(\"{typeName}\")";
                        }
                    }
                    else if (typeSymbol.IsList())
                    {
                        // Item type
                        var listSymbol     = (INamedTypeSymbol)typeSymbol;
                        var itemTypeSymbol = listSymbol.TypeArguments[0];
                        if (!itemTypeSymbol.IsSimpleType())
                        {
                            continue;
                        }
                        var itemDbType = GetDbType(itemTypeSymbol, isAnsi);

                        isDbString = true;

                        if (string.IsNullOrEmpty(typeName))
                        {
                            // String
                            valuePart = $"app.DB.ListToParameter({fieldName}, {itemDbType}, {length.ToIntCode()}, (type) => SqlServerUtils.GetListCommand(type, app.BuildCommandName))";
                        }
                        else
                        {
                            // SQL Server TVP
                            valuePart = $"SqlServerUtils.ListToIdRecords({fieldName}, {itemDbType}, {length.ToIntCode()}).AsTableValuedParameter(\"{typeName}\")";
                        }
                    }
                    else if (typeSymbol.IsDictionary())
                    {
                        var dicSymbol = (INamedTypeSymbol)typeSymbol;

                        // Key type
                        var keyType   = dicSymbol.TypeArguments[0];
                        var keyDbType = keyType.Name.ToDbType();

                        // Item value type
                        var itemType   = dicSymbol.TypeArguments[1];
                        var itemDbType = GetDbType(itemType, isAnsi);

                        isDbString = true;

                        if (string.IsNullOrEmpty(typeName))
                        {
                            // String
                            valuePart = $"app.DB.DictionaryToTVP({fieldName}, {keyDbType}, {itemDbType}, null, {length.ToIntCode()}, (keyType, valueType) => SqlServerUtils.GetDicCommand(keyType, valueType, app.BuildCommandName))";
                        }
                        else
                        {
                            // SQL Server TVP
                            valuePart = $"SqlServerUtils.DictionaryToRecords({fieldName}, {keyDbType}, {itemDbType}).AsTableValuedParameter(\"{typeName}\")";
                        }
                    }
                    else
                    {
                        continue;
                    }

                    // Item
                    var itemCode = new StringBuilder();
                    if (ignoreNull && (nullable || typeSymbol.IsReferenceType))
                    {
                        // Ignore null field
                        itemCode.AppendLine($"if({fieldName} != null)");
                    }

                    if (isDbString)
                    {
                        itemCode.Append($"parameters.Add(\"{name}\", {valuePart})");
                    }
                    else
                    {
                        itemCode.Append($"parameters.Add(\"{name}\", {valuePart}, {typeName.ToDbType()})");
                    }

                    body.Add(itemCode.ToString());
                }
            }

            return(body);
        }
Example #3
0
        private string GenerateBody(GeneratorExecutionContext context, TypeDeclarationSyntax tds, List <string> externalInheritances)
        {
            var body = new List <string>();

            var members = context.ParseMembers(tds, true, externalInheritances, out _);

            if (!context.CancellationToken.IsCancellationRequested)
            {
                foreach (var member in members)
                {
                    var(symbol, typeSymbol, nullable) = member;

                    // Field name
                    var fieldName = symbol.Name;

                    // Is field or property
                    var isField = (symbol.Kind == SymbolKind.Field).ToCode();

                    // Is readonly
                    var isReadonly = typeSymbol.IsReadOnly.ToCode();

                    // Is nullable
                    var isNullable = nullable ? $"{fieldName} == null" : "false";

                    // Parameter name
                    var pName = "name" + fieldName;

                    // Item
                    var item = new StringBuilder();
                    if (nullable)
                    {
                        item.AppendLine($@"if({fieldName} == null)
                            w.WriteNull({pName});
                        else {{
                        ");
                    }

                    if (typeSymbol.IsSimpleType())
                    {
                        // Value field
                        var valueField = nullable && typeSymbol.IsValueType ? $"{fieldName}.Value" : fieldName;

                        // typeSymbol.ToString() = "int", typeSymbol.Name = "Int32"
                        var method = GetMethod(typeSymbol.ToString());
                        item.AppendLine($@"w.{method}({pName}, {valueField});");
                    }
                    else if (typeSymbol.TypeKind == TypeKind.Enum)
                    {
                        // Enum item type
                        var enumSymbol = (INamedTypeSymbol)typeSymbol;
                        var enumType   = enumSymbol.EnumUnderlyingType?.Name ?? "Byte";
                        item.AppendLine($@"w.WriteNumber({pName}, ({enumType}){fieldName});");
                    }
                    else if (typeSymbol.TypeKind == TypeKind.Array || typeSymbol.IsList())
                    {
                        // Type
                        var itemTypeSymbol = typeSymbol.TypeKind == TypeKind.Array ? ((IArrayTypeSymbol)typeSymbol).ElementType : ((INamedTypeSymbol)typeSymbol).TypeArguments[0];
                        if (!itemTypeSymbol.IsSimpleType())
                        {
                            item.AppendLine($@"w.WritePropertyName({pName});");
                            item.AppendLine($@"JsonSerializer.Serialize(w, {fieldName}, options);");
                        }
                        else
                        {
                            var method   = GetMethod(itemTypeSymbol.ToString()) + "Value";
                            var itemName = "item" + fieldName;
                            item.AppendLine($@"w.WritePropertyName({pName});
                                w.WriteStartArray();

                                foreach (var {itemName} in {fieldName})
                                {{
                                    w.{method}({itemName});
                                }}

                                w.WriteEndArray();
                            ");
                        }
                    }
                    else
                    {
                        item.AppendLine($@"w.WritePropertyName({pName});");
                        item.AppendLine($@"JsonSerializer.Serialize(w, {fieldName}, options);");
                    }

                    if (nullable)
                    {
                        item.AppendLine("}");
                    }

                    // Is writable
                    body.Add($@"
                        if (options.IsWritable({isNullable}, {isField}, {isReadonly}))
                        {{
                            var {pName} = options.ConvertName(""{fieldName}"");
                            {item}
                        }}
                    ");
                }
            }

            return(string.Join("\n", body));
        }