public void writeFile(string fileName, string data) { if (fileName.EndsWith(".js.map")) { var relativeTo = PathUtils.Parent(PathUtils.Join(_owner.Owner.FullPath, fileName)); var sourceMap = SourceMap.Parse(data, relativeTo); var sourceFullPath = sourceMap.sources[0]; var sourceForMap = _result.Path2FileInfo[sourceFullPath]; sourceForMap.MapLink = sourceMap; return; } if (!fileName.StartsWith("_virtual/")) { throw new Exception("writeFile does not start with _virtual"); } var fullPathWithVirtual = PathUtils.Join(_owner.ProjectOptions.CurrentBuildCommonSourceDirectory, fileName); fileName = fileName.Substring(9); var fullPath = PathUtils.Join(_owner.ProjectOptions.CurrentBuildCommonSourceDirectory, fileName); if (fileName.EndsWith(".json")) { _result.Path2FileInfo.TryGetValue(fullPath, out var sourceForJs); _result.RecompiledLast.Add(sourceForJs); return; } if (fullPath.EndsWith(".js")) { OutputedJsFiles++; data = SourceMap.RemoveLinkToSourceMap(data); var sourceName = fullPath.Substring(0, fullPath.Length - ".js".Length) + ".ts"; TSFileAdditionalInfo sourceForJs = null; if (!_result.Path2FileInfo.TryGetValue(sourceName, out sourceForJs)) { _result.Path2FileInfo.TryGetValue(sourceName + "x", out sourceForJs); } if (sourceForJs == null) { if (!_result.Path2FileInfo.TryGetValue(fullPath, out sourceForJs)) { _result.Path2FileInfo.TryGetValue(fullPath + "x", out sourceForJs); } } sourceForJs.Output = data; _result.RecompiledLast.Add(sourceForJs); return; } if (!fullPath.EndsWith(".d.ts")) { throw new Exception("Unknown extension written by TS " + fullPath); } OutputedDtsFiles++; data = new Regex("\\/\\/\\/ *<reference path=\\\"(.+)\\\" *\\/>").Replace(data, (m) => { var origPath = m.Groups[1].Value; var newPath = PathUtils.Subtract(PathUtils.Join(PathUtils.Parent(fullPathWithVirtual), origPath), PathUtils.Parent(fullPath)); return("/// <reference path=\"" + newPath + "\" />"); }); var dirPath = PathUtils.Parent(fullPath); var fileOnly = fullPath.Substring(dirPath.Length + 1); var dc = _owner.DiskCache.TryGetItem(dirPath) as IDirectoryCache; var wasChange = dc.WriteVirtualFile(fileOnly, data); var output = dc.TryGetChild(fileOnly) as IFileCache; var outputInfo = TSFileAdditionalInfo.Get(output, _owner.DiskCache); var sourceName2 = fullPath.Substring(0, fullPath.Length - ".d.ts".Length) + ".ts"; TSFileAdditionalInfo source = null; if (!_result.Path2FileInfo.TryGetValue(sourceName2, out source)) { _result.Path2FileInfo.TryGetValue(sourceName2 + "x", out source); } source.DtsLink = outputInfo; outputInfo.MyProject = source.MyProject; if (wasChange) { ChangedDts = true; } }
public static Dictionary <string, string> BobrilSourceInfoTestCore(BobrilSourceInfoTestData testData) { var output = new Dictionary <string, string>(); var source = SourceMap.RemoveLinkToSourceMap(testData.InputContent["index.js"]); var toplevel = Parser.Parse(source); toplevel.FigureOutScope(); var files = new InMemoryImportResolver(); var ctx = new ResolvingConstEvalCtx("index.js", files); var sourceInfo = GatherBobrilSourceInfo.Gather(toplevel, ctx, (myctx, text) => { if (text.StartsWith('.')) { return(PathUtils.Join(PathUtils.Parent(myctx.SourceName), text)); } return(text); }); var builder = new SourceMapBuilder(); var adder = builder.CreateSourceAdder(source, testData.InputContent.ContainsKey("index.js.map") ? SourceMap.Parse(testData.InputContent["index.js.map"], ".") : null); var sourceReplacer = new SourceReplacer(); ProcessReplacements(sourceReplacer, sourceInfo); sourceReplacer.Apply(adder); builder.AddText("//# sourceMappingURL=index.js.map"); output["index.sourceinfo.json"] = JsonSerializer .Serialize(sourceInfo, new JsonSerializerOptions { WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull }) .Replace("\r\n", "\n"); output["index.js"] = builder.Content(); output["index.js.map"] = builder.Build(".", "..").ToString(); if (testData.InputContent.ContainsKey("index.js.map")) { SourceMap.Parse(testData.InputContent["index.js.map"], ".").ResolveInAst(toplevel); } var coverageInstrumentation = new CoverageInstrumentation(); toplevel = coverageInstrumentation.Instrument(toplevel); coverageInstrumentation.AddCountingHelpers(toplevel); coverageInstrumentation.CleanUp(new TestUtf8Reader(testData.InputContent)); builder = new SourceMapBuilder(); toplevel.PrintToBuilder(builder, new OutputOptions { Beautify = true }); builder.AddText("//# sourceMappingURL=cov.js.map"); output["cov.info.json"] = JsonSerializer .Serialize(coverageInstrumentation.InstrumentedFiles, new JsonSerializerOptions { WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull }) .Replace("\r\n", "\n"); output["cov.js"] = builder.Content(); output["cov.js.map"] = builder.Build(".", "..").ToString(); return(output); }
void Transpile(TSFileAdditionalInfo info) { ITSCompiler compiler = null; try { compiler = BuildCtx.CompilerPool.GetTs(Owner.DiskCache, BuildCtx.CompilerOptions); //_owner.Logger.Info("Transpiling " + info.Owner.FullPath); var result = compiler.Transpile(info.Owner.FullPath, info.Owner.Utf8Content); if (result.Diagnostics != null) { info.ReportDiag(result.Diagnostics); info.HasError = result.Diagnostics.Any(d => d.IsError); } else { info.HasError = false; } if (info.HasError) { info.Output = null; info.MapLink = null; } else { info.Output = SourceMap.RemoveLinkToSourceMap(result.JavaScript); info.MapLink = SourceMap.Parse(result.SourceMap, info.Owner.Parent.FullPath); } } finally { if (compiler != null) { BuildCtx.CompilerPool.ReleaseTs(compiler); } } if (info.HasError) { info.SourceInfo = null; return; } var backupCurrentlyTranspiling = _currentlyTranspiling; try { if (_currentlyTranspiling == null) { _currentlyTranspiling = info; } var parser = new Parser(new Options(), info.Output); var toplevel = parser.Parse(); toplevel.FigureOutScope(); var ctx = new ResolvingConstEvalCtx(info.Owner.FullPath, this); string resolver(IConstEvalCtx myctx, string text) { if (text.StartsWith("resource:", StringComparison.Ordinal)) { return("resource:" + resolver(myctx, text.Substring("resource:".Length))); } if (text.StartsWith("node_modules/", StringComparison.Ordinal)) { return(ResolveImport(info.Owner.FullPath, text.Substring("node_modules/".Length), false, true)); } var res = PathUtils.Join(PathUtils.Parent(myctx.SourceName), text); return(res); } var sourceInfo = GatherBobrilSourceInfo.Gather(toplevel, ctx, resolver); info.SourceInfo = sourceInfo; AddDependenciesFromSourceInfo(info); } finally { _currentlyTranspiling = backupCurrentlyTranspiling; } }
void Transpile(TsFileAdditionalInfo info) { ITSCompiler compiler = null; try { compiler = BuildCtx.CompilerPool.GetTs(Owner.DiskCache, BuildCtx.CompilerOptions); //_owner.Logger.Info("Transpiling " + info.Owner.FullPath); var result = compiler.Transpile(info.Owner.FullPath, info.Owner.Utf8Content); if (result.Diagnostics != null) { info.ReportDiag(result.Diagnostics); info.HasError = result.Diagnostics.Any(d => d.IsError); } else { info.HasError = false; } if (info.HasError) { info.Output = null; info.MapLink = null; } else { info.Output = SourceMap.RemoveLinkToSourceMap(result.JavaScript); info.MapLink = SourceMap.Parse(result.SourceMap, info.Owner.Parent.FullPath); } } finally { if (compiler != null) { BuildCtx.CompilerPool.ReleaseTs(compiler); } } if (info.HasError) { info.SourceInfo = null; return; } var backupCurrentlyTranspiling = _currentlyTranspiling; try { if (_currentlyTranspiling == null) { _currentlyTranspiling = info; } var parser = new Parser(new Options(), info.Output); var toplevel = parser.Parse(); toplevel.FigureOutScope(); var ctx = new ResolvingConstEvalCtx(info.Owner.FullPath, this); string Resolver(IConstEvalCtx myctx, string text) { return(ResolverWithPossibleForcingResource(myctx, text, false)); } string ResolverWithPossibleForcingResource(IConstEvalCtx myctx, string text, bool forceResource) { if (text.StartsWith("project:", StringComparison.Ordinal)) { var(pref, name) = SplitProjectAssetName(text); return(pref + ResolverWithPossibleForcingResource(myctx, name, true)); } if (text.StartsWith("resource:", StringComparison.Ordinal)) { return("resource:" + ResolverWithPossibleForcingResource(myctx, text.Substring("resource:".Length), true)); } if (text.StartsWith("node_modules/", StringComparison.Ordinal)) { var res2 = ResolveImport(info.Owner.FullPath, text.Substring("node_modules/".Length), false, true, forceResource, true); return(res2 == "?" ? text : res2); } var res = PathUtils.Join(PathUtils.Parent(myctx.SourceName), text); return(res); } var sourceInfo = GatherBobrilSourceInfo.Gather(toplevel, ctx, Resolver); info.SourceInfo = sourceInfo; AddDependenciesFromSourceInfo(info); } catch (SyntaxError error) { var pos = info.MapLink?.FindPosition(error.Position.Line, error.Position.Column) ?? new SourceCodePosition { Line = error.Position.Line, Col = error.Position.Column }; info.ReportDiag(true, -16, error.Message, pos.Line, pos.Col, pos.Line, pos.Col); info.SourceInfo = null; } finally { _currentlyTranspiling = backupCurrentlyTranspiling; } }
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); }