static string createRewriter(string file, Script script) { ANTLRFileStream stream = new ANTLRFileStream(file); SourceExprLexer lex = new SourceExprLexer(stream); // create a buffer of tokens pulled from the lexer // Must use TokenRewriteStream not CommonTokenStream! TokenRewriteStream tokens = new TokenRewriteStream(lex); SourceExprParser parser = new SourceExprParser(tokens); SourceExprParser.prog_return r = parser.prog(script); // WALK TREE AND REWRITE TOKEN BUFFER CommonTree t = (CommonTree)r.Tree; // get tree from parser // create a stream of tree nodes from AST built by parser CommonTreeNodeStream nodes = new CommonTreeNodeStream(t); // tell it where it can find the token objects nodes.TokenStream = tokens; //SourceRewrite rewriter = new SourceRewrite(nodes); //rewriter.prog(script); return tokens.ToString(); // return tweaked token buffer }
public virtual void Instrument(StreamReader inputStream, string inputFilename, StreamWriter outputStream) { var testTemplate = LoadStringTemplateGroup(); var inputPath = Path.GetFullPath(inputFilename); var inputFile = Path.GetFileName(inputFilename); //get headerTemplate for file header var headerTemplate = testTemplate.GetInstanceOf("file_header"); headerTemplate.SetAttribute("src", inputFile); headerTemplate.SetAttribute("path", inputPath.Replace("\\", "\\\\")); //read lines for later usage var codeLines = new StringBuilder(); var code = new StringBuilder(); codeLines.Append("_yuitest_coverage[\""); codeLines.Append(inputFile); codeLines.Append("\"].code=["); string line; while ((line = inputStream.ReadLine()) != null) { //build up array of lines codeLines.Append("\""); codeLines.Append(line.Replace(@"\", @"\\").Replace("\"", "\\\"")); codeLines.Append("\","); //build up source code code.AppendLine(line); } var index = codeLines.Length - 1; switch (codeLines[index]) { case ',': //if there's a dangling comma, replace it codeLines.Remove(index, 1); codeLines.Insert(index, ']'); break; case '[': //empty file codeLines.Append("]"); break; //no default } codeLines.Append(";"); //output full path //setup parser var antlrStream = new ANTLRReaderStream(new StringReader(code.ToString())); var lexer = new ES3YUITestLexer(antlrStream); var tokens = new TokenRewriteStream(lexer); var parser = new ES3YUITestParser(tokens) { TemplateGroup = testTemplate, SourceFileName = inputFile }; var result = string.Empty; //an empty string will cause the parser to explode if (code.ToString().Trim().Length > 0) { parser.program(); result = tokens.ToString(); } //output the resulting file outputStream.Write(headerTemplate.ToString()); outputStream.WriteLine(); outputStream.Write(codeLines.ToString()); outputStream.WriteLine(); outputStream.Write(result); outputStream.Flush(); }
private IModule Resolve(IEnumerable<string> idSegments) { var normalizedId = string.Join("/", idSegments); var subFolders = idSegments.Take(idSegments.Count() - 1); if (this.config.Shims != null && this.config.Shims.ContainsKey(normalizedId)) { return this.ResolveShimModule(subFolders, this.config.Shims[normalizedId]); } var filePath = this.GetModuleFileName(idSegments); if (!this.fileSystem.FileExists(filePath)) { var module = new Module { Id = normalizedId, Dependencies = Enumerable.Empty<IModule>() }; this.repository.Add(module); return module; } using (var stream = this.fileSystem.Open(filePath, FileMode.Open)) { var charStream = new ANTLRInputStream(stream); var lexer = new JavaScriptLexer(charStream); var tokenStream = new TokenRewriteStream(lexer); var parser = new JavaScriptParser(tokenStream); var program = parser.program().Tree as Program; var dependencies = new List<IModule>(); var moduleDef = ( from callExpression in program.Children.OfType<CallExpression>() where callExpression.Function.Text == "define" select callExpression ).SingleOrDefault(); if (moduleDef != null) { var argsToProcess = new List<Expression>(moduleDef.Arguments); if (argsToProcess.Count == 0) { throw new InvalidModuleException( normalizedId, "Module definition is empty."); } else if (argsToProcess.Count > 3) { throw new InvalidModuleException( normalizedId, "Module definition contains unexpected extra arguments."); } var factory = argsToProcess.Last(); argsToProcess.Remove(factory); var depsArray = argsToProcess.LastOrDefault() as ArrayLiteral; if (depsArray == null) { tokenStream.InsertBefore(factory.Token, "[], "); } else { foreach (var arrayItem in depsArray.Items) { if (arrayItem is StringLiteral) { var dependencyName = jsSerializer.Deserialize<string>(arrayItem.Text); var dependency = this.Resolve( subFolders, dependencyName); dependencies.Add(dependency); tokenStream.Replace( (arrayItem as StringLiteral).Token.TokenIndex, string.Format("'{0}'", dependency.Id)); } } argsToProcess.Remove(depsArray); } var idLiteral = argsToProcess.LastOrDefault() as StringLiteral; if (idLiteral == null) { tokenStream.InsertAfter( moduleDef.ArgumentList.Token, string.Format("'{0}', ", normalizedId)); } else { var definedName = jsSerializer.Deserialize<string>(idLiteral.Text); if (definedName != normalizedId) { throw new InvalidModuleException( normalizedId, string.Format( "Module name '{0}' does not match expected value '{1}'. Anonymous modules are recommended.", definedName, normalizedId)); } } } var module = new Module { Id = normalizedId, Content = tokenStream.ToString(), Dependencies = dependencies }; this.repository.Add(module); return module; } }