~ruther/NosSmooth

321d3bff73eaf8f733ee55b02be96cbe395c22ea — František Boháček 3 years ago 13d3f7d
feat: accept types and variable names in inline converter generators instead of packet parameters
M Core/NosSmooth.PacketSerializersGenerator/Extensions/TypeSymbolExtensions.cs => Core/NosSmooth.PacketSerializersGenerator/Extensions/TypeSymbolExtensions.cs +21 -0
@@ 5,6 5,7 @@
//  Licensed under the MIT license. See LICENSE file in the project root for full license information.

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;

namespace NosSmooth.PacketSerializersGenerator.Extensions;



@@ 30,7 31,27 @@ public static class TypeSymbolExtensions
            return false;
        }

        if (typeSymbol.ToString().EndsWith("?"))
        {
            return true;
        }

        // cannot determine if not nullable from reference type.
        return null;
    }

    /// <summary>
    /// Gets the type name with ? if it is nullable.
    /// </summary>
    /// <param name="typeSymbol">The type.</param>
    /// <returns>The actual name.</returns>
    public static string GetActualType(this ITypeSymbol typeSymbol)
    {
        if (typeSymbol.IsNullable() ?? false)
        {
            return typeSymbol.ToString().TrimEnd('?') + '?';
        }

        return typeSymbol.ToString();
    }
}
\ No newline at end of file

M Core/NosSmooth.PacketSerializersGenerator/Extensions/TypeSyntaxExtensions.cs => Core/NosSmooth.PacketSerializersGenerator/Extensions/TypeSyntaxExtensions.cs +16 -1
@@ 20,6 20,21 @@ public static class TypeSyntaxExtensions
    /// <returns>Whether the type syntax is nullable.</returns>
    public static bool IsNullable(this TypeSyntax typeSyntax)
    {
        return typeSyntax is NullableTypeSyntax;
        return typeSyntax is NullableTypeSyntax || typeSyntax.ToString().EndsWith("?");
    }

    /// <summary>
    /// Gets the type name with ? if it is nullable.
    /// </summary>
    /// <param name="typeSyntax">The type.</param>
    /// <returns>The actual name.</returns>
    public static string GetActualType(this TypeSyntax typeSyntax)
    {
        if (typeSyntax.IsNullable())
        {
            return typeSyntax.ToString().TrimEnd('?') + '?';
        }

        return typeSyntax.ToString();
    }
}
\ No newline at end of file

M Core/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/BasicInlineConverterGenerator.cs => Core/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/BasicInlineConverterGenerator.cs +17 -10
@@ 5,6 5,8 @@
//  Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System.CodeDom.Compiler;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using NosSmooth.PacketSerializersGenerator.Data;
using NosSmooth.PacketSerializersGenerator.Errors;
using NosSmooth.PacketSerializersGenerator.Extensions;


@@ 23,16 25,15 @@ public class BasicInlineConverterGenerator : IInlineConverterGenerator
    public static IReadOnlyList<string> HandleTypes => new[] { "long", "ulong", "int", "uint", "short", "ushort", "byte", "sbyte" };

    /// <inheritdoc />
    public bool ShouldHandle(ParameterInfo parameter)
        => HandleTypes.Contains(parameter.Parameter.Type!.ToString());
    public bool ShouldHandle(TypeSyntax? typeSyntax, ITypeSymbol? typeSymbol)
        => HandleTypes.Contains(typeSyntax?.ToString().TrimEnd('?')) || HandleTypes.Contains(typeSymbol?.ToString().TrimEnd('?'));

    /// <inheritdoc />
    public IError? GenerateSerializerPart(IndentedTextWriter textWriter, PacketInfo packet)
    public IError? GenerateSerializerPart(IndentedTextWriter textWriter, string variableName, TypeSyntax? typeSyntax, ITypeSymbol? typeSymbol)
    {
        var parameter = packet.Parameters.Current;
        if (parameter.Nullable)
        if ((typeSyntax is not null && typeSyntax.IsNullable()) || (typeSymbol is not null && (typeSymbol.IsNullable() ?? false)))
        {
            textWriter.WriteLine("if (obj is null)");
            textWriter.WriteLine($"if ({variableName} is null)");
            textWriter.WriteLine("{");
            textWriter.WriteLine("builder.Append('-');");
            textWriter.WriteLine("}");


@@ 40,16 41,22 @@ public class BasicInlineConverterGenerator : IInlineConverterGenerator
        }
        textWriter.WriteLine("{");
        textWriter.WriteLine
            ($"builder.Append(obj.{parameter.Name});");
            ($"builder.Append(({(typeSymbol?.ToString() ?? typeSyntax!.ToString()).TrimEnd('?')}){variableName});");
        textWriter.WriteLine("}");
        return null;
    }

    /// <inheritdoc />
    public IError? CallDeserialize(IndentedTextWriter textWriter, PacketInfo packet)
    public IError? CallDeserialize(IndentedTextWriter textWriter, TypeSyntax? typeSyntax, ITypeSymbol? typeSymbol)
    {
        var parameter = packet.Parameters.Current;
        var type = parameter.Parameter.Type!.ToString().Trim('?');
        var type = typeSyntax is not null
            ? typeSyntax.ToString().TrimEnd('?')
            : typeSymbol?.ToString();
        if (type is null)
        {
            throw new Exception("TypeSyntax or TypeSymbol has to be non null.");
        }

        textWriter.WriteLine($"{Constants.HelperClass}.ParseBasic{type}(this, stringEnumerator);");
        return null;
    }

M Core/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/BoolInlineConverterGenerator.cs => Core/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/BoolInlineConverterGenerator.cs +9 -19
@@ 5,6 5,8 @@
//  Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System.CodeDom.Compiler;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using NosSmooth.PacketSerializersGenerator.Data;
using NosSmooth.PacketSerializersGenerator.Errors;
using NosSmooth.PacketSerializersGenerator.Extensions;


@@ 15,16 17,15 @@ namespace NosSmooth.PacketSerializersGenerator.InlineConverterGenerators;
public class BoolInlineConverterGenerator : IInlineConverterGenerator
{
    /// <inheritdoc />
    public bool ShouldHandle(ParameterInfo parameter)
        => parameter.Parameter.Type!.ToString() == "bool";
    public bool ShouldHandle(TypeSyntax? typeSyntax, ITypeSymbol? typeSymbol)
        => typeSyntax?.ToString().TrimEnd('?') == "bool" || typeSymbol?.ToString().TrimEnd('?') == "bool";

    /// <inheritdoc />
    public IError? GenerateSerializerPart(IndentedTextWriter textWriter, PacketInfo packet)
    public IError? GenerateSerializerPart(IndentedTextWriter textWriter, string variableName, TypeSyntax? typeSyntax, ITypeSymbol? typeSymbol)
    {
        var parameter = packet.Parameters.Current;
        if (parameter.Nullable)
        if ((typeSyntax?.IsNullable() ?? false) || (typeSymbol?.IsNullable() ?? false))
        {
            textWriter.WriteLine($"if (obj.{parameter.Name} is null)");
            textWriter.WriteLine($"if ({variableName} is null)");
            textWriter.WriteLine("{");
            textWriter.Indent++;
            textWriter.WriteLine("builder.Append('-');");


@@ 34,27 35,16 @@ public class BoolInlineConverterGenerator : IInlineConverterGenerator
        }
        textWriter.WriteLine("{");
        textWriter.Indent++;
        textWriter.WriteLine($"builder.Append(obj.{parameter.Name} ? '1' : '0');");
        textWriter.WriteLine($"builder.Append({variableName} ? '1' : '0');");
        textWriter.Indent--;
        textWriter.WriteLine("}");
        return null;
    }

    /// <inheritdoc />
    public IError? CallDeserialize(IndentedTextWriter textWriter, PacketInfo packet)
    public IError? CallDeserialize(IndentedTextWriter textWriter, TypeSyntax? typeSyntax, ITypeSymbol? typeSymbol)
    {
        var parameter = packet.Parameters.Current;
        textWriter.WriteLine($"{Constants.HelperClass}.ParseBool(stringEnumerator);");
        /*string isLastString = packet.Parameters.IsLast ? "true" : "false";
        textWriter.WriteMultiline($@"
var {parameter.GetResultVariableName()} = stringEnumerator.GetNextToken();
var {parameter.GetErrorVariableName()} = CheckDeserializationResult({parameter.GetResultVariableName()}, ""{parameter.Name}"", stringEnumerator, {isLastString});
if ({parameter.GetErrorVariableName()} is not null)
{{
    return Result<{packet.Name}?>.FromError({parameter.GetErrorVariableName()}, {parameter.GetResultVariableName()});
}}
{parameter.GetNullableType()} {parameter.GetNullableVariableName()} = {parameter.GetResultVariableName()}.Entity.Token == ""1"" ? true : ({parameter.GetResultVariableName()}.Entity.Token == ""-"" ? null : false);
");*/
        return null;
    }


M Core/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/EnumInlineConverterGenerator.cs => Core/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/EnumInlineConverterGenerator.cs +20 -13
@@ 6,6 6,7 @@

using System.CodeDom.Compiler;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using NosSmooth.PacketSerializersGenerator.Data;
using NosSmooth.PacketSerializersGenerator.Errors;
using NosSmooth.PacketSerializersGenerator.Extensions;


@@ 26,15 27,20 @@ public class EnumInlineConverterGenerator : IInlineConverterGenerator
    }

    /// <inheritdoc />
    public bool ShouldHandle(ParameterInfo parameter)
        => parameter.Type.TypeKind == TypeKind.Enum;
    public bool ShouldHandle(TypeSyntax? typeSyntax, ITypeSymbol? typeSymbol)
        => typeSymbol?.TypeKind == TypeKind.Enum;

    /// <inheritdoc />
    public IError? GenerateSerializerPart(IndentedTextWriter textWriter, PacketInfo packet)
    public IError? GenerateSerializerPart
    (
        IndentedTextWriter textWriter,
        string variableName,
        TypeSyntax? typeSyntax,
        ITypeSymbol? typeSymbol
    )
    {
        var parameter = packet.Parameters.Current;
        var underlyingType = ((INamedTypeSymbol)parameter.Type).EnumUnderlyingType!.ToString();
        if (parameter.Nullable)
        var underlyingType = ((INamedTypeSymbol)typeSymbol!).EnumUnderlyingType!.ToString();
        if ((typeSyntax?.IsNullable() ?? false) || (typeSymbol?.IsNullable() ?? false))
        {
            textWriter.WriteLine("if (obj is null)");
            textWriter.WriteLine("{");


@@ 44,23 50,24 @@ public class EnumInlineConverterGenerator : IInlineConverterGenerator
        }
        textWriter.WriteLine("{");
        textWriter.WriteLine
            ($"builder.Append(({underlyingType})obj.{parameter.Name});");
            ($"builder.Append(({underlyingType}){variableName});");
        textWriter.WriteLine("}");

        return null;
    }

    /// <inheritdoc />
    public IError? CallDeserialize(IndentedTextWriter textWriter, PacketInfo packet)
    public IError? CallDeserialize(IndentedTextWriter textWriter, TypeSyntax? typeSyntax, ITypeSymbol? typeSymbol)
    {
        var parameter = packet.Parameters.Current;
        if (_enumTypes.All(x => x.ToString() != parameter.Type.ToString()))
        if (_enumTypes.All(x => x.ToString() != typeSymbol!.ToString()))
        {
            _enumTypes.Add(parameter.Type);
            _enumTypes.Add(typeSymbol!);
        }

        textWriter.WriteLine
            ($"{Constants.HelperClass}.ParseEnum{parameter.GetActualType().Replace('.', '_')}(this, stringEnumerator);");
        (
            $"{Constants.HelperClass}.ParseEnum{typeSymbol?.ToString().TrimEnd('?').Replace('.', '_')}(this, stringEnumerator);"
        );
        return null;
    }



@@ 98,4 105,4 @@ public static Result<{type}?> ParseEnum{type.ToString().Replace('.', '_')}(IType
            );
        }
    }
}
}
\ No newline at end of file

M Core/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/FallbackInlineConverterGenerator.cs => Core/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/FallbackInlineConverterGenerator.cs +19 -9
@@ 5,9 5,9 @@
//  Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System.CodeDom.Compiler;
using NosSmooth.PacketSerializersGenerator.Data;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using NosSmooth.PacketSerializersGenerator.Errors;
using NosSmooth.PacketSerializersGenerator.Extensions;

namespace NosSmooth.PacketSerializersGenerator.InlineConverterGenerators;



@@ 15,24 15,34 @@ namespace NosSmooth.PacketSerializersGenerator.InlineConverterGenerators;
public class FallbackInlineConverterGenerator : IInlineConverterGenerator
{
    /// <inheritdoc />
    public bool ShouldHandle(ParameterInfo parameter)
    public bool ShouldHandle(TypeSyntax? typeSyntax, ITypeSymbol? typeSymbol)
    {
        return true;
    }

    /// <inheritdoc />
    public IError? GenerateSerializerPart(IndentedTextWriter textWriter, PacketInfo packet)
    public IError? GenerateSerializerPart
    (
        IndentedTextWriter textWriter,
        string variableName,
        TypeSyntax? typeSyntax,
        ITypeSymbol? typeSymbol
    )
    {
        var parameter = packet.Parameters.Current;
        textWriter.WriteLine($"_typeConverterRepository.Serialize<{parameter.GetActualType()}>(obj.{parameter.Name}, builder);");
        textWriter.WriteLine
        (
            $"_typeConverterRepository.Serialize<{(typeSyntax?.ToString() ?? typeSymbol!.ToString()).TrimEnd('?')}?>({variableName}, builder);"
        );
        return null;
    }

    /// <inheritdoc />
    public IError? CallDeserialize(IndentedTextWriter textWriter, PacketInfo packet)
    public IError? CallDeserialize(IndentedTextWriter textWriter, TypeSyntax? typeSyntax, ITypeSymbol? typeSymbol)
    {
        var parameter = packet.Parameters.Current;
        textWriter.WriteLine($"_typeConverterRepository.Deserialize<{parameter.GetNullableType()}>(stringEnumerator);");
        textWriter.WriteLine
        (
            $"_typeConverterRepository.Deserialize<{(typeSyntax?.ToString() ?? typeSymbol!.ToString()).TrimEnd('?')}?>(stringEnumerator);"
        );
        return null;
    }


M Core/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/IInlineConverterGenerator.cs => Core/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/IInlineConverterGenerator.cs +13 -7
@@ 5,6 5,8 @@
//  Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System.CodeDom.Compiler;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using NosSmooth.PacketSerializersGenerator.Data;
using NosSmooth.PacketSerializersGenerator.Errors;



@@ 18,25 20,29 @@ public interface IInlineConverterGenerator
    /// <summary>
    /// Whether the given parameter should be handled by this.
    /// </summary>
    /// <param name="parameter">The parameter.</param>
    /// <returns>Whethet to handle.</returns>
    public bool ShouldHandle(ParameterInfo parameter);
    /// <param name="typeSyntax">The type syntax.</param>
    /// <param name="typeSymbol">The type symbol.</param>
    /// <returns>Whether to handle.</returns>
    public bool ShouldHandle(TypeSyntax? typeSyntax, ITypeSymbol? typeSymbol);

    /// <summary>
    /// Generate the serializer part.
    /// </summary>
    /// <param name="textWriter">The text writer to write to.</param>
    /// <param name="packet">The packet.</param>
    /// <param name="variableName">The name of the variable.</param>
    /// <param name="typeSyntax">The type syntax.</param>
    /// <param name="typeSymbol">The type symbol.</param>
    /// <returns>An error, if any.</returns>
    public IError? GenerateSerializerPart(IndentedTextWriter textWriter, PacketInfo packet);
    public IError? GenerateSerializerPart(IndentedTextWriter textWriter, string variableName, TypeSyntax? typeSyntax, ITypeSymbol? typeSymbol);

    /// <summary>
    /// Generate the deserializer part.
    /// </summary>
    /// <param name="textWriter">The text writer to write to.</param>
    /// <param name="packet">The packet.</param>
    /// <param name="typeSyntax">The type syntax.</param>
    /// <param name="typeSymbol">The type symbol.</param>
    /// <returns>An error, if any.</returns>
    public IError? CallDeserialize(IndentedTextWriter textWriter, PacketInfo packet);
    public IError? CallDeserialize(IndentedTextWriter textWriter, TypeSyntax? typeSyntax, ITypeSymbol? typeSymbol);

    /// <summary>
    /// Generate helper methods to HelperClass.

M Core/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/StringInlineConverterGenerator.cs => Core/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/StringInlineConverterGenerator.cs +7 -17
@@ 5,6 5,8 @@
//  Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System.CodeDom.Compiler;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using NosSmooth.PacketSerializersGenerator.Data;
using NosSmooth.PacketSerializersGenerator.Errors;
using NosSmooth.PacketSerializersGenerator.Extensions;


@@ 15,32 17,20 @@ namespace NosSmooth.PacketSerializersGenerator.InlineConverterGenerators;
public class StringInlineConverterGenerator : IInlineConverterGenerator
{
    /// <inheritdoc />
    public bool ShouldHandle(ParameterInfo parameter)
        => parameter.Parameter.Type!.ToString() == "string";
    public bool ShouldHandle(TypeSyntax? typeSyntax, ITypeSymbol? typeSymbol)
        => typeSyntax?.ToString().TrimEnd('?') == "string" || typeSymbol?.ToString().TrimEnd('?') == "string";

    /// <inheritdoc />
    public IError? GenerateSerializerPart(IndentedTextWriter textWriter, PacketInfo packet)
    public IError? GenerateSerializerPart(IndentedTextWriter textWriter, string variableName, TypeSyntax? typeSyntax, ITypeSymbol? typeSymbol)
    {
        var parameter = packet.Parameters.Current;
        textWriter.WriteLine($"builder.Append(obj.{parameter.Name} ?? \"-\");");
        textWriter.WriteLine($"builder.Append({variableName} ?? \"-\");");
        return null;
    }

    /// <inheritdoc />
    public IError? CallDeserialize(IndentedTextWriter textWriter, PacketInfo packet)
    public IError? CallDeserialize(IndentedTextWriter textWriter, TypeSyntax? typeSyntax, ITypeSymbol? typeSymbol)
    {
        // var parameter = packet.Parameters.Current;
        // string isLastString = packet.Parameters.IsLast ? "true" : "false";
        textWriter.WriteLine($"{Constants.HelperClass}.ParseString(stringEnumerator);");
        /*textWriter.WriteMultiline($@"
var {parameter.GetResultVariableName()} = stringEnumerator.GetNextToken();
var {parameter.GetErrorVariableName()} = CheckDeserializationResult({parameter.GetResultVariableName()}, ""{parameter.Name}"", stringEnumerator, {isLastString});
if ({parameter.GetErrorVariableName()} is not null)
{{
    return Result<{packet.Name}?>.FromError({parameter.GetErrorVariableName()}, {parameter.GetResultVariableName()});
}}
var {parameter.GetNullableVariableName()} = {parameter.GetResultVariableName()}.Entity.Token == ""-"" ? null : {parameter.GetResultVariableName()}.Entity.Token;
");*/
        return null;
    }


M Core/NosSmooth.PacketSerializersGenerator/InlineTypeConverterGenerator.cs => Core/NosSmooth.PacketSerializersGenerator/InlineTypeConverterGenerator.cs +9 -6
@@ 39,19 39,20 @@ public class InlineTypeConverterGenerator
    /// <returns>An error, if any.</returns>
    public IError? CallDeserialize(IndentedTextWriter textWriter, PacketInfo packet)
    {
        var parameter = packet.Parameters.Current;
        var shouldGenerateInline = packet.GenerateAttribute.GetIndexedValue<bool>(0);
        if (shouldGenerateInline)
        {
            foreach (var generator in _typeGenerators)
            {
                if (generator.ShouldHandle(packet.Parameters.Current))
                if (generator.ShouldHandle(parameter.Parameter.Type, parameter.Type))
                {
                    return generator.CallDeserialize(textWriter, packet);
                    return generator.CallDeserialize(textWriter, parameter.Parameter.Type, parameter.Type);
                }
            }
        }

        return _fallbackInlineConverterGenerator.CallDeserialize(textWriter, packet);
        return _fallbackInlineConverterGenerator.CallDeserialize(textWriter, parameter.Parameter.Type, parameter.Type);
    }

    /// <summary>


@@ 62,18 63,20 @@ public class InlineTypeConverterGenerator
    /// <returns>An error, if any.</returns>
    public IError? Serialize(IndentedTextWriter textWriter, PacketInfo packet)
    {
        var parameter = packet.Parameters.Current;
        var variableName = "obj." + parameter.Name;
        var shouldGenerateInline = packet.GenerateAttribute.GetIndexedValue<bool>(0);
        if (shouldGenerateInline)
        {
            foreach (var generator in _typeGenerators)
            {
                if (generator.ShouldHandle(packet.Parameters.Current))
                if (generator.ShouldHandle(parameter.Parameter.Type, parameter.Type))
                {
                    return generator.GenerateSerializerPart(textWriter, packet);
                    return generator.GenerateSerializerPart(textWriter, variableName, parameter.Parameter.Type, parameter.Type);
                }
            }
        }

        return _fallbackInlineConverterGenerator.GenerateSerializerPart(textWriter, packet);
        return _fallbackInlineConverterGenerator.GenerateSerializerPart(textWriter, variableName, parameter.Parameter.Type, parameter.Type);
    }
}
\ No newline at end of file

Do not follow this link