Skip to content

Commit 9868a8d

Browse files
committed
Added support for property initializers
1 parent e060000 commit 9868a8d

File tree

2 files changed

+65
-18
lines changed

2 files changed

+65
-18
lines changed

Diff for: src/CodeGeneration/CSharpProperty.cs

+42-18
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@ public CSharpProperty(CSharpIdentifier type, string name)
4646
/// </summary>
4747
public List<CSharpAttribute> Attributes { get; } = new List<CSharpAttribute>();
4848

49+
/// <summary>
50+
/// The property's initializer (sets default value).
51+
/// </summary>
52+
public CSharpConstructor? Initializer { get; set; }
53+
4954
/// <summary>
5055
/// An expression body for the property's getter.
5156
/// </summary>
@@ -61,14 +66,20 @@ public CSharpProperty(CSharpIdentifier type, string name)
6166
/// </summary>
6267
internal IEnumerable<string> GetNamespaces()
6368
{
69+
foreach (string ns in Type.GetNamespaces())
70+
yield return ns;
71+
6472
foreach (string? ns in Attributes.Select(x => x.Identifier.Namespace))
6573
{
6674
if (ns != null)
6775
yield return ns;
6876
}
6977

70-
foreach (string ns in Type.GetNamespaces())
71-
yield return ns;
78+
if (Initializer != null)
79+
{
80+
foreach (string ns in Initializer.GetNamespaces())
81+
yield return ns;
82+
}
7283

7384
if (GetterExpression != null)
7485
{
@@ -83,28 +94,41 @@ internal IEnumerable<string> GetNamespaces()
8394
/// <param name="makePublic">Controls whether to make the property public or not.</param>
8495
internal PropertyDeclarationSyntax ToSyntax(bool makePublic = false)
8596
{
86-
var propertyDeclaration =
87-
PropertyDeclaration(Type.ToSyntax(), Identifier(Name));
97+
var declaration = PropertyDeclaration(Type.ToSyntax(), Identifier(Name));
8898

8999
if (makePublic)
90-
propertyDeclaration = propertyDeclaration.AddModifiers(Token(SyntaxKind.PublicKeyword));
100+
declaration = declaration.AddModifiers(Token(SyntaxKind.PublicKeyword));
91101

92-
propertyDeclaration = propertyDeclaration
93-
.WithAttributeLists(List(Attributes.Select(x => x.ToSyntax())))
94-
.WithDocumentation(Summary);
102+
declaration = declaration.WithAttributeLists(List(Attributes.Select(x => x.ToSyntax())))
103+
.WithDocumentation(Summary);
95104

96-
return (GetterExpression == null)
97-
? propertyDeclaration.WithAccessorList(AccessorList(List(GetAccessors())))
98-
: propertyDeclaration.WithExpressionBody(ArrowExpressionClause(GetterExpression.ToInvocationSyntax()))
99-
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken));
100-
}
105+
if (GetterExpression != null)
106+
{
107+
if (Initializer != null)
108+
throw new InvalidOperationException($"{nameof(GetterExpression)} and {nameof(Initializer)} may not be both set for the same {nameof(CSharpProperty)}.");
101109

102-
private IEnumerable<AccessorDeclarationSyntax> GetAccessors()
103-
{
104-
AccessorDeclarationSyntax Declaration(SyntaxKind kind) => AccessorDeclaration(kind).WithSemicolonToken(Token(SyntaxKind.SemicolonToken));
110+
if (HasSetter)
111+
throw new InvalidOperationException($"{nameof(GetterExpression)} and {nameof(HasSetter)} may not be both set for the same {nameof(CSharpProperty)}.");
112+
113+
declaration = declaration.WithExpressionBody(ArrowExpressionClause(GetterExpression.ToInvocationSyntax()))
114+
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken));
115+
}
116+
else
117+
{
118+
var accessors = new List<SyntaxKind> {SyntaxKind.GetAccessorDeclaration};
119+
if (HasSetter) accessors.Add(SyntaxKind.SetAccessorDeclaration);
120+
121+
declaration = declaration.WithAccessorList(AccessorList(List(
122+
accessors.Select(x => AccessorDeclaration(x).WithSemicolonToken(Token(SyntaxKind.SemicolonToken))))));
123+
}
124+
125+
if (Initializer != null)
126+
{
127+
declaration = declaration.WithInitializer(EqualsValueClause(Initializer.ToInvocationSyntax()))
128+
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken));
129+
}
105130

106-
yield return Declaration(SyntaxKind.GetAccessorDeclaration);
107-
if (HasSetter) yield return Declaration(SyntaxKind.SetAccessorDeclaration);
131+
return declaration;
108132
}
109133

110134
/// <summary>

Diff for: src/UnitTests/CSharpClassFacts.cs

+23
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,19 @@ public void GeneratesCorrectCode()
4545
new CSharpParameter(CSharpIdentifier.String, "arg2") {Value = "value"}
4646
}
4747
}
48+
},
49+
new CSharpProperty(myInterface, "MyOtherProperty")
50+
{
51+
Summary = "My other property",
52+
HasSetter = true,
53+
Initializer = new CSharpConstructor(otherClass)
54+
{
55+
Parameters =
56+
{
57+
new CSharpParameter(myClass, "arg1") {Value = new ThisReference()},
58+
new CSharpParameter(CSharpIdentifier.String, "arg2") {Value = "value"}
59+
}
60+
}
4861
}
4962
}
5063
}, @"using Attributes;
@@ -69,6 +82,16 @@ public MyClass(IEndpoint referrer): base(referrer, relativeUri: ""./sample"")
6982
/// My property
7083
/// </summary>
7184
public MyInterface<MyModel> MyProperty => new OtherClass<MyModel>(this, arg2: ""value"");
85+
/// <summary>
86+
/// My other property
87+
/// </summary>
88+
public MyInterface<MyModel> MyOtherProperty
89+
{
90+
get;
91+
set;
92+
}
93+
94+
= new OtherClass<MyModel>(this, arg2: ""value"");
7295
}
7396
}");
7497
}

0 commit comments

Comments
 (0)