From 3b1eb338e61c6ef8223a9f0d123d390289fa6e49 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Mon, 29 Jan 2024 09:08:26 +0100 Subject: [PATCH] Binding System refactor (#13970) * Update ncrunch config. * WIP: Benchmarks * Initial refactor of binding infrastructure. - `ExpressionObserver` has been removed and its functionality merged with `BindingExpression` - `BindingExpression` handles all types of `BindingMode` itself; doesn't require `BindingOperations.Apply` to set up a separate observable for `TwoWay/`OneWayToSource` bindings - This allows us to fix some long-standing issues with `OneWayToSource` bindings - Expression nodes have been refactored - No longer split between `Avalonia.Base` and `Avalonia.Markup` - Categorize them according to whether they use reflection or not A few tests are failing around binding warnings: this is because the next step here is to fix binding warnings. * Make default binding Source = UnsetProperty. Null is a theoretically valid value for `Source`; setting it to null shouldn't mean "use the data context". * Move logging to BindingExpression. As `BindingExpression` now has enough information to decide when it's appropriate to log an error/warning or not. Fixes #5762 Fixes #9422 * Add compatibility hack for older compiled bindings. Previously, `CompiledBindingPathBuilder` didn't have a `TemplatedParent` method and instead the XAML compiler rewrite templated parent bindings to be a `$self.TemplateParent` property binding. resulting in extraneous logs. Add a constructor with an `apiVersion` to `CompiledBindingPathBuilder` which will be used by newer versions of the XAML compiler, and if a usage is detected using an `apiVersion` of 0, then upgrade `$self.TemplatedParent` to use a `TemplatedParentPathElement`. * Log errors from property accessors. * Don't log errors for named control bindings... ...on elements which aren't yet rooted. * Log errors for failed conversions. * Use consistent wording for binding warnings. "Could not convert" instead of "Cannot convert". * Log warnings for converter exceptions. * Don't convert new TargetTypeConverters each time. * Added failing test for implicit conversion. * Support cast operators in compiled bindings. A bit of a hack as we'd ideally not be using reflection when using compiled bindings. * This shouldn't be a public API. Should only be used for tests. * Make enum/int conversion work. * Check for SetValue equality after conversion. And also use "identity equals" where value types and strings use `object.Equals` and reference types use `object.ReferenceEquals`. * Added ConverterCulture back to bindings. * Fix merge error. Removed deleted files from csproj that were re-added due to indentation changes. * Use BindingExpression directly in ValueStoe. * Introduce BindingExpressionBase. And `UntypedBindingExpressionBase`. * Make TemplateBinding a BindingExpression. * Make DynamicResource use a BindingExpression. * WIP: Start exposing a BindingExpression API. * Finish exposing a BindingExpression API. * Fix OneTimeBinding. * Remove unneeded classes/methods. * Don't call obsolete API. * Make BindingExpressionBase the public API. This matches WPF's API. * Added BindingExpressionBase.UpdateTarget. * Initial implementation of UpdateSourceTrigger. * Don't use weak references for values. If they're boxed values, they can get collected. * No need for virtual/generic methods here now. * Reintroduce support for binding anchors. Turns out these were needed by animations, just our animation system has no unit tests so I missed that fact earlier. Add a basic animation unit test that fails without anchor support, and add binding anchors back in. Currently a private API as I suspect this feature shouldn't be needed outside the framework. * Include new property in clone. And add real-life example of `UpdateSourceTrigger=LostFocus` to BindingDemo. * Fix merge error. * Updated BindingExpression tests. - Make them run for both compiled and reflection bindings (found a bunch of tests that fail with compiled bindings) - Make them not depend on converting the `BindingExpression` to an observable and instead test the end result of the binding on an `AvaloniaObject` * Fix compiled binding indexer tests. * Use data validation plugins in PropertyAccessorNode. Added a warning suppression for now: we may need a separate `DataValidators` list for AOT-friendly plugins. * Don't separate plugins by reflection. `DataAnnotationsValidationPlugin` is public and so it can't be moved. No point in moving the others if this one will be in the wrong place. * Remove unneeded methods. * Make reflection binding tests use a string. Convert the `System.Linq.Expression` to a string and then use this, as reflection bindings will always be instanced with a string path. * Added TODO12 plan for IBinding2. * Use more specific exception. * Fix nits from code review. * Make expression nodes sealed where possible. * Unsubscribe on Stop, don't re-subscribe. D'oh. * Tweak ExpressionNode lists. Saves a few K in benchmarks and it's a cleaner API. * Add a pooled option in BindingExpressionGrammar. Micro-optimization. * Avoid allocations when enumerating binding plugins. * Add IBinding2 support to observable bind overloads. In the case of `TemplateBinding`, the `IObservable` bind overload is selected by C#. Add an explicit check for an `IBinding2` here to use the more performant code-path. * Remove disposed binding from ImmediateBindingFrame. * Added TemplateBinding benchmarks. * Remove duplicate items. Seems to have been caused by a merge error. * Fix exception when closing color picker. And add tests. * Don't skip converter when binding to self. * Don't pass UnsetValue to converters. This follows WPF behavior. * Log element name if present. More useful than just logging the control hash code. * Respect binding priority. * Throw on mismatched binding priorities. We don't want to respect the binding priority in this case as it breaks `TemplateBindings` when the default `LocalValue` priority is passed. Instead make sure that the priority parameter matches that of the expression. This reverts commit a72765d70514506d94b39ba33a3d91e11cd6dcd4. * Convert to target type in TemplateBinding. * Short-circuit target type conversion for same types. --- .ncrunch/Avalonia.Tizen.v3.ncrunchproject | 5 + .../ControlCatalog.Tizen.v3.ncrunchproject | 5 + .ncrunch/ControlCatalog.v3.ncrunchproject | 5 + .ncrunch/PInvoke.net6.0.v3.ncrunchproject | 5 + .../PInvoke.netstandard2.0.v3.ncrunchproject | 5 + samples/BindingDemo/MainWindow.xaml | 1 + .../Animation/AnimatorKeyFrame.cs | 4 +- src/Avalonia.Base/AvaloniaObject.cs | 84 +- src/Avalonia.Base/AvaloniaObjectExtensions.cs | 29 +- src/Avalonia.Base/AvaloniaProperty.cs | 8 + src/Avalonia.Base/ClassBindingManager.cs | 2 +- .../Data/BindingChainException.cs | 12 +- .../Data/BindingExpressionBase.cs | 55 ++ src/Avalonia.Base/Data/BindingNotification.cs | 41 + src/Avalonia.Base/Data/BindingOperations.cs | 34 +- src/Avalonia.Base/Data/BindingValue.cs | 39 + .../Data/Core/AvaloniaPropertyAccessorNode.cs | 57 -- src/Avalonia.Base/Data/Core/BindingError.cs | 18 + .../Data/Core/BindingExpression.cs | 906 +++++++++++------- .../Data/Core/EmptyExpressionNode.cs | 7 - src/Avalonia.Base/Data/Core/ExpressionNode.cs | 168 ---- .../Core/ExpressionNodes/ArrayIndexerNode.cs | 54 ++ .../AvaloniaPropertyAccessorNode.cs | 58 ++ .../ExpressionNodes/CollectionNodeBase.cs | 81 ++ .../Core/ExpressionNodes/DataContextNode.cs | 31 + .../ExpressionNodes/DataContextNodeBase.cs | 19 + .../Core/ExpressionNodes/ExpressionNode.cs | 253 +++++ .../Core/ExpressionNodes/FuncTransformNode.cs | 28 + .../ExpressionNodes/IPropertyAccessorNode.cs | 13 + .../Core/ExpressionNodes/ISettableNode.cs | 23 + .../LogicalAncestorElementNode.cs | 85 ++ .../Core/ExpressionNodes/LogicalNotNode.cs | 69 ++ .../Core/ExpressionNodes/MethodCommandNode.cs | 107 +++ .../Core/ExpressionNodes/NamedElementNode.cs | 46 + .../ExpressionNodes/ParentDataContextNode.cs | 67 ++ .../ExpressionNodes/PropertyAccessorNode.cs | 85 ++ .../DynamicPluginPropertyAccessorNode.cs | 95 ++ .../Reflection/DynamicPluginStreamNode.cs | 53 + .../Reflection/ExpressionTreeIndexerNode.cs | 81 ++ .../Reflection/ReflectionIndexerNode.cs | 159 +++ .../Reflection/ReflectionTypeCastNode.cs | 29 + .../Data/Core/ExpressionNodes/SourceNode.cs | 26 + .../Data/Core/ExpressionNodes/StreamNode.cs | 43 + .../ExpressionNodes/TemplatedParentNode.cs | 49 + .../VisualAncestorElementNode.cs | 86 ++ .../Data/Core/ExpressionObserver.cs | 316 ------ src/Avalonia.Base/Data/Core/IBinding2.cs | 20 + .../Data/Core/IBindingExpressionSink.cs | 34 + src/Avalonia.Base/Data/Core/ITransformNode.cs | 7 - .../Data/Core/IndexerBindingExpression.cs | 68 ++ .../Data/Core/IndexerExpressionNode.cs | 76 -- .../Data/Core/IndexerNodeBase.cs | 102 -- src/Avalonia.Base/Data/Core/LogicalNotNode.cs | 91 -- .../Data/Core/MarkupBindingChainException.cs | 43 - .../Core/Parsers/BindingExpressionVisitor.cs | 232 +++++ .../Data/Core/Parsers/ExpressionTreeParser.cs | 26 - .../Parsers/ExpressionVisitorNodeBuilder.cs | 219 ----- .../Plugins/AvaloniaPropertyAccessorPlugin.cs | 4 - .../Data/Core/Plugins/BindingPlugins.cs | 28 +- .../DataAnnotationsValidationPlugin.cs | 3 +- .../Core/Plugins/ExceptionValidationPlugin.cs | 2 - .../Core/Plugins/IDataValidationPlugin.cs | 5 +- .../Core/Plugins/IPropertyAccessorPlugin.cs | 6 +- .../Data/Core/Plugins/IStreamPlugin.cs | 3 - .../Core/Plugins/IndeiValidationPlugin.cs | 3 - .../Plugins/InpcPropertyAccessorPlugin.cs | 21 +- .../Data/Core/Plugins/MethodAccessorPlugin.cs | 157 +-- .../Core/Plugins/ObservableStreamPlugin.cs | 9 +- .../Core/Plugins/ObservableStreamPlugin`1.cs | 27 + .../Plugins/PropertyInfoAccessorPlugin.cs | 27 + .../Plugins/ReflectionMethodAccessorPlugin.cs | 141 +++ .../Data/Core/Plugins/TaskStreamPlugin.cs | 5 +- .../Data/Core/Plugins/TaskStreamPlugin`1.cs | 49 + .../Data/Core/PropertyAccessorNode.cs | 103 -- src/Avalonia.Base/Data/Core/SettableNode.cs | 53 - src/Avalonia.Base/Data/Core/StreamNode.cs | 56 -- .../Data/Core/TargetTypeConverter.cs | 127 +++ src/Avalonia.Base/Data/Core/TypeCastNode.cs | 34 - .../Data/Core/UntypedBindingExpressionBase.cs | 600 ++++++++++++ .../UntypedObservableBindingExpression.cs | 34 + .../CultureInfoIetfLanguageTagConverter.cs | 0 src/Avalonia.Base/Data/IBinding.cs | 3 + src/Avalonia.Base/Data/IndexerBinding.cs | 18 +- src/Avalonia.Base/Data/InstancedBinding.cs | 33 +- .../Data/TemplateBinding.Observable.cs | 21 + src/Avalonia.Base/Data/TemplateBinding.cs | 272 +++--- src/Avalonia.Base/Data/UpdateSourceTrigger.cs | 29 + .../Diagnostics/ObsoletionMessages.cs | 12 + src/Avalonia.Base/DirectProperty.cs | 7 +- src/Avalonia.Base/DirectPropertyBase.cs | 7 + src/Avalonia.Base/IDirectPropertyAccessor.cs | 6 + src/Avalonia.Base/Logging/TraceLogSink.cs | 37 +- src/Avalonia.Base/Properties/AssemblyInfo.cs | 2 + .../PropertyStore/BindingEntryBase.cs | 2 - .../PropertyStore/EffectiveValue.cs | 12 + .../PropertyStore/EffectiveValue`1.cs | 18 +- .../PropertyStore/ImmediateValueFrame.cs | 7 + .../LocalValueBindingObserverBase.cs | 2 - .../PropertyStore/LoggingUtils.cs | 82 -- .../PropertyStore/UntypedBindingEntry.cs | 39 - .../PropertyStore/UntypedValueUtils.cs | 18 - src/Avalonia.Base/PropertyStore/ValueFrame.cs | 1 + src/Avalonia.Base/PropertyStore/ValueStore.cs | 142 ++- src/Avalonia.Base/StyledProperty.cs | 13 +- .../Styling/PropertySetterBindingInstance.cs | 60 -- src/Avalonia.Base/Styling/Setter.cs | 25 +- src/Avalonia.Base/Utilities/TypeUtilities.cs | 30 +- src/Avalonia.Base/Visual.cs | 20 - .../AutoCompleteBox/AutoCompleteBox.cs | 2 +- .../XamlIlBindingPathHelper.cs | 43 +- .../Avalonia.Markup.Xaml.csproj | 99 +- .../Data/DynamicResourceExpression.cs | 155 +++ .../CompiledBindingExtension.cs | 136 ++- .../CompiledBindings/ArrayElementPlugin.cs | 72 -- .../CompiledBindings/CommandAccessorPlugin.cs | 155 --- .../CompiledBindings/CompiledBindingPath.cs | 90 +- .../FindVisualAncestorNode.cs | 53 - .../CompiledBindings/MethodAccessorPlugin.cs | 73 -- .../ObservableStreamPlugin.cs | 31 - .../PropertyInfoAccessorFactory.cs | 5 +- .../PropertyInfoAccessorPlugin.cs | 33 - .../CompiledBindings/StrongTypeCastNode.cs | 18 - .../CompiledBindings/TaskStreamPlugin.cs | 3 - .../DynamicResourceExtension.cs | 39 +- .../ReflectionBindingExtension.cs | 2 +- .../Templates/TreeDataTemplate.cs | 10 +- src/Markup/Avalonia.Markup/Data/Binding.cs | 194 ++-- .../Avalonia.Markup/Data/BindingBase.cs | 229 +---- .../Avalonia.Markup/Data/MultiBinding.cs | 52 +- .../Parsers/BindingExpressionGrammar.cs | 26 +- .../Markup/Parsers/ExpressionNodeFactory.cs | 145 +++ .../Parsers/ExpressionObserverBuilder.cs | 80 -- .../Markup/Parsers/ExpressionParser.cs | 139 --- .../Markup/Parsers/Nodes/ElementNameNode.cs | 37 - .../Markup/Parsers/Nodes/FindAncestorNode.cs | 53 - .../Markup/Parsers/Nodes/SelfNode.cs | 9 - .../Markup/Parsers/Nodes/StringIndexerNode.cs | 317 ------ .../Properties/AssemblyInfo.cs | 3 + .../Animation/StyleAnimationTests.cs | 124 +++ .../AvaloniaObjectTests_Binding.cs | 101 +- .../AvaloniaObjectTests_Direct.cs | 31 - .../AvaloniaPropertyTests.cs | 1 + ...BindingExpressionTests.AttachedProperty.cs | 132 +++ ...BindingExpressionTests.AvaloniaProperty.cs | 79 ++ .../BindingExpressionTests.DataValidation.cs | 361 +++++++ .../Core/BindingExpressionTests.GetValue.cs | 144 +++ .../Core/BindingExpressionTests.Indexer.cs | 299 ++++++ .../Data/Core/BindingExpressionTests.Mode.cs | 70 ++ .../Core/BindingExpressionTests.Negation.cs | 107 +++ .../Core/BindingExpressionTests.Observable.cs | 89 ++ .../Core/BindingExpressionTests.Property.cs | 238 +++++ .../Core/BindingExpressionTests.SetValue.cs | 232 +++++ .../Data/Core/BindingExpressionTests.Task.cs | 128 +++ ...dingExpressionTests.UpdateSourceTrigger.cs | 113 +++ .../Data/Core/BindingExpressionTests.cs | 665 +++++++------ .../Core/BindingPathFromExpressionBuilder.cs | 257 +++++ ...ompiledBindingPathFromExpressionBuilder.cs | 314 ++++++ ...xpressionObserverTests_AttachedProperty.cs | 125 --- ...xpressionObserverTests_AvaloniaProperty.cs | 86 -- .../ExpressionObserverTests_DataValidation.cs | 227 ----- .../ExpressionObserverTests_ExpressionTree.cs | 224 ----- .../Core/ExpressionObserverTests_Indexer.cs | 333 ------- .../Core/ExpressionObserverTests_Lifetime.cs | 112 --- .../Core/ExpressionObserverTests_Negation.cs | 42 - .../ExpressionObserverTests_Observable.cs | 199 ---- .../Core/ExpressionObserverTests_Property.cs | 738 -------------- .../Core/ExpressionObserverTests_SetValue.cs | 111 --- .../Data/Core/ExpressionObserverTests_Task.cs | 173 ---- .../Plugins/ExceptionValidationPluginTests.cs | 1 - .../PropertyStore/ValueStoreTests_Frames.cs | 18 +- .../Styling/SetterTests.cs | 9 +- .../Styling/StyleTests.cs | 23 + tests/Avalonia.Base.UnitTests/VisualTests.cs | 49 - .../Avalonia.Benchmarks/Data/Binding_Setup.cs | 58 ++ .../Data/Binding_Values.cs | 65 ++ .../Data/BindingsBenchmark.cs | 59 -- .../Data/PropertyAccessorBenchmarks.cs | 2 +- .../Data/PropertyAccessorPluginBenchmarks.cs | 4 +- .../Data/TemplateBinding_Setup.cs | 46 + .../Data/TemplateBinding_Values.cs | 50 + .../TreeViewTests.cs | 24 +- ...rverTests.cs => BindingExpressionTests.cs} | 32 +- .../Data/BindingTests.cs | 113 +-- .../Data/BindingTests_Converters.cs | 73 +- .../Data/BindingTests_Logging.cs | 490 ++++++++++ .../Data/TemplateBindingTests.cs | 20 + ...> BindingExpressionGrammarTests_Errors.cs} | 28 +- ...onObserverBuilderTests_AttachedProperty.cs | 32 +- ...onObserverBuilderTests_AvaloniaProperty.cs | 16 +- .../ExpressionObserverBuilderTests_Indexer.cs | 122 ++- .../ExpressionObserverBuilderTests_Method.cs | 17 +- ...ExpressionObserverBuilderTests_Negation.cs | 69 +- ...ExpressionObserverBuilderTests_Property.cs | 67 +- ...ilderTests.cs => ExpressionPathParsing.cs} | 86 +- .../Data/BindingTests_TemplatedParent.cs | 34 + .../MarkupExtensions/BindingExtensionTests.cs | 1 - .../CompiledBindingExtensionTests.cs | 116 ++- .../DynamicResourceExtensionTests.cs | 28 + .../Xaml/BindingTests_RelativeSource.cs | 19 - .../Xaml/ControlBindingTests.cs | 38 - .../Xaml/ControlThemeTests.cs | 30 + 201 files changed, 9573 insertions(+), 7203 deletions(-) create mode 100644 .ncrunch/Avalonia.Tizen.v3.ncrunchproject create mode 100644 .ncrunch/ControlCatalog.Tizen.v3.ncrunchproject create mode 100644 .ncrunch/ControlCatalog.v3.ncrunchproject create mode 100644 .ncrunch/PInvoke.net6.0.v3.ncrunchproject create mode 100644 .ncrunch/PInvoke.netstandard2.0.v3.ncrunchproject create mode 100644 src/Avalonia.Base/Data/BindingExpressionBase.cs delete mode 100644 src/Avalonia.Base/Data/Core/AvaloniaPropertyAccessorNode.cs create mode 100644 src/Avalonia.Base/Data/Core/BindingError.cs delete mode 100644 src/Avalonia.Base/Data/Core/EmptyExpressionNode.cs delete mode 100644 src/Avalonia.Base/Data/Core/ExpressionNode.cs create mode 100644 src/Avalonia.Base/Data/Core/ExpressionNodes/ArrayIndexerNode.cs create mode 100644 src/Avalonia.Base/Data/Core/ExpressionNodes/AvaloniaPropertyAccessorNode.cs create mode 100644 src/Avalonia.Base/Data/Core/ExpressionNodes/CollectionNodeBase.cs create mode 100644 src/Avalonia.Base/Data/Core/ExpressionNodes/DataContextNode.cs create mode 100644 src/Avalonia.Base/Data/Core/ExpressionNodes/DataContextNodeBase.cs create mode 100644 src/Avalonia.Base/Data/Core/ExpressionNodes/ExpressionNode.cs create mode 100644 src/Avalonia.Base/Data/Core/ExpressionNodes/FuncTransformNode.cs create mode 100644 src/Avalonia.Base/Data/Core/ExpressionNodes/IPropertyAccessorNode.cs create mode 100644 src/Avalonia.Base/Data/Core/ExpressionNodes/ISettableNode.cs create mode 100644 src/Avalonia.Base/Data/Core/ExpressionNodes/LogicalAncestorElementNode.cs create mode 100644 src/Avalonia.Base/Data/Core/ExpressionNodes/LogicalNotNode.cs create mode 100644 src/Avalonia.Base/Data/Core/ExpressionNodes/MethodCommandNode.cs create mode 100644 src/Avalonia.Base/Data/Core/ExpressionNodes/NamedElementNode.cs create mode 100644 src/Avalonia.Base/Data/Core/ExpressionNodes/ParentDataContextNode.cs create mode 100644 src/Avalonia.Base/Data/Core/ExpressionNodes/PropertyAccessorNode.cs create mode 100644 src/Avalonia.Base/Data/Core/ExpressionNodes/Reflection/DynamicPluginPropertyAccessorNode.cs create mode 100644 src/Avalonia.Base/Data/Core/ExpressionNodes/Reflection/DynamicPluginStreamNode.cs create mode 100644 src/Avalonia.Base/Data/Core/ExpressionNodes/Reflection/ExpressionTreeIndexerNode.cs create mode 100644 src/Avalonia.Base/Data/Core/ExpressionNodes/Reflection/ReflectionIndexerNode.cs create mode 100644 src/Avalonia.Base/Data/Core/ExpressionNodes/Reflection/ReflectionTypeCastNode.cs create mode 100644 src/Avalonia.Base/Data/Core/ExpressionNodes/SourceNode.cs create mode 100644 src/Avalonia.Base/Data/Core/ExpressionNodes/StreamNode.cs create mode 100644 src/Avalonia.Base/Data/Core/ExpressionNodes/TemplatedParentNode.cs create mode 100644 src/Avalonia.Base/Data/Core/ExpressionNodes/VisualAncestorElementNode.cs delete mode 100644 src/Avalonia.Base/Data/Core/ExpressionObserver.cs create mode 100644 src/Avalonia.Base/Data/Core/IBinding2.cs create mode 100644 src/Avalonia.Base/Data/Core/IBindingExpressionSink.cs delete mode 100644 src/Avalonia.Base/Data/Core/ITransformNode.cs create mode 100644 src/Avalonia.Base/Data/Core/IndexerBindingExpression.cs delete mode 100644 src/Avalonia.Base/Data/Core/IndexerExpressionNode.cs delete mode 100644 src/Avalonia.Base/Data/Core/IndexerNodeBase.cs delete mode 100644 src/Avalonia.Base/Data/Core/LogicalNotNode.cs delete mode 100644 src/Avalonia.Base/Data/Core/MarkupBindingChainException.cs create mode 100644 src/Avalonia.Base/Data/Core/Parsers/BindingExpressionVisitor.cs delete mode 100644 src/Avalonia.Base/Data/Core/Parsers/ExpressionTreeParser.cs delete mode 100644 src/Avalonia.Base/Data/Core/Parsers/ExpressionVisitorNodeBuilder.cs create mode 100644 src/Avalonia.Base/Data/Core/Plugins/ObservableStreamPlugin`1.cs create mode 100644 src/Avalonia.Base/Data/Core/Plugins/PropertyInfoAccessorPlugin.cs create mode 100644 src/Avalonia.Base/Data/Core/Plugins/ReflectionMethodAccessorPlugin.cs create mode 100644 src/Avalonia.Base/Data/Core/Plugins/TaskStreamPlugin`1.cs delete mode 100644 src/Avalonia.Base/Data/Core/PropertyAccessorNode.cs delete mode 100644 src/Avalonia.Base/Data/Core/SettableNode.cs delete mode 100644 src/Avalonia.Base/Data/Core/StreamNode.cs create mode 100644 src/Avalonia.Base/Data/Core/TargetTypeConverter.cs delete mode 100644 src/Avalonia.Base/Data/Core/TypeCastNode.cs create mode 100644 src/Avalonia.Base/Data/Core/UntypedBindingExpressionBase.cs create mode 100644 src/Avalonia.Base/Data/Core/UntypedObservableBindingExpression.cs rename src/{Markup/Avalonia.Markup => Avalonia.Base}/Data/CultureInfoIetfLanguageTagConverter.cs (100%) create mode 100644 src/Avalonia.Base/Data/TemplateBinding.Observable.cs create mode 100644 src/Avalonia.Base/Data/UpdateSourceTrigger.cs create mode 100644 src/Avalonia.Base/Diagnostics/ObsoletionMessages.cs delete mode 100644 src/Avalonia.Base/PropertyStore/LoggingUtils.cs delete mode 100644 src/Avalonia.Base/PropertyStore/UntypedBindingEntry.cs delete mode 100644 src/Avalonia.Base/Styling/PropertySetterBindingInstance.cs create mode 100644 src/Markup/Avalonia.Markup.Xaml/Data/DynamicResourceExpression.cs delete mode 100644 src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/ArrayElementPlugin.cs delete mode 100644 src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/CommandAccessorPlugin.cs delete mode 100644 src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/FindVisualAncestorNode.cs delete mode 100644 src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/MethodAccessorPlugin.cs delete mode 100644 src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/ObservableStreamPlugin.cs delete mode 100644 src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/PropertyInfoAccessorPlugin.cs delete mode 100644 src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/StrongTypeCastNode.cs create mode 100644 src/Markup/Avalonia.Markup/Markup/Parsers/ExpressionNodeFactory.cs delete mode 100644 src/Markup/Avalonia.Markup/Markup/Parsers/ExpressionObserverBuilder.cs delete mode 100644 src/Markup/Avalonia.Markup/Markup/Parsers/ExpressionParser.cs delete mode 100644 src/Markup/Avalonia.Markup/Markup/Parsers/Nodes/ElementNameNode.cs delete mode 100644 src/Markup/Avalonia.Markup/Markup/Parsers/Nodes/FindAncestorNode.cs delete mode 100644 src/Markup/Avalonia.Markup/Markup/Parsers/Nodes/SelfNode.cs delete mode 100644 src/Markup/Avalonia.Markup/Markup/Parsers/Nodes/StringIndexerNode.cs create mode 100644 tests/Avalonia.Base.UnitTests/Animation/StyleAnimationTests.cs create mode 100644 tests/Avalonia.Base.UnitTests/Data/Core/BindingExpressionTests.AttachedProperty.cs create mode 100644 tests/Avalonia.Base.UnitTests/Data/Core/BindingExpressionTests.AvaloniaProperty.cs create mode 100644 tests/Avalonia.Base.UnitTests/Data/Core/BindingExpressionTests.DataValidation.cs create mode 100644 tests/Avalonia.Base.UnitTests/Data/Core/BindingExpressionTests.GetValue.cs create mode 100644 tests/Avalonia.Base.UnitTests/Data/Core/BindingExpressionTests.Indexer.cs create mode 100644 tests/Avalonia.Base.UnitTests/Data/Core/BindingExpressionTests.Mode.cs create mode 100644 tests/Avalonia.Base.UnitTests/Data/Core/BindingExpressionTests.Negation.cs create mode 100644 tests/Avalonia.Base.UnitTests/Data/Core/BindingExpressionTests.Observable.cs create mode 100644 tests/Avalonia.Base.UnitTests/Data/Core/BindingExpressionTests.Property.cs create mode 100644 tests/Avalonia.Base.UnitTests/Data/Core/BindingExpressionTests.SetValue.cs create mode 100644 tests/Avalonia.Base.UnitTests/Data/Core/BindingExpressionTests.Task.cs create mode 100644 tests/Avalonia.Base.UnitTests/Data/Core/BindingExpressionTests.UpdateSourceTrigger.cs create mode 100644 tests/Avalonia.Base.UnitTests/Data/Core/BindingPathFromExpressionBuilder.cs create mode 100644 tests/Avalonia.Base.UnitTests/Data/Core/CompiledBindingPathFromExpressionBuilder.cs delete mode 100644 tests/Avalonia.Base.UnitTests/Data/Core/ExpressionObserverTests_AttachedProperty.cs delete mode 100644 tests/Avalonia.Base.UnitTests/Data/Core/ExpressionObserverTests_AvaloniaProperty.cs delete mode 100644 tests/Avalonia.Base.UnitTests/Data/Core/ExpressionObserverTests_DataValidation.cs delete mode 100644 tests/Avalonia.Base.UnitTests/Data/Core/ExpressionObserverTests_ExpressionTree.cs delete mode 100644 tests/Avalonia.Base.UnitTests/Data/Core/ExpressionObserverTests_Indexer.cs delete mode 100644 tests/Avalonia.Base.UnitTests/Data/Core/ExpressionObserverTests_Lifetime.cs delete mode 100644 tests/Avalonia.Base.UnitTests/Data/Core/ExpressionObserverTests_Negation.cs delete mode 100644 tests/Avalonia.Base.UnitTests/Data/Core/ExpressionObserverTests_Observable.cs delete mode 100644 tests/Avalonia.Base.UnitTests/Data/Core/ExpressionObserverTests_Property.cs delete mode 100644 tests/Avalonia.Base.UnitTests/Data/Core/ExpressionObserverTests_SetValue.cs delete mode 100644 tests/Avalonia.Base.UnitTests/Data/Core/ExpressionObserverTests_Task.cs create mode 100644 tests/Avalonia.Benchmarks/Data/Binding_Setup.cs create mode 100644 tests/Avalonia.Benchmarks/Data/Binding_Values.cs delete mode 100644 tests/Avalonia.Benchmarks/Data/BindingsBenchmark.cs create mode 100644 tests/Avalonia.Benchmarks/Data/TemplateBinding_Setup.cs create mode 100644 tests/Avalonia.Benchmarks/Data/TemplateBinding_Values.cs rename tests/Avalonia.LeakTests/{ExpressionObserverTests.cs => BindingExpressionTests.cs} (74%) create mode 100644 tests/Avalonia.Markup.UnitTests/Data/BindingTests_Logging.cs rename tests/Avalonia.Markup.UnitTests/Parsers/{ExpressionNodeBuilderTests_Errors.cs => BindingExpressionGrammarTests_Errors.cs} (71%) rename tests/Avalonia.Markup.UnitTests/Parsers/{ExpressionNodeBuilderTests.cs => ExpressionPathParsing.cs} (56%) diff --git a/.ncrunch/Avalonia.Tizen.v3.ncrunchproject b/.ncrunch/Avalonia.Tizen.v3.ncrunchproject new file mode 100644 index 000000000..319cd523c --- /dev/null +++ b/.ncrunch/Avalonia.Tizen.v3.ncrunchproject @@ -0,0 +1,5 @@ + + + True + + \ No newline at end of file diff --git a/.ncrunch/ControlCatalog.Tizen.v3.ncrunchproject b/.ncrunch/ControlCatalog.Tizen.v3.ncrunchproject new file mode 100644 index 000000000..319cd523c --- /dev/null +++ b/.ncrunch/ControlCatalog.Tizen.v3.ncrunchproject @@ -0,0 +1,5 @@ + + + True + + \ No newline at end of file diff --git a/.ncrunch/ControlCatalog.v3.ncrunchproject b/.ncrunch/ControlCatalog.v3.ncrunchproject new file mode 100644 index 000000000..319cd523c --- /dev/null +++ b/.ncrunch/ControlCatalog.v3.ncrunchproject @@ -0,0 +1,5 @@ + + + True + + \ No newline at end of file diff --git a/.ncrunch/PInvoke.net6.0.v3.ncrunchproject b/.ncrunch/PInvoke.net6.0.v3.ncrunchproject new file mode 100644 index 000000000..319cd523c --- /dev/null +++ b/.ncrunch/PInvoke.net6.0.v3.ncrunchproject @@ -0,0 +1,5 @@ + + + True + + \ No newline at end of file diff --git a/.ncrunch/PInvoke.netstandard2.0.v3.ncrunchproject b/.ncrunch/PInvoke.netstandard2.0.v3.ncrunchproject new file mode 100644 index 000000000..319cd523c --- /dev/null +++ b/.ncrunch/PInvoke.netstandard2.0.v3.ncrunchproject @@ -0,0 +1,5 @@ + + + True + + \ No newline at end of file diff --git a/samples/BindingDemo/MainWindow.xaml b/samples/BindingDemo/MainWindow.xaml index d1c65ca73..a00bed37f 100644 --- a/samples/BindingDemo/MainWindow.xaml +++ b/samples/BindingDemo/MainWindow.xaml @@ -23,6 +23,7 @@ +