UNPKG

ts-simple-ast

Version:

TypeScript compiler wrapper for static analysis and code manipulation.

983 lines (982 loc) 47.9 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 () { /** @internal */ function Directory(global, path) { this._global = global; 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, "global", { /** @internal */ get: function () { this._throwIfDeletedOrRemoved(); return this._global; }, 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 AST. */ 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 AST. */ 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.global.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.global.fileSystemWrapper.getStandardizedAbsolutePath(pathOrCondition, this.getPath()); return this.global.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.global.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.global.fileSystemWrapper.getStandardizedAbsolutePath(pathOrCondition, this.getPath()); return this.global.compilerFactory.getSourceFileFromCacheFromFilePath(path); } return utils_1.ArrayUtils.find(this.getSourceFiles(), pathOrCondition); }; /** * Gets the child directories. */ Directory.prototype.getDirectories = function () { return this.global.compilerFactory.getChildDirectoriesOfDirectory(this.getPath()); }; /** * Gets the source files within this directory. */ Directory.prototype.getSourceFiles = function () { return this.global.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*/]; } }); }; /** * Adds an existing directory to the AST 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.global.fileSystemWrapper.getStandardizedAbsolutePath(dirPath, this.getPath()); return this.global.directoryCoordinator.addExistingDirectoryIfExists(dirPath, options); }; /** * Adds an existing directory to the AST 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.global.fileSystemWrapper.getStandardizedAbsolutePath(dirPath, this.getPath()); return this.global.directoryCoordinator.addExistingDirectory(dirPath, options); }; /** * 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.global.fileSystemWrapper.getStandardizedAbsolutePath(dirPath, this.getPath()); return this.global.directoryCoordinator.createDirectoryOrAddIfExists(dirPath); }; Directory.prototype.createSourceFile = function (relativeFilePath, structureOrText, options) { var filePath = this.global.fileSystemWrapper.getStandardizedAbsolutePath(relativeFilePath, this.getPath()); return this.global.compilerFactory.createSourceFile(filePath, structureOrText || "", options || {}); }; /** * Adds an existing source file to the AST, relative to this directory, or returns undefined. * * Will return the source file if it was already added. * @param relativeFilePath - Relative file path to add. * @param options - Options for adding the source file. * @skipOrThrowCheck */ Directory.prototype.addExistingSourceFileIfExists = function (relativeFilePath, options) { var filePath = this.global.fileSystemWrapper.getStandardizedAbsolutePath(relativeFilePath, this.getPath()); return this.global.compilerFactory.addOrGetSourceFileFromFilePath(filePath, options || {}); }; /** * Adds an existing source file to the AST, 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. * @param options - Options for adding the source file. * @throws FileNotFoundError when the file doesn't exist. */ Directory.prototype.addExistingSourceFile = function (relativeFilePath, options) { var sourceFile = this.addExistingSourceFileIfExists(relativeFilePath, options); if (sourceFile == null) throw new errors.FileNotFoundError(this.global.fileSystemWrapper.getStandardizedAbsolutePath(relativeFilePath, this.getPath())); return sourceFile; }; /** * 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.global.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) { var e_5, _a; if (options === void 0) { options = {}; } var fileSystemWrapper = this.global.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.global.fileSystemWrapper.getStandardizedAbsolutePath(path, _this.getPath()); }; var getSubDirPath = function (path, dir) { return path == null ? undefined : utils_1.FileUtils.pathJoin(path, dir.getBaseName()); }; var hasDeclarationDir = this.global.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 a 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.global.fileSystemWrapper; var newPath = this.global.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.global.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.global.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 e_9, _a, e_10, _b, e_11, _c; var _this = this; var originalPath = this.getPath(); if (originalPath === newPath) return this; var fileSystem = this.global.fileSystemWrapper; var copyingDirectories = 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 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 _d = copyingDirectories_1_1.value, directory = _d.directory, oldPath = _d.oldPath, newDirPath = _d.newDirPath; this.global.compilerFactory.createDirectoryOrAddIfExists(newDirPath); } } 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 this.global.compilerFactory.getDirectoryFromCache(newPath); }; /** * 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.global.fileSystemWrapper; var originalPath = this.getPath(); var newPath = fileSystem.getStandardizedAbsolutePath(relativeOrAbsolutePath, originalPath); if (originalPath === newPath) return this; fileSystem.queueMoveDirectory(originalPath, newPath); return this._moveInternal(newPath, options); }; /** * 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.global.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.global.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) { var e_12, _a, e_13, _b, e_14, _c; var _this = this; var originalPath = this.getPath(); if (originalPath === newPath) return this; var fileSystem = this.global.fileSystemWrapper; var compilerFactory = this.global.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; } } 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.global.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.global.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.global.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.global.compilerFactory.removeDirectoryFromCache(this.getPath()); this._global = 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.global.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.global.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.global.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._global == null; }; /** @internal */ Directory.prototype._hasLoadedParent = function () { return this.global.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.isAncestorOf(r[1]); }), referencingLiterals: referencingLiterals.filter(function (l) { return !_this.isAncestorOf(l.sourceFile); }) }; }; /** @internal */ Directory.isAncestorOfDir = function (ancestor, descendant) { if (descendant instanceof compiler_1.SourceFile) { descendant = descendant.getDirectory(); if (ancestor === descendant) return true; } if (ancestor._pathParts.length >= descendant._pathParts.length) return false; // more likely to be a mistake at the end, so search backwards for (var i = ancestor._pathParts.length - 1; i >= 0; i--) { if (ancestor._pathParts[i] !== descendant._pathParts[i]) return false; } return true; }; return Directory; }()); exports.Directory = Directory; function getDirectoryCopyOptions(options) { options = utils_1.ObjectUtils.clone(options || {}); utils_1.setValueIfUndefined(options, "includeUntrackedFiles", true); return options; }