feat(binding): execute a command with each value a stream produces - #92
Merged
Conversation
- InvokeCommand joins the generated APIs. The overload naming a command property observes that path with the mechanism the generator picked for the declaring type, and offers every value the stream produces to whichever command the path currently holds - a chain is followed, so replacing a parent retargets the execution. - The overload taking the command itself has nothing to resolve and nothing to observe, so the runtime library serves it outright and no dispatch is emitted. - CanExecute is asked per emission rather than tracked from CanExecuteChanged: the value being offered is the command parameter, so only the command can answer for that value. A refused value is dropped, a null command drops the values offered while it stands, and replacing the command executes nothing by itself. - Both paths hand the resolved command to CommandInvoker, so a generated call site emits one call and the runtime engine's path cannot drift from it. - A call site the generator cannot claim reads the property through the runtime expression engine, which is what the stub's trimming annotation says. - RXUIBIND002 reads the type argument naming the observed object, which for this API is the second: the first is the value type of a stream the caller already built. RXUIBIND011 covers the API as well, so a call answered by ReactiveUI's own mixin is reported. - The overloads naming ReactiveCommandBase are not offered: naming that type would put a ReactiveUI reference in this package. A ReactiveCommand is reached through the ICommand overloads, with the parameter arriving as object.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #92 +/- ##
==========================================
+ Coverage 99.48% 99.49% +0.01%
==========================================
Files 251 258 +7
Lines 10652 10888 +236
Branches 1181 1209 +28
==========================================
+ Hits 10597 10833 +236
Misses 42 42
Partials 13 13 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
… it surfaces - A call the model could not resolve, a target held in a type parameter, and a selector whose body is no property path each reach a guard that had no test. - A fault in the values is surfaced while a command is being observed, which is a different observer from the one a fixed command uses.
|
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.
What is the new behavior?
InvokeCommandexecutes a command with each value an observable produces, resolved at compile time.CanExecuteis asked per emission rather than tracked fromCanExecuteChanged: the value being offered is the command parameter, so only the command can answer for that value.RXUIBIND002names the type holding the command rather than the value type of the stream, andRXUIBIND011reports anInvokeCommandthat ReactiveUI's own mixin answered.What is the current behavior?
The package has no
InvokeCommand. A consumer reaches ReactiveUI's mixin for it, which resolves the command property through the runtime expression engine - reflection on a path the compiler already knows.What might this PR break?
None.
ReactiveCommandBaseare not offered, because naming that type would put a ReactiveUI reference in this package. AReactiveCommandis reached through theICommandoverloads, with the parameter arriving asobjectrather than the command's declared input type.Checklist
mainbranchAdditional information
The gating and the executions live in one runtime type that both the generated call site and the expression engine hand their command to, so the two paths cannot drift. The AOT validation harness gains an
InvokeCommandscenario, and the shared-scenario sweep carries the new scenarios onto the System.Reactive package.