From ac3be6c662d56a3bb467227b6b3f29bfd94d66cf Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Sat, 6 Jul 2019 21:18:08 -0700 Subject: [PATCH] Fix handling of Not nodes. --- .../XamlIlBindingPathHelper.cs | 37 +++++++++++++------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/XamlIlBindingPathHelper.cs b/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/XamlIlBindingPathHelper.cs index dfa90d1989..598f9175e8 100644 --- a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/XamlIlBindingPathHelper.cs +++ b/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/XamlIlBindingPathHelper.cs @@ -67,7 +67,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions private static IXamlIlBindingPathNode TransformBindingPath(XamlIlAstTransformationContext context, IXamlIlLineInfo lineInfo, IXamlIlType startType, IEnumerable bindingExpression) { - bool appendNotNode = false; + List transformNodes = new List(); List nodes = new List(); foreach (var astNode in bindingExpression) { @@ -77,10 +77,19 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions case BindingExpressionGrammar.EmptyExpressionNode _: break; case BindingExpressionGrammar.NotNode _: - appendNotNode = !appendNotNode; + transformNodes.Add(new XamlIlNotPathElementNode(context.Configuration.WellKnownTypes.Boolean)); break; case BindingExpressionGrammar.StreamNode _: - var observableType = targetType.GetAllInterfaces().FirstOrDefault(i => i.GenericTypeDefinition?.Equals(context.Configuration.TypeSystem.FindType("System.IObservable`1")) ?? false); + IXamlIlType observableType; + if (targetType.GenericTypeDefinition?.Equals(context.Configuration.TypeSystem.FindType("System.IObservable`1")) == true) + { + observableType = targetType; + } + else + { + observableType = targetType.GetAllInterfaces().FirstOrDefault(i => i.GenericTypeDefinition?.Equals(context.Configuration.TypeSystem.FindType("System.IObservable`1")) ?? false); + } + if (observableType != null) { nodes.Add(new XamlIlStreamObservablePathElementNode(observableType.GenericArguments[0])); @@ -179,16 +188,9 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions nodes.Add(new ElementNamePathElementNode(elementName.Name, elementType)); break; } - } - if (appendNotNode) - { - // TODO: Fix Not behavior - nodes.Add(new XamlIlNotPathElementNode(context.Configuration.WellKnownTypes.Boolean)); - } - - return new XamlIlBindingPathNode(lineInfo, context.GetAvaloniaTypes().CompiledBindingPath, nodes); + return new XamlIlBindingPathNode(lineInfo, context.GetAvaloniaTypes().CompiledBindingPath, transformNodes, nodes); IXamlIlType GetType(string ns, string name) { @@ -422,17 +424,23 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions class XamlIlBindingPathNode : XamlIlAstNode, IXamlIlBindingPathNode, IXamlIlAstEmitableNode { + private readonly List _transformElements; private readonly List _elements; public XamlIlBindingPathNode(IXamlIlLineInfo lineInfo, IXamlIlType bindingPathType, + List transformElements, List elements) : base(lineInfo) { Type = new XamlIlAstClrTypeReference(lineInfo, bindingPathType, false); + _transformElements = transformElements; _elements = elements; } - public IXamlIlType BindingResultType => _elements[_elements.Count - 1].Type; + public IXamlIlType BindingResultType + => _transformElements.Count > 0 + ? _transformElements[0].Type + : _elements[_elements.Count - 1].Type; public IXamlIlAstTypeReference Type { get; } @@ -441,6 +449,11 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions var types = context.GetAvaloniaTypes(); codeGen.Newobj(types.CompiledBindingPathBuilder.FindConstructor()); + foreach (var transform in _transformElements) + { + transform.Emit(context, codeGen); + } + foreach (var element in _elements) { element.Emit(context, codeGen);