Пример #1
0
        public IArgumentList Parse(IReadOnlyList <string> args)
        {
            SealOptTable();

            IArgumentList al = OptTable.ParseArgs(args, out _);

            foreach (var info in infos)
            {
                var attribute = info.Member.MemberInfo.GetCustomAttribute <OptionAttribute>();
                if (attribute == null)
                {
                    continue;
                }

                attribute.PopulateValue(info.Member, info.OptionId, al);
            }

            return(al);
        }
Пример #2
0
        private static bool ParseOptions(
            string[] cliArgs, OptTable optTable, EmcCommandLineArguments arguments, DiagnosticsEngine diags)
        {
            var catalog = new AggregateCatalog();

            catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
            catalog.Catalogs.Add(new AssemblyCatalog(typeof(ICodeGeneratorProvider).Assembly));

            IArgumentList args = optTable.ParseArgs(cliArgs, out var missing);

            var extensions = args.GetAllArgValues(Opt.ext_eq);

            if (extensions.Count != 0)
            {
                foreach (var path in extensions)
                {
                    if (!File.Exists(path))
                    {
                        diags.Report(DiagnosticSeverity.Warning, "Ignoring extension assembly '{0}' because it does not exist.", path);
                        continue;
                    }
                    catalog.Catalogs.Add(new AssemblyCatalog(path));
                }
            }

            arguments.GeneratorOpts = new Dictionary <string, OptTable>();
            var codeGenerator = args.GetLastArgValue(Opt.generator_eq, arguments.CompilationOptions.CodeGenOptions.CodeGenerator);

            var container = new CompositionContainer(catalog);

            container.ComposeParts(diags);

            var codeGeneratorProviders = container.GetExportedValues <ICodeGeneratorProvider>().ToList();

            var    claimedArgs       = new HashSet <int>();
            object customCodeGenOpts = null;

            foreach (var provider in codeGeneratorProviders)
            {
                var info = new CodeGeneratorInfo(provider.Name, provider);
                if (info.OptTable != null)
                {
                    arguments.GeneratorOpts[provider.Name] = info.OptTable;
                }

                if (codeGenerator == provider.Name)
                {
                    customCodeGenOpts = info.ParseOptions(cliArgs, claimedArgs, diags);
                }
            }

            bool success = true;

            if (missing.ArgCount != 0)
            {
                diags.ReportError(
                    "Missing {1} argument{2} after: {0}",
                    cliArgs[missing.ArgIndex],
                    missing.ArgCount,
                    missing.ArgCount == 1 ? string.Empty : "s");
                success = false;
            }

            // Report errors on unknown arguments.
            foreach (var arg in args.Matching(Opt.Unknown))
            {
                if (claimedArgs.Contains(arg.Index) || IsExtensionArgument(arg))
                {
                    continue;
                }

                diags.ReportError("Unknown argument: {0}", arg.GetAsString());
                success = false;
            }

            arguments.ShowHelp          = args.HasArg(Opt.help) || args.HasArg(Opt.QuestionMark);
            arguments.ShowVersion       = args.HasArg(Opt.version);
            arguments.DumpMessageTable  = args.GetLastArgValue(Opt.dump_msg);
            arguments.DumpEventTemplate = args.GetLastArgValue(Opt.dump_wevt);
            arguments.OutputManifest    = args.GetLastArgValue(Opt.gen_manifest);
            arguments.Verify            = args.GetFlag(Opt.verify);

            var opts = arguments.CompilationOptions;

            opts.Inputs = args.GetAllArgValues(Opt.Input).ToList();
            opts.ResourceGenOnlyInputs = args.GetAllArgValues(Opt.resgen_manifest_eq).ToList();
            opts.OutputBaseName        = args.GetLastArgValue(Opt.out_eq);
            opts.GenerateResources     = args.GetFlag(Opt.res, Opt.no_res, true);
            opts.MessageTableFile      = args.GetLastArgValue(Opt.msg_file_eq);
            opts.EventTemplateFile     = args.GetLastArgValue(Opt.wevt_file_eq);
            opts.ResourceFile          = args.GetLastArgValue(Opt.rc_file_eq);

            opts.CodeGenOptions.GenerateCode   = args.GetFlag(Opt.code, Opt.no_code, true);
            opts.CodeGenOptions.CodeHeaderFile = args.GetLastArgValue(Opt.header_file_eq);
            opts.CodeGenOptions.CodeGenerator  = codeGenerator;

            if (opts.Inputs.Count == 1)
            {
                arguments.DecompilationOptions.InputModule = opts.Inputs[0];
            }
            else if (opts.Inputs.Count == 2)
            {
                arguments.DecompilationOptions.InputEventTemplate = opts.Inputs[0];
                arguments.DecompilationOptions.InputMessageTable  = opts.Inputs[1];
            }
            arguments.DecompilationOptions.OutputManifest = arguments.OutputManifest;

            var compatLevelString = args.GetLastArgValue(Opt.compat_eq, "10.0.16299");

            if (Version.TryParse(compatLevelString, out Version compatibilityLevel))
            {
                opts.CompatibilityLevel = compatibilityLevel;
            }
            else
            {
                diags.ReportError("Invalid compatibility level: {0}", compatLevelString);
                success = false;
            }

            opts.InferUnspecifiedOutputFiles();

            if (arguments.Verify)
            {
                opts.CodeGenOptions.GenerateCode = false;
                opts.GenerateResources           = false;
            }

            if (opts.CodeGenOptions.CodeGenerator != null)
            {
                var selectedCodeGen = codeGeneratorProviders.FirstOrDefault(x => x.Name == opts.CodeGenOptions.CodeGenerator);
                if (selectedCodeGen == null)
                {
                    diags.ReportError("No code generator found with name '{0}'.", opts.CodeGenOptions.CodeGenerator);
                    diags.Report(
                        DiagnosticSeverity.Note,
                        "Available generators: {0}",
                        string.Join(", ", codeGeneratorProviders.Select(x => x.Name)));
                    success = false;
                }
                else
                {
                    opts.CodeGenOptions.CodeGeneratorFactory = () => selectedCodeGen.CreateGenerator(customCodeGenOpts);
                }
            }

            return(success);
        }