public TextReader Find(string name) { if (InnerLookup != null && !ReadMap.Any(x => name.EndsWith(x.Key))) { return(InnerLookup.Find(name)); } return(new StringReader(ReadMap.Single(x => name.EndsWith(x.Key)).Value)); }
public bool Compile(string currentDir, string inputFile, string outputFile, IFileLookup lookup, Context context, Options options, WriterMode writerMode) { Current.SetContext(context); Current.SetWriterMode(writerMode); Current.SetOptions(options); CompilationTask noop = (List <Block> blocks) => blocks; var tasks = new List <CompilationTask>() { Tasks.Using.Task, References.Task, Charsets.Task, Tasks.Import.Task, Reset.Task, Sprite.Task, Mixin.Task, UnrollNestedMedia.Task, UnrollNestedSelectors.Task, UnrollVerify.Task, Tasks.Media.Task, Includes.Task, ResetIncludes.Task, Evaluate.Task, Important.Task, NoOps.Task, FontFace.Task, ResetReOrder.Task, Verify.Task, Current.Options.HasFlag(Options.Minify) ? Minify.Task : noop, Collapse.Task, WriteSprites.Task, Current.Options.HasFlag(Options.GenerateCacheBreakers) ? CacheBreak.Task : noop, Current.Options.HasFlag(Options.AutomateVendorPrefixes) ? AutoPrefix.Task : noop, Write.Task }; try { Current.SetWorkingDirectory(currentDir); Current.SetFileLookup(lookup); inputFile = Path.IsPathRooted(inputFile) ? inputFile : inputFile.RebaseFile(); Current.SetInitialFile(inputFile); List <Block> blocks; using (var stream = lookup.Find(inputFile)) { blocks = Parse.Task(stream); } using (var output = lookup.OpenWrite(outputFile)) { Current.SetOutputStream(output); if (blocks == null) { return(false); } foreach (var task in tasks) { blocks = task(blocks); if (Current.HasErrors()) { return(false); } } } Current.Dependecies.FileCompiled(inputFile, blocks); return(true); } catch (StoppedCompilingException) { return(false); } }
public bool Compile(string currentDir, string inputFile, string outputFile, IFileLookup lookup, Context context, Options options, WriterMode writerMode) { Current.SetContext(context); Current.SetWriterMode(writerMode); Current.SetOptions(options); CompilationTask noop = (List<Block> blocks) => blocks; var tasks = new List<CompilationTask>() { Tasks.Using.Task, References.Task, Charsets.Task, Tasks.Import.Task, Reset.Task, Sprite.Task, Mixin.Task, Unroll.Task, Tasks.Media.Task, Includes.Task, ResetIncludes.Task, Evaluate.Task, Important.Task, NoOps.Task, FontFace.Task, ResetReOrder.Task, Verify.Task, Current.Options.HasFlag(Options.Minify) ? Minify.Task : noop, Collapse.Task, Write.Task, WriteSprites.Task }; try { Current.SetWorkingDirectory(currentDir); Current.SetFileLookup(lookup); inputFile = inputFile.RebaseFile(); Current.SetInitialFile(inputFile); List<Block> blocks; using (var stream = lookup.Find(inputFile)) { blocks = Parse.Task(stream); } using (var output = lookup.OpenWrite(outputFile)) { Current.SetOutputStream(output); if (blocks == null) return false; foreach (var task in tasks) { blocks = task(blocks); if (Current.HasErrors()) return false; } } return true; } catch (StoppedCompilingException) { return false; } }
private static List <Block> EvaluateUsingsImpl(string initialFile, List <Block> initialStatements, IFileLookup lookup) { var imports = new List <Tuple <Model.Using, List <Block> > >(); imports.Add(Tuple.Create((Model.Using)null, initialStatements)); var unresolved = new List <Tuple <string, Model.Using> >(); unresolved.AddRange( initialStatements.OfType <Model.Using>().Select( u => Tuple.Create( u.RawPath.Replace('/', Path.DirectorySeparatorChar).RebaseFile(initialFile), u ) ) ); while (unresolved.Count > 0) { var allFiles = unresolved.Select(s => s.Item1); var loaded = Current.FileCache.Available( allFiles, delegate(string file) { var toResolve = unresolved.Single(w => w.Item1 == file); using (var @in = lookup.Find(file)) { var newParser = Parser.Parser.CreateParser(); var statements = Parse.CheckPostImport(newParser.Parse(file, @in)); if (statements == null) { Current.RecordError(ErrorType.Compiler, toResolve.Item2, "Could not resolve @using '" + toResolve.Item2.RawPath + "'"); return(null); } return(statements); } } ); var @using = unresolved.Single(s => s.Item1 == loaded.Item1); imports.Add(Tuple.Create(@using.Item2, loaded.Item2)); unresolved.RemoveAll(a => a.Item1 == loaded.Item1); if (loaded.Item2 != null) { var references = loaded.Item2.OfType <Model.Using>().Where(a => !imports.Any(x => x.Item1 == a)); foreach (var subRef in references) { unresolved.Add( Tuple.Create( subRef.RawPath.Replace('/', Path.DirectorySeparatorChar).RebaseFile(loaded.Item1), subRef ) ); } } } // Can't nest @media via @using foreach (var loaded in imports) { if (loaded.Item1 == null || (loaded.Item1.MediaQuery is MediaType && ((MediaType)loaded.Item1.MediaQuery).Type == Model.Media.all)) { continue; } if (loaded.Item2.OfType <MediaBlock>().Count() != 0) { Current.RecordError(ErrorType.Compiler, loaded.Item1, "Cannot nest @media rules via @imports"); } } // Can't continue if there's goofy nesting going on if (Current.HasErrors()) { throw new StoppedCompilingException(); } var ret = new List <Block>(); foreach (var loaded in imports.Where(w => w.Item1 == null || (w.Item1.MediaQuery is MediaType && ((MediaType)w.Item1.MediaQuery).Type == Model.Media.all))) { ret.AddRange(loaded.Item2); } foreach (var loaded in imports.Where(w => w.Item1 != null && !(w.Item1.MediaQuery is MediaType && ((MediaType)w.Item1.MediaQuery).Type == Model.Media.all))) { var statements = loaded.Item2; ret.AddRange(statements.OfType <MixinBlock>()); ret.AddRange(statements.OfType <KeyFramesBlock>()); ret.AddRange(statements.OfType <FontFaceBlock>()); var inner = statements.Where(w => !(w is MixinBlock || w is KeyFramesBlock || w is FontFaceBlock)); ret.Add(new MediaBlock(loaded.Item1.MediaQuery, inner.ToList(), loaded.Item1.Start, loaded.Item1.Stop, loaded.Item1.FilePath)); } // Record dependencies initialStatements .OfType <Model.Using>() .Each( u => Current.Dependecies.UsingResolved(initialFile, u.RawPath) ); return(ret); }
private static List<Block> EvaluateUsingsImpl(string initialFile, List<Block> initialStatements, IFileLookup lookup) { var imports = new List<Tuple<Model.Using, List<Block>>>(); imports.Add(Tuple.Create((Model.Using)null, initialStatements)); var unresolved = new List<Tuple<string, Model.Using>>(); unresolved.AddRange( initialStatements.OfType<Model.Using>().Select( u => Tuple.Create( u.RawPath.Replace('/', Path.DirectorySeparatorChar).RebaseFile(initialFile), u ) ) ); while (unresolved.Count > 0) { var allFiles = unresolved.Select(s => s.Item1); var loaded = Current.FileCache.Available( allFiles, delegate(string file) { var toResolve = unresolved.Single(w => w.Item1 == file); using (var @in = lookup.Find(file)) { var newParser = Parser.Parser.CreateParser(); var statements = Parse.CheckPostImport(newParser.Parse(file, @in)); if (statements == null) { Current.RecordError(ErrorType.Compiler, toResolve.Item2, "Could not resolve @using '" + toResolve.Item2.RawPath + "'"); return null; } return statements; } } ); var @using = unresolved.Single(s => s.Item1 == loaded.Item1); imports.Add(Tuple.Create(@using.Item2, loaded.Item2)); unresolved.RemoveAll(a => a.Item1 == loaded.Item1); if (loaded.Item2 != null) { var references = loaded.Item2.OfType<Model.Using>().Where(a => !imports.Any(x => x.Item1 == a)); foreach(var subRef in references) { unresolved.Add( Tuple.Create( subRef.RawPath.Replace('/', Path.DirectorySeparatorChar).RebaseFile(loaded.Item1), subRef ) ); } } } // Can't nest @media via @using foreach (var loaded in imports) { if (loaded.Item1 == null || (loaded.Item1.MediaQuery is MediaType && ((MediaType)loaded.Item1.MediaQuery).Type == Model.Media.all)) continue; if (loaded.Item2.OfType<MediaBlock>().Count() != 0) { Current.RecordError(ErrorType.Compiler, loaded.Item1, "Cannot nest @media rules via @imports"); } } // Can't continue if there's goofy nesting going on if (Current.HasErrors()) throw new StoppedCompilingException(); var ret = new List<Block>(); foreach (var loaded in imports.Where(w => w.Item1 == null || (w.Item1.MediaQuery is MediaType && ((MediaType)w.Item1.MediaQuery).Type == Model.Media.all))) { ret.AddRange(loaded.Item2); } foreach (var loaded in imports.Where(w => w.Item1 != null && !(w.Item1.MediaQuery is MediaType && ((MediaType)w.Item1.MediaQuery).Type == Model.Media.all))) { var statements = loaded.Item2; ret.AddRange(statements.OfType<MixinBlock>()); ret.AddRange(statements.OfType<KeyFramesBlock>()); ret.AddRange(statements.OfType<FontFaceBlock>()); var inner = statements.Where(w => !(w is MixinBlock || w is KeyFramesBlock || w is FontFaceBlock)); ret.Add(new MediaBlock(loaded.Item1.MediaQuery, inner.ToList(), loaded.Item1.Start, loaded.Item1.Stop, loaded.Item1.FilePath)); } // Record dependencies initialStatements .OfType<Model.Using>() .Each( u => Current.Dependecies.UsingResolved(initialFile, u.RawPath) ); return ret; }