M Core/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/BasicInlineConverterGenerator.cs => Core/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/BasicInlineConverterGenerator.cs +1 -1
@@ 57,7 57,7 @@ public class BasicInlineConverterGenerator : IInlineConverterGenerator
throw new Exception("TypeSyntax or TypeSymbol has to be non null.");
}
- textWriter.WriteLine($"{Constants.HelperClass}.ParseBasic{type}(this, stringEnumerator);");
+ textWriter.WriteLine($"{Constants.HelperClass}.ParseBasic{type}(typeConverter, stringEnumerator);");
return null;
}
M Core/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/EnumInlineConverterGenerator.cs => Core/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/EnumInlineConverterGenerator.cs +1 -1
@@ 66,7 66,7 @@ public class EnumInlineConverterGenerator : IInlineConverterGenerator
textWriter.WriteLine
(
- $"{Constants.HelperClass}.ParseEnum{typeSymbol?.ToString().TrimEnd('?').Replace('.', '_')}(this, stringEnumerator);"
+ $"{Constants.HelperClass}.ParseEnum{typeSymbol?.ToString().TrimEnd('?').Replace('.', '_')}(typeConverter, stringEnumerator);"
);
return null;
}
M Core/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/FallbackInlineConverterGenerator.cs => Core/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/FallbackInlineConverterGenerator.cs +8 -1
@@ 29,10 29,17 @@ public class FallbackInlineConverterGenerator : IInlineConverterGenerator
ITypeSymbol? typeSymbol
)
{
+ var resultName = $"{variableName.Replace(".", string.Empty)}Result";
textWriter.WriteLine
(
- $"_typeConverterRepository.Serialize<{(typeSyntax?.ToString() ?? typeSymbol!.ToString()).TrimEnd('?')}?>({variableName}, builder);"
+ $"var {resultName} = _typeConverterRepository.Serialize<{(typeSyntax?.ToString() ?? typeSymbol!.ToString()).TrimEnd('?')}?>({variableName}, builder);"
);
+ textWriter.WriteLine($"if (!{resultName}.IsSuccess)");
+ textWriter.WriteLine("{");
+ textWriter.Indent++;
+ textWriter.WriteLine($"return Result.FromError(new PacketParameterSerializerError(this, \"{variableName}\", {resultName}), {resultName});");
+ textWriter.Indent--;
+ textWriter.WriteLine("}");
return null;
}
A Core/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/ListInlineConverterGenerator.cs => Core/NosSmooth.PacketSerializersGenerator/InlineConverterGenerators/ListInlineConverterGenerator.cs +162 -0
@@ 0,0 1,162 @@
+//
+// ListInlineConverterGenerator.cs
+//
+// Copyright (c) František Boháček. All rights reserved.
+// 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.Errors;
+using NosSmooth.PacketSerializersGenerator.Extensions;
+
+namespace NosSmooth.PacketSerializersGenerator.InlineConverterGenerators;
+
+/// <inheritdoc/>
+public class ListInlineConverterGenerator : IInlineConverterGenerator
+{
+ private readonly InlineTypeConverterGenerator _inlineConverters;
+ private readonly List<ITypeSymbol> _listTypes;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ListInlineConverterGenerator"/> class.
+ /// </summary>
+ /// <param name="inlineConverters">The inline converter that is used for converting the values of the list.</param>
+ public ListInlineConverterGenerator(InlineTypeConverterGenerator inlineConverters)
+ {
+ _inlineConverters = inlineConverters;
+ _listTypes = new List<ITypeSymbol>();
+ }
+
+ /// <inheritdoc />
+ public bool ShouldHandle(TypeSyntax? typeSyntax, ITypeSymbol? typeSymbol)
+ => typeSymbol?.Name == "IReadOnlyList";
+
+ /// <inheritdoc />
+ public IError? GenerateSerializerPart
+ (
+ IndentedTextWriter textWriter,
+ string variableName,
+ TypeSyntax? typeSyntax,
+ ITypeSymbol? typeSymbol
+ )
+ {
+ ITypeSymbol genericArgument = ((INamedTypeSymbol)typeSymbol!).TypeArguments[0];
+ textWriter.WriteMultiline
+ (
+ @$"
+ if ({variableName} is null)
+ {{
+ builder.Append('-');
+ }}
+ else
+ {{
+ foreach (var item in {variableName})
+ {{
+ if (!builder.PushPreparedLevel())
+ {{
+ return new ArgumentInvalidError(nameof(builder), ""The string builder has to have a prepared level for all lists."");
+ }}
+
+"
+ );
+ var error = _inlineConverters.Serialize(textWriter, "item", null, genericArgument);
+ if (error is not null)
+ {
+ return error;
+ }
+
+ textWriter.WriteMultiline(@"
+ builder.PopLevel();
+ }
+ }
+"
+ );
+ return null;
+ }
+
+ /// <inheritdoc />
+ public IError? CallDeserialize(IndentedTextWriter textWriter, TypeSyntax? typeSyntax, ITypeSymbol? typeSymbol)
+ {
+ ITypeSymbol genericArgument = ((INamedTypeSymbol)typeSymbol!).TypeArguments[0];
+ if (_listTypes.All
+ (
+ x => x.ToString() != genericArgument!.ToString()
+ || ((x.IsNullable() ?? false) && (!genericArgument.IsNullable() ?? false))
+ ))
+ {
+ _listTypes.Add(genericArgument!);
+ }
+
+ textWriter.WriteLine
+ ($"{Constants.HelperClass}.{GetMethodName(genericArgument)}(typeConverter, _typeConverterRepository, stringEnumerator);");
+ return null;
+ }
+
+ private string GetMethodName(ITypeSymbol genericArgumentType)
+ {
+ return
+ $"ParseList{genericArgumentType.ToString().Replace('.', '_')}{((genericArgumentType.IsNullable() ?? false) ? "Nullable" : string.Empty)}";
+ }
+
+ /// <inheritdoc />
+ public void GenerateHelperMethods(IndentedTextWriter textWriter)
+ {
+ foreach (var type in _listTypes)
+ {
+ textWriter.WriteLine
+ (
+ @$"
+public static Result<IReadOnlyList<{type.GetActualType()}>> {GetMethodName(type)}(ITypeConverter typeConverter, ITypeConverterRepository _typeConverterRepository, PacketStringEnumerator stringEnumerator)
+{{
+ var data = new List<{type.GetActualType()}>();
+
+ while (!(stringEnumerator.IsOnLastToken() ?? false))
+ {{
+ if (!stringEnumerator.PushPreparedLevel())
+ {{
+ return new ArgumentInvalidError(nameof(stringEnumerator), ""The string enumerator has to have a prepared level for all lists."");
+ }}
+
+ var result = "
+ );
+ /*var error = */_inlineConverters.CallDeserialize(textWriter, null, type); // TODO handle error
+
+ textWriter.WriteMultiline(@$"
+
+ // If we know that we are not on the last token in the item level, just skip to the end of the item.
+ // Note that if this is the case, then that means the converter is either corrupted
+ // or the packet has more fields.
+ while (stringEnumerator.IsOnLastToken() == false)
+ {{
+ stringEnumerator.GetNextToken();
+ }}
+
+ stringEnumerator.PopLevel();
+ if (!result.IsSuccess)
+ {{
+ return Result<IReadOnlyList<{type}>>.FromError(new ListSerializerError(result, data.Count), result);
+ }}
+
+"
+ );
+
+ if (!(type.IsNullable() ?? false))
+ {
+ textWriter.WriteMultiline
+ (
+ $@"
+if (result.Entity is null)
+{{
+ return new DeserializedValueNullError(typeof({type.ToString().TrimEnd('?')}));
+}}
+"
+ );
+ }
+ textWriter.WriteLine($"data.Add(({type.GetActualType()})result.Entity);");
+ textWriter.WriteLine("}");
+ textWriter.WriteLine("return data;");
+ textWriter.WriteLine("}");
+ }
+ }
+}<
\ No newline at end of file
M Core/NosSmooth.PacketSerializersGenerator/InlineTypeConverterGenerator.cs => Core/NosSmooth.PacketSerializersGenerator/InlineTypeConverterGenerator.cs +62 -4
@@ 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;
@@ 32,7 34,7 @@ public class InlineTypeConverterGenerator
}
/// <summary>
- /// Generates deserialize and check code.
+ /// Generates deserialize call.
/// </summary>
/// <param name="textWriter">The text writer.</param>
/// <param name="packet">The packet.</param>
@@ 56,7 58,32 @@ public class InlineTypeConverterGenerator
}
/// <summary>
- /// Generates serialize and check code.
+ /// Generates deserialize call.
+ /// </summary>
+ /// <param name="textWriter">The text writer.</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,
+ TypeSyntax? typeSyntax,
+ ITypeSymbol? typeSymbol
+ )
+ {
+ foreach (var generator in _typeGenerators)
+ {
+ if (generator.ShouldHandle(typeSyntax, typeSymbol))
+ {
+ return generator.CallDeserialize(textWriter, typeSyntax, typeSymbol);
+ }
+ }
+
+ return _fallbackInlineConverterGenerator.CallDeserialize(textWriter, typeSyntax, typeSymbol);
+ }
+
+ /// <summary>
+ /// Generates serialize code.
/// </summary>
/// <param name="textWriter">The text writer.</param>
/// <param name="packet">The packet.</param>
@@ 72,11 99,42 @@ public class InlineTypeConverterGenerator
{
if (generator.ShouldHandle(parameter.Parameter.Type, parameter.Type))
{
- return generator.GenerateSerializerPart(textWriter, variableName, parameter.Parameter.Type, parameter.Type);
+ return generator.GenerateSerializerPart
+ (textWriter, variableName, parameter.Parameter.Type, parameter.Type);
}
}
}
- return _fallbackInlineConverterGenerator.GenerateSerializerPart(textWriter, variableName, parameter.Parameter.Type, parameter.Type);
+ return _fallbackInlineConverterGenerator.GenerateSerializerPart
+ (textWriter, variableName, parameter.Parameter.Type, parameter.Type);
+ }
+
+ /// <summary>
+ /// Generates serialize code.
+ /// </summary>
+ /// <param name="textWriter">The text writer.</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? Serialize
+ (
+ IndentedTextWriter textWriter,
+ string variableName,
+ TypeSyntax? typeSyntax,
+ ITypeSymbol? typeSymbol
+ )
+ {
+ foreach (var generator in _typeGenerators)
+ {
+ if (generator.ShouldHandle(typeSyntax, typeSymbol))
+ {
+ return generator.GenerateSerializerPart
+ (textWriter, variableName, typeSyntax, typeSymbol);
+ }
+ }
+
+ return _fallbackInlineConverterGenerator.GenerateSerializerPart
+ (textWriter, variableName, typeSyntax, typeSymbol);
}
}=
\ No newline at end of file
M Core/NosSmooth.PacketSerializersGenerator/NosSmooth.PacketSerializersGenerator.csproj => Core/NosSmooth.PacketSerializersGenerator/NosSmooth.PacketSerializersGenerator.csproj +0 -4
@@ 19,8 19,4 @@
<EmbeddedResource Include="$(PkgRemora_Results)\lib\netstandard2.0\*.dll" Visible="false" />
</ItemGroup>
- <ItemGroup>
- <Folder Include="HelperClassGenerators" />
- </ItemGroup>
-
</Project>
M Core/NosSmooth.PacketSerializersGenerator/PacketConverterGenerator.cs => Core/NosSmooth.PacketSerializersGenerator/PacketConverterGenerator.cs +1 -0
@@ 97,6 97,7 @@ public override Result Serialize({_packetInfo.Name}? obj, PacketStringBuilder bu
/// <inheritdoc />
public override Result<{_packetInfo.Name}?> Deserialize(PacketStringEnumerator stringEnumerator)
{{
+ var typeConverter = this;
"
);
M Core/NosSmooth.PacketSerializersGenerator/SourceGenerator.cs => Core/NosSmooth.PacketSerializersGenerator/SourceGenerator.cs +3 -11
@@ 42,8 42,8 @@ public class SourceGenerator : ISourceGenerator
new BoolInlineConverterGenerator(),
}
);
-
var inlineTypeConverter = new InlineTypeConverterGenerator(_typeConverterGenerator);
+ _typeConverterGenerator.Add(new ListInlineConverterGenerator(inlineTypeConverter));
_generators = new List<IParameterGenerator>
(
@@ 130,11 130,6 @@ public class SourceGenerator : ISourceGenerator
$"{packetRecord.GetPrefix()}.{packetRecord.Identifier.NormalizeWhitespace().ToFullString()}Converter.g.cs",
stringWriter.GetStringBuilder().ToString()
);
- File.WriteAllText
- (
- $"/tmp/{packetRecord.GetPrefix()}.{packetRecord.Identifier.NormalizeWhitespace().ToFullString()}Converter.g.cs",
- stringWriter.GetStringBuilder().ToString()
- );
}
}
@@ 144,11 139,6 @@ public class SourceGenerator : ISourceGenerator
$"HelperClass.g.cs",
helperClass
);
- File.WriteAllText
- (
- $"/tmp/HelperClass.g.cs",
- helperClass
- );
}
private string GenerateHelperMethods()
@@ 159,6 149,8 @@ public class SourceGenerator : ISourceGenerator
#nullable enable
#pragma warning disable 1591
+using System.Collections;
+using System.Collections.Generic;
using NosSmooth.Packets.Converters;
using NosSmooth.Packets.Errors;
using NosSmooth.Packets;