public static Dictionary <string, BooScriptAssembly> SerialCompile(IEnumerable <BooScriptAssemblyConfig> scriptConfigs, IEnumerable <Assembly> references, IEnumerable <string> imports = null, IEnumerable <EnsuredMethodSignature> ensuredMethodSignatures = null)
        {
            var assemblies = new Dictionary <string, BooScriptAssembly>();
            var configs    = new Dictionary <string, BooScriptAssemblyConfig>();
            var bc         = new BlockingCollection <CompilerContext>();

            foreach (var cfg in scriptConfigs)
            {
                if (!configs.ContainsKey(cfg.AssemblyName))
                {
                    configs.Add(cfg.AssemblyName, cfg);
                }
                else
                {
                    //duplicate found
                    Console.WriteLine($"Skipping build of duplicate Assembly, '{cfg.AssemblyName}'");
                }
            }

            //compiles scripts into assemblies, using n tasks/threads.
            foreach (var kvp in configs)
            {
                var cfg            = kvp.Value;
                var buildTime      = DateTime.Now;
                var context        = Compile(cfg.AssemblyName, cfg.FileNames, references, imports, ensuredMethodSignatures);
                var scriptAssembly = new BooScriptAssembly(buildTime, context);

                assemblies.Add(cfg.AssemblyName, scriptAssembly);

                if (context.Errors.Count > 0)
                {
                    foreach (var err in context.Errors)
                    {
                        Console.WriteLine($"Error: {err.LexicalInfo.FullPath} {err.LexicalInfo.Line},{err.LexicalInfo.Column} {err.Message}");
                    }
                }
                else if (context.Warnings.Count > 0)
                {
                    foreach (var war in context.Warnings)
                    {
                        Console.WriteLine($"Warning: {war.LexicalInfo.FullPath} {war.LexicalInfo.Line},{war.LexicalInfo.Column} {war.Message}");
                    }
                }
            }

            return(assemblies);
        }
        public static Dictionary <string, BooScriptAssembly> ParallelCompile(IEnumerable <BooScriptAssemblyConfig> scriptConfigs, IEnumerable <Assembly> references, IEnumerable <string> imports = null, IEnumerable <EnsuredMethodSignature> ensuredMethodSignatures = null)
        {
            var assemblies = new ConcurrentDictionary <string, BooScriptAssembly>();
            var configs    = new Dictionary <string, BooScriptAssemblyConfig>();
            var bc         = new BlockingCollection <CompilerContext>();

            foreach (var cfg in scriptConfigs)
            {
                if (!configs.ContainsKey(cfg.AssemblyName))
                {
                    configs.Add(cfg.AssemblyName, cfg);
                }
                else
                {
                    //duplicate found
                    Console.WriteLine($"Skipping build of duplicate Assembly, '{cfg.AssemblyName}'");
                }
            }

            //compiles scripts into assemblies, using n tasks/threads.
            var compileTask = Task.Factory.StartNew(() =>
            {
                var result = Parallel.ForEach(configs.Values, cfg =>
                {
                    var buildTime      = DateTime.Now;
                    var context        = Compile(cfg.AssemblyName, cfg.FileNames, references, imports, ensuredMethodSignatures);
                    var scriptAssembly = new BooScriptAssembly(buildTime, context);

                    assemblies.TryAdd(cfg.AssemblyName, scriptAssembly);

                    bc.Add(context);
                });

                bc.CompleteAdding();
            });

            //consumes contexts, and writes out errors or warnings..
            var reportTask = Task.Factory.StartNew(() =>
            {
                try
                {
                    Debug.WriteLine($"Starting reporting...");

                    while (true)
                    {
                        var context = bc.Take();

                        if (context.Errors.Count > 0)
                        {
                            foreach (var err in context.Errors)
                            {
                                Console.WriteLine($"Error: {err.LexicalInfo.FullPath} {err.LexicalInfo.Line},{err.LexicalInfo.Column} {err.Message}");
                            }
                        }
                        else if (context.Warnings.Count > 0)
                        {
                            foreach (var war in context.Warnings)
                            {
                                Console.WriteLine($"Warning: {war.LexicalInfo.FullPath} {war.LexicalInfo.Line},{war.LexicalInfo.Column} {war.Message}");
                            }
                        }
                    }
                }
                catch (InvalidOperationException ioex)
                {
                    //end
                    Debug.WriteLine($"BlockingCollection threw InvalidOperationException. ( Probably completed. )");
                }
                catch (Exception ex)
                {
                    Debug.WriteLine($"BlockingCollection threw exception; {ex.Message}");
                }
            });

            Task.WaitAll(reportTask, compileTask);

            //Task.WaitAll(compileTask);

            return(new Dictionary <string, BooScriptAssembly>(assemblies));
        }
Example #3
0
 //HACK - work around an api design wart. BooScriptAssembly.Build() expecs a Func with a BooScriptAssembly instance, but we also want a standalone instance method for our own use...
 internal static CompilerContext Compile(BooScriptAssembly scriptAssembly)
 {
     return(((Script)scriptAssembly).Compile());
 }