ParseTestCore( ParserTestData testData) { string outAst; var outMinJs = string.Empty; var outMinJsMap = string.Empty; var outNiceJs = string.Empty; var outNiceJsMap = string.Empty; try { var comments = new List <(bool block, string content, SourceLocation location)>(); var commentListener = new CommentListener(); var parser = new Parser( new() { SourceFile = testData.SourceName, EcmaVersion = testData.EcmaScriptVersion, OnComment = (block, content, location) => { commentListener.OnComment(block, content, location); comments.Add((block, content, location)); }, SourceType = testData.SourceName.StartsWith("module-") ? SourceType.Module : SourceType.Script }, testData.Input); var toplevel = parser.Parse(); commentListener.Walk(toplevel); SourceMap?inputSourceMap = null; if (testData.InputSourceMap != null) { inputSourceMap = SourceMap.Parse(testData.InputSourceMap, "."); inputSourceMap.ResolveInAst(toplevel); } var strSink = new StringLineSink(); toplevel.FigureOutScope(); var dumper = new DumpAst(new AstDumpWriter(strSink)); dumper.Walk(toplevel); foreach (var(block, content, location) in comments) { strSink.Print( $"{(block ? "Block" : "Line")} Comment ({location.Start.ToShortString()}-{location.End.ToShortString()}): {content}"); } outAst = strSink.ToString(); var outMinJsBuilder = new SourceMapBuilder(); var outputOptions = new OutputOptions { Shorthand = testData.EcmaScriptVersion >= 6 }; toplevel.PrintToBuilder(outMinJsBuilder, outputOptions); outMinJsBuilder.AddText( $"//# sourceMappingURL={PathUtils.ChangeExtension(testData.SourceName, "minjs.map")}"); if (inputSourceMap != null) { outMinJsBuilder.AttachSourcesContent(inputSourceMap); } outMinJs = outMinJsBuilder.Content(); outMinJsMap = outMinJsBuilder.Build(".", ".").ToString(); var outNiceJsBuilder = new SourceMapBuilder(); outputOptions = new() { Beautify = true, Shorthand = testData.EcmaScriptVersion >= 6 }; toplevel.PrintToBuilder(outNiceJsBuilder, outputOptions); outNiceJsBuilder.AddText( $"//# sourceMappingURL={PathUtils.ChangeExtension(testData.SourceName, "nicejs.map")}"); if (inputSourceMap != null) { outNiceJsBuilder.AttachSourcesContent(inputSourceMap); } outNiceJs = outNiceJsBuilder.Content(); outNiceJsMap = outNiceJsBuilder.Build(".", ".").ToString(); strSink = new StringLineSink(); toplevel.FigureOutScope(); dumper = new DumpAst(new AstDumpWriter(strSink)); dumper.Walk(toplevel); var beforeClone = strSink.ToString(); toplevel = toplevel.DeepClone(); strSink = new StringLineSink(); toplevel.FigureOutScope(); dumper = new DumpAst(new AstDumpWriter(strSink)); dumper.Walk(toplevel); var afterClone = strSink.ToString(); if (beforeClone != afterClone) { throw new Exception("Dump of clone is not identical"); } toplevel.Mangle(); } catch (SyntaxError e) { outAst = e.Message; } return(outAst, outMinJs, outMinJsMap, outNiceJs, outNiceJsMap); }