@lcap/nasl
Version:
NetEase Application Specific Language
1,159 lines (1,157 loc) • 156 kB
JavaScript
const ts = require('../lib/tsserver');
'use strict';
const __generator = (this && this.__generator) || function (thisArg, body) {
let _ = { label: 0, sent() {
if (t[0] & 1)
throw t[1]; return t[1];
}, trys: [], ops: [] }; let f; let y; let t; let 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 = op[0] & 2 ? y.return : op[0] ? y.throw || ((t = y.return) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done)
return t;
if (y = 0, t)
op = [op[0] & 2, 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 };
}
};
const __values = (this && this.__values) || function (o) {
const s = typeof Symbol === 'function' && Symbol.iterator; const m = s && o[s]; let
i = 0;
if (m)
return m.call(o);
if (o && typeof o.length === 'number')
return {
next() {
if (o && i >= o.length)
o = void 0;
return { value: o && o[i++], done: !o };
},
};
throw new TypeError(s ? 'Object is not iterable.' : 'Symbol.iterator is not defined.');
};
const __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf
|| ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; })
|| function (d, b) {
for (const p in b)
if (Object.prototype.hasOwnProperty.call(b, p))
d[p] = b[p];
};
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== 'function' && b !== null)
throw new TypeError('Class extends value ' + String(b) + ' is not a constructor or null');
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function (t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (const p in s)
if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
const __rest = (this && this.__rest) || function (s, e) {
const t = {};
for (var p in s)
if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === 'function')
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
const __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2)
for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar)
ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || from);
};
let collections;
(function (collections) {
const SortedMap = /** @class */ (function () {
function SortedMap(comparer, iterable) {
this._keys = [];
this._values = [];
this._version = 0;
this._copyOnWrite = false;
this._comparer = typeof comparer === 'object' ? comparer.comparer : comparer;
this._order = typeof comparer === 'object' && comparer.sort === 'insertion' ? [] : undefined;
if (iterable) {
const iterator = getIterator(iterable);
try {
for (let i = nextResult(iterator); i; i = nextResult(iterator)) {
const _a = i.value; const key = _a[0]; const
value = _a[1];
this.set(key, value);
}
} finally {
closeIterator(iterator);
}
}
}
Object.defineProperty(SortedMap.prototype, 'size', {
get() {
return this._keys.length;
},
enumerable: false,
configurable: true,
});
Object.defineProperty(SortedMap.prototype, 'comparer', {
get() {
return this._comparer;
},
enumerable: false,
configurable: true,
});
Object.defineProperty(SortedMap.prototype, Symbol.toStringTag, {
get() {
return 'SortedMap';
},
enumerable: false,
configurable: true,
});
SortedMap.prototype.has = function (key) {
return ts.binarySearch(this._keys, key, ts.identity, this._comparer) >= 0;
};
SortedMap.prototype.get = function (key) {
const index = ts.binarySearch(this._keys, key, ts.identity, this._comparer);
return index >= 0 ? this._values[index] : undefined;
};
SortedMap.prototype.getEntry = function (key) {
const index = ts.binarySearch(this._keys, key, ts.identity, this._comparer);
return index >= 0 ? [this._keys[index], this._values[index]] : undefined;
};
SortedMap.prototype.set = function (key, value) {
const index = ts.binarySearch(this._keys, key, ts.identity, this._comparer);
if (index >= 0) {
this._values[index] = value;
} else {
this.writePreamble();
insertAt(this._keys, ~index, key);
insertAt(this._values, ~index, value);
if (this._order)
insertAt(this._order, ~index, this._version);
this.writePostScript();
}
return this;
};
SortedMap.prototype.delete = function (key) {
const index = ts.binarySearch(this._keys, key, ts.identity, this._comparer);
if (index >= 0) {
this.writePreamble();
ts.orderedRemoveItemAt(this._keys, index);
ts.orderedRemoveItemAt(this._values, index);
if (this._order)
ts.orderedRemoveItemAt(this._order, index);
this.writePostScript();
return true;
}
return false;
};
SortedMap.prototype.clear = function () {
if (this.size > 0) {
this.writePreamble();
this._keys.length = 0;
this._values.length = 0;
if (this._order)
this._order.length = 0;
this.writePostScript();
}
};
SortedMap.prototype.forEach = function (callback, thisArg) {
const keys = this._keys;
const values = this._values;
const indices = this.getIterationOrder();
const version = this._version;
this._copyOnWrite = true;
try {
if (indices) {
for (let _i = 0, indices_1 = indices; _i < indices_1.length; _i++) {
var i = indices_1[_i];
callback.call(thisArg, values[i], keys[i], this);
}
} else {
for (var i = 0; i < keys.length; i++) {
callback.call(thisArg, values[i], keys[i], this);
}
}
} finally {
if (version === this._version) {
this._copyOnWrite = false;
}
}
};
SortedMap.prototype.keys = function () {
let keys; let indices; let version; let _i; let indices_2; let i;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
keys = this._keys;
indices = this.getIterationOrder();
version = this._version;
this._copyOnWrite = true;
_a.label = 1;
case 1:
_a.trys.push([1, , 9, 10]);
if (!indices)
return [3 /*break*/, 6];
_i = 0, indices_2 = indices;
_a.label = 2;
case 2:
if (!(_i < indices_2.length))
return [3 /*break*/, 5];
i = indices_2[_i];
return [4 /*yield*/, keys[i]];
case 3:
_a.sent();
_a.label = 4;
case 4:
_i++;
return [3 /*break*/, 2];
case 5: return [3 /*break*/, 8];
case 6: return [5 /*yield**/, __values(keys)];
case 7:
_a.sent();
_a.label = 8;
case 8: return [3 /*break*/, 10];
case 9:
if (version === this._version) {
this._copyOnWrite = false;
}
return [7];
case 10: return [2];
}
});
};
SortedMap.prototype.values = function () {
let values; let indices; let version; let _i; let indices_3; let i;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
values = this._values;
indices = this.getIterationOrder();
version = this._version;
this._copyOnWrite = true;
_a.label = 1;
case 1:
_a.trys.push([1, , 9, 10]);
if (!indices)
return [3 /*break*/, 6];
_i = 0, indices_3 = indices;
_a.label = 2;
case 2:
if (!(_i < indices_3.length))
return [3 /*break*/, 5];
i = indices_3[_i];
return [4 /*yield*/, values[i]];
case 3:
_a.sent();
_a.label = 4;
case 4:
_i++;
return [3 /*break*/, 2];
case 5: return [3 /*break*/, 8];
case 6: return [5 /*yield**/, __values(values)];
case 7:
_a.sent();
_a.label = 8;
case 8: return [3 /*break*/, 10];
case 9:
if (version === this._version) {
this._copyOnWrite = false;
}
return [7];
case 10: return [2];
}
});
};
SortedMap.prototype.entries = function () {
let keys; let values; let indices; let version; let _i; let indices_4; var i; var i;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
keys = this._keys;
values = this._values;
indices = this.getIterationOrder();
version = this._version;
this._copyOnWrite = true;
_a.label = 1;
case 1:
_a.trys.push([1, , 11, 12]);
if (!indices)
return [3 /*break*/, 6];
_i = 0, indices_4 = indices;
_a.label = 2;
case 2:
if (!(_i < indices_4.length))
return [3 /*break*/, 5];
i = indices_4[_i];
return [4 /*yield*/, [keys[i], values[i]]];
case 3:
_a.sent();
_a.label = 4;
case 4:
_i++;
return [3 /*break*/, 2];
case 5: return [3 /*break*/, 10];
case 6:
i = 0;
_a.label = 7;
case 7:
if (!(i < keys.length))
return [3 /*break*/, 10];
return [4 /*yield*/, [keys[i], values[i]]];
case 8:
_a.sent();
_a.label = 9;
case 9:
i++;
return [3 /*break*/, 7];
case 10: return [3 /*break*/, 12];
case 11:
if (version === this._version) {
this._copyOnWrite = false;
}
return [7];
case 12: return [2];
}
});
};
SortedMap.prototype[Symbol.iterator] = function () {
return this.entries();
};
SortedMap.prototype.writePreamble = function () {
if (this._copyOnWrite) {
this._keys = this._keys.slice();
this._values = this._values.slice();
if (this._order)
this._order = this._order.slice();
this._copyOnWrite = false;
}
};
SortedMap.prototype.writePostScript = function () {
this._version++;
};
SortedMap.prototype.getIterationOrder = function () {
if (this._order) {
const order_1 = this._order;
return this._order
.map((_, i) => i)
.sort((x, y) => order_1[x] - order_1[y]);
}
return undefined;
};
return SortedMap;
})();
collections.SortedMap = SortedMap;
function insertAt(array, index, value) {
if (index === 0) {
array.unshift(value);
} else if (index === array.length) {
array.push(value);
} else {
for (let i = array.length; i > index; i--) {
array[i] = array[i - 1];
}
array[index] = value;
}
}
collections.insertAt = insertAt;
function getIterator(iterable) {
return iterable[Symbol.iterator]();
}
collections.getIterator = getIterator;
function nextResult(iterator) {
const result = iterator.next();
return result.done ? undefined : result;
}
collections.nextResult = nextResult;
function closeIterator(iterator) {
const fn = iterator.return;
if (typeof fn === 'function')
fn.call(iterator);
}
collections.closeIterator = closeIterator;
/**
* A collection of metadata that supports inheritance.
*/
const Metadata = /** @class */ (function () {
function Metadata(parent) {
this._version = 0;
this._size = -1;
this._parent = parent;
this._map = Object.create(parent ? parent._map : null); // eslint-disable-line no-null/no-null
}
Object.defineProperty(Metadata.prototype, 'size', {
get() {
if (this._size === -1 || (this._parent && this._parent._version !== this._parentVersion)) {
let size = 0;
for (const _ in this._map)
size++;
this._size = size;
if (this._parent) {
this._parentVersion = this._parent._version;
}
}
return this._size;
},
enumerable: false,
configurable: true,
});
Object.defineProperty(Metadata.prototype, 'parent', {
get() {
return this._parent;
},
enumerable: false,
configurable: true,
});
Metadata.prototype.has = function (key) {
return this._map[Metadata._escapeKey(key)] !== undefined;
};
Metadata.prototype.get = function (key) {
const value = this._map[Metadata._escapeKey(key)];
return value === Metadata._undefinedValue ? undefined : value;
};
Metadata.prototype.set = function (key, value) {
this._map[Metadata._escapeKey(key)] = value === undefined ? Metadata._undefinedValue : value;
this._size = -1;
this._version++;
return this;
};
Metadata.prototype.delete = function (key) {
const escapedKey = Metadata._escapeKey(key);
if (this._map[escapedKey] !== undefined) {
delete this._map[escapedKey];
this._size = -1;
this._version++;
return true;
}
return false;
};
Metadata.prototype.clear = function () {
this._map = Object.create(this._parent ? this._parent._map : null); // eslint-disable-line no-null/no-null
this._size = -1;
this._version++;
};
Metadata.prototype.forEach = function (callback) {
for (const key in this._map) {
callback(this._map[key], Metadata._unescapeKey(key), this);
}
};
Metadata._escapeKey = function (text) {
return (text.length >= 2 && text.charAt(0) === '_' && text.charAt(1) === '_' ? '_' + text : text);
};
Metadata._unescapeKey = function (text) {
return (text.length >= 3 && text.charAt(0) === '_' && text.charAt(1) === '_' && text.charAt(2) === '_' ? text.slice(1) : text);
};
Metadata._undefinedValue = {};
return Metadata;
})();
collections.Metadata = Metadata;
})(collections || (collections = {}));
// NOTE: The contents of this file are all exported from the namespace 'documents'. This is to
// support the eventual conversion of harness into a modular system.
let documents;
(function (documents) {
const TextDocument = /** @class */ (function () {
function TextDocument(file, text, meta) {
this.file = file;
this.text = text;
this.meta = meta || new Map();
}
Object.defineProperty(TextDocument.prototype, 'lineStarts', {
get() {
return this._lineStarts || (this._lineStarts = ts.computeLineStarts(this.text));
},
enumerable: false,
configurable: true,
});
TextDocument.fromTestFile = function (file) {
return new TextDocument(file.unitName, file.content, file.fileOptions && Object.keys(file.fileOptions)
.reduce((meta, key) => meta.set(key, file.fileOptions[key]), new Map()));
};
TextDocument.prototype.asTestFile = function () {
return this._testFile || (this._testFile = {
unitName: this.file,
content: this.text,
fileOptions: Array.from(this.meta)
.reduce((obj, _a) => {
const key = _a[0]; const
value = _a[1];
return (obj[key] = value, obj);
}, {}),
});
};
return TextDocument;
})();
documents.TextDocument = TextDocument;
const SourceMap = /** @class */ (function () {
function SourceMap(mapFile, data) {
this.sources = [];
this.mappings = [];
this._emittedLineMappings = [];
this._sourceLineMappings = [];
this.raw = typeof data === 'string' ? JSON.parse(data) : data;
this.mapFile = mapFile;
this.version = this.raw.version;
this.file = this.raw.file;
this.sourceRoot = this.raw.sourceRoot;
this.sources = this.raw.sources;
this.sourcesContent = this.raw.sourcesContent;
this.names = this.raw.names;
// populate mappings
const mappings = [];
let emittedLine = 0;
let emittedColumn = 0;
let sourceIndex = 0;
let sourceLine = 0;
let sourceColumn = 0;
let nameIndex = 0;
let match;
while (match = SourceMap._mappingRegExp.exec(this.raw.mappings)) {
if (match[1]) {
const segment = SourceMap._decodeVLQ(match[1]);
if (segment.length !== 1 && segment.length !== 4 && segment.length !== 5) {
throw new Error('Invalid VLQ');
}
emittedColumn += segment[0];
if (segment.length >= 4) {
sourceIndex += segment[1];
sourceLine += segment[2];
sourceColumn += segment[3];
}
const mapping = { mappingIndex: mappings.length, emittedLine, emittedColumn, sourceIndex, sourceLine, sourceColumn };
if (segment.length === 5) {
nameIndex += segment[4];
mapping.nameIndex = nameIndex;
}
mappings.push(mapping);
const mappingsForEmittedLine = this._emittedLineMappings[mapping.emittedLine] || (this._emittedLineMappings[mapping.emittedLine] = []);
mappingsForEmittedLine.push(mapping);
const mappingsForSource = this._sourceLineMappings[mapping.sourceIndex] || (this._sourceLineMappings[mapping.sourceIndex] = []);
const mappingsForSourceLine = mappingsForSource[mapping.sourceLine] || (mappingsForSource[mapping.sourceLine] = []);
mappingsForSourceLine.push(mapping);
} else if (match[2]) {
emittedLine++;
emittedColumn = 0;
} else {
throw new Error("Unrecognized character '" + match[0] + "'.");
}
}
this.mappings = mappings;
}
SourceMap.getUrl = function (text) {
let match;
let lastMatch;
while (match = SourceMap._sourceMappingURLRegExp.exec(text)) {
lastMatch = match;
}
return lastMatch ? lastMatch[1] : undefined;
};
SourceMap.fromUrl = function (url) {
const match = SourceMap._dataURLRegExp.exec(url);
return match ? new SourceMap(/*mapFile*/ undefined, ts.sys.base64decode(match[1])) : undefined;
};
SourceMap.fromSource = function (text) {
const url = this.getUrl(text);
return url === undefined ? undefined : this.fromUrl(url);
};
SourceMap.prototype.getMappingsForEmittedLine = function (emittedLine) {
return this._emittedLineMappings[emittedLine];
};
SourceMap.prototype.getMappingsForSourceLine = function (sourceIndex, sourceLine) {
const mappingsForSource = this._sourceLineMappings[sourceIndex];
return mappingsForSource && mappingsForSource[sourceLine];
};
SourceMap._decodeVLQ = function (text) {
const vlq = [];
let shift = 0;
let value = 0;
for (let i = 0; i < text.length; i++) {
const currentByte = SourceMap._base64Chars.indexOf(text.charAt(i));
value += (currentByte & 31) << shift;
if ((currentByte & 32) === 0) {
vlq.push(value & 1 ? -(value >>> 1) : value >>> 1);
shift = 0;
value = 0;
} else {
shift += 5;
}
}
return vlq;
};
SourceMap._mappingRegExp = /([A-Za-z0-9+/]+),?|(;)|./g;
SourceMap._sourceMappingURLRegExp = /^\/\/[#@]\s*sourceMappingURL\s*=\s*(.*?)\s*$/mig;
SourceMap._dataURLRegExp = /^data:application\/json;base64,([a-z0-9+/=]+)$/i;
SourceMap._base64Chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
return SourceMap;
})();
documents.SourceMap = SourceMap;
})(documents || (documents = {}));
let vpath;
(function (vpath) {
vpath.sep = ts.directorySeparator;
vpath.normalizeSeparators = ts.normalizeSlashes;
vpath.isAbsolute = ts.isRootedDiskPath;
vpath.isRoot = ts.isDiskPathRoot;
vpath.hasTrailingSeparator = ts.hasTrailingDirectorySeparator;
vpath.addTrailingSeparator = ts.ensureTrailingDirectorySeparator;
vpath.removeTrailingSeparator = ts.removeTrailingDirectorySeparator;
vpath.normalize = ts.normalizePath;
vpath.combine = ts.combinePaths;
vpath.parse = ts.getPathComponents;
vpath.reduce = ts.reducePathComponents;
vpath.format = ts.getPathFromPathComponents;
vpath.resolve = ts.resolvePath;
vpath.compare = ts.comparePaths;
vpath.compareCaseSensitive = ts.comparePathsCaseSensitive;
vpath.compareCaseInsensitive = ts.comparePathsCaseInsensitive;
vpath.dirname = ts.getDirectoryPath;
vpath.basename = ts.getBaseFileName;
vpath.extname = ts.getAnyExtensionFromPath;
vpath.relative = ts.getRelativePathFromDirectory;
vpath.beneath = ts.containsPath;
vpath.changeExtension = ts.changeAnyExtension;
vpath.isTypeScript = ts.hasTSFileExtension;
vpath.isJavaScript = ts.hasJSFileExtension;
const invalidRootComponentRegExp = /^(?!(\/|\/\/\w+\/|[a-zA-Z]:\/?|)$)/;
const invalidNavigableComponentRegExp = /[:*?"<>|]/;
const invalidNavigableComponentWithWildcardsRegExp = /[:"<>|]/;
const invalidNonNavigableComponentRegExp = /^\.{1,2}$|[:*?"<>|]/;
const invalidNonNavigableComponentWithWildcardsRegExp = /^\.{1,2}$|[:"<>|]/;
const extRegExp = /\.\w+$/;
let ValidationFlags;
(function (ValidationFlags) {
ValidationFlags[ValidationFlags.None = 0] = 'None';
ValidationFlags[ValidationFlags.RequireRoot = 1] = 'RequireRoot';
ValidationFlags[ValidationFlags.RequireDirname = 2] = 'RequireDirname';
ValidationFlags[ValidationFlags.RequireBasename = 4] = 'RequireBasename';
ValidationFlags[ValidationFlags.RequireExtname = 8] = 'RequireExtname';
ValidationFlags[ValidationFlags.RequireTrailingSeparator = 16] = 'RequireTrailingSeparator';
ValidationFlags[ValidationFlags.AllowRoot = 32] = 'AllowRoot';
ValidationFlags[ValidationFlags.AllowDirname = 64] = 'AllowDirname';
ValidationFlags[ValidationFlags.AllowBasename = 128] = 'AllowBasename';
ValidationFlags[ValidationFlags.AllowExtname = 256] = 'AllowExtname';
ValidationFlags[ValidationFlags.AllowTrailingSeparator = 512] = 'AllowTrailingSeparator';
ValidationFlags[ValidationFlags.AllowNavigation = 1024] = 'AllowNavigation';
ValidationFlags[ValidationFlags.AllowWildcard = 2048] = 'AllowWildcard';
/** Path must be a valid directory root */
ValidationFlags[ValidationFlags.Root = 545] = 'Root';
/** Path must be a absolute */
ValidationFlags[ValidationFlags.Absolute = 2017] = 'Absolute';
/** Path may be relative or absolute */
ValidationFlags[ValidationFlags.RelativeOrAbsolute = 2016] = 'RelativeOrAbsolute';
/** Path may only be a filename */
ValidationFlags[ValidationFlags.Basename = 260] = 'Basename';
})(ValidationFlags = vpath.ValidationFlags || (vpath.ValidationFlags = {}));
function validateComponents(components, flags, hasTrailingSeparator) {
const hasRoot = !!components[0];
const hasDirname = components.length > 2;
const hasBasename = components.length > 1;
const hasExtname = hasBasename && extRegExp.test(components[components.length - 1]);
const invalidComponentRegExp = flags & 1024 /* AllowNavigation */
? flags & 2048 /* AllowWildcard */ ? invalidNavigableComponentWithWildcardsRegExp : invalidNavigableComponentRegExp
: flags & 2048 /* AllowWildcard */ ? invalidNonNavigableComponentWithWildcardsRegExp : invalidNonNavigableComponentRegExp;
// Validate required components
if (flags & 1 /* RequireRoot */ && !hasRoot)
return false;
if (flags & 2 /* RequireDirname */ && !hasDirname)
return false;
if (flags & 4 /* RequireBasename */ && !hasBasename)
return false;
if (flags & 8 /* RequireExtname */ && !hasExtname)
return false;
if (flags & 16 /* RequireTrailingSeparator */ && !hasTrailingSeparator)
return false;
// Required components indicate allowed components
if (flags & 1 /* RequireRoot */)
flags |= 32;
if (flags & 2 /* RequireDirname */)
flags |= 64;
if (flags & 4 /* RequireBasename */)
flags |= 128;
if (flags & 8 /* RequireExtname */)
flags |= 256;
if (flags & 16 /* RequireTrailingSeparator */)
flags |= 512;
// Validate disallowed components
if (~flags & 32 /* AllowRoot */ && hasRoot)
return false;
if (~flags & 64 /* AllowDirname */ && hasDirname)
return false;
if (~flags & 128 /* AllowBasename */ && hasBasename)
return false;
if (~flags & 256 /* AllowExtname */ && hasExtname)
return false;
if (~flags & 512 /* AllowTrailingSeparator */ && hasTrailingSeparator)
return false;
// Validate component strings
if (invalidRootComponentRegExp.test(components[0]))
return false;
for (let i = 1; i < components.length; i++) {
if (invalidComponentRegExp.test(components[i]))
return false;
}
return true;
}
function validate(path, flags) {
if (flags === void 0) { flags = 2016; }
const components = vpath.parse(path);
const trailing = vpath.hasTrailingSeparator(path);
if (!validateComponents(components, flags, trailing))
throw vfs.createIOError('ENOENT');
return components.length > 1 && trailing ? vpath.format(vpath.reduce(components)) + vpath.sep : vpath.format(vpath.reduce(components));
}
vpath.validate = validate;
function isDeclaration(path) {
return ts.fileExtensionIsOneOf(path, ['.d.mts' /* Dmts */, '.d.cts' /* Dcts */, '.d.ts']);
}
vpath.isDeclaration = isDeclaration;
function isSourceMap(path) {
return vpath.extname(path, '.map', /*ignoreCase*/ false).length > 0;
}
vpath.isSourceMap = isSourceMap;
const javaScriptSourceMapExtensions = ['.js.map', '.jsx.map'];
function isJavaScriptSourceMap(path) {
return vpath.extname(path, javaScriptSourceMapExtensions, /*ignoreCase*/ false).length > 0;
}
vpath.isJavaScriptSourceMap = isJavaScriptSourceMap;
function isJson(path) {
return vpath.extname(path, '.json', /*ignoreCase*/ false).length > 0;
}
vpath.isJson = isJson;
function isDefaultLibrary(path) {
return isDeclaration(path)
&& vpath.basename(path).startsWith('lib.');
}
vpath.isDefaultLibrary = isDefaultLibrary;
function isTsConfigFile(path) {
return path.indexOf('tsconfig') !== -1 && path.indexOf('json') !== -1;
}
vpath.isTsConfigFile = isTsConfigFile;
})(vpath || (vpath = {}));
let vfs;
(function (vfs) {
/**
* Posix-style path to the TypeScript compiler build outputs (including tsc.js, lib.d.ts, etc.)
*/
vfs.builtFolder = '/.ts';
/**
* Posix-style path to additional mountable folders (./tests/projects in this repo)
*/
vfs.projectsFolder = '/.projects';
/**
* Posix-style path to additional test libraries
*/
vfs.testLibFolder = '/.lib';
/**
* Posix-style path to sources under test
*/
vfs.srcFolder = '/.src';
// file type
const S_IFMT = 61440; // file type
const S_IFSOCK = 49152; // socket
const S_IFLNK = 40960; // symbolic link
const S_IFREG = 32768; // regular file
const S_IFBLK = 24576; // block device
const S_IFDIR = 16384; // directory
const S_IFCHR = 8192; // character device
const S_IFIFO = 4096; // FIFO
let devCount = 0; // A monotonically increasing count of device ids
let inoCount = 0; // A monotonically increasing count of inodes
/**
* Represents a virtual POSIX-like file system.
*/
const FileSystem = /** @class */ (function () {
function FileSystem(ignoreCase, options) {
if (options === void 0) { options = {}; }
// lazy-initialized state that should be mutable even if the FileSystem is frozen.
this._lazy = {};
const _a = options.time; const time = _a === void 0 ? -1 : _a; const files = options.files; const
meta = options.meta;
this.ignoreCase = ignoreCase;
this.stringComparer = this.ignoreCase ? vpath.compareCaseInsensitive : vpath.compareCaseSensitive;
this._time = time;
if (meta) {
for (let _i = 0, _b = Object.keys(meta); _i < _b.length; _i++) {
const key = _b[_i];
this.meta.set(key, meta[key]);
}
}
if (files) {
this._applyFiles(files, /*dirname*/ '');
}
let cwd = options.cwd;
if ((!cwd || !vpath.isRoot(cwd)) && this._lazy.links) {
const iterator = collections.getIterator(this._lazy.links.keys());
try {
for (let i = collections.nextResult(iterator); i; i = collections.nextResult(iterator)) {
const name = i.value;
cwd = cwd ? vpath.resolve(name, cwd) : name;
break;
}
} finally {
collections.closeIterator(iterator);
}
}
if (cwd) {
vpath.validate(cwd, 2017 /* Absolute */);
this.mkdirpSync(cwd);
}
this._cwd = cwd || '';
}
Object.defineProperty(FileSystem.prototype, 'meta', {
/**
* Gets metadata for this `FileSystem`.
*/
get() {
if (!this._lazy.meta) {
this._lazy.meta = new collections.Metadata(this._shadowRoot ? this._shadowRoot.meta : undefined);
}
return this._lazy.meta;
},
enumerable: false,
configurable: true,
});
Object.defineProperty(FileSystem.prototype, 'isReadonly', {
/**
* Gets a value indicating whether the file system is read-only.
*/
get() {
return Object.isFrozen(this);
},
enumerable: false,
configurable: true,
});
/**
* Makes the file system read-only.
*/
FileSystem.prototype.makeReadonly = function () {
Object.freeze(this);
return this;
};
Object.defineProperty(FileSystem.prototype, 'shadowRoot', {
/**
* Gets the file system shadowed by this file system.
*/
get() {
return this._shadowRoot;
},
enumerable: false,
configurable: true,
});
/**
* Snapshots the current file system, effectively shadowing itself. This is useful for
* generating file system patches using `.diff()` from one snapshot to the next. Performs
* no action if this file system is read-only.
*/
FileSystem.prototype.snapshot = function () {
if (this.isReadonly)
return;
const fs = new FileSystem(this.ignoreCase, { time: this._time });
fs._lazy = this._lazy;
fs._cwd = this._cwd;
fs._time = this._time;
fs._shadowRoot = this._shadowRoot;
fs._dirStack = this._dirStack;
fs.makeReadonly();
this._lazy = {};
this._shadowRoot = fs;
};
/**
* Gets a shadow copy of this file system. Changes to the shadow copy do not affect the
* original, allowing multiple copies of the same core file system without multiple copies
* of the same data.
*/
FileSystem.prototype.shadow = function (ignoreCase) {
if (ignoreCase === void 0) { ignoreCase = this.ignoreCase; }
if (!this.isReadonly)
throw new Error('Cannot shadow a mutable file system.');
if (ignoreCase && !this.ignoreCase)
throw new Error('Cannot create a case-insensitive file system from a case-sensitive one.');
const fs = new FileSystem(ignoreCase, { time: this._time });
fs._shadowRoot = this;
fs._cwd = this._cwd;
return fs;
};
/**
* Gets or sets the timestamp (in milliseconds) used for file status, returning the previous timestamp.
*
* @link http://pubs.opengroup.org/onlinepubs/9699919799/functions/time.html
*/
FileSystem.prototype.time = function (value) {
if (value !== undefined && this.isReadonly)
throw createIOError('EPERM');
let result = this._time;
if (typeof result === 'function')
result = result();
if (typeof result === 'object')
result = result.getTime();
if (result === -1)
result = Date.now();
if (value !== undefined) {
this._time = value;
}
return result;
};
/**
* Gets the metadata object for a path.
* @param path
*/
FileSystem.prototype.filemeta = function (path) {
const node = this._walk(this._resolve(path)).node;
if (!node)
throw createIOError('ENOENT');
return this._filemeta(node);
};
FileSystem.prototype._filemeta = function (node) {
if (!node.meta) {
const parentMeta = node.shadowRoot && this._shadowRoot && this._shadowRoot._filemeta(node.shadowRoot);
node.meta = new collections.Metadata(parentMeta);
}
return node.meta;
};
/**
* Get the pathname of the current working directory.
*
* @link - http://pubs.opengroup.org/onlinepubs/9699919799/functions/getcwd.html
*/
FileSystem.prototype.cwd = function () {
if (!this._cwd)
throw new Error('The current working directory has not been set.');
const node = this._walk(this._cwd).node;
if (!node)
throw createIOError('ENOENT');
if (!isDirectory(node))
throw createIOError('ENOTDIR');
return this._cwd;
};
/**
* Changes the current working directory.
*
* @link http://pubs.opengroup.org/onlinepubs/9699919799/functions/chdir.html
*/
FileSystem.prototype.chdir = function (path) {
if (this.isReadonly)
throw createIOError('EPERM');
path = this._resolve(path);
const node = this._walk(path).node;
if (!node)
throw createIOError('ENOENT');
if (!isDirectory(node))
throw createIOError('ENOTDIR');
this._cwd = path;
};
/**
* Pushes the current directory onto the directory stack and changes the current working directory to the supplied path.
*/
FileSystem.prototype.pushd = function (path) {
if (this.isReadonly)
throw createIOError('EPERM');
if (path)
path = this._resolve(path);
if (this._cwd) {
if (!this._dirStack)
this._dirStack = [];
this._dirStack.push(this._cwd);
}
if (path && path !== this._cwd) {
this.chdir(path);
}
};
/**
* Pops the previous directory from the location stack and changes the current directory to that directory.
*/
FileSystem.prototype.popd = function () {
if (this.isReadonly)
throw createIOError('EPERM');
const path = this._dirStack && this._dirStack.pop();
if (path) {
this.chdir(path);
}
};
/**
* Update the file system with a set of files.
*/
FileSystem.prototype.apply = function (files) {
this._applyFiles(files, this._cwd);
};
/**
* Scan file system entries along a path. If `path` is a symbolic link, it is dereferenced.
* @param path The path at which to start the scan.
* @param axis The axis along which to traverse.
* @param traversal The traversal scheme to use.
*/
FileSystem.prototype.scanSync = function (path, axis, traversal) {
path = this._resolve(path);
const results = [];
this._scan(path, this._stat(this._walk(path)), axis, traversal, /*noFollow*/ false, results);
return results;
};
/**
* Scan file system entries along a path.
* @param path The path at which to start the scan.
* @param axis The axis along which to traverse.
* @param traversal The traversal scheme to use.
*/
FileSystem.prototype.lscanSync = function (path, axis, traversal) {
path = this._resolve(path);
const results = [];
this._scan(path, this._stat(this._walk(path, /*noFollow*/ true)), axis, traversal, /*noFollow*/ true, results);
return results;
};
FileSystem.prototype._scan = function (path, stats, axis, traversal, noFollow, results) {
if (axis === 'ancestors-or-self' || axis === 'self' || axis === 'descendants-or-self') {
if (!traversal.accept || traversal.accept(path, stats)) {
results.push(path);
}
}
if (axis === 'ancestors-or-self' || axis === 'ancestors') {
const dirname = vpath.dirname(path);
if (dirname !== path) {
try {
const stats_1 = this._stat(this._walk(dirname, noFollow));
if (!traversal.traverse || traversal.traverse(dirname, stats_1)) {
this._scan(dirname, stats_1, 'ancestors-or-self', traversal, noFollow, results);
}
} catch (/*ignored*/_a) { /*ignored*/ }
}
}
if (axis === 'descendants-or-self' || axis === 'descendants') {
if (stats.isDirectory() && (!traversal.traverse || traversal.traverse(path, stats))) {
for (let _i = 0, _b = this.readdirSync(path); _i < _b.length; _i++) {
const file = _b[_i];
try {
const childpath = vpath.combine(path, file);
const stats_2 = this._stat(this._walk(childpath, noFollow));
this._scan(childpath, stats_2, 'descendants-or-self', traversal, noFollow, results);
} catch (/*ignored*/_c) { /*ignored*/ }
}
}
}
};
/**
* Mounts a physical or virtual file system at a location in this virtual file system.
*
* @param source The path in the physical (or other virtual) file system.
* @param target The path in this virtual file system.
* @param resolver An object used to resolve files in `source`.
*/
FileSystem.prototype.mountSync = function (source, target, resolver) {
if (this.isReadonly)
throw createIOError('EROFS');
source = vpath.validate(source, 2017 /* Absolute */);
const _a = this._walk(this._resolve(target), /*noFollow*/ true); const parent = _a.parent; const links = _a.links; const existingNode = _a.node; const
basename = _a.basename;
if (existingNode)
throw createIOError('EEXIST');
const time = this.time();
const node = this._mknod(parent ? parent.dev : ++devCount, S_IFDIR, /*mode*/ 511, time);
node.source = source;
node.resolver = resolver;
this._addLink(parent, links, basename, node, time);
};
/**
* Recursively remove all files and directories underneath the provided path.
*/
FileSystem.prototype.rimrafSync = function (path) {
try {
const stats = this.lstatSync(path);
if (stats.isFile() || stats.isSymbolicLink()) {
this.unlinkSync(path);
} else if (stats.isDirectory()) {
for (let _i = 0, _a = this.readdirSync(path); _i < _a.length; _i++) {
const file = _a[_i];
this.rimrafSync(vpath.combine(path, file));
}
this.rmdirSync(path);
}
} catch (e) {
if (e.code === 'ENOENT')
return;
throw e;
}
};
/**
* Make a directory and all of its parent paths (if they don't exist).
*/
FileSystem.prototype.mkdirpSync = function (path) {
const _this = this;
path = this._resolve(path);
const result = this._walk(path, /*noFollow*/ true, (error, result) => {
if (error.code === 'ENOENT') {
_this._mkdir(result);
return 'retry';
}
return 'throw';
});
if (!result.node)
this._mkdir(result);
};
FileSystem.prototype.getFileListing = function () {
const _this = this;
let result = '';
var printLinks = function (dirname, links) {
const iterator = collections.getIterator(links);
try {
for (let i = collections.nextResult(iterator); i; i = collections.nextResult(iterator)) {
const _a = i.value; const name = _a[0]; const
node = _a[1];
const path = dirname ? vpath.combine(dirname, name) : name;
const marker = vpath.compare(_this._cwd, path, _this.ignoreCase) === 0 ? '*' : ' ';
if (result)
result += '\n';
result += marker;
if (isDirectory(node)) {
result += vpath.addTrailingSeparator(path);
printLinks(path, _this._getLinks(node));
} else if (isFile(node)) {
result += path;
} else if (isSymlink(node)) {
result += path + ' -> ' + node.symlink;
}
}
} finally {
collections.closeIterator(iterator);
}
};
printLinks(/*dirname*/ undefined, this._getRootLinks());