UNPKG

ts-simple-ast

Version:

TypeScript compiler wrapper for static analysis and code manipulation.

1,006 lines 51.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var compiler_1 = require("../compiler"); var errors = require("../errors"); var typescript_1 = require("../typescript"); var utils_1 = require("../utils"); var DirectoryEmitResult_1 = require("./DirectoryEmitResult"); var Directory = /** @class */ (function () { /** @private */ function Directory(context, path) { this.__context = context; this._setPathInternal(path); } /** @internal */ Directory.prototype._setPathInternal = function (path) { this._path = path; this._pathParts = path.split("/").filter(function (p) { return p.length > 0; }); }; Object.defineProperty(Directory.prototype, "_context", { /** @internal */ get: function () { this._throwIfDeletedOrRemoved(); return this.__context; }, enumerable: true, configurable: true }); /** * Checks if this directory is an ancestor of the provided directory. * @param possibleDescendant - Directory or source file that's a possible descendant. */ Directory.prototype.isAncestorOf = function (possibleDescendant) { return Directory._isAncestorOfDir(this, possibleDescendant); }; /** * Checks if this directory is a descendant of the provided directory. * @param possibleAncestor - Directory or source file that's a possible ancestor. */ Directory.prototype.isDescendantOf = function (possibleAncestor) { return Directory._isAncestorOfDir(possibleAncestor, this); }; /** * Gets the directory depth. * @internal */ Directory.prototype._getDepth = function () { return this._pathParts.length; }; /** * Gets the path to the directory. */ Directory.prototype.getPath = function () { this._throwIfDeletedOrRemoved(); return this._path; }; /** * Gets the directory path's base name. */ Directory.prototype.getBaseName = function () { return this._pathParts[this._pathParts.length - 1]; }; /** * Gets the parent directory or throws if it doesn't exist or was never added to the project. */ Directory.prototype.getParentOrThrow = function () { var _this = this; return errors.throwIfNullOrUndefined(this.getParent(), function () { return "Parent directory of " + _this.getPath() + " does not exist or was never added."; }); }; /** * Gets the parent directory if it exists and was added to the project. */ Directory.prototype.getParent = function () { if (utils_1.FileUtils.isRootDirPath(this.getPath())) return undefined; return this.addExistingDirectoryIfExists(utils_1.FileUtils.getDirPath(this.getPath())); }; Directory.prototype.getDirectoryOrThrow = function (pathOrCondition) { var _this = this; return errors.throwIfNullOrUndefined(this.getDirectory(pathOrCondition), function () { if (typeof pathOrCondition === "string") return "Could not find a directory at path '" + _this._context.fileSystemWrapper.getStandardizedAbsolutePath(pathOrCondition, _this.getPath()) + "'."; return "Could not find child directory that matched condition."; }); }; Directory.prototype.getDirectory = function (pathOrCondition) { if (typeof pathOrCondition === "string") { var path = this._context.fileSystemWrapper.getStandardizedAbsolutePath(pathOrCondition, this.getPath()); return this._context.compilerFactory.getDirectoryFromCache(path); } return utils_1.ArrayUtils.find(this.getDirectories(), pathOrCondition); }; Directory.prototype.getSourceFileOrThrow = function (pathOrCondition) { var _this = this; return errors.throwIfNullOrUndefined(this.getSourceFile(pathOrCondition), function () { if (typeof pathOrCondition === "string") return "Could not find child source file at path '" + _this._context.fileSystemWrapper.getStandardizedAbsolutePath(pathOrCondition, _this.getPath()) + "'."; return "Could not find child source file that matched condition."; }); }; Directory.prototype.getSourceFile = function (pathOrCondition) { if (typeof pathOrCondition === "string") { var path = this._context.fileSystemWrapper.getStandardizedAbsolutePath(pathOrCondition, this.getPath()); return this._context.compilerFactory.getSourceFileFromCacheFromFilePath(path); } return utils_1.ArrayUtils.find(this.getSourceFiles(), pathOrCondition); }; /** * Gets the child directories. */ Directory.prototype.getDirectories = function () { return this._context.compilerFactory.getChildDirectoriesOfDirectory(this.getPath()); }; /** * Gets the source files within this directory. */ Directory.prototype.getSourceFiles = function () { return this._context.compilerFactory.getChildSourceFilesOfDirectory(this.getPath()); }; /** * Gets the source files in the current directory and all the descendant directories. */ Directory.prototype.getDescendantSourceFiles = function () { return utils_1.ArrayUtils.from(this._getDescendantSourceFilesIterator()); }; /** * Gets the source files in the current directory and all the descendant directories. * @internal */ Directory.prototype._getDescendantSourceFilesIterator = function () { var e_1, _a, e_2, _b, _c, _d, sourceFile, e_1_1, _e, _f, directory, e_2_1; return tslib_1.__generator(this, function (_g) { switch (_g.label) { case 0: _g.trys.push([0, 5, 6, 7]); _c = tslib_1.__values(this.getSourceFiles()), _d = _c.next(); _g.label = 1; case 1: if (!!_d.done) return [3 /*break*/, 4]; sourceFile = _d.value; return [4 /*yield*/, sourceFile]; case 2: _g.sent(); _g.label = 3; case 3: _d = _c.next(); return [3 /*break*/, 1]; case 4: return [3 /*break*/, 7]; case 5: e_1_1 = _g.sent(); e_1 = { error: e_1_1 }; return [3 /*break*/, 7]; case 6: try { if (_d && !_d.done && (_a = _c.return)) _a.call(_c); } finally { if (e_1) throw e_1.error; } return [7 /*endfinally*/]; case 7: _g.trys.push([7, 12, 13, 14]); _e = tslib_1.__values(this.getDirectories()), _f = _e.next(); _g.label = 8; case 8: if (!!_f.done) return [3 /*break*/, 11]; directory = _f.value; return [5 /*yield**/, tslib_1.__values(directory._getDescendantSourceFilesIterator())]; case 9: _g.sent(); _g.label = 10; case 10: _f = _e.next(); return [3 /*break*/, 8]; case 11: return [3 /*break*/, 14]; case 12: e_2_1 = _g.sent(); e_2 = { error: e_2_1 }; return [3 /*break*/, 14]; case 13: try { if (_f && !_f.done && (_b = _e.return)) _b.call(_e); } finally { if (e_2) throw e_2.error; } return [7 /*endfinally*/]; case 14: return [2 /*return*/]; } }); }; /** * Gets the descendant directories. */ Directory.prototype.getDescendantDirectories = function () { return utils_1.ArrayUtils.from(this._getDescendantDirectoriesIterator()); }; /** * Gets the descendant directories. * @internal */ Directory.prototype._getDescendantDirectoriesIterator = function () { var e_3, _a, _b, _c, directory, e_3_1; return tslib_1.__generator(this, function (_d) { switch (_d.label) { case 0: _d.trys.push([0, 6, 7, 8]); _b = tslib_1.__values(this.getDirectories()), _c = _b.next(); _d.label = 1; case 1: if (!!_c.done) return [3 /*break*/, 5]; directory = _c.value; return [4 /*yield*/, directory]; case 2: _d.sent(); return [5 /*yield**/, tslib_1.__values(directory._getDescendantDirectoriesIterator())]; case 3: _d.sent(); _d.label = 4; case 4: _c = _b.next(); return [3 /*break*/, 1]; case 5: return [3 /*break*/, 8]; case 6: e_3_1 = _d.sent(); e_3 = { error: e_3_1 }; return [3 /*break*/, 8]; case 7: try { if (_c && !_c.done && (_a = _b.return)) _a.call(_b); } finally { if (e_3) throw e_3.error; } return [7 /*endfinally*/]; case 8: return [2 /*return*/]; } }); }; /** * Add source files based on file globs. * @param fileGlobs - File glob or globs to add files based on. * @returns The matched source files. */ Directory.prototype.addExistingSourceFiles = function (fileGlobs) { var _this = this; fileGlobs = typeof fileGlobs === "string" ? [fileGlobs] : fileGlobs; fileGlobs = fileGlobs.map(function (g) { if (utils_1.FileUtils.pathIsAbsolute(g)) return g; return utils_1.FileUtils.pathJoin(_this.getPath(), g); }); return this._context.directoryCoordinator.addExistingSourceFiles(fileGlobs, { markInProject: this._isInProject() }); }; /** * Adds an existing directory from the relative path or directory name, or returns undefined if it doesn't exist. * * Will return the directory if it was already added. * @param dirPath - Directory name or path to the directory that should be added. * @param options - Options. * @skipOrThrowCheck */ Directory.prototype.addExistingDirectoryIfExists = function (dirPath, options) { if (options === void 0) { options = {}; } dirPath = this._context.fileSystemWrapper.getStandardizedAbsolutePath(dirPath, this.getPath()); return this._context.directoryCoordinator.addExistingDirectoryIfExists(dirPath, tslib_1.__assign({}, options, { markInProject: this._isInProject() })); }; /** * Adds an existing directory from the relative path or directory name, or throws if it doesn't exist. * * Will return the directory if it was already added. * @param dirPath - Directory name or path to the directory that should be added. * @throws DirectoryNotFoundError if the directory does not exist. */ Directory.prototype.addExistingDirectory = function (dirPath, options) { if (options === void 0) { options = {}; } dirPath = this._context.fileSystemWrapper.getStandardizedAbsolutePath(dirPath, this.getPath()); return this._context.directoryCoordinator.addExistingDirectory(dirPath, tslib_1.__assign({}, options, { markInProject: this._isInProject() })); }; /** * Creates a directory if it doesn't exist. * @param dirPath - Relative or absolute path to the directory that should be created. */ Directory.prototype.createDirectory = function (dirPath) { dirPath = this._context.fileSystemWrapper.getStandardizedAbsolutePath(dirPath, this.getPath()); return this._context.directoryCoordinator.createDirectoryOrAddIfExists(dirPath, { markInProject: this._isInProject() }); }; /** * Creates a source file, relative to this directory. * * Note: The file will not be created and saved to the file system until .save() is called on the source file. * @param relativeFilePath - Relative file path of the source file to create. * @param sourceFileText - Text, structure, or writer function to create the source file text with. * @param options - Options. * @throws - InvalidOperationError if a source file already exists at the provided file name. */ Directory.prototype.createSourceFile = function (relativeFilePath, sourceFileText, options) { var filePath = this._context.fileSystemWrapper.getStandardizedAbsolutePath(relativeFilePath, this.getPath()); return this._context.compilerFactory.createSourceFile(filePath, sourceFileText || "", tslib_1.__assign({}, (options || {}), { markInProject: this._isInProject() })); }; /** * Adds an existing source file, relative to this directory, or returns undefined. * * Will return the source file if it was already added. * @param relativeFilePath - Relative file path to add. * @skipOrThrowCheck */ Directory.prototype.addExistingSourceFileIfExists = function (relativeFilePath) { var filePath = this._context.fileSystemWrapper.getStandardizedAbsolutePath(relativeFilePath, this.getPath()); return this._context.directoryCoordinator.addExistingSourceFileIfExists(filePath, { markInProject: this._isInProject() }); }; /** * Adds an existing source file, relative to this directory, or throws if it doesn't exist. * * Will return the source file if it was already added. * @param relativeFilePath - Relative file path to add. * @throws FileNotFoundError when the file doesn't exist. */ Directory.prototype.addExistingSourceFile = function (relativeFilePath) { var filePath = this._context.fileSystemWrapper.getStandardizedAbsolutePath(relativeFilePath, this.getPath()); return this._context.directoryCoordinator.addExistingSourceFile(filePath, { markInProject: this._isInProject() }); }; /** * Emits the files in the directory. * @param options - Options for emitting. */ Directory.prototype.emit = function (options) { if (options === void 0) { options = {}; } return tslib_1.__awaiter(this, void 0, void 0, function () { var e_4, _a, fileSystemWrapper, writeTasks, outputFilePaths, _b, _c, emitResult, e_4_1; return tslib_1.__generator(this, function (_d) { switch (_d.label) { case 0: fileSystemWrapper = this._context.fileSystemWrapper; writeTasks = []; outputFilePaths = []; _d.label = 1; case 1: _d.trys.push([1, 7, 8, 9]); _b = tslib_1.__values(this._emitInternal(options)), _c = _b.next(); _d.label = 2; case 2: if (!!_c.done) return [3 /*break*/, 6]; emitResult = _c.value; if (!(emitResult === false)) return [3 /*break*/, 4]; return [4 /*yield*/, Promise.all(writeTasks)]; case 3: _d.sent(); return [2 /*return*/, new DirectoryEmitResult_1.DirectoryEmitResult(true, outputFilePaths)]; case 4: writeTasks.push(fileSystemWrapper.writeFile(emitResult.filePath, emitResult.fileText)); outputFilePaths.push(emitResult.filePath); _d.label = 5; case 5: _c = _b.next(); return [3 /*break*/, 2]; case 6: return [3 /*break*/, 9]; case 7: e_4_1 = _d.sent(); e_4 = { error: e_4_1 }; return [3 /*break*/, 9]; case 8: try { if (_c && !_c.done && (_a = _b.return)) _a.call(_b); } finally { if (e_4) throw e_4.error; } return [7 /*endfinally*/]; case 9: return [4 /*yield*/, Promise.all(writeTasks)]; case 10: _d.sent(); return [2 /*return*/, new DirectoryEmitResult_1.DirectoryEmitResult(false, outputFilePaths)]; } }); }); }; /** * Emits the files in the directory synchronously. * * Remarks: This might be very slow compared to the asynchronous version if there are a lot of files. * @param options - Options for emitting. */ Directory.prototype.emitSync = function (options) { if (options === void 0) { options = {}; } var e_5, _a; var fileSystemWrapper = this._context.fileSystemWrapper; var outputFilePaths = []; try { for (var _b = tslib_1.__values(this._emitInternal(options)), _c = _b.next(); !_c.done; _c = _b.next()) { var emitResult = _c.value; if (emitResult === false) return new DirectoryEmitResult_1.DirectoryEmitResult(true, outputFilePaths); fileSystemWrapper.writeFileSync(emitResult.filePath, emitResult.fileText); outputFilePaths.push(emitResult.filePath); } } catch (e_5_1) { e_5 = { error: e_5_1 }; } finally { try { if (_c && !_c.done && (_a = _b.return)) _a.call(_b); } finally { if (e_5) throw e_5.error; } } return new DirectoryEmitResult_1.DirectoryEmitResult(false, outputFilePaths); }; Directory.prototype._emitInternal = function (options) { var _this = this; if (options === void 0) { options = {}; } var _a = options.emitOnlyDtsFiles, emitOnlyDtsFiles = _a === void 0 ? false : _a; var isJsFile = options.outDir == null ? undefined : /\.js$/i; var isMapFile = options.outDir == null ? undefined : /\.js\.map$/i; var isDtsFile = options.declarationDir == null && options.outDir == null ? undefined : /\.d\.ts$/i; var getStandardizedPath = function (path) { return path == null ? undefined : _this._context.fileSystemWrapper.getStandardizedAbsolutePath(path, _this.getPath()); }; var getSubDirPath = function (path, dir) { return path == null ? undefined : utils_1.FileUtils.pathJoin(path, dir.getBaseName()); }; var hasDeclarationDir = this._context.compilerOptions.get().declarationDir != null || options.declarationDir != null; return emitDirectory(this, getStandardizedPath(options.outDir), getStandardizedPath(options.declarationDir)); function emitDirectory(directory, outDir, declarationDir) { var e_6, _a, e_7, _b, e_8, _c, _d, _e, sourceFile, output, _f, _g, outputFile, filePath, fileText, e_7_1, e_6_1, _h, _j, dir, e_8_1; return tslib_1.__generator(this, function (_k) { switch (_k.label) { case 0: _k.trys.push([0, 12, 13, 14]); _d = tslib_1.__values(directory.getSourceFiles()), _e = _d.next(); _k.label = 1; case 1: if (!!_e.done) return [3 /*break*/, 11]; sourceFile = _e.value; output = sourceFile.getEmitOutput({ emitOnlyDtsFiles: emitOnlyDtsFiles }); if (!output.getEmitSkipped()) return [3 /*break*/, 3]; return [4 /*yield*/, false]; case 2: _k.sent(); return [2 /*return*/]; case 3: _k.trys.push([3, 8, 9, 10]); _f = tslib_1.__values(output.getOutputFiles()), _g = _f.next(); _k.label = 4; case 4: if (!!_g.done) return [3 /*break*/, 7]; outputFile = _g.value; filePath = outputFile.getFilePath(); fileText = outputFile.getWriteByteOrderMark() ? utils_1.FileUtils.getTextWithByteOrderMark(outputFile.getText()) : outputFile.getText(); if (outDir != null && (isJsFile.test(filePath) || isMapFile.test(filePath) || (!hasDeclarationDir && isDtsFile.test(filePath)))) filePath = utils_1.FileUtils.pathJoin(outDir, utils_1.FileUtils.getBaseName(filePath)); else if (declarationDir != null && isDtsFile.test(filePath)) filePath = utils_1.FileUtils.pathJoin(declarationDir, utils_1.FileUtils.getBaseName(filePath)); return [4 /*yield*/, { filePath: filePath, fileText: fileText }]; case 5: _k.sent(); _k.label = 6; case 6: _g = _f.next(); return [3 /*break*/, 4]; case 7: return [3 /*break*/, 10]; case 8: e_7_1 = _k.sent(); e_7 = { error: e_7_1 }; return [3 /*break*/, 10]; case 9: try { if (_g && !_g.done && (_b = _f.return)) _b.call(_f); } finally { if (e_7) throw e_7.error; } return [7 /*endfinally*/]; case 10: _e = _d.next(); return [3 /*break*/, 1]; case 11: return [3 /*break*/, 14]; case 12: e_6_1 = _k.sent(); e_6 = { error: e_6_1 }; return [3 /*break*/, 14]; case 13: try { if (_e && !_e.done && (_a = _d.return)) _a.call(_d); } finally { if (e_6) throw e_6.error; } return [7 /*endfinally*/]; case 14: _k.trys.push([14, 19, 20, 21]); _h = tslib_1.__values(directory.getDirectories()), _j = _h.next(); _k.label = 15; case 15: if (!!_j.done) return [3 /*break*/, 18]; dir = _j.value; return [5 /*yield**/, tslib_1.__values(emitDirectory(dir, getSubDirPath(outDir, dir), getSubDirPath(declarationDir, dir)))]; case 16: _k.sent(); _k.label = 17; case 17: _j = _h.next(); return [3 /*break*/, 15]; case 18: return [3 /*break*/, 21]; case 19: e_8_1 = _k.sent(); e_8 = { error: e_8_1 }; return [3 /*break*/, 21]; case 20: try { if (_j && !_j.done && (_c = _h.return)) _c.call(_h); } finally { if (e_8) throw e_8.error; } return [7 /*endfinally*/]; case 21: return [2 /*return*/]; } }); } }; /** * Copies the directory to a subdirectory of the specified directory. * @param dirPathOrDirectory Directory path or directory object to copy the directory to. * @param options Options for copying. * @returns The new copied directory. */ Directory.prototype.copyToDirectory = function (dirPathOrDirectory, options) { var dirPath = typeof dirPathOrDirectory === "string" ? dirPathOrDirectory : dirPathOrDirectory.getPath(); return this.copy(utils_1.FileUtils.pathJoin(dirPath, this.getBaseName()), options); }; /** * Copies the directory to a new directory. * @param relativeOrAbsolutePath - The relative or absolute path to the new directory. * @param options - Options. * @returns The directory the copy was made to. */ Directory.prototype.copy = function (relativeOrAbsolutePath, options) { var originalPath = this.getPath(); var fileSystem = this._context.fileSystemWrapper; var newPath = this._context.fileSystemWrapper.getStandardizedAbsolutePath(relativeOrAbsolutePath, this.getPath()); if (originalPath === newPath) return this; options = getDirectoryCopyOptions(options); if (options.includeUntrackedFiles) fileSystem.queueCopyDirectory(originalPath, newPath); return this._copyInternal(newPath, options); }; /** * Immediately copies the directory to the specified path asynchronously. * @param relativeOrAbsolutePath - Directory path as an absolute or relative path. * @param options - Options for moving the directory. * @remarks If includeTrackedFiles is true, then it will execute the pending operations in the current directory. */ Directory.prototype.copyImmediately = function (relativeOrAbsolutePath, options) { return tslib_1.__awaiter(this, void 0, void 0, function () { var fileSystem, originalPath, newPath, newDir; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: fileSystem = this._context.fileSystemWrapper; originalPath = this.getPath(); newPath = fileSystem.getStandardizedAbsolutePath(relativeOrAbsolutePath, originalPath); if (!(originalPath === newPath)) return [3 /*break*/, 2]; return [4 /*yield*/, this.save()]; case 1: _a.sent(); return [2 /*return*/, this]; case 2: options = getDirectoryCopyOptions(options); newDir = this._copyInternal(newPath, options); if (!options.includeUntrackedFiles) return [3 /*break*/, 4]; return [4 /*yield*/, fileSystem.copyDirectoryImmediately(originalPath, newPath)]; case 3: _a.sent(); _a.label = 4; case 4: return [4 /*yield*/, newDir.save()]; case 5: _a.sent(); return [2 /*return*/, newDir]; } }); }); }; /** * Immediately copies the directory to the specified path synchronously. * @param relativeOrAbsolutePath - Directory path as an absolute or relative path. * @param options - Options for moving the directory. * @remarks If includeTrackedFiles is true, then it will execute the pending operations in the current directory. */ Directory.prototype.copyImmediatelySync = function (relativeOrAbsolutePath, options) { var fileSystem = this._context.fileSystemWrapper; var originalPath = this.getPath(); var newPath = fileSystem.getStandardizedAbsolutePath(relativeOrAbsolutePath, originalPath); if (originalPath === newPath) { this.saveSync(); return this; } options = getDirectoryCopyOptions(options); var newDir = this._copyInternal(newPath, options); if (options.includeUntrackedFiles) fileSystem.copyDirectoryImmediatelySync(originalPath, newPath); newDir.saveSync(); return newDir; }; /** @internal */ Directory.prototype._copyInternal = function (newPath, options) { var _this = this; var e_9, _a, e_10, _b, e_11, _c; var originalPath = this.getPath(); if (originalPath === newPath) return this; var _d = this._context, fileSystem = _d.fileSystemWrapper, compilerFactory = _d.compilerFactory; var copyingDirectories = tslib_1.__spread([this], this.getDescendantDirectories()).map(function (directory) { return ({ newDirPath: directory === _this ? newPath : fileSystem.getStandardizedAbsolutePath(_this.getRelativePathTo(directory), newPath) }); }); var copyingSourceFiles = this.getDescendantSourceFiles().map(function (sourceFile) { return ({ sourceFile: sourceFile, newFilePath: fileSystem.getStandardizedAbsolutePath(_this.getRelativePathTo(sourceFile), newPath), references: _this._getReferencesForCopy(sourceFile) }); }); try { // copy directories for (var copyingDirectories_1 = tslib_1.__values(copyingDirectories), copyingDirectories_1_1 = copyingDirectories_1.next(); !copyingDirectories_1_1.done; copyingDirectories_1_1 = copyingDirectories_1.next()) { var newDirPath = copyingDirectories_1_1.value.newDirPath; this._context.compilerFactory.createDirectoryOrAddIfExists(newDirPath, { markInProject: this._isInProject() }); } } catch (e_9_1) { e_9 = { error: e_9_1 }; } finally { try { if (copyingDirectories_1_1 && !copyingDirectories_1_1.done && (_a = copyingDirectories_1.return)) _a.call(copyingDirectories_1); } finally { if (e_9) throw e_9.error; } } try { // copy source files for (var copyingSourceFiles_1 = tslib_1.__values(copyingSourceFiles), copyingSourceFiles_1_1 = copyingSourceFiles_1.next(); !copyingSourceFiles_1_1.done; copyingSourceFiles_1_1 = copyingSourceFiles_1.next()) { var _e = copyingSourceFiles_1_1.value, sourceFile = _e.sourceFile, newFilePath = _e.newFilePath; sourceFile._copyInternal(newFilePath, options); } } catch (e_10_1) { e_10 = { error: e_10_1 }; } finally { try { if (copyingSourceFiles_1_1 && !copyingSourceFiles_1_1.done && (_b = copyingSourceFiles_1.return)) _b.call(copyingSourceFiles_1); } finally { if (e_10) throw e_10.error; } } try { // update the references for (var copyingSourceFiles_2 = tslib_1.__values(copyingSourceFiles), copyingSourceFiles_2_1 = copyingSourceFiles_2.next(); !copyingSourceFiles_2_1.done; copyingSourceFiles_2_1 = copyingSourceFiles_2.next()) { var _f = copyingSourceFiles_2_1.value, references = _f.references, newFilePath = _f.newFilePath; this.getSourceFileOrThrow(newFilePath)._updateReferencesForCopyInternal(references); } } catch (e_11_1) { e_11 = { error: e_11_1 }; } finally { try { if (copyingSourceFiles_2_1 && !copyingSourceFiles_2_1.done && (_c = copyingSourceFiles_2.return)) _c.call(copyingSourceFiles_2); } finally { if (e_11) throw e_11.error; } } return compilerFactory.getDirectoryFromCache(newPath); }; /** * Moves the directory to a subdirectory of the specified directory. * @param dirPathOrDirectory Directory path or directory object to move the directory to. * @param options Options for moving. */ Directory.prototype.moveToDirectory = function (dirPathOrDirectory, options) { var dirPath = typeof dirPathOrDirectory === "string" ? dirPathOrDirectory : dirPathOrDirectory.getPath(); return this.move(utils_1.FileUtils.pathJoin(dirPath, this.getBaseName()), options); }; /** * Moves the directory to a new path. * @param relativeOrAbsolutePath - Directory path as an absolute or relative path. * @param options - Options for moving the directory. */ Directory.prototype.move = function (relativeOrAbsolutePath, options) { var fileSystem = this._context.fileSystemWrapper; var originalPath = this.getPath(); var newPath = fileSystem.getStandardizedAbsolutePath(relativeOrAbsolutePath, originalPath); if (originalPath === newPath) return this; return this._moveInternal(newPath, options, function () { return fileSystem.queueMoveDirectory(originalPath, newPath); }); }; /** * Immediately moves the directory to a new path asynchronously. * @param relativeOrAbsolutePath - Directory path as an absolute or relative path. * @param options - Options for moving the directory. */ Directory.prototype.moveImmediately = function (relativeOrAbsolutePath, options) { return tslib_1.__awaiter(this, void 0, void 0, function () { var fileSystem, originalPath, newPath; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: fileSystem = this._context.fileSystemWrapper; originalPath = this.getPath(); newPath = fileSystem.getStandardizedAbsolutePath(relativeOrAbsolutePath, originalPath); if (!(originalPath === newPath)) return [3 /*break*/, 2]; return [4 /*yield*/, this.save()]; case 1: _a.sent(); return [2 /*return*/, this]; case 2: this._moveInternal(newPath, options); return [4 /*yield*/, fileSystem.moveDirectoryImmediately(originalPath, newPath)]; case 3: _a.sent(); return [4 /*yield*/, this.save()]; case 4: _a.sent(); return [2 /*return*/, this]; } }); }); }; /** * Immediately moves the directory to a new path synchronously. * @param relativeOrAbsolutePath - Directory path as an absolute or relative path. * @param options - Options for moving the directory. */ Directory.prototype.moveImmediatelySync = function (relativeOrAbsolutePath, options) { var fileSystem = this._context.fileSystemWrapper; var originalPath = this.getPath(); var newPath = fileSystem.getStandardizedAbsolutePath(relativeOrAbsolutePath, originalPath); if (originalPath === newPath) { this.saveSync(); return this; } this._moveInternal(newPath, options); fileSystem.moveDirectoryImmediatelySync(originalPath, newPath); this.saveSync(); return this; }; /** @internal */ Directory.prototype._moveInternal = function (newPath, options, preAction) { var _this = this; var e_12, _a, e_13, _b, e_14, _c; var originalPath = this.getPath(); if (originalPath === newPath) return this; var existingDir = this._context.compilerFactory.getDirectoryFromCacheOnlyIfInCache(newPath); var markInProject = existingDir != null && existingDir._isInProject(); if (preAction) preAction(); var fileSystem = this._context.fileSystemWrapper; var compilerFactory = this._context.compilerFactory; var movingDirectories = tslib_1.__spread([this], this.getDescendantDirectories()).map(function (directory) { return ({ directory: directory, oldPath: directory.getPath(), newDirPath: directory === _this ? newPath : fileSystem.getStandardizedAbsolutePath(_this.getRelativePathTo(directory), newPath) }); }); var movingSourceFiles = this.getDescendantSourceFiles().map(function (sourceFile) { return ({ sourceFile: sourceFile, newFilePath: fileSystem.getStandardizedAbsolutePath(_this.getRelativePathTo(sourceFile), newPath), references: _this._getReferencesForMove(sourceFile) }); }); try { // update directories for (var movingDirectories_1 = tslib_1.__values(movingDirectories), movingDirectories_1_1 = movingDirectories_1.next(); !movingDirectories_1_1.done; movingDirectories_1_1 = movingDirectories_1.next()) { var _d = movingDirectories_1_1.value, directory = _d.directory, oldPath = _d.oldPath, newDirPath = _d.newDirPath; compilerFactory.removeDirectoryFromCache(oldPath); var dirToOverwrite = compilerFactory.getDirectoryFromCache(newDirPath); if (dirToOverwrite != null) dirToOverwrite._forgetOnlyThis(); directory._setPathInternal(newDirPath); compilerFactory.addDirectoryToCache(directory); } } catch (e_12_1) { e_12 = { error: e_12_1 }; } finally { try { if (movingDirectories_1_1 && !movingDirectories_1_1.done && (_a = movingDirectories_1.return)) _a.call(movingDirectories_1); } finally { if (e_12) throw e_12.error; } } try { // update source files for (var movingSourceFiles_1 = tslib_1.__values(movingSourceFiles), movingSourceFiles_1_1 = movingSourceFiles_1.next(); !movingSourceFiles_1_1.done; movingSourceFiles_1_1 = movingSourceFiles_1.next()) { var _e = movingSourceFiles_1_1.value, sourceFile = _e.sourceFile, newFilePath = _e.newFilePath; sourceFile._moveInternal(newFilePath, options); } } catch (e_13_1) { e_13 = { error: e_13_1 }; } finally { try { if (movingSourceFiles_1_1 && !movingSourceFiles_1_1.done && (_b = movingSourceFiles_1.return)) _b.call(movingSourceFiles_1); } finally { if (e_13) throw e_13.error; } } try { // update the references for (var movingSourceFiles_2 = tslib_1.__values(movingSourceFiles), movingSourceFiles_2_1 = movingSourceFiles_2.next(); !movingSourceFiles_2_1.done; movingSourceFiles_2_1 = movingSourceFiles_2.next()) { var _f = movingSourceFiles_2_1.value, sourceFile = _f.sourceFile, references = _f.references; sourceFile._updateReferencesForMoveInternal(references, originalPath); } } catch (e_14_1) { e_14 = { error: e_14_1 }; } finally { try { if (movingSourceFiles_2_1 && !movingSourceFiles_2_1.done && (_c = movingSourceFiles_2.return)) _c.call(movingSourceFiles_2); } finally { if (e_14) throw e_14.error; } } // mark as in the project last to ensure the previous ancestor dirs aren't marked in the project as well if (markInProject) this._markAsInProject(); return this; }; /** * Queues a deletion of the directory to the file system. * * The directory will be deleted when calling ast.save(). If you wish to delete the file immediately, then use deleteImmediately(). */ Directory.prototype.delete = function () { var e_15, _a, e_16, _b; var fileSystemWrapper = this._context.fileSystemWrapper; var path = this.getPath(); try { for (var _c = tslib_1.__values(this.getSourceFiles()), _d = _c.next(); !_d.done; _d = _c.next()) { var sourceFile = _d.value; sourceFile.delete(); } } catch (e_15_1) { e_15 = { error: e_15_1 }; } finally { try { if (_d && !_d.done && (_a = _c.return)) _a.call(_c); } finally { if (e_15) throw e_15.error; } } try { for (var _e = tslib_1.__values(this.getDirectories()), _f = _e.next(); !_f.done; _f = _e.next()) { var dir = _f.value; dir.delete(); } } catch (e_16_1) { e_16 = { error: e_16_1 }; } finally { try { if (_f && !_f.done && (_b = _e.return)) _b.call(_e); } finally { if (e_16) throw e_16.error; } } fileSystemWrapper.queueDirectoryDelete(path); this.forget(); }; /** * Asyncronously deletes the directory and all its descendants from the file system. */ Directory.prototype.deleteImmediately = function () { return tslib_1.__awaiter(this, void 0, void 0, function () { var fileSystemWrapper, path; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: fileSystemWrapper = this._context.fileSystemWrapper; path = this.getPath(); this.forget(); return [4 /*yield*/, fileSystemWrapper.deleteDirectoryImmediately(path)]; case 1: _a.sent(); return [2 /*return*/]; } }); }); }; /** * Synchronously deletes the directory and all its descendants from the file system. */ Directory.prototype.deleteImmediatelySync = function () { var fileSystemWrapper = this._context.fileSystemWrapper; var path = this.getPath(); this.forget(); fileSystemWrapper.deleteDirectoryImmediatelySync(path); }; /** * Forgets the directory and all its descendants from the Project. * * Note: Does not delete the directory from the file system. */ Directory.prototype.forget = function () { var e_17, _a, e_18, _b; if (this.wasForgotten()) return; try { for (var _c = tslib_1.__values(this.getSourceFiles()), _d = _c.next(); !_d.done; _d = _c.next()) { var sourceFile = _d.value; sourceFile.forget(); } } catch (e_17_1) { e_17 = { error: e_17_1 }; } finally { try { if (_d && !_d.done && (_a = _c.return)) _a.call(_c); } finally { if (e_17) throw e_17.error; } } try { for (var _e = tslib_1.__values(this.getDirectories()), _f = _e.next(); !_f.done; _f = _e.next()) { var dir = _f.value; dir.forget(); } } catch (e_18_1) { e_18 = { error: e_18_1 }; } finally { try { if (_f && !_f.done && (_b = _e.return)) _b.call(_e); } finally { if (e_18) throw e_18.error; } } this._forgetOnlyThis(); }; /** @internal */ Directory.prototype._forgetOnlyThis = function () { if (this.wasForgotten()) return; this._context.compilerFactory.removeDirectoryFromCache(this.getPath()); this.__context = undefined; }; /** * Asynchronously saves the directory and all the unsaved source files to the disk. */ Directory.prototype.save = function () { return tslib_1.__awaiter(this, void 0, void 0, function () { var unsavedSourceFiles; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this._context.fileSystemWrapper.saveForDirectory(this.getPath())]; case 1: _a.sent(); unsavedSourceFiles = this.getDescendantSourceFiles().filter(function (s) { return !s.isSaved(); }); return [4 /*yield*/, Promise.all(unsavedSourceFiles.map(function (s) { return s.save(); }))]; case 2: _a.sent(); return [2 /*return*/]; } }); }); }; /** * Synchronously saves the directory and all the unsaved source files to the disk. */ Directory.prototype.saveSync = function () { this._context.fileSystemWrapper.saveForDirectorySync(this.getPath()); var unsavedSourceFiles = this.getDescendantSourceFiles().filter(function (s) { return !s.isSaved(); }); unsavedSourceFiles.forEach(function (s) { return s.saveSync(); }); }; Directory.prototype.getRelativePathTo = function (sourceFileOrDir) { return utils_1.FileUtils.getRelativePathTo(this.getPath(), getPath()); function getPath() { return sourceFileOrDir instanceof compiler_1.SourceFile ? sourceFileOrDir.getFilePath() : sourceFileOrDir.getPath(); } }; Directory.prototype.getRelativePathAsModuleSpecifierTo = function (sourceFileOrDir) { var moduleResolution = this._context.program.getEmitModuleResolutionKind(); var thisDirectory = this; var moduleSpecifier = utils_1.FileUtils.getRelativePathTo(this.getPath(), getPath()).replace(/((\.d\.ts$)|(\.[^/.]+$))/i, ""); return utils_1.StringUtils.startsWith(moduleSpecifier, "../") ? moduleSpecifier : "./" + moduleSpecifier; function getPath() { return sourceFileOrDir instanceof compiler_1.SourceFile ? getPathForSourceFile(sourceFileOrDir) : getPathForDirectory(sourceFileOrDir); function getPathForSourceFile(sourceFile) { switch (moduleResolution) { case typescript_1.ModuleResolutionKind.NodeJs: var filePath = sourceFile.getFilePath(); if (sourceFile.getDirectory() === thisDirectory) return filePath; return filePath.replace(/\/index?(\.d\.ts|\.ts|\.js)$/i, ""); case typescript_1.ModuleResolutionKind.Classic: return sourceFile.getFilePath(); default: throw errors.getNotImplementedForNeverValueError(moduleResolution); } } function getPathForDirectory(dir) { switch (moduleResolution) { case typescript_1.ModuleResolutionKind.NodeJs: if (dir === thisDirectory) return utils_1.FileUtils.pathJoin(dir.getPath(), "index.ts"); return dir.getPath(); case typescript_1.ModuleResolutionKind.Classic: return utils_1.FileUtils.pathJoin(dir.getPath(), "index.ts"); default: throw errors.getNotImplementedForNeverValueError(moduleResolution); } } } }; /** * Gets if the directory was forgotten. */ Directory.prototype.wasForgotten = function () { return this.__context == null; }; /** @internal */ Directory.prototype._isInProject = function () { return this._context.inProjectCoordinator.isDirectoryInProject(this); }; /** @internal */ Directory.prototype._markAsInProject = function () { this._context.inProjectCoordinator.markDirectoryAsInProject(this); }; /** @internal */ Directory.prototype._hasLoadedParent = function () { return this._context.compilerFactory.containsDirectoryAtPath(utils_1.FileUtils.getDirPath(this.getPath())); }; /** @internal */ Directory.prototype._throwIfDeletedOrRemoved = function () { if (this.wasForgotten()) throw new errors.InvalidOperationError("Cannot use a directory that was deleted, removed, or overwritten."); }; /** @internal */ Directory.prototype._getReferencesForCopy = function (sourceFile) { var _this = this; var literalReferences = sourceFile._getReferencesForCopyInternal(); return literalReferences.filter(function (r) { return !_this.isAncestorOf(r[1]); }); }; /** @internal */ Directory.prototype._getReferencesForMove = function (sourceFile) { var _this = this; var _a = sourceFile._getReferencesForMoveInternal(), literalReferences = _a.literalReferences, referencingLiterals = _a.referencingLiterals; return { literalReferences: literalReferences.filter(function (r) { return !_this.is