feat(binding): BindTo generator + analyzer, dependency updates, Sonar/CodeQL CI#32
Merged
Conversation
Update dependencies (verified against nuget.org, stable channel): - Microsoft.CodeAnalysis.Analyzers 3.11.0 -> 5.3.0 (build-time authoring rules only; no end-user Roslyn impact) - TUnit 1.19.22 -> 1.45.29, Verify.TUnit 31.13.2 -> 31.17.0 - Basic.Reference.Assemblies.* 1.8.4 -> 1.8.8 - Splat 19.3.1 -> 19.4.0 Deliberately kept Microsoft.CodeAnalysis.CSharp(.Workspaces) at 4.14.0 to match Visual Studio 2022's bundled Roslyn (our baseline); comment clarifies that Analyzers tracks latest independently. Supporting changes surfaced by the updates: - Enable TUnitImplicitUsings / TUnitAssertionsImplicitUsings, required by TUnit 1.45's implicit-usings gating. - Drop EOL net9.0-android target (now net10.0-android only). - Add TransitiveAssemblyResolver test helper: Splat 19.4.0 split into sub-packages and reset its assembly version to 19.0.0.0, which the pinned ReactiveUI 23.2.27 (built against Splat.Logging 19.3.0.0) cannot bind to. The resolver satisfies version-mismatched transitive references by simple name, keeping the test suite resilient to package version drift instead of pinning Splat back. Build clean under -warnaserror; all 7521 tests pass.
Implement a BindTo pipeline reaching parity with ReactiveUI 23.2.27's BindTo (apply an observable stream to a target property). All four RxUI overloads are exposed on IObservable<TValue>: basic, +conversionHint, +IBindingTypeConverter, and both. Generator (mirrors the BindOneWay pipeline): - BindToInvocationInfo model (target path only; source value type comes from the IObservable<T> receiver) - RoslynHelpers.IsBindToInvocation predicate + Constants.BindToMethodName - BindToExtractor extracts the target property chain and overload shape - BindToCodeGenerator emits the concrete typed overload + __BindTo_<hash> worker; wired into BindingGenerator Conversion semantics: - same value/property type, no converter -> direct assignment - differing types / hint / explicit converter -> new public RuntimeBindingConverter resolves via BindingConverters.Current or the supplied IBindingTypeConverter, skipping assignment when no converter applies (matches ReactiveUI) Analyzer: BindTo is recognised by the existing containing-class check, so the generic lambda diagnostics (RXUIBIND001/003/006) already apply. Added tests to lock this in and clarified the analyzer summary. Tests: 5 generator snapshot tests (4 overload variants at C#10 plus the CallerFilePath fallback at C#7.3), 2 runtime execution tests, and 4 analyzer diagnostic tests.
Add two workflows using the shared reactiveui/actions-common reusable workflows, mirroring the ReactiveUI.Extensions setup: - sonarcloud.yml -> workflow-common-sonarcloud.yml, project key reactiveui_ReactiveUI.Binding.SourceGenerators (org reactiveui), with test/benchmark/TestModels exclusions and a 15m test timeout for the Windows net10 MTP/TUnit coverage run. - codeql.yml -> workflow-common-codeql.yml analysing C# and Actions. Requires the org-level SONAR_TOKEN secret (already shared across reactiveui).
|
You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool. What Enabling Code Scanning Means:
For more information about GitHub Code Scanning, check out the documentation. |
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #32 +/- ##
===========================================
- Coverage 100.00% 95.69% -4.31%
===========================================
Files 126 138 +12
Lines 2119 2440 +321
Branches 395 374 -21
===========================================
+ Hits 2119 2335 +216
- Misses 0 91 +91
- Partials 0 14 +14 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
…en test suite Generated output: - Emit Expression<Func<VM, T?>> selector params for reference-type property-path leaves on Bind, BindCommand, BindTo, WhenAnyObservable, BindOneWay, BindTwoWay and OneWayBind under C# 8+, so binding over nullable properties no longer surfaces CS8603/CS8619 in consumer code. - Emit #nullable enable in generated files on C# 8+ targets. - Gate the // <auto-generated/> + #pragma warning disable header behind the new ReactiveUIBindingEmitGeneratedCodeMarkers MSBuild property (default on; set false to surface analyzer diagnostics in generated code), shipped via build/buildTransitive props and read through AnalyzerConfigOptions on the LanguageFeatures snapshot. Tests and tooling: - Fix SharedSourceReader to merge file-scoped-namespace scenario files correctly. - Correct stale runtime tests: non-constant indexer rewriter (parameterised so the index is not const-folded), InvalidOperationException on broken property chains, and the skipInitial initial-value emission count. - Regenerate generator snapshots. Full suite green: 7,047 tests (generator 1887, analyzer 438, runtime 4722) across net8/9/10.
The CallerFilePath/CallerLineNumber fallback tests compiled shared scenario source under C# 7.3, but the scenario view models use nullable reference type annotations (C# 8) and target-typed new() (C# 9), which raised "feature is not available in C# 7.3" diagnostics and failed CI. - Add TestHelper.FallbackLanguageVersion(bool nullableEnabled): C# 8 for nullable scenarios (still below C# 10 so CallerArgumentExpression does not take over and the file/line dispatch path is exercised), C# 7.3 otherwise. Switch the fallback tests to it. - Replace all target-typed new() in shared scenarios with explicit type names (= new T(), new PropertyChang(ed|ing)EventArgs(nameof(...))), so scenario source no longer depends on C# 9. - Regenerate the affected fallback snapshots (now nullable-enabled output). Full suite green: generator 1887, analyzer 438, runtime 4722; solution builds 0/0.
…tor nullability BindCommand runtime tests threw "No generated binding found": the call resolved to the generic runtime fallback stub instead of the generated concrete overload. Two regressions caused it: - The fallback stubs had their optional `toEvent = null` default removed and bare 4-parameter overloads added (to silence S2360). A bare stub that fills every parameter beats the generated overload (which defaults its caller-info optionals), so it always shadowed the generated code. Reverted to optional `toEvent` + no bare overloads, and suppressed S2360 on ReactiveUIBindingExtensions per the pre-approved CallerInfo-dispatch policy. - The generated control selector was emitted nullable (Expression<Func<TView, TControl?>>) while the stub uses non-null TControl; the command/withParameter selectors must stay nullable to match the stub (TProp?/TParam?). Control is now non-null; the expression withParameter is nullable. Also set ParameterIsReferenceType on the expression-parameter extraction path (CommandExtractor) so the generated withParameter expression is annotated nullable, fixing CS8603 over nullable command-parameter properties. Regenerated BindCommand snapshots. Full suite green: generator 1887, analyzer 438, GeneratedCode 528, runtime 4722; solution builds 0 errors / 0 warnings.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


What kind of change does this PR introduce?
Feature, dependency update, and CI.
What is the new behavior?
BindTo(all four overloads).CodeAnalysis.Analyzers,TUnit,Verify.TUnit,Basic.Reference.Assemblies,Splat); Roslyn held at the VS 2022 baseline.What is the current behavior?
No
BindTo; older package versions; no SonarCloud/CodeQL.What might this PR break?
None.
BindTois additive and Roslyn stays pinned at the VS 2022 baseline.Checklist
mainbranch