Skip to content

Commit 22e107f

Browse files
authored
Merge pull request #253 from Cysharp/ku/fix-default-value2
Fix problem when default value expression contains namespace
2 parents f2ce54e + 42e3456 commit 22e107f

File tree

4 files changed

+69
-9
lines changed

4 files changed

+69
-9
lines changed

src/MemoryPack.Generator/MemoryPackGenerator.Emitter.cs

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ static void Generate(TypeDeclarationSyntax syntax, Compilation compilation, stri
4646
}
4747
var unionFormatter = (unionSymbol != null);
4848

49-
var typeMeta = new TypeMeta(typeSymbol, reference);
49+
var typeMeta = new TypeMeta(semanticModel, typeSymbol, reference);
5050
if (unionFormatter)
5151
{
5252
// replace original symbol
@@ -1383,5 +1383,53 @@ string EmitConstantValue(object? constantValue)
13831383
}
13841384
return "null";
13851385
}
1386-
}
13871386

1387+
string EmitExpression(ExpressionSyntax expression)
1388+
{
1389+
switch (expression.Kind())
1390+
{
1391+
case SyntaxKind.SimpleMemberAccessExpression:
1392+
{
1393+
var memberAccess = (MemberAccessExpressionSyntax)expression;
1394+
var memberSymbol = semanticModel.GetSymbolInfo(memberAccess.Name).Symbol;
1395+
if (memberSymbol is INamedTypeSymbol namedTypeSymbol && namedTypeSymbol.TypeKind == TypeKind.Enum)
1396+
{
1397+
return $"{GetTypeFullName(namedTypeSymbol, semanticModel)}.{memberAccess.Name}";
1398+
}
1399+
if (memberSymbol is IFieldSymbol fieldSymbol && fieldSymbol.ContainingType.TypeKind == TypeKind.Enum)
1400+
{
1401+
return $"{GetTypeFullName(fieldSymbol.ContainingType, semanticModel)}.{fieldSymbol.Name}";
1402+
}
1403+
break;
1404+
}
1405+
1406+
case SyntaxKind.ObjectCreationExpression:
1407+
{
1408+
var objectCreation = (ObjectCreationExpressionSyntax)expression;
1409+
var symbolInfo = semanticModel.GetSymbolInfo(objectCreation.Type);
1410+
if (symbolInfo.Symbol is INamedTypeSymbol x)
1411+
{
1412+
var arguments = string.Join(", ",
1413+
objectCreation.ArgumentList?.Arguments.Select(arg =>
1414+
EmitExpression(arg.Expression)) ?? Enumerable.Empty<string>());
1415+
return $"new {x.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)}({arguments})";
1416+
}
1417+
break;
1418+
}
1419+
1420+
case SyntaxKind.TupleExpression:
1421+
var tupleExpression = (TupleExpressionSyntax)expression;
1422+
var tupleElements = string.Join(", ",
1423+
tupleExpression.Arguments.Select(arg => EmitExpression(arg.Expression)));
1424+
return $"({tupleElements})";
1425+
}
1426+
return expression.ToString();
1427+
}
1428+
1429+
string GetTypeFullName(ITypeSymbol typeSymbol, SemanticModel semanticModel)
1430+
{
1431+
var containingType = typeSymbol.ContainingType;
1432+
var containingTypeFullName = containingType == null ? "" : GetTypeFullName(containingType, semanticModel) + ".";
1433+
return containingTypeFullName + typeSymbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat);
1434+
}
1435+
}

src/MemoryPack.Generator/MemoryPackGenerator.Parser.cs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ public partial class TypeMeta
6666
public (ushort Tag, INamedTypeSymbol Type)[] UnionTags { get; }
6767
public bool IsUseEmptyConstructor => Constructor == null || Constructor.Parameters.IsEmpty;
6868

69-
public TypeMeta(INamedTypeSymbol symbol, ReferenceSymbols reference)
69+
public TypeMeta(SemanticModel semanticModel, INamedTypeSymbol symbol, ReferenceSymbols reference)
7070
{
7171
this.reference = reference;
7272
this.Symbol = symbol;
@@ -104,7 +104,7 @@ public TypeMeta(INamedTypeSymbol symbol, ReferenceSymbols reference)
104104
}
105105
return true;
106106
})
107-
.Select((x, i) => new MemberMeta(x, Constructor, reference, i))
107+
.Select((x, i) => new MemberMeta(semanticModel, x, Constructor, reference, i))
108108
.OrderBy(x => x.Order)
109109
.ToArray();
110110

@@ -616,6 +616,7 @@ partial class MemberMeta
616616
public bool HasExplicitOrder { get; }
617617
public MemberKind Kind { get; }
618618
public string DefaultValueExpression { get; } = "default!";
619+
readonly SemanticModel semanticModel;
619620

620621
MemberMeta(int order)
621622
{
@@ -626,8 +627,9 @@ partial class MemberMeta
626627
this.Kind = MemberKind.Blank;
627628
}
628629

629-
public MemberMeta(ISymbol symbol, IMethodSymbol? constructor, ReferenceSymbols references, int sequentialOrder)
630+
public MemberMeta(SemanticModel semanticModel, ISymbol symbol, IMethodSymbol? constructor, ReferenceSymbols references, int sequentialOrder)
630631
{
632+
this.semanticModel = semanticModel;
631633
this.Symbol = symbol;
632634
this.Name = symbol.Name;
633635
this.Order = sequentialOrder;
@@ -677,13 +679,13 @@ public MemberMeta(ISymbol symbol, IMethodSymbol? constructor, ReferenceSymbols r
677679
{
678680
if (variables.First().Initializer is { } initializer)
679681
{
680-
DefaultValueExpression = initializer.Value.ToString();
682+
DefaultValueExpression = EmitExpression(initializer.Value);
681683
break;
682684
}
683685
}
684686
if (syntax is VariableDeclaratorSyntax { Initializer: { } initializer2 })
685687
{
686-
DefaultValueExpression = initializer2.Value.ToString();
688+
DefaultValueExpression = EmitExpression(initializer2.Value);
687689
break;
688690
}
689691
}
@@ -705,7 +707,7 @@ public MemberMeta(ISymbol symbol, IMethodSymbol? constructor, ReferenceSymbols r
705707
{
706708
if (syntaxReference.GetSyntax() is PropertyDeclarationSyntax { Initializer: { } initializer })
707709
{
708-
DefaultValueExpression = initializer.Value.ToString();
710+
DefaultValueExpression = EmitExpression(initializer.Value);
709711
break;
710712
}
711713
}

src/MemoryPack.Generator/MemoryPackGenerator.TypeScript.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ partial class MemoryPackGenerator
3838
return null;
3939
}
4040

41-
var typeMeta = new TypeMeta(typeSymbol, reference);
41+
var typeMeta = new TypeMeta(semanticModel, typeSymbol, reference);
4242

4343
if (typeMeta.GenerateType is not (GenerateType.Object or GenerateType.Union))
4444
{

tests/MemoryPack.Tests/Models/DefaultValues.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
1+
using System.Collections.Generic;
2+
13
namespace MemoryPack.Tests.Models;
24

5+
enum TestEnum
6+
{
7+
A, B, C
8+
}
9+
310
[MemoryPackable]
411
partial class DefaultValuePlaceholder
512
{
@@ -24,6 +31,9 @@ partial class PropertyDefaultValue
2431
public float Z { get; set; } = 678.9f;
2532
public string S { get; set; } = "aaaaaaaaa";
2633
public bool B { get; set; } = true;
34+
public List<string> Alpha { get; set; } = new List<string>(new HashSet<string>());
35+
public TestEnum TestEnum { get; set; } = TestEnum.A;
36+
public (TestEnum, List<string>) Tuple { get; set; } = (TestEnum.A, new List<string>(new HashSet<string>()));
2737
}
2838

2939
[MemoryPackable]

0 commit comments

Comments
 (0)