internal static bool Compile(string currentDir, string inputFile, string outputFile, Context context, bool minify, bool warnAsErrors, bool autoCacheBreak, bool autoPrefix) { var opts = Options.None; var writerMode = WriterMode.Pretty; if (minify) { opts |= Options.Minify; writerMode = WriterMode.Minimize; } if (warnAsErrors) { opts |= Options.WarningsAsErrors; } if (autoCacheBreak) { opts |= Options.GenerateCacheBreakers; } if (autoPrefix) { opts |= Options.AutomateVendorPrefixes; } return Compiler.Get().Compile(currentDir, inputFile, outputFile, FileLookup.Singleton, context, opts, writerMode); }
private string TryCompile(string text, IFileLookup lookup = null, bool reset = true) { Context context; Options opts; WriterMode mode; if (reset) { context = new Context(new FileCache()); opts = Options.None; mode = WriterMode.Minimize; } else { context = Current.InnerContext.Value; opts = Current.Options; mode = Current.WriterMode; } var fakeFile = "error-fake-file" + Interlocked.Increment(ref TryCompileNumber) + ".more"; var fileLookup = new TestLookup(new Dictionary<string, string>() { { fakeFile, text } }, lookup); var compiler = Compiler.Get(); compiler.Compile(Environment.CurrentDirectory, fakeFile, fakeFile + ".out", fileLookup, context, opts, mode); return fileLookup.WriteMap.ElementAt(0).Value; }
private string TryCompile(string text, string fakeFile = null, IFileLookup lookup = null, bool minify = false, WriterMode mode = WriterMode.Minimize, bool cacheBreak = false, bool prefix = false) { if (mode == WriterMode.Minimize) { try { TryCompile(text, null, lookup, minify, WriterMode.Pretty); } catch (Exception e) { Assert.Fail("Pretty writing failed"); } } fakeFile = fakeFile ?? "compiler-fake-file " + Interlocked.Increment(ref TryCompileNumber) + ".more"; Options opts = Options.None; if (minify) { opts |= Options.Minify; } if (cacheBreak) { opts |= Options.GenerateCacheBreakers; } if (prefix) { opts |= Options.AutomateVendorPrefixes; } var fileLookup = new TestLookup(new Dictionary<string, string>() { { fakeFile, text } }, lookup); var compiler = Compiler.Get(); var ctx = new Context(new FileCache()); // it's hard to test minification steps if they all always run, so let's just go for a single pass in the "text comparison" cases // still do the full thing when we're doing our test "pretty pass" elsewhere to make sure it always terminates ctx.DisableMultipleMinificationPasses = mode != WriterMode.Pretty; compiler.Compile(Environment.CurrentDirectory, fakeFile, fakeFile + ".out", fileLookup, ctx, opts, mode); var ret = fileLookup.WriteMap.ElementAt(0).Value; return ret; }
public void MergeContexts() { var a = new Context(new FileCache()); var b = new Context(new FileCache()); a.Errors[ErrorType.Compiler] = new List<Error>() { Error.Create(ErrorType.Compiler, -1, -1, "test error", "dummy file 1") }; a.Errors[ErrorType.Parser] = new List<Error>() { Error.Create(ErrorType.Parser, -1, -1, "test error", "dummy file 1") }; a.Warnings[ErrorType.Parser] = new List<Error>() { Error.Create(ErrorType.Parser, -1, -1, "test error", "dummy file 1"), Error.Create(ErrorType.Compiler, -1, -1, "test error", "dummy file 3") }; a.Warnings[ErrorType.Compiler] = new List<Error>() { Error.Create(ErrorType.Compiler, -1, -1, "test error", "dummy file 1") }; b.Errors[ErrorType.Compiler] = new List<Error>() { Error.Create(ErrorType.Compiler, -1, -1, "test error", "dummy file 2") }; b.Errors[ErrorType.Parser] = new List<Error>() { Error.Create(ErrorType.Parser, -1, -1, "test error", "dummy file 2") }; b.Warnings[ErrorType.Parser] = new List<Error>() { Error.Create(ErrorType.Parser, -1, -1, "test error", "dummy file 2"), Error.Create(ErrorType.Compiler, -1, -1, "test error", "dummy file 3") }; b.Warnings[ErrorType.Compiler] = new List<Error>() { Error.Create(ErrorType.Compiler, -1, -1, "test error", "dummy file 2") }; var c = a.Merge(b); Assert.AreEqual(2, c.Errors.Count); Assert.AreEqual(2, c.Warnings.Count); Assert.AreEqual(2, c.GetErrors()[ErrorType.Compiler].Count()); Assert.AreEqual(2, c.GetErrors()[ErrorType.Parser].Count()); Assert.AreEqual(2, c.GetWarnings()[ErrorType.Parser].Count()); Assert.AreEqual(4, c.GetWarnings()[ErrorType.Compiler].Count()); }
static bool MultiThreadedCompile(int maxParallelism, string workingDirectory, List<string> toCompile, bool overwrite, bool warnAsErrors, bool minify, bool verbose, string spriteProg, string spriteArguments, bool autoCacheBreak, bool autoPrefix, out DependencyGraph dependencies) { var @lock = new Semaphore(0, toCompile.Count); var contexts = new ConcurrentBag<Context>(); var outMsg = new ConcurrentBag<string>(); toCompile.AsParallel() .WithDegreeOfParallelism(maxParallelism) .WithExecutionMode(ParallelExecutionMode.ForceParallelism) .ForAll( delegate(string compile) { try { var threadContext = new Context(FileCache); contexts.Add(threadContext); var buffer = new StringBuilder(); var outputFile = OutputFileFor(compile, overwrite: overwrite); buffer.AppendLine("\t" + compile); buffer.Append("\tto " + outputFile); var timer = new Stopwatch(); timer.Start(); var result = Compile(workingDirectory, compile, outputFile, threadContext, minify, warnAsErrors, autoCacheBreak, autoPrefix); timer.Stop(); if (result) { buffer.AppendLine(" in " + timer.ElapsedMilliseconds + "ms"); } else { buffer.AppendLine(" failed after " + timer.ElapsedMilliseconds + "ms"); } outMsg.Add(buffer.ToString()); } finally { @lock.Release(); } } ); for (int i = 0; i < toCompile.Count; i++) @lock.WaitOne(); var mergedContext = contexts.ElementAt(0); for (int i = 1; i < contexts.Count; i++) { mergedContext = mergedContext.Merge(contexts.ElementAt(i)); } dependencies = mergedContext.Dependecies; var infoMessages = mergedContext.GetInfoMessages().ToList(); var errors = mergedContext.GetErrors(); if (spriteProg.HasValue()) { foreach (var sprite in mergedContext.GetSpriteFiles()) { var commandErrors = RunSpriteCommand(spriteProg, workingDirectory, sprite, spriteArguments, infoMessages); errors = errors.SelectMany(s => s.ToList()).Union(commandErrors).ToLookup(k => k.Type); } } if (verbose) { foreach (var msg in outMsg) { Console.Write(msg); } if (outMsg.Count > 0) Console.WriteLine(); } if (errors.Count > 0) { var parseErrors = errors.Where(e => e.Key == ErrorType.Parser).SelectMany(s => s.ToList()).Distinct().ToList(); var compileErrors = errors.Where(e => e.Key == ErrorType.Compiler).SelectMany(s => s.ToList()).Distinct().ToList(); Print("Errors", parseErrors, compileErrors); } if (mergedContext.GetWarnings().Count > 0) { var parseWarnings = mergedContext.GetWarnings().Where(e => e.Key == ErrorType.Parser).SelectMany(s => s.ToList()).Distinct().ToList(); var compileWarnings = mergedContext.GetWarnings().Where(e => e.Key == ErrorType.Compiler).SelectMany(s => s.ToList()).Distinct().ToList(); Print("Warnings", parseWarnings, compileWarnings); } if (verbose && infoMessages.Count > 0) { Console.WriteLine("INFO"); Console.WriteLine("===="); foreach (var i in infoMessages) { Console.WriteLine(i); } } return mergedContext.GetErrors().Count == 0; }
public static void SetContext(Context context) { InnerContext.Value = context; }
public Context Merge(Context other) { if (this.Options != other.Options || this.WriterMode != other.WriterMode) { throw new InvalidOperationException(); } var errors = this.Errors.ToDictionary(d => d.Key, d => d.Value.ToList()); foreach (var k in other.Errors.Keys) { if (errors.ContainsKey(k)) { errors[k].AddRange(other.Errors[k]); } else { errors[k] = other.Errors[k].ToList(); } } var warnings = this.Warnings.ToDictionary(d => d.Key, d => d.Value.ToList()); foreach (var k in other.Warnings.Keys) { if (warnings.ContainsKey(k)) { warnings[k].AddRange(other.Warnings[k]); } else { warnings[k] = other.Warnings[k].ToList(); } } var infos = this.GetInfoMessages().ToList(); infos.AddRange(other.GetInfoMessages()); // Dupes should be removed here, thus Union() var sprites = this.GetSpriteFiles().Union(other.GetSpriteFiles()).ToList(); var ret = new Context(this.FileCache); ret.Errors = errors; ret.Warnings = warnings; ret.InfoMessages = infos; ret.SpriteFiles = sprites; ret.Options = this.Options; ret.WriterMode = this.WriterMode; return ret; }