codex/assignbinding-bindinglocal-datatype
9073e0c92Support binding-local DataType on assignable bindings38855852bUse binding-local DataType in language servicefb23e1e84Handle x:Type DataType in object-node bindings
AXSG handled Avalonia compiled bindings correctly for the common control/property cases, but it still missed an important Avalonia-specific pattern:
- a CLR property marked with
AssignBindingAttribute - whose type accepts an assigned binding object such as
BindingBase - receiving a compiled binding that provides its own
DataType
In that shape, AXSG could incorrectly fall back to the parent ambient x:DataType and report semantic diagnostics such as AXSG0110 or AXSG0111 against the wrong source type. The same gap also affected editor features, because completion and navigation were using the ambient data type instead of the binding-local one.
There was a second gap in the object-node parser:
- object-node bindings could preserve
DataTypewhen written as an attribute - but they did not fully handle property-element forms that used
<x:Type .../>
That meant verbose compiled-binding forms like:
<CompiledBinding>
<CompiledBinding.Path>Rows</CompiledBinding.Path>
<CompiledBinding.DataType>
<x:Type TypeName="vm:MainVm" />
</CompiledBinding.DataType>
</CompiledBinding>could still lose the intended source type during semantic analysis.
The change teaches AXSG to treat binding-local DataType as the authoritative source type whenever Avalonia markup semantics indicate the binding object itself is being assigned, rather than applied through an ambient binding target.
The implementation has three parts:
- Preserve
DataTypein parsed binding models and use it during semantic binding. - Mirror the same source-type resolution in the language service.
- Extend object-node parsing so
CompiledBinding.DataTypealso works when written as a property element containingx:Type.
Files:
src/XamlToCSharpGenerator.Core/Models/BindingEventMarkupModels.cssrc/XamlToCSharpGenerator.Core/Parsing/BindingEventMarkupParser.cssrc/XamlToCSharpGenerator.Avalonia/Binding/AvaloniaSemanticBinder.BindingSemantics.cssrc/XamlToCSharpGenerator.Avalonia/Binding/AvaloniaSemanticBinder.StylesTemplates.cssrc/XamlToCSharpGenerator.Avalonia/Binding/AvaloniaSemanticBinder.ObjectNodeBinding.cs
Key changes:
- Added
DataTypetoBindingMarkupso the parsed binding model no longer drops binding-local type information. - Updated
BindingEventMarkupParserto parse, normalize, and preserveDataTypethrough all binding rewrites. - Updated semantic source-type resolution to prefer
bindingMarkup.DataTypebefore falling back to ambientx:DataType. - Added
ResolveBindingMarkupDataType(...)to centralize type resolution from binding-local type expressions. - Extended emitted binding initializers to include
DataTypewhen the target binding type exposes that property. - Expanded assign-binding property detection so CLR properties typed as
BindingBase,IBinding, orIBinding2are all treated as valid binding-holder targets. - Added the canonical object-node argument mapping for
DataType, allowing object-node compiled bindings to feed the same binding model. - Updated internal
BindingMarkupconstruction sites to pass the newdataTypeargument explicitly.
Behavioral effect:
- AXSG now resolves
{CompiledBinding Name, DataType={x:Type vm:RowVm}}againstRowVmeven when the surrounding element has a different ambientx:DataType. - This now works for assign-binding CLR properties, not just standard Avalonia property-binding paths.
Files:
src/XamlToCSharpGenerator.LanguageService/Completion/XamlSemanticSourceTypeResolver.cssrc/XamlToCSharpGenerator.LanguageService/Definitions/XamlBindingNavigationService.cs
Key changes:
- Added binding-local
DataTyperesolution to completion source-type inference. - Added the same logic to definition/navigation lookup.
- Reused element-local prefix map resolution so
vm:Fooand similar type expressions resolve the same way as they do in generator analysis.
Behavioral effect:
- completion inside binding paths prefers the binding-local source type
- go-to-definition / navigation resolves binding members against the correct type
- editor behavior now matches generator/runtime semantics for this Avalonia pattern
Files:
src/XamlToCSharpGenerator.Avalonia/Binding/AvaloniaSemanticBinder.ObjectNodeBinding.cstests/XamlToCSharpGenerator.Tests/Generator/AvaloniaXamlSourceGeneratorTests.cs
Key changes:
- Extended
TryGetSingleBindingObjectNodeArgumentValue(...)so it can extract values from anx:Typeobject node, not only raw text or markup-extension argument forms. - Added
TryExtractTypeExpressionFromXamlTypeNode(...)to support:TypeName="vm:MainVm"Type="vm:MainVm"- property-element forms
- constructor/text-content fallback
- generic type argument reconstruction when the
x:Typenode carries type arguments
Behavioral effect:
- object-node compiled bindings now keep
DataTypewhen it is expressed via property-elementx:Type - inherited data-type flows such as
ItemsSourcetoItemTemplatenow work for this verbose binding form as well
File:
tests/XamlToCSharpGenerator.Tests/Generator/AvaloniaXamlSourceGeneratorTests.cs
Added coverage for:
- assign-binding CLR properties typed as
BindingBasewith binding-localDataType - both attribute and object-node compiled-binding forms for assign-binding CLR properties
- object-element
ItemsSourcecompiled binding withCompiledBinding.DataTypeexpressed as property-element<x:Type .../>
The tests assert:
- no
AXSG0110/AXSG0111diagnostics are produced - the generated descriptors use the expected source type
- the generated code still emits assign-binding object assignments
File:
tests/XamlToCSharpGenerator.Tests/LanguageService/XamlLanguageServiceEngineTests.cs
Added coverage for:
- completion preferring binding-local
DataTypeover ambientx:DataType
The test asserts that:
- members from the local binding type are offered
- unrelated members from the ambient type are not offered
Executed on the feature branch:
dotnet test tests/XamlToCSharpGenerator.Tests/XamlToCSharpGenerator.Tests.csproj --filter "FullyQualifiedName~Uses_BindingLocal_DataType_For_AssignBinding_Clr_Property_CompiledBindings|FullyQualifiedName~Infers_ItemTemplate_DataType_From_ObjectElement_ItemsSource_Binding_PropertyElement_DataType_XamlType|FullyQualifiedName~Completion_InBindingPathContext_Prefers_BindingLocal_DataType" -v minimalResult:
- Passed:
3 - Failed:
0 - Skipped:
0
Notes:
- The test run still surfaces existing nullable warnings from unrelated sample and Avalonia binder code paths.
- No new failing diagnostics or regressions were observed in the focused slice relevant to this change.
Suggested review order:
BindingEventMarkupModels.csBindingEventMarkupParser.csAvaloniaSemanticBinder.BindingSemantics.csXamlSemanticSourceTypeResolver.csXamlBindingNavigationService.csAvaloniaSemanticBinder.ObjectNodeBinding.cs- new regression tests
Key things to verify:
- binding-local
DataTypewins over ambientx:DataTypeonly when it is explicitly present - assign-binding CLR properties typed as
BindingBaseare treated as valid binding-holder properties - object-node
CompiledBinding.DataTypehandles both attribute and property-elementx:Typeforms - language-service source-type inference matches generator behavior
After this change, Avalonia authors using:
AssignBindingAttributeBindingBase-typed CLR properties- compiled bindings with local
DataType
should get correct AXSG generation, completion, and navigation results without false ambient-type diagnostics. This brings AXSG closer to actual Avalonia binding semantics for assigned binding objects rather than applied bindings.