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/src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs b/src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs
index 851b37d302..05659389b1 100644
--- a/src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs
+++ b/src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs
@@ -258,8 +258,8 @@ namespace Avalonia.Build.Tasks
int lineNumber = 0, linePosition = 0;
if (e is XamlIlParseException xe)
{
- lineNumber = xe.Line;
- linePosition = xe.Position;
+ lineNumber = xe.LineNumber;
+ linePosition = xe.LinePosition;
}
engine.LogErrorEvent(new BuildErrorEventArgs("Avalonia", "XAMLIL", res.FilePath,
lineNumber, linePosition, lineNumber, linePosition,
diff --git a/src/Avalonia.DesignerSupport/Remote/RemoteDesignerEntryPoint.cs b/src/Avalonia.DesignerSupport/Remote/RemoteDesignerEntryPoint.cs
index 67a93f3c9c..801ed74ca0 100644
--- a/src/Avalonia.DesignerSupport/Remote/RemoteDesignerEntryPoint.cs
+++ b/src/Avalonia.DesignerSupport/Remote/RemoteDesignerEntryPoint.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Net;
using System.Reflection;
+using System.Xml;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Remote.Protocol;
@@ -206,7 +207,8 @@ namespace Avalonia.DesignerSupport.Remote
catch (Exception e)
{
var xamlException = e as XamlException;
-
+ var xmlException = e as XmlException;
+
s_transport.Send(new UpdateXamlResultMessage
{
Error = e.ToString(),
@@ -214,8 +216,8 @@ namespace Avalonia.DesignerSupport.Remote
{
ExceptionType = e.GetType().FullName,
Message = e.Message.ToString(),
- LineNumber = xamlException?.LineNumber,
- LinePosition = xamlException?.LinePosition,
+ LineNumber = xamlException?.LineNumber ?? xmlException?.LineNumber,
+ LinePosition = xamlException?.LinePosition ?? xmlException?.LinePosition,
}
});
}
diff --git a/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj b/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj
index fe1c20eec9..a3d206edb7 100644
--- a/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj
+++ b/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj
@@ -56,6 +56,7 @@
+
diff --git a/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs b/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs
index a51390f5c7..717b2ed1e8 100644
--- a/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs
+++ b/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs
@@ -26,7 +26,7 @@ namespace Avalonia.Markup.Xaml
{
public bool IsDesignMode { get; set; }
- public bool UseLegacyXamlLoader { get; set; } = false;
+ public static bool UseLegacyXamlLoader { get; set; } = false;
///
/// Initializes a new instance of the class.
@@ -176,7 +176,7 @@ namespace Avalonia.Markup.Xaml
public object Load(Stream stream, Assembly localAssembly, object rootInstance = null, Uri uri = null)
{
if (!UseLegacyXamlLoader)
- return AvaloniaXamlIlRuntimeCompiler.Load(stream, localAssembly, rootInstance, uri);
+ return AvaloniaXamlIlRuntimeCompiler.Load(stream, localAssembly, rootInstance, uri, IsDesignMode);
var readerSettings = new XamlXmlReaderSettings()
diff --git a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/ResourceInclude.cs b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/ResourceInclude.cs
index 1f3d9fc139..827f58a909 100644
--- a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/ResourceInclude.cs
+++ b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/ResourceInclude.cs
@@ -54,6 +54,11 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions
///
public override object ProvideValue(IServiceProvider serviceProvider)
+ {
+ return ProvideTypedValue(serviceProvider);
+ }
+
+ public ResourceInclude ProvideTypedValue(IServiceProvider serviceProvider)
{
var tdc = (ITypeDescriptorContext)serviceProvider;
_baseUri = tdc?.GetContextBaseUri();
diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/AvaloniaXamlIlRuntimeCompiler.cs b/src/Markup/Avalonia.Markup.Xaml/XamlIl/AvaloniaXamlIlRuntimeCompiler.cs
index 621facea25..9c9418458a 100644
--- a/src/Markup/Avalonia.Markup.Xaml/XamlIl/AvaloniaXamlIlRuntimeCompiler.cs
+++ b/src/Markup/Avalonia.Markup.Xaml/XamlIl/AvaloniaXamlIlRuntimeCompiler.cs
@@ -23,6 +23,7 @@ namespace Avalonia.Markup.Xaml.XamlIl
#if !RUNTIME_XAML_CECIL
private static SreTypeSystem _sreTypeSystem;
private static ModuleBuilder _sreBuilder;
+ private static IXamlIlType _sreContextType;
private static XamlIlLanguageTypeMappings _sreMappings;
private static XamlIlXmlnsMappings _sreXmlns;
private static AssemblyBuilder _sreAsm;
@@ -53,7 +54,8 @@ namespace Avalonia.Markup.Xaml.XamlIl
_sreTypeSystem = new SreTypeSystem();
if (_sreBuilder == null)
{
- _sreCanSave = !AvaloniaLocator.Current.GetService().GetRuntimeInfo().IsCoreClr;
+ _sreCanSave = AvaloniaLocator.Current.GetService()?.GetRuntimeInfo().IsCoreClr ==
+ false;
var name = new AssemblyName(Guid.NewGuid().ToString("N"));
if (_sreCanSave)
{
@@ -77,22 +79,25 @@ namespace Avalonia.Markup.Xaml.XamlIl
AssemblyBuilderAccess.RunAndCollect);
_sreBuilder = _sreAsm.DefineDynamicModule("XamlIlLoader.ildump");
-
}
if (_sreMappings == null)
_sreMappings = AvaloniaXamlIlLanguage.Configure(_sreTypeSystem);
if (_sreXmlns == null)
_sreXmlns = XamlIlXmlnsMappings.Resolve(_sreTypeSystem, _sreMappings);
+ if (_sreContextType == null)
+ _sreContextType = XamlIlContextDefinition.GenerateContextClass(
+ _sreTypeSystem.CreateTypeBuilder(
+ _sreBuilder.DefineType("XamlIlContext")), _sreTypeSystem, _sreMappings);
}
- static object LoadSre(string xaml, Assembly localAssembly, object rootInstance, Uri uri)
+ static object LoadSre(string xaml, Assembly localAssembly, object rootInstance, Uri uri, bool isDesignMode)
{
var success = false;
try
{
- var rv = LoadSreCore(xaml, localAssembly, rootInstance, uri);
+ var rv = LoadSreCore(xaml, localAssembly, rootInstance, uri, isDesignMode);
success = true;
return rv;
}
@@ -104,15 +109,15 @@ namespace Avalonia.Markup.Xaml.XamlIl
}
- static object LoadSreCore(string xaml, Assembly localAssembly, object rootInstance, Uri uri)
+ static object LoadSreCore(string xaml, Assembly localAssembly, object rootInstance, Uri uri, bool isDesignMode)
{
InitializeSre();
var asm = localAssembly == null ? null : _sreTypeSystem.GetAssembly(localAssembly);
- var contextType = _sreBuilder.DefineType("XamlIlContext");
+
var compiler = new AvaloniaXamlIlCompiler(new XamlIlTransformerConfiguration(_sreTypeSystem, asm,
_sreMappings, _sreXmlns, AvaloniaXamlIlLanguage.CustomValueConverter),
- _sreTypeSystem.CreateTypeBuilder(contextType));
+ _sreContextType);
var tb = _sreBuilder.DefineType("Builder_" + Guid.NewGuid().ToString("N") + "_" + uri);
IXamlIlType overrideType = null;
@@ -121,6 +126,7 @@ namespace Avalonia.Markup.Xaml.XamlIl
overrideType = _sreTypeSystem.GetType(rootInstance.GetType());
}
+ compiler.IsDesignMode = isDesignMode;
compiler.ParseAndCompile(xaml, uri?.ToString(), null, _sreTypeSystem.CreateTypeBuilder(tb), overrideType);
var created = tb.CreateTypeInfo();
@@ -151,7 +157,8 @@ namespace Avalonia.Markup.Xaml.XamlIl
}
}
- public static object Load(Stream stream, Assembly localAssembly, object rootInstance, Uri uri)
+ public static object Load(Stream stream, Assembly localAssembly, object rootInstance, Uri uri,
+ bool isDesignMode)
{
string xaml;
using (var sr = new StreamReader(stream))
@@ -159,7 +166,7 @@ namespace Avalonia.Markup.Xaml.XamlIl
#if RUNTIME_XAML_CECIL
return LoadCecil(xaml, localAssembly, rootInstance, uri);
#else
- return LoadSre(xaml, localAssembly, rootInstance, uri);
+ return LoadSre(xaml, localAssembly, rootInstance, uri, isDesignMode);
#endif
}
diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/AvaloniaXamlIlCompiler.cs b/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/AvaloniaXamlIlCompiler.cs
index f9139a1beb..8484ae4ec6 100644
--- a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/AvaloniaXamlIlCompiler.cs
+++ b/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/AvaloniaXamlIlCompiler.cs
@@ -1,3 +1,4 @@
+using System.Collections.Generic;
using Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers;
using XamlIl;
using XamlIl.Ast;
@@ -11,6 +12,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
public class AvaloniaXamlIlCompiler : XamlIlCompiler
{
private readonly IXamlIlType _contextType;
+ private readonly AvaloniaXamlIlDesignPropertiesTransformer _designTransformer;
private AvaloniaXamlIlCompiler(XamlIlTransformerConfiguration configuration) : base(configuration, true)
{
@@ -18,6 +20,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
Transformers.Insert(0, new XNameTransformer());
Transformers.Insert(1, new IgnoredDirectivesTransformer());
+ Transformers.Insert(2, _designTransformer = new AvaloniaXamlIlDesignPropertiesTransformer());
// Targeted
@@ -55,10 +58,19 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
public const string PopulateName = "__AvaloniaXamlIlPopulate";
public const string BuildName = "__AvaloniaXamlIlBuild";
-
+
+ public bool IsDesignMode
+ {
+ get => _designTransformer.IsDesignMode;
+ set => _designTransformer.IsDesignMode = value;
+ }
+
public void ParseAndCompile(string xaml, string baseUri, IFileSource fileSource, IXamlIlTypeBuilder tb, IXamlIlType overrideRootType)
{
- var parsed = XDocumentXamlIlParser.Parse(xaml);
+ var parsed = XDocumentXamlIlParser.Parse(xaml, new Dictionary
+ {
+ {XamlNamespaces.Blend2008, XamlNamespaces.Blend2008}
+ });
if (overrideRootType != null)
{
diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlDesignPropertiesTransformer.cs b/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlDesignPropertiesTransformer.cs
new file mode 100644
index 0000000000..c422673d11
--- /dev/null
+++ b/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlDesignPropertiesTransformer.cs
@@ -0,0 +1,63 @@
+using System.Collections.Generic;
+using System.Linq;
+using XamlIl;
+using XamlIl.Ast;
+using XamlIl.Transform;
+
+namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
+{
+ public class AvaloniaXamlIlDesignPropertiesTransformer : IXamlIlAstTransformer
+ {
+ public bool IsDesignMode { get; set; }
+
+ private static Dictionary DesignDirectives = new Dictionary()
+ {
+ ["DataContext"] = "DataContext",
+ ["DesignWidth"] = "Width", ["DesignHeight"] = "Height", ["PreviewWith"] = "PreviewWith"
+ };
+
+ private const string AvaloniaNs = "https://github.com/avaloniaui";
+ public IXamlIlAstNode Transform(XamlIlAstTransformationContext context, IXamlIlAstNode node)
+ {
+ if (node is XamlIlAstObjectNode on)
+ {
+ for (var c=0; c";
- Assert.Throws(() => AvaloniaXamlLoader.Parse(xaml));
+ XamlTestHelpers.AssertThrowsXamlException(() => AvaloniaXamlLoader.Parse(xaml));
}
[Fact]
@@ -158,7 +162,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.Xaml
var xaml =
@"";
- Assert.Throws(() => AvaloniaXamlLoader.Parse(xaml));
+ XamlTestHelpers.AssertThrowsXamlException(() => AvaloniaXamlLoader.Parse(xaml));
}
[Fact]
@@ -587,6 +591,9 @@ namespace Avalonia.Markup.Xaml.UnitTests.Xaml
[Fact]
public void Xaml_Binding_Is_Delayed()
{
+ if (!AvaloniaXamlLoader.UseLegacyXamlLoader)
+ return;
+
using (UnitTestApplication.Start(TestServices.MockWindowingPlatform))
{
var xaml =
diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/EventTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/EventTests.cs
index 6ea3015138..ddecec0a95 100644
--- a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/EventTests.cs
+++ b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/EventTests.cs
@@ -31,12 +31,15 @@ namespace Avalonia.Markup.Xaml.UnitTests.Xaml
var loader = new AvaloniaXamlLoader();
var target = new MyButton();
- Assert.Throws(() => loader.Load(xaml, rootInstance: target));
+ XamlTestHelpers.AssertThrowsXamlException(() => loader.Load(xaml, rootInstance: target));
}
[Fact]
public void Exception_Is_Not_Thrown_If_Event_Not_Found_In_Design_Mode()
{
+ // Runtime compiler should properly understand x:Class
+ if (!AvaloniaXamlLoader.UseLegacyXamlLoader)
+ return;
var xaml = @"";
var loader = new AvaloniaXamlLoader { IsDesignMode = true };
var target = new MyButton();
diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlTestHelpers.cs b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlTestHelpers.cs
new file mode 100644
index 0000000000..1b09ddc186
--- /dev/null
+++ b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlTestHelpers.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Xml;
+using Portable.Xaml;
+
+namespace Avalonia.Markup.Xaml.UnitTests.Xaml
+{
+ public class XamlTestHelpers
+ {
+ public static void AssertThrowsXamlException(Action cb)
+ {
+ try
+ {
+ cb();
+ }
+ catch (Exception e)
+ {
+ if(e is XamlObjectWriterException || e is XmlException)
+ return;
+ }
+ throw new Exception("Expected to throw xaml exception");
+ }
+ }
+}
diff --git a/tests/Avalonia.UnitTests/MockAssetLoader.cs b/tests/Avalonia.UnitTests/MockAssetLoader.cs
index e550f38e42..f591ac445f 100644
--- a/tests/Avalonia.UnitTests/MockAssetLoader.cs
+++ b/tests/Avalonia.UnitTests/MockAssetLoader.cs
@@ -34,7 +34,7 @@ namespace Avalonia.UnitTests
public Assembly GetAssembly(Uri uri, Uri baseUri = null)
{
- throw new NotImplementedException();
+ return null;
}
public IEnumerable GetAssets(Uri uri, Uri baseUri)