diff --git a/VYaml.SourceGenerator.Roslyn3/MemberMeta.cs b/VYaml.SourceGenerator.Roslyn3/MemberMeta.cs index 7dea7df6..f8ac1c2c 100644 --- a/VYaml.SourceGenerator.Roslyn3/MemberMeta.cs +++ b/VYaml.SourceGenerator.Roslyn3/MemberMeta.cs @@ -9,16 +9,20 @@ class MemberMeta public string Name { get; } public string FullTypeName { get; } public ITypeSymbol MemberType { get; } - public INamedTypeSymbol? CustomFormatter { get; } - public string? CustomFormatterName { get; } public bool IsField { get; } public bool IsProperty { get; } public bool IsSettable { get; } - public bool IsConstructorParameter { get; } public int Order { get; } public bool HasExplicitOrder { get; } public bool HasKeyNameAlias { get; } + public bool IsConstructorParameter { get; set; } + public bool HasExplicitDefaultValueFromConstructor { get; set; } + public object? ExplicitDefaultValueFromConstructor { get; set; } + + public INamedTypeSymbol? CustomFormatter { get; } + public string? CustomFormatterName { get; } + public string KeyName => keyName ??= KeyNameHelper.ToCamelCase(Name); public byte[] KeyNameUtf8Bytes => keyNameUtf8Bytes ??= System.Text.Encoding.UTF8.GetBytes(KeyName); diff --git a/VYaml.SourceGenerator.Roslyn3/VYamlSourceGenerator.cs b/VYaml.SourceGenerator.Roslyn3/VYamlSourceGenerator.cs index e60f9bf0..dbfb8a8d 100644 --- a/VYaml.SourceGenerator.Roslyn3/VYamlSourceGenerator.cs +++ b/VYaml.SourceGenerator.Roslyn3/VYamlSourceGenerator.cs @@ -482,7 +482,19 @@ static bool TryEmitDeserializeMethod( codeWriter.Append("return new "); if (selectedConstructor != null) { - var parameters = string.Join(",", constructedMembers.Select(x => $"__{x.Name}__")); + var parameters = string.Join(",", constructedMembers.Select(x => + { + if (x.HasExplicitDefaultValueFromConstructor) + { + return x.ExplicitDefaultValueFromConstructor switch + { + null => $"__{x.Name}__ = null", + string stringValue => $"__{x.Name}__ = \"{stringValue}\"", + { } anyValue => $"__{x.Name}__ = {anyValue}" + }; + } + return $"__{x.Name}__"; + })); codeWriter.Append($"{typeMeta.TypeName}({parameters})", false); } else @@ -603,6 +615,12 @@ static bool TryGetConstructor( .FirstOrDefault(member => parameter.Name.Equals(member.Name, StringComparison.OrdinalIgnoreCase)); if (matchedMember != null) { + matchedMember.IsConstructorParameter = true; + if (parameter.HasExplicitDefaultValue) + { + matchedMember.HasExplicitDefaultValueFromConstructor = true; + matchedMember.ExplicitDefaultValueFromConstructor = parameter.ExplicitDefaultValue; + } parameterMembers.Add(matchedMember); } else diff --git a/VYaml.Tests/Serialization/SerializerTest.cs b/VYaml.Tests/Serialization/SerializerTest.cs index 1d3c7c36..e87b7743 100644 --- a/VYaml.Tests/Serialization/SerializerTest.cs +++ b/VYaml.Tests/Serialization/SerializerTest.cs @@ -2,12 +2,22 @@ using NUnit.Framework; using VYaml.Internal; using VYaml.Serialization; +using VYaml.Tests.TypeDeclarations; namespace VYaml.Tests.Serialization { [TestFixture] public class SerializerTest { + [Test] + public void Deserialize_ExplicitDefaultValueFromConstructor() + { + var yamlBytes = StringEncoding.Utf8.GetBytes("valueSet: 22"); + var value = YamlSerializer.Deserialize(yamlBytes); + Assert.That(value.Value, Is.EqualTo(12)); + Assert.That(value.ValueSet, Is.EqualTo(22)); + } + [Test] public void DeserializeMultipleDocuments() { diff --git a/VYaml.Tests/TypeDeclarations/Simple.cs b/VYaml.Tests/TypeDeclarations/Simple.cs index e17ef799..660a1609 100644 --- a/VYaml.Tests/TypeDeclarations/Simple.cs +++ b/VYaml.Tests/TypeDeclarations/Simple.cs @@ -64,6 +64,20 @@ public partial class WithValueTuple public ValueTuple Seven { get; set; } } + [YamlObject] + public partial class WithDefaultValue + { + public readonly int Value; + public readonly int ValueSet; + + [YamlConstructor] + public WithDefaultValue(int valueSet, int value = 12) + { + ValueSet = valueSet; + Value = value; + } + } + public enum SimpleEnum { A, diff --git a/VYaml.Unity/Assets/VYaml/Runtime/VYaml.SourceGenerator.Roslyn3.dll b/VYaml.Unity/Assets/VYaml/Runtime/VYaml.SourceGenerator.Roslyn3.dll index 95215b42..a59fbb24 100644 Binary files a/VYaml.Unity/Assets/VYaml/Runtime/VYaml.SourceGenerator.Roslyn3.dll and b/VYaml.Unity/Assets/VYaml/Runtime/VYaml.SourceGenerator.Roslyn3.dll differ diff --git a/VYaml.Unity/Assets/VYaml/Tests/Serialization/SerializerTest.cs b/VYaml.Unity/Assets/VYaml/Tests/Serialization/SerializerTest.cs index 1d3c7c36..e87b7743 100644 --- a/VYaml.Unity/Assets/VYaml/Tests/Serialization/SerializerTest.cs +++ b/VYaml.Unity/Assets/VYaml/Tests/Serialization/SerializerTest.cs @@ -2,12 +2,22 @@ using NUnit.Framework; using VYaml.Internal; using VYaml.Serialization; +using VYaml.Tests.TypeDeclarations; namespace VYaml.Tests.Serialization { [TestFixture] public class SerializerTest { + [Test] + public void Deserialize_ExplicitDefaultValueFromConstructor() + { + var yamlBytes = StringEncoding.Utf8.GetBytes("valueSet: 22"); + var value = YamlSerializer.Deserialize(yamlBytes); + Assert.That(value.Value, Is.EqualTo(12)); + Assert.That(value.ValueSet, Is.EqualTo(22)); + } + [Test] public void DeserializeMultipleDocuments() { diff --git a/VYaml.Unity/Assets/VYaml/Tests/TypeDeclarations/Simple.cs b/VYaml.Unity/Assets/VYaml/Tests/TypeDeclarations/Simple.cs index e17ef799..660a1609 100644 --- a/VYaml.Unity/Assets/VYaml/Tests/TypeDeclarations/Simple.cs +++ b/VYaml.Unity/Assets/VYaml/Tests/TypeDeclarations/Simple.cs @@ -64,6 +64,20 @@ public partial class WithValueTuple public ValueTuple Seven { get; set; } } + [YamlObject] + public partial class WithDefaultValue + { + public readonly int Value; + public readonly int ValueSet; + + [YamlConstructor] + public WithDefaultValue(int valueSet, int value = 12) + { + ValueSet = valueSet; + Value = value; + } + } + public enum SimpleEnum { A,