Skip to content

Commit ace68aa

Browse files
committed
supported AggregateBy and redid most of the generator
1 parent 277f236 commit ace68aa

21 files changed

Lines changed: 511 additions & 1012 deletions

File tree

src/ExpressiveSharp.Generator/PolyfillInterceptorGenerator.cs

Lines changed: 156 additions & 826 deletions
Large diffs are not rendered by default.

src/ExpressiveSharp/Extensions/RewritableQueryableLinqExtensions.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,14 @@ public static IRewritableQueryable<KeyValuePair<TKey, TAccumulate>> AggregateBy<
505505
TAccumulate seed,
506506
Func<TAccumulate, T, TAccumulate> func)
507507
=> throw new UnreachableException(InterceptedMessage);
508+
509+
[EditorBrowsable(EditorBrowsableState.Never)]
510+
public static IRewritableQueryable<KeyValuePair<TKey, TAccumulate>> AggregateBy<T, TKey, TAccumulate>(
511+
this IRewritableQueryable<T> source,
512+
Func<T, TKey> keySelector,
513+
Func<TKey, TAccumulate> seedSelector,
514+
Func<TAccumulate, T, TAccumulate> func)
515+
=> throw new UnreachableException(InterceptedMessage);
508516
#endif
509517

510518
// ── IEqualityComparer / IComparer overloads (intercepted) ────────────
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// <auto-generated/>
2+
#nullable disable
3+
4+
namespace ExpressiveSharp.Generated.Interceptors
5+
{
6+
internal static class PolyfillInterceptors
7+
{
8+
[global::System.Runtime.CompilerServices.InterceptsLocationAttribute(/* scrubbed */)]
9+
internal static global::ExpressiveSharp.IRewritableQueryable<global::System.Collections.Generic.KeyValuePair<string, decimal>> __Polyfill_AggregateBy_0(
10+
this global::ExpressiveSharp.IRewritableQueryable<global::TestNs.Order> source,
11+
global::System.Func<global::TestNs.Order, string> _1,
12+
decimal seed,
13+
global::System.Func<decimal, global::TestNs.Order, decimal> _2)
14+
{
15+
// Source: o => o.Tag
16+
var i0a_p_o = global::System.Linq.Expressions.Expression.Parameter(typeof(global::TestNs.Order), "o");
17+
var i0a_expr_0 = global::System.Linq.Expressions.Expression.Property(i0a_p_o, typeof(global::TestNs.Order).GetProperty("Tag")); // o.Tag
18+
var __lambda1 = global::System.Linq.Expressions.Expression.Lambda<global::System.Func<global::TestNs.Order, string>>(i0a_expr_0, i0a_p_o);
19+
// Source: (acc, o) => acc + o.Price
20+
var i0b_p_acc = global::System.Linq.Expressions.Expression.Parameter(typeof(decimal), "acc");
21+
var i0b_p_o = global::System.Linq.Expressions.Expression.Parameter(typeof(global::TestNs.Order), "o");
22+
var i0b_expr_1 = global::System.Linq.Expressions.Expression.Property(i0b_p_o, typeof(global::TestNs.Order).GetProperty("Price")); // o.Price
23+
var i0b_expr_0 = global::System.Linq.Expressions.Expression.MakeBinary(global::System.Linq.Expressions.ExpressionType.Add, i0b_p_acc, i0b_expr_1);
24+
var __lambda2 = global::System.Linq.Expressions.Expression.Lambda<global::System.Func<decimal, global::TestNs.Order, decimal>>(i0b_expr_0, i0b_p_acc, i0b_p_o);
25+
return global::ExpressiveSharp.Extensions.ExpressionRewriteExtensions.WithExpressionRewrite(
26+
global::System.Linq.Queryable.AggregateBy(
27+
(global::System.Linq.IQueryable<global::TestNs.Order>)source,
28+
__lambda1,
29+
seed,
30+
__lambda2));
31+
}
32+
}
33+
}
34+
35+
namespace System.Runtime.CompilerServices
36+
{
37+
[global::System.AttributeUsage(global::System.AttributeTargets.Method, AllowMultiple = true)]
38+
file sealed class InterceptsLocationAttribute : global::System.Attribute
39+
{
40+
public InterceptsLocationAttribute(int version, string data) { }
41+
}
42+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// <auto-generated/>
2+
#nullable disable
3+
4+
namespace ExpressiveSharp.Generated.Interceptors
5+
{
6+
internal static class PolyfillInterceptors
7+
{
8+
[global::System.Runtime.CompilerServices.InterceptsLocationAttribute(/* scrubbed */)]
9+
internal static global::ExpressiveSharp.IRewritableQueryable<global::System.Collections.Generic.KeyValuePair<string, decimal>> __Polyfill_AggregateBy_0(
10+
this global::ExpressiveSharp.IRewritableQueryable<global::TestNs.Order> source,
11+
global::System.Func<global::TestNs.Order, string> _1,
12+
global::System.Func<string, decimal> _2,
13+
global::System.Func<decimal, global::TestNs.Order, decimal> _3)
14+
{
15+
// Source: o => o.Tag
16+
var i0a_p_o = global::System.Linq.Expressions.Expression.Parameter(typeof(global::TestNs.Order), "o");
17+
var i0a_expr_0 = global::System.Linq.Expressions.Expression.Property(i0a_p_o, typeof(global::TestNs.Order).GetProperty("Tag")); // o.Tag
18+
var __lambda1 = global::System.Linq.Expressions.Expression.Lambda<global::System.Func<global::TestNs.Order, string>>(i0a_expr_0, i0a_p_o);
19+
// Source: k => 0m
20+
var i0b_p_k = global::System.Linq.Expressions.Expression.Parameter(typeof(string), "k");
21+
var i0b_expr_0 = global::System.Linq.Expressions.Expression.Constant(0m, typeof(decimal)); // 0m
22+
var __lambda2 = global::System.Linq.Expressions.Expression.Lambda<global::System.Func<string, decimal>>(i0b_expr_0, i0b_p_k);
23+
// Source: (acc, o) => acc + o.Price
24+
var i0c_p_acc = global::System.Linq.Expressions.Expression.Parameter(typeof(decimal), "acc");
25+
var i0c_p_o = global::System.Linq.Expressions.Expression.Parameter(typeof(global::TestNs.Order), "o");
26+
var i0c_expr_1 = global::System.Linq.Expressions.Expression.Property(i0c_p_o, typeof(global::TestNs.Order).GetProperty("Price")); // o.Price
27+
var i0c_expr_0 = global::System.Linq.Expressions.Expression.MakeBinary(global::System.Linq.Expressions.ExpressionType.Add, i0c_p_acc, i0c_expr_1);
28+
var __lambda3 = global::System.Linq.Expressions.Expression.Lambda<global::System.Func<decimal, global::TestNs.Order, decimal>>(i0c_expr_0, i0c_p_acc, i0c_p_o);
29+
return global::ExpressiveSharp.Extensions.ExpressionRewriteExtensions.WithExpressionRewrite(
30+
global::System.Linq.Queryable.AggregateBy(
31+
(global::System.Linq.IQueryable<global::TestNs.Order>)source,
32+
__lambda1,
33+
__lambda2,
34+
__lambda3));
35+
}
36+
}
37+
}
38+
39+
namespace System.Runtime.CompilerServices
40+
{
41+
[global::System.AttributeUsage(global::System.AttributeTargets.Method, AllowMultiple = true)]
42+
file sealed class InterceptsLocationAttribute : global::System.Attribute
43+
{
44+
public InterceptsLocationAttribute(int version, string data) { }
45+
}
46+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#if NET9_0_OR_GREATER
2+
using Microsoft.VisualStudio.TestTools.UnitTesting;
3+
using VerifyMSTest;
4+
using ExpressiveSharp.Generator.Tests.Infrastructure;
5+
6+
namespace ExpressiveSharp.Generator.Tests.PolyfillInterceptorGenerator;
7+
8+
[TestClass]
9+
public class AggregateByTests : GeneratorTestBase
10+
{
11+
[TestMethod]
12+
public Task AggregateBy_GeneratesInterceptor()
13+
{
14+
var source =
15+
"""
16+
using ExpressiveSharp.Extensions;
17+
18+
namespace TestNs
19+
{
20+
class Order { public string Tag { get; set; } public decimal Price { get; set; } }
21+
class TestClass
22+
{
23+
public void Run(System.Linq.IQueryable<Order> query)
24+
{
25+
query.WithExpressionRewrite()
26+
.AggregateBy(
27+
o => o.Tag,
28+
0m,
29+
(acc, o) => acc + o.Price)
30+
.ToList();
31+
}
32+
}
33+
}
34+
""";
35+
var result = RunPolyfillInterceptorGenerator(CreateCompilation(source));
36+
37+
Assert.AreEqual(1, result.GeneratedTrees.Length);
38+
39+
return Verifier.Verify(result.GeneratedTrees[0].GetText().ToString());
40+
}
41+
42+
[TestMethod]
43+
public Task AggregateBy_WithSeedSelector_GeneratesInterceptor()
44+
{
45+
var source =
46+
"""
47+
using ExpressiveSharp.Extensions;
48+
49+
namespace TestNs
50+
{
51+
class Order { public string Tag { get; set; } public decimal Price { get; set; } }
52+
class TestClass
53+
{
54+
public void Run(System.Linq.IQueryable<Order> query)
55+
{
56+
query.WithExpressionRewrite()
57+
.AggregateBy(
58+
o => o.Tag,
59+
k => 0m,
60+
(acc, o) => acc + o.Price)
61+
.ToList();
62+
}
63+
}
64+
}
65+
""";
66+
var result = RunPolyfillInterceptorGenerator(CreateCompilation(source));
67+
68+
Assert.AreEqual(1, result.GeneratedTrees.Length);
69+
70+
return Verifier.Verify(result.GeneratedTrees[0].GetText().ToString());
71+
}
72+
}
73+
#endif

tests/ExpressiveSharp.Generator.Tests/PolyfillInterceptorGenerator/AnonymousElementTests.Count_AfterAnonymousSelect_GeneratesScalarInterceptor.verified.txt

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ namespace ExpressiveSharp.Generated.Interceptors
88
[global::System.Runtime.CompilerServices.InterceptsLocationAttribute(/* scrubbed */)]
99
internal static int __Polyfill_Count_0<T0>(
1010
this global::ExpressiveSharp.IRewritableQueryable<T0> source,
11-
global::System.Func<T0, T1> _)
11+
global::System.Func<T0, bool> _)
1212
{
1313
// Source: x => x.Total > 0m
1414
var i0_p_x = global::System.Linq.Expressions.Expression.Parameter(typeof(T0), "x");
@@ -21,21 +21,21 @@ namespace ExpressiveSharp.Generated.Interceptors
2121
__lambda);
2222
}
2323
[global::System.Runtime.CompilerServices.InterceptsLocationAttribute(/* scrubbed */)]
24-
internal static global::ExpressiveSharp.IRewritableQueryable<TResult> __Polyfill_Select_1<TElem, TResult>(
25-
this global::ExpressiveSharp.IRewritableQueryable<TElem> source,
26-
global::System.Func<TElem, TResult> _)
24+
internal static global::ExpressiveSharp.IRewritableQueryable<T1> __Polyfill_Select_1<T0, T1>(
25+
this global::ExpressiveSharp.IRewritableQueryable<T0> source,
26+
global::System.Func<T0, T1> _)
2727
{
2828
// Source: o => new { o.Id, o.Total }
29-
var i1_p_o = global::System.Linq.Expressions.Expression.Parameter(typeof(global::TestNs.Order), "o");
30-
var i1_expr_1 = global::System.Linq.Expressions.Expression.Property(i1_p_o, typeof(global::TestNs.Order).GetProperty("Id")); // o.Id
31-
var i1_expr_2 = global::System.Linq.Expressions.Expression.Property(i1_p_o, typeof(global::TestNs.Order).GetProperty("Total")); // o.Total
32-
var i1_expr_3 = typeof(TResult).GetConstructors()[0];
33-
var i1_expr_0 = global::System.Linq.Expressions.Expression.New(i1_expr_3, new global::System.Linq.Expressions.Expression[] { i1_expr_1, i1_expr_2 }, new global::System.Reflection.MemberInfo[] { typeof(TResult).GetProperty("Id"), typeof(TResult).GetProperty("Total") });
34-
var __lambda = global::System.Linq.Expressions.Expression.Lambda<global::System.Func<global::TestNs.Order, TResult>>(i1_expr_0, i1_p_o);
35-
return (global::ExpressiveSharp.IRewritableQueryable<TResult>)(object)
29+
var i1_p_o = global::System.Linq.Expressions.Expression.Parameter(typeof(T0), "o");
30+
var i1_expr_1 = global::System.Linq.Expressions.Expression.Property(i1_p_o, typeof(T0).GetProperty("Id")); // o.Id
31+
var i1_expr_2 = global::System.Linq.Expressions.Expression.Property(i1_p_o, typeof(T0).GetProperty("Total")); // o.Total
32+
var i1_expr_3 = typeof(T1).GetConstructors()[0];
33+
var i1_expr_0 = global::System.Linq.Expressions.Expression.New(i1_expr_3, new global::System.Linq.Expressions.Expression[] { i1_expr_1, i1_expr_2 }, new global::System.Reflection.MemberInfo[] { typeof(T1).GetProperty("Id"), typeof(T1).GetProperty("Total") });
34+
var __lambda = global::System.Linq.Expressions.Expression.Lambda<global::System.Func<T0, T1>>(i1_expr_0, i1_p_o);
35+
return (global::ExpressiveSharp.IRewritableQueryable<T1>)(object)
3636
global::ExpressiveSharp.Extensions.ExpressionRewriteExtensions.WithExpressionRewrite(
3737
global::System.Linq.Queryable.Select(
38-
(global::System.Linq.IQueryable<global::TestNs.Order>)(object)source,
38+
(global::System.Linq.IQueryable<T0>)(object)source,
3939
__lambda));
4040
}
4141
}

tests/ExpressiveSharp.Generator.Tests/PolyfillInterceptorGenerator/AnonymousElementTests.DistinctBy_AfterAnonymousSelect_GeneratesInterceptor.verified.txt

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,29 +13,29 @@ namespace ExpressiveSharp.Generated.Interceptors
1313
// Source: x => x.Category
1414
var i0_p_x = global::System.Linq.Expressions.Expression.Parameter(typeof(T0), "x");
1515
var i0_expr_0 = global::System.Linq.Expressions.Expression.Property(i0_p_x, typeof(T0).GetProperty("Category")); // x.Category
16-
var __lambda = global::System.Linq.Expressions.Expression.Lambda<global::System.Func<T0, string>>(i0_expr_0, i0_p_x);
16+
var __lambda = global::System.Linq.Expressions.Expression.Lambda<global::System.Func<T0, T1>>(i0_expr_0, i0_p_x);
1717
return (global::ExpressiveSharp.IRewritableQueryable<T0>)(object)
1818
global::ExpressiveSharp.Extensions.ExpressionRewriteExtensions.WithExpressionRewrite(
1919
global::System.Linq.Queryable.DistinctBy(
2020
(global::System.Linq.IQueryable<T0>)(object)source,
2121
__lambda));
2222
}
2323
[global::System.Runtime.CompilerServices.InterceptsLocationAttribute(/* scrubbed */)]
24-
internal static global::ExpressiveSharp.IRewritableQueryable<TResult> __Polyfill_Select_1<TElem, TResult>(
25-
this global::ExpressiveSharp.IRewritableQueryable<TElem> source,
26-
global::System.Func<TElem, TResult> _)
24+
internal static global::ExpressiveSharp.IRewritableQueryable<T1> __Polyfill_Select_1<T0, T1>(
25+
this global::ExpressiveSharp.IRewritableQueryable<T0> source,
26+
global::System.Func<T0, T1> _)
2727
{
2828
// Source: o => new { o.Id, o.Category }
29-
var i1_p_o = global::System.Linq.Expressions.Expression.Parameter(typeof(global::TestNs.Order), "o");
30-
var i1_expr_1 = global::System.Linq.Expressions.Expression.Property(i1_p_o, typeof(global::TestNs.Order).GetProperty("Id")); // o.Id
31-
var i1_expr_2 = global::System.Linq.Expressions.Expression.Property(i1_p_o, typeof(global::TestNs.Order).GetProperty("Category")); // o.Category
32-
var i1_expr_3 = typeof(TResult).GetConstructors()[0];
33-
var i1_expr_0 = global::System.Linq.Expressions.Expression.New(i1_expr_3, new global::System.Linq.Expressions.Expression[] { i1_expr_1, i1_expr_2 }, new global::System.Reflection.MemberInfo[] { typeof(TResult).GetProperty("Id"), typeof(TResult).GetProperty("Category") });
34-
var __lambda = global::System.Linq.Expressions.Expression.Lambda<global::System.Func<global::TestNs.Order, TResult>>(i1_expr_0, i1_p_o);
35-
return (global::ExpressiveSharp.IRewritableQueryable<TResult>)(object)
29+
var i1_p_o = global::System.Linq.Expressions.Expression.Parameter(typeof(T0), "o");
30+
var i1_expr_1 = global::System.Linq.Expressions.Expression.Property(i1_p_o, typeof(T0).GetProperty("Id")); // o.Id
31+
var i1_expr_2 = global::System.Linq.Expressions.Expression.Property(i1_p_o, typeof(T0).GetProperty("Category")); // o.Category
32+
var i1_expr_3 = typeof(T1).GetConstructors()[0];
33+
var i1_expr_0 = global::System.Linq.Expressions.Expression.New(i1_expr_3, new global::System.Linq.Expressions.Expression[] { i1_expr_1, i1_expr_2 }, new global::System.Reflection.MemberInfo[] { typeof(T1).GetProperty("Id"), typeof(T1).GetProperty("Category") });
34+
var __lambda = global::System.Linq.Expressions.Expression.Lambda<global::System.Func<T0, T1>>(i1_expr_0, i1_p_o);
35+
return (global::ExpressiveSharp.IRewritableQueryable<T1>)(object)
3636
global::ExpressiveSharp.Extensions.ExpressionRewriteExtensions.WithExpressionRewrite(
3737
global::System.Linq.Queryable.Select(
38-
(global::System.Linq.IQueryable<global::TestNs.Order>)(object)source,
38+
(global::System.Linq.IQueryable<T0>)(object)source,
3939
__lambda));
4040
}
4141
}

0 commit comments

Comments
 (0)