diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/Avalonia.Markup.Xaml.Loader.csproj b/src/Markup/Avalonia.Markup.Xaml.Loader/Avalonia.Markup.Xaml.Loader.csproj index eadaed435e..939efc60d1 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/Avalonia.Markup.Xaml.Loader.csproj +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/Avalonia.Markup.Xaml.Loader.csproj @@ -3,7 +3,7 @@ net6.0;netstandard2.0 true - $(DefineConstants);XAMLX_INTERNAL + $(DefineConstants);XAMLX_INTERNAL;XAML_RUNTIME_LOADER @@ -21,4 +21,6 @@ + + diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/AvaloniaRuntimeXamlLoader.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/AvaloniaRuntimeXamlLoader.cs index 6f6420f66d..0368dea92f 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/AvaloniaRuntimeXamlLoader.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/AvaloniaRuntimeXamlLoader.cs @@ -1,9 +1,12 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Reflection; using System.Text; using Avalonia.Markup.Xaml.XamlIl; +using Avalonia.Markup.Xaml.XamlIl.CompilerExtensions; + #nullable enable namespace Avalonia.Markup.Xaml { @@ -18,6 +21,7 @@ namespace Avalonia.Markup.Xaml /// The URI of the XAML being loaded. /// Indicates whether the XAML is being loaded in design mode. /// The loaded object. + [RequiresUnreferencedCode(XamlX.TrimmingMessages.DynamicXamlReference)] public static object Load(string xaml, Assembly? localAssembly = null, object? rootInstance = null, Uri? uri = null, bool designMode = false) { xaml = xaml ?? throw new ArgumentNullException(nameof(xaml)); @@ -37,6 +41,7 @@ namespace Avalonia.Markup.Xaml /// The URI of the XAML being loaded. /// Indicates whether the XAML is being loaded in design mode. /// The loaded object. + [RequiresUnreferencedCode(XamlX.TrimmingMessages.DynamicXamlReference)] public static object Load(Stream stream, Assembly? localAssembly = null, object? rootInstance = null, Uri? uri = null, bool designMode = false) => AvaloniaXamlIlRuntimeCompiler.Load(new RuntimeXamlLoaderDocument(uri, rootInstance, stream), @@ -48,6 +53,7 @@ namespace Avalonia.Markup.Xaml /// The stream containing the XAML. /// Xaml loader configuration. /// The loaded object. + [RequiresUnreferencedCode(XamlX.TrimmingMessages.DynamicXamlReference)] public static object Load(RuntimeXamlLoaderDocument document, RuntimeXamlLoaderConfiguration? configuration = null) => AvaloniaXamlIlRuntimeCompiler.Load(document, configuration ?? new RuntimeXamlLoaderConfiguration()); @@ -57,6 +63,7 @@ namespace Avalonia.Markup.Xaml /// Collection of documents. /// Xaml loader configuration. /// The loaded objects per each input document. If document was removed, the element by index is null. + [RequiresUnreferencedCode(XamlX.TrimmingMessages.DynamicXamlReference)] public static IReadOnlyList LoadGroup(IReadOnlyCollection documents, RuntimeXamlLoaderConfiguration? configuration = null) => AvaloniaXamlIlRuntimeCompiler.LoadGroup(documents, configuration ?? new RuntimeXamlLoaderConfiguration()); @@ -66,6 +73,7 @@ namespace Avalonia.Markup.Xaml /// The string containing the XAML. /// Default assembly for clr-namespace:. /// The loaded object. + [RequiresUnreferencedCode(XamlX.TrimmingMessages.DynamicXamlReference)] public static object Parse(string xaml, Assembly? localAssembly = null) => Load(xaml, localAssembly); @@ -76,8 +84,8 @@ namespace Avalonia.Markup.Xaml /// >The string containing the XAML. /// >Default assembly for clr-namespace:. /// The loaded object. - public static T Parse(string xaml, Assembly? localAssembly = null) + [RequiresUnreferencedCode(XamlX.TrimmingMessages.DynamicXamlReference)] + public static T Parse<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] T>(string xaml, Assembly? localAssembly = null) => (T)Parse(xaml, localAssembly); - } } diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/AvaloniaXamlIlRuntimeCompiler.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/AvaloniaXamlIlRuntimeCompiler.cs index 995ed91b8d..be39878807 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/AvaloniaXamlIlRuntimeCompiler.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/AvaloniaXamlIlRuntimeCompiler.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Linq; @@ -11,6 +12,7 @@ using System.Runtime.InteropServices; using Avalonia.Markup.Xaml.XamlIl.CompilerExtensions; using Avalonia.Markup.Xaml.XamlIl.Runtime; using Avalonia.Platform; +using XamlX; using XamlX.Ast; using XamlX.Transform; using XamlX.TypeSystem; @@ -22,9 +24,13 @@ using Mono.Cecil; using XamlX.Ast; using XamlX.IL.Cecil; #endif + namespace Avalonia.Markup.Xaml.XamlIl { - static class AvaloniaXamlIlRuntimeCompiler +#if !RUNTIME_XAML_CECIL + [RequiresUnreferencedCode(XamlX.TrimmingMessages.DynamicXamlReference)] +#endif + internal static class AvaloniaXamlIlRuntimeCompiler { #if !RUNTIME_XAML_CECIL private static SreTypeSystem _sreTypeSystem; @@ -37,6 +43,7 @@ namespace Avalonia.Markup.Xaml.XamlIl private static AssemblyBuilder _sreAsm; private static bool _sreCanSave; + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = XamlX.TrimmingMessages.CanBeSafelyTrimmed)] public static void DumpRuntimeCompilationResults() { if (_sreBuilder == null) @@ -55,7 +62,9 @@ namespace Avalonia.Markup.Xaml.XamlIl //Ignore } } - + + [CompilerDynamicDependencies] + [UnconditionalSuppressMessage("Trimming", "IL2072", Justification = XamlX.TrimmingMessages.GeneratedTypes)] static void InitializeSre() { if (_sreTypeSystem == null) @@ -66,10 +75,7 @@ namespace Avalonia.Markup.Xaml.XamlIl var name = new AssemblyName(Guid.NewGuid().ToString("N")); if (_sreCanSave) { - var define = AppDomain.CurrentDomain.GetType().GetMethods() - .FirstOrDefault(m => m.Name == "DefineDynamicAssembly" - && m.GetParameters().Length == 3 && - m.GetParameters()[2].ParameterType == typeof(string)); + var define = GetDefineDynamicAssembly(); if (define != null) _sreAsm = (AssemblyBuilder)define.Invoke(AppDomain.CurrentDomain, new object[] { @@ -101,6 +107,12 @@ namespace Avalonia.Markup.Xaml.XamlIl _ignoresAccessChecksFromAttribute = EmitIgnoresAccessCheckAttributeDefinition(_sreBuilder); } + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = XamlX.TrimmingMessages.CanBeSafelyTrimmed)] + static MethodInfo GetDefineDynamicAssembly() => AppDomain.CurrentDomain.GetType().GetMethods() + .FirstOrDefault(m => m.Name == "DefineDynamicAssembly" + && m.GetParameters().Length == 3 && + m.GetParameters()[2].ParameterType == typeof(string)); + static Type EmitIgnoresAccessCheckAttributeDefinition(ModuleBuilder builder) { var tb = builder.DefineType("System.Runtime.CompilerServices.IgnoresAccessChecksToAttribute", @@ -138,6 +150,7 @@ namespace Avalonia.Markup.Xaml.XamlIl return tb.CreateTypeInfo(); } + [UnconditionalSuppressMessage("Trimming", "IL2080", Justification = XamlX.TrimmingMessages.GeneratedTypes)] static void EmitIgnoresAccessCheckToAttribute(AssemblyName assemblyName) { var name = assemblyName.Name; @@ -150,7 +163,6 @@ namespace Avalonia.Markup.Xaml.XamlIl _ignoresAccessChecksFromAttribute.GetConstructors()[0], new object[] { name })); } - static object LoadSre(RuntimeXamlLoaderDocument document, RuntimeXamlLoaderConfiguration configuration) { @@ -184,7 +196,8 @@ namespace Avalonia.Markup.Xaml.XamlIl DumpRuntimeCompilationResults(); } } - + + [UnconditionalSuppressMessage("Trimming", "IL2072", Justification = XamlX.TrimmingMessages.GeneratedTypes)] static IReadOnlyList LoadGroupSreCore(IReadOnlyCollection documents, RuntimeXamlLoaderConfiguration configuration) { InitializeSre(); @@ -264,14 +277,16 @@ namespace Avalonia.Markup.Xaml.XamlIl .Select(t => LoadOrPopulate(t.Item1, t.Item2.RootInstance, t.Item2.ServiceProvider)) .ToArray(); } - + static object LoadSreCore(RuntimeXamlLoaderDocument document, RuntimeXamlLoaderConfiguration configuration) { return LoadGroupSreCore(new[] { document }, configuration).Single(); } #endif - static object LoadOrPopulate(Type created, object rootInstance, IServiceProvider parentServiceProvider) + [UnconditionalSuppressMessage("Trimming", "IL2075", Justification = XamlX.TrimmingMessages.GeneratedTypes)] + [UnconditionalSuppressMessage("Trimming", "IL2072", Justification = XamlX.TrimmingMessages.GeneratedTypes)] + static object LoadOrPopulate([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type created, object rootInstance, IServiceProvider parentServiceProvider) { var isp = Expression.Parameter(typeof(IServiceProvider)); @@ -317,7 +332,7 @@ namespace Avalonia.Markup.Xaml.XamlIl return rootInstance; } } - + public static object Load(RuntimeXamlLoaderDocument document, RuntimeXamlLoaderConfiguration configuration) { #if RUNTIME_XAML_CECIL @@ -364,6 +379,7 @@ namespace Avalonia.Markup.Xaml.XamlIl private static XamlIlXmlnsMappings _cecilXmlns; private static bool _cecilInitialized; + [CompilerDynamicDependencies] static void InitializeCecil() { if(_cecilInitialized) diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerDynamicDependencies.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerDynamicDependencies.cs new file mode 100644 index 0000000000..953cf177ad --- /dev/null +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerDynamicDependencies.cs @@ -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); +} diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlCompiler.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlCompiler.cs index af34d55a3d..7658911d06 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlCompiler.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlCompiler.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.GroupTransformers; using Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers; @@ -143,6 +144,9 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions } } +#if !XAMLX_CECIL_INTERNAL + [RequiresUnreferencedCode(XamlX.TrimmingMessages.DynamicXamlReference)] +#endif public XamlDocument Parse(string xaml, IXamlType overrideRootType) { var parsed = XDocumentXamlParser.Parse(xaml, new Dictionary @@ -191,7 +195,10 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions (s, returnType, parameters) => tb.DefineDelegateSubType(s, false, returnType, parameters), baseUri, fileSource); } - + +#if !XAMLX_CECIL_INTERNAL + [RequiresUnreferencedCode(XamlX.TrimmingMessages.DynamicXamlReference)] +#endif public void ParseAndCompile(string xaml, string baseUri, IFileSource fileSource, IXamlTypeBuilder tb, IXamlType overrideRootType) { var parsed = Parse(xaml, overrideRootType); diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguage.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguage.cs index ded5768648..e8212f38be 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguage.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguage.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; using Avalonia.Controls; @@ -120,21 +121,18 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions void AddType(IXamlType type, IXamlType conv) => _converters.Add(new KeyValuePair(type, conv)); - - void Add(string type, string conv) - => AddType(typeSystem.GetType(type), typeSystem.GetType(conv)); - Add("Avalonia.Media.IImage","Avalonia.Markup.Xaml.Converters.BitmapTypeConverter"); - Add("Avalonia.Media.Imaging.Bitmap","Avalonia.Markup.Xaml.Converters.BitmapTypeConverter"); - Add("Avalonia.Media.IImageBrushSource","Avalonia.Markup.Xaml.Converters.BitmapTypeConverter"); + AddType(typeSystem.GetType("Avalonia.Media.IImage"), typeSystem.GetType("Avalonia.Markup.Xaml.Converters.BitmapTypeConverter")); + AddType(typeSystem.GetType("Avalonia.Media.Imaging.Bitmap"), typeSystem.GetType("Avalonia.Markup.Xaml.Converters.BitmapTypeConverter")); + AddType(typeSystem.GetType("Avalonia.Media.IImageBrushSource"), typeSystem.GetType("Avalonia.Markup.Xaml.Converters.BitmapTypeConverter")); var ilist = typeSystem.GetType("System.Collections.Generic.IList`1"); AddType(ilist.MakeGenericType(typeSystem.GetType("Avalonia.Point")), typeSystem.GetType("Avalonia.Markup.Xaml.Converters.PointsListTypeConverter")); - Add("Avalonia.Controls.WindowIcon","Avalonia.Markup.Xaml.Converters.IconTypeConverter"); - Add("System.Globalization.CultureInfo", "System.ComponentModel.CultureInfoConverter"); - Add("System.Uri", "Avalonia.Markup.Xaml.Converters.AvaloniaUriTypeConverter"); - Add("System.TimeSpan", "Avalonia.Markup.Xaml.Converters.TimeSpanTypeConverter"); - Add("Avalonia.Media.FontFamily","Avalonia.Markup.Xaml.Converters.FontFamilyTypeConverter"); + AddType(typeSystem.GetType("Avalonia.Controls.WindowIcon"), typeSystem.GetType("Avalonia.Markup.Xaml.Converters.IconTypeConverter")); + AddType(typeSystem.GetType("System.Globalization.CultureInfo"), typeSystem.GetType( "System.ComponentModel.CultureInfoConverter")); + AddType(typeSystem.GetType("System.Uri"), typeSystem.GetType( "Avalonia.Markup.Xaml.Converters.AvaloniaUriTypeConverter")); + AddType(typeSystem.GetType("System.TimeSpan"), typeSystem.GetType( "Avalonia.Markup.Xaml.Converters.TimeSpanTypeConverter")); + AddType(typeSystem.GetType("Avalonia.Media.FontFamily"), typeSystem.GetType("Avalonia.Markup.Xaml.Converters.FontFamilyTypeConverter")); _avaloniaList = typeSystem.GetType("Avalonia.Collections.AvaloniaList`1"); _avaloniaListConverter = typeSystem.GetType("Avalonia.Collections.AvaloniaListConverter`1"); } 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 05fe4bd2b8..b5dfcc6861 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.GroupTransformers; using XamlX.Emit; @@ -203,7 +204,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers ThemeVariant = cfg.TypeSystem.GetType("Avalonia.Styling.ThemeVariant"); WindowTransparencyLevel = cfg.TypeSystem.GetType("Avalonia.Controls.WindowTransparencyLevel"); - (IXamlType, IXamlConstructor) GetNumericTypeInfo(string name, IXamlType componentType, int componentCount) + (IXamlType, IXamlConstructor) GetNumericTypeInfo([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] string name, IXamlType componentType, int componentCount) { var type = cfg.TypeSystem.GetType(name); var ctor = type.GetConstructor(Enumerable.Range(0, componentCount).Select(_ => componentType).ToList()); diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github b/src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github index 3d57397eed..c23ae3ed66 160000 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github @@ -1 +1 @@ -Subproject commit 3d57397eed3f111e1fa20446de4ef5f9310ebe71 +Subproject commit c23ae3ed669532e2af8d86be18369584a803170a diff --git a/src/tools/Avalonia.Designer.HostApp/Avalonia.Designer.HostApp.csproj b/src/tools/Avalonia.Designer.HostApp/Avalonia.Designer.HostApp.csproj index abdd19bf58..cf069cc971 100644 --- a/src/tools/Avalonia.Designer.HostApp/Avalonia.Designer.HostApp.csproj +++ b/src/tools/Avalonia.Designer.HostApp/Avalonia.Designer.HostApp.csproj @@ -18,6 +18,7 @@ + diff --git a/src/tools/Avalonia.Generators/Avalonia.Generators.csproj b/src/tools/Avalonia.Generators/Avalonia.Generators.csproj index bfc0458ef6..fbd331b6e0 100644 --- a/src/tools/Avalonia.Generators/Avalonia.Generators.csproj +++ b/src/tools/Avalonia.Generators/Avalonia.Generators.csproj @@ -19,7 +19,8 @@ - + + diff --git a/src/tools/DevGenerators/CompilerDynamicDependenciesGenerator.cs b/src/tools/DevGenerators/CompilerDynamicDependenciesGenerator.cs new file mode 100644 index 0000000000..3838dc7bef --- /dev/null +++ b/src/tools/DevGenerators/CompilerDynamicDependenciesGenerator.cs @@ -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(""" +//------------------------------------------------------------------------------ +// +// This code was generated by CompilerDynamicDependenciesGenerator source generator. +// +//------------------------------------------------------------------------------ + +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()); + }); + } +} diff --git a/src/tools/DevGenerators/DevGenerators.csproj b/src/tools/DevGenerators/DevGenerators.csproj index ff5a4aa81d..8d856d5fc5 100644 --- a/src/tools/DevGenerators/DevGenerators.csproj +++ b/src/tools/DevGenerators/DevGenerators.csproj @@ -1,10 +1,11 @@ - + netstandard2.0 enable false True + true diff --git a/src/tools/DevGenerators/Properties/launchSettings.json b/src/tools/DevGenerators/Properties/launchSettings.json new file mode 100644 index 0000000000..47a566ee98 --- /dev/null +++ b/src/tools/DevGenerators/Properties/launchSettings.json @@ -0,0 +1,8 @@ +{ + "profiles": { + "Profile 1": { + "commandName": "DebugRoslynComponent", + "targetProject": "..\\..\\Markup\\Avalonia.Markup.Xaml.Loader\\Avalonia.Markup.Xaml.Loader.csproj" + } + } +} \ No newline at end of file