Skip to content

Commit 1c63c16

Browse files
Improve generator code layout (#638)
* Improve generator code layout * Improve `Cartesian` coverage
1 parent 17f5689 commit 1c63c16

File tree

23 files changed

+6712
-4859
lines changed

23 files changed

+6712
-4859
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,66 @@
1-
{{
2-
$arity = arity
3-
$ordinals = ordinals
4-
$cardinals = cardinals
5-
}}
6-
1+
{{~
2+
$arity = arity
3+
$ordinals = ordinals
4+
$cardinals = cardinals
5+
~}}
76
namespace SuperLinq.Async;
87

98
#nullable enable
109

1110
public static partial class AsyncSuperEnumerable
1211
{
1312
{{~ for $i in 2..4 ~}}
14-
/// <summary>
13+
/// <summary>
1514
/// <para>
1615
/// Applies a specified function to the corresponding elements of {{ $ordinals[$i] }} sequences,
1716
/// producing a sequence of the results.</para>
1817
/// <para>
1918
/// The resulting sequence has the same length as the input sequences.
2019
/// If the input sequences are of different lengths, an exception is thrown.</para>
21-
/// </summary>
22-
/// <typeparam name="TResult">
23-
/// The type of the elements of the result sequence.</typeparam>
24-
/// <param name="resultSelector">A projection function that combines
25-
/// elements from all of the sequences.</param>
26-
/// <returns>A sequence of elements returned by <paramref name="resultSelector"/>.</returns>
27-
/// <remarks>
28-
/// This method uses deferred execution and stream its results.
29-
/// </remarks>
30-
/// <exception cref="global::System.ArgumentNullException"><paramref name="resultSelector"/> or any of the input sequences is null.</exception>
31-
/// <exception cref="global::System.InvalidOperationException">
20+
/// </summary>
21+
/// <typeparam name="TResult">
22+
/// The type of the elements of the result sequence.</typeparam>
23+
/// <param name="resultSelector">A projection function that combines
24+
/// elements from all of the sequences.</param>
25+
/// <returns>A sequence of elements returned by <paramref name="resultSelector"/>.</returns>
26+
/// <remarks>
27+
/// This method uses deferred execution and stream its results.
28+
/// </remarks>
29+
/// <exception cref="global::System.ArgumentNullException"><paramref name="resultSelector"/> or any of the input sequences is null.</exception>
30+
/// <exception cref="global::System.InvalidOperationException">
3231
/// Any of the input sequences are shorter than the others.
3332
/// </exception>
3433
{{~ for $j in 1..$i ~}}
35-
/// <typeparam name="T{{ $cardinals[$j] }}">The type of the elements of <paramref name="{{ $ordinals[$j] }}" />.</typeparam>
34+
/// <typeparam name="T{{ $cardinals[$j] }}">The type of the elements of <paramref name="{{ $ordinals[$j] }}" />.</typeparam>
3635
/// <param name="{{ $ordinals[$j] }}">The {{ $ordinals[$j] }} sequence of elements.</param>
3736
{{~ end ~}}
38-
public static global::System.Collections.Generic.IAsyncEnumerable<TResult> EquiZip<{{ for $j in 1..$i }}T{{ $cardinals[$j] }}, {{ end }}TResult>(this
37+
public static global::System.Collections.Generic.IAsyncEnumerable<TResult> EquiZip<{{ for $j in 1..$i }}T{{ $cardinals[$j] }}, {{ end }}TResult>(this
3938
{{~ for $j in 1..$i ~}}
40-
global::System.Collections.Generic.IAsyncEnumerable<T{{ $cardinals[$j] }}> {{ $ordinals[$j] }},
39+
global::System.Collections.Generic.IAsyncEnumerable<T{{ $cardinals[$j] }}> {{ $ordinals[$j] }},
4140
{{~ end ~}}
42-
global::System.Func<{{ for $j in 1..$i }}T{{ $cardinals[$j] }}, {{ end }}TResult> resultSelector)
41+
global::System.Func<{{ for $j in 1..$i }}T{{ $cardinals[$j] }}, {{ end }}TResult> resultSelector
42+
)
4343
{
4444
{{~ for $j in 1..$i ~}}
45-
ArgumentNullException.ThrowIfNull({{ $ordinals[$j] }});
45+
ArgumentNullException.ThrowIfNull({{ $ordinals[$j] }});
4646
{{~ end ~}}
4747

48-
ArgumentNullException.ThrowIfNull(resultSelector);
48+
ArgumentNullException.ThrowIfNull(resultSelector);
4949

5050
return Core(
5151
{{~ for $j in 1..$i ~}}
5252
{{ $ordinals[$j] }},
5353
{{~ end ~}}
54-
resultSelector);
54+
resultSelector
55+
);
5556

5657
static async global::System.Collections.Generic.IAsyncEnumerable<TResult> Core(
5758
{{~ for $j in 1..$i ~}}
5859
global::System.Collections.Generic.IAsyncEnumerable<T{{ $cardinals[$j] }}> {{ $ordinals[$j] }},
5960
{{~ end ~}}
6061
global::System.Func<{{ for $j in 1..$i }}T{{ $cardinals[$j] }}, {{ end }}TResult> resultSelector,
61-
[EnumeratorCancellation] CancellationToken cancellationToken = default)
62+
[EnumeratorCancellation] CancellationToken cancellationToken = default
63+
)
6264
{
6365
{{~ for $j in 1..$i ~}}
6466
await using var e{{ $j }} = {{ $ordinals[$j] }}.ConfigureAwait(false).WithCancellation(cancellationToken).GetAsyncEnumerator();
@@ -75,10 +77,10 @@ public static partial class AsyncSuperEnumerable
7577
|| await e{{$j}}.MoveNextAsync()
7678
{{~ end
7779
end ~}}
78-
)
80+
)
7981
{
80-
ThrowHelper.ThrowInvalidOperationException("First sequence too short.");
81-
}
82+
ThrowHelper.ThrowInvalidOperationException("First sequence too short.");
83+
}
8284

8385
yield break;
8486
}
@@ -101,26 +103,27 @@ public static partial class AsyncSuperEnumerable
101103
/// <summary>
102104
/// Joins the corresponding elements of {{ $ordinals[$i] }} sequences,
103105
/// producing a sequence of tuples containing them.
104-
/// </summary>
105-
/// <returns>A sequence of
106+
/// </summary>
107+
/// <returns>A sequence of
106108
/// <see cref="global::System.ValueTuple{ {{~ for $j in 1..$i ~}}T{{$j}}{{ if !for.last }},{{ end }}{{ end }} }" />
107-
/// containing corresponding elements from each of the sequences.</returns>
108-
/// <remarks>
109-
/// This method uses deferred execution and stream its results.
110-
/// </remarks>
111-
/// <exception cref="global::System.ArgumentNullException">Any of the input sequences is null.</exception>
112-
/// <exception cref="global::System.InvalidOperationException">
109+
/// containing corresponding elements from each of the sequences.</returns>
110+
/// <remarks>
111+
/// This method uses deferred execution and stream its results.
112+
/// </remarks>
113+
/// <exception cref="global::System.ArgumentNullException">Any of the input sequences is null.</exception>
114+
/// <exception cref="global::System.InvalidOperationException">
113115
/// Any of the input sequences are shorter than the others.
114116
/// </exception>
115117
{{~ for $j in 1..$i ~}}
116-
/// <typeparam name="T{{ $cardinals[$j] }}">The type of the elements of <paramref name="{{ $ordinals[$j] }}" />.</typeparam>
118+
/// <typeparam name="T{{ $cardinals[$j] }}">The type of the elements of <paramref name="{{ $ordinals[$j] }}" />.</typeparam>
117119
/// <param name="{{ $ordinals[$j] }}">The {{ $ordinals[$j] }} sequence of elements.</param>
118120
{{~ end ~}}
119-
public static global::System.Collections.Generic.IAsyncEnumerable<({{~ for $j in 1..$i ~}}T{{ $cardinals[$j] }}{{ if !for.last }},{{ end }}{{ end }})>
121+
public static global::System.Collections.Generic.IAsyncEnumerable<({{~ for $j in 1..$i ~}}T{{ $cardinals[$j] }}{{ if !for.last }},{{ end }}{{ end }})>
120122
EquiZip<{{~ for $j in 1..$i ~}}T{{ $cardinals[$j] }}{{ if !for.last }},{{ end }}{{ end }}>(this
121123
{{~ for $j in 1..$i ~}}
122124
global::System.Collections.Generic.IAsyncEnumerable<T{{ $cardinals[$j] }}> {{ $ordinals[$j] }}{{ if !for.last }},{{ end }}
123-
{{~ end ~}}) =>
124-
EquiZip({{~ for $j in 1..$i ~}}{{ $ordinals[$j] }}, {{ end }}global::System.ValueTuple.Create);
125-
{{ end ~}}
125+
{{~ end ~}}
126+
) => EquiZip({{~ for $j in 1..$i ~}}{{ $ordinals[$j] }}, {{ end }}global::System.ValueTuple.Create);
127+
128+
{{~ end ~}}
126129
}
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,39 @@
1-
namespace SuperLinq.Async;
1+
namespace SuperLinq.Async;
22

33
#nullable enable
44

55
public static partial class AsyncSuperEnumerable
66
{
77
{{~ for $i in 1..16 ~}}
8-
/// <summary>
9-
/// Returns the result of applying a function to a sequence of {{$i}} element{{if $i != 1}}s{{end}}.
10-
/// </summary>
11-
/// <remarks>
12-
/// This operator uses immediate execution and buffers as many items of the source sequence as necessary.
13-
/// </remarks>
14-
/// <typeparam name="T">Type of element in the source sequence</typeparam>
15-
/// <typeparam name="TResult">Type of the result</typeparam>
16-
/// <param name="source">The sequence of items to fold.</param>
17-
/// <param name="folder">Function to apply to the elements in the sequence.</param>
18-
/// <returns>The folded value returned by <paramref name="folder"/>.</returns>
19-
/// <exception cref="global::System.ArgumentNullException"><paramref name="source"/> or <paramref name="folder"/> is null.</exception>
20-
/// <exception cref="global::System.InvalidOperationException">
8+
/// <summary>
9+
/// Returns the result of applying a function to a sequence of {{$i}} element{{if $i != 1}}s{{end}}.
10+
/// </summary>
11+
/// <remarks>
12+
/// This operator uses immediate execution and buffers as many items of the source sequence as necessary.
13+
/// </remarks>
14+
/// <typeparam name="T">Type of element in the source sequence</typeparam>
15+
/// <typeparam name="TResult">Type of the result</typeparam>
16+
/// <param name="source">The sequence of items to fold.</param>
17+
/// <param name="folder">Function to apply to the elements in the sequence.</param>
18+
/// <returns>The folded value returned by <paramref name="folder"/>.</returns>
19+
/// <exception cref="global::System.ArgumentNullException"><paramref name="source"/> or <paramref name="folder"/> is null.</exception>
20+
/// <exception cref="global::System.InvalidOperationException">
2121
/// <paramref name="source"/> does not contain exactly {{$i}} element{{if $i != 1}}s{{end}}.
2222
/// </exception>
23-
public static global::System.Threading.Tasks.ValueTask<TResult> Fold<T, TResult>(this global::System.Collections.Generic.IAsyncEnumerable<T> source, global::System.Func<
24-
{{~ for $j in 1..$i ~}}
25-
T,
26-
{{~ end ~}}
27-
TResult> folder)
28-
{
23+
public static global::System.Threading.Tasks.ValueTask<TResult> Fold<T, TResult>(
24+
this global::System.Collections.Generic.IAsyncEnumerable<T> source,
25+
global::System.Func<{{~ for $j in 1..$i ~}}T, {{ end ~}}TResult> folder
26+
)
27+
{
2928
ArgumentNullException.ThrowIfNull(source);
3029
ArgumentNullException.ThrowIfNull(folder);
3130

3231
return Core(source, folder);
3332

34-
static async global::System.Threading.Tasks.ValueTask<TResult> Core(global::System.Collections.Generic.IAsyncEnumerable<T> source, global::System.Func<
35-
{{~ for $j in 1..$i ~}}
36-
T,
37-
{{~ end ~}}
38-
TResult> folder)
33+
static async global::System.Threading.Tasks.ValueTask<TResult> Core(
34+
global::System.Collections.Generic.IAsyncEnumerable<T> source,
35+
global::System.Func<{{~ for $j in 1..$i ~}}T, {{ end ~}}TResult> folder
36+
)
3937
{
4038
var elements = await source.AssertCount({{$i}}).ToListAsync().ConfigureAwait(false);
4139

@@ -46,5 +44,6 @@ public static partial class AsyncSuperEnumerable
4644
);
4745
}
4846
}
49-
{{ end ~}}
47+
48+
{{~ end ~}}
5049
}

Generators/SuperLinq.Async.Generator/Generator.cs

+1-9
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System.Text;
1+
using System.Text;
22
using Microsoft.CodeAnalysis;
33
using Microsoft.CodeAnalysis.Text;
44
using Scriban;
@@ -28,14 +28,6 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
2828
private static SourceText GenerateArgumentNamesTemplate(string template)
2929
{
3030
var output = Template.Parse(template).Render(ArgumentNames.Instance);
31-
32-
// Apply formatting since indenting isn't that nice in Scriban when rendering nested
33-
// structures via functions.
34-
output = Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ParseCompilationUnit(output)
35-
.NormalizeWhitespace()
36-
.GetText()
37-
.ToString();
38-
3931
return SourceText.From(output, Encoding.UTF8);
4032
}
4133
}
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,62 @@
1-
{{
2-
$arity = arity
3-
$ordinals = ordinals
4-
$cardinals = cardinals
5-
}}
6-
1+
{{~
2+
$arity = arity
3+
$ordinals = ordinals
4+
$cardinals = cardinals
5+
~}}
76
namespace SuperLinq.Async;
87

98
#nullable enable
109

1110
public static partial class AsyncSuperEnumerable
1211
{
1312
{{~ for $i in 2..4 ~}}
14-
/// <summary>
13+
/// <summary>
1514
/// Returns a projection of tuples, where each tuple contains the N-th
1615
/// element from each of the argument sequences. The resulting sequence
1716
/// will always be as long as the longest of input sequences where the
1817
/// default value of each of the shorter sequence element types is used
1918
/// for padding.
20-
/// </summary>
21-
/// <typeparam name="TResult">
22-
/// The type of the elements of the result sequence.</typeparam>
23-
/// <param name="resultSelector">A projection function that combines
24-
/// elements from all of the sequences.</param>
25-
/// <returns>A sequence of elements returned by <paramref name="resultSelector"/>.</returns>
26-
/// <remarks>
27-
/// This method uses deferred execution and streams its results.
28-
/// </remarks>
29-
/// <exception cref="global::System.ArgumentNullException"><paramref name="resultSelector"/> or any of the input sequences is null.</exception>
19+
/// </summary>
20+
/// <typeparam name="TResult">
21+
/// The type of the elements of the result sequence.</typeparam>
22+
/// <param name="resultSelector">A projection function that combines
23+
/// elements from all of the sequences.</param>
24+
/// <returns>A sequence of elements returned by <paramref name="resultSelector"/>.</returns>
25+
/// <remarks>
26+
/// This method uses deferred execution and streams its results.
27+
/// </remarks>
28+
/// <exception cref="global::System.ArgumentNullException"><paramref name="resultSelector"/> or any of the input sequences is null.</exception>
3029
{{~ for $j in 1..$i ~}}
31-
/// <typeparam name="T{{ $j }}">The type of the elements of <paramref name="{{ $ordinals[$j] }}" />.</typeparam>
30+
/// <typeparam name="T{{ $j }}">The type of the elements of <paramref name="{{ $ordinals[$j] }}" />.</typeparam>
3231
/// <param name="{{ $ordinals[$j] }}">The {{ $ordinals[$j] }} sequence of elements.</param>
3332
{{~ end ~}}
34-
public static global::System.Collections.Generic.IAsyncEnumerable<TResult> ZipLongest<{{ for $j in 1..$i }}T{{ $j }}, {{ end }}TResult>(this
33+
public static global::System.Collections.Generic.IAsyncEnumerable<TResult> ZipLongest<{{ for $j in 1..$i }}T{{ $j }}, {{ end }}TResult>(this
3534
{{~ for $j in 1..$i ~}}
36-
global::System.Collections.Generic.IAsyncEnumerable<T{{ $j }}> {{ $ordinals[$j] }},
35+
global::System.Collections.Generic.IAsyncEnumerable<T{{ $j }}> {{ $ordinals[$j] }},
3736
{{~ end ~}}
38-
global::System.Func<{{ for $j in 1..$i }}T{{ $j }}?, {{ end }}TResult> resultSelector)
37+
global::System.Func<{{ for $j in 1..$i }}T{{ $j }}?, {{ end }}TResult> resultSelector
38+
)
3939
{
4040
{{~ for $j in 1..$i ~}}
41-
ArgumentNullException.ThrowIfNull({{ $ordinals[$j] }});
41+
ArgumentNullException.ThrowIfNull({{ $ordinals[$j] }});
4242
{{~ end ~}}
4343

44-
ArgumentNullException.ThrowIfNull(resultSelector);
44+
ArgumentNullException.ThrowIfNull(resultSelector);
4545

4646
return Core(
4747
{{~ for $j in 1..$i ~}}
4848
{{ $ordinals[$j] }},
4949
{{~ end ~}}
50-
resultSelector);
50+
resultSelector
51+
);
5152

5253
static async global::System.Collections.Generic.IAsyncEnumerable<TResult> Core(
5354
{{~ for $j in 1..$i ~}}
5455
global::System.Collections.Generic.IAsyncEnumerable<T{{ $j }}> {{ $ordinals[$j] }},
5556
{{~ end ~}}
5657
global::System.Func<{{ for $j in 1..$i }}T{{ $j }}?, {{ end }}TResult> resultSelector,
57-
[EnumeratorCancellation] CancellationToken cancellationToken = default)
58+
[EnumeratorCancellation] CancellationToken cancellationToken = default
59+
)
5860
{
5961
{{~ for $j in 1..$i ~}}
6062
await using var e{{ $j }} = {{ $ordinals[$j] }}.ConfigureAwait(false).WithCancellation(cancellationToken).GetAsyncEnumerator();
@@ -68,7 +70,7 @@ public static partial class AsyncSuperEnumerable
6870
? e{{ $j }}.Current : default(T{{ $j }});
6971
{{~ end ~}}
7072

71-
if (!f1 {{ for $j in 2..$i }}&& !f{{ $j }}{{ end }})
73+
if (!f1{{ for $j in 2..$i }} && !f{{ $j }}{{ end }})
7274
yield break;
7375

7476
yield return resultSelector(
@@ -86,23 +88,24 @@ public static partial class AsyncSuperEnumerable
8688
/// will always be as long as the longest of input sequences where the
8789
/// default value of each of the shorter sequence element types is used
8890
/// for padding.
89-
/// </summary>
90-
/// <returns>A sequence of
91+
/// </summary>
92+
/// <returns>A sequence of
9193
/// <see cref="global::System.ValueTuple{ {{~ for $j in 1..$i ~}}T{{$j}}{{ if !for.last }},{{ end }}{{ end }} }" />
92-
/// containing corresponding elements from each of the sequences.</returns>
93-
/// <remarks>
94-
/// This method uses deferred execution and streams its results.
95-
/// </remarks>
96-
/// <exception cref="global::System.ArgumentNullException">Any of the input sequences is null.</exception>
94+
/// containing corresponding elements from each of the sequences.</returns>
95+
/// <remarks>
96+
/// This method uses deferred execution and streams its results.
97+
/// </remarks>
98+
/// <exception cref="global::System.ArgumentNullException">Any of the input sequences is null.</exception>
9799
{{~ for $j in 1..$i ~}}
98-
/// <typeparam name="T{{ $j }}">The type of the elements of <paramref name="{{ $ordinals[$j] }}" />.</typeparam>
100+
/// <typeparam name="T{{ $j }}">The type of the elements of <paramref name="{{ $ordinals[$j] }}" />.</typeparam>
99101
/// <param name="{{ $ordinals[$j] }}">The {{ $ordinals[$j] }} sequence of elements.</param>
100102
{{~ end ~}}
101-
public static global::System.Collections.Generic.IAsyncEnumerable<({{~ for $j in 1..$i ~}}T{{ $j }}?{{ if !for.last }},{{ end }}{{ end }})>
103+
public static global::System.Collections.Generic.IAsyncEnumerable<({{~ for $j in 1..$i ~}}T{{ $j }}?{{ if !for.last }},{{ end }}{{ end }})>
102104
ZipLongest<{{~ for $j in 1..$i ~}}T{{ $j }}{{ if !for.last }},{{ end }}{{ end }}>(this
103105
{{~ for $j in 1..$i ~}}
104106
global::System.Collections.Generic.IAsyncEnumerable<T{{ $j }}> {{ $ordinals[$j] }}{{ if !for.last }},{{ end }}
105-
{{~ end ~}}) =>
106-
ZipLongest({{~ for $j in 1..$i ~}}{{ $ordinals[$j] }}, {{ end }}global::System.ValueTuple.Create);
107-
{{ end ~}}
107+
{{~ end ~}}
108+
) => ZipLongest({{~ for $j in 1..$i ~}}{{ $ordinals[$j] }}, {{ end }}global::System.ValueTuple.Create);
109+
110+
{{~ end ~}}
108111
}

0 commit comments

Comments
 (0)