public static BenchmarkRunInfo[] SourceToBenchmarks(string source, IConfig config = null)
        {
            string          benchmarkContent = source;
            CompilerResults compilerResults;

            using (var cSharpCodeProvider = new CSharpCodeProvider()) {
                string directoryName = Path.GetDirectoryName(typeof(BenchmarkCase).Assembly.Location)
                                       ?? throw new DirectoryNotFoundException(typeof(BenchmarkCase).Assembly.Location);
                var compilerParameters = new CompilerParameters(
                    new[]
                {
                    "mscorlib.dll",
                    "System.dll",
                    "System.Core.dll"
                })
                {
                    CompilerOptions  = "/unsafe /optimize",
                    GenerateInMemory = false,
                    OutputAssembly   = Path.Combine(
                        directoryName,
                        $"{Path.GetFileNameWithoutExtension(Path.GetTempFileName())}.dll")
                };

                compilerParameters.ReferencedAssemblies.Add(typeof(BenchmarkCase).Assembly.Location);
                compilerResults = cSharpCodeProvider.CompileAssemblyFromSource(compilerParameters, benchmarkContent);
            }

            if (compilerResults.Errors.HasErrors)
            {
                var logger = HostEnvironmentInfo.FallbackLogger;

                compilerResults.Errors.Cast <CompilerError>().ToList().ForEach(error => logger.WriteLineError(error.ErrorText));
                return(Array.Empty <BenchmarkRunInfo>());
            }

            var types = compilerResults.CompiledAssembly.GetTypes();

            var resultBenchmarks = new List <BenchmarkRunInfo>();

            foreach (var type in types)
            {
                var runInfo    = TypeToBenchmarks(type, config);
                var benchmarks = runInfo.BenchmarksCases.Select(b =>
                {
                    var target = b.Descriptor;
                    return(BenchmarkCase.Create(
                               new Descriptor(target.Type, target.WorkloadMethod, target.GlobalSetupMethod, target.GlobalCleanupMethod,
                                              target.IterationSetupMethod, target.IterationCleanupMethod,
                                              target.WorkloadMethodDisplayInfo, benchmarkContent, target.Baseline, target.Categories, target.OperationsPerInvoke),
                               b.Job,
                               b.Parameters,
                               b.Config));
                });
                resultBenchmarks.Add(
                    new BenchmarkRunInfo(benchmarks.ToArray(), runInfo.Type, runInfo.Config));
            }

            return(resultBenchmarks.ToArray());
        }
        private static BenchmarkRunInfo MethodsToBenchmarksWithFullConfig(Type containingType, MethodInfo[] benchmarkMethods, ReadOnlyConfig fullConfig)
        {
            if (fullConfig == null)
            {
                throw new ArgumentNullException(nameof(fullConfig));
            }

            var helperMethods = containingType.GetMethods(); // benchmarkMethods can be filtered, without Setups, look #564

            var globalSetupMethods      = GetAttributedMethods <GlobalSetupAttribute>(helperMethods, "GlobalSetup");
            var globalCleanupMethods    = GetAttributedMethods <GlobalCleanupAttribute>(helperMethods, "GlobalCleanup");
            var iterationSetupMethods   = GetAttributedMethods <IterationSetupAttribute>(helperMethods, "IterationSetup");
            var iterationCleanupMethods = GetAttributedMethods <IterationCleanupAttribute>(helperMethods, "IterationCleanup");

            var targetMethods = benchmarkMethods.Where(method => method.HasAttribute <BenchmarkAttribute>()).ToArray();

            var parameterDefinitions   = GetParameterDefinitions(containingType);
            var parameterInstancesList = parameterDefinitions.Expand();

            var rawJobs = fullConfig.GetJobs().ToArray();

            if (rawJobs.IsEmpty())
            {
                rawJobs = new[] { Job.Default }
            }
            ;
            var jobs = rawJobs.Distinct().ToArray();

            var targets = GetTargets(targetMethods, containingType, globalSetupMethods, globalCleanupMethods, iterationSetupMethods, iterationCleanupMethods).ToArray();

            var benchmarks = new List <BenchmarkCase>();

            foreach (var target in targets)
            {
                var argumentsDefinitions = GetArgumentsDefinitions(target.WorkloadMethod, target.Type).ToArray();

                benchmarks.AddRange(
                    from job in jobs
                    from parameterInstance in parameterInstancesList
                    from argumentDefinition in argumentsDefinitions
                    select BenchmarkCase.Create(target, job, new ParameterInstances(parameterInstance.Items.Concat(argumentDefinition.Items).ToArray()))
                    );
            }

            var filters            = fullConfig.GetFilters().ToList();
            var filteredBenchmarks = GetFilteredBenchmarks(benchmarks, filters);

            var orderProvider = fullConfig.GetOrderer() ?? DefaultOrderer.Instance;

            return(new BenchmarkRunInfo(
                       orderProvider.GetExecutionOrder(filteredBenchmarks).ToArray(),
                       containingType,
                       fullConfig));
        }
        private static BenchmarkRunInfo MethodsToBenchmarksWithFullConfig(Type type, MethodInfo[] benchmarkMethods, IConfig config)
        {
            var allPublicMethods = type.GetMethods(); // benchmarkMethods can be filtered, without Setups, look #564
            var configPerType    = GetFullTypeConfig(type, config);

            var globalSetupMethods      = GetAttributedMethods <GlobalSetupAttribute>(allPublicMethods, "GlobalSetup");
            var globalCleanupMethods    = GetAttributedMethods <GlobalCleanupAttribute>(allPublicMethods, "GlobalCleanup");
            var iterationSetupMethods   = GetAttributedMethods <IterationSetupAttribute>(allPublicMethods, "IterationSetup");
            var iterationCleanupMethods = GetAttributedMethods <IterationCleanupAttribute>(allPublicMethods, "IterationCleanup");

            var targets = GetTargets(benchmarkMethods, type, globalSetupMethods, globalCleanupMethods, iterationSetupMethods, iterationCleanupMethods).ToArray();

            var parameterDefinitions   = GetParameterDefinitions(type);
            var parameterInstancesList = parameterDefinitions.Expand(configPerType.SummaryStyle);

            var benchmarks = new List <BenchmarkCase>();

            foreach (var target in targets)
            {
                var argumentsDefinitions = GetArgumentsDefinitions(target.WorkloadMethod, target.Type, configPerType.SummaryStyle).ToArray();

                var parameterInstances =
                    (from parameterInstance in parameterInstancesList
                     from argumentDefinition in argumentsDefinitions
                     select new ParameterInstances(parameterInstance.Items.Concat(argumentDefinition.Items).ToArray())).ToArray();

                var configPerMethod = GetFullMethodConfig(target.WorkloadMethod, configPerType);

                var benchmarksForTarget =
                    from job in configPerMethod.GetJobs()
                    from parameterInstance in parameterInstances
                    select BenchmarkCase.Create(target, job, parameterInstance, configPerMethod);

                benchmarks.AddRange(GetFilteredBenchmarks(benchmarksForTarget, configPerMethod.GetFilters()));
            }

            var orderedBenchmarks = configPerType.Orderer.GetExecutionOrder(benchmarks.ToImmutableArray()).ToArray();

            return(new BenchmarkRunInfo(orderedBenchmarks, type, configPerType));
        }