Пример #1
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);
        }
Пример #2
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);
        }
Пример #3
0
        // returns "?" if error in resolving
        public string ResolveImport(string from, string name, bool preferDts = false, bool isAsset = false,
                                    bool forceResource = false, bool skipCheckAdd = false)
        {
            if (Result.ResolveCache.TryGetValue((from, name), out var res))
            {
                if (res.IterationId == IterationId)
                {
                    return(res.FileName);
                }
                if (res.FileName != null && !CheckFileExistence(res.FileName))
                {
                    goto again;
                }
                for (uint i = 0; i < res.NegativeChecks.Count; i++)
                {
                    if (CheckItemExistence(res.NegativeChecks[i]))
                    {
                        goto again;
                    }
                }
            }

            again :;
            if (res == null)
            {
                res = new ResolveResult();
                Result.ResolveCache.Add((from, name), res);
            }
            else
            {
                res.FileName = null;
                res.NegativeChecks.Clear();
            }

            res.IterationId = IterationId;
            var relative = name.StartsWith("./") || name.StartsWith("../");

            Result.Path2FileInfo.TryGetValue(from, out var parentInfo);
            string?fn = null;

            if (relative)
            {
                fn = PathUtils.Join(parentInfo.Owner.Parent.FullPath, name);
                var browserResolve = parentInfo.FromModule?.ProjectOptions?.BrowserResolve;
                if (browserResolve != null)
                {
                    var relativeToModule = PathUtils.Subtract(fn + ".js", parentInfo.FromModule.Owner.FullPath);
                    if (!relativeToModule.StartsWith("../"))
                    {
                        relativeToModule = "./" + relativeToModule;
                    }
                    if (browserResolve.TryGetValue(relativeToModule, out var resolveReplace))
                    {
                        fn = PathUtils.Join(parentInfo.FromModule.Owner.FullPath, resolveReplace);
                    }
                }
            }

            relative :;
            if (relative)
            {
                if (fn.EndsWith(".json") || fn.EndsWith(".css"))
                {
                    var fc = Owner.DiskCache.TryGetItem(fn) as IFileCache;
                    if (fc != null && !fc.IsInvalid)
                    {
                        res.FileName = fn;
                        CheckAdd(fn, forceResource
                            ? FileCompilationType.Resource
                            : fn.EndsWith(".json")
                                ? (isAsset ? FileCompilationType.Resource : FileCompilationType.Json)
                                : (isAsset ? FileCompilationType.Css : FileCompilationType.ImportedCss));
                        return(res.FileName);
                    }

                    res.NegativeChecks.Add(fn);
                }

                var dirPath  = PathUtils.Parent(fn).ToString();
                var fileOnly = fn.Substring(dirPath.Length + 1);
                var dc       = Owner.DiskCache.TryGetItem(dirPath) as IDirectoryCache;
                if (dc == null || dc.IsInvalid)
                {
                    res.FileName = "?";
                    res.NegativeChecks.Add(dirPath);
                    return(res.FileName);
                }

                IFileCache item = (parentInfo.Type == FileCompilationType.EsmJavaScript
                        ? ExtensionsToImportFromJs
                        : ExtensionsToImport).Select(ext =>
                {
                    var ff = dc.TryGetChild(fileOnly + ext) as IFileCache;
                    if (ff == null || ff.IsInvalid)
                    {
                        res.NegativeChecks.Add(dirPath + "/" + fileOnly + ext);
                        return(null);
                    }

                    return(ff);
                })
                                  .FirstOrDefault(i => i != null);
                if (item == null)
                {
                    res.FileName = "?";
                    return(res.FileName);
                }

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

                if (!skipCheckAdd)
                {
                    if (forceResource)
                    {
                        CheckAdd(item.FullPath, FileCompilationType.Resource);
                    }
                    else if (IsDts(item.Name))
                    {
                        CheckAdd(item.FullPath, FileCompilationType.TypeScriptDefinition);
                        if (dc.TryGetChild(fileOnly + ".js") is IFileCache jsItem)
                        {
                            CheckAdd(jsItem.FullPath, FileCompilationType.EsmJavaScript);
                            res.FileNameJs = jsItem.FullPath;
                            parentInfo.ReportDependency(jsItem.FullPath);
                        }
                        else
                        {
                            res.NegativeChecks.Add(dirPath + "/" + fileOnly + ".js");
                            // 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 if (IsTsOrTsxOrJsOrJsx(item.Name))
                    {
                        CheckAdd(item.FullPath,
                                 IsTsOrTsx(item.Name) ? FileCompilationType.TypeScript :
                                 isAsset?FileCompilationType.JavaScriptAsset: FileCompilationType.EsmJavaScript);
                    }
                    else
                    {
                        CheckAdd(item.FullPath, FileCompilationType.Unknown);
                    }
                }

                return(res.FileNameWithPreference(preferDts));
            }
            else
            {
                var pos = 0;
                PathUtils.EnumParts(name, ref pos, out var mn, out _);
                string mname;
                if (name[0] == '@')
                {
                    PathUtils.EnumParts(name, ref pos, out var mn2, out _);
                    mname = mn.ToString() + "/" + mn2.ToString();
                }
                else
                {
                    mname = mn.ToString();
                }

                string?mainFileReplace = null;
                if (mname.Length == name.Length && parentInfo != null)
                {
                    var browserResolve = parentInfo.FromModule?.ProjectOptions?.BrowserResolve;
                    if (browserResolve != null)
                    {
                        if (browserResolve.TryGetValue(name, out var resolveReplace))
                        {
                            if (resolveReplace == null)
                            {
                                res.FileName = "<empty>";
                                return(res.FileName);
                            }

                            if (!resolveReplace.StartsWith(name + "/"))
                            {
                                fn       = PathUtils.Join(parentInfo.FromModule !.Owner.FullPath, resolveReplace);
                                relative = true;
                                goto relative;
                            }

                            mainFileReplace = resolveReplace.Substring(name.Length + 1);
                        }
                    }
                }

                var moduleInfo = ResolveModule(mname);
                if (moduleInfo == null)
                {
                    ReportMissingImport(from, name);
                    res.FileName = "?";
                    return(res.FileName);
                }

                if (parentInfo !.FromModule == Owner)
                {
                    if (!Owner.Dependencies?.Contains(moduleInfo.Name !) ?? false)
                    {
                        var allowDevDependencies =
                            (Owner.ProjectOptions.ExampleSources?.Contains(parentInfo.Owner !.FullPath) ?? false) ||
                            (Owner.ProjectOptions.TestSources?.Contains(parentInfo.Owner !.FullPath) ?? false) ||
                            IsExampleOrSpecDir(Owner.Owner, parentInfo.Owner !.Parent !)
                        ;
                        if (!allowDevDependencies || (!Owner.DevDependencies?.Contains(moduleInfo.Name !) ?? false))
                        {
                            parentInfo.ReportDiag(false, -12,
                                                  $"Importing module {moduleInfo.Name} without being in package.json as dependency", 0, 0,
                                                  0, 0);
                        }
                    }
                }

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

                if (mname.Length != name.Length)
                {
                    fn       = PathUtils.Join(moduleInfo.Owner.FullPath, name.Substring(mname.Length + 1));
                    relative = true;
                    goto relative;
                }

                if (mainFileReplace != null)
                {
                    moduleInfo.MainFile = mainFileReplace;
                }

                var mainFile = PathUtils.Join(moduleInfo.Owner.FullPath, moduleInfo.MainFile);
                res.FileName = mainFile;
                if (!skipCheckAdd)
                {
                    CheckAdd(mainFile,
                             IsTsOrTsx(mainFile) ? FileCompilationType.TypeScript : FileCompilationType.EsmJavaScript);
                }

                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);
                    }
                }

                return(res.FileName);
            }
        }