Beispiel #1
0
        public string resolveModuleMain(string name, TSFileAdditionalInfo parentInfo)
        {
            var moduleInfo = TSProject.FindInfoForModule(_owner.Owner, _owner.DiskCache, name, out var diskName);

            if (moduleInfo == null)
            {
                return(null);
            }
            if (name != diskName)
            {
                parentInfo.ReportDiag(false, 2, "Module import has wrong casing '" + name + "' on disk '" + diskName + "'", 0, 0, 0, 0);
            }
            moduleInfo.LoadProjectJson(true);
            parentInfo.ImportingModule(moduleInfo);
            var mainFile = PathUtils.Join(moduleInfo.Owner.FullPath, moduleInfo.MainFile);
            var item     = _owner.DiskCache.TryGetItem(mainFile) as IFileCache;

            if (item == null || item.IsInvalid)
            {
                return(null);
            }
            var itemInfo = TSFileAdditionalInfo.Get(item, _owner.DiskCache);

            itemInfo.ImportedAsModule = name;
            AddSource(itemInfo);
            if (!IsTsOrTsx(mainFile))
            {
                itemInfo.Type = FileCompilationType.JavaScript;
                CheckAdd(mainFile);
                if (moduleInfo.TypesMainFile != null)
                {
                    var dtsPath = PathUtils.Join(moduleInfo.Owner.FullPath, moduleInfo.TypesMainFile);
                    item             = _owner.DiskCache.TryGetItem(dtsPath) as IFileCache;
                    itemInfo.DtsLink = TSFileAdditionalInfo.Get(item, _owner.DiskCache);
                    if (item != null && !item.IsInvalid)
                    {
                        return(dtsPath);
                    }
                }
                return(null);
            }
            itemInfo.Type = FileCompilationType.TypeScript;
            CheckAdd(item.FullPath);
            TryToResolveFromBuildCache(itemInfo);
            Crawl();
            if (itemInfo.DtsLink != null && !ToCompile.Contains(item.FullPath))
            {
                return(itemInfo.DtsLink.Owner.FullPath);
            }
            return(item.FullPath);
        }
Beispiel #2
0
        public string resolveLocalImport(string name, TSFileAdditionalInfo parentInfo)
        {
            var dirPath  = PathUtils.Parent(name);
            var fileOnly = name.Substring(dirPath.Length + 1);
            var dc       = _owner.DiskCache.TryGetItem(dirPath) as IDirectoryCache;

            if (dc == null || dc.IsInvalid)
            {
                return(null);
            }
            var item = ExtensionsToImport.Select(ext => dc.TryGetChild(fileOnly + ext) as IFileCache).FirstOrDefault(i => i != null && !i.IsInvalid);

            if (item == null)
            {
                return(null);
            }
            if (item.FullPath.Substring(0, name.Length) != name)
            {
                parentInfo.ReportDiag(false, 1, "Local import has wrong casing '" + name + "' on disk '" + item.FullPath + "'", 0, 0, 0, 0);
            }
            var itemInfo = TSFileAdditionalInfo.Get(item, _owner.DiskCache);

            parentInfo.ImportingLocal(itemInfo);
            if (IsDts(item.FullPath))
            {
                var jsItem = dc.TryGetChild(fileOnly + ".js") as IFileCache;
                if (jsItem != null)
                {
                    var jsItemInfo = TSFileAdditionalInfo.Get(jsItem, _owner.DiskCache);
                    jsItemInfo.Type = FileCompilationType.JavaScript;
                    parentInfo.ImportingLocal(jsItemInfo);
                    CheckAdd(jsItem.FullPath);
                }
                // implementation for .d.ts file does not have same name, it needs to be added to build by b.asset("lib.js") and cannot have dependencies
            }
            else
            {
                itemInfo.Type = FileCompilationType.TypeScript;
                AddSource(itemInfo);
            }
            CheckAdd(item.FullPath);
            TryToResolveFromBuildCache(itemInfo);
            Crawl();
            if (itemInfo.DtsLink != null && !ToCompile.Contains(item.FullPath))
            {
                return(itemInfo.DtsLink.Owner.FullPath);
            }
            return(item.FullPath);
        }
Beispiel #3
0
 void ReportDependenciesFromCss(TSFileAdditionalInfo info)
 {
     if (info.TranspilationDependencies != null)
     {
         foreach (var dep in info.TranspilationDependencies)
         {
             var fullJustName       = PathUtils.Join(info.Owner.Parent.FullPath, dep.Import);
             var fileAdditionalInfo =
                 AutodetectAndAddDependency(fullJustName);
             if (fileAdditionalInfo == null)
             {
                 info.ReportDiag(true, -3, "Missing dependency " + dep.Import, 0, 0, 0, 0);
             }
             info.ReportDependency(fullJustName);
         }
     }
 }
Beispiel #4
0
        public string resolveModuleMain(string name, TSFileAdditionalInfo parentInfo)
        {
            var moduleInfo =
                TSProject.FindInfoForModule(_owner.Owner, _owner.DiskCache, _owner.Logger, name, out var diskName);

            if (moduleInfo == null)
            {
                return(null);
            }
            if (name != diskName)
            {
                parentInfo.ReportDiag(false, -2,
                                      "Module import has wrong casing '" + name + "' on disk '" + diskName + "'", 0, 0, 0, 0);
            }

            moduleInfo.LoadProjectJson(true);
            parentInfo.ImportingModule(moduleInfo);
            var mainFile = PathUtils.Join(moduleInfo.Owner.FullPath, moduleInfo.MainFile);
            var item     = _owner.DiskCache.TryGetItem(mainFile) as IFileCache;

            if (item == null || item.IsInvalid)
            {
                return(null);
            }

            var itemInfo = TSFileAdditionalInfo.Get(item, _owner.DiskCache);

            moduleInfo.MainFileInfo   = itemInfo;
            itemInfo.ImportedAsModule = name;
            itemInfo.MyProject        = moduleInfo;
            var parentProject = parentInfo.MyProject;

            if (parentProject.IsRootProject &&
                ((parentProject.Dependencies == null || !parentProject.Dependencies.Contains(name)) &&
                 (parentProject.DevDependencies == null || !parentProject.DevDependencies.Contains(name))))
            {
                parentInfo.ReportDiag(false, -12,
                                      "Importing module " + name + " without being in package.json as dependency", 0, 0, 0, 0);
            }

            if (moduleInfo.ProjectOptions?.ObsoleteMessage != null)
            {
                if (!PragmaParser.ParseIgnoreImportingObsolete(parentInfo.Owner.Utf8Content).Contains(name))
                {
                    parentInfo.ReportDiag(false, -14,
                                          "Importing obsolete module: " + moduleInfo.ProjectOptions?.ObsoleteMessage, 0, 0, 0, 0);
                }
            }

            AddSource(itemInfo);
            if (!IsTsOrTsx(mainFile))
            {
                itemInfo.Type = FileCompilationType.JavaScript;
                CheckAdd(mainFile);
                if (moduleInfo.TypesMainFile != null)
                {
                    var dtsPath = PathUtils.Join(moduleInfo.Owner.FullPath, moduleInfo.TypesMainFile);
                    item             = _owner.DiskCache.TryGetItem(dtsPath) as IFileCache;
                    itemInfo.DtsLink = TSFileAdditionalInfo.Get(item, _owner.DiskCache);
                    if (item != null && !item.IsInvalid)
                    {
                        return(dtsPath);
                    }
                }

                return(null);
            }

            itemInfo.Type = FileCompilationType.TypeScript;
            CheckAdd(item.FullPath);
            TryToResolveFromBuildCache(itemInfo);
            if (itemInfo.DtsLink != null && !ToCompile.Contains(item.FullPath) && !itemInfo.NeedsCompilation())
            {
                return(itemInfo.DtsLink.Owner.FullPath);
            }

            return(item.FullPath);
        }
Beispiel #5
0
        public string resolveModuleMain(string name, TSFileAdditionalInfo parentInfo)
        {
            if (!_owner.ProjectOptions.AllowModuleDeepImport)
            {
                if (!parentInfo.Owner.Name.EndsWith(".d.ts") && (name.Contains('/') || name.Contains('\\')))
                {
                    parentInfo.ReportDiag(true, -10, "Absolute import '" + name + "' must be just simple module name",
                                          0, 0, 0, 0);
                    return(null);
                }
            }

            var mname      = PathUtils.EnumParts(name).First().name;
            var moduleInfo =
                TSProject.FindInfoForModule(_owner.Owner, parentInfo.Owner.Parent, _owner.DiskCache, _owner.Logger,
                                            mname, out var diskName);

            if (moduleInfo == null)
            {
                return(null);
            }
            if (mname != diskName)
            {
                parentInfo.ReportDiag(false, -2,
                                      "Module import has wrong casing '" + mname + "' on disk '" + diskName + "'", 0, 0, 0, 0);
            }

            moduleInfo.LoadProjectJson(true);
            if (mname.Length != name.Length)
            {
                return(ResolveLocalImport(PathUtils.Join(moduleInfo.Owner.FullPath, name.Substring(mname.Length + 1)),
                                          parentInfo, moduleInfo, name));
            }

            parentInfo.ImportingModule(moduleInfo);
            var mainFile = PathUtils.Join(moduleInfo.Owner.FullPath, moduleInfo.MainFile);
            var item     = _owner.DiskCache.TryGetItemPreferReal(mainFile) as IFileCache;

            if (item == null || item.IsInvalid)
            {
                return(null);
            }

            var itemInfo = TSFileAdditionalInfo.Get(item, _owner.DiskCache);

            moduleInfo.MainFileInfo   = itemInfo;
            itemInfo.ImportedAsModule = name;
            itemInfo.MyProject        = moduleInfo;
            var parentProject = parentInfo.MyProject;

            if (parentProject != null && parentProject.IsRootProject && !parentInfo.Owner.FullPath.Contains("/node_modules/") &&
                ((parentProject.Dependencies == null || !parentProject.Dependencies.Contains(name)) &&
                 (parentProject.DevDependencies == null || !parentProject.DevDependencies.Contains(name))))
            {
                parentInfo.ReportDiag(false, -12,
                                      "Importing module " + name + " without being in package.json as dependency", 0, 0, 0, 0);
            }

            if (moduleInfo.ProjectOptions?.ObsoleteMessage != null)
            {
                if (!PragmaParser.ParseIgnoreImportingObsolete(parentInfo.Owner.Utf8Content).Contains(name))
                {
                    parentInfo.ReportDiag(false, -14,
                                          "Importing obsolete module: " + moduleInfo.ProjectOptions?.ObsoleteMessage, 0, 0, 0, 0);
                }
            }

            AddSource(itemInfo);
            if (!IsTsOrTsx(mainFile))
            {
                if (moduleInfo.MainFileNeedsToBeCompiled)
                {
                    itemInfo.Type = FileCompilationType.EsmJavaScript;
                    CheckAdd(mainFile);
                    TryToResolveFromBuildCache(itemInfo);
                }
                else
                {
                    itemInfo.Type = FileCompilationType.JavaScript;
                    CheckAdd(mainFile);
                }

                if (moduleInfo.TypesMainFile != null)
                {
                    var dtsPath = PathUtils.Join(moduleInfo.Owner.FullPath, moduleInfo.TypesMainFile);
                    item             = _owner.DiskCache.TryGetItem(dtsPath) as IFileCache;
                    itemInfo.DtsLink = TSFileAdditionalInfo.Get(item, _owner.DiskCache);
                    if (item != null && !item.IsInvalid)
                    {
                        return(dtsPath);
                    }
                }

                return(null);
            }

            itemInfo.Type = FileCompilationType.TypeScript;
            CheckAdd(item.FullPath);
            TryToResolveFromBuildCache(itemInfo);
            if (itemInfo.DtsLink != null && !ToCompile.Contains(item.FullPath) && !itemInfo.NeedsCompilation())
            {
                var fp = itemInfo.DtsLink.Owner.FullPath;
                _readFileMap[fp] = itemInfo.DtsLink.Owner;
                return(fp);
            }

            return(item.FullPath);
        }
Beispiel #6
0
        public string ResolveLocalImport(string name, TSFileAdditionalInfo parentInfo, TSProject moduleInfo, string importedAsModule)
        {
            var dirPath  = PathUtils.Parent(name);
            var fileOnly = name.Substring(dirPath.Length + 1);
            var dc       = _owner.DiskCache.TryGetItemPreferReal(dirPath) as IDirectoryCache;

            if (dc == null || dc.IsInvalid)
            {
                return(null);
            }
            var        isJson = false;
            var        isCss  = false;
            IFileCache item   = null;

            if (fileOnly.EndsWith(".json"))
            {
                item = dc.TryGetChild(fileOnly, true) as IFileCache;
                if (item != null)
                {
                    isJson = true;
                }
            }

            if (fileOnly.EndsWith(".css"))
            {
                item = dc.TryGetChild(fileOnly, true) as IFileCache;
                if (item != null)
                {
                    isCss = true;
                }
            }


            if (item == null)
            {
                item = (parentInfo.Type == FileCompilationType.EsmJavaScript ? ExtensionsToImportFromJs : ExtensionsToImport).Select(ext => dc.TryGetChild(fileOnly + ext, true) as IFileCache)
                       .FirstOrDefault(i => i != null && !i.IsInvalid);
            }

            if (item == null)
            {
                parentInfo.ReportDiag(false, -15, "Cannot resolve import '" + name + "'", 0, 0, 0, 0);
                return(null);
            }

            if (item.FullPath.Substring(0, name.Length) != name)
            {
                parentInfo.ReportDiag(false, -1,
                                      "Local import has wrong casing '" + name + "' on disk '" + item.FullPath + "'", 0, 0, 0, 0);
            }

            var itemInfo = TSFileAdditionalInfo.Get(item, _owner.DiskCache);

            parentInfo.ImportingLocal(itemInfo);
            itemInfo.MyProject = moduleInfo ?? parentInfo.MyProject;
            if (importedAsModule != null)
            {
                itemInfo.ImportedAsModule = importedAsModule;
            }
            if (isCss)
            {
                itemInfo.Type = FileCompilationType.ImportedCss;
                AddSource(itemInfo);
                CheckAdd(item.FullPath);
                var po = itemInfo.MyProject.ProjectOptions;
                if (!po.BundleCss)
                {
                    if (itemInfo.OutputUrl == null)
                    {
                        itemInfo.OutputUrl =
                            po.AllocateName(PathUtils.Subtract(item.FullPath,
                                                               po.Owner.Owner.FullPath));
                    }
                }
                return(null);
            }
            if (IsDts(item.Name))
            {
                if (dc.TryGetChild(fileOnly + ".js", true) is IFileCache jsItem)
                {
                    var jsItemInfo = TSFileAdditionalInfo.Get(jsItem, _owner.DiskCache);
                    jsItemInfo.Type      = FileCompilationType.JavaScript;
                    jsItemInfo.MyProject = itemInfo.MyProject;
                    parentInfo.ImportingLocal(jsItemInfo);
                    CheckAdd(jsItem.FullPath);
                }

                // implementation for .d.ts file does not have same name, it needs to be added to build by b.asset("lib.js") and cannot have dependencies
            }
            else
            {
                itemInfo.Type = isJson ? FileCompilationType.Json : parentInfo.Type;
                AddSource(itemInfo);
            }

            if (LocalResolveCache.TryGetValue(name, out var res))
            {
                return(res);
            }

            CheckAdd(item.FullPath);
            TryToResolveFromBuildCache(itemInfo);

            if (itemInfo.DtsLink != null && !ToCompile.Contains(item.FullPath) && !itemInfo.NeedsCompilation())
            {
                res = itemInfo.DtsLink.Owner.FullPath;
            }
            else
            {
                res = item.FullPath;
            }

            LocalResolveCache.Add(name, res);
            return(res);
        }
Beispiel #7
0
        public void AddDependenciesFromSourceInfo(TSFileAdditionalInfo fileInfo)
        {
            var sourceInfo = fileInfo.SourceInfo;

            if (sourceInfo == null)
            {
                return;
            }
            sourceInfo.Imports?.ForEach(i =>
            {
                var resolved = ResolveImport(fileInfo.Owner.FullPath, i.Name);
                if (resolved != null && resolved != "?")
                {
                    fileInfo.ReportDependency(resolved);
                }
                else
                {
                    fileInfo.ReportDiag(true, -3, "Missing import " + i.Name, i.StartLine, i.StartCol, i.EndLine, i.EndCol);
                }
            });
            sourceInfo.Assets?.ForEach(a =>
            {
                if (a.Name == null)
                {
                    return;
                }
                var assetName = a.Name;
                if (assetName.StartsWith("resource:"))
                {
                    assetName = assetName.Substring(9);
                    if (ReportDependency(fileInfo, AutodetectAndAddDependency(assetName, true)) == null)
                    {
                        fileInfo.ReportDiag(true, -3, "Missing dependency " + assetName, a.StartLine, a.StartCol, a.EndLine, a.EndCol);
                    }
                }
                else
                {
                    if (ReportDependency(fileInfo, AutodetectAndAddDependency(assetName)) == null)
                    {
                        fileInfo.ReportDiag(true, -3, "Missing dependency " + assetName, a.StartLine, a.StartCol, a.EndLine, a.EndCol);
                    }
                }
            });
            if (sourceInfo.Sprites != null)
            {
                if (Owner.ProjectOptions.SpriteGeneration)
                {
                    var spriteHolder = Owner.ProjectOptions.SpriteGenerator;
                    spriteHolder.Process(sourceInfo.Sprites);
                }
                else
                {
                    sourceInfo.Sprites.ForEach(s =>
                    {
                        if (s.Name == null)
                        {
                            return;
                        }
                        var assetName = s.Name;
                        if (ReportDependency(fileInfo, AutodetectAndAddDependency(assetName)) == null)
                        {
                            fileInfo.ReportDiag(true, -3, "Missing dependency " + assetName, s.NameStartLine, s.NameStartCol, s.NameEndLine, s.NameEndCol);
                        }
                    });
                }
            }
            if (sourceInfo.Translations != null)
            {
                var trdb = Owner.ProjectOptions.TranslationDb;
                if (trdb != null)
                {
                    sourceInfo.Translations.ForEach(t =>
                    {
                        if (t.Message == null)
                        {
                            return;
                        }
                        if (t.WithParams)
                        {
                            var err = trdb.CheckMessage(t.Message, t.KnownParams);
                            if (err != null)
                            {
                                fileInfo.ReportDiag(false, -7,
                                                    "Problem with translation message \"" + t.Message + "\" " + err.ToString(), t.StartLine, t.StartCol, t.EndLine, t.EndCol);
                            }
                        }
                    });
                }
            }
        }
Beispiel #8
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;
            }
        }