File tree Expand file tree Collapse file tree 6 files changed +223
-16
lines changed
Immutype.Tests/Integration
Immutype.UsageScenarios.Tests Expand file tree Collapse file tree 6 files changed +223
-16
lines changed Original file line number Diff line number Diff line change 44
55namespace Immutype . Tests . Integration
66{
7+ using System . Security . Cryptography . X509Certificates ;
78 using Microsoft . CodeAnalysis ;
89
910 public class Tests
@@ -47,6 +48,34 @@ public record Rec(int val);
4748 // Then
4849 output . ShouldBe ( new [ ] { "Rec { val = 99 }" } , generatedCode ) ;
4950 }
51+
52+ [ Fact ]
53+ public void ShouldCreateRecordWithCtor ( )
54+ {
55+ // Given
56+ const string statements = "System.Console.WriteLine(new Rec(33).WithVal(99).Val);" ;
57+
58+ // When
59+ var output = @"
60+ namespace Sample
61+ {
62+ using System;
63+
64+ [Immutype.TargetAttribute()]
65+ public record Rec
66+ {
67+ public Rec(int val)
68+ {
69+ Val = val;
70+ }
71+
72+ public int Val { get; }
73+ }
74+ }" . Run ( out var generatedCode , new RunOptions { Statements = statements } ) ;
75+
76+ // Then
77+ output . ShouldBe ( new [ ] { "99" } , generatedCode ) ;
78+ }
5079
5180 [ Fact ]
5281 public void ShouldCreateRecordWithTwoValues ( )
Original file line number Diff line number Diff line change 99 - [ Removing] ( #removing )
1010 - [ Nullable collection] ( #nullable-collection )
1111 - [ Set] ( #set )
12+ - [ Record with constructor] ( #record-with-constructor )
1213
1314### Sample scenario
1415
@@ -228,3 +229,55 @@ public class Set
228229
229230
230231
232+ ### Record with constructor
233+
234+
235+
236+ ``` CSharp
237+ [Immutype .Target ]
238+ internal record Person
239+ {
240+ public Person (
241+ string name ,
242+ int ? age = default ,
243+ ICollection <Person >? friends = default )
244+ {
245+ Name = name ;
246+ Age = age ;
247+ Friends = friends ;
248+ }
249+
250+ public string Name { get ; }
251+
252+ public int ? Age { get ; }
253+
254+ public ICollection <Person >? Friends { get ; }
255+
256+ public void Deconstruct (
257+ out string name ,
258+ out int ? age ,
259+ out ICollection <Person >? friends )
260+ {
261+ name = Name ;
262+ age = Age ;
263+ friends = Friends ;
264+ }
265+ }
266+
267+ public class RecordWithConstructor
268+ {
269+ public void Run ()
270+ {
271+ var john = new Person (" John" ,15 )
272+ .WithFriends (
273+ new Person (" David" ).WithAge (16 ),
274+ new Person (" James" ).WithAge (17 )
275+ .WithFriends (new Person (" Tyler" ).WithAge (16 )));
276+
277+ john .Friends ? .Count .ShouldBe (2 );
278+ }
279+ }
280+ ```
281+
282+
283+
Original file line number Diff line number Diff line change 1+ // ReSharper disable ClassNeverInstantiated.Global
2+ // ReSharper disable MemberCanBePrivate.Global
3+ // ReSharper disable UnusedMember.Global
4+ // ReSharper disable RedundantNameQualifier
5+ // ReSharper disable CheckNamespace
6+ // ReSharper disable ConvertToPrimaryConstructor
7+ namespace Immutype . UsageScenarios . Tests . RecordWithConstructor
8+ {
9+ using System . Collections . Generic ;
10+ using Shouldly ;
11+ using Xunit ;
12+
13+ // $visible=true
14+ // $tag=1 Basics
15+ // $priority=05
16+ // $description=Record with constructor
17+ // {
18+ [ Immutype . Target ]
19+ internal record Person
20+ {
21+ public Person (
22+ string name ,
23+ int ? age = default ,
24+ ICollection < Person > ? friends = default )
25+ {
26+ Name = name ;
27+ Age = age ;
28+ Friends = friends ;
29+ }
30+
31+ public string Name { get ; }
32+
33+ public int ? Age { get ; }
34+
35+ public ICollection < Person > ? Friends { get ; }
36+
37+ public void Deconstruct (
38+ out string name ,
39+ out int ? age ,
40+ out ICollection < Person > ? friends )
41+ {
42+ name = Name ;
43+ age = Age ;
44+ friends = Friends ;
45+ }
46+ }
47+
48+ public class RecordWithConstructor
49+ {
50+ // }
51+ [ Fact ]
52+ // {
53+ public void Run ( )
54+ {
55+ var john = new Person ( "John" , 15 )
56+ . WithFriends (
57+ new Person ( "David" ) . WithAge ( 16 ) ,
58+ new Person ( "James" ) . WithAge ( 17 )
59+ . WithFriends ( new Person ( "Tyler" ) . WithAge ( 16 ) ) ) ;
60+
61+ john . Friends ? . Count . ShouldBe ( 2 ) ;
62+ }
63+ }
64+ // }
65+ }
Original file line number Diff line number Diff line change @@ -36,20 +36,22 @@ from source in Build(typeDeclarationSyntax, cancellationToken)
3636
3737 public IEnumerable < Source > Build ( TypeDeclarationSyntax typeDeclarationSyntax , CancellationToken cancellationToken )
3838 {
39- IReadOnlyList < ParameterSyntax > ? parameters = typeDeclarationSyntax switch
39+ IReadOnlyList < ParameterSyntax > ? parameters = default ;
40+ if ( typeDeclarationSyntax is RecordDeclarationSyntax recordDeclarationSyntax && recordDeclarationSyntax . ParameterList ? . Parameters . Count != 0 )
4041 {
41- RecordDeclarationSyntax recordDeclarationSyntax => recordDeclarationSyntax . ParameterList ? . Parameters ,
42- _ => (
43- from ctor in typeDeclarationSyntax . Members . OfType < ConstructorDeclarationSyntax > ( )
44- where ! cancellationToken . IsCancellationRequested
45- where ctor . Modifiers . Any ( i => i . IsKind ( SyntaxKind . PublicKeyword ) || i . IsKind ( SyntaxKind . InternalKeyword ) ) || ! ctor . Modifiers . Any ( )
46- orderby ctor . ParameterList . Parameters . Count descending
47- select ctor )
48- . FirstOrDefault ( )
49- ? . ParameterList
50- . Parameters
51- } ;
42+ parameters = recordDeclarationSyntax . ParameterList ? . Parameters ;
43+ }
5244
45+ parameters ??= (
46+ from ctor in typeDeclarationSyntax . Members . OfType < ConstructorDeclarationSyntax > ( )
47+ where ! cancellationToken . IsCancellationRequested
48+ where ctor . ParameterList . Parameters . Count > 0 && ctor . Modifiers . Any ( i => i . IsKind ( SyntaxKind . PublicKeyword ) || i . IsKind ( SyntaxKind . InternalKeyword ) ) || ! ctor . Modifiers . Any ( )
49+ orderby ctor . ParameterList . Parameters . Count descending
50+ select ctor )
51+ . FirstOrDefault ( )
52+ ? . ParameterList
53+ . Parameters ;
54+
5355 return parameters != default
5456 ? _unitFactory . Create ( typeDeclarationSyntax , parameters , cancellationToken )
5557 : Enumerable . Empty < Source > ( ) ;
Original file line number Diff line number Diff line change 22namespace Immutype . Core
33{
44 using System . Linq ;
5+ using Microsoft . CodeAnalysis ;
6+ using Microsoft . CodeAnalysis . CSharp ;
57 using Microsoft . CodeAnalysis . CSharp . Syntax ;
68
79 internal class TypeSyntaxFilter : ITypeSyntaxFilter
@@ -33,11 +35,14 @@ public bool IsAccepted(TypeDeclarationSyntax typeDeclarationSyntax)
3335 return false ;
3436 }
3537
36- return typeDeclarationSyntax switch
38+ if ( typeDeclarationSyntax is RecordDeclarationSyntax { ParameterList . Parameters . Count : > 0 } )
3739 {
38- RecordDeclarationSyntax recordDeclarationSyntax => recordDeclarationSyntax . ParameterList is { Parameters . Count : > 0 } ,
39- _ => typeDeclarationSyntax . Members . OfType < ConstructorDeclarationSyntax > ( ) . Any ( i => i . ParameterList . Parameters . Count > 0 )
40- } ;
40+ return true ;
41+ }
42+
43+ return typeDeclarationSyntax . Members
44+ . OfType < ConstructorDeclarationSyntax > ( )
45+ . Any ( ctor => ctor . ParameterList . Parameters . Count > 0 && ctor . Modifiers . Any ( i => i . IsKind ( SyntaxKind . PublicKeyword ) || i . IsKind ( SyntaxKind . InternalKeyword ) ) || ! ctor . Modifiers . Any ( ) ) ;
4146 }
4247 }
4348}
Original file line number Diff line number Diff line change @@ -95,6 +95,7 @@ _Immutype_ supports [IIncrementalGenerator](https://docs.microsoft.com/en-us/dot
9595 - [ Removing] ( #removing )
9696 - [ Nullable collection] ( #nullable-collection )
9797 - [ Set] ( #set )
98+ - [ Record with constructor] ( #record-with-constructor )
9899
99100### Sample scenario
100101
@@ -314,3 +315,55 @@ public class Set
314315
315316
316317
318+ ### Record with constructor
319+
320+
321+
322+ ``` CSharp
323+ [Immutype .Target ]
324+ internal record Person
325+ {
326+ public Person (
327+ string name ,
328+ int ? age = default ,
329+ ICollection <Person >? friends = default )
330+ {
331+ Name = name ;
332+ Age = age ;
333+ Friends = friends ;
334+ }
335+
336+ public string Name { get ; }
337+
338+ public int ? Age { get ; }
339+
340+ public ICollection <Person >? Friends { get ; }
341+
342+ public void Deconstruct (
343+ out string name ,
344+ out int ? age ,
345+ out ICollection <Person >? friends )
346+ {
347+ name = Name ;
348+ age = Age ;
349+ friends = Friends ;
350+ }
351+ }
352+
353+ public class RecordWithConstructor
354+ {
355+ public void Run ()
356+ {
357+ var john = new Person (" John" ,15 )
358+ .WithFriends (
359+ new Person (" David" ).WithAge (16 ),
360+ new Person (" James" ).WithAge (17 )
361+ .WithFriends (new Person (" Tyler" ).WithAge (16 )));
362+
363+ john .Friends ? .Count .ShouldBe (2 );
364+ }
365+ }
366+ ```
367+
368+
369+
You can’t perform that action at this time.
0 commit comments