Vixen
dd8b0a81
csharp
public sealed class ComponentParameterAnalyzer

Says which of a component's public properties can follow the value bound to them.

No guide page documents this yet — the page shows what the code says about itself.

Remarks

A component's public settable properties are its parameter surface — <Panel Model="@Model" /> assigns one — and whether a parameter tracks its source is decided entirely by how the property is declared. An effect subscribes to what it reads; a plain auto-property is not something to subscribe to, so a binding assigns it, the child reads it once while building, and every later change to the caller's expression reaches nothing.

⚠ This is what is left of the defect after the ordering half was fixed. The markup emitter now writes Create … assignments … Compose, so the value a child is built with is the caller's rather than the property's default. That was the loud half. What it cannot fix is tracking, because signal-backing is what makes a property something an effect can subscribe to and no arrangement of statements substitutes for it.

⚠ It cannot be a VXML2xxx, and the issue that proposed one called that the cheaper option. VxmlGenerator never takes a Compilation — deliberately, so that editing a C# file re-runs no markup — and Binder is pure syntax, so "is this property signal-backed" is a question the markup compiler cannot ask at all. It has to be a separate analyzer over the C#, which is this.

⚠ Reported as a suggestion rather than a warning, and the reason is a rule of this repository rather than a doubt about the diagnostic. TreatWarningsAsErrors is a stated non-negotiable, so a warning that fires anywhere in the tree is a broken build — and a plain parameter is sometimes right: a label a caller sets once and never changes does not need a signal and would be paying for one. Promoting this to a warning is a decision to take after the tree has been swept with it, not before.

⚠ A full Compile does not sweep it, and expecting one to is the trap. Analyzers do not flow transitively through a ProjectReference — Vixen.Ui.csproj says so three lines above the reference that loads this — so the rule runs only where a project names Vixen.Ui.Generators itself or sets <VixenUi>true</VixenUi>. Six .vxml-owning projects in this repository name only Vixen.Ui.Markup.Generators, which is what compiles the markup, and therefore never see this at all. A consumer outside the repository has no such gap: a PackageReference to Vixen.Ui carries both.

⚠ And while it is Info it prints nothing at any MSBuild verbosity, so a sweep that greps a build log for the id reads zero whether or not there is anything to find. Promote it in .editorconfig for the run — TreatWarningsAsErrors then turns every hit into a build error that cannot be missed — and put the severity back afterwards.

⚠ A parameter declared in a .vxml's @code block is reached through the #line, and that is the only reason generated code is analyzed at all. The block is copied into a file whose first line is // <auto-generated />, so under None the declaration was neither analyzed nor reported — and that is where every markup component in this repository puts its parameters, Samples/02-HelloUi/Panels/Inspector.vxml's Model included. The objection to reporting in generated code is that it points at code the author cannot edit; ComponentEmitter writes each block under a #line span, which answers exactly that objection, so Reported reports against the .vxml when a mapping exists. Where none does, the location stays inside the generated tree and Roslyn drops it, because ReportDiagnostics is deliberately not set.

⚠ Reactive is a question about the accessors and not only about the type, and asking only the narrow half made the rule fire on the shape its own message asks for. public ShellModel Model { get => model.Value; set => model.Value = value; } over a readonly Signal<ShellModel> is precisely "back it with a Signal<T>", and it does track — an effect reading it reads model.Value and subscribes — yet IsReactive tests the property's type, which is ShellModel. The operation-block half of Inspect is the other: a getter that reads anything reactive is subscribable whatever the property's own type says, and an auto-property — the case the rule exists for — has no operation block to look at.

What is deliberately not reported. A read-only or computed property is not a parameter — a caller cannot assign it — and neither is a delegate: a callback parameter is invoked rather than read, so nothing about it needs to be subscribable. A property whose type is already reactive is the shape this rule is asking for.

Fields and properties (2)

  • public const string PlainParameterId

    The id reported for a component parameter that cannot follow its source.

  • public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics

    Returns a set of descriptors for the diagnostics that this analyzer is capable of producing.

Methods (1)

  • public override void Initialize(AnalysisContext context)

    Called once at session start to register actions in the analysis context.

Used by (1)

  • ComponentParameterTestsVixen.Ui.Generators.Tests