static bool? CompileCore()

in src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs [104:674]


        static bool? CompileCore(IBuildEngine engine, CecilTypeSystem typeSystem,
            string projectDirectory, bool verifyIl,
            bool defaultCompileBindings,
            MessageImportance logImportance,
            XamlCompilerDiagnosticsFilter diagnosticsFilter,
            bool debuggerLaunch,
            bool verboseExceptions)
        {
            if (debuggerLaunch)
            {
                // According this https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.debugger.launch?view=net-6.0#remarks
                // documentation, on not windows platform Debugger.Launch() always return true without running a debugger.
                if (System.Diagnostics.Debugger.Launch())
                {
                    // Set timeout at 1 minute.
                    var time = new System.Diagnostics.Stopwatch();
                    var timeout = TimeSpan.FromMinutes(1);
                    time.Start();

                    // wait for the debugger to be attached or timeout.
                    while (!System.Diagnostics.Debugger.IsAttached && time.Elapsed < timeout)
                    {
                        engine.LogMessage($"[PID:{System.Diagnostics.Process.GetCurrentProcess().Id}] Waiting to attach debugger. Elapsed {time.Elapsed}...", MessageImportance.High);
                        System.Threading.Thread.Sleep(100);
                    }

                    time.Stop();
                    if (time.Elapsed >= timeout)
                    {
                        engine.LogMessage("Waiting to attach debugger has timed out.", MessageImportance.Normal);
                    }
                }
                else
                {
                    engine.LogMessage("Debugging cancelled.", MessageImportance.Normal);
                }
            }

            // Some transformers might need to parse "avares://" Uri.
            AssetLoader.RegisterResUriParsers();

            var asm = typeSystem.TargetAssemblyDefinition;
            var avares = new AvaloniaResources(asm, projectDirectory);
            if (avares.Resources.Count(CheckXamlName) == 0)
                // Nothing to do
                return null;

            if (typeSystem.FindType("System.Reflection.AssemblyMetadataAttribute") is {} asmMetadata)
            {
                var ctor = asm.MainModule.ImportReference(typeSystem.GetTypeReference(asmMetadata).Resolve()
                    .GetConstructors().First(c => c.Parameters.Count == 2).Resolve());
                var strType = asm.MainModule.TypeSystem.String;
                var arg1 = new CustomAttributeArgument(strType, "AvaloniaUseCompiledBindingsByDefault");
                var arg2 = new CustomAttributeArgument(strType, defaultCompileBindings.ToString());
                asm.CustomAttributes.Add(new CustomAttribute(ctor) { ConstructorArguments = { arg1, arg2 } });
            }

            TypeDefinition AddClass(string name, TypeAttributes extraAttributes = 0)
            {
                var typeDef = new TypeDefinition(
                    CompiledAvaloniaXamlNamespace,
                    name,
                    TypeAttributes.Class | extraAttributes,
                    asm.MainModule.TypeSystem.Object);
                asm.MainModule.Types.Add(typeDef);
                return typeDef;
            }

            var clrPropertiesDef = AddClass("XamlIlHelpers");
            var indexerAccessorClosure = AddClass("!IndexerAccessorFactoryClosure");
            var trampolineBuilder = AddClass("XamlIlTrampolines");
            var dynamicSettersBuilder = typeSystem.CreateTypeBuilder(AddClass("XamlDynamicSetters"));

            var (xamlLanguage , emitConfig) = AvaloniaXamlIlLanguage.Configure(typeSystem);
            var diagnostics = new List<XamlDiagnostic>();
            var diagnosticsHandler = new XamlDiagnosticsHandler()
            {
                HandleDiagnostic = diagnostic =>
                {
                    var newSeverity = diagnosticsFilter.Handle(diagnostic);
                    diagnostic = diagnostic with { Severity = newSeverity };
                    diagnostics.Add(diagnostic);
                    return newSeverity;
                },
                CodeMappings = AvaloniaXamlDiagnosticCodes.XamlXDiagnosticCodeToAvalonia,
                ExceptionFormatter = ex => ex.FormatException(verboseExceptions)
            };

            var compilerConfig = new AvaloniaXamlIlCompilerConfiguration(typeSystem,
                typeSystem.TargetAssembly,
                xamlLanguage,
                XamlXmlnsMappings.Resolve(typeSystem, xamlLanguage),
                AvaloniaXamlIlLanguage.CustomValueConverter,
                new XamlIlClrPropertyInfoEmitter(typeSystem.CreateTypeBuilder(clrPropertiesDef)),
                new XamlIlPropertyInfoAccessorFactoryEmitter(typeSystem.CreateTypeBuilder(indexerAccessorClosure)),
                new XamlIlTrampolineBuilder(typeSystem.CreateTypeBuilder(trampolineBuilder)),
                new DeterministicIdGenerator(),
                diagnosticsHandler);


            var contextDef = AddClass("XamlIlContext");

            var contextClass = XamlILContextDefinition.GenerateContextClass(typeSystem.CreateTypeBuilder(contextDef), typeSystem,
                xamlLanguage, emitConfig);

            var compiler = new AvaloniaXamlIlCompiler(compilerConfig, emitConfig, contextClass)
            {
                EnableIlVerification = verifyIl,
                DefaultCompileBindings = defaultCompileBindings,
                DynamicSetterContainerProvider = new DefaultXamlDynamicSetterContainerProvider(dynamicSettersBuilder)
            };

            var editorBrowsableAttribute = typeSystem
                .GetTypeReference(typeSystem.FindType("System.ComponentModel.EditorBrowsableAttribute"))
                .Resolve();
            var editorBrowsableCtor =
                asm.MainModule.ImportReference(editorBrowsableAttribute.GetConstructors()
                    .First(c => c.Parameters.Count == 1));

            var runtimeHelpers = typeSystem.GetType("Avalonia.Markup.Xaml.XamlIl.Runtime.XamlIlRuntimeHelpers");
            var createRootServiceProviderMethod = asm.MainModule.ImportReference(
                typeSystem.GetTypeReference(runtimeHelpers).Resolve().Methods
                    .First(x => x.Name == "CreateRootServiceProviderV3"));
            var serviceProviderType = createRootServiceProviderMethod.ReturnType;

            var loaderDispatcherDef = AddClass("!XamlLoader", TypeAttributes.Public);

            loaderDispatcherDef.CustomAttributes.Add(new CustomAttribute(editorBrowsableCtor)
            {
                ConstructorArguments = {new CustomAttributeArgument(editorBrowsableCtor.Parameters[0].ParameterType, 1)}
            });


            var loaderDispatcherMethod = new MethodDefinition("TryLoad",
                MethodAttributes.Static | MethodAttributes.Public,
                asm.MainModule.TypeSystem.Object)
            {
                Parameters =
                {
                    new ParameterDefinition(serviceProviderType),
                    new ParameterDefinition(asm.MainModule.TypeSystem.String)
                },
            };
            var loaderDispatcherMethodOld = new MethodDefinition("TryLoad",
                MethodAttributes.Static | MethodAttributes.Public,
                asm.MainModule.TypeSystem.Object)
            {
                Parameters =
                {
                    new ParameterDefinition(asm.MainModule.TypeSystem.String)
                },
                Body =
                {
                    Instructions =
                    {
                        Instruction.Create(OpCodes.Ldnull),
                        Instruction.Create(OpCodes.Ldarg_0),
                        Instruction.Create(OpCodes.Call, loaderDispatcherMethod),
                        Instruction.Create(OpCodes.Ret)
                    }
                }
            };
            loaderDispatcherDef.Methods.Add(loaderDispatcherMethod);
            loaderDispatcherDef.Methods.Add(loaderDispatcherMethodOld);
            typeSystem.AddCompilerGeneratedAttribute(loaderDispatcherDef);


            var stringEquals = asm.MainModule.ImportReference(asm.MainModule.TypeSystem.String.Resolve().Methods.First(
                m =>
                    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[2].ParameterType.FullName == "System.StringComparison"));
            
            bool CompileGroup(IResourceGroup group)
            {
                var typeDef = AddClass("!" + group.Name, TypeAttributes.Public);
                var transformFailed = false;

                typeDef.CustomAttributes.Add(new CustomAttribute(editorBrowsableCtor)
                {
                    ConstructorArguments = {new CustomAttributeArgument(editorBrowsableCtor.Parameters[0].ParameterType, 1)}
                });
                var builder = typeSystem.CreateTypeBuilder(typeDef);

                IReadOnlyCollection<XamlDocumentResource> parsedXamlDocuments = new List<XamlDocumentResource>();
                foreach (var res in group.Resources.Where(CheckXamlName).OrderBy(x => x.FilePath.ToLowerInvariant()))
                {
                    engine.LogMessage($"XAMLIL: {res.Name} -> {res.Uri}", logImportance);

                    try
                    {
                        // StreamReader is needed here to handle BOM
                        var xaml = new StreamReader(new MemoryStream(res.FileContents)).ReadToEnd();
                        var parsed = XDocumentXamlParser.Parse(xaml);
                        parsed.Document = res.FilePath;

                        var initialRoot = (XamlAstObjectNode)parsed.Root;
                        
                        
                        var precompileDirective = initialRoot.Children.OfType<XamlAstXmlDirective>()
                            .FirstOrDefault(d => d.Namespace == XamlNamespaces.Xaml2006 && d.Name == "Precompile");
                        if (precompileDirective != null)
                        {
                            var precompileText = (precompileDirective.Values[0] as XamlAstTextNode)?.Text.Trim()
                                .ToLowerInvariant();
                            if (precompileText == "false")
                                continue;
                            if (precompileText != "true")
                                throw new XamlParseException("Invalid value for x:Precompile", precompileDirective);
                        }

                        var classModifierDirective = initialRoot.Children.OfType<XamlAstXmlDirective>()
                            .FirstOrDefault(d => d.Namespace == XamlNamespaces.Xaml2006 && d.Name == "ClassModifier");
                        bool? classModifierPublic = null;
                        if (classModifierDirective != null)
                        {
                            var classModifierText = (classModifierDirective.Values[0] as XamlAstTextNode)?.Text.Trim()
                                .ToLowerInvariant();
                            if ("Public".Equals(classModifierText, StringComparison.OrdinalIgnoreCase))
                                classModifierPublic = true;
                            // XAML spec uses "Public" and "NotPublic" values,
                            // When WPF documentation uses "public" and "internal".
                            else if ("NotPublic".Equals(classModifierText, StringComparison.OrdinalIgnoreCase)
                                     || "Internal".Equals(classModifierText, StringComparison.OrdinalIgnoreCase))
                                classModifierPublic = false;
                            else
                                throw new XamlParseException("Invalid value for x:ClassModifier. Expected value are: Public, NotPublic (internal).", classModifierDirective);
                        }

                        var classDirective = initialRoot.Children.OfType<XamlAstXmlDirective>()
                            .FirstOrDefault(d => d.Namespace == XamlNamespaces.Xaml2006 && d.Name == "Class");
                        IXamlType classType = null;
                        if (classDirective != null)
                        {
                            if (classDirective.Values.Count != 1 || !(classDirective.Values[0] is XamlAstTextNode tn))
                                throw new XamlParseException("x:Class should have a string value", classDirective);
                            classType = typeSystem.TargetAssembly.FindType(tn.Text);

                            if (classType == null)
                                throw new XamlParseException($"Unable to find type `{tn.Text}`", classDirective);

                            var isClassPublic = typeSystem.GetTypeReference(classType).Resolve().IsPublic;
                            classModifierPublic ??= isClassPublic;

                            // We do not really need x:ClassModifier support for x:Class, but we can at least use it for validation here.
                            if (classModifierPublic != isClassPublic)
                            {
                                throw new XamlParseException(
                                    "XAML file x:ClassModifier doesn't match the x:Class type modifiers.",
                                    precompileDirective);
                            }

                            compiler.OverrideRootType(parsed,
                                new XamlAstClrTypeReference(classDirective, classType, false));
                            initialRoot.Children.Remove(classDirective);
                        }

                        compiler.Transform(parsed);

                        var populateName = classType == null ? "Populate:" + res.Name : "!XamlIlPopulate";
                        var buildName = classType == null ? "Build:" + res.Name : null;
                        var classTypeDefinition =
                            classType == null ? null : typeSystem.GetTypeReference(classType).Resolve();

                        // All XAML files are public by default.
                        classModifierPublic ??= true;

                        var populateBuilder = classTypeDefinition == null ?
                            builder :
                            typeSystem.CreateTypeBuilder(classTypeDefinition, compilerGeneratedType: false); // don't add CompilerGeneratedAttribute to the user's type

                        ((List<XamlDocumentResource>)parsedXamlDocuments).Add(new XamlDocumentResource(
                            parsed, res.Uri, res, classType,
                            classModifierPublic.Value,
                            () => new XamlDocumentTypeBuilderProvider(
                                populateBuilder,
                                compiler.DefinePopulateMethod(
                                    populateBuilder,
                                    parsed,
                                    populateName,
                                    classTypeDefinition == null && classModifierPublic.Value
                                        ? XamlVisibility.Public
                                        : XamlVisibility.Private),
                                buildName == null ? null : builder,
                                buildName == null ?
                                    null :
                                    compiler.DefineBuildMethod(
                                        builder,
                                        parsed,
                                        buildName,
                                        classModifierPublic.Value ? XamlVisibility.Public : XamlVisibility.Assembly))));
                    }
                    catch (Exception e)
                    {
                        transformFailed = true;
                        engine.LogError(AvaloniaXamlDiagnosticCodes.TransformError, res.FilePath, e);
                    }
                }

                try
                {
                    if (!transformFailed)
                    {
                        compiler.TransformGroup(parsedXamlDocuments);
                    }
                }
                catch (Exception e)
                {
                    transformFailed = true;
                    engine.LogError(AvaloniaXamlDiagnosticCodes.TransformError, "", e);
                }

                var hasAnyError = ReportDiagnostics(engine, diagnostics) || transformFailed;
                if (hasAnyError)
                {
                    return false;
                }

                foreach (var document in parsedXamlDocuments)
                {
                    var res = (IResource)document.FileSource!;

                    if (document.Usage == XamlDocumentUsage.Merged && !document.IsPublic)
                    {
                        res.Remove();
                        continue;
                    }

                    var parsed = document.XamlDocument;
                    var classType = document.ClassType;
                    var populateBuilder = document.TypeBuilderProvider.PopulateDeclaringType;

                    try
                    {
                        var classTypeDefinition =
                            classType == null ? null : typeSystem.GetTypeReference(classType).Resolve();

                        compiler.Compile(parsed,
                            contextClass,
                            document.TypeBuilderProvider.PopulateMethod,
                            populateBuilder,
                            document.TypeBuilderProvider.BuildMethod,
                            builder,
                            builder.DefineSubType(compilerConfig.WellKnownTypes.Object, "NamespaceInfo:" + res.Name, XamlVisibility.Assembly),
                            res.Uri, res
                        );

                        if (classTypeDefinition != null)
                        {
                            var compiledPopulateMethod = typeSystem.GetTypeReference(populateBuilder).Resolve()
                                .Methods.First(m => m.Name == document.TypeBuilderProvider.PopulateMethod.Name);

                            var designLoaderFieldType = typeSystem
                                .GetType("System.Action`1")
                                .MakeGenericType(typeSystem.GetType("System.Object"));

                            var designLoaderFieldTypeReference = (GenericInstanceType)typeSystem.GetTypeReference(designLoaderFieldType);
                            designLoaderFieldTypeReference.GenericArguments[0] =
                                asm.MainModule.ImportReference(designLoaderFieldTypeReference.GenericArguments[0]);
                            designLoaderFieldTypeReference = (GenericInstanceType)
                                asm.MainModule.ImportReference(designLoaderFieldTypeReference);
                            
                            var designLoaderLoad =
                                typeSystem.GetMethodReference(
                                    designLoaderFieldType.Methods.First(m => m.Name == "Invoke"));
                            designLoaderLoad =
                                asm.MainModule.ImportReference(designLoaderLoad);
                            designLoaderLoad.DeclaringType = designLoaderFieldTypeReference;

                            var designLoaderField = new FieldDefinition("!XamlIlPopulateOverride",
                                FieldAttributes.Static | FieldAttributes.Private, designLoaderFieldTypeReference);
                            classTypeDefinition.Fields.Add(designLoaderField);
                            typeSystem.AddCompilerGeneratedAttribute(designLoaderField);

                            const string TrampolineName = "!XamlIlPopulateTrampoline";
                            var trampolineMethodWithoutSP = new Lazy<MethodDefinition>(() => CreateTrampolineMethod(false));
                            var trampolineMethodWithSP = new Lazy<MethodDefinition>(() => CreateTrampolineMethod(true));
                            MethodDefinition CreateTrampolineMethod(bool hasSystemProviderArg)
                            {
                                var trampoline = new MethodDefinition(TrampolineName,
                                    MethodAttributes.Static | MethodAttributes.Private, asm.MainModule.TypeSystem.Void);
                                if (hasSystemProviderArg)
                                {
                                    trampoline.Parameters.Add(new ParameterDefinition(serviceProviderType));
                                }
                                trampoline.Parameters.Add(new ParameterDefinition(classTypeDefinition));

                                classTypeDefinition.Methods.Add(trampoline);
                                typeSystem.AddCompilerGeneratedAttribute(trampoline);

                                var regularStart = Instruction.Create(OpCodes.Nop);
                            
                                trampoline.Body.Instructions.Add(Instruction.Create(OpCodes.Ldsfld, designLoaderField));
                                trampoline.Body.Instructions.Add(Instruction.Create(OpCodes.Brfalse, regularStart));
                                trampoline.Body.Instructions.Add(Instruction.Create(OpCodes.Ldsfld, designLoaderField));
                                trampoline.Body.Instructions.Add(Instruction.Create(hasSystemProviderArg ? OpCodes.Ldarg_1 : OpCodes.Ldarg_0));
                                trampoline.Body.Instructions.Add(Instruction.Create(OpCodes.Call, designLoaderLoad));
                                trampoline.Body.Instructions.Add(Instruction.Create(OpCodes.Ret));
                            
                                trampoline.Body.Instructions.Add(regularStart);
                                trampoline.Body.Instructions.Add(Instruction.Create(hasSystemProviderArg ? OpCodes.Ldarg_0 : OpCodes.Ldnull));
                                trampoline.Body.Instructions.Add(Instruction.Create(OpCodes.Call, createRootServiceProviderMethod));
                                trampoline.Body.Instructions.Add(Instruction.Create(hasSystemProviderArg ? OpCodes.Ldarg_1 : OpCodes.Ldarg_0));
                                trampoline.Body.Instructions.Add(Instruction.Create(OpCodes.Call, compiledPopulateMethod));
                                trampoline.Body.Instructions.Add(Instruction.Create(OpCodes.Ret));
                                CopyDebugDocument(trampoline, compiledPopulateMethod);
                                return trampoline;
                            }

                            var foundXamlLoader = false;
                            // Find AvaloniaXamlLoader.Load(this) or AvaloniaXamlLoader.Load(sp, this) and replace it with !XamlIlPopulateTrampoline(this)
                            foreach (var method in classTypeDefinition.Methods.Where(m => m.Body is not null).ToArray())
                            {
                                var i = method.Body.Instructions;
                                for (var c = 1; c < i.Count; c++)
                                {
                                    if (i[c].OpCode == OpCodes.Call)
                                    {
                                        var op = i[c].Operand as MethodReference;
                                        if (op != null
                                            && op.Name == TrampolineName)
                                        {
                                            throw new InvalidProgramException("Same XAML file was loaded twice." +
                                                "Make sure there is no x:Class duplicates no files were added to the AvaloniaResource msbuild items group twice.");
                                        }
                                        if (op != null
                                            && op.Name == "Load"
                                            && op.Parameters.Count == 1
                                            && op.Parameters[0].ParameterType.FullName == "System.Object"
                                            && op.DeclaringType.FullName == "Avalonia.Markup.Xaml.AvaloniaXamlLoader")
                                        {
                                            if (MatchThisCall(i, c - 1))
                                            {
                                                i[c].Operand = trampolineMethodWithoutSP.Value;
                                                foundXamlLoader = true;
                                            }
                                        }
                                        if (op != null
                                            && op.Name == "Load"
                                            && op.Parameters.Count == 2
                                            && op.Parameters[0].ParameterType.FullName == "System.IServiceProvider"
                                            && op.Parameters[1].ParameterType.FullName == "System.Object"
                                            && op.DeclaringType.FullName == "Avalonia.Markup.Xaml.AvaloniaXamlLoader")
                                        {
                                            if (MatchThisCall(i, c - 1))
                                            {
                                                i[c].Operand = trampolineMethodWithSP.Value;
                                                foundXamlLoader = true;
                                            }
                                        }
                                    }
                                }
                            }

                            if (!foundXamlLoader)
                            {
                                var ctors = classTypeDefinition.GetConstructors()
                                    .Where(c => !c.IsStatic).ToList();
                                // We can inject xaml loader into default constructor
                                if (ctors.Count == 1 && ctors[0].Body.Instructions.Count(o=>o.OpCode != OpCodes.Nop) == 3)
                                {
                                    var i = ctors[0].Body.Instructions;
                                    var retIdx = i.IndexOf(i.Last(x => x.OpCode == OpCodes.Ret));
                                    i.Insert(retIdx, Instruction.Create(OpCodes.Call, trampolineMethodWithoutSP.Value));
                                    i.Insert(retIdx, Instruction.Create(OpCodes.Ldarg_0));
                                }
                                else
                                {
                                    throw new InvalidProgramException(
                                        $"No call to AvaloniaXamlLoader.Load(this) call found anywhere in the type {classType.FullName} and type seems to have custom constructors.");
                                }
                            }

                        }

                        if (document.IsPublic
                            && (document.TypeBuilderProvider.BuildMethod != null || classTypeDefinition != null))
                        {
                            var compiledBuildMethod = document.TypeBuilderProvider.BuildMethod is not { } buildMethod ?
                                null :
                                typeSystem.GetTypeReference(builder).Resolve()
                                    .Methods.First(m => m.Name == buildMethod.Name);
                            var parameterlessConstructor = compiledBuildMethod != null ?
                                null :
                                classTypeDefinition.GetConstructors().FirstOrDefault(c =>
                                    c.IsPublic && !c.IsStatic && !c.HasParameters);
                            var constructorWithSp = compiledBuildMethod != null ?
                                null :
                                classTypeDefinition.GetConstructors().FirstOrDefault(c =>
                                    c.IsPublic && !c.IsStatic && c.Parameters.Count == 1 && c.Parameters[0].ParameterType.FullName == serviceProviderType.FullName);

                            if (compiledBuildMethod != null || parameterlessConstructor != null || constructorWithSp != null)
                            {
                                var i = loaderDispatcherMethod.Body.Instructions;
                                var nop = Instruction.Create(OpCodes.Nop);
                                i.Add(Instruction.Create(OpCodes.Ldarg_1));
                                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)
                                {
                                    i.Add(Instruction.Create(OpCodes.Newobj, parameterlessConstructor));
                                }
                                else if (constructorWithSp != null)
                                {
                                    i.Add(Instruction.Create(OpCodes.Ldarg_0));
                                    i.Add(Instruction.Create(OpCodes.Call, createRootServiceProviderMethod));
                                    i.Add(Instruction.Create(OpCodes.Newobj, constructorWithSp));
                                }
                                else
                                {
                                    i.Add(Instruction.Create(OpCodes.Ldarg_0));
                                    i.Add(Instruction.Create(OpCodes.Call, createRootServiceProviderMethod));
                                    i.Add(Instruction.Create(OpCodes.Call, compiledBuildMethod));
                                }

                                i.Add(Instruction.Create(OpCodes.Ret));
                                i.Add(nop);
                            }
                            else
                            {
                                var diagnostic = new XamlDiagnostic(
                                    AvaloniaXamlDiagnosticCodes.XamlLoaderUnreachable,
                                    diagnosticsFilter.Handle(
                                        XamlDiagnosticSeverity.Warning,
                                        AvaloniaXamlDiagnosticCodes.XamlLoaderUnreachable),
                                    $"XAML resource \"{res.Uri}\" won't be reachable via runtime loader, as no public constructor was found")
                                {
                                    Document = document.FileSource?.FilePath
                                };
                                engine.LogDiagnostic(diagnostic);
                            }
                        }

                    }
                    catch (Exception e)
                    {
                        engine.LogError(AvaloniaXamlDiagnosticCodes.EmitError, res.FilePath, e);
                        return false;
                    }
                    res.Remove();
                }

                // Technically that's a hack, but it fixes corert incompatibility caused by deterministic builds
                int dupeCounter = 1;
                foreach (var grp in typeDef.NestedTypes.GroupBy(x => x.Name))
                {
                    if (grp.Count() > 1)
                    {
                        foreach (var dupe in grp)
                            dupe.Name += "_dup" + dupeCounter++;
                    }
                }

                return true;
            }

            if (avares.Resources.Count(CheckXamlName) != 0)
            {
                if (!CompileGroup(avares))
                    return false;
                avares.Save();
            }
            
            loaderDispatcherMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ldnull));
            loaderDispatcherMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ret));
            return true;
        }