diff --git a/src/MemoryPack.Generator/MemoryPackGenerator.Emitter.cs b/src/MemoryPack.Generator/MemoryPackGenerator.Emitter.cs index 4246386..c264cf1 100644 --- a/src/MemoryPack.Generator/MemoryPackGenerator.Emitter.cs +++ b/src/MemoryPack.Generator/MemoryPackGenerator.Emitter.cs @@ -1376,12 +1376,12 @@ string EmitConstantValue(object? constantValue) string x => $"\"{x}\"", char x => $"'{x}'", float x => $"{x}f", - decimal x => $"{x}D", + decimal x => $"{x}M", bool x => x ? "true" : "false", _ => constantValue.ToString() }; } - return "null"; + return "default!"; } string EmitExpression(ExpressionSyntax expression) @@ -1392,13 +1392,13 @@ string EmitExpression(ExpressionSyntax expression) { var memberAccess = (MemberAccessExpressionSyntax)expression; var memberSymbol = semanticModel.GetSymbolInfo(memberAccess.Name).Symbol; - if (memberSymbol is INamedTypeSymbol namedTypeSymbol && namedTypeSymbol.TypeKind == TypeKind.Enum) + if (memberSymbol is INamedTypeSymbol { TypeKind: TypeKind.Enum } namedTypeSymbol) { - return $"{GetTypeFullName(namedTypeSymbol, semanticModel)}.{memberAccess.Name}"; + return $"{GetTypeFullName(namedTypeSymbol)}.{memberAccess.Name}"; } - if (memberSymbol is IFieldSymbol fieldSymbol && fieldSymbol.ContainingType.TypeKind == TypeKind.Enum) + if (memberSymbol is IFieldSymbol { Type.TypeKind: TypeKind.Enum } fieldSymbol) { - return $"{GetTypeFullName(fieldSymbol.ContainingType, semanticModel)}.{fieldSymbol.Name}"; + return $"{GetTypeFullName(fieldSymbol.Type)}.{fieldSymbol.Name}"; } break; } @@ -1412,7 +1412,7 @@ string EmitExpression(ExpressionSyntax expression) var arguments = string.Join(", ", objectCreation.ArgumentList?.Arguments.Select(arg => EmitExpression(arg.Expression)) ?? Enumerable.Empty()); - return $"new {x.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)}({arguments})"; + return $"new {GetTypeFullName(x)}({arguments})"; } break; } @@ -1426,10 +1426,15 @@ string EmitExpression(ExpressionSyntax expression) return expression.ToString(); } - string GetTypeFullName(ITypeSymbol typeSymbol, SemanticModel semanticModel) + static string GetTypeFullName(ITypeSymbol typeSymbol) { - var containingType = typeSymbol.ContainingType; - var containingTypeFullName = containingType == null ? "" : GetTypeFullName(containingType, semanticModel) + "."; - return containingTypeFullName + typeSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat); + if (typeSymbol.ContainingType is { } containingType) + { + // nested type + var containingTypeFullName = containingType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat); + var typeName = typeSymbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat); + return $"{containingTypeFullName}.{typeName}"; + } + return typeSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat); } } diff --git a/tests/MemoryPack.Tests/Models/DefaultValues.cs b/tests/MemoryPack.Tests/Models/DefaultValues.cs index ab878bc..c13aa0a 100644 --- a/tests/MemoryPack.Tests/Models/DefaultValues.cs +++ b/tests/MemoryPack.Tests/Models/DefaultValues.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; namespace MemoryPack.Tests.Models; @@ -26,14 +27,21 @@ partial class FieldDefaultValue [MemoryPackable] partial class PropertyDefaultValue { + internal enum NestedEnum + { + A, B + } + public int X { get; set; } public int Y { get; set; } = 12345; public float Z { get; set; } = 678.9f; public string S { get; set; } = "aaaaaaaaa"; public bool B { get; set; } = true; public List Alpha { get; set; } = new List(new HashSet()); - public TestEnum TestEnum { get; set; } = TestEnum.A; + public TestEnum E { get; set; } = TestEnum.A; + public NestedEnum E2 { get; set; } = NestedEnum.A; public (TestEnum, List) Tuple { get; set; } = (TestEnum.A, new List(new HashSet())); + public DateTime Struct { get; set; } = default!; } [MemoryPackable] @@ -44,14 +52,18 @@ partial class CtorParamDefaultValue public float Z; public string S; public bool B; + public decimal D; + public DateTime StructValue; [MemoryPackConstructor] - public CtorParamDefaultValue(int x, int y = 12345, float z = 678.9f, string s = "aaaaaa", bool b = true) + public CtorParamDefaultValue(int x, int y = 12345, float z = 678.9f, string s = "aaaaaa", bool b = true, decimal d = 99M, DateTime structValue = default) { X = x; Y = y; Z = z; S = s; B = b; + D = d; + StructValue = structValue; } }