~ruther/NosSmooth

0074ecfd924e8d06ceb2902bb7db850ca1283ad1 — František Boháček 3 years ago 04d319b
fix: handle non-nullable values correctly in packet index code generator
M Core/NosSmooth.PacketSerializersGenerator/AttributeGenerators/PacketIndexAttributeGenerator.cs => Core/NosSmooth.PacketSerializersGenerator/AttributeGenerators/PacketIndexAttributeGenerator.cs +63 -35
@@ 10,19 10,32 @@ using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using NosSmooth.PacketSerializersGenerator.Errors;

namespace NosSmooth.PacketSerializersGenerator.AttributeGenerators
namespace NosSmooth.PacketSerializersGenerator.AttributeGenerators;

/// <inheritdoc />
public class PacketIndexAttributeGenerator : IParameterGenerator
{
    /// <inheritdoc />
    public class PacketIndexAttributeGenerator : IParameterGenerator
    public bool ShouldHandle(AttributeSyntax attribute)
        => attribute.Name.NormalizeWhitespace().ToFullString() == "PacketIndex";

    /// <inheritdoc />
    public IError? GenerateSerializerPart(IndentedTextWriter textWriter, RecordDeclarationSyntax recordDeclarationSyntax, ParameterInfo parameterInfo)
    {
        /// <inheritdoc />
        public bool ShouldHandle(AttributeSyntax attribute)
            => attribute.Name.NormalizeWhitespace().ToFullString() == "PacketIndex";
        bool pushedLevel = false;

        /// <inheritdoc />
        public IError? GenerateSerializerPart(IndentedTextWriter textWriter, RecordDeclarationSyntax recordDeclarationSyntax, ParameterInfo parameterInfo)
        if (parameterInfo.NamedAttributeArguments.ContainsKey("AfterSeparator") && parameterInfo.NamedAttributeArguments["AfterSeparator"] is not null)
        {
            textWriter.WriteLine($@"
            textWriter.WriteLine($"builder.SetAfterSeparatorOnce('{parameterInfo.NamedAttributeArguments["AfterSeparator"]}');");
        }

        if (parameterInfo.NamedAttributeArguments.ContainsKey("InnerSeparator") && parameterInfo.NamedAttributeArguments["InnerSeparator"] is not null)
        {
            pushedLevel = true;
            textWriter.WriteLine($"builder.PushLevel('{parameterInfo.NamedAttributeArguments["InnerSeparator"]}');");
        }

        textWriter.WriteLine($@"
var {parameterInfo.Name}Result = _typeConverterRepository.Serialize(obj.{parameterInfo.Name}, builder);
if (!{parameterInfo.Name}Result.IsSuccess)
{{


@@ 30,44 43,59 @@ if (!{parameterInfo.Name}Result.IsSuccess)
}}
");

            return null;
        if (pushedLevel)
        {
            textWriter.WriteLine("builder.PopLevel();");
        }

        /// <inheritdoc />
        public IError? GenerateDeserializerPart(IndentedTextWriter textWriter, RecordDeclarationSyntax recordDeclarationSyntax, ParameterInfo parameterInfo)
        return null;
    }

    /// <inheritdoc />
    public IError? GenerateDeserializerPart(IndentedTextWriter textWriter, RecordDeclarationSyntax recordDeclarationSyntax, ParameterInfo parameterInfo)
    {
        bool pushedLevel = false;
        bool nullable = parameterInfo.Parameter.Type is NullableTypeSyntax;

        if (parameterInfo.NamedAttributeArguments.ContainsKey("AfterSeparator") && parameterInfo.NamedAttributeArguments["AfterSeparator"] is not null)
        {
            bool pushedLevel = false;

            if (parameterInfo.NamedAttributeArguments.ContainsKey("AfterSeparator") && parameterInfo.NamedAttributeArguments["AfterSeparator"] is not null)
            {
                textWriter.WriteLine($"stringEnumerator.SetAfterSeparatorOnce('{parameterInfo.NamedAttributeArguments["AfterSeparator"]}');");
            }

            if (parameterInfo.NamedAttributeArguments.ContainsKey("InnerSeparator") && parameterInfo.NamedAttributeArguments["InnerSeparator"] is not null)
            {
                pushedLevel = true;
                textWriter.WriteLine($"stringEnumerator.PushLevel('{parameterInfo.NamedAttributeArguments["InnerSeparator"]}');");
            }

            var semanticModel = parameterInfo.Compilation.GetSemanticModel(recordDeclarationSyntax.SyntaxTree);
            var type = semanticModel.GetTypeInfo(parameterInfo.Parameter.Type!).Type;
            string last = parameterInfo.IsLast ? "true" : "false";
            textWriter.WriteLine($@"
var {parameterInfo.Name}Result = _typeConverterRepository.Deserialize<{type!.ToString()}>(stringEnumerator);
            textWriter.WriteLine($"stringEnumerator.SetAfterSeparatorOnce('{parameterInfo.NamedAttributeArguments["AfterSeparator"]}');");
        }

        if (parameterInfo.NamedAttributeArguments.ContainsKey("InnerSeparator") && parameterInfo.NamedAttributeArguments["InnerSeparator"] is not null)
        {
            pushedLevel = true;
            textWriter.WriteLine($"stringEnumerator.PushLevel('{parameterInfo.NamedAttributeArguments["InnerSeparator"]}');");
        }

        var semanticModel = parameterInfo.Compilation.GetSemanticModel(recordDeclarationSyntax.SyntaxTree);
        var type = semanticModel.GetTypeInfo(parameterInfo.Parameter.Type!).Type;
        string last = parameterInfo.IsLast ? "true" : "false";
        textWriter.WriteLine($@"
var {parameterInfo.Name}Result = _typeConverterRepository.Deserialize<{type!.ToString()}{(nullable ? string.Empty : "?")}>(stringEnumerator);
var {parameterInfo.Name}Error = CheckDeserializationResult({parameterInfo.Name}Result, ""{parameterInfo.Name}"", stringEnumerator, {last});
if ({parameterInfo.Name}Error is not null)
{{
        return Result<{recordDeclarationSyntax.Identifier.NormalizeWhitespace().ToFullString()}?>.FromError({parameterInfo.Name}Error, {parameterInfo.Name}Result);
}}
");

var {parameterInfo.Name} = {parameterInfo.Name}Result.Entity;
        if (!nullable)
        {
            textWriter.WriteLine($@"
if ({parameterInfo.Name}Result.Entity is null) {{
  return new PacketParameterSerializerError(this, ""{parameterInfo.Name}"", {parameterInfo.Name}Result, ""The converter has returned null even though it was not expected."");
}}
");
            if (pushedLevel)
            {
                textWriter.WriteLine("stringEnumerator.PopLevel();");
            }
        }

            return null;
        textWriter.WriteLine($"var {parameterInfo.Name} = ({type!.ToString()}){parameterInfo.Name}Result.Entity;");

        if (pushedLevel)
        {
            textWriter.WriteLine("stringEnumerator.PopLevel();");
        }

        return null;
    }
}
\ No newline at end of file

Do not follow this link