ts-simple-ast
Version:
TypeScript compiler wrapper for AST navigation and code generation.
776 lines (775 loc) • 35 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter)/* istanbul ignore next */ || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator)/* istanbul ignore next */ || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [0, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __read = (this && this.__read)/* istanbul ignore next */ || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __spread = (this && this.__spread)/* istanbul ignore next */ || function () {
for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));
return ar;
};
var __values = (this && this.__values)/* istanbul ignore next */ || function (o) {
var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
if (m) return m.call(o);
return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
};
Object.defineProperty(exports, "__esModule", { value: true });
var compiler_1 = require("./../compiler");
var errors = require("./../errors");
var utils_1 = require("./../utils");
var DirectoryEmitResult_1 = require("./DirectoryEmitResult");
var Directory = /** @class */ (function () {
/** @internal */
function Directory(global, _path) {
this._path = _path;
this._directories = [];
this._sourceFiles = [];
this._global = global;
this._pathParts = this._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 () {
this.throwIfDeletedOrRemoved();
return this._parent;
};
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 '" + utils_1.FileUtils.getStandardizedAbsolutePath(_this.global.fileSystem, pathOrCondition, _this.getPath()) + "'.";
return "Could not find child directory that matched condition.";
});
};
Directory.prototype.getDirectory = function (pathOrCondition) {
if (typeof pathOrCondition === "string") {
var path = utils_1.FileUtils.getStandardizedAbsolutePath(this.global.fileSystem, pathOrCondition, this.getPath());
return this.global.compilerFactory.getDirectory(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 '" + utils_1.FileUtils.getStandardizedAbsolutePath(_this.global.fileSystem, pathOrCondition, _this.getPath()) + "'.";
return "Could not find child source file that matched condition.";
});
};
Directory.prototype.getSourceFile = function (pathOrCondition) {
if (typeof pathOrCondition === "string") {
var path = utils_1.FileUtils.getStandardizedAbsolutePath(this.global.fileSystem, pathOrCondition, this.getPath());
if (this.global.compilerFactory.containsSourceFileAtPath(path))
return this.global.compilerFactory.getSourceFileFromFilePath(path);
else
return undefined;
}
return utils_1.ArrayUtils.find(this.getSourceFiles(), pathOrCondition);
};
/**
* Gets the child directories.
*/
Directory.prototype.getDirectories = function () {
this.throwIfDeletedOrRemoved();
return __spread(this._directories);
};
/**
* Gets the source files within this directory.
*/
Directory.prototype.getSourceFiles = function () {
this.throwIfDeletedOrRemoved();
return __spread(this._sourceFiles);
};
/**
* 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 _a, _b, sourceFile, e_1_1, _c, _d, directory, e_2_1, e_1, _e, e_2, _f;
return __generator(this, function (_g) {
switch (_g.label) {
case 0:
this.throwIfDeletedOrRemoved();
_g.label = 1;
case 1:
_g.trys.push([1, 6, 7, 8]);
_a = __values(this._sourceFiles), _b = _a.next();
_g.label = 2;
case 2:
if (!!_b.done) return [3 /*break*/, 5];
sourceFile = _b.value;
return [4 /*yield*/, sourceFile];
case 3:
_g.sent();
_g.label = 4;
case 4:
_b = _a.next();
return [3 /*break*/, 2];
case 5: return [3 /*break*/, 8];
case 6:
e_1_1 = _g.sent();
e_1 = { error: e_1_1 };
return [3 /*break*/, 8];
case 7:
try {
if (_b && !_b.done && (_e = _a.return)) _e.call(_a);
}
finally { if (e_1) throw e_1.error; }
return [7 /*endfinally*/];
case 8:
_g.trys.push([8, 13, 14, 15]);
_c = __values(this._directories), _d = _c.next();
_g.label = 9;
case 9:
if (!!_d.done) return [3 /*break*/, 12];
directory = _d.value;
return [5 /*yield**/, __values(directory.getDescendantSourceFilesIterator())];
case 10:
_g.sent();
_g.label = 11;
case 11:
_d = _c.next();
return [3 /*break*/, 9];
case 12: return [3 /*break*/, 15];
case 13:
e_2_1 = _g.sent();
e_2 = { error: e_2_1 };
return [3 /*break*/, 15];
case 14:
try {
if (_d && !_d.done && (_f = _c.return)) _f.call(_c);
}
finally { if (e_2) throw e_2.error; }
return [7 /*endfinally*/];
case 15: 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 _a, _b, directory, e_3_1, e_3, _c;
return __generator(this, function (_d) {
switch (_d.label) {
case 0:
this.throwIfDeletedOrRemoved();
_d.label = 1;
case 1:
_d.trys.push([1, 7, 8, 9]);
_a = __values(this._directories), _b = _a.next();
_d.label = 2;
case 2:
if (!!_b.done) return [3 /*break*/, 6];
directory = _b.value;
return [4 /*yield*/, directory];
case 3:
_d.sent();
return [5 /*yield**/, __values(directory.getDescendantDirectoriesIterator())];
case 4:
_d.sent();
_d.label = 5;
case 5:
_b = _a.next();
return [3 /*break*/, 2];
case 6: return [3 /*break*/, 9];
case 7:
e_3_1 = _d.sent();
e_3 = { error: e_3_1 };
return [3 /*break*/, 9];
case 8:
try {
if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
}
finally { if (e_3) throw e_3.error; }
return [7 /*endfinally*/];
case 9: 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 path - Directory name or path to the directory that should be added.
*/
Directory.prototype.addDirectoryIfExists = function (path) {
var dirPath = utils_1.FileUtils.getStandardizedAbsolutePath(this.global.fileSystem, path, this.getPath());
return this.global.compilerFactory.getDirectoryFromPath(dirPath);
};
/**
* 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 path - Directory name or path to the directory that should be added.
* @throws DirectoryNotFoundError if the directory does not exist.
*/
Directory.prototype.addExistingDirectory = function (path) {
var dirPath = utils_1.FileUtils.getStandardizedAbsolutePath(this.global.fileSystem, path, this.getPath());
var directory = this.addDirectoryIfExists(dirPath);
if (directory == null)
throw new errors.DirectoryNotFoundError(dirPath);
return directory;
};
/**
* Creates a directory if it doesn't exist.
* @param path - Relative or absolute path to the directory that should be created.
*/
Directory.prototype.createDirectory = function (path) {
var dirPath = utils_1.FileUtils.getStandardizedAbsolutePath(this.global.fileSystem, path, this.getPath());
return this.global.compilerFactory.createDirectory(dirPath);
};
Directory.prototype.createSourceFile = function (relativeFilePath, structureOrText) {
var filePath = utils_1.FileUtils.getStandardizedAbsolutePath(this.global.fileSystem, relativeFilePath, this.getPath());
return this.global.compilerFactory.createSourceFile(filePath, structureOrText);
};
/**
* 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.
*/
Directory.prototype.addSourceFileIfExists = function (relativeFilePath) {
var filePath = utils_1.FileUtils.getStandardizedAbsolutePath(this.global.fileSystem, relativeFilePath, this.getPath());
return this.global.compilerFactory.getSourceFileFromFilePath(filePath);
};
/**
* 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.
* @throws FileNotFoundError when the file doesn't exist.
*/
Directory.prototype.addExistingSourceFile = function (relativeFilePath) {
var sourceFile = this.addSourceFileIfExists(relativeFilePath);
if (sourceFile == null)
throw new errors.FileNotFoundError(utils_1.FileUtils.getStandardizedAbsolutePath(this.global.fileSystem, 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 __awaiter(this, void 0, void 0, function () {
var fileSystem, writeTasks, outputFilePaths, _a, _b, emitResult, e_4_1, e_4, _c;
return __generator(this, function (_d) {
switch (_d.label) {
case 0:
fileSystem = this.global.fileSystem;
writeTasks = [];
outputFilePaths = [];
_d.label = 1;
case 1:
_d.trys.push([1, 7, 8, 9]);
_a = __values(this._emitInternal(options)), _b = _a.next();
_d.label = 2;
case 2:
if (!!_b.done) return [3 /*break*/, 6];
emitResult = _b.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(fileSystem.writeFile(emitResult.filePath, emitResult.fileText));
outputFilePaths.push(emitResult.filePath);
_d.label = 5;
case 5:
_b = _a.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 (_b && !_b.done && (_c = _a.return)) _c.call(_a);
}
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 fileSystem = this.global.fileSystem;
var outputFilePaths = [];
try {
for (var _a = __values(this._emitInternal(options)), _b = _a.next(); !_b.done; _b = _a.next()) {
var emitResult = _b.value;
if (emitResult === false)
return new DirectoryEmitResult_1.DirectoryEmitResult(true, outputFilePaths);
fileSystem.writeFileSync(emitResult.filePath, emitResult.fileText);
outputFilePaths.push(emitResult.filePath);
}
}
catch (e_5_1) { e_5 = { error: e_5_1 }; }
finally {
try {
if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
}
finally { if (e_5) throw e_5.error; }
}
return new DirectoryEmitResult_1.DirectoryEmitResult(false, outputFilePaths);
var e_5, _c;
};
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 : utils_1.FileUtils.getStandardizedAbsolutePath(_this.global.fileSystem, path, _this.getPath()); };
var getSubDirPath = function (path, dir) { return path == null ? undefined : utils_1.FileUtils.pathJoin(path, dir.getBaseName()); };
var hasDeclarationDir = this.global.compilerOptions.declarationDir != null || options.declarationDir != null;
return emitDirectory(this, getStandardizedPath(options.outDir), getStandardizedPath(options.declarationDir));
function emitDirectory(directory, outDir, declarationDir) {
var _a, _b, sourceFile, output, _c, _d, outputFile, filePath, fileText, e_6_1, e_7_1, _e, _f, dir, e_8_1, e_7, _g, e_6, _h, e_8, _j;
return __generator(this, function (_k) {
switch (_k.label) {
case 0:
_k.trys.push([0, 12, 13, 14]);
_a = __values(directory.getSourceFiles()), _b = _a.next();
_k.label = 1;
case 1:
if (!!_b.done) return [3 /*break*/, 11];
sourceFile = _b.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]);
_c = __values(output.getOutputFiles()), _d = _c.next();
_k.label = 4;
case 4:
if (!!_d.done) return [3 /*break*/, 7];
outputFile = _d.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:
_d = _c.next();
return [3 /*break*/, 4];
case 7: return [3 /*break*/, 10];
case 8:
e_6_1 = _k.sent();
e_6 = { error: e_6_1 };
return [3 /*break*/, 10];
case 9:
try {
if (_d && !_d.done && (_h = _c.return)) _h.call(_c);
}
finally { if (e_6) throw e_6.error; }
return [7 /*endfinally*/];
case 10:
_b = _a.next();
return [3 /*break*/, 1];
case 11: return [3 /*break*/, 14];
case 12:
e_7_1 = _k.sent();
e_7 = { error: e_7_1 };
return [3 /*break*/, 14];
case 13:
try {
if (_b && !_b.done && (_g = _a.return)) _g.call(_a);
}
finally { if (e_7) throw e_7.error; }
return [7 /*endfinally*/];
case 14:
_k.trys.push([14, 19, 20, 21]);
_e = __values(directory.getDirectories()), _f = _e.next();
_k.label = 15;
case 15:
if (!!_f.done) return [3 /*break*/, 18];
dir = _f.value;
return [5 /*yield**/, __values(emitDirectory(dir, getSubDirPath(outDir, dir), getSubDirPath(declarationDir, dir)))];
case 16:
_k.sent();
_k.label = 17;
case 17:
_f = _e.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 (_f && !_f.done && (_j = _e.return)) _j.call(_e);
}
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) {
if (options === void 0) { options = {}; }
var newPath = utils_1.FileUtils.getStandardizedAbsolutePath(this.global.fileSystem, relativeOrAbsolutePath, this.getPath());
var directory = this.global.compilerFactory.createOrAddDirectoryIfNotExists(newPath);
try {
for (var _a = __values(this.getSourceFiles()), _b = _a.next(); !_b.done; _b = _a.next()) {
var sourceFile = _b.value;
sourceFile.copy(utils_1.FileUtils.pathJoin(newPath, sourceFile.getBaseName()), options);
}
}
catch (e_9_1) { e_9 = { error: e_9_1 }; }
finally {
try {
if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
}
finally { if (e_9) throw e_9.error; }
}
try {
for (var _d = __values(this.getDirectories()), _e = _d.next(); !_e.done; _e = _d.next()) {
var childDir = _e.value;
childDir.copy(utils_1.FileUtils.pathJoin(newPath, childDir.getBaseName()), options);
}
}
catch (e_10_1) { e_10 = { error: e_10_1 }; }
finally {
try {
if (_e && !_e.done && (_f = _d.return)) _f.call(_d);
}
finally { if (e_10) throw e_10.error; }
}
return directory;
var e_9, _c, e_10, _f;
};
/**
* Asyncronously deletes the directory and all its descendants.
*
* WARNING: This will delete the directory from the file system.
*/
Directory.prototype.delete = function () {
return __awaiter(this, void 0, void 0, function () {
var fileSystem, path;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
fileSystem = this.global.fileSystem;
path = this.getPath();
this.remove();
return [4 /*yield*/, fileSystem.delete(path)];
case 1:
_a.sent();
return [2 /*return*/];
}
});
});
};
/**
* Synchronously deletes the directory and all its descendants.
*
* WARNING: This will delete the directory from the file system.
*/
Directory.prototype.deleteSync = function () {
var fileSystem = this.global.fileSystem;
var path = this.getPath();
this.remove();
fileSystem.deleteSync(path);
};
/**
* Removes the directory and all its descendants from the AST.
*
* Note: Does not delete the directory from the file system.
*/
Directory.prototype.remove = function () {
try {
for (var _a = __values(this._sourceFiles), _b = _a.next(); !_b.done; _b = _a.next()) {
var sourceFile = _b.value;
sourceFile.forget();
}
}
catch (e_11_1) { e_11 = { error: e_11_1 }; }
finally {
try {
if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
}
finally { if (e_11) throw e_11.error; }
}
try {
for (var _d = __values(this._directories), _e = _d.next(); !_e.done; _e = _d.next()) {
var dir = _e.value;
dir.remove();
}
}
catch (e_12_1) { e_12 = { error: e_12_1 }; }
finally {
try {
if (_e && !_e.done && (_f = _d.return)) _f.call(_d);
}
finally { if (e_12) throw e_12.error; }
}
this.global.compilerFactory.removeDirectoryFromCache(this);
if (this._parent != null)
this._parent._removeDirectory(this);
this._global = undefined;
var e_11, _c, e_12, _f;
};
/**
* Saves all the unsaved descendant source files.
*/
Directory.prototype.saveUnsavedSourceFiles = function () {
return Promise.all(this._getUnsavedSourceFiles().map(function (f) { return f.save(); }));
};
/**
* Saves all the unsaved descendant source files synchronously.
*
* Remarks: This might be very slow compared to the asynchronous version if there are a lot of files.
*/
Directory.prototype.saveUnsavedSourceFilesSync = function () {
try {
for (var _a = __values(this._getUnsavedSourceFiles()), _b = _a.next(); !_b.done; _b = _a.next()) {
var file = _b.value;
file.saveSync();
}
}
catch (e_13_1) { e_13 = { error: e_13_1 }; }
finally {
try {
if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
}
finally { if (e_13) throw e_13.error; }
}
var e_13, _c;
};
/** @internal */
Directory.prototype._addSourceFile = function (sourceFile) {
var baseName = sourceFile.getBaseName().toUpperCase();
utils_1.ArrayUtils.binaryInsert(this._sourceFiles, sourceFile, function (item) { return item.getBaseName().toUpperCase() > baseName; });
};
/** @internal */
Directory.prototype._removeSourceFile = function (filePath) {
for (var i = 0; i < this._sourceFiles.length; i++) {
if (this._sourceFiles[i].getFilePath() === filePath) {
this._sourceFiles.splice(i, 1);
break;
}
}
};
/** @internal */
Directory.prototype._addDirectory = function (dir) {
var baseName = dir.getBaseName().toUpperCase();
utils_1.ArrayUtils.binaryInsert(this._directories, dir, function (item) { return item.getBaseName().toUpperCase() > baseName; });
dir._parent = this;
};
/** @internal */
Directory.prototype._wasRemoved = function () {
return this._global == null;
};
/** @internal */
Directory.prototype._removeDirectory = function (dir) {
var index = this._directories.indexOf(dir);
if (index >= 0)
this._directories.splice(index, 1);
};
Directory.prototype.throwIfDeletedOrRemoved = function () {
if (this._wasRemoved())
throw new errors.InvalidOperationError("Cannot use a directory that was deleted or removed.");
};
Directory.prototype._getUnsavedSourceFiles = function () {
return utils_1.ArrayUtils.from(getUnsavedIterator(this.getDescendantSourceFilesIterator()));
function getUnsavedIterator(sourceFiles) {
var sourceFiles_1, sourceFiles_1_1, sourceFile, e_14_1, e_14, _a;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
_b.trys.push([0, 5, 6, 7]);
sourceFiles_1 = __values(sourceFiles), sourceFiles_1_1 = sourceFiles_1.next();
_b.label = 1;
case 1:
if (!!sourceFiles_1_1.done) return [3 /*break*/, 4];
sourceFile = sourceFiles_1_1.value;
if (!!sourceFile.isSaved()) return [3 /*break*/, 3];
return [4 /*yield*/, sourceFile];
case 2:
_b.sent();
_b.label = 3;
case 3:
sourceFiles_1_1 = sourceFiles_1.next();
return [3 /*break*/, 1];
case 4: return [3 /*break*/, 7];
case 5:
e_14_1 = _b.sent();
e_14 = { error: e_14_1 };
return [3 /*break*/, 7];
case 6:
try {
if (sourceFiles_1_1 && !sourceFiles_1_1.done && (_a = sourceFiles_1.return)) _a.call(sourceFiles_1);
}
finally { if (e_14) throw e_14.error; }
return [7 /*endfinally*/];
case 7: return [2 /*return*/];
}
});
}
};
/** @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;