Browse Source

Merge pull request #2558 from AvaloniaUI/xamlil-fixes

Various xaml compiler fixes
pull/2580/head
Nikita Tsukanov 7 years ago
committed by GitHub
parent
commit
4e92b8ca6d
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs
  2. 24
      src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/AvaloniaXamlIlCompiler.cs
  3. 18
      src/Markup/Avalonia.Markup.Xaml/XamlIl/Runtime/XamlIlRuntimeHelpers.cs
  4. 2
      src/Markup/Avalonia.Markup.Xaml/XamlIl/xamlil.github
  5. 3
      tests/Avalonia.Markup.Xaml.UnitTests/Avalonia.Markup.Xaml.UnitTests.csproj
  6. 6
      tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlIlClassWithCustomProperty.xaml
  7. 79
      tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlIlTests.cs

3
src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs

@ -150,7 +150,8 @@ namespace Avalonia.Build.Tasks
classType = typeSystem.TargetAssembly.FindType(tn.Text);
if (classType == null)
throw new XamlIlParseException($"Unable to find type `{tn.Text}`", classDirective);
initialRoot.Type = new XamlIlAstClrTypeReference(classDirective, classType, false);
compiler.OverrideRootType(parsed,
new XamlIlAstClrTypeReference(classDirective, classType, false));
initialRoot.Children.Remove(classDirective);
}

24
src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/AvaloniaXamlIlCompiler.cs

@ -112,13 +112,31 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
rootType = new XamlIlAstClrTypeReference(rootObject, overrideRootType, false);
}
rootObject.Type = rootType;
OverrideRootType(parsed, rootType);
Transform(parsed);
Compile(parsed, tb, _contextType, PopulateName, BuildName, "__AvaloniaXamlIlNsInfo", baseUri, fileSource);
}
public void OverrideRootType(XamlIlDocument doc, IXamlIlAstTypeReference newType)
{
var root = (XamlIlAstObjectNode)doc.Root;
var oldType = root.Type;
if (oldType.Equals(newType))
return;
root.Type = newType;
foreach (var child in root.Children.OfType<XamlIlAstXamlPropertyValueNode>())
{
if (child.Property is XamlIlAstNamePropertyReference prop)
{
if (prop.DeclaringType.Equals(oldType))
prop.DeclaringType = newType;
if (prop.TargetType.Equals(oldType))
prop.TargetType = newType;
}
}
}
}
}

18
src/Markup/Avalonia.Markup.Xaml/XamlIl/Runtime/XamlIlRuntimeHelpers.cs

@ -4,6 +4,7 @@ using System.Linq;
using System.Reflection;
using Avalonia.Controls;
using Avalonia.Data;
using Portable.Xaml;
using Portable.Xaml.Markup;
// ReSharper disable UnusedMember.Global
// ReSharper disable UnusedParameter.Global
@ -17,19 +18,24 @@ namespace Avalonia.Markup.Xaml.XamlIl.Runtime
{
var resourceNodes = provider.GetService<IAvaloniaXamlIlParentStackProvider>().Parents
.OfType<IResourceNode>().ToList();
return sp => builder(new DeferredParentServiceProvider(sp, resourceNodes));
var rootObject = provider.GetService<IRootObjectProvider>().RootObject;
return sp => builder(new DeferredParentServiceProvider(sp, resourceNodes, rootObject));
}
class DeferredParentServiceProvider : IAvaloniaXamlIlParentStackProvider, IServiceProvider
class DeferredParentServiceProvider :
IAvaloniaXamlIlParentStackProvider,
IServiceProvider,
IRootObjectProvider
{
private readonly IServiceProvider _parentProvider;
private readonly List<IResourceNode> _parentResourceNodes;
public DeferredParentServiceProvider(IServiceProvider parentProvider, List<IResourceNode> parentResourceNodes)
public DeferredParentServiceProvider(IServiceProvider parentProvider, List<IResourceNode> parentResourceNodes,
object rootObject)
{
_parentProvider = parentProvider;
_parentResourceNodes = parentResourceNodes;
RootObject = rootObject;
}
public IEnumerable<object> Parents => GetParents();
@ -46,8 +52,12 @@ namespace Avalonia.Markup.Xaml.XamlIl.Runtime
{
if (serviceType == typeof(IAvaloniaXamlIlParentStackProvider))
return this;
if (serviceType == typeof(IRootObjectProvider))
return this;
return _parentProvider?.GetService(serviceType);
}
public object RootObject { get; }
}

2
src/Markup/Avalonia.Markup.Xaml/XamlIl/xamlil.github

@ -1 +1 @@
Subproject commit 3b3c1f93a566080d417b9782f9cc4ea67cd62344
Subproject commit 1e3ffc315401f0b2eb96a0e79b25c2fc19a80d78

3
tests/Avalonia.Markup.Xaml.UnitTests/Avalonia.Markup.Xaml.UnitTests.csproj

@ -32,7 +32,8 @@
<EmbeddedResource Include="Xaml\Style2.xaml">
<SubType>Designer</SubType>
</EmbeddedResource>
<AvaloniaResource Include="Xaml\XamlIlClassWithPrecompiledXaml.xaml"/>
<AvaloniaResource Include="Xaml\XamlIlClassWithPrecompiledXaml.xaml" />
<AvaloniaResource Include="Xaml\XamlIlClassWithCustomProperty.xaml" />
</ItemGroup>
<Import Project="..\..\build\BuildTargets.targets" />
</Project>

6
tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlIlClassWithCustomProperty.xaml

@ -0,0 +1,6 @@
<UserControl xmlns='https://github.com/avaloniaui'
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
x:Class='Avalonia.Markup.Xaml.UnitTests.XamlIlClassWithCustomProperty'
Test="123">
</UserControl>

79
tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlIlTests.cs

@ -5,8 +5,12 @@ using System.Globalization;
using System.Linq;
using System.Runtime.CompilerServices;
using Avalonia.Controls;
using Avalonia.Controls.Presenters;
using Avalonia.Data.Converters;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Media;
using Avalonia.Threading;
using Avalonia.UnitTests;
using Avalonia.VisualTree;
using JetBrains.Annotations;
@ -117,6 +121,81 @@ namespace Avalonia.Markup.Xaml.UnitTests
Assert.Equal(Brushes.Red.Color, ((ISolidColorBrush)canvas.Background).Color);
}
}
[Fact]
public void Event_Handlers_Should_Work_For_Templates()
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var w =new XamlIlBugTestsEventHandlerCodeBehind();
w.ApplyTemplate();
w.Show();
Dispatcher.UIThread.RunJobs();
var itemsPresenter = ((ItemsControl)w.Content).GetVisualChildren().FirstOrDefault();
var item = itemsPresenter
.GetVisualChildren().First()
.GetVisualChildren().First()
.GetVisualChildren().First();
((Control)item).RaiseEvent(new PointerPressedEventArgs {ClickCount = 20});
Assert.Equal(20, w.Args.ClickCount);
}
}
[Fact]
public void Custom_Properties_Should_Work_With_XClass()
{
var precompiled = new XamlIlClassWithCustomProperty();
Assert.Equal("123", precompiled.Test);
var loaded = (XamlIlClassWithCustomProperty)AvaloniaXamlLoader.Parse(@"
<UserControl xmlns='https://github.com/avaloniaui'
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
x:Class='Avalonia.Markup.Xaml.UnitTests.XamlIlClassWithCustomProperty'
Test='321'>
</UserControl>");
Assert.Equal("321", loaded.Test);
}
}
public class XamlIlBugTestsEventHandlerCodeBehind : Window
{
public PointerPressedEventArgs Args;
public void HandlePointerPressed(object sender, PointerPressedEventArgs args)
{
Args = args;
}
public XamlIlBugTestsEventHandlerCodeBehind()
{
new AvaloniaXamlLoader().Load(@"
<Window x:Class='Avalonia.Markup.Xaml.UnitTests.XamlIlBugTestsEventHandlerCodeBehind'
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
xmlns='https://github.com/avaloniaui'
xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests;assembly=Avalonia.Markup.Xaml.UnitTests'
>
<ItemsControl>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button PointerPressed='HandlePointerPressed' Content='{Binding .}' />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Window>
", typeof(XamlIlBugTestsEventHandlerCodeBehind).Assembly, this);
((ItemsControl)Content).Items = new[] {"123"};
}
}
public class XamlIlClassWithCustomProperty : UserControl
{
public string Test { get; set; }
public XamlIlClassWithCustomProperty()
{
AvaloniaXamlLoader.Load(this);
}
}
public class XamlIlBugTestsBrushToColorConverter : IMultiValueConverter

Loading…
Cancel
Save