14 changed files with 148 additions and 24 deletions
@ -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<string, string> DesignDirectives = new Dictionary<string, string>() |
||||
|
{ |
||||
|
["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<on.Children.Count;) |
||||
|
{ |
||||
|
var ch = on.Children[c]; |
||||
|
if (ch is XamlIlAstXmlDirective directive |
||||
|
&& directive.Namespace == XamlNamespaces.Blend2008 |
||||
|
&& DesignDirectives.TryGetValue(directive.Name, out var mapTo)) |
||||
|
{ |
||||
|
if (!IsDesignMode) |
||||
|
// Just remove it from AST in non-design mode
|
||||
|
on.Children.RemoveAt(c); |
||||
|
else |
||||
|
{ |
||||
|
// Map to an actual property in `Design` class
|
||||
|
on.Children[c] = new XamlIlAstXamlPropertyValueNode(ch, |
||||
|
new XamlIlAstNamePropertyReference(ch, |
||||
|
new XamlIlAstXmlTypeReference(ch, AvaloniaNs, "Design"), |
||||
|
mapTo, on.Type), directive.Values); |
||||
|
c++; |
||||
|
} |
||||
|
} |
||||
|
// Remove all "Design" attached properties in non-design mode
|
||||
|
else if ( |
||||
|
!IsDesignMode |
||||
|
&& ch is XamlIlAstXamlPropertyValueNode pv |
||||
|
&& pv.Property is XamlIlAstNamePropertyReference pref |
||||
|
&& pref.DeclaringType is XamlIlAstXmlTypeReference dref |
||||
|
&& dref.XmlNamespace == AvaloniaNs && dref.Name == "Design" |
||||
|
) |
||||
|
{ |
||||
|
on.Children.RemoveAt(c); |
||||
|
} |
||||
|
else |
||||
|
c++; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return node; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1 +1 @@ |
|||||
Subproject commit c8b95cfa9da04dbf4afdd903c9aa76efefd59e42 |
Subproject commit b318b6dcc67370f7ebea1e3c6741a0b6d4dd5db1 |
||||
@ -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"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue