diff --git a/.gitmodules b/.gitmodules
index 22c56307b0..22a241f120 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -4,3 +4,6 @@
[submodule "nukebuild/Numerge"]
path = nukebuild/Numerge
url = https://github.com/kekekeks/Numerge.git
+[submodule "src/Markup/Avalonia.Markup.Xaml/XamlIl/xamlil.github"]
+ path = src/Markup/Avalonia.Markup.Xaml/XamlIl/xamlil.github
+ url = https://github.com/kekekeks/XamlIl.git
diff --git a/build/EmbedXaml.props b/build/EmbedXaml.props
index 219ffb2e42..dba14521ab 100644
--- a/build/EmbedXaml.props
+++ b/build/EmbedXaml.props
@@ -4,8 +4,8 @@
%(Filename)
-
+
Designer
-
+
-
\ No newline at end of file
+
diff --git a/build/SampleApp.props b/build/SampleApp.props
index 5580a4c2c9..285f880129 100644
--- a/build/SampleApp.props
+++ b/build/SampleApp.props
@@ -5,4 +5,9 @@
+
+
+
diff --git a/dirs.proj b/dirs.proj
index 0f24632b72..4939a158bb 100644
--- a/dirs.proj
+++ b/dirs.proj
@@ -6,12 +6,12 @@
+
-
+
+
-
-
diff --git a/packages/Avalonia/AvaloniaBuildTasks.targets b/packages/Avalonia/AvaloniaBuildTasks.targets
index 10f971cc4c..a455e2b3fc 100644
--- a/packages/Avalonia/AvaloniaBuildTasks.targets
+++ b/packages/Avalonia/AvaloniaBuildTasks.targets
@@ -8,6 +8,10 @@
AssemblyFile="$(AvaloniaBuildTasksLocation)"
/>
+
+
@@ -20,11 +24,15 @@
+
+ $(BuildAvaloniaResourcesDependsOn);AddAvaloniaResources;ResolveReferences
+
+
+ DependsOnTargets="$(BuildAvaloniaResourcesDependsOn)">
+ Command="dotnet msbuild /nodereuse:false $(MSBuildProjectFile) /t:GenerateAvaloniaResources /p:_AvaloniaForceInternalMSBuild=true /p:Configuration=$(Configuration) /p:TargetFramework=$(TargetFramework) /p:BuildProjectReferences=false"/>
+
+
+
+ $(IntermediateOutputPath)/Avalonia/references
+ $(IntermediateOutputPath)/Avalonia/original.dll
+
+
+
+
+
+
diff --git a/samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj b/samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj
index 589f41c06b..804ca1f9b8 100644
--- a/samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj
+++ b/samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj
@@ -3,6 +3,7 @@
Exe
netcoreapp2.0
+ true
diff --git a/samples/ControlCatalog/App.xaml b/samples/ControlCatalog/App.xaml
index d20e0100a0..2f6d25c089 100644
--- a/samples/ControlCatalog/App.xaml
+++ b/samples/ControlCatalog/App.xaml
@@ -4,7 +4,7 @@
-
+
";
+ var xaml = "";
var loader = new AvaloniaXamlLoader();
var style = (Style)loader.Load(xaml);
var setter = (Setter)(style.Setters.First());
diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/BasicTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/BasicTests.cs
index 2e67541c1f..359d2521e0 100644
--- a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/BasicTests.cs
+++ b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/BasicTests.cs
@@ -1,6 +1,7 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
+using System;
using Avalonia.Collections;
using Avalonia.Controls;
using Avalonia.Controls.Presenters;
@@ -17,6 +18,7 @@ using Portable.Xaml;
using System.Collections;
using System.ComponentModel;
using System.Linq;
+using System.Xml;
using Xunit;
namespace Avalonia.Markup.Xaml.UnitTests.Xaml
@@ -48,6 +50,9 @@ namespace Avalonia.Markup.Xaml.UnitTests.Xaml
[Fact]
public void AvaloniaProperty_Without_Getter_And_Setter_Is_Set()
{
+ // It's not possible to know in compile time if a read-only property has a magic way of being not read-only
+ if (!AvaloniaXamlLoader.UseLegacyXamlLoader)
+ return;
var xaml =
@"";
- Assert.Throws(() => AvaloniaXamlLoader.Parse(xaml));
+ XamlTestHelpers.AssertThrowsXamlException(() => AvaloniaXamlLoader.Parse(xaml));
}
[Fact]
public void Non_Attached_Property_With_Attached_Property_Syntax_Throws()
{
+ // 1) It has been allowed in AvaloniaObject.SetValue for ages
+ // 2) There is no way to know if AddOwner was called in compile-time
+ if (!AvaloniaXamlLoader.UseLegacyXamlLoader)
+ return;
var xaml =
@"";
- Assert.Throws(() => AvaloniaXamlLoader.Parse(xaml));
+ XamlTestHelpers.AssertThrowsXamlException(() => AvaloniaXamlLoader.Parse(xaml));
}
[Fact]
@@ -518,7 +529,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.Xaml
var xaml = @"
\ No newline at end of file
+
diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/Style2.xaml b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/Style2.xaml
index fd93c4a468..04db8fd2dd 100644
--- a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/Style2.xaml
+++ b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/Style2.xaml
@@ -1,8 +1,9 @@
\ No newline at end of file
+
diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlIlClassWithPrecompiledXaml.xaml b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlIlClassWithPrecompiledXaml.xaml
new file mode 100644
index 0000000000..ac2f75b893
--- /dev/null
+++ b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlIlClassWithPrecompiledXaml.xaml
@@ -0,0 +1,6 @@
+
+
+
diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlIlTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlIlTests.cs
new file mode 100644
index 0000000000..a584027768
--- /dev/null
+++ b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlIlTests.cs
@@ -0,0 +1,146 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Globalization;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using Avalonia.Controls;
+using Avalonia.Data.Converters;
+using Avalonia.Media;
+using Avalonia.UnitTests;
+using Avalonia.VisualTree;
+using JetBrains.Annotations;
+using Xunit;
+
+namespace Avalonia.Markup.Xaml.UnitTests
+{
+ public class XamlIlTests
+ {
+ [Fact]
+ public void Binding_Button_IsPressed_ShouldWork()
+ {
+ var parsed = (Button)AvaloniaXamlLoader.Parse(@"
+");
+ var ctx = new XamlIlBugTestsDataContext();
+ parsed.DataContext = ctx;
+ parsed.SetValue(Button.IsPressedProperty, true);
+ Assert.True(ctx.IsPressed);
+ }
+
+ [Fact]
+ public void Transitions_Should_Be_Properly_Parsed()
+ {
+ var parsed = (Grid)AvaloniaXamlLoader.Parse(@"
+
+
+
+
+");
+ Assert.Equal(1, parsed.Transitions.Count);
+ Assert.Equal(Visual.OpacityProperty, parsed.Transitions[0].Property);
+ }
+
+ [Fact]
+ public void Parser_Should_Override_Precompiled_Xaml()
+ {
+ var precompiled = new XamlIlClassWithPrecompiledXaml();
+ Assert.Equal(Brushes.Red, precompiled.Background);
+ Assert.Equal(1, precompiled.Opacity);
+ var loaded = (XamlIlClassWithPrecompiledXaml)AvaloniaXamlLoader.Parse(@"
+
+
+");
+ Assert.Equal(loaded.Opacity, 0);
+ Assert.Null(loaded.Background);
+
+ }
+
+ [Fact]
+ public void RelativeSource_TemplatedParent_Works()
+ {
+ using (UnitTestApplication.Start(TestServices.StyledWindow))
+ {
+ new AvaloniaXamlLoader().Load(@"
+
+
+
+
+",
+ null, Application.Current);
+ var parsed = (Window)AvaloniaXamlLoader.Parse(@"
+
+
+
+
+
+");
+ var btn = ((Button)parsed.Content);
+ btn.ApplyTemplate();
+ var canvas = (Canvas)btn.GetVisualChildren().First()
+ .VisualChildren.First()
+ .VisualChildren.First()
+ .VisualChildren.First();
+ Assert.Equal(Brushes.Red.Color, ((ISolidColorBrush)canvas.Background).Color);
+ }
+ }
+ }
+
+ public class XamlIlBugTestsBrushToColorConverter : IMultiValueConverter
+ {
+ public object Convert(IList