From dd61a5d7a8cf313cddfbca0196430314d1d668c1 Mon Sep 17 00:00:00 2001 From: Giuseppe Lippolis Date: Thu, 10 Nov 2022 19:47:02 +0100 Subject: [PATCH 1/3] perf: parse uri when xaml compiled --- .../AvaloniaXamlIlCompiler.cs | 4 ++-- .../AvaloniaXamlIlLanguageParseIntrinsics.cs | 21 +++++++++++++++++++ .../AvaloniaXamlIlWellKnownTypes.cs | 6 ++++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlCompiler.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlCompiler.cs index 4ece433530..4572f72e3d 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlCompiler.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlCompiler.cs @@ -30,7 +30,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions // Before everything else - + Transformers.Insert(0, new XNameTransformer()); Transformers.Insert(1, new IgnoredDirectivesTransformer()); Transformers.Insert(2, _designTransformer = new AvaloniaXamlIlDesignPropertiesTransformer()); @@ -49,7 +49,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions InsertBefore( new AvaloniaXamlIlControlThemeTransformer(), new AvaloniaXamlIlSelectorTransformer(), - new AvaloniaXamlIlControlTemplateTargetTypeMetadataTransformer(), + new AvaloniaXamlIlControlTemplateTargetTypeMetadataTransformer(), new AvaloniaXamlIlBindingPathParser(), new AvaloniaXamlIlPropertyPathTransformer(), new AvaloniaXamlIlSetterTargetTypeMetadataTransformer(), diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguageParseIntrinsics.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguageParseIntrinsics.cs index d907bcbef9..8d9439a748 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguageParseIntrinsics.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguageParseIntrinsics.cs @@ -270,6 +270,27 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions } } + if (type.Equals(types.Uri)) + { + var uriText = text.Trim(); + + var kind = ((!uriText?.StartsWith("/") == true) ? UriKind.Absolute : UriKind.Relative); + + if (string.IsNullOrWhiteSpace(uriText) || !Uri.TryCreate(uriText, kind, out var _)) + { + throw new XamlX.XamlLoadException($"Unable to parse text {uriText} as a {kind} uri.", node); + } + result = new XamlAstNewClrObjectNode(node + , new(node, types.Uri, false) + , types.UriConstructor + , new List() + { + new XamlConstantNode(node, types.String, uriText), + new XamlConstantNode(node, types.UriKind, (int)kind), + }); + return true; + } + result = null; return false; } diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs index dbfbe0e070..ee9ae1a0e8 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs @@ -101,6 +101,9 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers public IXamlType IResourceDictionary { get; } public IXamlType ResourceDictionary { get; } public IXamlMethod ResourceDictionaryDeferredAdd { get; } + public IXamlType String { get; } + public IXamlType UriKind { get; } + public IXamlConstructor UriConstructor { get; } public AvaloniaXamlIlWellKnownTypes(TransformerConfiguration cfg) { @@ -227,6 +230,9 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers cfg.TypeSystem.GetType("System.Func`2").MakeGenericType( cfg.TypeSystem.GetType("System.IServiceProvider"), XamlIlTypes.Object)); + String = cfg.TypeSystem.GetType("System.String"); + UriKind = cfg.TypeSystem.GetType("System.UriKind"); + UriConstructor = Uri.GetConstructor(new List() { String, UriKind }); } } From 8da962a71decdfbd2b65df5b8fee709ad5224328 Mon Sep 17 00:00:00 2001 From: Giuseppe Lippolis Date: Fri, 11 Nov 2022 01:55:21 +0100 Subject: [PATCH 2/3] perf: optimizze TryLoad --- src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs b/src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs index d2ccea8fa4..97aa8abc2f 100644 --- a/src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs +++ b/src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs @@ -178,10 +178,11 @@ namespace Avalonia.Build.Tasks var stringEquals = asm.MainModule.ImportReference(asm.MainModule.TypeSystem.String.Resolve().Methods.First( m => - m.IsStatic && m.Name == "Equals" && m.Parameters.Count == 2 && + m.IsStatic && m.Name == "Equals" && m.Parameters.Count == 3 && m.ReturnType.FullName == "System.Boolean" && m.Parameters[0].ParameterType.FullName == "System.String" - && m.Parameters[1].ParameterType.FullName == "System.String")); + && m.Parameters[1].ParameterType.FullName == "System.String" + && m.Parameters[2].ParameterType.FullName == "System.StringComparison")); bool CompileGroup(IResourceGroup group) { @@ -384,6 +385,7 @@ namespace Avalonia.Build.Tasks var nop = Instruction.Create(OpCodes.Nop); i.Add(Instruction.Create(OpCodes.Ldarg_0)); i.Add(Instruction.Create(OpCodes.Ldstr, res.Uri)); + i.Add(Instruction.Create(OpCodes.Ldc_I4, (int)StringComparison.OrdinalIgnoreCase)); i.Add(Instruction.Create(OpCodes.Call, stringEquals)); i.Add(Instruction.Create(OpCodes.Brfalse, nop)); if (parameterlessConstructor != null) From 5e52a5989755486c541127f58a45c3270db04add Mon Sep 17 00:00:00 2001 From: Giuseppe Lippolis Date: Sat, 12 Nov 2022 10:32:11 +0100 Subject: [PATCH 3/3] fix: Address review --- .../AvaloniaXamlIlLanguageParseIntrinsics.cs | 2 +- .../Transformers/AvaloniaXamlIlWellKnownTypes.cs | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguageParseIntrinsics.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguageParseIntrinsics.cs index cc833858fb..64fdfe155d 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguageParseIntrinsics.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguageParseIntrinsics.cs @@ -285,7 +285,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions , types.UriConstructor , new List() { - new XamlConstantNode(node, types.String, uriText), + new XamlConstantNode(node, context.Configuration.WellKnownTypes.String, uriText), new XamlConstantNode(node, types.UriKind, (int)kind), }); return true; diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs index 4ebce0e7ba..bf8427a129 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs @@ -105,7 +105,6 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers public IXamlType IResourceDictionary { get; } public IXamlType ResourceDictionary { get; } public IXamlMethod ResourceDictionaryDeferredAdd { get; } - public IXamlType String { get; } public IXamlType UriKind { get; } public IXamlConstructor UriConstructor { get; } @@ -239,9 +238,8 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers cfg.TypeSystem.GetType("System.Func`2").MakeGenericType( cfg.TypeSystem.GetType("System.IServiceProvider"), XamlIlTypes.Object)); - String = cfg.TypeSystem.GetType("System.String"); UriKind = cfg.TypeSystem.GetType("System.UriKind"); - UriConstructor = Uri.GetConstructor(new List() { String, UriKind }); + UriConstructor = Uri.GetConstructor(new List() { cfg.WellKnownTypes.String, UriKind }); } }