Skip to content

Refactor code structure for improved readability and maintainability#14

Merged
koenbeuk merged 2 commits intomainfrom
feat/generator-cleanup
Mar 30, 2026
Merged

Refactor code structure for improved readability and maintainability#14
koenbeuk merged 2 commits intomainfrom
feat/generator-cleanup

Conversation

@koenbeuk
Copy link
Copy Markdown
Collaborator

  • Removed dead code
  • Simplified emitter by finding ways to reuse/unify emitters

Copilot AI review requested due to automatic review settings March 30, 2026 00:10
Comment on lines +859 to +862
if (isElementSelector)
delegateFqn2 = $"global::System.Func<{elemRef}, {thirdRef}>";
else
delegateFqn2 = $"global::System.Func<{keyRef}, global::System.Collections.Generic.IEnumerable<{elemRef}>, {thirdRef}>";
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Refactors the Polyfill interceptor source generator and expression-tree emitter plumbing to remove unused static-field emission paths and unify several emitter implementations, especially around anonymous-type handling.

Changes:

  • Removed EmitResult.StaticFields and related “static field declarations” emission from the generator pipeline.
  • Simplified ReflectionFieldCache / ExpressionTreeEmitter construction and removed reflection-expression caching logic.
  • Unified several per-operator emitters (e.g., Select/indexed Select) and consolidated anonymous-type alias handling helpers.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
src/ExpressiveSharp.Generator/PolyfillInterceptorGenerator.cs Refactors interceptor emission, unifies emitters, and changes anonymous-type alias handling + lambda emission plumbing.
src/ExpressiveSharp.Generator/Emitter/ReflectionFieldCache.cs Simplifies cache to always emit inline reflection expressions; removes internal caching/declarations API.
src/ExpressiveSharp.Generator/Emitter/ExpressionTreeEmitter.cs Updates emitter to the new ReflectionFieldCache / EmitResult APIs.
src/ExpressiveSharp.Generator/Emitter/EmitResult.cs Removes StaticFields from the emit result model.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +1210 to +1218
// Build generic Func<> — map each func type arg to T0, T1, etc.
var funcArgStrings = new string[funcTypeArgs.Length];
for (int i = 0; i < funcTypeArgs.Length; i++)
funcArgStrings[i] = $"T{i}";
var funcFqnGeneric = "global::System.Func<" + string.Join(", ", funcArgStrings) + ">";

delegateFqn = "global::System.Func<" +
string.Join(", ", funcTypeArgs.Select((t, i) =>
IsAnonymousType(t) ? funcArgStrings[i] : t.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat))) + ">";
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In EmitGenericSingleLambda's hasAnyAnon branch, funcFqnGeneric is built as Func<T0, T1, ...> based on the delegate arity, but typeParams only declares T0..T{method.TypeArguments.Length-1}. For common operators like Count/Any/TakeWhile (method type args = 1, Func args = 2), this yields emitted interceptor signatures like __Polyfill_Count_0<T0>(..., Func<T0, T1> _), which won’t compile (undeclared T1) and also doesn’t match the call-site delegate type (should be Func<T0, bool>). Consider building the interceptor parameter type from the actual funcTypeArgs (substituting aliases for anonymous types) — e.g., reuse delegateFqn for the placeholder parameter — instead of synthesizing T{i} for each Func type argument.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark 'ExpressiveSharp Benchmarks'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.20.

Benchmark suite Current: 0d1b29a Previous: dc0d77d Ratio
ExpressiveSharp.Benchmarks.EFCoreQueryOverheadBenchmarks.WithExpressives_Method 28162.139526367188 ns (± 9314.371390135553) 21135.239705403645 ns (± 5378.281048071639) 1.33
ExpressiveSharp.Benchmarks.GeneratorBenchmarks.RunGenerator_ExpressiveChange(ExpressiveCount: 100) 124966579.33333333 ns (± 3421441.1373593393) 90394538.5 ns (± 22293193.035217773) 1.38

This comment was automatically generated by workflow using github-action-benchmark.

Resolve conflicts in ReflectionFieldCache.cs and
PolyfillInterceptorGenerator.cs — both branches independently
made the same functional changes (removed obsolete cache,
renamed fieldPrefix to varPrefix), so the PR's refactored
structure is preserved with main's changes incorporated.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@koenbeuk koenbeuk merged commit afcbb05 into main Mar 30, 2026
7 checks passed
@koenbeuk koenbeuk deleted the feat/generator-cleanup branch March 30, 2026 01:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants