Beispiel #1
0
        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;
            }
        }
Beispiel #2
0
    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);
    }
Beispiel #3
0
        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;
            }
        }
Beispiel #4
0
        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;
            }
        }
Beispiel #5
0
    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);
    }