Browse Source
* Add trimming attributes to the Runtime XAML Loader project * Create CompilerDynamicDependenciesAttribute with all known dynamic types * Use master XamlX * Implement CompilerDynamicDependenciesGenerator to simplify CompilerDynamicDependencies attribute * Better formatting of generated code * Be safe about type converters as well * Remove unnecessary warning * Also include FindType just in caserelease/11.0.5-rc1
committed by
Dan Walmsley
12 changed files with 167 additions and 29 deletions
@ -0,0 +1,18 @@ |
|||||
|
using System; |
||||
|
using System.Diagnostics.CodeAnalysis; |
||||
|
|
||||
|
// WARNING: this is a partial class, second part of which is generated by CompilerDynamicDependenciesGenerator.
|
||||
|
|
||||
|
namespace Avalonia.Markup.Xaml.XamlIl; |
||||
|
|
||||
|
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] |
||||
|
internal sealed partial class CompilerDynamicDependenciesAttribute : Attribute |
||||
|
{ |
||||
|
public const DynamicallyAccessedMemberTypes XamlDynamicallyAccessedMemberTypes = DynamicallyAccessedMemberTypes.All ^ |
||||
|
(DynamicallyAccessedMemberTypes.NonPublicConstructors |
||||
|
| DynamicallyAccessedMemberTypes.NonPublicEvents |
||||
|
| DynamicallyAccessedMemberTypes.NonPublicFields |
||||
|
| DynamicallyAccessedMemberTypes.NonPublicMethods |
||||
|
| DynamicallyAccessedMemberTypes.NonPublicProperties |
||||
|
| DynamicallyAccessedMemberTypes.NonPublicNestedTypes); |
||||
|
} |
||||
@ -0,0 +1,77 @@ |
|||||
|
using System.Linq; |
||||
|
using System.Text; |
||||
|
using Microsoft.CodeAnalysis; |
||||
|
using Microsoft.CodeAnalysis.CSharp.Syntax; |
||||
|
|
||||
|
namespace DevGenerators; |
||||
|
|
||||
|
[Generator(LanguageNames.CSharp)] |
||||
|
public class CompilerDynamicDependenciesGenerator : IIncrementalGenerator |
||||
|
{ |
||||
|
public void Initialize(IncrementalGeneratorInitializationContext context) |
||||
|
{ |
||||
|
var invocationSyntaxes = context.SyntaxProvider |
||||
|
.CreateSyntaxProvider( |
||||
|
static (s, _) => s is InvocationExpressionSyntax inv && inv.Expression is MemberAccessExpressionSyntax |
||||
|
{ |
||||
|
Name: { Identifier: { Text: "GetType" or "FindType" } } |
||||
|
} && inv.ArgumentList.Arguments.Count == 1 && inv.ArgumentList.Arguments[0].Expression is LiteralExpressionSyntax, |
||||
|
static (context, _) => (InvocationExpressionSyntax)context.Node!); |
||||
|
|
||||
|
context.RegisterSourceOutput(invocationSyntaxes.Collect(), static (context, invocations) => |
||||
|
{ |
||||
|
var types = invocations |
||||
|
.Select(t => t.ArgumentList.Arguments[0].GetText().ToString()) |
||||
|
.Distinct() |
||||
|
.Select(t => t |
||||
|
.Replace("\"", "") |
||||
|
.Replace("`1", "<>") |
||||
|
.Replace("`2", "<,>") |
||||
|
.Replace("`3", "<,,>") |
||||
|
.Replace("`4", "<,,,>")) |
||||
|
.OrderBy(t => t) |
||||
|
.ToArray(); |
||||
|
if (types.Length == 0) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
var attributesBuilder = new StringBuilder(); |
||||
|
attributesBuilder.AppendLine("""
|
||||
|
//------------------------------------------------------------------------------
|
||||
|
// <auto-generated>
|
||||
|
// This code was generated by CompilerDynamicDependenciesGenerator source generator.
|
||||
|
// </auto-generated>
|
||||
|
//------------------------------------------------------------------------------
|
||||
|
|
||||
|
using System; |
||||
|
using System.Diagnostics.CodeAnalysis; |
||||
|
#if XAML_RUNTIME_LOADER
|
||||
|
namespace Avalonia.Markup.Xaml.XamlIl |
||||
|
{ |
||||
|
internal sealed partial class CompilerDynamicDependenciesAttribute |
||||
|
{ |
||||
|
""");
|
||||
|
foreach (var type in types) |
||||
|
{ |
||||
|
if (type is "System.Void" or "XamlX.XamlDebugHatch" |
||||
|
|| type.StartsWith("CompiledAvaloniaXaml")) |
||||
|
{ |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
attributesBuilder.AppendFormat( |
||||
|
" [DynamicDependency(XamlDynamicallyAccessedMemberTypes, typeof({0}))]", type); |
||||
|
attributesBuilder.AppendLine(); |
||||
|
} |
||||
|
attributesBuilder.AppendLine("""
|
||||
|
public CompilerDynamicDependenciesAttribute() {} |
||||
|
} |
||||
|
} |
||||
|
#endif
|
||||
|
""");
|
||||
|
var str = attributesBuilder.ToString(); |
||||
|
context.AddSource("CompilerDynamicDependenciesAttribute.generated.cs", attributesBuilder.ToString()); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,8 @@ |
|||||
|
{ |
||||
|
"profiles": { |
||||
|
"Profile 1": { |
||||
|
"commandName": "DebugRoslynComponent", |
||||
|
"targetProject": "..\\..\\Markup\\Avalonia.Markup.Xaml.Loader\\Avalonia.Markup.Xaml.Loader.csproj" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue