Browse Source

Fix handling of Not nodes.

pull/3001/head
Jeremy Koritzinsky 7 years ago
parent
commit
ac3be6c662
  1. 37
      src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/XamlIlBindingPathHelper.cs

37
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<BindingExpressionGrammar.INode> bindingExpression)
{
bool appendNotNode = false;
List<IXamlIlBindingPathElementNode> transformNodes = new List<IXamlIlBindingPathElementNode>();
List<IXamlIlBindingPathElementNode> nodes = new List<IXamlIlBindingPathElementNode>();
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<IXamlIlBindingPathElementNode> _transformElements;
private readonly List<IXamlIlBindingPathElementNode> _elements;
public XamlIlBindingPathNode(IXamlIlLineInfo lineInfo,
IXamlIlType bindingPathType,
List<IXamlIlBindingPathElementNode> transformElements,
List<IXamlIlBindingPathElementNode> 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);

Loading…
Cancel
Save