Esempio n. 1
0
        public static string GetAssemblyMetadata(this GeneratorExecutionContext context, string key)
        {
            foreach (var a in context.FindAttributes("AssemblyMetadataAttribute"))
            {
                if (a.ConstructorArguments.Length == 2 && a.ConstructorArguments[0].Value?.ToString() == key)
                {
                    return(a.ConstructorArguments[1].Value?.ToString());
                }
            }

            return(null);
        }
        public void Execute(GeneratorExecutionContext context)
        {
            var isIos     = context.IsiOS();
            var isAndroid = context.IsAndroid();

            if (!isIos && !isAndroid)
            {
                return;
            }

            var syntaxReceiver = (AppStartupSyntaxReceiver)context.SyntaxReceiver;

            var namespaceName = context.Compilation.GlobalNamespace.Name;

            if (string.IsNullOrEmpty(namespaceName))
            {
                namespaceName = context.Compilation.AssemblyName ?? "GeneratedMauiApp";
            }

            if (context.IsAppHead())
            {
                // Look for a `[assembly: MauiStartup(typeof(StartupClass))]` attribute
                var startupAttributes = context.FindAttributes("MauiStartupAttribute")?.ToList();

                // If we have multiple, throw an error
                if ((startupAttributes?.Count ?? 0) > 1)
                {
                    context.ReportDiagnostic(Diagnostic.Create("MAUI1010", "Compiler", "More than one MauiStartupAttribute found.", DiagnosticSeverity.Error, DiagnosticSeverity.Error, true, 0));
                    return;
                }

                var startupAttribute = startupAttributes.FirstOrDefault();

                // If we don't have any,
                if (startupAttribute != null)
                {
                    // Get the constructor arg which we expect to be the startup class type name
                    var ctorTypeArg = startupAttribute.ConstructorArguments.FirstOrDefault();

                    var startupClassName = ctorTypeArg.Value?.ToString();

                    if (!string.IsNullOrEmpty(startupClassName))
                    {
                        // Prefix with global:: when we generate code to be safe
                        if (!startupClassName.StartsWith("global::"))
                        {
                            startupClassName = $"global::{startupClassName}";
                        }

                        if (isIos)
                        {
                            // Prefix with global:: when we generate code to be safe
                            var appDelegateClassName = $"{namespaceName}.AppDelegate";
                            if (!appDelegateClassName.StartsWith("global::"))
                            {
                                appDelegateClassName = $"global::{appDelegateClassName}";
                            }

                            // Create an app delegate
                            // We check to see if there's already an app delegate
                            // If there is, if it's partial and the same name as the one we generate, that's fine too
                            if (!syntaxReceiver.HasiOSAppDelegateSubclass || syntaxReceiver.iOSPartialAppDelegateSubclassType.Equals(appDelegateClassName))
                            {
                                context.AddSource("Maui_Generated_MauiGeneratedAppDelegate.cs",
                                                  GenerateiOSAppDelegate(namespaceName, startupClassName));
                            }
                            else
                            {
                                context.ReportDiagnostic(Diagnostic.Create("MAUI1020", "Compiler", "UIApplicationDelegate implementation already exists, not generating one.", DiagnosticSeverity.Warning, DiagnosticSeverity.Warning, true, 3));
                            }

                            // Create a main method
                            if (!syntaxReceiver.HasiOSMainMethod)
                            {
                                context.AddSource("Maui_Generated_MauiGeneratedMain.cs",
                                                  GenerateiOSMain(namespaceName, appDelegateClassName));
                            }
                            else
                            {
                                context.ReportDiagnostic(Diagnostic.Create("MAUI1021", "Compiler", "Main method implementation already exists, not generating one.", DiagnosticSeverity.Warning, DiagnosticSeverity.Warning, true, 3));
                            }
                        }
                        else if (isAndroid)
                        {
                            var appName = context.GetMSBuildProperty("ApplicationTitle") ?? "App1";

                            context.AddSource("Maui_Generated_MauiGeneratedAndroidActivity.cs",
                                              GenerateAndroidMainActivity(appName, namespaceName, startupClassName));

                            if (!syntaxReceiver.HasAndroidMainLauncher)
                            {
                                context.AddSource("Maui_Generated_MauiGeneratedAndroidApplication.cs",
                                                  GenerateAndroidApplication(namespaceName, startupClassName));
                            }
                            else
                            {
                                context.ReportDiagnostic(Diagnostic.Create("MAUI1021", "Compiler", "Activity with MainLauncher=true already exists, not generating one.", DiagnosticSeverity.Warning, DiagnosticSeverity.Warning, true, 3));
                            }
                        }
                    }
                }
            }
        }