Skip to content

Commit 61a637d

Browse files
committed
[c#] add support for init-only setters on generated classes
1 parent 79de73c commit 61a637d

File tree

9 files changed

+54
-3
lines changed

9 files changed

+54
-3
lines changed

compiler/Main.hs

+2
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ csCodegen options@Cs {..} = do
114114
else csTypeMapping
115115
fieldMapping = if readonly_properties
116116
then ReadOnlyProperties
117+
else if init_only_properties
118+
then InitOnlyProperties
117119
else if fields
118120
then PublicFields
119121
else Properties

compiler/Options.hs

+3-1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ data Options
5353
, namespace :: [String]
5454
, collection_interfaces :: Bool
5555
, readonly_properties :: Bool
56+
, init_only_properties :: Bool
5657
, fields :: Bool
5758
, jobs :: Maybe Int
5859
, no_banner :: Bool
@@ -106,9 +107,10 @@ cs :: Options
106107
cs = Cs
107108
{ collection_interfaces = def &= name "c" &= help "Use interfaces rather than concrete collection types"
108109
, readonly_properties = def &= name "r" &= help "Generate private property setters"
110+
, init_only_properties = def &= name "init-only" &= help "Generate init-only property setters"
109111
, fields = def &= name "f" &= help "Generate public fields rather than properties"
110112
, structs_enabled = True &= explicit &= name "structs" &= help "Generate C# types for Bond structs and enums (true by default, use \"--structs=false\" to disable)"
111-
, constructor_parameters = def &= explicit &= name "preview-constructor-parameters" &= help "PREVIEW FEATURE: Generate a constructor that takes all the fields as parameters. Typically used with readonly-properties."
113+
, constructor_parameters = def &= explicit &= name "preview-constructor-parameters" &= help "PREVIEW FEATURE: Generate a constructor that takes all the fields as parameters. Typically used with readonly-properties or init-only-properties."
112114
} &=
113115
name "c#" &=
114116
help "Generate C# code"

compiler/src/Language/Bond/Codegen/Cs/Types_cs.hs

+3-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ data StructMapping =
3131
data FieldMapping =
3232
PublicFields | -- ^ public fields
3333
Properties | -- ^ auto-properties
34-
ReadOnlyProperties -- ^ auto-properties with private setter
34+
ReadOnlyProperties | -- ^ auto-properties with private setter
35+
InitOnlyProperties -- ^ auto-properties with init-only setter
3536
deriving Eq
3637

3738
-- | Options for how constructors should be generated.
@@ -186,6 +187,7 @@ namespace #{csNamespace}
186187
PublicFields -> [lt|#{optional fieldInitializer $ csDefault f};|]
187188
Properties -> [lt| { get; set; }|]
188189
ReadOnlyProperties -> [lt| { get; private set; }|]
190+
InitOnlyProperties -> [lt| { get; init; }|]
189191
fieldInitializer x = [lt| = #{x}|]
190192
new = if isBaseField fieldName structBase then "new " else "" :: String
191193

compiler/tests/TestMain.hs

+14
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,13 @@ tests = testGroup "Compiler tests"
151151
]
152152
"complex_inheritance"
153153
"constructor-parameters"
154+
, verifyCodegenVariation
155+
[ "c#"
156+
, "--preview-constructor-parameters"
157+
, "--init-only-properties"
158+
]
159+
"complex_inheritance"
160+
"constructor-parameters"
154161
, verifyCodegenVariation
155162
[ "c#"
156163
, "--preview-constructor-parameters"
@@ -180,6 +187,13 @@ tests = testGroup "Compiler tests"
180187
]
181188
"empty_struct"
182189
"constructor-parameters"
190+
, verifyCodegenVariation
191+
[ "c#"
192+
, "--preview-constructor-parameters"
193+
, "--init-only-properties"
194+
]
195+
"empty_struct"
196+
"constructor-parameters"
183197
]
184198
, testGroup "Java"
185199
[ verifyJavaCodegen "attributes"

compiler/tests/Tests/Codegen.hs

+2
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ verifyFiles options baseName variation =
9393
verify = verifyFile options baseName
9494
fieldMapping Cs {..} = if readonly_properties
9595
then ReadOnlyProperties
96+
else if init_only_properties
97+
then InitOnlyProperties
9698
else if fields
9799
then PublicFields
98100
else Properties

cs/nuget/bond.csharp.test.csproj

+5
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,9 @@
4040
<Options>$(BondOptions) --using="DateTime=System.DateTime"</Options>
4141
</BondCodegen>
4242
</ItemGroup>
43+
<ItemGroup Condition="$(TargetFramework.StartsWith('net5.0')) or $(TargetFramework.StartsWith('net6.0'))">
44+
<BondCodegen Update="..\test\core\InitOnly.bond">
45+
<Options>$(BondOptions) --init-only-properties</Options>
46+
</BondCodegen>
47+
</ItemGroup>
4348
</Project>

cs/test/core/SerializationTests.cs

+14
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,20 @@ public void ReadonlySimpleContainers()
8383
TestSerialization<Readonly.SimpleContainers>();
8484
}
8585

86+
#if NET5_0_OR_GREATER
87+
[Test]
88+
public void InitOnlyBasicTypes()
89+
{
90+
TestSerialization<InitOnly.BasicTypes>();
91+
}
92+
93+
[Test]
94+
public void InitOnlySimpleContainers()
95+
{
96+
TestSerialization<InitOnly.SimpleContainers>();
97+
}
98+
#endif
99+
86100
[Test]
87101
public void Nested()
88102
{

cs/test/coreNS10/CoreNS10.csproj

+5
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@
3737
<Options Condition=" '$(Configuration)' != 'Fields' ">$(BondOptions) --readonly-properties</Options>
3838
<Options Condition=" '$(Configuration)' == 'Fields' ">--readonly-properties --collection-interfaces</Options>
3939
</BondCodegen>
40+
<BondCodegen Update="InitOnly.bond">
41+
<Options Condition=" '$(Configuration)' != 'Fields' ">$(BondOptions) --init-only-properties</Options>
42+
<Options Condition=" '$(Configuration)' == 'Fields' ">--init-only-properties --collection-interfaces</Options>
43+
</BondCodegen>
4044
<BondCodegen Include="..\core\Containers.bond">
4145
<Options Condition=" '$(Configuration)' != 'Fields' ">$(BondOptions) --collection-interfaces</Options>
4246
<Options Condition=" '$(Configuration)' == 'Fields' ">--fields</Options>
@@ -53,6 +57,7 @@
5357
<Compile Include="$(IntermediateOutputPath)\NamespaceConflict_types.cs" Condition="False" />
5458
<Compile Include="$(IntermediateOutputPath)\NamespaceConflictBond_types.cs" Condition="False" />
5559
<Compile Include="$(IntermediateOutputPath)\ReadOnly_types.cs" Condition="False" />
60+
<Compile Include="$(IntermediateOutputPath)\InitOnly_types.cs" Condition="False" />
5661
<Compile Include="$(IntermediateOutputPath)\UnitTest_types.cs" Condition="False" />
5762
<!-- End Resharper Workaround -->
5863
</ItemGroup>

doc/src/bond_cs.md

+6-1
Original file line numberDiff line numberDiff line change
@@ -127,11 +127,16 @@ Schema fields are represented by properties with public getter and private
127127
setter and initialized to the default values in the default constructor.
128128
Classes with read-only properties are fully supported by all Bond APIs.
129129

130+
`--init-only-properties`
131+
132+
Schema fields are represented by properties with public getter and
133+
[C# 9 init-only setter](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/init) and initialized to the default values in the default constructor. Classes with init-only properties are fully supported by all Bond APIs.
134+
130135
`--preview-constructor-parameters`
131136

132137
A constructor is generated with a parameter to initialize each of the schema
133138
fields. This option is typically used in conjunction with
134-
`--readonly-properties`. This functionailty is in preview and may change.
139+
`--readonly-properties` or `--init-only-properties`. This functionailty is in preview and may change.
135140

136141
`--collection-interfaces`
137142

0 commit comments

Comments
 (0)