private UstExprs.Expression VisitTemplateLiteral(TemplateLiteral templateLiteral) { var elems = new Collections.List <INode>(templateLiteral.Expressions.Count + templateLiteral.Quasis.Count); elems.AddRange(templateLiteral.Expressions); elems.AddRange(templateLiteral.Quasis); elems.Sort(NodeLocationComparer.Instance); UstExprs.Expression result = null; for (int i = 0; i < elems.Count; i++) { UstExprs.Expression expr; if (elems[i] is Expression expression) { expr = VisitExpression(expression); } else { expr = VisitTemplateElement((TemplateElement)elems[i]); } var opLiteral = new UstLiterals.BinaryOperatorLiteral(UstTokens.BinaryOperator.Plus, TextSpan.FromBounds(expr.TextSpan.End, expr.TextSpan.End)); result = result == null ? expr : new UstExprs.BinaryOperatorExpression(result, opLiteral, expr, result.TextSpan.Union(expr.TextSpan)); } return(result); }
public ParseTree Parse(TextFile sourceFile, out TimeSpan parserTimeSpan) { if (sourceFile.Data == null) { return(null); } var errorHandler = new JavaScriptEsprimaErrorHandler(sourceFile) { Logger = Logger, Offset = Offset, OriginFile = OriginFile }; try { var parserOptions = new ParserOptions(sourceFile.FullName) { Range = true, Comment = true, Tolerant = true, ErrorHandler = errorHandler }; var parser = new JavaScriptParser(sourceFile.Data, parserOptions); var stopwatch = Stopwatch.StartNew(); Program ast = parser.ParseProgram(JavaScriptType == JavaScriptType.Strict); stopwatch.Stop(); parserTimeSpan = stopwatch.Elapsed; var scanner = new Scanner(sourceFile.Data, parserOptions); errorHandler.Scanner = scanner; errorHandler.Logger = DummyLogger.Instance; // Ignore errors on tokenization because of the first stage var comments = new Collections.List <Comment>(); stopwatch.Restart(); Token token; do { comments.AddRange(scanner.ScanComments()); try { token = scanner.Lex(); } catch (Exception ex) when(!(ex is ThreadAbortException)) { // TODO: handle the end of the stream without exception Logger.LogError(new ParsingException(sourceFile, ex)); break; } }while (token.Type != TokenType.EOF); stopwatch.Stop(); TimeSpan lexerTimeSpan = stopwatch.Elapsed; // TODO: store lexer time // TODO: comments handling without scanner, https://github.com/sebastienros/esprima-dotnet/issues/39 var result = new JavaScriptEsprimaParseTree(ast, comments); result.SourceFile = sourceFile; return(result); } catch (Exception ex) when(!(ex is ThreadAbortException)) { ParsingException exception = ex is ParserException parserException ? errorHandler.CreateException(parserException.Index, parserException.Message) : ex is ParsingException parsingException ? parsingException : new ParsingException(sourceFile, ex); Logger.LogError(exception); return(null); } }