mirror of
https://github.com/johndoe6345789/low-code-react-app-b.git
synced 2026-05-01 00:54:55 +00:00
35710 lines
1.3 MiB
35710 lines
1.3 MiB
import fs from 'fs';
|
|
import require$$4 from 'os';
|
|
|
|
function _mergeNamespaces(n, m) {
|
|
m.forEach(function (e) {
|
|
e && typeof e !== 'string' && !Array.isArray(e) && Object.keys(e).forEach(function (k) {
|
|
if (k !== 'default' && !(k in n)) {
|
|
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
Object.defineProperty(n, k, d.get ? d : {
|
|
enumerable: true,
|
|
get: function () { return e[k]; }
|
|
});
|
|
}
|
|
});
|
|
});
|
|
return Object.freeze(n);
|
|
}
|
|
|
|
function getDefaultExportFromCjs (x) {
|
|
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
|
}
|
|
|
|
function getAugmentedNamespace(n) {
|
|
if (Object.prototype.hasOwnProperty.call(n, '__esModule')) return n;
|
|
var f = n.default;
|
|
if (typeof f == "function") {
|
|
var a = function a () {
|
|
var isInstance = false;
|
|
try {
|
|
isInstance = this instanceof a;
|
|
} catch {}
|
|
if (isInstance) {
|
|
return Reflect.construct(f, arguments, this.constructor);
|
|
}
|
|
return f.apply(this, arguments);
|
|
};
|
|
a.prototype = f.prototype;
|
|
} else a = {};
|
|
Object.defineProperty(a, '__esModule', {value: true});
|
|
Object.keys(n).forEach(function (k) {
|
|
var d = Object.getOwnPropertyDescriptor(n, k);
|
|
Object.defineProperty(a, k, d.get ? d : {
|
|
enumerable: true,
|
|
get: function () {
|
|
return n[k];
|
|
}
|
|
});
|
|
});
|
|
return a;
|
|
}
|
|
|
|
var main$1 = {};
|
|
|
|
/******************************************************************************
|
|
Copyright (c) Microsoft Corporation.
|
|
|
|
Permission to use, copy, modify, and/or distribute this software for any
|
|
purpose with or without fee is hereby granted.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
PERFORMANCE OF THIS SOFTWARE.
|
|
***************************************************************************** */
|
|
/* global Reflect, Promise, SuppressedError, Symbol, Iterator */
|
|
|
|
var extendStatics = function(d, b) {
|
|
extendStatics = Object.setPrototypeOf ||
|
|
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
return extendStatics(d, b);
|
|
};
|
|
|
|
function __extends(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 = function() {
|
|
__assign = Object.assign || function __assign(t) {
|
|
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
s = arguments[i];
|
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
|
|
}
|
|
return t;
|
|
};
|
|
return __assign.apply(this, arguments);
|
|
};
|
|
|
|
function __rest(s, e) {
|
|
var 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;
|
|
}
|
|
|
|
function __decorate(decorators, target, key, desc) {
|
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
}
|
|
|
|
function __param(paramIndex, decorator) {
|
|
return function (target, key) { decorator(target, key, paramIndex); }
|
|
}
|
|
|
|
function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
var _, done = false;
|
|
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
var context = {};
|
|
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
if (kind === "accessor") {
|
|
if (result === void 0) continue;
|
|
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
if (_ = accept(result.get)) descriptor.get = _;
|
|
if (_ = accept(result.set)) descriptor.set = _;
|
|
if (_ = accept(result.init)) initializers.unshift(_);
|
|
}
|
|
else if (_ = accept(result)) {
|
|
if (kind === "field") initializers.unshift(_);
|
|
else descriptor[key] = _;
|
|
}
|
|
}
|
|
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
done = true;
|
|
}
|
|
function __runInitializers(thisArg, initializers, value) {
|
|
var useValue = arguments.length > 2;
|
|
for (var i = 0; i < initializers.length; i++) {
|
|
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
}
|
|
return useValue ? value : void 0;
|
|
}
|
|
function __propKey(x) {
|
|
return typeof x === "symbol" ? x : "".concat(x);
|
|
}
|
|
function __setFunctionName(f, name, prefix) {
|
|
if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";
|
|
return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
|
|
}
|
|
function __metadata(metadataKey, metadataValue) {
|
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
|
|
}
|
|
|
|
function __awaiter(thisArg, _arguments, P, generator) {
|
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
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) : adopt(result.value).then(fulfilled, rejected); }
|
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
});
|
|
}
|
|
|
|
function __generator(thisArg, body) {
|
|
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
return g.next = verb(0), g["throw"] = verb(1), g["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 (g && (g = 0, op[0] && (_ = 0)), _) 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 };
|
|
}
|
|
}
|
|
|
|
var __createBinding = Object.create ? (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
}
|
|
Object.defineProperty(o, k2, desc);
|
|
}) : (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
o[k2] = m[k];
|
|
});
|
|
|
|
function __exportStar(m, o) {
|
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);
|
|
}
|
|
|
|
function __values(o) {
|
|
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
|
|
if (m) return m.call(o);
|
|
if (o && typeof o.length === "number") return {
|
|
next: function () {
|
|
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.");
|
|
}
|
|
|
|
function __read(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;
|
|
}
|
|
|
|
/** @deprecated */
|
|
function __spread() {
|
|
for (var ar = [], i = 0; i < arguments.length; i++)
|
|
ar = ar.concat(__read(arguments[i]));
|
|
return ar;
|
|
}
|
|
|
|
/** @deprecated */
|
|
function __spreadArrays() {
|
|
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
|
|
for (var r = Array(s), k = 0, i = 0; i < il; i++)
|
|
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
|
|
r[k] = a[j];
|
|
return r;
|
|
}
|
|
|
|
function __spreadArray(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 || Array.prototype.slice.call(from));
|
|
}
|
|
|
|
function __await(v) {
|
|
return this instanceof __await ? (this.v = v, this) : new __await(v);
|
|
}
|
|
|
|
function __asyncGenerator(thisArg, _arguments, generator) {
|
|
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
var g = generator.apply(thisArg, _arguments || []), i, q = [];
|
|
return i = Object.create((typeof AsyncIterator === "function" ? AsyncIterator : Object).prototype), verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;
|
|
function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }
|
|
function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }
|
|
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
|
|
function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
|
|
function fulfill(value) { resume("next", value); }
|
|
function reject(value) { resume("throw", value); }
|
|
function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
|
|
}
|
|
|
|
function __asyncDelegator(o) {
|
|
var i, p;
|
|
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
|
|
function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; }
|
|
}
|
|
|
|
function __asyncValues(o) {
|
|
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
var m = o[Symbol.asyncIterator], i;
|
|
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
|
|
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
|
|
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
|
|
}
|
|
|
|
function __makeTemplateObject(cooked, raw) {
|
|
if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
|
|
return cooked;
|
|
}
|
|
var __setModuleDefault = Object.create ? (function(o, v) {
|
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
}) : function(o, v) {
|
|
o["default"] = v;
|
|
};
|
|
|
|
var ownKeys = function(o) {
|
|
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
var ar = [];
|
|
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
return ar;
|
|
};
|
|
return ownKeys(o);
|
|
};
|
|
|
|
function __importStar(mod) {
|
|
if (mod && mod.__esModule) return mod;
|
|
var result = {};
|
|
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
__setModuleDefault(result, mod);
|
|
return result;
|
|
}
|
|
|
|
function __importDefault(mod) {
|
|
return (mod && mod.__esModule) ? mod : { default: mod };
|
|
}
|
|
|
|
function __classPrivateFieldGet(receiver, state, kind, f) {
|
|
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
}
|
|
|
|
function __classPrivateFieldSet(receiver, state, value, kind, f) {
|
|
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
}
|
|
|
|
function __classPrivateFieldIn(state, receiver) {
|
|
if (receiver === null || (typeof receiver !== "object" && typeof receiver !== "function")) throw new TypeError("Cannot use 'in' operator on non-object");
|
|
return typeof state === "function" ? receiver === state : state.has(receiver);
|
|
}
|
|
|
|
function __addDisposableResource(env, value, async) {
|
|
if (value !== null && value !== void 0) {
|
|
if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
|
|
var dispose, inner;
|
|
if (async) {
|
|
if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
|
|
dispose = value[Symbol.asyncDispose];
|
|
}
|
|
if (dispose === void 0) {
|
|
if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
|
|
dispose = value[Symbol.dispose];
|
|
if (async) inner = dispose;
|
|
}
|
|
if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
|
|
if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
|
|
env.stack.push({ value: value, dispose: dispose, async: async });
|
|
}
|
|
else if (async) {
|
|
env.stack.push({ async: true });
|
|
}
|
|
return value;
|
|
|
|
}
|
|
|
|
var _SuppressedError = typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
var e = new Error(message);
|
|
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
};
|
|
|
|
function __disposeResources(env) {
|
|
function fail(e) {
|
|
env.error = env.hasError ? new _SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
|
|
env.hasError = true;
|
|
}
|
|
var r, s = 0;
|
|
function next() {
|
|
while (r = env.stack.pop()) {
|
|
try {
|
|
if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
|
|
if (r.dispose) {
|
|
var result = r.dispose.call(r.value);
|
|
if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
|
|
}
|
|
else s |= 1;
|
|
}
|
|
catch (e) {
|
|
fail(e);
|
|
}
|
|
}
|
|
if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
|
|
if (env.hasError) throw env.error;
|
|
}
|
|
return next();
|
|
}
|
|
|
|
function __rewriteRelativeImportExtension(path, preserveJsx) {
|
|
if (typeof path === "string" && /^\.\.?\//.test(path)) {
|
|
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
|
|
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
|
|
});
|
|
}
|
|
return path;
|
|
}
|
|
|
|
var tslib_es6 = {
|
|
__extends: __extends,
|
|
__assign: __assign,
|
|
__rest: __rest,
|
|
__decorate: __decorate,
|
|
__param: __param,
|
|
__esDecorate: __esDecorate,
|
|
__runInitializers: __runInitializers,
|
|
__propKey: __propKey,
|
|
__setFunctionName: __setFunctionName,
|
|
__metadata: __metadata,
|
|
__awaiter: __awaiter,
|
|
__generator: __generator,
|
|
__createBinding: __createBinding,
|
|
__exportStar: __exportStar,
|
|
__values: __values,
|
|
__read: __read,
|
|
__spread: __spread,
|
|
__spreadArrays: __spreadArrays,
|
|
__spreadArray: __spreadArray,
|
|
__await: __await,
|
|
__asyncGenerator: __asyncGenerator,
|
|
__asyncDelegator: __asyncDelegator,
|
|
__asyncValues: __asyncValues,
|
|
__makeTemplateObject: __makeTemplateObject,
|
|
__importStar: __importStar,
|
|
__importDefault: __importDefault,
|
|
__classPrivateFieldGet: __classPrivateFieldGet,
|
|
__classPrivateFieldSet: __classPrivateFieldSet,
|
|
__classPrivateFieldIn: __classPrivateFieldIn,
|
|
__addDisposableResource: __addDisposableResource,
|
|
__disposeResources: __disposeResources,
|
|
__rewriteRelativeImportExtension: __rewriteRelativeImportExtension,
|
|
};
|
|
|
|
var tslib_es6$1 = /*#__PURE__*/Object.freeze({
|
|
__proto__: null,
|
|
__addDisposableResource: __addDisposableResource,
|
|
get __assign () { return __assign; },
|
|
__asyncDelegator: __asyncDelegator,
|
|
__asyncGenerator: __asyncGenerator,
|
|
__asyncValues: __asyncValues,
|
|
__await: __await,
|
|
__awaiter: __awaiter,
|
|
__classPrivateFieldGet: __classPrivateFieldGet,
|
|
__classPrivateFieldIn: __classPrivateFieldIn,
|
|
__classPrivateFieldSet: __classPrivateFieldSet,
|
|
__createBinding: __createBinding,
|
|
__decorate: __decorate,
|
|
__disposeResources: __disposeResources,
|
|
__esDecorate: __esDecorate,
|
|
__exportStar: __exportStar,
|
|
__extends: __extends,
|
|
__generator: __generator,
|
|
__importDefault: __importDefault,
|
|
__importStar: __importStar,
|
|
__makeTemplateObject: __makeTemplateObject,
|
|
__metadata: __metadata,
|
|
__param: __param,
|
|
__propKey: __propKey,
|
|
__read: __read,
|
|
__rest: __rest,
|
|
__rewriteRelativeImportExtension: __rewriteRelativeImportExtension,
|
|
__runInitializers: __runInitializers,
|
|
__setFunctionName: __setFunctionName,
|
|
__spread: __spread,
|
|
__spreadArray: __spreadArray,
|
|
__spreadArrays: __spreadArrays,
|
|
__values: __values,
|
|
default: tslib_es6
|
|
});
|
|
|
|
var require$$0 = /*@__PURE__*/getAugmentedNamespace(tslib_es6$1);
|
|
|
|
var main = {};
|
|
|
|
var fork = {exports: {}};
|
|
|
|
var types = {exports: {}};
|
|
|
|
var shared = {};
|
|
|
|
var hasRequiredShared;
|
|
|
|
function requireShared () {
|
|
if (hasRequiredShared) return shared;
|
|
hasRequiredShared = 1;
|
|
Object.defineProperty(shared, "__esModule", { value: true });
|
|
shared.maybeSetModuleExports = void 0;
|
|
var tslib_1 = require$$0;
|
|
var types_1 = tslib_1.__importDefault(requireTypes());
|
|
function default_1(fork) {
|
|
var types = fork.use(types_1.default);
|
|
var Type = types.Type;
|
|
var builtin = types.builtInTypes;
|
|
var isNumber = builtin.number;
|
|
// An example of constructing a new type with arbitrary constraints from
|
|
// an existing type.
|
|
function geq(than) {
|
|
return Type.from(function (value) { return isNumber.check(value) && value >= than; }, isNumber + " >= " + than);
|
|
}
|
|
// Default value-returning functions that may optionally be passed as a
|
|
// third argument to Def.prototype.field.
|
|
var defaults = {
|
|
// Functions were used because (among other reasons) that's the most
|
|
// elegant way to allow for the emptyArray one always to give a new
|
|
// array instance.
|
|
"null": function () { return null; },
|
|
"emptyArray": function () { return []; },
|
|
"false": function () { return false; },
|
|
"true": function () { return true; },
|
|
"undefined": function () { },
|
|
"use strict": function () { return "use strict"; }
|
|
};
|
|
var naiveIsPrimitive = Type.or(builtin.string, builtin.number, builtin.boolean, builtin.null, builtin.undefined);
|
|
var isPrimitive = Type.from(function (value) {
|
|
if (value === null)
|
|
return true;
|
|
var type = typeof value;
|
|
if (type === "object" ||
|
|
type === "function") {
|
|
return false;
|
|
}
|
|
return true;
|
|
}, naiveIsPrimitive.toString());
|
|
return {
|
|
geq: geq,
|
|
defaults: defaults,
|
|
isPrimitive: isPrimitive,
|
|
};
|
|
}
|
|
shared.default = default_1;
|
|
// This function accepts a getter function that should return an object
|
|
// conforming to the NodeModule interface above. Typically, this means calling
|
|
// maybeSetModuleExports(() => module) at the very end of any module that has a
|
|
// default export, so the default export value can replace module.exports and
|
|
// thus CommonJS consumers can continue to rely on require("./that/module")
|
|
// returning the default-exported value, rather than always returning an exports
|
|
// object with a default property equal to that value. This function should help
|
|
// preserve backwards compatibility for CommonJS consumers, as a replacement for
|
|
// the ts-add-module-exports package.
|
|
function maybeSetModuleExports(moduleGetter) {
|
|
try {
|
|
var nodeModule = moduleGetter();
|
|
var originalExports = nodeModule.exports;
|
|
var defaultExport = originalExports["default"];
|
|
}
|
|
catch (_a) {
|
|
// It's normal/acceptable for this code to throw a ReferenceError due to
|
|
// the moduleGetter function attempting to access a non-existent global
|
|
// `module` variable. That's the reason we use a getter function here:
|
|
// so the calling code doesn't have to do its own typeof module ===
|
|
// "object" checking (because it's always safe to pass `() => module` as
|
|
// an argument, even when `module` is not defined in the calling scope).
|
|
return;
|
|
}
|
|
if (defaultExport &&
|
|
defaultExport !== originalExports &&
|
|
typeof originalExports === "object") {
|
|
// Make all properties found in originalExports properties of the
|
|
// default export, including the default property itself, so that
|
|
// require(nodeModule.id).default === require(nodeModule.id).
|
|
Object.assign(defaultExport, originalExports, { "default": defaultExport });
|
|
// Object.assign only transfers enumerable properties, and
|
|
// __esModule is (and should remain) non-enumerable.
|
|
if (originalExports.__esModule) {
|
|
Object.defineProperty(defaultExport, "__esModule", { value: true });
|
|
}
|
|
// This line allows require(nodeModule.id) === defaultExport, rather
|
|
// than (only) require(nodeModule.id).default === defaultExport.
|
|
nodeModule.exports = defaultExport;
|
|
}
|
|
}
|
|
shared.maybeSetModuleExports = maybeSetModuleExports;
|
|
|
|
return shared;
|
|
}
|
|
|
|
types.exports;
|
|
|
|
var hasRequiredTypes;
|
|
|
|
function requireTypes () {
|
|
if (hasRequiredTypes) return types.exports;
|
|
hasRequiredTypes = 1;
|
|
(function (module, exports$1) {
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
exports$1.Def = void 0;
|
|
var tslib_1 = require$$0;
|
|
var shared_1 = requireShared();
|
|
var Op = Object.prototype;
|
|
var objToStr = Op.toString;
|
|
var hasOwn = Op.hasOwnProperty;
|
|
var BaseType = /** @class */ (function () {
|
|
function BaseType() {
|
|
}
|
|
BaseType.prototype.assert = function (value, deep) {
|
|
if (!this.check(value, deep)) {
|
|
var str = shallowStringify(value);
|
|
throw new Error(str + " does not match type " + this);
|
|
}
|
|
return true;
|
|
};
|
|
BaseType.prototype.arrayOf = function () {
|
|
var elemType = this;
|
|
return new ArrayType(elemType);
|
|
};
|
|
return BaseType;
|
|
}());
|
|
var ArrayType = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ArrayType, _super);
|
|
function ArrayType(elemType) {
|
|
var _this = _super.call(this) || this;
|
|
_this.elemType = elemType;
|
|
_this.kind = "ArrayType";
|
|
return _this;
|
|
}
|
|
ArrayType.prototype.toString = function () {
|
|
return "[" + this.elemType + "]";
|
|
};
|
|
ArrayType.prototype.check = function (value, deep) {
|
|
var _this = this;
|
|
return Array.isArray(value) && value.every(function (elem) { return _this.elemType.check(elem, deep); });
|
|
};
|
|
return ArrayType;
|
|
}(BaseType));
|
|
var IdentityType = /** @class */ (function (_super) {
|
|
tslib_1.__extends(IdentityType, _super);
|
|
function IdentityType(value) {
|
|
var _this = _super.call(this) || this;
|
|
_this.value = value;
|
|
_this.kind = "IdentityType";
|
|
return _this;
|
|
}
|
|
IdentityType.prototype.toString = function () {
|
|
return String(this.value);
|
|
};
|
|
IdentityType.prototype.check = function (value, deep) {
|
|
var result = value === this.value;
|
|
if (!result && typeof deep === "function") {
|
|
deep(this, value);
|
|
}
|
|
return result;
|
|
};
|
|
return IdentityType;
|
|
}(BaseType));
|
|
var ObjectType = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ObjectType, _super);
|
|
function ObjectType(fields) {
|
|
var _this = _super.call(this) || this;
|
|
_this.fields = fields;
|
|
_this.kind = "ObjectType";
|
|
return _this;
|
|
}
|
|
ObjectType.prototype.toString = function () {
|
|
return "{ " + this.fields.join(", ") + " }";
|
|
};
|
|
ObjectType.prototype.check = function (value, deep) {
|
|
return (objToStr.call(value) === objToStr.call({}) &&
|
|
this.fields.every(function (field) {
|
|
return field.type.check(value[field.name], deep);
|
|
}));
|
|
};
|
|
return ObjectType;
|
|
}(BaseType));
|
|
var OrType = /** @class */ (function (_super) {
|
|
tslib_1.__extends(OrType, _super);
|
|
function OrType(types) {
|
|
var _this = _super.call(this) || this;
|
|
_this.types = types;
|
|
_this.kind = "OrType";
|
|
return _this;
|
|
}
|
|
OrType.prototype.toString = function () {
|
|
return this.types.join(" | ");
|
|
};
|
|
OrType.prototype.check = function (value, deep) {
|
|
if (this.types.some(function (type) { return type.check(value, !!deep); })) {
|
|
return true;
|
|
}
|
|
if (typeof deep === "function") {
|
|
deep(this, value);
|
|
}
|
|
return false;
|
|
};
|
|
return OrType;
|
|
}(BaseType));
|
|
var PredicateType = /** @class */ (function (_super) {
|
|
tslib_1.__extends(PredicateType, _super);
|
|
function PredicateType(name, predicate) {
|
|
var _this = _super.call(this) || this;
|
|
_this.name = name;
|
|
_this.predicate = predicate;
|
|
_this.kind = "PredicateType";
|
|
return _this;
|
|
}
|
|
PredicateType.prototype.toString = function () {
|
|
return this.name;
|
|
};
|
|
PredicateType.prototype.check = function (value, deep) {
|
|
var result = this.predicate(value, deep);
|
|
if (!result && typeof deep === "function") {
|
|
deep(this, value);
|
|
}
|
|
return result;
|
|
};
|
|
return PredicateType;
|
|
}(BaseType));
|
|
var Def = /** @class */ (function () {
|
|
function Def(type, typeName) {
|
|
this.type = type;
|
|
this.typeName = typeName;
|
|
this.baseNames = [];
|
|
this.ownFields = Object.create(null);
|
|
// Includes own typeName. Populated during finalization.
|
|
this.allSupertypes = Object.create(null);
|
|
// Linear inheritance hierarchy. Populated during finalization.
|
|
this.supertypeList = [];
|
|
// Includes inherited fields.
|
|
this.allFields = Object.create(null);
|
|
// Non-hidden keys of allFields.
|
|
this.fieldNames = [];
|
|
// This property will be overridden as true by individual Def instances
|
|
// when they are finalized.
|
|
this.finalized = false;
|
|
// False by default until .build(...) is called on an instance.
|
|
this.buildable = false;
|
|
this.buildParams = [];
|
|
}
|
|
Def.prototype.isSupertypeOf = function (that) {
|
|
if (that instanceof Def) {
|
|
if (this.finalized !== true ||
|
|
that.finalized !== true) {
|
|
throw new Error("");
|
|
}
|
|
return hasOwn.call(that.allSupertypes, this.typeName);
|
|
}
|
|
else {
|
|
throw new Error(that + " is not a Def");
|
|
}
|
|
};
|
|
Def.prototype.checkAllFields = function (value, deep) {
|
|
var allFields = this.allFields;
|
|
if (this.finalized !== true) {
|
|
throw new Error("" + this.typeName);
|
|
}
|
|
function checkFieldByName(name) {
|
|
var field = allFields[name];
|
|
var type = field.type;
|
|
var child = field.getValue(value);
|
|
return type.check(child, deep);
|
|
}
|
|
return value !== null &&
|
|
typeof value === "object" &&
|
|
Object.keys(allFields).every(checkFieldByName);
|
|
};
|
|
Def.prototype.bases = function () {
|
|
var supertypeNames = [];
|
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
supertypeNames[_i] = arguments[_i];
|
|
}
|
|
var bases = this.baseNames;
|
|
if (this.finalized) {
|
|
if (supertypeNames.length !== bases.length) {
|
|
throw new Error("");
|
|
}
|
|
for (var i = 0; i < supertypeNames.length; i++) {
|
|
if (supertypeNames[i] !== bases[i]) {
|
|
throw new Error("");
|
|
}
|
|
}
|
|
return this;
|
|
}
|
|
supertypeNames.forEach(function (baseName) {
|
|
// This indexOf lookup may be O(n), but the typical number of base
|
|
// names is very small, and indexOf is a native Array method.
|
|
if (bases.indexOf(baseName) < 0) {
|
|
bases.push(baseName);
|
|
}
|
|
});
|
|
return this; // For chaining.
|
|
};
|
|
return Def;
|
|
}());
|
|
exports$1.Def = Def;
|
|
var Field = /** @class */ (function () {
|
|
function Field(name, type, defaultFn, hidden) {
|
|
this.name = name;
|
|
this.type = type;
|
|
this.defaultFn = defaultFn;
|
|
this.hidden = !!hidden;
|
|
}
|
|
Field.prototype.toString = function () {
|
|
return JSON.stringify(this.name) + ": " + this.type;
|
|
};
|
|
Field.prototype.getValue = function (obj) {
|
|
var value = obj[this.name];
|
|
if (typeof value !== "undefined") {
|
|
return value;
|
|
}
|
|
if (typeof this.defaultFn === "function") {
|
|
value = this.defaultFn.call(obj);
|
|
}
|
|
return value;
|
|
};
|
|
return Field;
|
|
}());
|
|
function shallowStringify(value) {
|
|
if (Array.isArray(value)) {
|
|
return "[" + value.map(shallowStringify).join(", ") + "]";
|
|
}
|
|
if (value && typeof value === "object") {
|
|
return "{ " + Object.keys(value).map(function (key) {
|
|
return key + ": " + value[key];
|
|
}).join(", ") + " }";
|
|
}
|
|
return JSON.stringify(value);
|
|
}
|
|
function typesPlugin(_fork) {
|
|
var Type = {
|
|
or: function () {
|
|
var types = [];
|
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
types[_i] = arguments[_i];
|
|
}
|
|
return new OrType(types.map(function (type) { return Type.from(type); }));
|
|
},
|
|
from: function (value, name) {
|
|
if (value instanceof ArrayType ||
|
|
value instanceof IdentityType ||
|
|
value instanceof ObjectType ||
|
|
value instanceof OrType ||
|
|
value instanceof PredicateType) {
|
|
return value;
|
|
}
|
|
// The Def type is used as a helper for constructing compound
|
|
// interface types for AST nodes.
|
|
if (value instanceof Def) {
|
|
return value.type;
|
|
}
|
|
// Support [ElemType] syntax.
|
|
if (isArray.check(value)) {
|
|
if (value.length !== 1) {
|
|
throw new Error("only one element type is permitted for typed arrays");
|
|
}
|
|
return new ArrayType(Type.from(value[0]));
|
|
}
|
|
// Support { someField: FieldType, ... } syntax.
|
|
if (isObject.check(value)) {
|
|
return new ObjectType(Object.keys(value).map(function (name) {
|
|
return new Field(name, Type.from(value[name], name));
|
|
}));
|
|
}
|
|
if (typeof value === "function") {
|
|
var bicfIndex = builtInCtorFns.indexOf(value);
|
|
if (bicfIndex >= 0) {
|
|
return builtInCtorTypes[bicfIndex];
|
|
}
|
|
if (typeof name !== "string") {
|
|
throw new Error("missing name");
|
|
}
|
|
return new PredicateType(name, value);
|
|
}
|
|
// As a last resort, toType returns a type that matches any value that
|
|
// is === from. This is primarily useful for literal values like
|
|
// toType(null), but it has the additional advantage of allowing
|
|
// toType to be a total function.
|
|
return new IdentityType(value);
|
|
},
|
|
// Define a type whose name is registered in a namespace (the defCache) so
|
|
// that future definitions will return the same type given the same name.
|
|
// In particular, this system allows for circular and forward definitions.
|
|
// The Def object d returned from Type.def may be used to configure the
|
|
// type d.type by calling methods such as d.bases, d.build, and d.field.
|
|
def: function (typeName) {
|
|
return hasOwn.call(defCache, typeName)
|
|
? defCache[typeName]
|
|
: defCache[typeName] = new DefImpl(typeName);
|
|
},
|
|
hasDef: function (typeName) {
|
|
return hasOwn.call(defCache, typeName);
|
|
}
|
|
};
|
|
var builtInCtorFns = [];
|
|
var builtInCtorTypes = [];
|
|
function defBuiltInType(name, example) {
|
|
var objStr = objToStr.call(example);
|
|
var type = new PredicateType(name, function (value) { return objToStr.call(value) === objStr; });
|
|
if (example && typeof example.constructor === "function") {
|
|
builtInCtorFns.push(example.constructor);
|
|
builtInCtorTypes.push(type);
|
|
}
|
|
return type;
|
|
}
|
|
// These types check the underlying [[Class]] attribute of the given
|
|
// value, rather than using the problematic typeof operator. Note however
|
|
// that no subtyping is considered; so, for instance, isObject.check
|
|
// returns false for [], /./, new Date, and null.
|
|
var isString = defBuiltInType("string", "truthy");
|
|
var isFunction = defBuiltInType("function", function () { });
|
|
var isArray = defBuiltInType("array", []);
|
|
var isObject = defBuiltInType("object", {});
|
|
var isRegExp = defBuiltInType("RegExp", /./);
|
|
var isDate = defBuiltInType("Date", new Date());
|
|
var isNumber = defBuiltInType("number", 3);
|
|
var isBoolean = defBuiltInType("boolean", true);
|
|
var isNull = defBuiltInType("null", null);
|
|
var isUndefined = defBuiltInType("undefined", undefined);
|
|
var isBigInt = typeof BigInt === "function"
|
|
? defBuiltInType("BigInt", BigInt(1234))
|
|
: new PredicateType("BigInt", function () { return false; });
|
|
var builtInTypes = {
|
|
string: isString,
|
|
function: isFunction,
|
|
array: isArray,
|
|
object: isObject,
|
|
RegExp: isRegExp,
|
|
Date: isDate,
|
|
number: isNumber,
|
|
boolean: isBoolean,
|
|
null: isNull,
|
|
undefined: isUndefined,
|
|
BigInt: isBigInt,
|
|
};
|
|
// In order to return the same Def instance every time Type.def is called
|
|
// with a particular name, those instances need to be stored in a cache.
|
|
var defCache = Object.create(null);
|
|
function defFromValue(value) {
|
|
if (value && typeof value === "object") {
|
|
var type = value.type;
|
|
if (typeof type === "string" &&
|
|
hasOwn.call(defCache, type)) {
|
|
var d = defCache[type];
|
|
if (d.finalized) {
|
|
return d;
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
var DefImpl = /** @class */ (function (_super) {
|
|
tslib_1.__extends(DefImpl, _super);
|
|
function DefImpl(typeName) {
|
|
var _this = _super.call(this, new PredicateType(typeName, function (value, deep) { return _this.check(value, deep); }), typeName) || this;
|
|
return _this;
|
|
}
|
|
DefImpl.prototype.check = function (value, deep) {
|
|
if (this.finalized !== true) {
|
|
throw new Error("prematurely checking unfinalized type " + this.typeName);
|
|
}
|
|
// A Def type can only match an object value.
|
|
if (value === null || typeof value !== "object") {
|
|
return false;
|
|
}
|
|
var vDef = defFromValue(value);
|
|
if (!vDef) {
|
|
// If we couldn't infer the Def associated with the given value,
|
|
// and we expected it to be a SourceLocation or a Position, it was
|
|
// probably just missing a "type" field (because Esprima does not
|
|
// assign a type property to such nodes). Be optimistic and let
|
|
// this.checkAllFields make the final decision.
|
|
if (this.typeName === "SourceLocation" ||
|
|
this.typeName === "Position") {
|
|
return this.checkAllFields(value, deep);
|
|
}
|
|
// Calling this.checkAllFields for any other type of node is both
|
|
// bad for performance and way too forgiving.
|
|
return false;
|
|
}
|
|
// If checking deeply and vDef === this, then we only need to call
|
|
// checkAllFields once. Calling checkAllFields is too strict when deep
|
|
// is false, because then we only care about this.isSupertypeOf(vDef).
|
|
if (deep && vDef === this) {
|
|
return this.checkAllFields(value, deep);
|
|
}
|
|
// In most cases we rely exclusively on isSupertypeOf to make O(1)
|
|
// subtyping determinations. This suffices in most situations outside
|
|
// of unit tests, since interface conformance is checked whenever new
|
|
// instances are created using builder functions.
|
|
if (!this.isSupertypeOf(vDef)) {
|
|
return false;
|
|
}
|
|
// The exception is when deep is true; then, we recursively check all
|
|
// fields.
|
|
if (!deep) {
|
|
return true;
|
|
}
|
|
// Use the more specific Def (vDef) to perform the deep check, but
|
|
// shallow-check fields defined by the less specific Def (this).
|
|
return vDef.checkAllFields(value, deep)
|
|
&& this.checkAllFields(value, false);
|
|
};
|
|
DefImpl.prototype.build = function () {
|
|
var _this = this;
|
|
var buildParams = [];
|
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
buildParams[_i] = arguments[_i];
|
|
}
|
|
// Calling Def.prototype.build multiple times has the effect of merely
|
|
// redefining this property.
|
|
this.buildParams = buildParams;
|
|
if (this.buildable) {
|
|
// If this Def is already buildable, update self.buildParams and
|
|
// continue using the old builder function.
|
|
return this;
|
|
}
|
|
// Every buildable type will have its "type" field filled in
|
|
// automatically. This includes types that are not subtypes of Node,
|
|
// like SourceLocation, but that seems harmless (TODO?).
|
|
this.field("type", String, function () { return _this.typeName; });
|
|
// Override Dp.buildable for this Def instance.
|
|
this.buildable = true;
|
|
var addParam = function (built, param, arg, isArgAvailable) {
|
|
if (hasOwn.call(built, param))
|
|
return;
|
|
var all = _this.allFields;
|
|
if (!hasOwn.call(all, param)) {
|
|
throw new Error("" + param);
|
|
}
|
|
var field = all[param];
|
|
var type = field.type;
|
|
var value;
|
|
if (isArgAvailable) {
|
|
value = arg;
|
|
}
|
|
else if (field.defaultFn) {
|
|
// Expose the partially-built object to the default
|
|
// function as its `this` object.
|
|
value = field.defaultFn.call(built);
|
|
}
|
|
else {
|
|
var message = "no value or default function given for field " +
|
|
JSON.stringify(param) + " of " + _this.typeName + "(" +
|
|
_this.buildParams.map(function (name) {
|
|
return all[name];
|
|
}).join(", ") + ")";
|
|
throw new Error(message);
|
|
}
|
|
if (!type.check(value)) {
|
|
throw new Error(shallowStringify(value) +
|
|
" does not match field " + field +
|
|
" of type " + _this.typeName);
|
|
}
|
|
built[param] = value;
|
|
};
|
|
// Calling the builder function will construct an instance of the Def,
|
|
// with positional arguments mapped to the fields original passed to .build.
|
|
// If not enough arguments are provided, the default value for the remaining fields
|
|
// will be used.
|
|
var builder = function () {
|
|
var args = [];
|
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
args[_i] = arguments[_i];
|
|
}
|
|
var argc = args.length;
|
|
if (!_this.finalized) {
|
|
throw new Error("attempting to instantiate unfinalized type " +
|
|
_this.typeName);
|
|
}
|
|
var built = Object.create(nodePrototype);
|
|
_this.buildParams.forEach(function (param, i) {
|
|
if (i < argc) {
|
|
addParam(built, param, args[i], true);
|
|
}
|
|
else {
|
|
addParam(built, param, null, false);
|
|
}
|
|
});
|
|
Object.keys(_this.allFields).forEach(function (param) {
|
|
// Use the default value.
|
|
addParam(built, param, null, false);
|
|
});
|
|
// Make sure that the "type" field was filled automatically.
|
|
if (built.type !== _this.typeName) {
|
|
throw new Error("");
|
|
}
|
|
return built;
|
|
};
|
|
// Calling .from on the builder function will construct an instance of the Def,
|
|
// using field values from the passed object. For fields missing from the passed object,
|
|
// their default value will be used.
|
|
builder.from = function (obj) {
|
|
if (!_this.finalized) {
|
|
throw new Error("attempting to instantiate unfinalized type " +
|
|
_this.typeName);
|
|
}
|
|
var built = Object.create(nodePrototype);
|
|
Object.keys(_this.allFields).forEach(function (param) {
|
|
if (hasOwn.call(obj, param)) {
|
|
addParam(built, param, obj[param], true);
|
|
}
|
|
else {
|
|
addParam(built, param, null, false);
|
|
}
|
|
});
|
|
// Make sure that the "type" field was filled automatically.
|
|
if (built.type !== _this.typeName) {
|
|
throw new Error("");
|
|
}
|
|
return built;
|
|
};
|
|
Object.defineProperty(builders, getBuilderName(this.typeName), {
|
|
enumerable: true,
|
|
value: builder
|
|
});
|
|
return this;
|
|
};
|
|
// The reason fields are specified using .field(...) instead of an object
|
|
// literal syntax is somewhat subtle: the object literal syntax would
|
|
// support only one key and one value, but with .field(...) we can pass
|
|
// any number of arguments to specify the field.
|
|
DefImpl.prototype.field = function (name, type, defaultFn, hidden) {
|
|
if (this.finalized) {
|
|
console.error("Ignoring attempt to redefine field " +
|
|
JSON.stringify(name) + " of finalized type " +
|
|
JSON.stringify(this.typeName));
|
|
return this;
|
|
}
|
|
this.ownFields[name] = new Field(name, Type.from(type), defaultFn, hidden);
|
|
return this; // For chaining.
|
|
};
|
|
DefImpl.prototype.finalize = function () {
|
|
var _this = this;
|
|
// It's not an error to finalize a type more than once, but only the
|
|
// first call to .finalize does anything.
|
|
if (!this.finalized) {
|
|
var allFields = this.allFields;
|
|
var allSupertypes = this.allSupertypes;
|
|
this.baseNames.forEach(function (name) {
|
|
var def = defCache[name];
|
|
if (def instanceof Def) {
|
|
def.finalize();
|
|
extend(allFields, def.allFields);
|
|
extend(allSupertypes, def.allSupertypes);
|
|
}
|
|
else {
|
|
var message = "unknown supertype name " +
|
|
JSON.stringify(name) +
|
|
" for subtype " +
|
|
JSON.stringify(_this.typeName);
|
|
throw new Error(message);
|
|
}
|
|
});
|
|
// TODO Warn if fields are overridden with incompatible types.
|
|
extend(allFields, this.ownFields);
|
|
allSupertypes[this.typeName] = this;
|
|
this.fieldNames.length = 0;
|
|
for (var fieldName in allFields) {
|
|
if (hasOwn.call(allFields, fieldName) &&
|
|
!allFields[fieldName].hidden) {
|
|
this.fieldNames.push(fieldName);
|
|
}
|
|
}
|
|
// Types are exported only once they have been finalized.
|
|
Object.defineProperty(namedTypes, this.typeName, {
|
|
enumerable: true,
|
|
value: this.type
|
|
});
|
|
this.finalized = true;
|
|
// A linearization of the inheritance hierarchy.
|
|
populateSupertypeList(this.typeName, this.supertypeList);
|
|
if (this.buildable &&
|
|
this.supertypeList.lastIndexOf("Expression") >= 0) {
|
|
wrapExpressionBuilderWithStatement(this.typeName);
|
|
}
|
|
}
|
|
};
|
|
return DefImpl;
|
|
}(Def));
|
|
// Note that the list returned by this function is a copy of the internal
|
|
// supertypeList, *without* the typeName itself as the first element.
|
|
function getSupertypeNames(typeName) {
|
|
if (!hasOwn.call(defCache, typeName)) {
|
|
throw new Error("");
|
|
}
|
|
var d = defCache[typeName];
|
|
if (d.finalized !== true) {
|
|
throw new Error("");
|
|
}
|
|
return d.supertypeList.slice(1);
|
|
}
|
|
// Returns an object mapping from every known type in the defCache to the
|
|
// most specific supertype whose name is an own property of the candidates
|
|
// object.
|
|
function computeSupertypeLookupTable(candidates) {
|
|
var table = {};
|
|
var typeNames = Object.keys(defCache);
|
|
var typeNameCount = typeNames.length;
|
|
for (var i = 0; i < typeNameCount; ++i) {
|
|
var typeName = typeNames[i];
|
|
var d = defCache[typeName];
|
|
if (d.finalized !== true) {
|
|
throw new Error("" + typeName);
|
|
}
|
|
for (var j = 0; j < d.supertypeList.length; ++j) {
|
|
var superTypeName = d.supertypeList[j];
|
|
if (hasOwn.call(candidates, superTypeName)) {
|
|
table[typeName] = superTypeName;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return table;
|
|
}
|
|
var builders = Object.create(null);
|
|
// This object is used as prototype for any node created by a builder.
|
|
var nodePrototype = {};
|
|
// Call this function to define a new method to be shared by all AST
|
|
// nodes. The replaced method (if any) is returned for easy wrapping.
|
|
function defineMethod(name, func) {
|
|
var old = nodePrototype[name];
|
|
// Pass undefined as func to delete nodePrototype[name].
|
|
if (isUndefined.check(func)) {
|
|
delete nodePrototype[name];
|
|
}
|
|
else {
|
|
isFunction.assert(func);
|
|
Object.defineProperty(nodePrototype, name, {
|
|
enumerable: true,
|
|
configurable: true,
|
|
value: func
|
|
});
|
|
}
|
|
return old;
|
|
}
|
|
function getBuilderName(typeName) {
|
|
return typeName.replace(/^[A-Z]+/, function (upperCasePrefix) {
|
|
var len = upperCasePrefix.length;
|
|
switch (len) {
|
|
case 0: return "";
|
|
// If there's only one initial capital letter, just lower-case it.
|
|
case 1: return upperCasePrefix.toLowerCase();
|
|
default:
|
|
// If there's more than one initial capital letter, lower-case
|
|
// all but the last one, so that XMLDefaultDeclaration (for
|
|
// example) becomes xmlDefaultDeclaration.
|
|
return upperCasePrefix.slice(0, len - 1).toLowerCase() +
|
|
upperCasePrefix.charAt(len - 1);
|
|
}
|
|
});
|
|
}
|
|
function getStatementBuilderName(typeName) {
|
|
typeName = getBuilderName(typeName);
|
|
return typeName.replace(/(Expression)?$/, "Statement");
|
|
}
|
|
var namedTypes = {};
|
|
// Like Object.keys, but aware of what fields each AST type should have.
|
|
function getFieldNames(object) {
|
|
var d = defFromValue(object);
|
|
if (d) {
|
|
return d.fieldNames.slice(0);
|
|
}
|
|
if ("type" in object) {
|
|
throw new Error("did not recognize object of type " +
|
|
JSON.stringify(object.type));
|
|
}
|
|
return Object.keys(object);
|
|
}
|
|
// Get the value of an object property, taking object.type and default
|
|
// functions into account.
|
|
function getFieldValue(object, fieldName) {
|
|
var d = defFromValue(object);
|
|
if (d) {
|
|
var field = d.allFields[fieldName];
|
|
if (field) {
|
|
return field.getValue(object);
|
|
}
|
|
}
|
|
return object && object[fieldName];
|
|
}
|
|
// Iterate over all defined fields of an object, including those missing
|
|
// or undefined, passing each field name and effective value (as returned
|
|
// by getFieldValue) to the callback. If the object has no corresponding
|
|
// Def, the callback will never be called.
|
|
function eachField(object, callback, context) {
|
|
getFieldNames(object).forEach(function (name) {
|
|
callback.call(this, name, getFieldValue(object, name));
|
|
}, context);
|
|
}
|
|
// Similar to eachField, except that iteration stops as soon as the
|
|
// callback returns a truthy value. Like Array.prototype.some, the final
|
|
// result is either true or false to indicates whether the callback
|
|
// returned true for any element or not.
|
|
function someField(object, callback, context) {
|
|
return getFieldNames(object).some(function (name) {
|
|
return callback.call(this, name, getFieldValue(object, name));
|
|
}, context);
|
|
}
|
|
// Adds an additional builder for Expression subtypes
|
|
// that wraps the built Expression in an ExpressionStatements.
|
|
function wrapExpressionBuilderWithStatement(typeName) {
|
|
var wrapperName = getStatementBuilderName(typeName);
|
|
// skip if the builder already exists
|
|
if (builders[wrapperName])
|
|
return;
|
|
// the builder function to wrap with builders.ExpressionStatement
|
|
var wrapped = builders[getBuilderName(typeName)];
|
|
// skip if there is nothing to wrap
|
|
if (!wrapped)
|
|
return;
|
|
var builder = function () {
|
|
var args = [];
|
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
args[_i] = arguments[_i];
|
|
}
|
|
return builders.expressionStatement(wrapped.apply(builders, args));
|
|
};
|
|
builder.from = function () {
|
|
var args = [];
|
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
args[_i] = arguments[_i];
|
|
}
|
|
return builders.expressionStatement(wrapped.from.apply(builders, args));
|
|
};
|
|
builders[wrapperName] = builder;
|
|
}
|
|
function populateSupertypeList(typeName, list) {
|
|
list.length = 0;
|
|
list.push(typeName);
|
|
var lastSeen = Object.create(null);
|
|
for (var pos = 0; pos < list.length; ++pos) {
|
|
typeName = list[pos];
|
|
var d = defCache[typeName];
|
|
if (d.finalized !== true) {
|
|
throw new Error("");
|
|
}
|
|
// If we saw typeName earlier in the breadth-first traversal,
|
|
// delete the last-seen occurrence.
|
|
if (hasOwn.call(lastSeen, typeName)) {
|
|
delete list[lastSeen[typeName]];
|
|
}
|
|
// Record the new index of the last-seen occurrence of typeName.
|
|
lastSeen[typeName] = pos;
|
|
// Enqueue the base names of this type.
|
|
list.push.apply(list, d.baseNames);
|
|
}
|
|
// Compaction loop to remove array holes.
|
|
for (var to = 0, from = to, len = list.length; from < len; ++from) {
|
|
if (hasOwn.call(list, from)) {
|
|
list[to++] = list[from];
|
|
}
|
|
}
|
|
list.length = to;
|
|
}
|
|
function extend(into, from) {
|
|
Object.keys(from).forEach(function (name) {
|
|
into[name] = from[name];
|
|
});
|
|
return into;
|
|
}
|
|
function finalize() {
|
|
Object.keys(defCache).forEach(function (name) {
|
|
defCache[name].finalize();
|
|
});
|
|
}
|
|
return {
|
|
Type: Type,
|
|
builtInTypes: builtInTypes,
|
|
getSupertypeNames: getSupertypeNames,
|
|
computeSupertypeLookupTable: computeSupertypeLookupTable,
|
|
builders: builders,
|
|
defineMethod: defineMethod,
|
|
getBuilderName: getBuilderName,
|
|
getStatementBuilderName: getStatementBuilderName,
|
|
namedTypes: namedTypes,
|
|
getFieldNames: getFieldNames,
|
|
getFieldValue: getFieldValue,
|
|
eachField: eachField,
|
|
someField: someField,
|
|
finalize: finalize,
|
|
};
|
|
}
|
|
exports$1.default = typesPlugin;
|
|
(0, shared_1.maybeSetModuleExports)(function () { return module; });
|
|
|
|
} (types, types.exports));
|
|
return types.exports;
|
|
}
|
|
|
|
var pathVisitor = {exports: {}};
|
|
|
|
var nodePath = {exports: {}};
|
|
|
|
var path = {exports: {}};
|
|
|
|
path.exports;
|
|
|
|
var hasRequiredPath;
|
|
|
|
function requirePath () {
|
|
if (hasRequiredPath) return path.exports;
|
|
hasRequiredPath = 1;
|
|
(function (module, exports$1) {
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
var tslib_1 = require$$0;
|
|
var shared_1 = requireShared();
|
|
var types_1 = tslib_1.__importDefault(requireTypes());
|
|
var Op = Object.prototype;
|
|
var hasOwn = Op.hasOwnProperty;
|
|
function pathPlugin(fork) {
|
|
var types = fork.use(types_1.default);
|
|
var isArray = types.builtInTypes.array;
|
|
var isNumber = types.builtInTypes.number;
|
|
var Path = function Path(value, parentPath, name) {
|
|
if (!(this instanceof Path)) {
|
|
throw new Error("Path constructor cannot be invoked without 'new'");
|
|
}
|
|
if (parentPath) {
|
|
if (!(parentPath instanceof Path)) {
|
|
throw new Error("");
|
|
}
|
|
}
|
|
else {
|
|
parentPath = null;
|
|
name = null;
|
|
}
|
|
// The value encapsulated by this Path, generally equal to
|
|
// parentPath.value[name] if we have a parentPath.
|
|
this.value = value;
|
|
// The immediate parent Path of this Path.
|
|
this.parentPath = parentPath;
|
|
// The name of the property of parentPath.value through which this
|
|
// Path's value was reached.
|
|
this.name = name;
|
|
// Calling path.get("child") multiple times always returns the same
|
|
// child Path object, for both performance and consistency reasons.
|
|
this.__childCache = null;
|
|
};
|
|
var Pp = Path.prototype;
|
|
function getChildCache(path) {
|
|
// Lazily create the child cache. This also cheapens cache
|
|
// invalidation, since you can just reset path.__childCache to null.
|
|
return path.__childCache || (path.__childCache = Object.create(null));
|
|
}
|
|
function getChildPath(path, name) {
|
|
var cache = getChildCache(path);
|
|
var actualChildValue = path.getValueProperty(name);
|
|
var childPath = cache[name];
|
|
if (!hasOwn.call(cache, name) ||
|
|
// Ensure consistency between cache and reality.
|
|
childPath.value !== actualChildValue) {
|
|
childPath = cache[name] = new path.constructor(actualChildValue, path, name);
|
|
}
|
|
return childPath;
|
|
}
|
|
// This method is designed to be overridden by subclasses that need to
|
|
// handle missing properties, etc.
|
|
Pp.getValueProperty = function getValueProperty(name) {
|
|
return this.value[name];
|
|
};
|
|
Pp.get = function get() {
|
|
var names = [];
|
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
names[_i] = arguments[_i];
|
|
}
|
|
var path = this;
|
|
var count = names.length;
|
|
for (var i = 0; i < count; ++i) {
|
|
path = getChildPath(path, names[i]);
|
|
}
|
|
return path;
|
|
};
|
|
Pp.each = function each(callback, context) {
|
|
var childPaths = [];
|
|
var len = this.value.length;
|
|
var i = 0;
|
|
// Collect all the original child paths before invoking the callback.
|
|
for (var i = 0; i < len; ++i) {
|
|
if (hasOwn.call(this.value, i)) {
|
|
childPaths[i] = this.get(i);
|
|
}
|
|
}
|
|
// Invoke the callback on just the original child paths, regardless of
|
|
// any modifications made to the array by the callback. I chose these
|
|
// semantics over cleverly invoking the callback on new elements because
|
|
// this way is much easier to reason about.
|
|
context = context || this;
|
|
for (i = 0; i < len; ++i) {
|
|
if (hasOwn.call(childPaths, i)) {
|
|
callback.call(context, childPaths[i]);
|
|
}
|
|
}
|
|
};
|
|
Pp.map = function map(callback, context) {
|
|
var result = [];
|
|
this.each(function (childPath) {
|
|
result.push(callback.call(this, childPath));
|
|
}, context);
|
|
return result;
|
|
};
|
|
Pp.filter = function filter(callback, context) {
|
|
var result = [];
|
|
this.each(function (childPath) {
|
|
if (callback.call(this, childPath)) {
|
|
result.push(childPath);
|
|
}
|
|
}, context);
|
|
return result;
|
|
};
|
|
function emptyMoves() { }
|
|
function getMoves(path, offset, start, end) {
|
|
isArray.assert(path.value);
|
|
if (offset === 0) {
|
|
return emptyMoves;
|
|
}
|
|
var length = path.value.length;
|
|
if (length < 1) {
|
|
return emptyMoves;
|
|
}
|
|
var argc = arguments.length;
|
|
if (argc === 2) {
|
|
start = 0;
|
|
end = length;
|
|
}
|
|
else if (argc === 3) {
|
|
start = Math.max(start, 0);
|
|
end = length;
|
|
}
|
|
else {
|
|
start = Math.max(start, 0);
|
|
end = Math.min(end, length);
|
|
}
|
|
isNumber.assert(start);
|
|
isNumber.assert(end);
|
|
var moves = Object.create(null);
|
|
var cache = getChildCache(path);
|
|
for (var i = start; i < end; ++i) {
|
|
if (hasOwn.call(path.value, i)) {
|
|
var childPath = path.get(i);
|
|
if (childPath.name !== i) {
|
|
throw new Error("");
|
|
}
|
|
var newIndex = i + offset;
|
|
childPath.name = newIndex;
|
|
moves[newIndex] = childPath;
|
|
delete cache[i];
|
|
}
|
|
}
|
|
delete cache.length;
|
|
return function () {
|
|
for (var newIndex in moves) {
|
|
var childPath = moves[newIndex];
|
|
if (childPath.name !== +newIndex) {
|
|
throw new Error("");
|
|
}
|
|
cache[newIndex] = childPath;
|
|
path.value[newIndex] = childPath.value;
|
|
}
|
|
};
|
|
}
|
|
Pp.shift = function shift() {
|
|
var move = getMoves(this, -1);
|
|
var result = this.value.shift();
|
|
move();
|
|
return result;
|
|
};
|
|
Pp.unshift = function unshift() {
|
|
var args = [];
|
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
args[_i] = arguments[_i];
|
|
}
|
|
var move = getMoves(this, args.length);
|
|
var result = this.value.unshift.apply(this.value, args);
|
|
move();
|
|
return result;
|
|
};
|
|
Pp.push = function push() {
|
|
var args = [];
|
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
args[_i] = arguments[_i];
|
|
}
|
|
isArray.assert(this.value);
|
|
delete getChildCache(this).length;
|
|
return this.value.push.apply(this.value, args);
|
|
};
|
|
Pp.pop = function pop() {
|
|
isArray.assert(this.value);
|
|
var cache = getChildCache(this);
|
|
delete cache[this.value.length - 1];
|
|
delete cache.length;
|
|
return this.value.pop();
|
|
};
|
|
Pp.insertAt = function insertAt(index) {
|
|
var argc = arguments.length;
|
|
var move = getMoves(this, argc - 1, index);
|
|
if (move === emptyMoves && argc <= 1) {
|
|
return this;
|
|
}
|
|
index = Math.max(index, 0);
|
|
for (var i = 1; i < argc; ++i) {
|
|
this.value[index + i - 1] = arguments[i];
|
|
}
|
|
move();
|
|
return this;
|
|
};
|
|
Pp.insertBefore = function insertBefore() {
|
|
var args = [];
|
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
args[_i] = arguments[_i];
|
|
}
|
|
var pp = this.parentPath;
|
|
var argc = args.length;
|
|
var insertAtArgs = [this.name];
|
|
for (var i = 0; i < argc; ++i) {
|
|
insertAtArgs.push(args[i]);
|
|
}
|
|
return pp.insertAt.apply(pp, insertAtArgs);
|
|
};
|
|
Pp.insertAfter = function insertAfter() {
|
|
var args = [];
|
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
args[_i] = arguments[_i];
|
|
}
|
|
var pp = this.parentPath;
|
|
var argc = args.length;
|
|
var insertAtArgs = [this.name + 1];
|
|
for (var i = 0; i < argc; ++i) {
|
|
insertAtArgs.push(args[i]);
|
|
}
|
|
return pp.insertAt.apply(pp, insertAtArgs);
|
|
};
|
|
function repairRelationshipWithParent(path) {
|
|
if (!(path instanceof Path)) {
|
|
throw new Error("");
|
|
}
|
|
var pp = path.parentPath;
|
|
if (!pp) {
|
|
// Orphan paths have no relationship to repair.
|
|
return path;
|
|
}
|
|
var parentValue = pp.value;
|
|
var parentCache = getChildCache(pp);
|
|
// Make sure parentCache[path.name] is populated.
|
|
if (parentValue[path.name] === path.value) {
|
|
parentCache[path.name] = path;
|
|
}
|
|
else if (isArray.check(parentValue)) {
|
|
// Something caused path.name to become out of date, so attempt to
|
|
// recover by searching for path.value in parentValue.
|
|
var i = parentValue.indexOf(path.value);
|
|
if (i >= 0) {
|
|
parentCache[path.name = i] = path;
|
|
}
|
|
}
|
|
else {
|
|
// If path.value disagrees with parentValue[path.name], and
|
|
// path.name is not an array index, let path.value become the new
|
|
// parentValue[path.name] and update parentCache accordingly.
|
|
parentValue[path.name] = path.value;
|
|
parentCache[path.name] = path;
|
|
}
|
|
if (parentValue[path.name] !== path.value) {
|
|
throw new Error("");
|
|
}
|
|
if (path.parentPath.get(path.name) !== path) {
|
|
throw new Error("");
|
|
}
|
|
return path;
|
|
}
|
|
Pp.replace = function replace(replacement) {
|
|
var results = [];
|
|
var parentValue = this.parentPath.value;
|
|
var parentCache = getChildCache(this.parentPath);
|
|
var count = arguments.length;
|
|
repairRelationshipWithParent(this);
|
|
if (isArray.check(parentValue)) {
|
|
var originalLength = parentValue.length;
|
|
var move = getMoves(this.parentPath, count - 1, this.name + 1);
|
|
var spliceArgs = [this.name, 1];
|
|
for (var i = 0; i < count; ++i) {
|
|
spliceArgs.push(arguments[i]);
|
|
}
|
|
var splicedOut = parentValue.splice.apply(parentValue, spliceArgs);
|
|
if (splicedOut[0] !== this.value) {
|
|
throw new Error("");
|
|
}
|
|
if (parentValue.length !== (originalLength - 1 + count)) {
|
|
throw new Error("");
|
|
}
|
|
move();
|
|
if (count === 0) {
|
|
delete this.value;
|
|
delete parentCache[this.name];
|
|
this.__childCache = null;
|
|
}
|
|
else {
|
|
if (parentValue[this.name] !== replacement) {
|
|
throw new Error("");
|
|
}
|
|
if (this.value !== replacement) {
|
|
this.value = replacement;
|
|
this.__childCache = null;
|
|
}
|
|
for (i = 0; i < count; ++i) {
|
|
results.push(this.parentPath.get(this.name + i));
|
|
}
|
|
if (results[0] !== this) {
|
|
throw new Error("");
|
|
}
|
|
}
|
|
}
|
|
else if (count === 1) {
|
|
if (this.value !== replacement) {
|
|
this.__childCache = null;
|
|
}
|
|
this.value = parentValue[this.name] = replacement;
|
|
results.push(this);
|
|
}
|
|
else if (count === 0) {
|
|
delete parentValue[this.name];
|
|
delete this.value;
|
|
this.__childCache = null;
|
|
// Leave this path cached as parentCache[this.name], even though
|
|
// it no longer has a value defined.
|
|
}
|
|
else {
|
|
throw new Error("Could not replace path");
|
|
}
|
|
return results;
|
|
};
|
|
return Path;
|
|
}
|
|
exports$1.default = pathPlugin;
|
|
(0, shared_1.maybeSetModuleExports)(function () { return module; });
|
|
|
|
} (path, path.exports));
|
|
return path.exports;
|
|
}
|
|
|
|
var scope = {exports: {}};
|
|
|
|
scope.exports;
|
|
|
|
var hasRequiredScope;
|
|
|
|
function requireScope () {
|
|
if (hasRequiredScope) return scope.exports;
|
|
hasRequiredScope = 1;
|
|
(function (module, exports$1) {
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
var tslib_1 = require$$0;
|
|
var shared_1 = requireShared();
|
|
var types_1 = tslib_1.__importDefault(requireTypes());
|
|
var hasOwn = Object.prototype.hasOwnProperty;
|
|
function scopePlugin(fork) {
|
|
var types = fork.use(types_1.default);
|
|
var Type = types.Type;
|
|
var namedTypes = types.namedTypes;
|
|
var Node = namedTypes.Node;
|
|
var Expression = namedTypes.Expression;
|
|
var isArray = types.builtInTypes.array;
|
|
var b = types.builders;
|
|
var Scope = function Scope(path, parentScope) {
|
|
if (!(this instanceof Scope)) {
|
|
throw new Error("Scope constructor cannot be invoked without 'new'");
|
|
}
|
|
if (!TypeParameterScopeType.check(path.value)) {
|
|
ScopeType.assert(path.value);
|
|
}
|
|
var depth;
|
|
if (parentScope) {
|
|
if (!(parentScope instanceof Scope)) {
|
|
throw new Error("");
|
|
}
|
|
depth = parentScope.depth + 1;
|
|
}
|
|
else {
|
|
parentScope = null;
|
|
depth = 0;
|
|
}
|
|
Object.defineProperties(this, {
|
|
path: { value: path },
|
|
node: { value: path.value },
|
|
isGlobal: { value: !parentScope, enumerable: true },
|
|
depth: { value: depth },
|
|
parent: { value: parentScope },
|
|
bindings: { value: {} },
|
|
types: { value: {} },
|
|
});
|
|
};
|
|
var ScopeType = Type.or(
|
|
// Program nodes introduce global scopes.
|
|
namedTypes.Program,
|
|
// Function is the supertype of FunctionExpression,
|
|
// FunctionDeclaration, ArrowExpression, etc.
|
|
namedTypes.Function,
|
|
// In case you didn't know, the caught parameter shadows any variable
|
|
// of the same name in an outer scope.
|
|
namedTypes.CatchClause);
|
|
// These types introduce scopes that are restricted to type parameters in
|
|
// Flow (this doesn't apply to ECMAScript).
|
|
var TypeParameterScopeType = Type.or(namedTypes.Function, namedTypes.ClassDeclaration, namedTypes.ClassExpression, namedTypes.InterfaceDeclaration, namedTypes.TSInterfaceDeclaration, namedTypes.TypeAlias, namedTypes.TSTypeAliasDeclaration);
|
|
var FlowOrTSTypeParameterType = Type.or(namedTypes.TypeParameter, namedTypes.TSTypeParameter);
|
|
Scope.isEstablishedBy = function (node) {
|
|
return ScopeType.check(node) || TypeParameterScopeType.check(node);
|
|
};
|
|
var Sp = Scope.prototype;
|
|
// Will be overridden after an instance lazily calls scanScope.
|
|
Sp.didScan = false;
|
|
Sp.declares = function (name) {
|
|
this.scan();
|
|
return hasOwn.call(this.bindings, name);
|
|
};
|
|
Sp.declaresType = function (name) {
|
|
this.scan();
|
|
return hasOwn.call(this.types, name);
|
|
};
|
|
Sp.declareTemporary = function (prefix) {
|
|
if (prefix) {
|
|
if (!/^[a-z$_]/i.test(prefix)) {
|
|
throw new Error("");
|
|
}
|
|
}
|
|
else {
|
|
prefix = "t$";
|
|
}
|
|
// Include this.depth in the name to make sure the name does not
|
|
// collide with any variables in nested/enclosing scopes.
|
|
prefix += this.depth.toString(36) + "$";
|
|
this.scan();
|
|
var index = 0;
|
|
while (this.declares(prefix + index)) {
|
|
++index;
|
|
}
|
|
var name = prefix + index;
|
|
return this.bindings[name] = types.builders.identifier(name);
|
|
};
|
|
Sp.injectTemporary = function (identifier, init) {
|
|
identifier || (identifier = this.declareTemporary());
|
|
var bodyPath = this.path.get("body");
|
|
if (namedTypes.BlockStatement.check(bodyPath.value)) {
|
|
bodyPath = bodyPath.get("body");
|
|
}
|
|
bodyPath.unshift(b.variableDeclaration("var", [b.variableDeclarator(identifier, init || null)]));
|
|
return identifier;
|
|
};
|
|
Sp.scan = function (force) {
|
|
if (force || !this.didScan) {
|
|
for (var name in this.bindings) {
|
|
// Empty out this.bindings, just in cases.
|
|
delete this.bindings[name];
|
|
}
|
|
for (var name in this.types) {
|
|
// Empty out this.types, just in cases.
|
|
delete this.types[name];
|
|
}
|
|
scanScope(this.path, this.bindings, this.types);
|
|
this.didScan = true;
|
|
}
|
|
};
|
|
Sp.getBindings = function () {
|
|
this.scan();
|
|
return this.bindings;
|
|
};
|
|
Sp.getTypes = function () {
|
|
this.scan();
|
|
return this.types;
|
|
};
|
|
function scanScope(path, bindings, scopeTypes) {
|
|
var node = path.value;
|
|
if (TypeParameterScopeType.check(node)) {
|
|
var params = path.get('typeParameters', 'params');
|
|
if (isArray.check(params.value)) {
|
|
params.each(function (childPath) {
|
|
addTypeParameter(childPath, scopeTypes);
|
|
});
|
|
}
|
|
}
|
|
if (ScopeType.check(node)) {
|
|
if (namedTypes.CatchClause.check(node)) {
|
|
// A catch clause establishes a new scope but the only variable
|
|
// bound in that scope is the catch parameter. Any other
|
|
// declarations create bindings in the outer scope.
|
|
addPattern(path.get("param"), bindings);
|
|
}
|
|
else {
|
|
recursiveScanScope(path, bindings, scopeTypes);
|
|
}
|
|
}
|
|
}
|
|
function recursiveScanScope(path, bindings, scopeTypes) {
|
|
var node = path.value;
|
|
if (path.parent &&
|
|
namedTypes.FunctionExpression.check(path.parent.node) &&
|
|
path.parent.node.id) {
|
|
addPattern(path.parent.get("id"), bindings);
|
|
}
|
|
if (!node) ;
|
|
else if (isArray.check(node)) {
|
|
path.each(function (childPath) {
|
|
recursiveScanChild(childPath, bindings, scopeTypes);
|
|
});
|
|
}
|
|
else if (namedTypes.Function.check(node)) {
|
|
path.get("params").each(function (paramPath) {
|
|
addPattern(paramPath, bindings);
|
|
});
|
|
recursiveScanChild(path.get("body"), bindings, scopeTypes);
|
|
recursiveScanScope(path.get("typeParameters"), bindings, scopeTypes);
|
|
}
|
|
else if ((namedTypes.TypeAlias && namedTypes.TypeAlias.check(node)) ||
|
|
(namedTypes.InterfaceDeclaration && namedTypes.InterfaceDeclaration.check(node)) ||
|
|
(namedTypes.TSTypeAliasDeclaration && namedTypes.TSTypeAliasDeclaration.check(node)) ||
|
|
(namedTypes.TSInterfaceDeclaration && namedTypes.TSInterfaceDeclaration.check(node))) {
|
|
addTypePattern(path.get("id"), scopeTypes);
|
|
}
|
|
else if (namedTypes.VariableDeclarator.check(node)) {
|
|
addPattern(path.get("id"), bindings);
|
|
recursiveScanChild(path.get("init"), bindings, scopeTypes);
|
|
}
|
|
else if (node.type === "ImportSpecifier" ||
|
|
node.type === "ImportNamespaceSpecifier" ||
|
|
node.type === "ImportDefaultSpecifier") {
|
|
addPattern(
|
|
// Esprima used to use the .name field to refer to the local
|
|
// binding identifier for ImportSpecifier nodes, but .id for
|
|
// ImportNamespaceSpecifier and ImportDefaultSpecifier nodes.
|
|
// ESTree/Acorn/ESpree use .local for all three node types.
|
|
path.get(node.local ? "local" :
|
|
node.name ? "name" : "id"), bindings);
|
|
}
|
|
else if (Node.check(node) && !Expression.check(node)) {
|
|
types.eachField(node, function (name, child) {
|
|
var childPath = path.get(name);
|
|
if (!pathHasValue(childPath, child)) {
|
|
throw new Error("");
|
|
}
|
|
recursiveScanChild(childPath, bindings, scopeTypes);
|
|
});
|
|
}
|
|
}
|
|
function pathHasValue(path, value) {
|
|
if (path.value === value) {
|
|
return true;
|
|
}
|
|
// Empty arrays are probably produced by defaults.emptyArray, in which
|
|
// case is makes sense to regard them as equivalent, if not ===.
|
|
if (Array.isArray(path.value) &&
|
|
path.value.length === 0 &&
|
|
Array.isArray(value) &&
|
|
value.length === 0) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
function recursiveScanChild(path, bindings, scopeTypes) {
|
|
var node = path.value;
|
|
if (!node || Expression.check(node)) ;
|
|
else if (namedTypes.FunctionDeclaration.check(node) &&
|
|
node.id !== null) {
|
|
addPattern(path.get("id"), bindings);
|
|
}
|
|
else if (namedTypes.ClassDeclaration &&
|
|
namedTypes.ClassDeclaration.check(node) &&
|
|
node.id !== null) {
|
|
addPattern(path.get("id"), bindings);
|
|
recursiveScanScope(path.get("typeParameters"), bindings, scopeTypes);
|
|
}
|
|
else if ((namedTypes.InterfaceDeclaration &&
|
|
namedTypes.InterfaceDeclaration.check(node)) ||
|
|
(namedTypes.TSInterfaceDeclaration &&
|
|
namedTypes.TSInterfaceDeclaration.check(node))) {
|
|
addTypePattern(path.get("id"), scopeTypes);
|
|
}
|
|
else if (ScopeType.check(node)) {
|
|
if (namedTypes.CatchClause.check(node) &&
|
|
// TODO Broaden this to accept any pattern.
|
|
namedTypes.Identifier.check(node.param)) {
|
|
var catchParamName = node.param.name;
|
|
var hadBinding = hasOwn.call(bindings, catchParamName);
|
|
// Any declarations that occur inside the catch body that do
|
|
// not have the same name as the catch parameter should count
|
|
// as bindings in the outer scope.
|
|
recursiveScanScope(path.get("body"), bindings, scopeTypes);
|
|
// If a new binding matching the catch parameter name was
|
|
// created while scanning the catch body, ignore it because it
|
|
// actually refers to the catch parameter and not the outer
|
|
// scope that we're currently scanning.
|
|
if (!hadBinding) {
|
|
delete bindings[catchParamName];
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
recursiveScanScope(path, bindings, scopeTypes);
|
|
}
|
|
}
|
|
function addPattern(patternPath, bindings) {
|
|
var pattern = patternPath.value;
|
|
namedTypes.Pattern.assert(pattern);
|
|
if (namedTypes.Identifier.check(pattern)) {
|
|
if (hasOwn.call(bindings, pattern.name)) {
|
|
bindings[pattern.name].push(patternPath);
|
|
}
|
|
else {
|
|
bindings[pattern.name] = [patternPath];
|
|
}
|
|
}
|
|
else if (namedTypes.AssignmentPattern &&
|
|
namedTypes.AssignmentPattern.check(pattern)) {
|
|
addPattern(patternPath.get('left'), bindings);
|
|
}
|
|
else if (namedTypes.ObjectPattern &&
|
|
namedTypes.ObjectPattern.check(pattern)) {
|
|
patternPath.get('properties').each(function (propertyPath) {
|
|
var property = propertyPath.value;
|
|
if (namedTypes.Pattern.check(property)) {
|
|
addPattern(propertyPath, bindings);
|
|
}
|
|
else if (namedTypes.Property.check(property) ||
|
|
(namedTypes.ObjectProperty &&
|
|
namedTypes.ObjectProperty.check(property))) {
|
|
addPattern(propertyPath.get('value'), bindings);
|
|
}
|
|
else if (namedTypes.SpreadProperty &&
|
|
namedTypes.SpreadProperty.check(property)) {
|
|
addPattern(propertyPath.get('argument'), bindings);
|
|
}
|
|
});
|
|
}
|
|
else if (namedTypes.ArrayPattern &&
|
|
namedTypes.ArrayPattern.check(pattern)) {
|
|
patternPath.get('elements').each(function (elementPath) {
|
|
var element = elementPath.value;
|
|
if (namedTypes.Pattern.check(element)) {
|
|
addPattern(elementPath, bindings);
|
|
}
|
|
else if (namedTypes.SpreadElement &&
|
|
namedTypes.SpreadElement.check(element)) {
|
|
addPattern(elementPath.get("argument"), bindings);
|
|
}
|
|
});
|
|
}
|
|
else if (namedTypes.PropertyPattern &&
|
|
namedTypes.PropertyPattern.check(pattern)) {
|
|
addPattern(patternPath.get('pattern'), bindings);
|
|
}
|
|
else if ((namedTypes.SpreadElementPattern &&
|
|
namedTypes.SpreadElementPattern.check(pattern)) ||
|
|
(namedTypes.RestElement &&
|
|
namedTypes.RestElement.check(pattern)) ||
|
|
(namedTypes.SpreadPropertyPattern &&
|
|
namedTypes.SpreadPropertyPattern.check(pattern))) {
|
|
addPattern(patternPath.get('argument'), bindings);
|
|
}
|
|
}
|
|
function addTypePattern(patternPath, types) {
|
|
var pattern = patternPath.value;
|
|
namedTypes.Pattern.assert(pattern);
|
|
if (namedTypes.Identifier.check(pattern)) {
|
|
if (hasOwn.call(types, pattern.name)) {
|
|
types[pattern.name].push(patternPath);
|
|
}
|
|
else {
|
|
types[pattern.name] = [patternPath];
|
|
}
|
|
}
|
|
}
|
|
function addTypeParameter(parameterPath, types) {
|
|
var parameter = parameterPath.value;
|
|
FlowOrTSTypeParameterType.assert(parameter);
|
|
if (hasOwn.call(types, parameter.name)) {
|
|
types[parameter.name].push(parameterPath);
|
|
}
|
|
else {
|
|
types[parameter.name] = [parameterPath];
|
|
}
|
|
}
|
|
Sp.lookup = function (name) {
|
|
for (var scope = this; scope; scope = scope.parent)
|
|
if (scope.declares(name))
|
|
break;
|
|
return scope;
|
|
};
|
|
Sp.lookupType = function (name) {
|
|
for (var scope = this; scope; scope = scope.parent)
|
|
if (scope.declaresType(name))
|
|
break;
|
|
return scope;
|
|
};
|
|
Sp.getGlobalScope = function () {
|
|
var scope = this;
|
|
while (!scope.isGlobal)
|
|
scope = scope.parent;
|
|
return scope;
|
|
};
|
|
return Scope;
|
|
}
|
|
exports$1.default = scopePlugin;
|
|
(0, shared_1.maybeSetModuleExports)(function () { return module; });
|
|
|
|
} (scope, scope.exports));
|
|
return scope.exports;
|
|
}
|
|
|
|
nodePath.exports;
|
|
|
|
var hasRequiredNodePath;
|
|
|
|
function requireNodePath () {
|
|
if (hasRequiredNodePath) return nodePath.exports;
|
|
hasRequiredNodePath = 1;
|
|
(function (module, exports$1) {
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
var tslib_1 = require$$0;
|
|
var types_1 = tslib_1.__importDefault(requireTypes());
|
|
var path_1 = tslib_1.__importDefault(requirePath());
|
|
var scope_1 = tslib_1.__importDefault(requireScope());
|
|
var shared_1 = requireShared();
|
|
function nodePathPlugin(fork) {
|
|
var types = fork.use(types_1.default);
|
|
var n = types.namedTypes;
|
|
var b = types.builders;
|
|
var isNumber = types.builtInTypes.number;
|
|
var isArray = types.builtInTypes.array;
|
|
var Path = fork.use(path_1.default);
|
|
var Scope = fork.use(scope_1.default);
|
|
var NodePath = function NodePath(value, parentPath, name) {
|
|
if (!(this instanceof NodePath)) {
|
|
throw new Error("NodePath constructor cannot be invoked without 'new'");
|
|
}
|
|
Path.call(this, value, parentPath, name);
|
|
};
|
|
var NPp = NodePath.prototype = Object.create(Path.prototype, {
|
|
constructor: {
|
|
value: NodePath,
|
|
enumerable: false,
|
|
writable: true,
|
|
configurable: true
|
|
}
|
|
});
|
|
Object.defineProperties(NPp, {
|
|
node: {
|
|
get: function () {
|
|
Object.defineProperty(this, "node", {
|
|
configurable: true,
|
|
value: this._computeNode()
|
|
});
|
|
return this.node;
|
|
}
|
|
},
|
|
parent: {
|
|
get: function () {
|
|
Object.defineProperty(this, "parent", {
|
|
configurable: true,
|
|
value: this._computeParent()
|
|
});
|
|
return this.parent;
|
|
}
|
|
},
|
|
scope: {
|
|
get: function () {
|
|
Object.defineProperty(this, "scope", {
|
|
configurable: true,
|
|
value: this._computeScope()
|
|
});
|
|
return this.scope;
|
|
}
|
|
}
|
|
});
|
|
NPp.replace = function () {
|
|
delete this.node;
|
|
delete this.parent;
|
|
delete this.scope;
|
|
return Path.prototype.replace.apply(this, arguments);
|
|
};
|
|
NPp.prune = function () {
|
|
var remainingNodePath = this.parent;
|
|
this.replace();
|
|
return cleanUpNodesAfterPrune(remainingNodePath);
|
|
};
|
|
// The value of the first ancestor Path whose value is a Node.
|
|
NPp._computeNode = function () {
|
|
var value = this.value;
|
|
if (n.Node.check(value)) {
|
|
return value;
|
|
}
|
|
var pp = this.parentPath;
|
|
return pp && pp.node || null;
|
|
};
|
|
// The first ancestor Path whose value is a Node distinct from this.node.
|
|
NPp._computeParent = function () {
|
|
var value = this.value;
|
|
var pp = this.parentPath;
|
|
if (!n.Node.check(value)) {
|
|
while (pp && !n.Node.check(pp.value)) {
|
|
pp = pp.parentPath;
|
|
}
|
|
if (pp) {
|
|
pp = pp.parentPath;
|
|
}
|
|
}
|
|
while (pp && !n.Node.check(pp.value)) {
|
|
pp = pp.parentPath;
|
|
}
|
|
return pp || null;
|
|
};
|
|
// The closest enclosing scope that governs this node.
|
|
NPp._computeScope = function () {
|
|
var value = this.value;
|
|
var pp = this.parentPath;
|
|
var scope = pp && pp.scope;
|
|
if (n.Node.check(value) &&
|
|
Scope.isEstablishedBy(value)) {
|
|
scope = new Scope(this, scope);
|
|
}
|
|
return scope || null;
|
|
};
|
|
NPp.getValueProperty = function (name) {
|
|
return types.getFieldValue(this.value, name);
|
|
};
|
|
/**
|
|
* Determine whether this.node needs to be wrapped in parentheses in order
|
|
* for a parser to reproduce the same local AST structure.
|
|
*
|
|
* For instance, in the expression `(1 + 2) * 3`, the BinaryExpression
|
|
* whose operator is "+" needs parentheses, because `1 + 2 * 3` would
|
|
* parse differently.
|
|
*
|
|
* If assumeExpressionContext === true, we don't worry about edge cases
|
|
* like an anonymous FunctionExpression appearing lexically first in its
|
|
* enclosing statement and thus needing parentheses to avoid being parsed
|
|
* as a FunctionDeclaration with a missing name.
|
|
*/
|
|
NPp.needsParens = function (assumeExpressionContext) {
|
|
var pp = this.parentPath;
|
|
if (!pp) {
|
|
return false;
|
|
}
|
|
var node = this.value;
|
|
// Only expressions need parentheses.
|
|
if (!n.Expression.check(node)) {
|
|
return false;
|
|
}
|
|
// Identifiers never need parentheses.
|
|
if (node.type === "Identifier") {
|
|
return false;
|
|
}
|
|
while (!n.Node.check(pp.value)) {
|
|
pp = pp.parentPath;
|
|
if (!pp) {
|
|
return false;
|
|
}
|
|
}
|
|
var parent = pp.value;
|
|
switch (node.type) {
|
|
case "UnaryExpression":
|
|
case "SpreadElement":
|
|
case "SpreadProperty":
|
|
return parent.type === "MemberExpression"
|
|
&& this.name === "object"
|
|
&& parent.object === node;
|
|
case "BinaryExpression":
|
|
case "LogicalExpression":
|
|
switch (parent.type) {
|
|
case "CallExpression":
|
|
return this.name === "callee"
|
|
&& parent.callee === node;
|
|
case "UnaryExpression":
|
|
case "SpreadElement":
|
|
case "SpreadProperty":
|
|
return true;
|
|
case "MemberExpression":
|
|
return this.name === "object"
|
|
&& parent.object === node;
|
|
case "BinaryExpression":
|
|
case "LogicalExpression": {
|
|
var n_1 = node;
|
|
var po = parent.operator;
|
|
var pp_1 = PRECEDENCE[po];
|
|
var no = n_1.operator;
|
|
var np = PRECEDENCE[no];
|
|
if (pp_1 > np) {
|
|
return true;
|
|
}
|
|
if (pp_1 === np && this.name === "right") {
|
|
if (parent.right !== n_1) {
|
|
throw new Error("Nodes must be equal");
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
default:
|
|
return false;
|
|
}
|
|
case "SequenceExpression":
|
|
switch (parent.type) {
|
|
case "ForStatement":
|
|
// Although parentheses wouldn't hurt around sequence
|
|
// expressions in the head of for loops, traditional style
|
|
// dictates that e.g. i++, j++ should not be wrapped with
|
|
// parentheses.
|
|
return false;
|
|
case "ExpressionStatement":
|
|
return this.name !== "expression";
|
|
default:
|
|
// Otherwise err on the side of overparenthesization, adding
|
|
// explicit exceptions above if this proves overzealous.
|
|
return true;
|
|
}
|
|
case "YieldExpression":
|
|
switch (parent.type) {
|
|
case "BinaryExpression":
|
|
case "LogicalExpression":
|
|
case "UnaryExpression":
|
|
case "SpreadElement":
|
|
case "SpreadProperty":
|
|
case "CallExpression":
|
|
case "MemberExpression":
|
|
case "NewExpression":
|
|
case "ConditionalExpression":
|
|
case "YieldExpression":
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
case "Literal":
|
|
return parent.type === "MemberExpression"
|
|
&& isNumber.check(node.value)
|
|
&& this.name === "object"
|
|
&& parent.object === node;
|
|
case "AssignmentExpression":
|
|
case "ConditionalExpression":
|
|
switch (parent.type) {
|
|
case "UnaryExpression":
|
|
case "SpreadElement":
|
|
case "SpreadProperty":
|
|
case "BinaryExpression":
|
|
case "LogicalExpression":
|
|
return true;
|
|
case "CallExpression":
|
|
return this.name === "callee"
|
|
&& parent.callee === node;
|
|
case "ConditionalExpression":
|
|
return this.name === "test"
|
|
&& parent.test === node;
|
|
case "MemberExpression":
|
|
return this.name === "object"
|
|
&& parent.object === node;
|
|
default:
|
|
return false;
|
|
}
|
|
default:
|
|
if (parent.type === "NewExpression" &&
|
|
this.name === "callee" &&
|
|
parent.callee === node) {
|
|
return containsCallExpression(node);
|
|
}
|
|
}
|
|
if (assumeExpressionContext !== true &&
|
|
!this.canBeFirstInStatement() &&
|
|
this.firstInStatement())
|
|
return true;
|
|
return false;
|
|
};
|
|
function isBinary(node) {
|
|
return n.BinaryExpression.check(node)
|
|
|| n.LogicalExpression.check(node);
|
|
}
|
|
var PRECEDENCE = {};
|
|
[["||"],
|
|
["&&"],
|
|
["|"],
|
|
["^"],
|
|
["&"],
|
|
["==", "===", "!=", "!=="],
|
|
["<", ">", "<=", ">=", "in", "instanceof"],
|
|
[">>", "<<", ">>>"],
|
|
["+", "-"],
|
|
["*", "/", "%"]
|
|
].forEach(function (tier, i) {
|
|
tier.forEach(function (op) {
|
|
PRECEDENCE[op] = i;
|
|
});
|
|
});
|
|
function containsCallExpression(node) {
|
|
if (n.CallExpression.check(node)) {
|
|
return true;
|
|
}
|
|
if (isArray.check(node)) {
|
|
return node.some(containsCallExpression);
|
|
}
|
|
if (n.Node.check(node)) {
|
|
return types.someField(node, function (_name, child) {
|
|
return containsCallExpression(child);
|
|
});
|
|
}
|
|
return false;
|
|
}
|
|
NPp.canBeFirstInStatement = function () {
|
|
var node = this.node;
|
|
return !n.FunctionExpression.check(node)
|
|
&& !n.ObjectExpression.check(node);
|
|
};
|
|
NPp.firstInStatement = function () {
|
|
return firstInStatement(this);
|
|
};
|
|
function firstInStatement(path) {
|
|
for (var node, parent; path.parent; path = path.parent) {
|
|
node = path.node;
|
|
parent = path.parent.node;
|
|
if (n.BlockStatement.check(parent) &&
|
|
path.parent.name === "body" &&
|
|
path.name === 0) {
|
|
if (parent.body[0] !== node) {
|
|
throw new Error("Nodes must be equal");
|
|
}
|
|
return true;
|
|
}
|
|
if (n.ExpressionStatement.check(parent) &&
|
|
path.name === "expression") {
|
|
if (parent.expression !== node) {
|
|
throw new Error("Nodes must be equal");
|
|
}
|
|
return true;
|
|
}
|
|
if (n.SequenceExpression.check(parent) &&
|
|
path.parent.name === "expressions" &&
|
|
path.name === 0) {
|
|
if (parent.expressions[0] !== node) {
|
|
throw new Error("Nodes must be equal");
|
|
}
|
|
continue;
|
|
}
|
|
if (n.CallExpression.check(parent) &&
|
|
path.name === "callee") {
|
|
if (parent.callee !== node) {
|
|
throw new Error("Nodes must be equal");
|
|
}
|
|
continue;
|
|
}
|
|
if (n.MemberExpression.check(parent) &&
|
|
path.name === "object") {
|
|
if (parent.object !== node) {
|
|
throw new Error("Nodes must be equal");
|
|
}
|
|
continue;
|
|
}
|
|
if (n.ConditionalExpression.check(parent) &&
|
|
path.name === "test") {
|
|
if (parent.test !== node) {
|
|
throw new Error("Nodes must be equal");
|
|
}
|
|
continue;
|
|
}
|
|
if (isBinary(parent) &&
|
|
path.name === "left") {
|
|
if (parent.left !== node) {
|
|
throw new Error("Nodes must be equal");
|
|
}
|
|
continue;
|
|
}
|
|
if (n.UnaryExpression.check(parent) &&
|
|
!parent.prefix &&
|
|
path.name === "argument") {
|
|
if (parent.argument !== node) {
|
|
throw new Error("Nodes must be equal");
|
|
}
|
|
continue;
|
|
}
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
/**
|
|
* Pruning certain nodes will result in empty or incomplete nodes, here we clean those nodes up.
|
|
*/
|
|
function cleanUpNodesAfterPrune(remainingNodePath) {
|
|
if (n.VariableDeclaration.check(remainingNodePath.node)) {
|
|
var declarations = remainingNodePath.get('declarations').value;
|
|
if (!declarations || declarations.length === 0) {
|
|
return remainingNodePath.prune();
|
|
}
|
|
}
|
|
else if (n.ExpressionStatement.check(remainingNodePath.node)) {
|
|
if (!remainingNodePath.get('expression').value) {
|
|
return remainingNodePath.prune();
|
|
}
|
|
}
|
|
else if (n.IfStatement.check(remainingNodePath.node)) {
|
|
cleanUpIfStatementAfterPrune(remainingNodePath);
|
|
}
|
|
return remainingNodePath;
|
|
}
|
|
function cleanUpIfStatementAfterPrune(ifStatement) {
|
|
var testExpression = ifStatement.get('test').value;
|
|
var alternate = ifStatement.get('alternate').value;
|
|
var consequent = ifStatement.get('consequent').value;
|
|
if (!consequent && !alternate) {
|
|
var testExpressionStatement = b.expressionStatement(testExpression);
|
|
ifStatement.replace(testExpressionStatement);
|
|
}
|
|
else if (!consequent && alternate) {
|
|
var negatedTestExpression = b.unaryExpression('!', testExpression, true);
|
|
if (n.UnaryExpression.check(testExpression) && testExpression.operator === '!') {
|
|
negatedTestExpression = testExpression.argument;
|
|
}
|
|
ifStatement.get("test").replace(negatedTestExpression);
|
|
ifStatement.get("consequent").replace(alternate);
|
|
ifStatement.get("alternate").replace();
|
|
}
|
|
}
|
|
return NodePath;
|
|
}
|
|
exports$1.default = nodePathPlugin;
|
|
(0, shared_1.maybeSetModuleExports)(function () { return module; });
|
|
|
|
} (nodePath, nodePath.exports));
|
|
return nodePath.exports;
|
|
}
|
|
|
|
pathVisitor.exports;
|
|
|
|
var hasRequiredPathVisitor;
|
|
|
|
function requirePathVisitor () {
|
|
if (hasRequiredPathVisitor) return pathVisitor.exports;
|
|
hasRequiredPathVisitor = 1;
|
|
(function (module, exports$1) {
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
var tslib_1 = require$$0;
|
|
var types_1 = tslib_1.__importDefault(requireTypes());
|
|
var node_path_1 = tslib_1.__importDefault(requireNodePath());
|
|
var shared_1 = requireShared();
|
|
var hasOwn = Object.prototype.hasOwnProperty;
|
|
function pathVisitorPlugin(fork) {
|
|
var types = fork.use(types_1.default);
|
|
var NodePath = fork.use(node_path_1.default);
|
|
var isArray = types.builtInTypes.array;
|
|
var isObject = types.builtInTypes.object;
|
|
var isFunction = types.builtInTypes.function;
|
|
var undefined$1;
|
|
var PathVisitor = function PathVisitor() {
|
|
if (!(this instanceof PathVisitor)) {
|
|
throw new Error("PathVisitor constructor cannot be invoked without 'new'");
|
|
}
|
|
// Permanent state.
|
|
this._reusableContextStack = [];
|
|
this._methodNameTable = computeMethodNameTable(this);
|
|
this._shouldVisitComments =
|
|
hasOwn.call(this._methodNameTable, "Block") ||
|
|
hasOwn.call(this._methodNameTable, "Line");
|
|
this.Context = makeContextConstructor(this);
|
|
// State reset every time PathVisitor.prototype.visit is called.
|
|
this._visiting = false;
|
|
this._changeReported = false;
|
|
};
|
|
function computeMethodNameTable(visitor) {
|
|
var typeNames = Object.create(null);
|
|
for (var methodName in visitor) {
|
|
if (/^visit[A-Z]/.test(methodName)) {
|
|
typeNames[methodName.slice("visit".length)] = true;
|
|
}
|
|
}
|
|
var supertypeTable = types.computeSupertypeLookupTable(typeNames);
|
|
var methodNameTable = Object.create(null);
|
|
var typeNameKeys = Object.keys(supertypeTable);
|
|
var typeNameCount = typeNameKeys.length;
|
|
for (var i = 0; i < typeNameCount; ++i) {
|
|
var typeName = typeNameKeys[i];
|
|
methodName = "visit" + supertypeTable[typeName];
|
|
if (isFunction.check(visitor[methodName])) {
|
|
methodNameTable[typeName] = methodName;
|
|
}
|
|
}
|
|
return methodNameTable;
|
|
}
|
|
PathVisitor.fromMethodsObject = function fromMethodsObject(methods) {
|
|
if (methods instanceof PathVisitor) {
|
|
return methods;
|
|
}
|
|
if (!isObject.check(methods)) {
|
|
// An empty visitor?
|
|
return new PathVisitor;
|
|
}
|
|
var Visitor = function Visitor() {
|
|
if (!(this instanceof Visitor)) {
|
|
throw new Error("Visitor constructor cannot be invoked without 'new'");
|
|
}
|
|
PathVisitor.call(this);
|
|
};
|
|
var Vp = Visitor.prototype = Object.create(PVp);
|
|
Vp.constructor = Visitor;
|
|
extend(Vp, methods);
|
|
extend(Visitor, PathVisitor);
|
|
isFunction.assert(Visitor.fromMethodsObject);
|
|
isFunction.assert(Visitor.visit);
|
|
return new Visitor;
|
|
};
|
|
function extend(target, source) {
|
|
for (var property in source) {
|
|
if (hasOwn.call(source, property)) {
|
|
target[property] = source[property];
|
|
}
|
|
}
|
|
return target;
|
|
}
|
|
PathVisitor.visit = function visit(node, methods) {
|
|
return PathVisitor.fromMethodsObject(methods).visit(node);
|
|
};
|
|
var PVp = PathVisitor.prototype;
|
|
PVp.visit = function () {
|
|
if (this._visiting) {
|
|
throw new Error("Recursively calling visitor.visit(path) resets visitor state. " +
|
|
"Try this.visit(path) or this.traverse(path) instead.");
|
|
}
|
|
// Private state that needs to be reset before every traversal.
|
|
this._visiting = true;
|
|
this._changeReported = false;
|
|
this._abortRequested = false;
|
|
var argc = arguments.length;
|
|
var args = new Array(argc);
|
|
for (var i = 0; i < argc; ++i) {
|
|
args[i] = arguments[i];
|
|
}
|
|
if (!(args[0] instanceof NodePath)) {
|
|
args[0] = new NodePath({ root: args[0] }).get("root");
|
|
}
|
|
// Called with the same arguments as .visit.
|
|
this.reset.apply(this, args);
|
|
var didNotThrow;
|
|
try {
|
|
var root = this.visitWithoutReset(args[0]);
|
|
didNotThrow = true;
|
|
}
|
|
finally {
|
|
this._visiting = false;
|
|
if (!didNotThrow && this._abortRequested) {
|
|
// If this.visitWithoutReset threw an exception and
|
|
// this._abortRequested was set to true, return the root of
|
|
// the AST instead of letting the exception propagate, so that
|
|
// client code does not have to provide a try-catch block to
|
|
// intercept the AbortRequest exception. Other kinds of
|
|
// exceptions will propagate without being intercepted and
|
|
// rethrown by a catch block, so their stacks will accurately
|
|
// reflect the original throwing context.
|
|
return args[0].value;
|
|
}
|
|
}
|
|
return root;
|
|
};
|
|
PVp.AbortRequest = function AbortRequest() { };
|
|
PVp.abort = function () {
|
|
var visitor = this;
|
|
visitor._abortRequested = true;
|
|
var request = new visitor.AbortRequest();
|
|
// If you decide to catch this exception and stop it from propagating,
|
|
// make sure to call its cancel method to avoid silencing other
|
|
// exceptions that might be thrown later in the traversal.
|
|
request.cancel = function () {
|
|
visitor._abortRequested = false;
|
|
};
|
|
throw request;
|
|
};
|
|
PVp.reset = function (_path /*, additional arguments */) {
|
|
// Empty stub; may be reassigned or overridden by subclasses.
|
|
};
|
|
PVp.visitWithoutReset = function (path) {
|
|
if (this instanceof this.Context) {
|
|
// Since this.Context.prototype === this, there's a chance we
|
|
// might accidentally call context.visitWithoutReset. If that
|
|
// happens, re-invoke the method against context.visitor.
|
|
return this.visitor.visitWithoutReset(path);
|
|
}
|
|
if (!(path instanceof NodePath)) {
|
|
throw new Error("");
|
|
}
|
|
var value = path.value;
|
|
var methodName = value &&
|
|
typeof value === "object" &&
|
|
typeof value.type === "string" &&
|
|
this._methodNameTable[value.type];
|
|
if (methodName) {
|
|
var context = this.acquireContext(path);
|
|
try {
|
|
return context.invokeVisitorMethod(methodName);
|
|
}
|
|
finally {
|
|
this.releaseContext(context);
|
|
}
|
|
}
|
|
else {
|
|
// If there was no visitor method to call, visit the children of
|
|
// this node generically.
|
|
return visitChildren(path, this);
|
|
}
|
|
};
|
|
function visitChildren(path, visitor) {
|
|
if (!(path instanceof NodePath)) {
|
|
throw new Error("");
|
|
}
|
|
if (!(visitor instanceof PathVisitor)) {
|
|
throw new Error("");
|
|
}
|
|
var value = path.value;
|
|
if (isArray.check(value)) {
|
|
path.each(visitor.visitWithoutReset, visitor);
|
|
}
|
|
else if (!isObject.check(value)) ;
|
|
else {
|
|
var childNames = types.getFieldNames(value);
|
|
// The .comments field of the Node type is hidden, so we only
|
|
// visit it if the visitor defines visitBlock or visitLine, and
|
|
// value.comments is defined.
|
|
if (visitor._shouldVisitComments &&
|
|
value.comments &&
|
|
childNames.indexOf("comments") < 0) {
|
|
childNames.push("comments");
|
|
}
|
|
var childCount = childNames.length;
|
|
var childPaths = [];
|
|
for (var i = 0; i < childCount; ++i) {
|
|
var childName = childNames[i];
|
|
if (!hasOwn.call(value, childName)) {
|
|
value[childName] = types.getFieldValue(value, childName);
|
|
}
|
|
childPaths.push(path.get(childName));
|
|
}
|
|
for (var i = 0; i < childCount; ++i) {
|
|
visitor.visitWithoutReset(childPaths[i]);
|
|
}
|
|
}
|
|
return path.value;
|
|
}
|
|
PVp.acquireContext = function (path) {
|
|
if (this._reusableContextStack.length === 0) {
|
|
return new this.Context(path);
|
|
}
|
|
return this._reusableContextStack.pop().reset(path);
|
|
};
|
|
PVp.releaseContext = function (context) {
|
|
if (!(context instanceof this.Context)) {
|
|
throw new Error("");
|
|
}
|
|
this._reusableContextStack.push(context);
|
|
context.currentPath = null;
|
|
};
|
|
PVp.reportChanged = function () {
|
|
this._changeReported = true;
|
|
};
|
|
PVp.wasChangeReported = function () {
|
|
return this._changeReported;
|
|
};
|
|
function makeContextConstructor(visitor) {
|
|
function Context(path) {
|
|
if (!(this instanceof Context)) {
|
|
throw new Error("");
|
|
}
|
|
if (!(this instanceof PathVisitor)) {
|
|
throw new Error("");
|
|
}
|
|
if (!(path instanceof NodePath)) {
|
|
throw new Error("");
|
|
}
|
|
Object.defineProperty(this, "visitor", {
|
|
value: visitor,
|
|
writable: false,
|
|
enumerable: true,
|
|
configurable: false
|
|
});
|
|
this.currentPath = path;
|
|
this.needToCallTraverse = true;
|
|
Object.seal(this);
|
|
}
|
|
if (!(visitor instanceof PathVisitor)) {
|
|
throw new Error("");
|
|
}
|
|
// Note that the visitor object is the prototype of Context.prototype,
|
|
// so all visitor methods are inherited by context objects.
|
|
var Cp = Context.prototype = Object.create(visitor);
|
|
Cp.constructor = Context;
|
|
extend(Cp, sharedContextProtoMethods);
|
|
return Context;
|
|
}
|
|
// Every PathVisitor has a different this.Context constructor and
|
|
// this.Context.prototype object, but those prototypes can all use the
|
|
// same reset, invokeVisitorMethod, and traverse function objects.
|
|
var sharedContextProtoMethods = Object.create(null);
|
|
sharedContextProtoMethods.reset =
|
|
function reset(path) {
|
|
if (!(this instanceof this.Context)) {
|
|
throw new Error("");
|
|
}
|
|
if (!(path instanceof NodePath)) {
|
|
throw new Error("");
|
|
}
|
|
this.currentPath = path;
|
|
this.needToCallTraverse = true;
|
|
return this;
|
|
};
|
|
sharedContextProtoMethods.invokeVisitorMethod =
|
|
function invokeVisitorMethod(methodName) {
|
|
if (!(this instanceof this.Context)) {
|
|
throw new Error("");
|
|
}
|
|
if (!(this.currentPath instanceof NodePath)) {
|
|
throw new Error("");
|
|
}
|
|
var result = this.visitor[methodName].call(this, this.currentPath);
|
|
if (result === false) {
|
|
// Visitor methods return false to indicate that they have handled
|
|
// their own traversal needs, and we should not complain if
|
|
// this.needToCallTraverse is still true.
|
|
this.needToCallTraverse = false;
|
|
}
|
|
else if (result !== undefined$1) {
|
|
// Any other non-undefined value returned from the visitor method
|
|
// is interpreted as a replacement value.
|
|
this.currentPath = this.currentPath.replace(result)[0];
|
|
if (this.needToCallTraverse) {
|
|
// If this.traverse still hasn't been called, visit the
|
|
// children of the replacement node.
|
|
this.traverse(this.currentPath);
|
|
}
|
|
}
|
|
if (this.needToCallTraverse !== false) {
|
|
throw new Error("Must either call this.traverse or return false in " + methodName);
|
|
}
|
|
var path = this.currentPath;
|
|
return path && path.value;
|
|
};
|
|
sharedContextProtoMethods.traverse =
|
|
function traverse(path, newVisitor) {
|
|
if (!(this instanceof this.Context)) {
|
|
throw new Error("");
|
|
}
|
|
if (!(path instanceof NodePath)) {
|
|
throw new Error("");
|
|
}
|
|
if (!(this.currentPath instanceof NodePath)) {
|
|
throw new Error("");
|
|
}
|
|
this.needToCallTraverse = false;
|
|
return visitChildren(path, PathVisitor.fromMethodsObject(newVisitor || this.visitor));
|
|
};
|
|
sharedContextProtoMethods.visit =
|
|
function visit(path, newVisitor) {
|
|
if (!(this instanceof this.Context)) {
|
|
throw new Error("");
|
|
}
|
|
if (!(path instanceof NodePath)) {
|
|
throw new Error("");
|
|
}
|
|
if (!(this.currentPath instanceof NodePath)) {
|
|
throw new Error("");
|
|
}
|
|
this.needToCallTraverse = false;
|
|
return PathVisitor.fromMethodsObject(newVisitor || this.visitor).visitWithoutReset(path);
|
|
};
|
|
sharedContextProtoMethods.reportChanged = function reportChanged() {
|
|
this.visitor.reportChanged();
|
|
};
|
|
sharedContextProtoMethods.abort = function abort() {
|
|
this.needToCallTraverse = false;
|
|
this.visitor.abort();
|
|
};
|
|
return PathVisitor;
|
|
}
|
|
exports$1.default = pathVisitorPlugin;
|
|
(0, shared_1.maybeSetModuleExports)(function () { return module; });
|
|
|
|
} (pathVisitor, pathVisitor.exports));
|
|
return pathVisitor.exports;
|
|
}
|
|
|
|
var equiv = {exports: {}};
|
|
|
|
equiv.exports;
|
|
|
|
var hasRequiredEquiv;
|
|
|
|
function requireEquiv () {
|
|
if (hasRequiredEquiv) return equiv.exports;
|
|
hasRequiredEquiv = 1;
|
|
(function (module, exports$1) {
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
var tslib_1 = require$$0;
|
|
var shared_1 = requireShared();
|
|
var types_1 = tslib_1.__importDefault(requireTypes());
|
|
function default_1(fork) {
|
|
var types = fork.use(types_1.default);
|
|
var getFieldNames = types.getFieldNames;
|
|
var getFieldValue = types.getFieldValue;
|
|
var isArray = types.builtInTypes.array;
|
|
var isObject = types.builtInTypes.object;
|
|
var isDate = types.builtInTypes.Date;
|
|
var isRegExp = types.builtInTypes.RegExp;
|
|
var hasOwn = Object.prototype.hasOwnProperty;
|
|
function astNodesAreEquivalent(a, b, problemPath) {
|
|
if (isArray.check(problemPath)) {
|
|
problemPath.length = 0;
|
|
}
|
|
else {
|
|
problemPath = null;
|
|
}
|
|
return areEquivalent(a, b, problemPath);
|
|
}
|
|
astNodesAreEquivalent.assert = function (a, b) {
|
|
var problemPath = [];
|
|
if (!astNodesAreEquivalent(a, b, problemPath)) {
|
|
if (problemPath.length === 0) {
|
|
if (a !== b) {
|
|
throw new Error("Nodes must be equal");
|
|
}
|
|
}
|
|
else {
|
|
throw new Error("Nodes differ in the following path: " +
|
|
problemPath.map(subscriptForProperty).join(""));
|
|
}
|
|
}
|
|
};
|
|
function subscriptForProperty(property) {
|
|
if (/[_$a-z][_$a-z0-9]*/i.test(property)) {
|
|
return "." + property;
|
|
}
|
|
return "[" + JSON.stringify(property) + "]";
|
|
}
|
|
function areEquivalent(a, b, problemPath) {
|
|
if (a === b) {
|
|
return true;
|
|
}
|
|
if (isArray.check(a)) {
|
|
return arraysAreEquivalent(a, b, problemPath);
|
|
}
|
|
if (isObject.check(a)) {
|
|
return objectsAreEquivalent(a, b, problemPath);
|
|
}
|
|
if (isDate.check(a)) {
|
|
return isDate.check(b) && (+a === +b);
|
|
}
|
|
if (isRegExp.check(a)) {
|
|
return isRegExp.check(b) && (a.source === b.source &&
|
|
a.global === b.global &&
|
|
a.multiline === b.multiline &&
|
|
a.ignoreCase === b.ignoreCase);
|
|
}
|
|
return a == b;
|
|
}
|
|
function arraysAreEquivalent(a, b, problemPath) {
|
|
isArray.assert(a);
|
|
var aLength = a.length;
|
|
if (!isArray.check(b) || b.length !== aLength) {
|
|
if (problemPath) {
|
|
problemPath.push("length");
|
|
}
|
|
return false;
|
|
}
|
|
for (var i = 0; i < aLength; ++i) {
|
|
if (problemPath) {
|
|
problemPath.push(i);
|
|
}
|
|
if (i in a !== i in b) {
|
|
return false;
|
|
}
|
|
if (!areEquivalent(a[i], b[i], problemPath)) {
|
|
return false;
|
|
}
|
|
if (problemPath) {
|
|
var problemPathTail = problemPath.pop();
|
|
if (problemPathTail !== i) {
|
|
throw new Error("" + problemPathTail);
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
function objectsAreEquivalent(a, b, problemPath) {
|
|
isObject.assert(a);
|
|
if (!isObject.check(b)) {
|
|
return false;
|
|
}
|
|
// Fast path for a common property of AST nodes.
|
|
if (a.type !== b.type) {
|
|
if (problemPath) {
|
|
problemPath.push("type");
|
|
}
|
|
return false;
|
|
}
|
|
var aNames = getFieldNames(a);
|
|
var aNameCount = aNames.length;
|
|
var bNames = getFieldNames(b);
|
|
var bNameCount = bNames.length;
|
|
if (aNameCount === bNameCount) {
|
|
for (var i = 0; i < aNameCount; ++i) {
|
|
var name = aNames[i];
|
|
var aChild = getFieldValue(a, name);
|
|
var bChild = getFieldValue(b, name);
|
|
if (problemPath) {
|
|
problemPath.push(name);
|
|
}
|
|
if (!areEquivalent(aChild, bChild, problemPath)) {
|
|
return false;
|
|
}
|
|
if (problemPath) {
|
|
var problemPathTail = problemPath.pop();
|
|
if (problemPathTail !== name) {
|
|
throw new Error("" + problemPathTail);
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
if (!problemPath) {
|
|
return false;
|
|
}
|
|
// Since aNameCount !== bNameCount, we need to find some name that's
|
|
// missing in aNames but present in bNames, or vice-versa.
|
|
var seenNames = Object.create(null);
|
|
for (i = 0; i < aNameCount; ++i) {
|
|
seenNames[aNames[i]] = true;
|
|
}
|
|
for (i = 0; i < bNameCount; ++i) {
|
|
name = bNames[i];
|
|
if (!hasOwn.call(seenNames, name)) {
|
|
problemPath.push(name);
|
|
return false;
|
|
}
|
|
delete seenNames[name];
|
|
}
|
|
for (name in seenNames) {
|
|
problemPath.push(name);
|
|
break;
|
|
}
|
|
return false;
|
|
}
|
|
return astNodesAreEquivalent;
|
|
}
|
|
exports$1.default = default_1;
|
|
(0, shared_1.maybeSetModuleExports)(function () { return module; });
|
|
|
|
} (equiv, equiv.exports));
|
|
return equiv.exports;
|
|
}
|
|
|
|
fork.exports;
|
|
|
|
var hasRequiredFork;
|
|
|
|
function requireFork () {
|
|
if (hasRequiredFork) return fork.exports;
|
|
hasRequiredFork = 1;
|
|
(function (module, exports$1) {
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
var tslib_1 = require$$0;
|
|
var types_1 = tslib_1.__importDefault(requireTypes());
|
|
var path_visitor_1 = tslib_1.__importDefault(requirePathVisitor());
|
|
var equiv_1 = tslib_1.__importDefault(requireEquiv());
|
|
var path_1 = tslib_1.__importDefault(requirePath());
|
|
var node_path_1 = tslib_1.__importDefault(requireNodePath());
|
|
var shared_1 = requireShared();
|
|
function default_1(plugins) {
|
|
var fork = createFork();
|
|
var types = fork.use(types_1.default);
|
|
plugins.forEach(fork.use);
|
|
types.finalize();
|
|
var PathVisitor = fork.use(path_visitor_1.default);
|
|
return {
|
|
Type: types.Type,
|
|
builtInTypes: types.builtInTypes,
|
|
namedTypes: types.namedTypes,
|
|
builders: types.builders,
|
|
defineMethod: types.defineMethod,
|
|
getFieldNames: types.getFieldNames,
|
|
getFieldValue: types.getFieldValue,
|
|
eachField: types.eachField,
|
|
someField: types.someField,
|
|
getSupertypeNames: types.getSupertypeNames,
|
|
getBuilderName: types.getBuilderName,
|
|
astNodesAreEquivalent: fork.use(equiv_1.default),
|
|
finalize: types.finalize,
|
|
Path: fork.use(path_1.default),
|
|
NodePath: fork.use(node_path_1.default),
|
|
PathVisitor: PathVisitor,
|
|
use: fork.use,
|
|
visit: PathVisitor.visit,
|
|
};
|
|
}
|
|
exports$1.default = default_1;
|
|
function createFork() {
|
|
var used = [];
|
|
var usedResult = [];
|
|
function use(plugin) {
|
|
var idx = used.indexOf(plugin);
|
|
if (idx === -1) {
|
|
idx = used.length;
|
|
used.push(plugin);
|
|
usedResult[idx] = plugin(fork);
|
|
}
|
|
return usedResult[idx];
|
|
}
|
|
var fork = { use: use };
|
|
return fork;
|
|
}
|
|
(0, shared_1.maybeSetModuleExports)(function () { return module; });
|
|
|
|
} (fork, fork.exports));
|
|
return fork.exports;
|
|
}
|
|
|
|
var esProposals = {exports: {}};
|
|
|
|
var es2022 = {exports: {}};
|
|
|
|
var es2021$1 = {exports: {}};
|
|
|
|
var es2021 = {exports: {}};
|
|
|
|
var es2020$1 = {exports: {}};
|
|
|
|
var es2016$1 = {exports: {}};
|
|
|
|
var core$1 = {exports: {}};
|
|
|
|
core$1.exports;
|
|
|
|
var hasRequiredCore$1;
|
|
|
|
function requireCore$1 () {
|
|
if (hasRequiredCore$1) return core$1.exports;
|
|
hasRequiredCore$1 = 1;
|
|
(function (module, exports$1) {
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
var shared_1 = requireShared();
|
|
function default_1() {
|
|
return {
|
|
BinaryOperators: [
|
|
"==", "!=", "===", "!==",
|
|
"<", "<=", ">", ">=",
|
|
"<<", ">>", ">>>",
|
|
"+", "-", "*", "/", "%",
|
|
"&",
|
|
"|", "^", "in",
|
|
"instanceof",
|
|
],
|
|
AssignmentOperators: [
|
|
"=", "+=", "-=", "*=", "/=", "%=",
|
|
"<<=", ">>=", ">>>=",
|
|
"|=", "^=", "&=",
|
|
],
|
|
LogicalOperators: [
|
|
"||", "&&",
|
|
],
|
|
};
|
|
}
|
|
exports$1.default = default_1;
|
|
(0, shared_1.maybeSetModuleExports)(function () { return module; });
|
|
|
|
} (core$1, core$1.exports));
|
|
return core$1.exports;
|
|
}
|
|
|
|
es2016$1.exports;
|
|
|
|
var hasRequiredEs2016$1;
|
|
|
|
function requireEs2016$1 () {
|
|
if (hasRequiredEs2016$1) return es2016$1.exports;
|
|
hasRequiredEs2016$1 = 1;
|
|
(function (module, exports$1) {
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
var tslib_1 = require$$0;
|
|
var shared_1 = requireShared();
|
|
var core_1 = tslib_1.__importDefault(requireCore$1());
|
|
function default_1(fork) {
|
|
var result = fork.use(core_1.default);
|
|
// Exponentiation operators. Must run before BinaryOperators or
|
|
// AssignmentOperators are used (hence before fork.use(es6Def)).
|
|
// https://github.com/tc39/proposal-exponentiation-operator
|
|
if (result.BinaryOperators.indexOf("**") < 0) {
|
|
result.BinaryOperators.push("**");
|
|
}
|
|
if (result.AssignmentOperators.indexOf("**=") < 0) {
|
|
result.AssignmentOperators.push("**=");
|
|
}
|
|
return result;
|
|
}
|
|
exports$1.default = default_1;
|
|
(0, shared_1.maybeSetModuleExports)(function () { return module; });
|
|
|
|
} (es2016$1, es2016$1.exports));
|
|
return es2016$1.exports;
|
|
}
|
|
|
|
es2020$1.exports;
|
|
|
|
var hasRequiredEs2020$1;
|
|
|
|
function requireEs2020$1 () {
|
|
if (hasRequiredEs2020$1) return es2020$1.exports;
|
|
hasRequiredEs2020$1 = 1;
|
|
(function (module, exports$1) {
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
var tslib_1 = require$$0;
|
|
var shared_1 = requireShared();
|
|
var es2016_1 = tslib_1.__importDefault(requireEs2016$1());
|
|
function default_1(fork) {
|
|
var result = fork.use(es2016_1.default);
|
|
// Nullish coalescing. Must run before LogicalOperators is used.
|
|
// https://github.com/tc39/proposal-nullish-coalescing
|
|
if (result.LogicalOperators.indexOf("??") < 0) {
|
|
result.LogicalOperators.push("??");
|
|
}
|
|
return result;
|
|
}
|
|
exports$1.default = default_1;
|
|
(0, shared_1.maybeSetModuleExports)(function () { return module; });
|
|
|
|
} (es2020$1, es2020$1.exports));
|
|
return es2020$1.exports;
|
|
}
|
|
|
|
es2021.exports;
|
|
|
|
var hasRequiredEs2021$1;
|
|
|
|
function requireEs2021$1 () {
|
|
if (hasRequiredEs2021$1) return es2021.exports;
|
|
hasRequiredEs2021$1 = 1;
|
|
(function (module, exports$1) {
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
var tslib_1 = require$$0;
|
|
var shared_1 = requireShared();
|
|
var es2020_1 = tslib_1.__importDefault(requireEs2020$1());
|
|
function default_1(fork) {
|
|
var result = fork.use(es2020_1.default);
|
|
// Logical assignment operators. Must run before AssignmentOperators is used.
|
|
// https://github.com/tc39/proposal-logical-assignment
|
|
result.LogicalOperators.forEach(function (op) {
|
|
var assignOp = op + "=";
|
|
if (result.AssignmentOperators.indexOf(assignOp) < 0) {
|
|
result.AssignmentOperators.push(assignOp);
|
|
}
|
|
});
|
|
return result;
|
|
}
|
|
exports$1.default = default_1;
|
|
(0, shared_1.maybeSetModuleExports)(function () { return module; });
|
|
|
|
} (es2021, es2021.exports));
|
|
return es2021.exports;
|
|
}
|
|
|
|
var es2020 = {exports: {}};
|
|
|
|
var es2019 = {exports: {}};
|
|
|
|
var es2018 = {exports: {}};
|
|
|
|
var es2017 = {exports: {}};
|
|
|
|
var es2016 = {exports: {}};
|
|
|
|
var es6 = {exports: {}};
|
|
|
|
var core = {exports: {}};
|
|
|
|
core.exports;
|
|
|
|
var hasRequiredCore;
|
|
|
|
function requireCore () {
|
|
if (hasRequiredCore) return core.exports;
|
|
hasRequiredCore = 1;
|
|
(function (module, exports$1) {
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
var tslib_1 = require$$0;
|
|
var core_1 = tslib_1.__importDefault(requireCore$1());
|
|
var types_1 = tslib_1.__importDefault(requireTypes());
|
|
var shared_1 = tslib_1.__importStar(requireShared());
|
|
function default_1(fork) {
|
|
var types = fork.use(types_1.default);
|
|
var Type = types.Type;
|
|
var def = Type.def;
|
|
var or = Type.or;
|
|
var shared = fork.use(shared_1.default);
|
|
var defaults = shared.defaults;
|
|
var geq = shared.geq;
|
|
var _a = fork.use(core_1.default), BinaryOperators = _a.BinaryOperators, AssignmentOperators = _a.AssignmentOperators, LogicalOperators = _a.LogicalOperators;
|
|
// Abstract supertype of all syntactic entities that are allowed to have a
|
|
// .loc field.
|
|
def("Printable")
|
|
.field("loc", or(def("SourceLocation"), null), defaults["null"], true);
|
|
def("Node")
|
|
.bases("Printable")
|
|
.field("type", String)
|
|
.field("comments", or([def("Comment")], null), defaults["null"], true);
|
|
def("SourceLocation")
|
|
.field("start", def("Position"))
|
|
.field("end", def("Position"))
|
|
.field("source", or(String, null), defaults["null"]);
|
|
def("Position")
|
|
.field("line", geq(1))
|
|
.field("column", geq(0));
|
|
def("File")
|
|
.bases("Node")
|
|
.build("program", "name")
|
|
.field("program", def("Program"))
|
|
.field("name", or(String, null), defaults["null"]);
|
|
def("Program")
|
|
.bases("Node")
|
|
.build("body")
|
|
.field("body", [def("Statement")]);
|
|
def("Function")
|
|
.bases("Node")
|
|
.field("id", or(def("Identifier"), null), defaults["null"])
|
|
.field("params", [def("Pattern")])
|
|
.field("body", def("BlockStatement"))
|
|
.field("generator", Boolean, defaults["false"])
|
|
.field("async", Boolean, defaults["false"]);
|
|
def("Statement").bases("Node");
|
|
// The empty .build() here means that an EmptyStatement can be constructed
|
|
// (i.e. it's not abstract) but that it needs no arguments.
|
|
def("EmptyStatement").bases("Statement").build();
|
|
def("BlockStatement")
|
|
.bases("Statement")
|
|
.build("body")
|
|
.field("body", [def("Statement")]);
|
|
// TODO Figure out how to silently coerce Expressions to
|
|
// ExpressionStatements where a Statement was expected.
|
|
def("ExpressionStatement")
|
|
.bases("Statement")
|
|
.build("expression")
|
|
.field("expression", def("Expression"));
|
|
def("IfStatement")
|
|
.bases("Statement")
|
|
.build("test", "consequent", "alternate")
|
|
.field("test", def("Expression"))
|
|
.field("consequent", def("Statement"))
|
|
.field("alternate", or(def("Statement"), null), defaults["null"]);
|
|
def("LabeledStatement")
|
|
.bases("Statement")
|
|
.build("label", "body")
|
|
.field("label", def("Identifier"))
|
|
.field("body", def("Statement"));
|
|
def("BreakStatement")
|
|
.bases("Statement")
|
|
.build("label")
|
|
.field("label", or(def("Identifier"), null), defaults["null"]);
|
|
def("ContinueStatement")
|
|
.bases("Statement")
|
|
.build("label")
|
|
.field("label", or(def("Identifier"), null), defaults["null"]);
|
|
def("WithStatement")
|
|
.bases("Statement")
|
|
.build("object", "body")
|
|
.field("object", def("Expression"))
|
|
.field("body", def("Statement"));
|
|
def("SwitchStatement")
|
|
.bases("Statement")
|
|
.build("discriminant", "cases", "lexical")
|
|
.field("discriminant", def("Expression"))
|
|
.field("cases", [def("SwitchCase")])
|
|
.field("lexical", Boolean, defaults["false"]);
|
|
def("ReturnStatement")
|
|
.bases("Statement")
|
|
.build("argument")
|
|
.field("argument", or(def("Expression"), null));
|
|
def("ThrowStatement")
|
|
.bases("Statement")
|
|
.build("argument")
|
|
.field("argument", def("Expression"));
|
|
def("TryStatement")
|
|
.bases("Statement")
|
|
.build("block", "handler", "finalizer")
|
|
.field("block", def("BlockStatement"))
|
|
.field("handler", or(def("CatchClause"), null), function () {
|
|
return this.handlers && this.handlers[0] || null;
|
|
})
|
|
.field("handlers", [def("CatchClause")], function () {
|
|
return this.handler ? [this.handler] : [];
|
|
}, true) // Indicates this field is hidden from eachField iteration.
|
|
.field("guardedHandlers", [def("CatchClause")], defaults.emptyArray)
|
|
.field("finalizer", or(def("BlockStatement"), null), defaults["null"]);
|
|
def("CatchClause")
|
|
.bases("Node")
|
|
.build("param", "guard", "body")
|
|
.field("param", def("Pattern"))
|
|
.field("guard", or(def("Expression"), null), defaults["null"])
|
|
.field("body", def("BlockStatement"));
|
|
def("WhileStatement")
|
|
.bases("Statement")
|
|
.build("test", "body")
|
|
.field("test", def("Expression"))
|
|
.field("body", def("Statement"));
|
|
def("DoWhileStatement")
|
|
.bases("Statement")
|
|
.build("body", "test")
|
|
.field("body", def("Statement"))
|
|
.field("test", def("Expression"));
|
|
def("ForStatement")
|
|
.bases("Statement")
|
|
.build("init", "test", "update", "body")
|
|
.field("init", or(def("VariableDeclaration"), def("Expression"), null))
|
|
.field("test", or(def("Expression"), null))
|
|
.field("update", or(def("Expression"), null))
|
|
.field("body", def("Statement"));
|
|
def("ForInStatement")
|
|
.bases("Statement")
|
|
.build("left", "right", "body")
|
|
.field("left", or(def("VariableDeclaration"), def("Expression")))
|
|
.field("right", def("Expression"))
|
|
.field("body", def("Statement"));
|
|
def("DebuggerStatement").bases("Statement").build();
|
|
def("Declaration").bases("Statement");
|
|
def("FunctionDeclaration")
|
|
.bases("Function", "Declaration")
|
|
.build("id", "params", "body")
|
|
.field("id", def("Identifier"));
|
|
def("FunctionExpression")
|
|
.bases("Function", "Expression")
|
|
.build("id", "params", "body");
|
|
def("VariableDeclaration")
|
|
.bases("Declaration")
|
|
.build("kind", "declarations")
|
|
.field("kind", or("var", "let", "const"))
|
|
.field("declarations", [def("VariableDeclarator")]);
|
|
def("VariableDeclarator")
|
|
.bases("Node")
|
|
.build("id", "init")
|
|
.field("id", def("Pattern"))
|
|
.field("init", or(def("Expression"), null), defaults["null"]);
|
|
def("Expression").bases("Node");
|
|
def("ThisExpression").bases("Expression").build();
|
|
def("ArrayExpression")
|
|
.bases("Expression")
|
|
.build("elements")
|
|
.field("elements", [or(def("Expression"), null)]);
|
|
def("ObjectExpression")
|
|
.bases("Expression")
|
|
.build("properties")
|
|
.field("properties", [def("Property")]);
|
|
// TODO Not in the Mozilla Parser API, but used by Esprima.
|
|
def("Property")
|
|
.bases("Node") // Want to be able to visit Property Nodes.
|
|
.build("kind", "key", "value")
|
|
.field("kind", or("init", "get", "set"))
|
|
.field("key", or(def("Literal"), def("Identifier")))
|
|
.field("value", def("Expression"));
|
|
def("SequenceExpression")
|
|
.bases("Expression")
|
|
.build("expressions")
|
|
.field("expressions", [def("Expression")]);
|
|
var UnaryOperator = or("-", "+", "!", "~", "typeof", "void", "delete");
|
|
def("UnaryExpression")
|
|
.bases("Expression")
|
|
.build("operator", "argument", "prefix")
|
|
.field("operator", UnaryOperator)
|
|
.field("argument", def("Expression"))
|
|
// Esprima doesn't bother with this field, presumably because it's
|
|
// always true for unary operators.
|
|
.field("prefix", Boolean, defaults["true"]);
|
|
var BinaryOperator = or.apply(void 0, BinaryOperators);
|
|
def("BinaryExpression")
|
|
.bases("Expression")
|
|
.build("operator", "left", "right")
|
|
.field("operator", BinaryOperator)
|
|
.field("left", def("Expression"))
|
|
.field("right", def("Expression"));
|
|
var AssignmentOperator = or.apply(void 0, AssignmentOperators);
|
|
def("AssignmentExpression")
|
|
.bases("Expression")
|
|
.build("operator", "left", "right")
|
|
.field("operator", AssignmentOperator)
|
|
.field("left", or(def("Pattern"), def("MemberExpression")))
|
|
.field("right", def("Expression"));
|
|
var UpdateOperator = or("++", "--");
|
|
def("UpdateExpression")
|
|
.bases("Expression")
|
|
.build("operator", "argument", "prefix")
|
|
.field("operator", UpdateOperator)
|
|
.field("argument", def("Expression"))
|
|
.field("prefix", Boolean);
|
|
var LogicalOperator = or.apply(void 0, LogicalOperators);
|
|
def("LogicalExpression")
|
|
.bases("Expression")
|
|
.build("operator", "left", "right")
|
|
.field("operator", LogicalOperator)
|
|
.field("left", def("Expression"))
|
|
.field("right", def("Expression"));
|
|
def("ConditionalExpression")
|
|
.bases("Expression")
|
|
.build("test", "consequent", "alternate")
|
|
.field("test", def("Expression"))
|
|
.field("consequent", def("Expression"))
|
|
.field("alternate", def("Expression"));
|
|
def("NewExpression")
|
|
.bases("Expression")
|
|
.build("callee", "arguments")
|
|
.field("callee", def("Expression"))
|
|
// The Mozilla Parser API gives this type as [or(def("Expression"),
|
|
// null)], but null values don't really make sense at the call site.
|
|
// TODO Report this nonsense.
|
|
.field("arguments", [def("Expression")]);
|
|
def("CallExpression")
|
|
.bases("Expression")
|
|
.build("callee", "arguments")
|
|
.field("callee", def("Expression"))
|
|
// See comment for NewExpression above.
|
|
.field("arguments", [def("Expression")]);
|
|
def("MemberExpression")
|
|
.bases("Expression")
|
|
.build("object", "property", "computed")
|
|
.field("object", def("Expression"))
|
|
.field("property", or(def("Identifier"), def("Expression")))
|
|
.field("computed", Boolean, function () {
|
|
var type = this.property.type;
|
|
if (type === 'Literal' ||
|
|
type === 'MemberExpression' ||
|
|
type === 'BinaryExpression') {
|
|
return true;
|
|
}
|
|
return false;
|
|
});
|
|
def("Pattern").bases("Node");
|
|
def("SwitchCase")
|
|
.bases("Node")
|
|
.build("test", "consequent")
|
|
.field("test", or(def("Expression"), null))
|
|
.field("consequent", [def("Statement")]);
|
|
def("Identifier")
|
|
.bases("Expression", "Pattern")
|
|
.build("name")
|
|
.field("name", String)
|
|
.field("optional", Boolean, defaults["false"]);
|
|
def("Literal")
|
|
.bases("Expression")
|
|
.build("value")
|
|
.field("value", or(String, Boolean, null, Number, RegExp, BigInt));
|
|
// Abstract (non-buildable) comment supertype. Not a Node.
|
|
def("Comment")
|
|
.bases("Printable")
|
|
.field("value", String)
|
|
// A .leading comment comes before the node, whereas a .trailing
|
|
// comment comes after it. These two fields should not both be true,
|
|
// but they might both be false when the comment falls inside a node
|
|
// and the node has no children for the comment to lead or trail,
|
|
// e.g. { /*dangling*/ }.
|
|
.field("leading", Boolean, defaults["true"])
|
|
.field("trailing", Boolean, defaults["false"]);
|
|
}
|
|
exports$1.default = default_1;
|
|
(0, shared_1.maybeSetModuleExports)(function () { return module; });
|
|
|
|
} (core, core.exports));
|
|
return core.exports;
|
|
}
|
|
|
|
es6.exports;
|
|
|
|
var hasRequiredEs6;
|
|
|
|
function requireEs6 () {
|
|
if (hasRequiredEs6) return es6.exports;
|
|
hasRequiredEs6 = 1;
|
|
(function (module, exports$1) {
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
var tslib_1 = require$$0;
|
|
var core_1 = tslib_1.__importDefault(requireCore());
|
|
var types_1 = tslib_1.__importDefault(requireTypes());
|
|
var shared_1 = tslib_1.__importStar(requireShared());
|
|
function default_1(fork) {
|
|
fork.use(core_1.default);
|
|
var types = fork.use(types_1.default);
|
|
var def = types.Type.def;
|
|
var or = types.Type.or;
|
|
var defaults = fork.use(shared_1.default).defaults;
|
|
def("Function")
|
|
.field("generator", Boolean, defaults["false"])
|
|
.field("expression", Boolean, defaults["false"])
|
|
.field("defaults", [or(def("Expression"), null)], defaults.emptyArray)
|
|
// Legacy
|
|
.field("rest", or(def("Identifier"), null), defaults["null"]);
|
|
// The ESTree way of representing a ...rest parameter.
|
|
def("RestElement")
|
|
.bases("Pattern")
|
|
.build("argument")
|
|
.field("argument", def("Pattern"))
|
|
.field("typeAnnotation", // for Babylon. Flow parser puts it on the identifier
|
|
or(def("TypeAnnotation"), def("TSTypeAnnotation"), null), defaults["null"]);
|
|
def("SpreadElementPattern")
|
|
.bases("Pattern")
|
|
.build("argument")
|
|
.field("argument", def("Pattern"));
|
|
def("FunctionDeclaration")
|
|
.build("id", "params", "body", "generator", "expression")
|
|
// May be `null` in the context of `export default function () {}`
|
|
.field("id", or(def("Identifier"), null));
|
|
def("FunctionExpression")
|
|
.build("id", "params", "body", "generator", "expression");
|
|
def("ArrowFunctionExpression")
|
|
.bases("Function", "Expression")
|
|
.build("params", "body", "expression")
|
|
// The forced null value here is compatible with the overridden
|
|
// definition of the "id" field in the Function interface.
|
|
.field("id", null, defaults["null"])
|
|
// Arrow function bodies are allowed to be expressions.
|
|
.field("body", or(def("BlockStatement"), def("Expression")))
|
|
// The current spec forbids arrow generators, so I have taken the
|
|
// liberty of enforcing that. TODO Report this.
|
|
.field("generator", false, defaults["false"]);
|
|
def("ForOfStatement")
|
|
.bases("Statement")
|
|
.build("left", "right", "body")
|
|
.field("left", or(def("VariableDeclaration"), def("Pattern")))
|
|
.field("right", def("Expression"))
|
|
.field("body", def("Statement"));
|
|
def("YieldExpression")
|
|
.bases("Expression")
|
|
.build("argument", "delegate")
|
|
.field("argument", or(def("Expression"), null))
|
|
.field("delegate", Boolean, defaults["false"]);
|
|
def("GeneratorExpression")
|
|
.bases("Expression")
|
|
.build("body", "blocks", "filter")
|
|
.field("body", def("Expression"))
|
|
.field("blocks", [def("ComprehensionBlock")])
|
|
.field("filter", or(def("Expression"), null));
|
|
def("ComprehensionExpression")
|
|
.bases("Expression")
|
|
.build("body", "blocks", "filter")
|
|
.field("body", def("Expression"))
|
|
.field("blocks", [def("ComprehensionBlock")])
|
|
.field("filter", or(def("Expression"), null));
|
|
def("ComprehensionBlock")
|
|
.bases("Node")
|
|
.build("left", "right", "each")
|
|
.field("left", def("Pattern"))
|
|
.field("right", def("Expression"))
|
|
.field("each", Boolean);
|
|
def("Property")
|
|
.field("key", or(def("Literal"), def("Identifier"), def("Expression")))
|
|
.field("value", or(def("Expression"), def("Pattern")))
|
|
.field("method", Boolean, defaults["false"])
|
|
.field("shorthand", Boolean, defaults["false"])
|
|
.field("computed", Boolean, defaults["false"]);
|
|
def("ObjectProperty")
|
|
.field("shorthand", Boolean, defaults["false"]);
|
|
def("PropertyPattern")
|
|
.bases("Pattern")
|
|
.build("key", "pattern")
|
|
.field("key", or(def("Literal"), def("Identifier"), def("Expression")))
|
|
.field("pattern", def("Pattern"))
|
|
.field("computed", Boolean, defaults["false"]);
|
|
def("ObjectPattern")
|
|
.bases("Pattern")
|
|
.build("properties")
|
|
.field("properties", [or(def("PropertyPattern"), def("Property"))]);
|
|
def("ArrayPattern")
|
|
.bases("Pattern")
|
|
.build("elements")
|
|
.field("elements", [or(def("Pattern"), null)]);
|
|
def("SpreadElement")
|
|
.bases("Node")
|
|
.build("argument")
|
|
.field("argument", def("Expression"));
|
|
def("ArrayExpression")
|
|
.field("elements", [or(def("Expression"), def("SpreadElement"), def("RestElement"), null)]);
|
|
def("NewExpression")
|
|
.field("arguments", [or(def("Expression"), def("SpreadElement"))]);
|
|
def("CallExpression")
|
|
.field("arguments", [or(def("Expression"), def("SpreadElement"))]);
|
|
// Note: this node type is *not* an AssignmentExpression with a Pattern on
|
|
// the left-hand side! The existing AssignmentExpression type already
|
|
// supports destructuring assignments. AssignmentPattern nodes may appear
|
|
// wherever a Pattern is allowed, and the right-hand side represents a
|
|
// default value to be destructured against the left-hand side, if no
|
|
// value is otherwise provided. For example: default parameter values.
|
|
def("AssignmentPattern")
|
|
.bases("Pattern")
|
|
.build("left", "right")
|
|
.field("left", def("Pattern"))
|
|
.field("right", def("Expression"));
|
|
def("MethodDefinition")
|
|
.bases("Declaration")
|
|
.build("kind", "key", "value", "static")
|
|
.field("kind", or("constructor", "method", "get", "set"))
|
|
.field("key", def("Expression"))
|
|
.field("value", def("Function"))
|
|
.field("computed", Boolean, defaults["false"])
|
|
.field("static", Boolean, defaults["false"]);
|
|
var ClassBodyElement = or(def("MethodDefinition"), def("VariableDeclarator"), def("ClassPropertyDefinition"), def("ClassProperty"), def("StaticBlock"));
|
|
def("ClassProperty")
|
|
.bases("Declaration")
|
|
.build("key")
|
|
.field("key", or(def("Literal"), def("Identifier"), def("Expression")))
|
|
.field("computed", Boolean, defaults["false"]);
|
|
def("ClassPropertyDefinition") // static property
|
|
.bases("Declaration")
|
|
.build("definition")
|
|
// Yes, Virginia, circular definitions are permitted.
|
|
.field("definition", ClassBodyElement);
|
|
def("ClassBody")
|
|
.bases("Declaration")
|
|
.build("body")
|
|
.field("body", [ClassBodyElement]);
|
|
def("ClassDeclaration")
|
|
.bases("Declaration")
|
|
.build("id", "body", "superClass")
|
|
.field("id", or(def("Identifier"), null))
|
|
.field("body", def("ClassBody"))
|
|
.field("superClass", or(def("Expression"), null), defaults["null"]);
|
|
def("ClassExpression")
|
|
.bases("Expression")
|
|
.build("id", "body", "superClass")
|
|
.field("id", or(def("Identifier"), null), defaults["null"])
|
|
.field("body", def("ClassBody"))
|
|
.field("superClass", or(def("Expression"), null), defaults["null"]);
|
|
def("Super")
|
|
.bases("Expression")
|
|
.build();
|
|
// Specifier and ModuleSpecifier are abstract non-standard types
|
|
// introduced for definitional convenience.
|
|
def("Specifier").bases("Node");
|
|
// This supertype is shared/abused by both def/babel.js and
|
|
// def/esprima.js. In the future, it will be possible to load only one set
|
|
// of definitions appropriate for a given parser, but until then we must
|
|
// rely on default functions to reconcile the conflicting AST formats.
|
|
def("ModuleSpecifier")
|
|
.bases("Specifier")
|
|
// This local field is used by Babel/Acorn. It should not technically
|
|
// be optional in the Babel/Acorn AST format, but it must be optional
|
|
// in the Esprima AST format.
|
|
.field("local", or(def("Identifier"), null), defaults["null"])
|
|
// The id and name fields are used by Esprima. The id field should not
|
|
// technically be optional in the Esprima AST format, but it must be
|
|
// optional in the Babel/Acorn AST format.
|
|
.field("id", or(def("Identifier"), null), defaults["null"])
|
|
.field("name", or(def("Identifier"), null), defaults["null"]);
|
|
// import {<id [as name]>} from ...;
|
|
def("ImportSpecifier")
|
|
.bases("ModuleSpecifier")
|
|
.build("imported", "local")
|
|
.field("imported", def("Identifier"));
|
|
// import <id> from ...;
|
|
def("ImportDefaultSpecifier")
|
|
.bases("ModuleSpecifier")
|
|
.build("local");
|
|
// import <* as id> from ...;
|
|
def("ImportNamespaceSpecifier")
|
|
.bases("ModuleSpecifier")
|
|
.build("local");
|
|
def("ImportDeclaration")
|
|
.bases("Declaration")
|
|
.build("specifiers", "source", "importKind")
|
|
.field("specifiers", [or(def("ImportSpecifier"), def("ImportNamespaceSpecifier"), def("ImportDefaultSpecifier"))], defaults.emptyArray)
|
|
.field("source", def("Literal"))
|
|
.field("importKind", or("value", "type"), function () {
|
|
return "value";
|
|
});
|
|
def("ExportNamedDeclaration")
|
|
.bases("Declaration")
|
|
.build("declaration", "specifiers", "source")
|
|
.field("declaration", or(def("Declaration"), null))
|
|
.field("specifiers", [def("ExportSpecifier")], defaults.emptyArray)
|
|
.field("source", or(def("Literal"), null), defaults["null"]);
|
|
def("ExportSpecifier")
|
|
.bases("ModuleSpecifier")
|
|
.build("local", "exported")
|
|
.field("exported", def("Identifier"));
|
|
def("ExportDefaultDeclaration")
|
|
.bases("Declaration")
|
|
.build("declaration")
|
|
.field("declaration", or(def("Declaration"), def("Expression")));
|
|
def("ExportAllDeclaration")
|
|
.bases("Declaration")
|
|
.build("source")
|
|
.field("source", def("Literal"));
|
|
def("TaggedTemplateExpression")
|
|
.bases("Expression")
|
|
.build("tag", "quasi")
|
|
.field("tag", def("Expression"))
|
|
.field("quasi", def("TemplateLiteral"));
|
|
def("TemplateLiteral")
|
|
.bases("Expression")
|
|
.build("quasis", "expressions")
|
|
.field("quasis", [def("TemplateElement")])
|
|
.field("expressions", [def("Expression")]);
|
|
def("TemplateElement")
|
|
.bases("Node")
|
|
.build("value", "tail")
|
|
.field("value", { "cooked": String, "raw": String })
|
|
.field("tail", Boolean);
|
|
def("MetaProperty")
|
|
.bases("Expression")
|
|
.build("meta", "property")
|
|
.field("meta", def("Identifier"))
|
|
.field("property", def("Identifier"));
|
|
}
|
|
exports$1.default = default_1;
|
|
(0, shared_1.maybeSetModuleExports)(function () { return module; });
|
|
|
|
} (es6, es6.exports));
|
|
return es6.exports;
|
|
}
|
|
|
|
es2016.exports;
|
|
|
|
var hasRequiredEs2016;
|
|
|
|
function requireEs2016 () {
|
|
if (hasRequiredEs2016) return es2016.exports;
|
|
hasRequiredEs2016 = 1;
|
|
(function (module, exports$1) {
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
var tslib_1 = require$$0;
|
|
var es2016_1 = tslib_1.__importDefault(requireEs2016$1());
|
|
var es6_1 = tslib_1.__importDefault(requireEs6());
|
|
var shared_1 = requireShared();
|
|
function default_1(fork) {
|
|
// The es2016OpsDef plugin comes before es6Def so BinaryOperators and
|
|
// AssignmentOperators will be appropriately augmented before they are first
|
|
// used in the core definitions for this fork.
|
|
fork.use(es2016_1.default);
|
|
fork.use(es6_1.default);
|
|
}
|
|
exports$1.default = default_1;
|
|
(0, shared_1.maybeSetModuleExports)(function () { return module; });
|
|
|
|
} (es2016, es2016.exports));
|
|
return es2016.exports;
|
|
}
|
|
|
|
es2017.exports;
|
|
|
|
var hasRequiredEs2017;
|
|
|
|
function requireEs2017 () {
|
|
if (hasRequiredEs2017) return es2017.exports;
|
|
hasRequiredEs2017 = 1;
|
|
(function (module, exports$1) {
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
var tslib_1 = require$$0;
|
|
var es2016_1 = tslib_1.__importDefault(requireEs2016());
|
|
var types_1 = tslib_1.__importDefault(requireTypes());
|
|
var shared_1 = tslib_1.__importStar(requireShared());
|
|
function default_1(fork) {
|
|
fork.use(es2016_1.default);
|
|
var types = fork.use(types_1.default);
|
|
var def = types.Type.def;
|
|
var defaults = fork.use(shared_1.default).defaults;
|
|
def("Function")
|
|
.field("async", Boolean, defaults["false"]);
|
|
def("AwaitExpression")
|
|
.bases("Expression")
|
|
.build("argument")
|
|
.field("argument", def("Expression"));
|
|
}
|
|
exports$1.default = default_1;
|
|
(0, shared_1.maybeSetModuleExports)(function () { return module; });
|
|
|
|
} (es2017, es2017.exports));
|
|
return es2017.exports;
|
|
}
|
|
|
|
es2018.exports;
|
|
|
|
var hasRequiredEs2018;
|
|
|
|
function requireEs2018 () {
|
|
if (hasRequiredEs2018) return es2018.exports;
|
|
hasRequiredEs2018 = 1;
|
|
(function (module, exports$1) {
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
var tslib_1 = require$$0;
|
|
var es2017_1 = tslib_1.__importDefault(requireEs2017());
|
|
var types_1 = tslib_1.__importDefault(requireTypes());
|
|
var shared_1 = tslib_1.__importStar(requireShared());
|
|
function default_1(fork) {
|
|
fork.use(es2017_1.default);
|
|
var types = fork.use(types_1.default);
|
|
var def = types.Type.def;
|
|
var or = types.Type.or;
|
|
var defaults = fork.use(shared_1.default).defaults;
|
|
def("ForOfStatement")
|
|
.field("await", Boolean, defaults["false"]);
|
|
// Legacy
|
|
def("SpreadProperty")
|
|
.bases("Node")
|
|
.build("argument")
|
|
.field("argument", def("Expression"));
|
|
def("ObjectExpression")
|
|
.field("properties", [or(def("Property"), def("SpreadProperty"), // Legacy
|
|
def("SpreadElement"))]);
|
|
def("TemplateElement")
|
|
.field("value", { "cooked": or(String, null), "raw": String });
|
|
// Legacy
|
|
def("SpreadPropertyPattern")
|
|
.bases("Pattern")
|
|
.build("argument")
|
|
.field("argument", def("Pattern"));
|
|
def("ObjectPattern")
|
|
.field("properties", [or(def("PropertyPattern"), def("Property"), def("RestElement"), def("SpreadPropertyPattern"))]);
|
|
}
|
|
exports$1.default = default_1;
|
|
(0, shared_1.maybeSetModuleExports)(function () { return module; });
|
|
|
|
} (es2018, es2018.exports));
|
|
return es2018.exports;
|
|
}
|
|
|
|
es2019.exports;
|
|
|
|
var hasRequiredEs2019;
|
|
|
|
function requireEs2019 () {
|
|
if (hasRequiredEs2019) return es2019.exports;
|
|
hasRequiredEs2019 = 1;
|
|
(function (module, exports$1) {
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
var tslib_1 = require$$0;
|
|
var es2018_1 = tslib_1.__importDefault(requireEs2018());
|
|
var types_1 = tslib_1.__importDefault(requireTypes());
|
|
var shared_1 = tslib_1.__importStar(requireShared());
|
|
function default_1(fork) {
|
|
fork.use(es2018_1.default);
|
|
var types = fork.use(types_1.default);
|
|
var def = types.Type.def;
|
|
var or = types.Type.or;
|
|
var defaults = fork.use(shared_1.default).defaults;
|
|
def("CatchClause")
|
|
.field("param", or(def("Pattern"), null), defaults["null"]);
|
|
}
|
|
exports$1.default = default_1;
|
|
(0, shared_1.maybeSetModuleExports)(function () { return module; });
|
|
|
|
} (es2019, es2019.exports));
|
|
return es2019.exports;
|
|
}
|
|
|
|
es2020.exports;
|
|
|
|
var hasRequiredEs2020;
|
|
|
|
function requireEs2020 () {
|
|
if (hasRequiredEs2020) return es2020.exports;
|
|
hasRequiredEs2020 = 1;
|
|
(function (module, exports$1) {
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
var tslib_1 = require$$0;
|
|
var es2020_1 = tslib_1.__importDefault(requireEs2020$1());
|
|
var es2019_1 = tslib_1.__importDefault(requireEs2019());
|
|
var types_1 = tslib_1.__importDefault(requireTypes());
|
|
var shared_1 = tslib_1.__importStar(requireShared());
|
|
function default_1(fork) {
|
|
// The es2020OpsDef plugin comes before es2019Def so LogicalOperators will be
|
|
// appropriately augmented before first used.
|
|
fork.use(es2020_1.default);
|
|
fork.use(es2019_1.default);
|
|
var types = fork.use(types_1.default);
|
|
var def = types.Type.def;
|
|
var or = types.Type.or;
|
|
var shared = fork.use(shared_1.default);
|
|
var defaults = shared.defaults;
|
|
def("ImportExpression")
|
|
.bases("Expression")
|
|
.build("source")
|
|
.field("source", def("Expression"));
|
|
def("ExportAllDeclaration")
|
|
.bases("Declaration")
|
|
.build("source", "exported")
|
|
.field("source", def("Literal"))
|
|
.field("exported", or(def("Identifier"), null, void 0), defaults["null"]);
|
|
// Optional chaining
|
|
def("ChainElement")
|
|
.bases("Node")
|
|
.field("optional", Boolean, defaults["false"]);
|
|
def("CallExpression")
|
|
.bases("Expression", "ChainElement");
|
|
def("MemberExpression")
|
|
.bases("Expression", "ChainElement");
|
|
def("ChainExpression")
|
|
.bases("Expression")
|
|
.build("expression")
|
|
.field("expression", def("ChainElement"));
|
|
def("OptionalCallExpression")
|
|
.bases("CallExpression")
|
|
.build("callee", "arguments", "optional")
|
|
.field("optional", Boolean, defaults["true"]);
|
|
// Deprecated optional chaining type, doesn't work with babelParser@7.11.0 or newer
|
|
def("OptionalMemberExpression")
|
|
.bases("MemberExpression")
|
|
.build("object", "property", "computed", "optional")
|
|
.field("optional", Boolean, defaults["true"]);
|
|
}
|
|
exports$1.default = default_1;
|
|
(0, shared_1.maybeSetModuleExports)(function () { return module; });
|
|
|
|
} (es2020, es2020.exports));
|
|
return es2020.exports;
|
|
}
|
|
|
|
es2021$1.exports;
|
|
|
|
var hasRequiredEs2021;
|
|
|
|
function requireEs2021 () {
|
|
if (hasRequiredEs2021) return es2021$1.exports;
|
|
hasRequiredEs2021 = 1;
|
|
(function (module, exports$1) {
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
var tslib_1 = require$$0;
|
|
var es2021_1 = tslib_1.__importDefault(requireEs2021$1());
|
|
var es2020_1 = tslib_1.__importDefault(requireEs2020());
|
|
var shared_1 = requireShared();
|
|
function default_1(fork) {
|
|
// The es2021OpsDef plugin comes before es2020Def so AssignmentOperators will
|
|
// be appropriately augmented before first used.
|
|
fork.use(es2021_1.default);
|
|
fork.use(es2020_1.default);
|
|
}
|
|
exports$1.default = default_1;
|
|
(0, shared_1.maybeSetModuleExports)(function () { return module; });
|
|
|
|
} (es2021$1, es2021$1.exports));
|
|
return es2021$1.exports;
|
|
}
|
|
|
|
es2022.exports;
|
|
|
|
var hasRequiredEs2022;
|
|
|
|
function requireEs2022 () {
|
|
if (hasRequiredEs2022) return es2022.exports;
|
|
hasRequiredEs2022 = 1;
|
|
(function (module, exports$1) {
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
var tslib_1 = require$$0;
|
|
var es2021_1 = tslib_1.__importDefault(requireEs2021());
|
|
var types_1 = tslib_1.__importDefault(requireTypes());
|
|
var shared_1 = requireShared();
|
|
function default_1(fork) {
|
|
fork.use(es2021_1.default);
|
|
var types = fork.use(types_1.default);
|
|
var def = types.Type.def;
|
|
def("StaticBlock")
|
|
.bases("Declaration")
|
|
.build("body")
|
|
.field("body", [def("Statement")]);
|
|
}
|
|
exports$1.default = default_1;
|
|
(0, shared_1.maybeSetModuleExports)(function () { return module; });
|
|
|
|
} (es2022, es2022.exports));
|
|
return es2022.exports;
|
|
}
|
|
|
|
esProposals.exports;
|
|
|
|
var hasRequiredEsProposals;
|
|
|
|
function requireEsProposals () {
|
|
if (hasRequiredEsProposals) return esProposals.exports;
|
|
hasRequiredEsProposals = 1;
|
|
(function (module, exports$1) {
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
var tslib_1 = require$$0;
|
|
var types_1 = tslib_1.__importDefault(requireTypes());
|
|
var shared_1 = tslib_1.__importStar(requireShared());
|
|
var es2022_1 = tslib_1.__importDefault(requireEs2022());
|
|
function default_1(fork) {
|
|
fork.use(es2022_1.default);
|
|
var types = fork.use(types_1.default);
|
|
var Type = types.Type;
|
|
var def = types.Type.def;
|
|
var or = Type.or;
|
|
var shared = fork.use(shared_1.default);
|
|
var defaults = shared.defaults;
|
|
def("AwaitExpression")
|
|
.build("argument", "all")
|
|
.field("argument", or(def("Expression"), null))
|
|
.field("all", Boolean, defaults["false"]);
|
|
// Decorators
|
|
def("Decorator")
|
|
.bases("Node")
|
|
.build("expression")
|
|
.field("expression", def("Expression"));
|
|
def("Property")
|
|
.field("decorators", or([def("Decorator")], null), defaults["null"]);
|
|
def("MethodDefinition")
|
|
.field("decorators", or([def("Decorator")], null), defaults["null"]);
|
|
// Private names
|
|
def("PrivateName")
|
|
.bases("Expression", "Pattern")
|
|
.build("id")
|
|
.field("id", def("Identifier"));
|
|
def("ClassPrivateProperty")
|
|
.bases("ClassProperty")
|
|
.build("key", "value")
|
|
.field("key", def("PrivateName"))
|
|
.field("value", or(def("Expression"), null), defaults["null"]);
|
|
// https://github.com/tc39/proposal-import-assertions
|
|
def("ImportAttribute")
|
|
.bases("Node")
|
|
.build("key", "value")
|
|
.field("key", or(def("Identifier"), def("Literal")))
|
|
.field("value", def("Expression"));
|
|
["ImportDeclaration",
|
|
"ExportAllDeclaration",
|
|
"ExportNamedDeclaration",
|
|
].forEach(function (decl) {
|
|
def(decl).field("assertions", [def("ImportAttribute")], defaults.emptyArray);
|
|
});
|
|
// https://github.com/tc39/proposal-record-tuple
|
|
// https://github.com/babel/babel/pull/10865
|
|
def("RecordExpression")
|
|
.bases("Expression")
|
|
.build("properties")
|
|
.field("properties", [or(def("ObjectProperty"), def("ObjectMethod"), def("SpreadElement"))]);
|
|
def("TupleExpression")
|
|
.bases("Expression")
|
|
.build("elements")
|
|
.field("elements", [or(def("Expression"), def("SpreadElement"), null)]);
|
|
// https://github.com/tc39/proposal-js-module-blocks
|
|
// https://github.com/babel/babel/pull/12469
|
|
def("ModuleExpression")
|
|
.bases("Node")
|
|
.build("body")
|
|
.field("body", def("Program"));
|
|
}
|
|
exports$1.default = default_1;
|
|
(0, shared_1.maybeSetModuleExports)(function () { return module; });
|
|
|
|
} (esProposals, esProposals.exports));
|
|
return esProposals.exports;
|
|
}
|
|
|
|
var jsx = {exports: {}};
|
|
|
|
jsx.exports;
|
|
|
|
var hasRequiredJsx;
|
|
|
|
function requireJsx () {
|
|
if (hasRequiredJsx) return jsx.exports;
|
|
hasRequiredJsx = 1;
|
|
(function (module, exports$1) {
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
var tslib_1 = require$$0;
|
|
var es_proposals_1 = tslib_1.__importDefault(requireEsProposals());
|
|
var types_1 = tslib_1.__importDefault(requireTypes());
|
|
var shared_1 = tslib_1.__importStar(requireShared());
|
|
function default_1(fork) {
|
|
fork.use(es_proposals_1.default);
|
|
var types = fork.use(types_1.default);
|
|
var def = types.Type.def;
|
|
var or = types.Type.or;
|
|
var defaults = fork.use(shared_1.default).defaults;
|
|
def("JSXAttribute")
|
|
.bases("Node")
|
|
.build("name", "value")
|
|
.field("name", or(def("JSXIdentifier"), def("JSXNamespacedName")))
|
|
.field("value", or(def("Literal"), // attr="value"
|
|
def("JSXExpressionContainer"), // attr={value}
|
|
def("JSXElement"), // attr=<div />
|
|
def("JSXFragment"), // attr=<></>
|
|
null // attr= or just attr
|
|
), defaults["null"]);
|
|
def("JSXIdentifier")
|
|
.bases("Identifier")
|
|
.build("name")
|
|
.field("name", String);
|
|
def("JSXNamespacedName")
|
|
.bases("Node")
|
|
.build("namespace", "name")
|
|
.field("namespace", def("JSXIdentifier"))
|
|
.field("name", def("JSXIdentifier"));
|
|
def("JSXMemberExpression")
|
|
.bases("MemberExpression")
|
|
.build("object", "property")
|
|
.field("object", or(def("JSXIdentifier"), def("JSXMemberExpression")))
|
|
.field("property", def("JSXIdentifier"))
|
|
.field("computed", Boolean, defaults.false);
|
|
var JSXElementName = or(def("JSXIdentifier"), def("JSXNamespacedName"), def("JSXMemberExpression"));
|
|
def("JSXSpreadAttribute")
|
|
.bases("Node")
|
|
.build("argument")
|
|
.field("argument", def("Expression"));
|
|
var JSXAttributes = [or(def("JSXAttribute"), def("JSXSpreadAttribute"))];
|
|
def("JSXExpressionContainer")
|
|
.bases("Expression")
|
|
.build("expression")
|
|
.field("expression", or(def("Expression"), def("JSXEmptyExpression")));
|
|
var JSXChildren = [or(def("JSXText"), def("JSXExpressionContainer"), def("JSXSpreadChild"), def("JSXElement"), def("JSXFragment"), def("Literal") // Legacy: Esprima should return JSXText instead.
|
|
)];
|
|
def("JSXElement")
|
|
.bases("Expression")
|
|
.build("openingElement", "closingElement", "children")
|
|
.field("openingElement", def("JSXOpeningElement"))
|
|
.field("closingElement", or(def("JSXClosingElement"), null), defaults["null"])
|
|
.field("children", JSXChildren, defaults.emptyArray)
|
|
.field("name", JSXElementName, function () {
|
|
// Little-known fact: the `this` object inside a default function
|
|
// is none other than the partially-built object itself, and any
|
|
// fields initialized directly from builder function arguments
|
|
// (like openingElement, closingElement, and children) are
|
|
// guaranteed to be available.
|
|
return this.openingElement.name;
|
|
}, true) // hidden from traversal
|
|
.field("selfClosing", Boolean, function () {
|
|
return this.openingElement.selfClosing;
|
|
}, true) // hidden from traversal
|
|
.field("attributes", JSXAttributes, function () {
|
|
return this.openingElement.attributes;
|
|
}, true); // hidden from traversal
|
|
def("JSXOpeningElement")
|
|
.bases("Node")
|
|
.build("name", "attributes", "selfClosing")
|
|
.field("name", JSXElementName)
|
|
.field("attributes", JSXAttributes, defaults.emptyArray)
|
|
.field("selfClosing", Boolean, defaults["false"]);
|
|
def("JSXClosingElement")
|
|
.bases("Node")
|
|
.build("name")
|
|
.field("name", JSXElementName);
|
|
def("JSXFragment")
|
|
.bases("Expression")
|
|
.build("openingFragment", "closingFragment", "children")
|
|
.field("openingFragment", def("JSXOpeningFragment"))
|
|
.field("closingFragment", def("JSXClosingFragment"))
|
|
.field("children", JSXChildren, defaults.emptyArray);
|
|
def("JSXOpeningFragment")
|
|
.bases("Node")
|
|
.build();
|
|
def("JSXClosingFragment")
|
|
.bases("Node")
|
|
.build();
|
|
def("JSXText")
|
|
.bases("Literal")
|
|
.build("value", "raw")
|
|
.field("value", String)
|
|
.field("raw", String, function () {
|
|
return this.value;
|
|
});
|
|
def("JSXEmptyExpression")
|
|
.bases("Node")
|
|
.build();
|
|
def("JSXSpreadChild")
|
|
.bases("Node")
|
|
.build("expression")
|
|
.field("expression", def("Expression"));
|
|
}
|
|
exports$1.default = default_1;
|
|
(0, shared_1.maybeSetModuleExports)(function () { return module; });
|
|
|
|
} (jsx, jsx.exports));
|
|
return jsx.exports;
|
|
}
|
|
|
|
var flow = {exports: {}};
|
|
|
|
var typeAnnotations = {exports: {}};
|
|
|
|
typeAnnotations.exports;
|
|
|
|
var hasRequiredTypeAnnotations;
|
|
|
|
function requireTypeAnnotations () {
|
|
if (hasRequiredTypeAnnotations) return typeAnnotations.exports;
|
|
hasRequiredTypeAnnotations = 1;
|
|
(function (module, exports$1) {
|
|
/**
|
|
* Type annotation defs shared between Flow and TypeScript.
|
|
* These defs could not be defined in ./flow.ts or ./typescript.ts directly
|
|
* because they use the same name.
|
|
*/
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
var tslib_1 = require$$0;
|
|
var types_1 = tslib_1.__importDefault(requireTypes());
|
|
var shared_1 = tslib_1.__importStar(requireShared());
|
|
function default_1(fork) {
|
|
var types = fork.use(types_1.default);
|
|
var def = types.Type.def;
|
|
var or = types.Type.or;
|
|
var defaults = fork.use(shared_1.default).defaults;
|
|
var TypeAnnotation = or(def("TypeAnnotation"), def("TSTypeAnnotation"), null);
|
|
var TypeParamDecl = or(def("TypeParameterDeclaration"), def("TSTypeParameterDeclaration"), null);
|
|
def("Identifier")
|
|
.field("typeAnnotation", TypeAnnotation, defaults["null"]);
|
|
def("ObjectPattern")
|
|
.field("typeAnnotation", TypeAnnotation, defaults["null"]);
|
|
def("Function")
|
|
.field("returnType", TypeAnnotation, defaults["null"])
|
|
.field("typeParameters", TypeParamDecl, defaults["null"]);
|
|
def("ClassProperty")
|
|
.build("key", "value", "typeAnnotation", "static")
|
|
.field("value", or(def("Expression"), null))
|
|
.field("static", Boolean, defaults["false"])
|
|
.field("typeAnnotation", TypeAnnotation, defaults["null"]);
|
|
["ClassDeclaration",
|
|
"ClassExpression",
|
|
].forEach(function (typeName) {
|
|
def(typeName)
|
|
.field("typeParameters", TypeParamDecl, defaults["null"])
|
|
.field("superTypeParameters", or(def("TypeParameterInstantiation"), def("TSTypeParameterInstantiation"), null), defaults["null"])
|
|
.field("implements", or([def("ClassImplements")], [def("TSExpressionWithTypeArguments")]), defaults.emptyArray);
|
|
});
|
|
}
|
|
exports$1.default = default_1;
|
|
(0, shared_1.maybeSetModuleExports)(function () { return module; });
|
|
|
|
} (typeAnnotations, typeAnnotations.exports));
|
|
return typeAnnotations.exports;
|
|
}
|
|
|
|
flow.exports;
|
|
|
|
var hasRequiredFlow;
|
|
|
|
function requireFlow () {
|
|
if (hasRequiredFlow) return flow.exports;
|
|
hasRequiredFlow = 1;
|
|
(function (module, exports$1) {
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
var tslib_1 = require$$0;
|
|
var es_proposals_1 = tslib_1.__importDefault(requireEsProposals());
|
|
var type_annotations_1 = tslib_1.__importDefault(requireTypeAnnotations());
|
|
var types_1 = tslib_1.__importDefault(requireTypes());
|
|
var shared_1 = tslib_1.__importStar(requireShared());
|
|
function default_1(fork) {
|
|
fork.use(es_proposals_1.default);
|
|
fork.use(type_annotations_1.default);
|
|
var types = fork.use(types_1.default);
|
|
var def = types.Type.def;
|
|
var or = types.Type.or;
|
|
var defaults = fork.use(shared_1.default).defaults;
|
|
// Base types
|
|
def("Flow").bases("Node");
|
|
def("FlowType").bases("Flow");
|
|
// Type annotations
|
|
def("AnyTypeAnnotation")
|
|
.bases("FlowType")
|
|
.build();
|
|
def("EmptyTypeAnnotation")
|
|
.bases("FlowType")
|
|
.build();
|
|
def("MixedTypeAnnotation")
|
|
.bases("FlowType")
|
|
.build();
|
|
def("VoidTypeAnnotation")
|
|
.bases("FlowType")
|
|
.build();
|
|
def("SymbolTypeAnnotation")
|
|
.bases("FlowType")
|
|
.build();
|
|
def("NumberTypeAnnotation")
|
|
.bases("FlowType")
|
|
.build();
|
|
def("BigIntTypeAnnotation")
|
|
.bases("FlowType")
|
|
.build();
|
|
def("NumberLiteralTypeAnnotation")
|
|
.bases("FlowType")
|
|
.build("value", "raw")
|
|
.field("value", Number)
|
|
.field("raw", String);
|
|
// Babylon 6 differs in AST from Flow
|
|
// same as NumberLiteralTypeAnnotation
|
|
def("NumericLiteralTypeAnnotation")
|
|
.bases("FlowType")
|
|
.build("value", "raw")
|
|
.field("value", Number)
|
|
.field("raw", String);
|
|
def("BigIntLiteralTypeAnnotation")
|
|
.bases("FlowType")
|
|
.build("value", "raw")
|
|
.field("value", null)
|
|
.field("raw", String);
|
|
def("StringTypeAnnotation")
|
|
.bases("FlowType")
|
|
.build();
|
|
def("StringLiteralTypeAnnotation")
|
|
.bases("FlowType")
|
|
.build("value", "raw")
|
|
.field("value", String)
|
|
.field("raw", String);
|
|
def("BooleanTypeAnnotation")
|
|
.bases("FlowType")
|
|
.build();
|
|
def("BooleanLiteralTypeAnnotation")
|
|
.bases("FlowType")
|
|
.build("value", "raw")
|
|
.field("value", Boolean)
|
|
.field("raw", String);
|
|
def("TypeAnnotation")
|
|
.bases("Node")
|
|
.build("typeAnnotation")
|
|
.field("typeAnnotation", def("FlowType"));
|
|
def("NullableTypeAnnotation")
|
|
.bases("FlowType")
|
|
.build("typeAnnotation")
|
|
.field("typeAnnotation", def("FlowType"));
|
|
def("NullLiteralTypeAnnotation")
|
|
.bases("FlowType")
|
|
.build();
|
|
def("NullTypeAnnotation")
|
|
.bases("FlowType")
|
|
.build();
|
|
def("ThisTypeAnnotation")
|
|
.bases("FlowType")
|
|
.build();
|
|
def("ExistsTypeAnnotation")
|
|
.bases("FlowType")
|
|
.build();
|
|
def("ExistentialTypeParam")
|
|
.bases("FlowType")
|
|
.build();
|
|
def("FunctionTypeAnnotation")
|
|
.bases("FlowType")
|
|
.build("params", "returnType", "rest", "typeParameters")
|
|
.field("params", [def("FunctionTypeParam")])
|
|
.field("returnType", def("FlowType"))
|
|
.field("rest", or(def("FunctionTypeParam"), null))
|
|
.field("typeParameters", or(def("TypeParameterDeclaration"), null));
|
|
def("FunctionTypeParam")
|
|
.bases("Node")
|
|
.build("name", "typeAnnotation", "optional")
|
|
.field("name", or(def("Identifier"), null))
|
|
.field("typeAnnotation", def("FlowType"))
|
|
.field("optional", Boolean);
|
|
def("ArrayTypeAnnotation")
|
|
.bases("FlowType")
|
|
.build("elementType")
|
|
.field("elementType", def("FlowType"));
|
|
def("ObjectTypeAnnotation")
|
|
.bases("FlowType")
|
|
.build("properties", "indexers", "callProperties")
|
|
.field("properties", [
|
|
or(def("ObjectTypeProperty"), def("ObjectTypeSpreadProperty"))
|
|
])
|
|
.field("indexers", [def("ObjectTypeIndexer")], defaults.emptyArray)
|
|
.field("callProperties", [def("ObjectTypeCallProperty")], defaults.emptyArray)
|
|
.field("inexact", or(Boolean, void 0), defaults["undefined"])
|
|
.field("exact", Boolean, defaults["false"])
|
|
.field("internalSlots", [def("ObjectTypeInternalSlot")], defaults.emptyArray);
|
|
def("Variance")
|
|
.bases("Node")
|
|
.build("kind")
|
|
.field("kind", or("plus", "minus"));
|
|
var LegacyVariance = or(def("Variance"), "plus", "minus", null);
|
|
def("ObjectTypeProperty")
|
|
.bases("Node")
|
|
.build("key", "value", "optional")
|
|
.field("key", or(def("Literal"), def("Identifier")))
|
|
.field("value", def("FlowType"))
|
|
.field("optional", Boolean)
|
|
.field("variance", LegacyVariance, defaults["null"]);
|
|
def("ObjectTypeIndexer")
|
|
.bases("Node")
|
|
.build("id", "key", "value")
|
|
.field("id", def("Identifier"))
|
|
.field("key", def("FlowType"))
|
|
.field("value", def("FlowType"))
|
|
.field("variance", LegacyVariance, defaults["null"])
|
|
.field("static", Boolean, defaults["false"]);
|
|
def("ObjectTypeCallProperty")
|
|
.bases("Node")
|
|
.build("value")
|
|
.field("value", def("FunctionTypeAnnotation"))
|
|
.field("static", Boolean, defaults["false"]);
|
|
def("QualifiedTypeIdentifier")
|
|
.bases("Node")
|
|
.build("qualification", "id")
|
|
.field("qualification", or(def("Identifier"), def("QualifiedTypeIdentifier")))
|
|
.field("id", def("Identifier"));
|
|
def("GenericTypeAnnotation")
|
|
.bases("FlowType")
|
|
.build("id", "typeParameters")
|
|
.field("id", or(def("Identifier"), def("QualifiedTypeIdentifier")))
|
|
.field("typeParameters", or(def("TypeParameterInstantiation"), null));
|
|
def("MemberTypeAnnotation")
|
|
.bases("FlowType")
|
|
.build("object", "property")
|
|
.field("object", def("Identifier"))
|
|
.field("property", or(def("MemberTypeAnnotation"), def("GenericTypeAnnotation")));
|
|
def("IndexedAccessType")
|
|
.bases("FlowType")
|
|
.build("objectType", "indexType")
|
|
.field("objectType", def("FlowType"))
|
|
.field("indexType", def("FlowType"));
|
|
def("OptionalIndexedAccessType")
|
|
.bases("FlowType")
|
|
.build("objectType", "indexType", "optional")
|
|
.field("objectType", def("FlowType"))
|
|
.field("indexType", def("FlowType"))
|
|
.field('optional', Boolean);
|
|
def("UnionTypeAnnotation")
|
|
.bases("FlowType")
|
|
.build("types")
|
|
.field("types", [def("FlowType")]);
|
|
def("IntersectionTypeAnnotation")
|
|
.bases("FlowType")
|
|
.build("types")
|
|
.field("types", [def("FlowType")]);
|
|
def("TypeofTypeAnnotation")
|
|
.bases("FlowType")
|
|
.build("argument")
|
|
.field("argument", def("FlowType"));
|
|
def("ObjectTypeSpreadProperty")
|
|
.bases("Node")
|
|
.build("argument")
|
|
.field("argument", def("FlowType"));
|
|
def("ObjectTypeInternalSlot")
|
|
.bases("Node")
|
|
.build("id", "value", "optional", "static", "method")
|
|
.field("id", def("Identifier"))
|
|
.field("value", def("FlowType"))
|
|
.field("optional", Boolean)
|
|
.field("static", Boolean)
|
|
.field("method", Boolean);
|
|
def("TypeParameterDeclaration")
|
|
.bases("Node")
|
|
.build("params")
|
|
.field("params", [def("TypeParameter")]);
|
|
def("TypeParameterInstantiation")
|
|
.bases("Node")
|
|
.build("params")
|
|
.field("params", [def("FlowType")]);
|
|
def("TypeParameter")
|
|
.bases("FlowType")
|
|
.build("name", "variance", "bound", "default")
|
|
.field("name", String)
|
|
.field("variance", LegacyVariance, defaults["null"])
|
|
.field("bound", or(def("TypeAnnotation"), null), defaults["null"])
|
|
.field("default", or(def("FlowType"), null), defaults["null"]);
|
|
def("ClassProperty")
|
|
.field("variance", LegacyVariance, defaults["null"]);
|
|
def("ClassImplements")
|
|
.bases("Node")
|
|
.build("id")
|
|
.field("id", def("Identifier"))
|
|
.field("superClass", or(def("Expression"), null), defaults["null"])
|
|
.field("typeParameters", or(def("TypeParameterInstantiation"), null), defaults["null"]);
|
|
def("InterfaceTypeAnnotation")
|
|
.bases("FlowType")
|
|
.build("body", "extends")
|
|
.field("body", def("ObjectTypeAnnotation"))
|
|
.field("extends", or([def("InterfaceExtends")], null), defaults["null"]);
|
|
def("InterfaceDeclaration")
|
|
.bases("Declaration")
|
|
.build("id", "body", "extends")
|
|
.field("id", def("Identifier"))
|
|
.field("typeParameters", or(def("TypeParameterDeclaration"), null), defaults["null"])
|
|
.field("body", def("ObjectTypeAnnotation"))
|
|
.field("extends", [def("InterfaceExtends")]);
|
|
def("DeclareInterface")
|
|
.bases("InterfaceDeclaration")
|
|
.build("id", "body", "extends");
|
|
def("InterfaceExtends")
|
|
.bases("Node")
|
|
.build("id")
|
|
.field("id", def("Identifier"))
|
|
.field("typeParameters", or(def("TypeParameterInstantiation"), null), defaults["null"]);
|
|
def("TypeAlias")
|
|
.bases("Declaration")
|
|
.build("id", "typeParameters", "right")
|
|
.field("id", def("Identifier"))
|
|
.field("typeParameters", or(def("TypeParameterDeclaration"), null))
|
|
.field("right", def("FlowType"));
|
|
def("DeclareTypeAlias")
|
|
.bases("TypeAlias")
|
|
.build("id", "typeParameters", "right");
|
|
def("OpaqueType")
|
|
.bases("Declaration")
|
|
.build("id", "typeParameters", "impltype", "supertype")
|
|
.field("id", def("Identifier"))
|
|
.field("typeParameters", or(def("TypeParameterDeclaration"), null))
|
|
.field("impltype", def("FlowType"))
|
|
.field("supertype", or(def("FlowType"), null));
|
|
def("DeclareOpaqueType")
|
|
.bases("OpaqueType")
|
|
.build("id", "typeParameters", "supertype")
|
|
.field("impltype", or(def("FlowType"), null));
|
|
def("TypeCastExpression")
|
|
.bases("Expression")
|
|
.build("expression", "typeAnnotation")
|
|
.field("expression", def("Expression"))
|
|
.field("typeAnnotation", def("TypeAnnotation"));
|
|
def("TupleTypeAnnotation")
|
|
.bases("FlowType")
|
|
.build("types")
|
|
.field("types", [def("FlowType")]);
|
|
def("DeclareVariable")
|
|
.bases("Statement")
|
|
.build("id")
|
|
.field("id", def("Identifier"));
|
|
def("DeclareFunction")
|
|
.bases("Statement")
|
|
.build("id")
|
|
.field("id", def("Identifier"))
|
|
.field("predicate", or(def("FlowPredicate"), null), defaults["null"]);
|
|
def("DeclareClass")
|
|
.bases("InterfaceDeclaration")
|
|
.build("id");
|
|
def("DeclareModule")
|
|
.bases("Statement")
|
|
.build("id", "body")
|
|
.field("id", or(def("Identifier"), def("Literal")))
|
|
.field("body", def("BlockStatement"));
|
|
def("DeclareModuleExports")
|
|
.bases("Statement")
|
|
.build("typeAnnotation")
|
|
.field("typeAnnotation", def("TypeAnnotation"));
|
|
def("DeclareExportDeclaration")
|
|
.bases("Declaration")
|
|
.build("default", "declaration", "specifiers", "source")
|
|
.field("default", Boolean)
|
|
.field("declaration", or(def("DeclareVariable"), def("DeclareFunction"), def("DeclareClass"), def("FlowType"), // Implies default.
|
|
def("TypeAlias"), // Implies named type
|
|
def("DeclareOpaqueType"), // Implies named opaque type
|
|
def("InterfaceDeclaration"), null))
|
|
.field("specifiers", [or(def("ExportSpecifier"), def("ExportBatchSpecifier"))], defaults.emptyArray)
|
|
.field("source", or(def("Literal"), null), defaults["null"]);
|
|
def("DeclareExportAllDeclaration")
|
|
.bases("Declaration")
|
|
.build("source")
|
|
.field("source", or(def("Literal"), null), defaults["null"]);
|
|
def("ImportDeclaration")
|
|
.field("importKind", or("value", "type", "typeof"), function () { return "value"; });
|
|
def("FlowPredicate").bases("Flow");
|
|
def("InferredPredicate")
|
|
.bases("FlowPredicate")
|
|
.build();
|
|
def("DeclaredPredicate")
|
|
.bases("FlowPredicate")
|
|
.build("value")
|
|
.field("value", def("Expression"));
|
|
def("Function")
|
|
.field("predicate", or(def("FlowPredicate"), null), defaults["null"]);
|
|
def("CallExpression")
|
|
.field("typeArguments", or(null, def("TypeParameterInstantiation")), defaults["null"]);
|
|
def("NewExpression")
|
|
.field("typeArguments", or(null, def("TypeParameterInstantiation")), defaults["null"]);
|
|
// Enums
|
|
def("EnumDeclaration")
|
|
.bases("Declaration")
|
|
.build("id", "body")
|
|
.field("id", def("Identifier"))
|
|
.field("body", or(def("EnumBooleanBody"), def("EnumNumberBody"), def("EnumStringBody"), def("EnumSymbolBody")));
|
|
def("EnumBooleanBody")
|
|
.build("members", "explicitType")
|
|
.field("members", [def("EnumBooleanMember")])
|
|
.field("explicitType", Boolean);
|
|
def("EnumNumberBody")
|
|
.build("members", "explicitType")
|
|
.field("members", [def("EnumNumberMember")])
|
|
.field("explicitType", Boolean);
|
|
def("EnumStringBody")
|
|
.build("members", "explicitType")
|
|
.field("members", or([def("EnumStringMember")], [def("EnumDefaultedMember")]))
|
|
.field("explicitType", Boolean);
|
|
def("EnumSymbolBody")
|
|
.build("members")
|
|
.field("members", [def("EnumDefaultedMember")]);
|
|
def("EnumBooleanMember")
|
|
.build("id", "init")
|
|
.field("id", def("Identifier"))
|
|
.field("init", or(def("Literal"), Boolean));
|
|
def("EnumNumberMember")
|
|
.build("id", "init")
|
|
.field("id", def("Identifier"))
|
|
.field("init", def("Literal"));
|
|
def("EnumStringMember")
|
|
.build("id", "init")
|
|
.field("id", def("Identifier"))
|
|
.field("init", def("Literal"));
|
|
def("EnumDefaultedMember")
|
|
.build("id")
|
|
.field("id", def("Identifier"));
|
|
}
|
|
exports$1.default = default_1;
|
|
(0, shared_1.maybeSetModuleExports)(function () { return module; });
|
|
|
|
} (flow, flow.exports));
|
|
return flow.exports;
|
|
}
|
|
|
|
var esprima$3 = {exports: {}};
|
|
|
|
esprima$3.exports;
|
|
|
|
var hasRequiredEsprima$2;
|
|
|
|
function requireEsprima$2 () {
|
|
if (hasRequiredEsprima$2) return esprima$3.exports;
|
|
hasRequiredEsprima$2 = 1;
|
|
(function (module, exports$1) {
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
var tslib_1 = require$$0;
|
|
var es_proposals_1 = tslib_1.__importDefault(requireEsProposals());
|
|
var types_1 = tslib_1.__importDefault(requireTypes());
|
|
var shared_1 = tslib_1.__importStar(requireShared());
|
|
function default_1(fork) {
|
|
fork.use(es_proposals_1.default);
|
|
var types = fork.use(types_1.default);
|
|
var defaults = fork.use(shared_1.default).defaults;
|
|
var def = types.Type.def;
|
|
var or = types.Type.or;
|
|
def("VariableDeclaration")
|
|
.field("declarations", [or(def("VariableDeclarator"), def("Identifier") // Esprima deviation.
|
|
)]);
|
|
def("Property")
|
|
.field("value", or(def("Expression"), def("Pattern") // Esprima deviation.
|
|
));
|
|
def("ArrayPattern")
|
|
.field("elements", [or(def("Pattern"), def("SpreadElement"), null)]);
|
|
def("ObjectPattern")
|
|
.field("properties", [or(def("Property"), def("PropertyPattern"), def("SpreadPropertyPattern"), def("SpreadProperty") // Used by Esprima.
|
|
)]);
|
|
// Like ModuleSpecifier, except type:"ExportSpecifier" and buildable.
|
|
// export {<id [as name]>} [from ...];
|
|
def("ExportSpecifier")
|
|
.bases("ModuleSpecifier")
|
|
.build("id", "name");
|
|
// export <*> from ...;
|
|
def("ExportBatchSpecifier")
|
|
.bases("Specifier")
|
|
.build();
|
|
def("ExportDeclaration")
|
|
.bases("Declaration")
|
|
.build("default", "declaration", "specifiers", "source")
|
|
.field("default", Boolean)
|
|
.field("declaration", or(def("Declaration"), def("Expression"), // Implies default.
|
|
null))
|
|
.field("specifiers", [or(def("ExportSpecifier"), def("ExportBatchSpecifier"))], defaults.emptyArray)
|
|
.field("source", or(def("Literal"), null), defaults["null"]);
|
|
def("Block")
|
|
.bases("Comment")
|
|
.build("value", /*optional:*/ "leading", "trailing");
|
|
def("Line")
|
|
.bases("Comment")
|
|
.build("value", /*optional:*/ "leading", "trailing");
|
|
}
|
|
exports$1.default = default_1;
|
|
(0, shared_1.maybeSetModuleExports)(function () { return module; });
|
|
|
|
} (esprima$3, esprima$3.exports));
|
|
return esprima$3.exports;
|
|
}
|
|
|
|
var babel$1 = {exports: {}};
|
|
|
|
var babelCore = {exports: {}};
|
|
|
|
babelCore.exports;
|
|
|
|
var hasRequiredBabelCore;
|
|
|
|
function requireBabelCore () {
|
|
if (hasRequiredBabelCore) return babelCore.exports;
|
|
hasRequiredBabelCore = 1;
|
|
(function (module, exports$1) {
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
var tslib_1 = require$$0;
|
|
var es_proposals_1 = tslib_1.__importDefault(requireEsProposals());
|
|
var types_1 = tslib_1.__importDefault(requireTypes());
|
|
var shared_1 = tslib_1.__importStar(requireShared());
|
|
function default_1(fork) {
|
|
var _a, _b, _c, _d, _e;
|
|
fork.use(es_proposals_1.default);
|
|
var types = fork.use(types_1.default);
|
|
var defaults = fork.use(shared_1.default).defaults;
|
|
var def = types.Type.def;
|
|
var or = types.Type.or;
|
|
var isUndefined = types.builtInTypes.undefined;
|
|
def("Noop")
|
|
.bases("Statement")
|
|
.build();
|
|
def("DoExpression")
|
|
.bases("Expression")
|
|
.build("body")
|
|
.field("body", [def("Statement")]);
|
|
def("BindExpression")
|
|
.bases("Expression")
|
|
.build("object", "callee")
|
|
.field("object", or(def("Expression"), null))
|
|
.field("callee", def("Expression"));
|
|
def("ParenthesizedExpression")
|
|
.bases("Expression")
|
|
.build("expression")
|
|
.field("expression", def("Expression"));
|
|
def("ExportNamespaceSpecifier")
|
|
.bases("Specifier")
|
|
.build("exported")
|
|
.field("exported", def("Identifier"));
|
|
def("ExportDefaultSpecifier")
|
|
.bases("Specifier")
|
|
.build("exported")
|
|
.field("exported", def("Identifier"));
|
|
def("CommentBlock")
|
|
.bases("Comment")
|
|
.build("value", /*optional:*/ "leading", "trailing");
|
|
def("CommentLine")
|
|
.bases("Comment")
|
|
.build("value", /*optional:*/ "leading", "trailing");
|
|
def("Directive")
|
|
.bases("Node")
|
|
.build("value")
|
|
.field("value", def("DirectiveLiteral"));
|
|
def("DirectiveLiteral")
|
|
.bases("Node", "Expression")
|
|
.build("value")
|
|
.field("value", String, defaults["use strict"]);
|
|
def("InterpreterDirective")
|
|
.bases("Node")
|
|
.build("value")
|
|
.field("value", String);
|
|
def("BlockStatement")
|
|
.bases("Statement")
|
|
.build("body")
|
|
.field("body", [def("Statement")])
|
|
.field("directives", [def("Directive")], defaults.emptyArray);
|
|
def("Program")
|
|
.bases("Node")
|
|
.build("body")
|
|
.field("body", [def("Statement")])
|
|
.field("directives", [def("Directive")], defaults.emptyArray)
|
|
.field("interpreter", or(def("InterpreterDirective"), null), defaults["null"]);
|
|
function makeLiteralExtra(rawValueType, toRaw) {
|
|
if (rawValueType === void 0) { rawValueType = String; }
|
|
return [
|
|
"extra",
|
|
{
|
|
rawValue: rawValueType,
|
|
raw: String,
|
|
},
|
|
function getDefault() {
|
|
var value = types.getFieldValue(this, "value");
|
|
return {
|
|
rawValue: value,
|
|
raw: toRaw ? toRaw(value) : String(value),
|
|
};
|
|
},
|
|
];
|
|
}
|
|
// Split Literal
|
|
(_a = def("StringLiteral")
|
|
.bases("Literal")
|
|
.build("value")
|
|
.field("value", String))
|
|
.field.apply(_a, makeLiteralExtra(String, function (val) { return JSON.stringify(val); }));
|
|
(_b = def("NumericLiteral")
|
|
.bases("Literal")
|
|
.build("value")
|
|
.field("value", Number)
|
|
.field("raw", or(String, null), defaults["null"]))
|
|
.field.apply(_b, makeLiteralExtra(Number));
|
|
(_c = def("BigIntLiteral")
|
|
.bases("Literal")
|
|
.build("value")
|
|
// Only String really seems appropriate here, since BigInt values
|
|
// often exceed the limits of JS numbers.
|
|
.field("value", or(String, Number)))
|
|
.field.apply(_c, makeLiteralExtra(String, function (val) { return val + "n"; }));
|
|
// https://github.com/tc39/proposal-decimal
|
|
// https://github.com/babel/babel/pull/11640
|
|
(_d = def("DecimalLiteral")
|
|
.bases("Literal")
|
|
.build("value")
|
|
.field("value", String))
|
|
.field.apply(_d, makeLiteralExtra(String, function (val) { return val + "m"; }));
|
|
def("NullLiteral")
|
|
.bases("Literal")
|
|
.build()
|
|
.field("value", null, defaults["null"]);
|
|
def("BooleanLiteral")
|
|
.bases("Literal")
|
|
.build("value")
|
|
.field("value", Boolean);
|
|
(_e = def("RegExpLiteral")
|
|
.bases("Literal")
|
|
.build("pattern", "flags")
|
|
.field("pattern", String)
|
|
.field("flags", String)
|
|
.field("value", RegExp, function () {
|
|
return new RegExp(this.pattern, this.flags);
|
|
}))
|
|
.field.apply(_e, makeLiteralExtra(or(RegExp, isUndefined), function (exp) { return "/".concat(exp.pattern, "/").concat(exp.flags || ""); })).field("regex", {
|
|
pattern: String,
|
|
flags: String
|
|
}, function () {
|
|
return {
|
|
pattern: this.pattern,
|
|
flags: this.flags,
|
|
};
|
|
});
|
|
var ObjectExpressionProperty = or(def("Property"), def("ObjectMethod"), def("ObjectProperty"), def("SpreadProperty"), def("SpreadElement"));
|
|
// Split Property -> ObjectProperty and ObjectMethod
|
|
def("ObjectExpression")
|
|
.bases("Expression")
|
|
.build("properties")
|
|
.field("properties", [ObjectExpressionProperty]);
|
|
// ObjectMethod hoist .value properties to own properties
|
|
def("ObjectMethod")
|
|
.bases("Node", "Function")
|
|
.build("kind", "key", "params", "body", "computed")
|
|
.field("kind", or("method", "get", "set"))
|
|
.field("key", or(def("Literal"), def("Identifier"), def("Expression")))
|
|
.field("params", [def("Pattern")])
|
|
.field("body", def("BlockStatement"))
|
|
.field("computed", Boolean, defaults["false"])
|
|
.field("generator", Boolean, defaults["false"])
|
|
.field("async", Boolean, defaults["false"])
|
|
.field("accessibility", // TypeScript
|
|
or(def("Literal"), null), defaults["null"])
|
|
.field("decorators", or([def("Decorator")], null), defaults["null"]);
|
|
def("ObjectProperty")
|
|
.bases("Node")
|
|
.build("key", "value")
|
|
.field("key", or(def("Literal"), def("Identifier"), def("Expression")))
|
|
.field("value", or(def("Expression"), def("Pattern")))
|
|
.field("accessibility", // TypeScript
|
|
or(def("Literal"), null), defaults["null"])
|
|
.field("computed", Boolean, defaults["false"]);
|
|
var ClassBodyElement = or(def("MethodDefinition"), def("VariableDeclarator"), def("ClassPropertyDefinition"), def("ClassProperty"), def("ClassPrivateProperty"), def("ClassMethod"), def("ClassPrivateMethod"), def("ClassAccessorProperty"), def("StaticBlock"));
|
|
// MethodDefinition -> ClassMethod
|
|
def("ClassBody")
|
|
.bases("Declaration")
|
|
.build("body")
|
|
.field("body", [ClassBodyElement]);
|
|
def("ClassMethod")
|
|
.bases("Declaration", "Function")
|
|
.build("kind", "key", "params", "body", "computed", "static")
|
|
.field("key", or(def("Literal"), def("Identifier"), def("Expression")));
|
|
def("ClassPrivateMethod")
|
|
.bases("Declaration", "Function")
|
|
.build("key", "params", "body", "kind", "computed", "static")
|
|
.field("key", def("PrivateName"));
|
|
def("ClassAccessorProperty")
|
|
.bases("Declaration")
|
|
.build("key", "value", "decorators", "computed", "static")
|
|
.field("key", or(def("Literal"), def("Identifier"), def("PrivateName"),
|
|
// Only when .computed is true (TODO enforce this)
|
|
def("Expression")))
|
|
.field("value", or(def("Expression"), null), defaults["null"]);
|
|
["ClassMethod",
|
|
"ClassPrivateMethod",
|
|
].forEach(function (typeName) {
|
|
def(typeName)
|
|
.field("kind", or("get", "set", "method", "constructor"), function () { return "method"; })
|
|
.field("body", def("BlockStatement"))
|
|
// For backwards compatibility only. Expect accessibility instead (see below).
|
|
.field("access", or("public", "private", "protected", null), defaults["null"]);
|
|
});
|
|
["ClassMethod",
|
|
"ClassPrivateMethod",
|
|
"ClassAccessorProperty",
|
|
].forEach(function (typeName) {
|
|
def(typeName)
|
|
.field("computed", Boolean, defaults["false"])
|
|
.field("static", Boolean, defaults["false"])
|
|
.field("abstract", Boolean, defaults["false"])
|
|
.field("accessibility", or("public", "private", "protected", null), defaults["null"])
|
|
.field("decorators", or([def("Decorator")], null), defaults["null"])
|
|
.field("definite", Boolean, defaults["false"])
|
|
.field("optional", Boolean, defaults["false"])
|
|
.field("override", Boolean, defaults["false"])
|
|
.field("readonly", Boolean, defaults["false"]);
|
|
});
|
|
var ObjectPatternProperty = or(def("Property"), def("PropertyPattern"), def("SpreadPropertyPattern"), def("SpreadProperty"), // Used by Esprima
|
|
def("ObjectProperty"), // Babel 6
|
|
def("RestProperty"), // Babel 6
|
|
def("RestElement"));
|
|
// Split into RestProperty and SpreadProperty
|
|
def("ObjectPattern")
|
|
.bases("Pattern")
|
|
.build("properties")
|
|
.field("properties", [ObjectPatternProperty])
|
|
.field("decorators", or([def("Decorator")], null), defaults["null"]);
|
|
def("SpreadProperty")
|
|
.bases("Node")
|
|
.build("argument")
|
|
.field("argument", def("Expression"));
|
|
def("RestProperty")
|
|
.bases("Node")
|
|
.build("argument")
|
|
.field("argument", def("Expression"));
|
|
def("ForAwaitStatement")
|
|
.bases("Statement")
|
|
.build("left", "right", "body")
|
|
.field("left", or(def("VariableDeclaration"), def("Expression")))
|
|
.field("right", def("Expression"))
|
|
.field("body", def("Statement"));
|
|
// The callee node of a dynamic import(...) expression.
|
|
def("Import")
|
|
.bases("Expression")
|
|
.build();
|
|
}
|
|
exports$1.default = default_1;
|
|
(0, shared_1.maybeSetModuleExports)(function () { return module; });
|
|
|
|
} (babelCore, babelCore.exports));
|
|
return babelCore.exports;
|
|
}
|
|
|
|
babel$1.exports;
|
|
|
|
var hasRequiredBabel$1;
|
|
|
|
function requireBabel$1 () {
|
|
if (hasRequiredBabel$1) return babel$1.exports;
|
|
hasRequiredBabel$1 = 1;
|
|
(function (module, exports$1) {
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
var tslib_1 = require$$0;
|
|
var types_1 = tslib_1.__importDefault(requireTypes());
|
|
var babel_core_1 = tslib_1.__importDefault(requireBabelCore());
|
|
var flow_1 = tslib_1.__importDefault(requireFlow());
|
|
var shared_1 = requireShared();
|
|
function default_1(fork) {
|
|
var types = fork.use(types_1.default);
|
|
var def = types.Type.def;
|
|
fork.use(babel_core_1.default);
|
|
fork.use(flow_1.default);
|
|
// https://github.com/babel/babel/pull/10148
|
|
def("V8IntrinsicIdentifier")
|
|
.bases("Expression")
|
|
.build("name")
|
|
.field("name", String);
|
|
// https://github.com/babel/babel/pull/13191
|
|
// https://github.com/babel/website/pull/2541
|
|
def("TopicReference")
|
|
.bases("Expression")
|
|
.build();
|
|
}
|
|
exports$1.default = default_1;
|
|
(0, shared_1.maybeSetModuleExports)(function () { return module; });
|
|
|
|
} (babel$1, babel$1.exports));
|
|
return babel$1.exports;
|
|
}
|
|
|
|
var typescript = {exports: {}};
|
|
|
|
typescript.exports;
|
|
|
|
var hasRequiredTypescript;
|
|
|
|
function requireTypescript () {
|
|
if (hasRequiredTypescript) return typescript.exports;
|
|
hasRequiredTypescript = 1;
|
|
(function (module, exports$1) {
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
var tslib_1 = require$$0;
|
|
var babel_core_1 = tslib_1.__importDefault(requireBabelCore());
|
|
var type_annotations_1 = tslib_1.__importDefault(requireTypeAnnotations());
|
|
var types_1 = tslib_1.__importDefault(requireTypes());
|
|
var shared_1 = tslib_1.__importStar(requireShared());
|
|
function default_1(fork) {
|
|
// Since TypeScript is parsed by Babylon, include the core Babylon types
|
|
// but omit the Flow-related types.
|
|
fork.use(babel_core_1.default);
|
|
fork.use(type_annotations_1.default);
|
|
var types = fork.use(types_1.default);
|
|
var n = types.namedTypes;
|
|
var def = types.Type.def;
|
|
var or = types.Type.or;
|
|
var defaults = fork.use(shared_1.default).defaults;
|
|
var StringLiteral = types.Type.from(function (value, deep) {
|
|
if (n.StringLiteral &&
|
|
n.StringLiteral.check(value, deep)) {
|
|
return true;
|
|
}
|
|
if (n.Literal &&
|
|
n.Literal.check(value, deep) &&
|
|
typeof value.value === "string") {
|
|
return true;
|
|
}
|
|
return false;
|
|
}, "StringLiteral");
|
|
def("TSType")
|
|
.bases("Node");
|
|
var TSEntityName = or(def("Identifier"), def("TSQualifiedName"));
|
|
def("TSTypeReference")
|
|
.bases("TSType", "TSHasOptionalTypeParameterInstantiation")
|
|
.build("typeName", "typeParameters")
|
|
.field("typeName", TSEntityName);
|
|
// An abstract (non-buildable) base type that provide a commonly-needed
|
|
// optional .typeParameters field.
|
|
def("TSHasOptionalTypeParameterInstantiation")
|
|
.field("typeParameters", or(def("TSTypeParameterInstantiation"), null), defaults["null"]);
|
|
// An abstract (non-buildable) base type that provide a commonly-needed
|
|
// optional .typeParameters field.
|
|
def("TSHasOptionalTypeParameters")
|
|
.field("typeParameters", or(def("TSTypeParameterDeclaration"), null, void 0), defaults["null"]);
|
|
// An abstract (non-buildable) base type that provide a commonly-needed
|
|
// optional .typeAnnotation field.
|
|
def("TSHasOptionalTypeAnnotation")
|
|
.field("typeAnnotation", or(def("TSTypeAnnotation"), null), defaults["null"]);
|
|
def("TSQualifiedName")
|
|
.bases("Node")
|
|
.build("left", "right")
|
|
.field("left", TSEntityName)
|
|
.field("right", TSEntityName);
|
|
def("TSAsExpression")
|
|
.bases("Expression", "Pattern")
|
|
.build("expression", "typeAnnotation")
|
|
.field("expression", def("Expression"))
|
|
.field("typeAnnotation", def("TSType"))
|
|
.field("extra", or({ parenthesized: Boolean }, null), defaults["null"]);
|
|
def("TSTypeCastExpression")
|
|
.bases("Expression")
|
|
.build("expression", "typeAnnotation")
|
|
.field("expression", def("Expression"))
|
|
.field("typeAnnotation", def("TSType"));
|
|
def("TSSatisfiesExpression")
|
|
.bases("Expression", "Pattern")
|
|
.build("expression", "typeAnnotation")
|
|
.field("expression", def("Expression"))
|
|
.field("typeAnnotation", def("TSType"));
|
|
def("TSNonNullExpression")
|
|
.bases("Expression", "Pattern")
|
|
.build("expression")
|
|
.field("expression", def("Expression"));
|
|
[
|
|
"TSAnyKeyword",
|
|
"TSBigIntKeyword",
|
|
"TSBooleanKeyword",
|
|
"TSNeverKeyword",
|
|
"TSNullKeyword",
|
|
"TSNumberKeyword",
|
|
"TSObjectKeyword",
|
|
"TSStringKeyword",
|
|
"TSSymbolKeyword",
|
|
"TSUndefinedKeyword",
|
|
"TSUnknownKeyword",
|
|
"TSVoidKeyword",
|
|
"TSIntrinsicKeyword",
|
|
"TSThisType",
|
|
].forEach(function (keywordType) {
|
|
def(keywordType)
|
|
.bases("TSType")
|
|
.build();
|
|
});
|
|
def("TSArrayType")
|
|
.bases("TSType")
|
|
.build("elementType")
|
|
.field("elementType", def("TSType"));
|
|
def("TSLiteralType")
|
|
.bases("TSType")
|
|
.build("literal")
|
|
.field("literal", or(def("NumericLiteral"), def("StringLiteral"), def("BooleanLiteral"), def("TemplateLiteral"), def("UnaryExpression"), def("BigIntLiteral")));
|
|
def("TemplateLiteral")
|
|
// The TemplateLiteral type appears to be reused for TypeScript template
|
|
// literal types (instead of introducing a new TSTemplateLiteralType type),
|
|
// so we allow the templateLiteral.expressions array to be either all
|
|
// expressions or all TypeScript types.
|
|
.field("expressions", or([def("Expression")], [def("TSType")]));
|
|
["TSUnionType",
|
|
"TSIntersectionType",
|
|
].forEach(function (typeName) {
|
|
def(typeName)
|
|
.bases("TSType")
|
|
.build("types")
|
|
.field("types", [def("TSType")]);
|
|
});
|
|
def("TSConditionalType")
|
|
.bases("TSType")
|
|
.build("checkType", "extendsType", "trueType", "falseType")
|
|
.field("checkType", def("TSType"))
|
|
.field("extendsType", def("TSType"))
|
|
.field("trueType", def("TSType"))
|
|
.field("falseType", def("TSType"));
|
|
def("TSInferType")
|
|
.bases("TSType")
|
|
.build("typeParameter")
|
|
.field("typeParameter", def("TSTypeParameter"));
|
|
def("TSParenthesizedType")
|
|
.bases("TSType")
|
|
.build("typeAnnotation")
|
|
.field("typeAnnotation", def("TSType"));
|
|
var ParametersType = [or(def("Identifier"), def("RestElement"), def("ArrayPattern"), def("ObjectPattern"))];
|
|
["TSFunctionType",
|
|
"TSConstructorType",
|
|
].forEach(function (typeName) {
|
|
def(typeName)
|
|
.bases("TSType", "TSHasOptionalTypeParameters", "TSHasOptionalTypeAnnotation")
|
|
.build("parameters")
|
|
.field("parameters", ParametersType);
|
|
});
|
|
def("TSDeclareFunction")
|
|
.bases("Declaration", "TSHasOptionalTypeParameters")
|
|
.build("id", "params", "returnType")
|
|
.field("declare", Boolean, defaults["false"])
|
|
.field("async", Boolean, defaults["false"])
|
|
.field("generator", Boolean, defaults["false"])
|
|
.field("id", or(def("Identifier"), null), defaults["null"])
|
|
.field("params", [def("Pattern")])
|
|
// tSFunctionTypeAnnotationCommon
|
|
.field("returnType", or(def("TSTypeAnnotation"), def("Noop"), // Still used?
|
|
null), defaults["null"]);
|
|
def("TSDeclareMethod")
|
|
.bases("Declaration", "TSHasOptionalTypeParameters")
|
|
.build("key", "params", "returnType")
|
|
.field("async", Boolean, defaults["false"])
|
|
.field("generator", Boolean, defaults["false"])
|
|
.field("params", [def("Pattern")])
|
|
// classMethodOrPropertyCommon
|
|
.field("abstract", Boolean, defaults["false"])
|
|
.field("accessibility", or("public", "private", "protected", void 0), defaults["undefined"])
|
|
.field("static", Boolean, defaults["false"])
|
|
.field("computed", Boolean, defaults["false"])
|
|
.field("optional", Boolean, defaults["false"])
|
|
.field("key", or(def("Identifier"), def("StringLiteral"), def("NumericLiteral"),
|
|
// Only allowed if .computed is true.
|
|
def("Expression")))
|
|
// classMethodOrDeclareMethodCommon
|
|
.field("kind", or("get", "set", "method", "constructor"), function getDefault() { return "method"; })
|
|
.field("access", // Not "accessibility"?
|
|
or("public", "private", "protected", void 0), defaults["undefined"])
|
|
.field("decorators", or([def("Decorator")], null), defaults["null"])
|
|
// tSFunctionTypeAnnotationCommon
|
|
.field("returnType", or(def("TSTypeAnnotation"), def("Noop"), // Still used?
|
|
null), defaults["null"]);
|
|
def("TSMappedType")
|
|
.bases("TSType")
|
|
.build("typeParameter", "typeAnnotation")
|
|
.field("readonly", or(Boolean, "+", "-"), defaults["false"])
|
|
.field("typeParameter", def("TSTypeParameter"))
|
|
.field("optional", or(Boolean, "+", "-"), defaults["false"])
|
|
.field("typeAnnotation", or(def("TSType"), null), defaults["null"]);
|
|
def("TSTupleType")
|
|
.bases("TSType")
|
|
.build("elementTypes")
|
|
.field("elementTypes", [or(def("TSType"), def("TSNamedTupleMember"))]);
|
|
def("TSNamedTupleMember")
|
|
.bases("TSType")
|
|
.build("label", "elementType", "optional")
|
|
.field("label", def("Identifier"))
|
|
.field("optional", Boolean, defaults["false"])
|
|
.field("elementType", def("TSType"));
|
|
def("TSRestType")
|
|
.bases("TSType")
|
|
.build("typeAnnotation")
|
|
.field("typeAnnotation", def("TSType"));
|
|
def("TSOptionalType")
|
|
.bases("TSType")
|
|
.build("typeAnnotation")
|
|
.field("typeAnnotation", def("TSType"));
|
|
def("TSIndexedAccessType")
|
|
.bases("TSType")
|
|
.build("objectType", "indexType")
|
|
.field("objectType", def("TSType"))
|
|
.field("indexType", def("TSType"));
|
|
def("TSTypeOperator")
|
|
.bases("TSType")
|
|
.build("operator")
|
|
.field("operator", String)
|
|
.field("typeAnnotation", def("TSType"));
|
|
def("TSTypeAnnotation")
|
|
.bases("Node")
|
|
.build("typeAnnotation")
|
|
.field("typeAnnotation", or(def("TSType"), def("TSTypeAnnotation")));
|
|
def("TSIndexSignature")
|
|
.bases("Declaration", "TSHasOptionalTypeAnnotation")
|
|
.build("parameters", "typeAnnotation")
|
|
.field("parameters", [def("Identifier")]) // Length === 1
|
|
.field("readonly", Boolean, defaults["false"]);
|
|
def("TSPropertySignature")
|
|
.bases("Declaration", "TSHasOptionalTypeAnnotation")
|
|
.build("key", "typeAnnotation", "optional")
|
|
.field("key", def("Expression"))
|
|
.field("computed", Boolean, defaults["false"])
|
|
.field("readonly", Boolean, defaults["false"])
|
|
.field("optional", Boolean, defaults["false"])
|
|
.field("initializer", or(def("Expression"), null), defaults["null"]);
|
|
def("TSMethodSignature")
|
|
.bases("Declaration", "TSHasOptionalTypeParameters", "TSHasOptionalTypeAnnotation")
|
|
.build("key", "parameters", "typeAnnotation")
|
|
.field("key", def("Expression"))
|
|
.field("computed", Boolean, defaults["false"])
|
|
.field("optional", Boolean, defaults["false"])
|
|
.field("parameters", ParametersType);
|
|
def("TSTypePredicate")
|
|
.bases("TSTypeAnnotation", "TSType")
|
|
.build("parameterName", "typeAnnotation", "asserts")
|
|
.field("parameterName", or(def("Identifier"), def("TSThisType")))
|
|
.field("typeAnnotation", or(def("TSTypeAnnotation"), null), defaults["null"])
|
|
.field("asserts", Boolean, defaults["false"]);
|
|
["TSCallSignatureDeclaration",
|
|
"TSConstructSignatureDeclaration",
|
|
].forEach(function (typeName) {
|
|
def(typeName)
|
|
.bases("Declaration", "TSHasOptionalTypeParameters", "TSHasOptionalTypeAnnotation")
|
|
.build("parameters", "typeAnnotation")
|
|
.field("parameters", ParametersType);
|
|
});
|
|
def("TSEnumMember")
|
|
.bases("Node")
|
|
.build("id", "initializer")
|
|
.field("id", or(def("Identifier"), StringLiteral))
|
|
.field("initializer", or(def("Expression"), null), defaults["null"]);
|
|
def("TSTypeQuery")
|
|
.bases("TSType")
|
|
.build("exprName")
|
|
.field("exprName", or(TSEntityName, def("TSImportType")));
|
|
// Inferred from Babylon's tsParseTypeMember method.
|
|
var TSTypeMember = or(def("TSCallSignatureDeclaration"), def("TSConstructSignatureDeclaration"), def("TSIndexSignature"), def("TSMethodSignature"), def("TSPropertySignature"));
|
|
def("TSTypeLiteral")
|
|
.bases("TSType")
|
|
.build("members")
|
|
.field("members", [TSTypeMember]);
|
|
def("TSTypeParameter")
|
|
.bases("Identifier")
|
|
.build("name", "constraint", "default")
|
|
.field("name", or(def("Identifier"), String))
|
|
.field("constraint", or(def("TSType"), void 0), defaults["undefined"])
|
|
.field("default", or(def("TSType"), void 0), defaults["undefined"]);
|
|
def("TSTypeAssertion")
|
|
.bases("Expression", "Pattern")
|
|
.build("typeAnnotation", "expression")
|
|
.field("typeAnnotation", def("TSType"))
|
|
.field("expression", def("Expression"))
|
|
.field("extra", or({ parenthesized: Boolean }, null), defaults["null"]);
|
|
def("TSTypeParameterDeclaration")
|
|
.bases("Declaration")
|
|
.build("params")
|
|
.field("params", [def("TSTypeParameter")]);
|
|
def("TSInstantiationExpression")
|
|
.bases("Expression", "TSHasOptionalTypeParameterInstantiation")
|
|
.build("expression", "typeParameters")
|
|
.field("expression", def("Expression"));
|
|
def("TSTypeParameterInstantiation")
|
|
.bases("Node")
|
|
.build("params")
|
|
.field("params", [def("TSType")]);
|
|
def("TSEnumDeclaration")
|
|
.bases("Declaration")
|
|
.build("id", "members")
|
|
.field("id", def("Identifier"))
|
|
.field("const", Boolean, defaults["false"])
|
|
.field("declare", Boolean, defaults["false"])
|
|
.field("members", [def("TSEnumMember")])
|
|
.field("initializer", or(def("Expression"), null), defaults["null"]);
|
|
def("TSTypeAliasDeclaration")
|
|
.bases("Declaration", "TSHasOptionalTypeParameters")
|
|
.build("id", "typeAnnotation")
|
|
.field("id", def("Identifier"))
|
|
.field("declare", Boolean, defaults["false"])
|
|
.field("typeAnnotation", def("TSType"));
|
|
def("TSModuleBlock")
|
|
.bases("Node")
|
|
.build("body")
|
|
.field("body", [def("Statement")]);
|
|
def("TSModuleDeclaration")
|
|
.bases("Declaration")
|
|
.build("id", "body")
|
|
.field("id", or(StringLiteral, TSEntityName))
|
|
.field("declare", Boolean, defaults["false"])
|
|
.field("global", Boolean, defaults["false"])
|
|
.field("body", or(def("TSModuleBlock"), def("TSModuleDeclaration"), null), defaults["null"]);
|
|
def("TSImportType")
|
|
.bases("TSType", "TSHasOptionalTypeParameterInstantiation")
|
|
.build("argument", "qualifier", "typeParameters")
|
|
.field("argument", StringLiteral)
|
|
.field("qualifier", or(TSEntityName, void 0), defaults["undefined"]);
|
|
def("TSImportEqualsDeclaration")
|
|
.bases("Declaration")
|
|
.build("id", "moduleReference")
|
|
.field("id", def("Identifier"))
|
|
.field("isExport", Boolean, defaults["false"])
|
|
.field("moduleReference", or(TSEntityName, def("TSExternalModuleReference")));
|
|
def("TSExternalModuleReference")
|
|
.bases("Declaration")
|
|
.build("expression")
|
|
.field("expression", StringLiteral);
|
|
def("TSExportAssignment")
|
|
.bases("Statement")
|
|
.build("expression")
|
|
.field("expression", def("Expression"));
|
|
def("TSNamespaceExportDeclaration")
|
|
.bases("Declaration")
|
|
.build("id")
|
|
.field("id", def("Identifier"));
|
|
def("TSInterfaceBody")
|
|
.bases("Node")
|
|
.build("body")
|
|
.field("body", [TSTypeMember]);
|
|
def("TSExpressionWithTypeArguments")
|
|
.bases("TSType", "TSHasOptionalTypeParameterInstantiation")
|
|
.build("expression", "typeParameters")
|
|
.field("expression", TSEntityName);
|
|
def("TSInterfaceDeclaration")
|
|
.bases("Declaration", "TSHasOptionalTypeParameters")
|
|
.build("id", "body")
|
|
.field("id", TSEntityName)
|
|
.field("declare", Boolean, defaults["false"])
|
|
.field("extends", or([def("TSExpressionWithTypeArguments")], null), defaults["null"])
|
|
.field("body", def("TSInterfaceBody"));
|
|
def("TSParameterProperty")
|
|
.bases("Pattern")
|
|
.build("parameter")
|
|
.field("accessibility", or("public", "private", "protected", void 0), defaults["undefined"])
|
|
.field("readonly", Boolean, defaults["false"])
|
|
.field("parameter", or(def("Identifier"), def("AssignmentPattern")));
|
|
def("ClassProperty")
|
|
.field("access", // Not "accessibility"?
|
|
or("public", "private", "protected", void 0), defaults["undefined"]);
|
|
def("ClassAccessorProperty")
|
|
.bases("Declaration", "TSHasOptionalTypeAnnotation");
|
|
// Defined already in es6 and babel-core.
|
|
def("ClassBody")
|
|
.field("body", [or(def("MethodDefinition"), def("VariableDeclarator"), def("ClassPropertyDefinition"), def("ClassProperty"), def("ClassPrivateProperty"), def("ClassAccessorProperty"), def("ClassMethod"), def("ClassPrivateMethod"), def("StaticBlock"),
|
|
// Just need to add these types:
|
|
def("TSDeclareMethod"), TSTypeMember)]);
|
|
}
|
|
exports$1.default = default_1;
|
|
(0, shared_1.maybeSetModuleExports)(function () { return module; });
|
|
|
|
} (typescript, typescript.exports));
|
|
return typescript.exports;
|
|
}
|
|
|
|
var namedTypes = {};
|
|
|
|
var hasRequiredNamedTypes;
|
|
|
|
function requireNamedTypes () {
|
|
if (hasRequiredNamedTypes) return namedTypes;
|
|
hasRequiredNamedTypes = 1;
|
|
(function (exports$1) {
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
exports$1.namedTypes = void 0;
|
|
(function (namedTypes) {
|
|
})(exports$1.namedTypes || (exports$1.namedTypes = {}));
|
|
|
|
} (namedTypes));
|
|
return namedTypes;
|
|
}
|
|
|
|
var hasRequiredMain$1;
|
|
|
|
function requireMain$1 () {
|
|
if (hasRequiredMain$1) return main;
|
|
hasRequiredMain$1 = 1;
|
|
(function (exports$1) {
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
exports$1.visit = exports$1.use = exports$1.Type = exports$1.someField = exports$1.PathVisitor = exports$1.Path = exports$1.NodePath = exports$1.namedTypes = exports$1.getSupertypeNames = exports$1.getFieldValue = exports$1.getFieldNames = exports$1.getBuilderName = exports$1.finalize = exports$1.eachField = exports$1.defineMethod = exports$1.builtInTypes = exports$1.builders = exports$1.astNodesAreEquivalent = void 0;
|
|
var tslib_1 = require$$0;
|
|
var fork_1 = tslib_1.__importDefault(requireFork());
|
|
var es_proposals_1 = tslib_1.__importDefault(requireEsProposals());
|
|
var jsx_1 = tslib_1.__importDefault(requireJsx());
|
|
var flow_1 = tslib_1.__importDefault(requireFlow());
|
|
var esprima_1 = tslib_1.__importDefault(requireEsprima$2());
|
|
var babel_1 = tslib_1.__importDefault(requireBabel$1());
|
|
var typescript_1 = tslib_1.__importDefault(requireTypescript());
|
|
var namedTypes_1 = requireNamedTypes();
|
|
Object.defineProperty(exports$1, "namedTypes", { enumerable: true, get: function () { return namedTypes_1.namedTypes; } });
|
|
var _a = (0, fork_1.default)([
|
|
// Feel free to add to or remove from this list of extension modules to
|
|
// configure the precise type hierarchy that you need.
|
|
es_proposals_1.default,
|
|
jsx_1.default,
|
|
flow_1.default,
|
|
esprima_1.default,
|
|
babel_1.default,
|
|
typescript_1.default,
|
|
]), astNodesAreEquivalent = _a.astNodesAreEquivalent, builders = _a.builders, builtInTypes = _a.builtInTypes, defineMethod = _a.defineMethod, eachField = _a.eachField, finalize = _a.finalize, getBuilderName = _a.getBuilderName, getFieldNames = _a.getFieldNames, getFieldValue = _a.getFieldValue, getSupertypeNames = _a.getSupertypeNames, n = _a.namedTypes, NodePath = _a.NodePath, Path = _a.Path, PathVisitor = _a.PathVisitor, someField = _a.someField, Type = _a.Type, use = _a.use, visit = _a.visit;
|
|
exports$1.astNodesAreEquivalent = astNodesAreEquivalent;
|
|
exports$1.builders = builders;
|
|
exports$1.builtInTypes = builtInTypes;
|
|
exports$1.defineMethod = defineMethod;
|
|
exports$1.eachField = eachField;
|
|
exports$1.finalize = finalize;
|
|
exports$1.getBuilderName = getBuilderName;
|
|
exports$1.getFieldNames = getFieldNames;
|
|
exports$1.getFieldValue = getFieldValue;
|
|
exports$1.getSupertypeNames = getSupertypeNames;
|
|
exports$1.NodePath = NodePath;
|
|
exports$1.Path = Path;
|
|
exports$1.PathVisitor = PathVisitor;
|
|
exports$1.someField = someField;
|
|
exports$1.Type = Type;
|
|
exports$1.use = use;
|
|
exports$1.visit = visit;
|
|
// Populate the exported fields of the namedTypes namespace, while still
|
|
// retaining its member types.
|
|
Object.assign(namedTypes_1.namedTypes, n);
|
|
|
|
} (main));
|
|
return main;
|
|
}
|
|
|
|
var parser$1 = {};
|
|
|
|
var tinyInvariant_cjs;
|
|
var hasRequiredTinyInvariant_cjs;
|
|
|
|
function requireTinyInvariant_cjs () {
|
|
if (hasRequiredTinyInvariant_cjs) return tinyInvariant_cjs;
|
|
hasRequiredTinyInvariant_cjs = 1;
|
|
|
|
var isProduction = process.env.NODE_ENV === 'production';
|
|
var prefix = 'Invariant failed';
|
|
function invariant(condition, message) {
|
|
if (condition) {
|
|
return;
|
|
}
|
|
if (isProduction) {
|
|
throw new Error(prefix);
|
|
}
|
|
var provided = typeof message === 'function' ? message() : message;
|
|
var value = provided ? "".concat(prefix, ": ").concat(provided) : prefix;
|
|
throw new Error(value);
|
|
}
|
|
|
|
tinyInvariant_cjs = invariant;
|
|
return tinyInvariant_cjs;
|
|
}
|
|
|
|
var options = {};
|
|
|
|
var util$1 = {};
|
|
|
|
var sourceMap = {};
|
|
|
|
var sourceMapGenerator = {};
|
|
|
|
var base64Vlq = {};
|
|
|
|
var base64 = {};
|
|
|
|
/* -*- Mode: js; js-indent-level: 2; -*- */
|
|
|
|
var hasRequiredBase64;
|
|
|
|
function requireBase64 () {
|
|
if (hasRequiredBase64) return base64;
|
|
hasRequiredBase64 = 1;
|
|
/*
|
|
* Copyright 2011 Mozilla Foundation and contributors
|
|
* Licensed under the New BSD license. See LICENSE or:
|
|
* http://opensource.org/licenses/BSD-3-Clause
|
|
*/
|
|
|
|
var intToCharMap = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split('');
|
|
|
|
/**
|
|
* Encode an integer in the range of 0 to 63 to a single base 64 digit.
|
|
*/
|
|
base64.encode = function (number) {
|
|
if (0 <= number && number < intToCharMap.length) {
|
|
return intToCharMap[number];
|
|
}
|
|
throw new TypeError("Must be between 0 and 63: " + number);
|
|
};
|
|
|
|
/**
|
|
* Decode a single base 64 character code digit to an integer. Returns -1 on
|
|
* failure.
|
|
*/
|
|
base64.decode = function (charCode) {
|
|
var bigA = 65; // 'A'
|
|
var bigZ = 90; // 'Z'
|
|
|
|
var littleA = 97; // 'a'
|
|
var littleZ = 122; // 'z'
|
|
|
|
var zero = 48; // '0'
|
|
var nine = 57; // '9'
|
|
|
|
var plus = 43; // '+'
|
|
var slash = 47; // '/'
|
|
|
|
var littleOffset = 26;
|
|
var numberOffset = 52;
|
|
|
|
// 0 - 25: ABCDEFGHIJKLMNOPQRSTUVWXYZ
|
|
if (bigA <= charCode && charCode <= bigZ) {
|
|
return (charCode - bigA);
|
|
}
|
|
|
|
// 26 - 51: abcdefghijklmnopqrstuvwxyz
|
|
if (littleA <= charCode && charCode <= littleZ) {
|
|
return (charCode - littleA + littleOffset);
|
|
}
|
|
|
|
// 52 - 61: 0123456789
|
|
if (zero <= charCode && charCode <= nine) {
|
|
return (charCode - zero + numberOffset);
|
|
}
|
|
|
|
// 62: +
|
|
if (charCode == plus) {
|
|
return 62;
|
|
}
|
|
|
|
// 63: /
|
|
if (charCode == slash) {
|
|
return 63;
|
|
}
|
|
|
|
// Invalid base64 digit.
|
|
return -1;
|
|
};
|
|
return base64;
|
|
}
|
|
|
|
/* -*- Mode: js; js-indent-level: 2; -*- */
|
|
|
|
var hasRequiredBase64Vlq;
|
|
|
|
function requireBase64Vlq () {
|
|
if (hasRequiredBase64Vlq) return base64Vlq;
|
|
hasRequiredBase64Vlq = 1;
|
|
/*
|
|
* Copyright 2011 Mozilla Foundation and contributors
|
|
* Licensed under the New BSD license. See LICENSE or:
|
|
* http://opensource.org/licenses/BSD-3-Clause
|
|
*
|
|
* Based on the Base 64 VLQ implementation in Closure Compiler:
|
|
* https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java
|
|
*
|
|
* Copyright 2011 The Closure Compiler Authors. All rights reserved.
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are
|
|
* met:
|
|
*
|
|
* * Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* * Redistributions in binary form must reproduce the above
|
|
* copyright notice, this list of conditions and the following
|
|
* disclaimer in the documentation and/or other materials provided
|
|
* with the distribution.
|
|
* * Neither the name of Google Inc. nor the names of its
|
|
* contributors may be used to endorse or promote products derived
|
|
* from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
var base64 = requireBase64();
|
|
|
|
// A single base 64 digit can contain 6 bits of data. For the base 64 variable
|
|
// length quantities we use in the source map spec, the first bit is the sign,
|
|
// the next four bits are the actual value, and the 6th bit is the
|
|
// continuation bit. The continuation bit tells us whether there are more
|
|
// digits in this value following this digit.
|
|
//
|
|
// Continuation
|
|
// | Sign
|
|
// | |
|
|
// V V
|
|
// 101011
|
|
|
|
var VLQ_BASE_SHIFT = 5;
|
|
|
|
// binary: 100000
|
|
var VLQ_BASE = 1 << VLQ_BASE_SHIFT;
|
|
|
|
// binary: 011111
|
|
var VLQ_BASE_MASK = VLQ_BASE - 1;
|
|
|
|
// binary: 100000
|
|
var VLQ_CONTINUATION_BIT = VLQ_BASE;
|
|
|
|
/**
|
|
* Converts from a two-complement value to a value where the sign bit is
|
|
* placed in the least significant bit. For example, as decimals:
|
|
* 1 becomes 2 (10 binary), -1 becomes 3 (11 binary)
|
|
* 2 becomes 4 (100 binary), -2 becomes 5 (101 binary)
|
|
*/
|
|
function toVLQSigned(aValue) {
|
|
return aValue < 0
|
|
? ((-aValue) << 1) + 1
|
|
: (aValue << 1) + 0;
|
|
}
|
|
|
|
/**
|
|
* Converts to a two-complement value from a value where the sign bit is
|
|
* placed in the least significant bit. For example, as decimals:
|
|
* 2 (10 binary) becomes 1, 3 (11 binary) becomes -1
|
|
* 4 (100 binary) becomes 2, 5 (101 binary) becomes -2
|
|
*/
|
|
function fromVLQSigned(aValue) {
|
|
var isNegative = (aValue & 1) === 1;
|
|
var shifted = aValue >> 1;
|
|
return isNegative
|
|
? -shifted
|
|
: shifted;
|
|
}
|
|
|
|
/**
|
|
* Returns the base 64 VLQ encoded value.
|
|
*/
|
|
base64Vlq.encode = function base64VLQ_encode(aValue) {
|
|
var encoded = "";
|
|
var digit;
|
|
|
|
var vlq = toVLQSigned(aValue);
|
|
|
|
do {
|
|
digit = vlq & VLQ_BASE_MASK;
|
|
vlq >>>= VLQ_BASE_SHIFT;
|
|
if (vlq > 0) {
|
|
// There are still more digits in this value, so we must make sure the
|
|
// continuation bit is marked.
|
|
digit |= VLQ_CONTINUATION_BIT;
|
|
}
|
|
encoded += base64.encode(digit);
|
|
} while (vlq > 0);
|
|
|
|
return encoded;
|
|
};
|
|
|
|
/**
|
|
* Decodes the next base 64 VLQ value from the given string and returns the
|
|
* value and the rest of the string via the out parameter.
|
|
*/
|
|
base64Vlq.decode = function base64VLQ_decode(aStr, aIndex, aOutParam) {
|
|
var strLen = aStr.length;
|
|
var result = 0;
|
|
var shift = 0;
|
|
var continuation, digit;
|
|
|
|
do {
|
|
if (aIndex >= strLen) {
|
|
throw new Error("Expected more digits in base 64 VLQ value.");
|
|
}
|
|
|
|
digit = base64.decode(aStr.charCodeAt(aIndex++));
|
|
if (digit === -1) {
|
|
throw new Error("Invalid base64 digit: " + aStr.charAt(aIndex - 1));
|
|
}
|
|
|
|
continuation = !!(digit & VLQ_CONTINUATION_BIT);
|
|
digit &= VLQ_BASE_MASK;
|
|
result = result + (digit << shift);
|
|
shift += VLQ_BASE_SHIFT;
|
|
} while (continuation);
|
|
|
|
aOutParam.value = fromVLQSigned(result);
|
|
aOutParam.rest = aIndex;
|
|
};
|
|
return base64Vlq;
|
|
}
|
|
|
|
var util = {};
|
|
|
|
/* -*- Mode: js; js-indent-level: 2; -*- */
|
|
|
|
var hasRequiredUtil$1;
|
|
|
|
function requireUtil$1 () {
|
|
if (hasRequiredUtil$1) return util;
|
|
hasRequiredUtil$1 = 1;
|
|
(function (exports$1) {
|
|
/*
|
|
* Copyright 2011 Mozilla Foundation and contributors
|
|
* Licensed under the New BSD license. See LICENSE or:
|
|
* http://opensource.org/licenses/BSD-3-Clause
|
|
*/
|
|
|
|
/**
|
|
* This is a helper function for getting values from parameter/options
|
|
* objects.
|
|
*
|
|
* @param args The object we are extracting values from
|
|
* @param name The name of the property we are getting.
|
|
* @param defaultValue An optional value to return if the property is missing
|
|
* from the object. If this is not specified and the property is missing, an
|
|
* error will be thrown.
|
|
*/
|
|
function getArg(aArgs, aName, aDefaultValue) {
|
|
if (aName in aArgs) {
|
|
return aArgs[aName];
|
|
} else if (arguments.length === 3) {
|
|
return aDefaultValue;
|
|
} else {
|
|
throw new Error('"' + aName + '" is a required argument.');
|
|
}
|
|
}
|
|
exports$1.getArg = getArg;
|
|
|
|
var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/;
|
|
var dataUrlRegexp = /^data:.+\,.+$/;
|
|
|
|
function urlParse(aUrl) {
|
|
var match = aUrl.match(urlRegexp);
|
|
if (!match) {
|
|
return null;
|
|
}
|
|
return {
|
|
scheme: match[1],
|
|
auth: match[2],
|
|
host: match[3],
|
|
port: match[4],
|
|
path: match[5]
|
|
};
|
|
}
|
|
exports$1.urlParse = urlParse;
|
|
|
|
function urlGenerate(aParsedUrl) {
|
|
var url = '';
|
|
if (aParsedUrl.scheme) {
|
|
url += aParsedUrl.scheme + ':';
|
|
}
|
|
url += '//';
|
|
if (aParsedUrl.auth) {
|
|
url += aParsedUrl.auth + '@';
|
|
}
|
|
if (aParsedUrl.host) {
|
|
url += aParsedUrl.host;
|
|
}
|
|
if (aParsedUrl.port) {
|
|
url += ":" + aParsedUrl.port;
|
|
}
|
|
if (aParsedUrl.path) {
|
|
url += aParsedUrl.path;
|
|
}
|
|
return url;
|
|
}
|
|
exports$1.urlGenerate = urlGenerate;
|
|
|
|
/**
|
|
* Normalizes a path, or the path portion of a URL:
|
|
*
|
|
* - Replaces consecutive slashes with one slash.
|
|
* - Removes unnecessary '.' parts.
|
|
* - Removes unnecessary '<dir>/..' parts.
|
|
*
|
|
* Based on code in the Node.js 'path' core module.
|
|
*
|
|
* @param aPath The path or url to normalize.
|
|
*/
|
|
function normalize(aPath) {
|
|
var path = aPath;
|
|
var url = urlParse(aPath);
|
|
if (url) {
|
|
if (!url.path) {
|
|
return aPath;
|
|
}
|
|
path = url.path;
|
|
}
|
|
var isAbsolute = exports$1.isAbsolute(path);
|
|
|
|
var parts = path.split(/\/+/);
|
|
for (var part, up = 0, i = parts.length - 1; i >= 0; i--) {
|
|
part = parts[i];
|
|
if (part === '.') {
|
|
parts.splice(i, 1);
|
|
} else if (part === '..') {
|
|
up++;
|
|
} else if (up > 0) {
|
|
if (part === '') {
|
|
// The first part is blank if the path is absolute. Trying to go
|
|
// above the root is a no-op. Therefore we can remove all '..' parts
|
|
// directly after the root.
|
|
parts.splice(i + 1, up);
|
|
up = 0;
|
|
} else {
|
|
parts.splice(i, 2);
|
|
up--;
|
|
}
|
|
}
|
|
}
|
|
path = parts.join('/');
|
|
|
|
if (path === '') {
|
|
path = isAbsolute ? '/' : '.';
|
|
}
|
|
|
|
if (url) {
|
|
url.path = path;
|
|
return urlGenerate(url);
|
|
}
|
|
return path;
|
|
}
|
|
exports$1.normalize = normalize;
|
|
|
|
/**
|
|
* Joins two paths/URLs.
|
|
*
|
|
* @param aRoot The root path or URL.
|
|
* @param aPath The path or URL to be joined with the root.
|
|
*
|
|
* - If aPath is a URL or a data URI, aPath is returned, unless aPath is a
|
|
* scheme-relative URL: Then the scheme of aRoot, if any, is prepended
|
|
* first.
|
|
* - Otherwise aPath is a path. If aRoot is a URL, then its path portion
|
|
* is updated with the result and aRoot is returned. Otherwise the result
|
|
* is returned.
|
|
* - If aPath is absolute, the result is aPath.
|
|
* - Otherwise the two paths are joined with a slash.
|
|
* - Joining for example 'http://' and 'www.example.com' is also supported.
|
|
*/
|
|
function join(aRoot, aPath) {
|
|
if (aRoot === "") {
|
|
aRoot = ".";
|
|
}
|
|
if (aPath === "") {
|
|
aPath = ".";
|
|
}
|
|
var aPathUrl = urlParse(aPath);
|
|
var aRootUrl = urlParse(aRoot);
|
|
if (aRootUrl) {
|
|
aRoot = aRootUrl.path || '/';
|
|
}
|
|
|
|
// `join(foo, '//www.example.org')`
|
|
if (aPathUrl && !aPathUrl.scheme) {
|
|
if (aRootUrl) {
|
|
aPathUrl.scheme = aRootUrl.scheme;
|
|
}
|
|
return urlGenerate(aPathUrl);
|
|
}
|
|
|
|
if (aPathUrl || aPath.match(dataUrlRegexp)) {
|
|
return aPath;
|
|
}
|
|
|
|
// `join('http://', 'www.example.com')`
|
|
if (aRootUrl && !aRootUrl.host && !aRootUrl.path) {
|
|
aRootUrl.host = aPath;
|
|
return urlGenerate(aRootUrl);
|
|
}
|
|
|
|
var joined = aPath.charAt(0) === '/'
|
|
? aPath
|
|
: normalize(aRoot.replace(/\/+$/, '') + '/' + aPath);
|
|
|
|
if (aRootUrl) {
|
|
aRootUrl.path = joined;
|
|
return urlGenerate(aRootUrl);
|
|
}
|
|
return joined;
|
|
}
|
|
exports$1.join = join;
|
|
|
|
exports$1.isAbsolute = function (aPath) {
|
|
return aPath.charAt(0) === '/' || urlRegexp.test(aPath);
|
|
};
|
|
|
|
/**
|
|
* Make a path relative to a URL or another path.
|
|
*
|
|
* @param aRoot The root path or URL.
|
|
* @param aPath The path or URL to be made relative to aRoot.
|
|
*/
|
|
function relative(aRoot, aPath) {
|
|
if (aRoot === "") {
|
|
aRoot = ".";
|
|
}
|
|
|
|
aRoot = aRoot.replace(/\/$/, '');
|
|
|
|
// It is possible for the path to be above the root. In this case, simply
|
|
// checking whether the root is a prefix of the path won't work. Instead, we
|
|
// need to remove components from the root one by one, until either we find
|
|
// a prefix that fits, or we run out of components to remove.
|
|
var level = 0;
|
|
while (aPath.indexOf(aRoot + '/') !== 0) {
|
|
var index = aRoot.lastIndexOf("/");
|
|
if (index < 0) {
|
|
return aPath;
|
|
}
|
|
|
|
// If the only part of the root that is left is the scheme (i.e. http://,
|
|
// file:///, etc.), one or more slashes (/), or simply nothing at all, we
|
|
// have exhausted all components, so the path is not relative to the root.
|
|
aRoot = aRoot.slice(0, index);
|
|
if (aRoot.match(/^([^\/]+:\/)?\/*$/)) {
|
|
return aPath;
|
|
}
|
|
|
|
++level;
|
|
}
|
|
|
|
// Make sure we add a "../" for each component we removed from the root.
|
|
return Array(level + 1).join("../") + aPath.substr(aRoot.length + 1);
|
|
}
|
|
exports$1.relative = relative;
|
|
|
|
var supportsNullProto = (function () {
|
|
var obj = Object.create(null);
|
|
return !('__proto__' in obj);
|
|
}());
|
|
|
|
function identity (s) {
|
|
return s;
|
|
}
|
|
|
|
/**
|
|
* Because behavior goes wacky when you set `__proto__` on objects, we
|
|
* have to prefix all the strings in our set with an arbitrary character.
|
|
*
|
|
* See https://github.com/mozilla/source-map/pull/31 and
|
|
* https://github.com/mozilla/source-map/issues/30
|
|
*
|
|
* @param String aStr
|
|
*/
|
|
function toSetString(aStr) {
|
|
if (isProtoString(aStr)) {
|
|
return '$' + aStr;
|
|
}
|
|
|
|
return aStr;
|
|
}
|
|
exports$1.toSetString = supportsNullProto ? identity : toSetString;
|
|
|
|
function fromSetString(aStr) {
|
|
if (isProtoString(aStr)) {
|
|
return aStr.slice(1);
|
|
}
|
|
|
|
return aStr;
|
|
}
|
|
exports$1.fromSetString = supportsNullProto ? identity : fromSetString;
|
|
|
|
function isProtoString(s) {
|
|
if (!s) {
|
|
return false;
|
|
}
|
|
|
|
var length = s.length;
|
|
|
|
if (length < 9 /* "__proto__".length */) {
|
|
return false;
|
|
}
|
|
|
|
if (s.charCodeAt(length - 1) !== 95 /* '_' */ ||
|
|
s.charCodeAt(length - 2) !== 95 /* '_' */ ||
|
|
s.charCodeAt(length - 3) !== 111 /* 'o' */ ||
|
|
s.charCodeAt(length - 4) !== 116 /* 't' */ ||
|
|
s.charCodeAt(length - 5) !== 111 /* 'o' */ ||
|
|
s.charCodeAt(length - 6) !== 114 /* 'r' */ ||
|
|
s.charCodeAt(length - 7) !== 112 /* 'p' */ ||
|
|
s.charCodeAt(length - 8) !== 95 /* '_' */ ||
|
|
s.charCodeAt(length - 9) !== 95 /* '_' */) {
|
|
return false;
|
|
}
|
|
|
|
for (var i = length - 10; i >= 0; i--) {
|
|
if (s.charCodeAt(i) !== 36 /* '$' */) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Comparator between two mappings where the original positions are compared.
|
|
*
|
|
* Optionally pass in `true` as `onlyCompareGenerated` to consider two
|
|
* mappings with the same original source/line/column, but different generated
|
|
* line and column the same. Useful when searching for a mapping with a
|
|
* stubbed out mapping.
|
|
*/
|
|
function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) {
|
|
var cmp = strcmp(mappingA.source, mappingB.source);
|
|
if (cmp !== 0) {
|
|
return cmp;
|
|
}
|
|
|
|
cmp = mappingA.originalLine - mappingB.originalLine;
|
|
if (cmp !== 0) {
|
|
return cmp;
|
|
}
|
|
|
|
cmp = mappingA.originalColumn - mappingB.originalColumn;
|
|
if (cmp !== 0 || onlyCompareOriginal) {
|
|
return cmp;
|
|
}
|
|
|
|
cmp = mappingA.generatedColumn - mappingB.generatedColumn;
|
|
if (cmp !== 0) {
|
|
return cmp;
|
|
}
|
|
|
|
cmp = mappingA.generatedLine - mappingB.generatedLine;
|
|
if (cmp !== 0) {
|
|
return cmp;
|
|
}
|
|
|
|
return strcmp(mappingA.name, mappingB.name);
|
|
}
|
|
exports$1.compareByOriginalPositions = compareByOriginalPositions;
|
|
|
|
/**
|
|
* Comparator between two mappings with deflated source and name indices where
|
|
* the generated positions are compared.
|
|
*
|
|
* Optionally pass in `true` as `onlyCompareGenerated` to consider two
|
|
* mappings with the same generated line and column, but different
|
|
* source/name/original line and column the same. Useful when searching for a
|
|
* mapping with a stubbed out mapping.
|
|
*/
|
|
function compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGenerated) {
|
|
var cmp = mappingA.generatedLine - mappingB.generatedLine;
|
|
if (cmp !== 0) {
|
|
return cmp;
|
|
}
|
|
|
|
cmp = mappingA.generatedColumn - mappingB.generatedColumn;
|
|
if (cmp !== 0 || onlyCompareGenerated) {
|
|
return cmp;
|
|
}
|
|
|
|
cmp = strcmp(mappingA.source, mappingB.source);
|
|
if (cmp !== 0) {
|
|
return cmp;
|
|
}
|
|
|
|
cmp = mappingA.originalLine - mappingB.originalLine;
|
|
if (cmp !== 0) {
|
|
return cmp;
|
|
}
|
|
|
|
cmp = mappingA.originalColumn - mappingB.originalColumn;
|
|
if (cmp !== 0) {
|
|
return cmp;
|
|
}
|
|
|
|
return strcmp(mappingA.name, mappingB.name);
|
|
}
|
|
exports$1.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated;
|
|
|
|
function strcmp(aStr1, aStr2) {
|
|
if (aStr1 === aStr2) {
|
|
return 0;
|
|
}
|
|
|
|
if (aStr1 === null) {
|
|
return 1; // aStr2 !== null
|
|
}
|
|
|
|
if (aStr2 === null) {
|
|
return -1; // aStr1 !== null
|
|
}
|
|
|
|
if (aStr1 > aStr2) {
|
|
return 1;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* Comparator between two mappings with inflated source and name strings where
|
|
* the generated positions are compared.
|
|
*/
|
|
function compareByGeneratedPositionsInflated(mappingA, mappingB) {
|
|
var cmp = mappingA.generatedLine - mappingB.generatedLine;
|
|
if (cmp !== 0) {
|
|
return cmp;
|
|
}
|
|
|
|
cmp = mappingA.generatedColumn - mappingB.generatedColumn;
|
|
if (cmp !== 0) {
|
|
return cmp;
|
|
}
|
|
|
|
cmp = strcmp(mappingA.source, mappingB.source);
|
|
if (cmp !== 0) {
|
|
return cmp;
|
|
}
|
|
|
|
cmp = mappingA.originalLine - mappingB.originalLine;
|
|
if (cmp !== 0) {
|
|
return cmp;
|
|
}
|
|
|
|
cmp = mappingA.originalColumn - mappingB.originalColumn;
|
|
if (cmp !== 0) {
|
|
return cmp;
|
|
}
|
|
|
|
return strcmp(mappingA.name, mappingB.name);
|
|
}
|
|
exports$1.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated;
|
|
|
|
/**
|
|
* Strip any JSON XSSI avoidance prefix from the string (as documented
|
|
* in the source maps specification), and then parse the string as
|
|
* JSON.
|
|
*/
|
|
function parseSourceMapInput(str) {
|
|
return JSON.parse(str.replace(/^\)]}'[^\n]*\n/, ''));
|
|
}
|
|
exports$1.parseSourceMapInput = parseSourceMapInput;
|
|
|
|
/**
|
|
* Compute the URL of a source given the the source root, the source's
|
|
* URL, and the source map's URL.
|
|
*/
|
|
function computeSourceURL(sourceRoot, sourceURL, sourceMapURL) {
|
|
sourceURL = sourceURL || '';
|
|
|
|
if (sourceRoot) {
|
|
// This follows what Chrome does.
|
|
if (sourceRoot[sourceRoot.length - 1] !== '/' && sourceURL[0] !== '/') {
|
|
sourceRoot += '/';
|
|
}
|
|
// The spec says:
|
|
// Line 4: An optional source root, useful for relocating source
|
|
// files on a server or removing repeated values in the
|
|
// “sources” entry. This value is prepended to the individual
|
|
// entries in the “source” field.
|
|
sourceURL = sourceRoot + sourceURL;
|
|
}
|
|
|
|
// Historically, SourceMapConsumer did not take the sourceMapURL as
|
|
// a parameter. This mode is still somewhat supported, which is why
|
|
// this code block is conditional. However, it's preferable to pass
|
|
// the source map URL to SourceMapConsumer, so that this function
|
|
// can implement the source URL resolution algorithm as outlined in
|
|
// the spec. This block is basically the equivalent of:
|
|
// new URL(sourceURL, sourceMapURL).toString()
|
|
// ... except it avoids using URL, which wasn't available in the
|
|
// older releases of node still supported by this library.
|
|
//
|
|
// The spec says:
|
|
// If the sources are not absolute URLs after prepending of the
|
|
// “sourceRoot”, the sources are resolved relative to the
|
|
// SourceMap (like resolving script src in a html document).
|
|
if (sourceMapURL) {
|
|
var parsed = urlParse(sourceMapURL);
|
|
if (!parsed) {
|
|
throw new Error("sourceMapURL could not be parsed");
|
|
}
|
|
if (parsed.path) {
|
|
// Strip the last path component, but keep the "/".
|
|
var index = parsed.path.lastIndexOf('/');
|
|
if (index >= 0) {
|
|
parsed.path = parsed.path.substring(0, index + 1);
|
|
}
|
|
}
|
|
sourceURL = join(urlGenerate(parsed), sourceURL);
|
|
}
|
|
|
|
return normalize(sourceURL);
|
|
}
|
|
exports$1.computeSourceURL = computeSourceURL;
|
|
} (util));
|
|
return util;
|
|
}
|
|
|
|
var arraySet = {};
|
|
|
|
/* -*- Mode: js; js-indent-level: 2; -*- */
|
|
|
|
var hasRequiredArraySet;
|
|
|
|
function requireArraySet () {
|
|
if (hasRequiredArraySet) return arraySet;
|
|
hasRequiredArraySet = 1;
|
|
/*
|
|
* Copyright 2011 Mozilla Foundation and contributors
|
|
* Licensed under the New BSD license. See LICENSE or:
|
|
* http://opensource.org/licenses/BSD-3-Clause
|
|
*/
|
|
|
|
var util = requireUtil$1();
|
|
var has = Object.prototype.hasOwnProperty;
|
|
var hasNativeMap = typeof Map !== "undefined";
|
|
|
|
/**
|
|
* A data structure which is a combination of an array and a set. Adding a new
|
|
* member is O(1), testing for membership is O(1), and finding the index of an
|
|
* element is O(1). Removing elements from the set is not supported. Only
|
|
* strings are supported for membership.
|
|
*/
|
|
function ArraySet() {
|
|
this._array = [];
|
|
this._set = hasNativeMap ? new Map() : Object.create(null);
|
|
}
|
|
|
|
/**
|
|
* Static method for creating ArraySet instances from an existing array.
|
|
*/
|
|
ArraySet.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) {
|
|
var set = new ArraySet();
|
|
for (var i = 0, len = aArray.length; i < len; i++) {
|
|
set.add(aArray[i], aAllowDuplicates);
|
|
}
|
|
return set;
|
|
};
|
|
|
|
/**
|
|
* Return how many unique items are in this ArraySet. If duplicates have been
|
|
* added, than those do not count towards the size.
|
|
*
|
|
* @returns Number
|
|
*/
|
|
ArraySet.prototype.size = function ArraySet_size() {
|
|
return hasNativeMap ? this._set.size : Object.getOwnPropertyNames(this._set).length;
|
|
};
|
|
|
|
/**
|
|
* Add the given string to this set.
|
|
*
|
|
* @param String aStr
|
|
*/
|
|
ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) {
|
|
var sStr = hasNativeMap ? aStr : util.toSetString(aStr);
|
|
var isDuplicate = hasNativeMap ? this.has(aStr) : has.call(this._set, sStr);
|
|
var idx = this._array.length;
|
|
if (!isDuplicate || aAllowDuplicates) {
|
|
this._array.push(aStr);
|
|
}
|
|
if (!isDuplicate) {
|
|
if (hasNativeMap) {
|
|
this._set.set(aStr, idx);
|
|
} else {
|
|
this._set[sStr] = idx;
|
|
}
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Is the given string a member of this set?
|
|
*
|
|
* @param String aStr
|
|
*/
|
|
ArraySet.prototype.has = function ArraySet_has(aStr) {
|
|
if (hasNativeMap) {
|
|
return this._set.has(aStr);
|
|
} else {
|
|
var sStr = util.toSetString(aStr);
|
|
return has.call(this._set, sStr);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* What is the index of the given string in the array?
|
|
*
|
|
* @param String aStr
|
|
*/
|
|
ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) {
|
|
if (hasNativeMap) {
|
|
var idx = this._set.get(aStr);
|
|
if (idx >= 0) {
|
|
return idx;
|
|
}
|
|
} else {
|
|
var sStr = util.toSetString(aStr);
|
|
if (has.call(this._set, sStr)) {
|
|
return this._set[sStr];
|
|
}
|
|
}
|
|
|
|
throw new Error('"' + aStr + '" is not in the set.');
|
|
};
|
|
|
|
/**
|
|
* What is the element at the given index?
|
|
*
|
|
* @param Number aIdx
|
|
*/
|
|
ArraySet.prototype.at = function ArraySet_at(aIdx) {
|
|
if (aIdx >= 0 && aIdx < this._array.length) {
|
|
return this._array[aIdx];
|
|
}
|
|
throw new Error('No element indexed by ' + aIdx);
|
|
};
|
|
|
|
/**
|
|
* Returns the array representation of this set (which has the proper indices
|
|
* indicated by indexOf). Note that this is a copy of the internal array used
|
|
* for storing the members so that no one can mess with internal state.
|
|
*/
|
|
ArraySet.prototype.toArray = function ArraySet_toArray() {
|
|
return this._array.slice();
|
|
};
|
|
|
|
arraySet.ArraySet = ArraySet;
|
|
return arraySet;
|
|
}
|
|
|
|
var mappingList = {};
|
|
|
|
/* -*- Mode: js; js-indent-level: 2; -*- */
|
|
|
|
var hasRequiredMappingList;
|
|
|
|
function requireMappingList () {
|
|
if (hasRequiredMappingList) return mappingList;
|
|
hasRequiredMappingList = 1;
|
|
/*
|
|
* Copyright 2014 Mozilla Foundation and contributors
|
|
* Licensed under the New BSD license. See LICENSE or:
|
|
* http://opensource.org/licenses/BSD-3-Clause
|
|
*/
|
|
|
|
var util = requireUtil$1();
|
|
|
|
/**
|
|
* Determine whether mappingB is after mappingA with respect to generated
|
|
* position.
|
|
*/
|
|
function generatedPositionAfter(mappingA, mappingB) {
|
|
// Optimized for most common case
|
|
var lineA = mappingA.generatedLine;
|
|
var lineB = mappingB.generatedLine;
|
|
var columnA = mappingA.generatedColumn;
|
|
var columnB = mappingB.generatedColumn;
|
|
return lineB > lineA || lineB == lineA && columnB >= columnA ||
|
|
util.compareByGeneratedPositionsInflated(mappingA, mappingB) <= 0;
|
|
}
|
|
|
|
/**
|
|
* A data structure to provide a sorted view of accumulated mappings in a
|
|
* performance conscious manner. It trades a neglibable overhead in general
|
|
* case for a large speedup in case of mappings being added in order.
|
|
*/
|
|
function MappingList() {
|
|
this._array = [];
|
|
this._sorted = true;
|
|
// Serves as infimum
|
|
this._last = {generatedLine: -1, generatedColumn: 0};
|
|
}
|
|
|
|
/**
|
|
* Iterate through internal items. This method takes the same arguments that
|
|
* `Array.prototype.forEach` takes.
|
|
*
|
|
* NOTE: The order of the mappings is NOT guaranteed.
|
|
*/
|
|
MappingList.prototype.unsortedForEach =
|
|
function MappingList_forEach(aCallback, aThisArg) {
|
|
this._array.forEach(aCallback, aThisArg);
|
|
};
|
|
|
|
/**
|
|
* Add the given source mapping.
|
|
*
|
|
* @param Object aMapping
|
|
*/
|
|
MappingList.prototype.add = function MappingList_add(aMapping) {
|
|
if (generatedPositionAfter(this._last, aMapping)) {
|
|
this._last = aMapping;
|
|
this._array.push(aMapping);
|
|
} else {
|
|
this._sorted = false;
|
|
this._array.push(aMapping);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Returns the flat, sorted array of mappings. The mappings are sorted by
|
|
* generated position.
|
|
*
|
|
* WARNING: This method returns internal data without copying, for
|
|
* performance. The return value must NOT be mutated, and should be treated as
|
|
* an immutable borrow. If you want to take ownership, you must make your own
|
|
* copy.
|
|
*/
|
|
MappingList.prototype.toArray = function MappingList_toArray() {
|
|
if (!this._sorted) {
|
|
this._array.sort(util.compareByGeneratedPositionsInflated);
|
|
this._sorted = true;
|
|
}
|
|
return this._array;
|
|
};
|
|
|
|
mappingList.MappingList = MappingList;
|
|
return mappingList;
|
|
}
|
|
|
|
/* -*- Mode: js; js-indent-level: 2; -*- */
|
|
|
|
var hasRequiredSourceMapGenerator;
|
|
|
|
function requireSourceMapGenerator () {
|
|
if (hasRequiredSourceMapGenerator) return sourceMapGenerator;
|
|
hasRequiredSourceMapGenerator = 1;
|
|
/*
|
|
* Copyright 2011 Mozilla Foundation and contributors
|
|
* Licensed under the New BSD license. See LICENSE or:
|
|
* http://opensource.org/licenses/BSD-3-Clause
|
|
*/
|
|
|
|
var base64VLQ = requireBase64Vlq();
|
|
var util = requireUtil$1();
|
|
var ArraySet = requireArraySet().ArraySet;
|
|
var MappingList = requireMappingList().MappingList;
|
|
|
|
/**
|
|
* An instance of the SourceMapGenerator represents a source map which is
|
|
* being built incrementally. You may pass an object with the following
|
|
* properties:
|
|
*
|
|
* - file: The filename of the generated source.
|
|
* - sourceRoot: A root for all relative URLs in this source map.
|
|
*/
|
|
function SourceMapGenerator(aArgs) {
|
|
if (!aArgs) {
|
|
aArgs = {};
|
|
}
|
|
this._file = util.getArg(aArgs, 'file', null);
|
|
this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null);
|
|
this._skipValidation = util.getArg(aArgs, 'skipValidation', false);
|
|
this._sources = new ArraySet();
|
|
this._names = new ArraySet();
|
|
this._mappings = new MappingList();
|
|
this._sourcesContents = null;
|
|
}
|
|
|
|
SourceMapGenerator.prototype._version = 3;
|
|
|
|
/**
|
|
* Creates a new SourceMapGenerator based on a SourceMapConsumer
|
|
*
|
|
* @param aSourceMapConsumer The SourceMap.
|
|
*/
|
|
SourceMapGenerator.fromSourceMap =
|
|
function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) {
|
|
var sourceRoot = aSourceMapConsumer.sourceRoot;
|
|
var generator = new SourceMapGenerator({
|
|
file: aSourceMapConsumer.file,
|
|
sourceRoot: sourceRoot
|
|
});
|
|
aSourceMapConsumer.eachMapping(function (mapping) {
|
|
var newMapping = {
|
|
generated: {
|
|
line: mapping.generatedLine,
|
|
column: mapping.generatedColumn
|
|
}
|
|
};
|
|
|
|
if (mapping.source != null) {
|
|
newMapping.source = mapping.source;
|
|
if (sourceRoot != null) {
|
|
newMapping.source = util.relative(sourceRoot, newMapping.source);
|
|
}
|
|
|
|
newMapping.original = {
|
|
line: mapping.originalLine,
|
|
column: mapping.originalColumn
|
|
};
|
|
|
|
if (mapping.name != null) {
|
|
newMapping.name = mapping.name;
|
|
}
|
|
}
|
|
|
|
generator.addMapping(newMapping);
|
|
});
|
|
aSourceMapConsumer.sources.forEach(function (sourceFile) {
|
|
var sourceRelative = sourceFile;
|
|
if (sourceRoot !== null) {
|
|
sourceRelative = util.relative(sourceRoot, sourceFile);
|
|
}
|
|
|
|
if (!generator._sources.has(sourceRelative)) {
|
|
generator._sources.add(sourceRelative);
|
|
}
|
|
|
|
var content = aSourceMapConsumer.sourceContentFor(sourceFile);
|
|
if (content != null) {
|
|
generator.setSourceContent(sourceFile, content);
|
|
}
|
|
});
|
|
return generator;
|
|
};
|
|
|
|
/**
|
|
* Add a single mapping from original source line and column to the generated
|
|
* source's line and column for this source map being created. The mapping
|
|
* object should have the following properties:
|
|
*
|
|
* - generated: An object with the generated line and column positions.
|
|
* - original: An object with the original line and column positions.
|
|
* - source: The original source file (relative to the sourceRoot).
|
|
* - name: An optional original token name for this mapping.
|
|
*/
|
|
SourceMapGenerator.prototype.addMapping =
|
|
function SourceMapGenerator_addMapping(aArgs) {
|
|
var generated = util.getArg(aArgs, 'generated');
|
|
var original = util.getArg(aArgs, 'original', null);
|
|
var source = util.getArg(aArgs, 'source', null);
|
|
var name = util.getArg(aArgs, 'name', null);
|
|
|
|
if (!this._skipValidation) {
|
|
this._validateMapping(generated, original, source, name);
|
|
}
|
|
|
|
if (source != null) {
|
|
source = String(source);
|
|
if (!this._sources.has(source)) {
|
|
this._sources.add(source);
|
|
}
|
|
}
|
|
|
|
if (name != null) {
|
|
name = String(name);
|
|
if (!this._names.has(name)) {
|
|
this._names.add(name);
|
|
}
|
|
}
|
|
|
|
this._mappings.add({
|
|
generatedLine: generated.line,
|
|
generatedColumn: generated.column,
|
|
originalLine: original != null && original.line,
|
|
originalColumn: original != null && original.column,
|
|
source: source,
|
|
name: name
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Set the source content for a source file.
|
|
*/
|
|
SourceMapGenerator.prototype.setSourceContent =
|
|
function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) {
|
|
var source = aSourceFile;
|
|
if (this._sourceRoot != null) {
|
|
source = util.relative(this._sourceRoot, source);
|
|
}
|
|
|
|
if (aSourceContent != null) {
|
|
// Add the source content to the _sourcesContents map.
|
|
// Create a new _sourcesContents map if the property is null.
|
|
if (!this._sourcesContents) {
|
|
this._sourcesContents = Object.create(null);
|
|
}
|
|
this._sourcesContents[util.toSetString(source)] = aSourceContent;
|
|
} else if (this._sourcesContents) {
|
|
// Remove the source file from the _sourcesContents map.
|
|
// If the _sourcesContents map is empty, set the property to null.
|
|
delete this._sourcesContents[util.toSetString(source)];
|
|
if (Object.keys(this._sourcesContents).length === 0) {
|
|
this._sourcesContents = null;
|
|
}
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Applies the mappings of a sub-source-map for a specific source file to the
|
|
* source map being generated. Each mapping to the supplied source file is
|
|
* rewritten using the supplied source map. Note: The resolution for the
|
|
* resulting mappings is the minimium of this map and the supplied map.
|
|
*
|
|
* @param aSourceMapConsumer The source map to be applied.
|
|
* @param aSourceFile Optional. The filename of the source file.
|
|
* If omitted, SourceMapConsumer's file property will be used.
|
|
* @param aSourceMapPath Optional. The dirname of the path to the source map
|
|
* to be applied. If relative, it is relative to the SourceMapConsumer.
|
|
* This parameter is needed when the two source maps aren't in the same
|
|
* directory, and the source map to be applied contains relative source
|
|
* paths. If so, those relative source paths need to be rewritten
|
|
* relative to the SourceMapGenerator.
|
|
*/
|
|
SourceMapGenerator.prototype.applySourceMap =
|
|
function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile, aSourceMapPath) {
|
|
var sourceFile = aSourceFile;
|
|
// If aSourceFile is omitted, we will use the file property of the SourceMap
|
|
if (aSourceFile == null) {
|
|
if (aSourceMapConsumer.file == null) {
|
|
throw new Error(
|
|
'SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, ' +
|
|
'or the source map\'s "file" property. Both were omitted.'
|
|
);
|
|
}
|
|
sourceFile = aSourceMapConsumer.file;
|
|
}
|
|
var sourceRoot = this._sourceRoot;
|
|
// Make "sourceFile" relative if an absolute Url is passed.
|
|
if (sourceRoot != null) {
|
|
sourceFile = util.relative(sourceRoot, sourceFile);
|
|
}
|
|
// Applying the SourceMap can add and remove items from the sources and
|
|
// the names array.
|
|
var newSources = new ArraySet();
|
|
var newNames = new ArraySet();
|
|
|
|
// Find mappings for the "sourceFile"
|
|
this._mappings.unsortedForEach(function (mapping) {
|
|
if (mapping.source === sourceFile && mapping.originalLine != null) {
|
|
// Check if it can be mapped by the source map, then update the mapping.
|
|
var original = aSourceMapConsumer.originalPositionFor({
|
|
line: mapping.originalLine,
|
|
column: mapping.originalColumn
|
|
});
|
|
if (original.source != null) {
|
|
// Copy mapping
|
|
mapping.source = original.source;
|
|
if (aSourceMapPath != null) {
|
|
mapping.source = util.join(aSourceMapPath, mapping.source);
|
|
}
|
|
if (sourceRoot != null) {
|
|
mapping.source = util.relative(sourceRoot, mapping.source);
|
|
}
|
|
mapping.originalLine = original.line;
|
|
mapping.originalColumn = original.column;
|
|
if (original.name != null) {
|
|
mapping.name = original.name;
|
|
}
|
|
}
|
|
}
|
|
|
|
var source = mapping.source;
|
|
if (source != null && !newSources.has(source)) {
|
|
newSources.add(source);
|
|
}
|
|
|
|
var name = mapping.name;
|
|
if (name != null && !newNames.has(name)) {
|
|
newNames.add(name);
|
|
}
|
|
|
|
}, this);
|
|
this._sources = newSources;
|
|
this._names = newNames;
|
|
|
|
// Copy sourcesContents of applied map.
|
|
aSourceMapConsumer.sources.forEach(function (sourceFile) {
|
|
var content = aSourceMapConsumer.sourceContentFor(sourceFile);
|
|
if (content != null) {
|
|
if (aSourceMapPath != null) {
|
|
sourceFile = util.join(aSourceMapPath, sourceFile);
|
|
}
|
|
if (sourceRoot != null) {
|
|
sourceFile = util.relative(sourceRoot, sourceFile);
|
|
}
|
|
this.setSourceContent(sourceFile, content);
|
|
}
|
|
}, this);
|
|
};
|
|
|
|
/**
|
|
* A mapping can have one of the three levels of data:
|
|
*
|
|
* 1. Just the generated position.
|
|
* 2. The Generated position, original position, and original source.
|
|
* 3. Generated and original position, original source, as well as a name
|
|
* token.
|
|
*
|
|
* To maintain consistency, we validate that any new mapping being added falls
|
|
* in to one of these categories.
|
|
*/
|
|
SourceMapGenerator.prototype._validateMapping =
|
|
function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource,
|
|
aName) {
|
|
// When aOriginal is truthy but has empty values for .line and .column,
|
|
// it is most likely a programmer error. In this case we throw a very
|
|
// specific error message to try to guide them the right way.
|
|
// For example: https://github.com/Polymer/polymer-bundler/pull/519
|
|
if (aOriginal && typeof aOriginal.line !== 'number' && typeof aOriginal.column !== 'number') {
|
|
throw new Error(
|
|
'original.line and original.column are not numbers -- you probably meant to omit ' +
|
|
'the original mapping entirely and only map the generated position. If so, pass ' +
|
|
'null for the original mapping instead of an object with empty or null values.'
|
|
);
|
|
}
|
|
|
|
if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
|
|
&& aGenerated.line > 0 && aGenerated.column >= 0
|
|
&& !aOriginal && !aSource && !aName) {
|
|
// Case 1.
|
|
return;
|
|
}
|
|
else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
|
|
&& aOriginal && 'line' in aOriginal && 'column' in aOriginal
|
|
&& aGenerated.line > 0 && aGenerated.column >= 0
|
|
&& aOriginal.line > 0 && aOriginal.column >= 0
|
|
&& aSource) {
|
|
// Cases 2 and 3.
|
|
return;
|
|
}
|
|
else {
|
|
throw new Error('Invalid mapping: ' + JSON.stringify({
|
|
generated: aGenerated,
|
|
source: aSource,
|
|
original: aOriginal,
|
|
name: aName
|
|
}));
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Serialize the accumulated mappings in to the stream of base 64 VLQs
|
|
* specified by the source map format.
|
|
*/
|
|
SourceMapGenerator.prototype._serializeMappings =
|
|
function SourceMapGenerator_serializeMappings() {
|
|
var previousGeneratedColumn = 0;
|
|
var previousGeneratedLine = 1;
|
|
var previousOriginalColumn = 0;
|
|
var previousOriginalLine = 0;
|
|
var previousName = 0;
|
|
var previousSource = 0;
|
|
var result = '';
|
|
var next;
|
|
var mapping;
|
|
var nameIdx;
|
|
var sourceIdx;
|
|
|
|
var mappings = this._mappings.toArray();
|
|
for (var i = 0, len = mappings.length; i < len; i++) {
|
|
mapping = mappings[i];
|
|
next = '';
|
|
|
|
if (mapping.generatedLine !== previousGeneratedLine) {
|
|
previousGeneratedColumn = 0;
|
|
while (mapping.generatedLine !== previousGeneratedLine) {
|
|
next += ';';
|
|
previousGeneratedLine++;
|
|
}
|
|
}
|
|
else {
|
|
if (i > 0) {
|
|
if (!util.compareByGeneratedPositionsInflated(mapping, mappings[i - 1])) {
|
|
continue;
|
|
}
|
|
next += ',';
|
|
}
|
|
}
|
|
|
|
next += base64VLQ.encode(mapping.generatedColumn
|
|
- previousGeneratedColumn);
|
|
previousGeneratedColumn = mapping.generatedColumn;
|
|
|
|
if (mapping.source != null) {
|
|
sourceIdx = this._sources.indexOf(mapping.source);
|
|
next += base64VLQ.encode(sourceIdx - previousSource);
|
|
previousSource = sourceIdx;
|
|
|
|
// lines are stored 0-based in SourceMap spec version 3
|
|
next += base64VLQ.encode(mapping.originalLine - 1
|
|
- previousOriginalLine);
|
|
previousOriginalLine = mapping.originalLine - 1;
|
|
|
|
next += base64VLQ.encode(mapping.originalColumn
|
|
- previousOriginalColumn);
|
|
previousOriginalColumn = mapping.originalColumn;
|
|
|
|
if (mapping.name != null) {
|
|
nameIdx = this._names.indexOf(mapping.name);
|
|
next += base64VLQ.encode(nameIdx - previousName);
|
|
previousName = nameIdx;
|
|
}
|
|
}
|
|
|
|
result += next;
|
|
}
|
|
|
|
return result;
|
|
};
|
|
|
|
SourceMapGenerator.prototype._generateSourcesContent =
|
|
function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) {
|
|
return aSources.map(function (source) {
|
|
if (!this._sourcesContents) {
|
|
return null;
|
|
}
|
|
if (aSourceRoot != null) {
|
|
source = util.relative(aSourceRoot, source);
|
|
}
|
|
var key = util.toSetString(source);
|
|
return Object.prototype.hasOwnProperty.call(this._sourcesContents, key)
|
|
? this._sourcesContents[key]
|
|
: null;
|
|
}, this);
|
|
};
|
|
|
|
/**
|
|
* Externalize the source map.
|
|
*/
|
|
SourceMapGenerator.prototype.toJSON =
|
|
function SourceMapGenerator_toJSON() {
|
|
var map = {
|
|
version: this._version,
|
|
sources: this._sources.toArray(),
|
|
names: this._names.toArray(),
|
|
mappings: this._serializeMappings()
|
|
};
|
|
if (this._file != null) {
|
|
map.file = this._file;
|
|
}
|
|
if (this._sourceRoot != null) {
|
|
map.sourceRoot = this._sourceRoot;
|
|
}
|
|
if (this._sourcesContents) {
|
|
map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot);
|
|
}
|
|
|
|
return map;
|
|
};
|
|
|
|
/**
|
|
* Render the source map being generated to a string.
|
|
*/
|
|
SourceMapGenerator.prototype.toString =
|
|
function SourceMapGenerator_toString() {
|
|
return JSON.stringify(this.toJSON());
|
|
};
|
|
|
|
sourceMapGenerator.SourceMapGenerator = SourceMapGenerator;
|
|
return sourceMapGenerator;
|
|
}
|
|
|
|
var sourceMapConsumer = {};
|
|
|
|
var binarySearch = {};
|
|
|
|
/* -*- Mode: js; js-indent-level: 2; -*- */
|
|
|
|
var hasRequiredBinarySearch;
|
|
|
|
function requireBinarySearch () {
|
|
if (hasRequiredBinarySearch) return binarySearch;
|
|
hasRequiredBinarySearch = 1;
|
|
(function (exports$1) {
|
|
/*
|
|
* Copyright 2011 Mozilla Foundation and contributors
|
|
* Licensed under the New BSD license. See LICENSE or:
|
|
* http://opensource.org/licenses/BSD-3-Clause
|
|
*/
|
|
|
|
exports$1.GREATEST_LOWER_BOUND = 1;
|
|
exports$1.LEAST_UPPER_BOUND = 2;
|
|
|
|
/**
|
|
* Recursive implementation of binary search.
|
|
*
|
|
* @param aLow Indices here and lower do not contain the needle.
|
|
* @param aHigh Indices here and higher do not contain the needle.
|
|
* @param aNeedle The element being searched for.
|
|
* @param aHaystack The non-empty array being searched.
|
|
* @param aCompare Function which takes two elements and returns -1, 0, or 1.
|
|
* @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or
|
|
* 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the
|
|
* closest element that is smaller than or greater than the one we are
|
|
* searching for, respectively, if the exact element cannot be found.
|
|
*/
|
|
function recursiveSearch(aLow, aHigh, aNeedle, aHaystack, aCompare, aBias) {
|
|
// This function terminates when one of the following is true:
|
|
//
|
|
// 1. We find the exact element we are looking for.
|
|
//
|
|
// 2. We did not find the exact element, but we can return the index of
|
|
// the next-closest element.
|
|
//
|
|
// 3. We did not find the exact element, and there is no next-closest
|
|
// element than the one we are searching for, so we return -1.
|
|
var mid = Math.floor((aHigh - aLow) / 2) + aLow;
|
|
var cmp = aCompare(aNeedle, aHaystack[mid], true);
|
|
if (cmp === 0) {
|
|
// Found the element we are looking for.
|
|
return mid;
|
|
}
|
|
else if (cmp > 0) {
|
|
// Our needle is greater than aHaystack[mid].
|
|
if (aHigh - mid > 1) {
|
|
// The element is in the upper half.
|
|
return recursiveSearch(mid, aHigh, aNeedle, aHaystack, aCompare, aBias);
|
|
}
|
|
|
|
// The exact needle element was not found in this haystack. Determine if
|
|
// we are in termination case (3) or (2) and return the appropriate thing.
|
|
if (aBias == exports$1.LEAST_UPPER_BOUND) {
|
|
return aHigh < aHaystack.length ? aHigh : -1;
|
|
} else {
|
|
return mid;
|
|
}
|
|
}
|
|
else {
|
|
// Our needle is less than aHaystack[mid].
|
|
if (mid - aLow > 1) {
|
|
// The element is in the lower half.
|
|
return recursiveSearch(aLow, mid, aNeedle, aHaystack, aCompare, aBias);
|
|
}
|
|
|
|
// we are in termination case (3) or (2) and return the appropriate thing.
|
|
if (aBias == exports$1.LEAST_UPPER_BOUND) {
|
|
return mid;
|
|
} else {
|
|
return aLow < 0 ? -1 : aLow;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* This is an implementation of binary search which will always try and return
|
|
* the index of the closest element if there is no exact hit. This is because
|
|
* mappings between original and generated line/col pairs are single points,
|
|
* and there is an implicit region between each of them, so a miss just means
|
|
* that you aren't on the very start of a region.
|
|
*
|
|
* @param aNeedle The element you are looking for.
|
|
* @param aHaystack The array that is being searched.
|
|
* @param aCompare A function which takes the needle and an element in the
|
|
* array and returns -1, 0, or 1 depending on whether the needle is less
|
|
* than, equal to, or greater than the element, respectively.
|
|
* @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or
|
|
* 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the
|
|
* closest element that is smaller than or greater than the one we are
|
|
* searching for, respectively, if the exact element cannot be found.
|
|
* Defaults to 'binarySearch.GREATEST_LOWER_BOUND'.
|
|
*/
|
|
exports$1.search = function search(aNeedle, aHaystack, aCompare, aBias) {
|
|
if (aHaystack.length === 0) {
|
|
return -1;
|
|
}
|
|
|
|
var index = recursiveSearch(-1, aHaystack.length, aNeedle, aHaystack,
|
|
aCompare, aBias || exports$1.GREATEST_LOWER_BOUND);
|
|
if (index < 0) {
|
|
return -1;
|
|
}
|
|
|
|
// We have found either the exact element, or the next-closest element than
|
|
// the one we are searching for. However, there may be more than one such
|
|
// element. Make sure we always return the smallest of these.
|
|
while (index - 1 >= 0) {
|
|
if (aCompare(aHaystack[index], aHaystack[index - 1], true) !== 0) {
|
|
break;
|
|
}
|
|
--index;
|
|
}
|
|
|
|
return index;
|
|
};
|
|
} (binarySearch));
|
|
return binarySearch;
|
|
}
|
|
|
|
var quickSort = {};
|
|
|
|
/* -*- Mode: js; js-indent-level: 2; -*- */
|
|
|
|
var hasRequiredQuickSort;
|
|
|
|
function requireQuickSort () {
|
|
if (hasRequiredQuickSort) return quickSort;
|
|
hasRequiredQuickSort = 1;
|
|
/*
|
|
* Copyright 2011 Mozilla Foundation and contributors
|
|
* Licensed under the New BSD license. See LICENSE or:
|
|
* http://opensource.org/licenses/BSD-3-Clause
|
|
*/
|
|
|
|
// It turns out that some (most?) JavaScript engines don't self-host
|
|
// `Array.prototype.sort`. This makes sense because C++ will likely remain
|
|
// faster than JS when doing raw CPU-intensive sorting. However, when using a
|
|
// custom comparator function, calling back and forth between the VM's C++ and
|
|
// JIT'd JS is rather slow *and* loses JIT type information, resulting in
|
|
// worse generated code for the comparator function than would be optimal. In
|
|
// fact, when sorting with a comparator, these costs outweigh the benefits of
|
|
// sorting in C++. By using our own JS-implemented Quick Sort (below), we get
|
|
// a ~3500ms mean speed-up in `bench/bench.html`.
|
|
|
|
/**
|
|
* Swap the elements indexed by `x` and `y` in the array `ary`.
|
|
*
|
|
* @param {Array} ary
|
|
* The array.
|
|
* @param {Number} x
|
|
* The index of the first item.
|
|
* @param {Number} y
|
|
* The index of the second item.
|
|
*/
|
|
function swap(ary, x, y) {
|
|
var temp = ary[x];
|
|
ary[x] = ary[y];
|
|
ary[y] = temp;
|
|
}
|
|
|
|
/**
|
|
* Returns a random integer within the range `low .. high` inclusive.
|
|
*
|
|
* @param {Number} low
|
|
* The lower bound on the range.
|
|
* @param {Number} high
|
|
* The upper bound on the range.
|
|
*/
|
|
function randomIntInRange(low, high) {
|
|
return Math.round(low + (Math.random() * (high - low)));
|
|
}
|
|
|
|
/**
|
|
* The Quick Sort algorithm.
|
|
*
|
|
* @param {Array} ary
|
|
* An array to sort.
|
|
* @param {function} comparator
|
|
* Function to use to compare two items.
|
|
* @param {Number} p
|
|
* Start index of the array
|
|
* @param {Number} r
|
|
* End index of the array
|
|
*/
|
|
function doQuickSort(ary, comparator, p, r) {
|
|
// If our lower bound is less than our upper bound, we (1) partition the
|
|
// array into two pieces and (2) recurse on each half. If it is not, this is
|
|
// the empty array and our base case.
|
|
|
|
if (p < r) {
|
|
// (1) Partitioning.
|
|
//
|
|
// The partitioning chooses a pivot between `p` and `r` and moves all
|
|
// elements that are less than or equal to the pivot to the before it, and
|
|
// all the elements that are greater than it after it. The effect is that
|
|
// once partition is done, the pivot is in the exact place it will be when
|
|
// the array is put in sorted order, and it will not need to be moved
|
|
// again. This runs in O(n) time.
|
|
|
|
// Always choose a random pivot so that an input array which is reverse
|
|
// sorted does not cause O(n^2) running time.
|
|
var pivotIndex = randomIntInRange(p, r);
|
|
var i = p - 1;
|
|
|
|
swap(ary, pivotIndex, r);
|
|
var pivot = ary[r];
|
|
|
|
// Immediately after `j` is incremented in this loop, the following hold
|
|
// true:
|
|
//
|
|
// * Every element in `ary[p .. i]` is less than or equal to the pivot.
|
|
//
|
|
// * Every element in `ary[i+1 .. j-1]` is greater than the pivot.
|
|
for (var j = p; j < r; j++) {
|
|
if (comparator(ary[j], pivot) <= 0) {
|
|
i += 1;
|
|
swap(ary, i, j);
|
|
}
|
|
}
|
|
|
|
swap(ary, i + 1, j);
|
|
var q = i + 1;
|
|
|
|
// (2) Recurse on each half.
|
|
|
|
doQuickSort(ary, comparator, p, q - 1);
|
|
doQuickSort(ary, comparator, q + 1, r);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sort the given array in-place with the given comparator function.
|
|
*
|
|
* @param {Array} ary
|
|
* An array to sort.
|
|
* @param {function} comparator
|
|
* Function to use to compare two items.
|
|
*/
|
|
quickSort.quickSort = function (ary, comparator) {
|
|
doQuickSort(ary, comparator, 0, ary.length - 1);
|
|
};
|
|
return quickSort;
|
|
}
|
|
|
|
/* -*- Mode: js; js-indent-level: 2; -*- */
|
|
|
|
var hasRequiredSourceMapConsumer;
|
|
|
|
function requireSourceMapConsumer () {
|
|
if (hasRequiredSourceMapConsumer) return sourceMapConsumer;
|
|
hasRequiredSourceMapConsumer = 1;
|
|
/*
|
|
* Copyright 2011 Mozilla Foundation and contributors
|
|
* Licensed under the New BSD license. See LICENSE or:
|
|
* http://opensource.org/licenses/BSD-3-Clause
|
|
*/
|
|
|
|
var util = requireUtil$1();
|
|
var binarySearch = requireBinarySearch();
|
|
var ArraySet = requireArraySet().ArraySet;
|
|
var base64VLQ = requireBase64Vlq();
|
|
var quickSort = requireQuickSort().quickSort;
|
|
|
|
function SourceMapConsumer(aSourceMap, aSourceMapURL) {
|
|
var sourceMap = aSourceMap;
|
|
if (typeof aSourceMap === 'string') {
|
|
sourceMap = util.parseSourceMapInput(aSourceMap);
|
|
}
|
|
|
|
return sourceMap.sections != null
|
|
? new IndexedSourceMapConsumer(sourceMap, aSourceMapURL)
|
|
: new BasicSourceMapConsumer(sourceMap, aSourceMapURL);
|
|
}
|
|
|
|
SourceMapConsumer.fromSourceMap = function(aSourceMap, aSourceMapURL) {
|
|
return BasicSourceMapConsumer.fromSourceMap(aSourceMap, aSourceMapURL);
|
|
};
|
|
|
|
/**
|
|
* The version of the source mapping spec that we are consuming.
|
|
*/
|
|
SourceMapConsumer.prototype._version = 3;
|
|
|
|
// `__generatedMappings` and `__originalMappings` are arrays that hold the
|
|
// parsed mapping coordinates from the source map's "mappings" attribute. They
|
|
// are lazily instantiated, accessed via the `_generatedMappings` and
|
|
// `_originalMappings` getters respectively, and we only parse the mappings
|
|
// and create these arrays once queried for a source location. We jump through
|
|
// these hoops because there can be many thousands of mappings, and parsing
|
|
// them is expensive, so we only want to do it if we must.
|
|
//
|
|
// Each object in the arrays is of the form:
|
|
//
|
|
// {
|
|
// generatedLine: The line number in the generated code,
|
|
// generatedColumn: The column number in the generated code,
|
|
// source: The path to the original source file that generated this
|
|
// chunk of code,
|
|
// originalLine: The line number in the original source that
|
|
// corresponds to this chunk of generated code,
|
|
// originalColumn: The column number in the original source that
|
|
// corresponds to this chunk of generated code,
|
|
// name: The name of the original symbol which generated this chunk of
|
|
// code.
|
|
// }
|
|
//
|
|
// All properties except for `generatedLine` and `generatedColumn` can be
|
|
// `null`.
|
|
//
|
|
// `_generatedMappings` is ordered by the generated positions.
|
|
//
|
|
// `_originalMappings` is ordered by the original positions.
|
|
|
|
SourceMapConsumer.prototype.__generatedMappings = null;
|
|
Object.defineProperty(SourceMapConsumer.prototype, '_generatedMappings', {
|
|
configurable: true,
|
|
enumerable: true,
|
|
get: function () {
|
|
if (!this.__generatedMappings) {
|
|
this._parseMappings(this._mappings, this.sourceRoot);
|
|
}
|
|
|
|
return this.__generatedMappings;
|
|
}
|
|
});
|
|
|
|
SourceMapConsumer.prototype.__originalMappings = null;
|
|
Object.defineProperty(SourceMapConsumer.prototype, '_originalMappings', {
|
|
configurable: true,
|
|
enumerable: true,
|
|
get: function () {
|
|
if (!this.__originalMappings) {
|
|
this._parseMappings(this._mappings, this.sourceRoot);
|
|
}
|
|
|
|
return this.__originalMappings;
|
|
}
|
|
});
|
|
|
|
SourceMapConsumer.prototype._charIsMappingSeparator =
|
|
function SourceMapConsumer_charIsMappingSeparator(aStr, index) {
|
|
var c = aStr.charAt(index);
|
|
return c === ";" || c === ",";
|
|
};
|
|
|
|
/**
|
|
* Parse the mappings in a string in to a data structure which we can easily
|
|
* query (the ordered arrays in the `this.__generatedMappings` and
|
|
* `this.__originalMappings` properties).
|
|
*/
|
|
SourceMapConsumer.prototype._parseMappings =
|
|
function SourceMapConsumer_parseMappings(aStr, aSourceRoot) {
|
|
throw new Error("Subclasses must implement _parseMappings");
|
|
};
|
|
|
|
SourceMapConsumer.GENERATED_ORDER = 1;
|
|
SourceMapConsumer.ORIGINAL_ORDER = 2;
|
|
|
|
SourceMapConsumer.GREATEST_LOWER_BOUND = 1;
|
|
SourceMapConsumer.LEAST_UPPER_BOUND = 2;
|
|
|
|
/**
|
|
* Iterate over each mapping between an original source/line/column and a
|
|
* generated line/column in this source map.
|
|
*
|
|
* @param Function aCallback
|
|
* The function that is called with each mapping.
|
|
* @param Object aContext
|
|
* Optional. If specified, this object will be the value of `this` every
|
|
* time that `aCallback` is called.
|
|
* @param aOrder
|
|
* Either `SourceMapConsumer.GENERATED_ORDER` or
|
|
* `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to
|
|
* iterate over the mappings sorted by the generated file's line/column
|
|
* order or the original's source/line/column order, respectively. Defaults to
|
|
* `SourceMapConsumer.GENERATED_ORDER`.
|
|
*/
|
|
SourceMapConsumer.prototype.eachMapping =
|
|
function SourceMapConsumer_eachMapping(aCallback, aContext, aOrder) {
|
|
var context = aContext || null;
|
|
var order = aOrder || SourceMapConsumer.GENERATED_ORDER;
|
|
|
|
var mappings;
|
|
switch (order) {
|
|
case SourceMapConsumer.GENERATED_ORDER:
|
|
mappings = this._generatedMappings;
|
|
break;
|
|
case SourceMapConsumer.ORIGINAL_ORDER:
|
|
mappings = this._originalMappings;
|
|
break;
|
|
default:
|
|
throw new Error("Unknown order of iteration.");
|
|
}
|
|
|
|
var sourceRoot = this.sourceRoot;
|
|
mappings.map(function (mapping) {
|
|
var source = mapping.source === null ? null : this._sources.at(mapping.source);
|
|
source = util.computeSourceURL(sourceRoot, source, this._sourceMapURL);
|
|
return {
|
|
source: source,
|
|
generatedLine: mapping.generatedLine,
|
|
generatedColumn: mapping.generatedColumn,
|
|
originalLine: mapping.originalLine,
|
|
originalColumn: mapping.originalColumn,
|
|
name: mapping.name === null ? null : this._names.at(mapping.name)
|
|
};
|
|
}, this).forEach(aCallback, context);
|
|
};
|
|
|
|
/**
|
|
* Returns all generated line and column information for the original source,
|
|
* line, and column provided. If no column is provided, returns all mappings
|
|
* corresponding to a either the line we are searching for or the next
|
|
* closest line that has any mappings. Otherwise, returns all mappings
|
|
* corresponding to the given line and either the column we are searching for
|
|
* or the next closest column that has any offsets.
|
|
*
|
|
* The only argument is an object with the following properties:
|
|
*
|
|
* - source: The filename of the original source.
|
|
* - line: The line number in the original source. The line number is 1-based.
|
|
* - column: Optional. the column number in the original source.
|
|
* The column number is 0-based.
|
|
*
|
|
* and an array of objects is returned, each with the following properties:
|
|
*
|
|
* - line: The line number in the generated source, or null. The
|
|
* line number is 1-based.
|
|
* - column: The column number in the generated source, or null.
|
|
* The column number is 0-based.
|
|
*/
|
|
SourceMapConsumer.prototype.allGeneratedPositionsFor =
|
|
function SourceMapConsumer_allGeneratedPositionsFor(aArgs) {
|
|
var line = util.getArg(aArgs, 'line');
|
|
|
|
// When there is no exact match, BasicSourceMapConsumer.prototype._findMapping
|
|
// returns the index of the closest mapping less than the needle. By
|
|
// setting needle.originalColumn to 0, we thus find the last mapping for
|
|
// the given line, provided such a mapping exists.
|
|
var needle = {
|
|
source: util.getArg(aArgs, 'source'),
|
|
originalLine: line,
|
|
originalColumn: util.getArg(aArgs, 'column', 0)
|
|
};
|
|
|
|
needle.source = this._findSourceIndex(needle.source);
|
|
if (needle.source < 0) {
|
|
return [];
|
|
}
|
|
|
|
var mappings = [];
|
|
|
|
var index = this._findMapping(needle,
|
|
this._originalMappings,
|
|
"originalLine",
|
|
"originalColumn",
|
|
util.compareByOriginalPositions,
|
|
binarySearch.LEAST_UPPER_BOUND);
|
|
if (index >= 0) {
|
|
var mapping = this._originalMappings[index];
|
|
|
|
if (aArgs.column === undefined) {
|
|
var originalLine = mapping.originalLine;
|
|
|
|
// Iterate until either we run out of mappings, or we run into
|
|
// a mapping for a different line than the one we found. Since
|
|
// mappings are sorted, this is guaranteed to find all mappings for
|
|
// the line we found.
|
|
while (mapping && mapping.originalLine === originalLine) {
|
|
mappings.push({
|
|
line: util.getArg(mapping, 'generatedLine', null),
|
|
column: util.getArg(mapping, 'generatedColumn', null),
|
|
lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null)
|
|
});
|
|
|
|
mapping = this._originalMappings[++index];
|
|
}
|
|
} else {
|
|
var originalColumn = mapping.originalColumn;
|
|
|
|
// Iterate until either we run out of mappings, or we run into
|
|
// a mapping for a different line than the one we were searching for.
|
|
// Since mappings are sorted, this is guaranteed to find all mappings for
|
|
// the line we are searching for.
|
|
while (mapping &&
|
|
mapping.originalLine === line &&
|
|
mapping.originalColumn == originalColumn) {
|
|
mappings.push({
|
|
line: util.getArg(mapping, 'generatedLine', null),
|
|
column: util.getArg(mapping, 'generatedColumn', null),
|
|
lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null)
|
|
});
|
|
|
|
mapping = this._originalMappings[++index];
|
|
}
|
|
}
|
|
}
|
|
|
|
return mappings;
|
|
};
|
|
|
|
sourceMapConsumer.SourceMapConsumer = SourceMapConsumer;
|
|
|
|
/**
|
|
* A BasicSourceMapConsumer instance represents a parsed source map which we can
|
|
* query for information about the original file positions by giving it a file
|
|
* position in the generated source.
|
|
*
|
|
* The first parameter is the raw source map (either as a JSON string, or
|
|
* already parsed to an object). According to the spec, source maps have the
|
|
* following attributes:
|
|
*
|
|
* - version: Which version of the source map spec this map is following.
|
|
* - sources: An array of URLs to the original source files.
|
|
* - names: An array of identifiers which can be referrenced by individual mappings.
|
|
* - sourceRoot: Optional. The URL root from which all sources are relative.
|
|
* - sourcesContent: Optional. An array of contents of the original source files.
|
|
* - mappings: A string of base64 VLQs which contain the actual mappings.
|
|
* - file: Optional. The generated file this source map is associated with.
|
|
*
|
|
* Here is an example source map, taken from the source map spec[0]:
|
|
*
|
|
* {
|
|
* version : 3,
|
|
* file: "out.js",
|
|
* sourceRoot : "",
|
|
* sources: ["foo.js", "bar.js"],
|
|
* names: ["src", "maps", "are", "fun"],
|
|
* mappings: "AA,AB;;ABCDE;"
|
|
* }
|
|
*
|
|
* The second parameter, if given, is a string whose value is the URL
|
|
* at which the source map was found. This URL is used to compute the
|
|
* sources array.
|
|
*
|
|
* [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1#
|
|
*/
|
|
function BasicSourceMapConsumer(aSourceMap, aSourceMapURL) {
|
|
var sourceMap = aSourceMap;
|
|
if (typeof aSourceMap === 'string') {
|
|
sourceMap = util.parseSourceMapInput(aSourceMap);
|
|
}
|
|
|
|
var version = util.getArg(sourceMap, 'version');
|
|
var sources = util.getArg(sourceMap, 'sources');
|
|
// Sass 3.3 leaves out the 'names' array, so we deviate from the spec (which
|
|
// requires the array) to play nice here.
|
|
var names = util.getArg(sourceMap, 'names', []);
|
|
var sourceRoot = util.getArg(sourceMap, 'sourceRoot', null);
|
|
var sourcesContent = util.getArg(sourceMap, 'sourcesContent', null);
|
|
var mappings = util.getArg(sourceMap, 'mappings');
|
|
var file = util.getArg(sourceMap, 'file', null);
|
|
|
|
// Once again, Sass deviates from the spec and supplies the version as a
|
|
// string rather than a number, so we use loose equality checking here.
|
|
if (version != this._version) {
|
|
throw new Error('Unsupported version: ' + version);
|
|
}
|
|
|
|
if (sourceRoot) {
|
|
sourceRoot = util.normalize(sourceRoot);
|
|
}
|
|
|
|
sources = sources
|
|
.map(String)
|
|
// Some source maps produce relative source paths like "./foo.js" instead of
|
|
// "foo.js". Normalize these first so that future comparisons will succeed.
|
|
// See bugzil.la/1090768.
|
|
.map(util.normalize)
|
|
// Always ensure that absolute sources are internally stored relative to
|
|
// the source root, if the source root is absolute. Not doing this would
|
|
// be particularly problematic when the source root is a prefix of the
|
|
// source (valid, but why??). See github issue #199 and bugzil.la/1188982.
|
|
.map(function (source) {
|
|
return sourceRoot && util.isAbsolute(sourceRoot) && util.isAbsolute(source)
|
|
? util.relative(sourceRoot, source)
|
|
: source;
|
|
});
|
|
|
|
// Pass `true` below to allow duplicate names and sources. While source maps
|
|
// are intended to be compressed and deduplicated, the TypeScript compiler
|
|
// sometimes generates source maps with duplicates in them. See Github issue
|
|
// #72 and bugzil.la/889492.
|
|
this._names = ArraySet.fromArray(names.map(String), true);
|
|
this._sources = ArraySet.fromArray(sources, true);
|
|
|
|
this._absoluteSources = this._sources.toArray().map(function (s) {
|
|
return util.computeSourceURL(sourceRoot, s, aSourceMapURL);
|
|
});
|
|
|
|
this.sourceRoot = sourceRoot;
|
|
this.sourcesContent = sourcesContent;
|
|
this._mappings = mappings;
|
|
this._sourceMapURL = aSourceMapURL;
|
|
this.file = file;
|
|
}
|
|
|
|
BasicSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype);
|
|
BasicSourceMapConsumer.prototype.consumer = SourceMapConsumer;
|
|
|
|
/**
|
|
* Utility function to find the index of a source. Returns -1 if not
|
|
* found.
|
|
*/
|
|
BasicSourceMapConsumer.prototype._findSourceIndex = function(aSource) {
|
|
var relativeSource = aSource;
|
|
if (this.sourceRoot != null) {
|
|
relativeSource = util.relative(this.sourceRoot, relativeSource);
|
|
}
|
|
|
|
if (this._sources.has(relativeSource)) {
|
|
return this._sources.indexOf(relativeSource);
|
|
}
|
|
|
|
// Maybe aSource is an absolute URL as returned by |sources|. In
|
|
// this case we can't simply undo the transform.
|
|
var i;
|
|
for (i = 0; i < this._absoluteSources.length; ++i) {
|
|
if (this._absoluteSources[i] == aSource) {
|
|
return i;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
};
|
|
|
|
/**
|
|
* Create a BasicSourceMapConsumer from a SourceMapGenerator.
|
|
*
|
|
* @param SourceMapGenerator aSourceMap
|
|
* The source map that will be consumed.
|
|
* @param String aSourceMapURL
|
|
* The URL at which the source map can be found (optional)
|
|
* @returns BasicSourceMapConsumer
|
|
*/
|
|
BasicSourceMapConsumer.fromSourceMap =
|
|
function SourceMapConsumer_fromSourceMap(aSourceMap, aSourceMapURL) {
|
|
var smc = Object.create(BasicSourceMapConsumer.prototype);
|
|
|
|
var names = smc._names = ArraySet.fromArray(aSourceMap._names.toArray(), true);
|
|
var sources = smc._sources = ArraySet.fromArray(aSourceMap._sources.toArray(), true);
|
|
smc.sourceRoot = aSourceMap._sourceRoot;
|
|
smc.sourcesContent = aSourceMap._generateSourcesContent(smc._sources.toArray(),
|
|
smc.sourceRoot);
|
|
smc.file = aSourceMap._file;
|
|
smc._sourceMapURL = aSourceMapURL;
|
|
smc._absoluteSources = smc._sources.toArray().map(function (s) {
|
|
return util.computeSourceURL(smc.sourceRoot, s, aSourceMapURL);
|
|
});
|
|
|
|
// Because we are modifying the entries (by converting string sources and
|
|
// names to indices into the sources and names ArraySets), we have to make
|
|
// a copy of the entry or else bad things happen. Shared mutable state
|
|
// strikes again! See github issue #191.
|
|
|
|
var generatedMappings = aSourceMap._mappings.toArray().slice();
|
|
var destGeneratedMappings = smc.__generatedMappings = [];
|
|
var destOriginalMappings = smc.__originalMappings = [];
|
|
|
|
for (var i = 0, length = generatedMappings.length; i < length; i++) {
|
|
var srcMapping = generatedMappings[i];
|
|
var destMapping = new Mapping;
|
|
destMapping.generatedLine = srcMapping.generatedLine;
|
|
destMapping.generatedColumn = srcMapping.generatedColumn;
|
|
|
|
if (srcMapping.source) {
|
|
destMapping.source = sources.indexOf(srcMapping.source);
|
|
destMapping.originalLine = srcMapping.originalLine;
|
|
destMapping.originalColumn = srcMapping.originalColumn;
|
|
|
|
if (srcMapping.name) {
|
|
destMapping.name = names.indexOf(srcMapping.name);
|
|
}
|
|
|
|
destOriginalMappings.push(destMapping);
|
|
}
|
|
|
|
destGeneratedMappings.push(destMapping);
|
|
}
|
|
|
|
quickSort(smc.__originalMappings, util.compareByOriginalPositions);
|
|
|
|
return smc;
|
|
};
|
|
|
|
/**
|
|
* The version of the source mapping spec that we are consuming.
|
|
*/
|
|
BasicSourceMapConsumer.prototype._version = 3;
|
|
|
|
/**
|
|
* The list of original sources.
|
|
*/
|
|
Object.defineProperty(BasicSourceMapConsumer.prototype, 'sources', {
|
|
get: function () {
|
|
return this._absoluteSources.slice();
|
|
}
|
|
});
|
|
|
|
/**
|
|
* Provide the JIT with a nice shape / hidden class.
|
|
*/
|
|
function Mapping() {
|
|
this.generatedLine = 0;
|
|
this.generatedColumn = 0;
|
|
this.source = null;
|
|
this.originalLine = null;
|
|
this.originalColumn = null;
|
|
this.name = null;
|
|
}
|
|
|
|
/**
|
|
* Parse the mappings in a string in to a data structure which we can easily
|
|
* query (the ordered arrays in the `this.__generatedMappings` and
|
|
* `this.__originalMappings` properties).
|
|
*/
|
|
BasicSourceMapConsumer.prototype._parseMappings =
|
|
function SourceMapConsumer_parseMappings(aStr, aSourceRoot) {
|
|
var generatedLine = 1;
|
|
var previousGeneratedColumn = 0;
|
|
var previousOriginalLine = 0;
|
|
var previousOriginalColumn = 0;
|
|
var previousSource = 0;
|
|
var previousName = 0;
|
|
var length = aStr.length;
|
|
var index = 0;
|
|
var cachedSegments = {};
|
|
var temp = {};
|
|
var originalMappings = [];
|
|
var generatedMappings = [];
|
|
var mapping, str, segment, end, value;
|
|
|
|
while (index < length) {
|
|
if (aStr.charAt(index) === ';') {
|
|
generatedLine++;
|
|
index++;
|
|
previousGeneratedColumn = 0;
|
|
}
|
|
else if (aStr.charAt(index) === ',') {
|
|
index++;
|
|
}
|
|
else {
|
|
mapping = new Mapping();
|
|
mapping.generatedLine = generatedLine;
|
|
|
|
// Because each offset is encoded relative to the previous one,
|
|
// many segments often have the same encoding. We can exploit this
|
|
// fact by caching the parsed variable length fields of each segment,
|
|
// allowing us to avoid a second parse if we encounter the same
|
|
// segment again.
|
|
for (end = index; end < length; end++) {
|
|
if (this._charIsMappingSeparator(aStr, end)) {
|
|
break;
|
|
}
|
|
}
|
|
str = aStr.slice(index, end);
|
|
|
|
segment = cachedSegments[str];
|
|
if (segment) {
|
|
index += str.length;
|
|
} else {
|
|
segment = [];
|
|
while (index < end) {
|
|
base64VLQ.decode(aStr, index, temp);
|
|
value = temp.value;
|
|
index = temp.rest;
|
|
segment.push(value);
|
|
}
|
|
|
|
if (segment.length === 2) {
|
|
throw new Error('Found a source, but no line and column');
|
|
}
|
|
|
|
if (segment.length === 3) {
|
|
throw new Error('Found a source and line, but no column');
|
|
}
|
|
|
|
cachedSegments[str] = segment;
|
|
}
|
|
|
|
// Generated column.
|
|
mapping.generatedColumn = previousGeneratedColumn + segment[0];
|
|
previousGeneratedColumn = mapping.generatedColumn;
|
|
|
|
if (segment.length > 1) {
|
|
// Original source.
|
|
mapping.source = previousSource + segment[1];
|
|
previousSource += segment[1];
|
|
|
|
// Original line.
|
|
mapping.originalLine = previousOriginalLine + segment[2];
|
|
previousOriginalLine = mapping.originalLine;
|
|
// Lines are stored 0-based
|
|
mapping.originalLine += 1;
|
|
|
|
// Original column.
|
|
mapping.originalColumn = previousOriginalColumn + segment[3];
|
|
previousOriginalColumn = mapping.originalColumn;
|
|
|
|
if (segment.length > 4) {
|
|
// Original name.
|
|
mapping.name = previousName + segment[4];
|
|
previousName += segment[4];
|
|
}
|
|
}
|
|
|
|
generatedMappings.push(mapping);
|
|
if (typeof mapping.originalLine === 'number') {
|
|
originalMappings.push(mapping);
|
|
}
|
|
}
|
|
}
|
|
|
|
quickSort(generatedMappings, util.compareByGeneratedPositionsDeflated);
|
|
this.__generatedMappings = generatedMappings;
|
|
|
|
quickSort(originalMappings, util.compareByOriginalPositions);
|
|
this.__originalMappings = originalMappings;
|
|
};
|
|
|
|
/**
|
|
* Find the mapping that best matches the hypothetical "needle" mapping that
|
|
* we are searching for in the given "haystack" of mappings.
|
|
*/
|
|
BasicSourceMapConsumer.prototype._findMapping =
|
|
function SourceMapConsumer_findMapping(aNeedle, aMappings, aLineName,
|
|
aColumnName, aComparator, aBias) {
|
|
// To return the position we are searching for, we must first find the
|
|
// mapping for the given position and then return the opposite position it
|
|
// points to. Because the mappings are sorted, we can use binary search to
|
|
// find the best mapping.
|
|
|
|
if (aNeedle[aLineName] <= 0) {
|
|
throw new TypeError('Line must be greater than or equal to 1, got '
|
|
+ aNeedle[aLineName]);
|
|
}
|
|
if (aNeedle[aColumnName] < 0) {
|
|
throw new TypeError('Column must be greater than or equal to 0, got '
|
|
+ aNeedle[aColumnName]);
|
|
}
|
|
|
|
return binarySearch.search(aNeedle, aMappings, aComparator, aBias);
|
|
};
|
|
|
|
/**
|
|
* Compute the last column for each generated mapping. The last column is
|
|
* inclusive.
|
|
*/
|
|
BasicSourceMapConsumer.prototype.computeColumnSpans =
|
|
function SourceMapConsumer_computeColumnSpans() {
|
|
for (var index = 0; index < this._generatedMappings.length; ++index) {
|
|
var mapping = this._generatedMappings[index];
|
|
|
|
// Mappings do not contain a field for the last generated columnt. We
|
|
// can come up with an optimistic estimate, however, by assuming that
|
|
// mappings are contiguous (i.e. given two consecutive mappings, the
|
|
// first mapping ends where the second one starts).
|
|
if (index + 1 < this._generatedMappings.length) {
|
|
var nextMapping = this._generatedMappings[index + 1];
|
|
|
|
if (mapping.generatedLine === nextMapping.generatedLine) {
|
|
mapping.lastGeneratedColumn = nextMapping.generatedColumn - 1;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
// The last mapping for each line spans the entire line.
|
|
mapping.lastGeneratedColumn = Infinity;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Returns the original source, line, and column information for the generated
|
|
* source's line and column positions provided. The only argument is an object
|
|
* with the following properties:
|
|
*
|
|
* - line: The line number in the generated source. The line number
|
|
* is 1-based.
|
|
* - column: The column number in the generated source. The column
|
|
* number is 0-based.
|
|
* - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or
|
|
* 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the
|
|
* closest element that is smaller than or greater than the one we are
|
|
* searching for, respectively, if the exact element cannot be found.
|
|
* Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'.
|
|
*
|
|
* and an object is returned with the following properties:
|
|
*
|
|
* - source: The original source file, or null.
|
|
* - line: The line number in the original source, or null. The
|
|
* line number is 1-based.
|
|
* - column: The column number in the original source, or null. The
|
|
* column number is 0-based.
|
|
* - name: The original identifier, or null.
|
|
*/
|
|
BasicSourceMapConsumer.prototype.originalPositionFor =
|
|
function SourceMapConsumer_originalPositionFor(aArgs) {
|
|
var needle = {
|
|
generatedLine: util.getArg(aArgs, 'line'),
|
|
generatedColumn: util.getArg(aArgs, 'column')
|
|
};
|
|
|
|
var index = this._findMapping(
|
|
needle,
|
|
this._generatedMappings,
|
|
"generatedLine",
|
|
"generatedColumn",
|
|
util.compareByGeneratedPositionsDeflated,
|
|
util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND)
|
|
);
|
|
|
|
if (index >= 0) {
|
|
var mapping = this._generatedMappings[index];
|
|
|
|
if (mapping.generatedLine === needle.generatedLine) {
|
|
var source = util.getArg(mapping, 'source', null);
|
|
if (source !== null) {
|
|
source = this._sources.at(source);
|
|
source = util.computeSourceURL(this.sourceRoot, source, this._sourceMapURL);
|
|
}
|
|
var name = util.getArg(mapping, 'name', null);
|
|
if (name !== null) {
|
|
name = this._names.at(name);
|
|
}
|
|
return {
|
|
source: source,
|
|
line: util.getArg(mapping, 'originalLine', null),
|
|
column: util.getArg(mapping, 'originalColumn', null),
|
|
name: name
|
|
};
|
|
}
|
|
}
|
|
|
|
return {
|
|
source: null,
|
|
line: null,
|
|
column: null,
|
|
name: null
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Return true if we have the source content for every source in the source
|
|
* map, false otherwise.
|
|
*/
|
|
BasicSourceMapConsumer.prototype.hasContentsOfAllSources =
|
|
function BasicSourceMapConsumer_hasContentsOfAllSources() {
|
|
if (!this.sourcesContent) {
|
|
return false;
|
|
}
|
|
return this.sourcesContent.length >= this._sources.size() &&
|
|
!this.sourcesContent.some(function (sc) { return sc == null; });
|
|
};
|
|
|
|
/**
|
|
* Returns the original source content. The only argument is the url of the
|
|
* original source file. Returns null if no original source content is
|
|
* available.
|
|
*/
|
|
BasicSourceMapConsumer.prototype.sourceContentFor =
|
|
function SourceMapConsumer_sourceContentFor(aSource, nullOnMissing) {
|
|
if (!this.sourcesContent) {
|
|
return null;
|
|
}
|
|
|
|
var index = this._findSourceIndex(aSource);
|
|
if (index >= 0) {
|
|
return this.sourcesContent[index];
|
|
}
|
|
|
|
var relativeSource = aSource;
|
|
if (this.sourceRoot != null) {
|
|
relativeSource = util.relative(this.sourceRoot, relativeSource);
|
|
}
|
|
|
|
var url;
|
|
if (this.sourceRoot != null
|
|
&& (url = util.urlParse(this.sourceRoot))) {
|
|
// XXX: file:// URIs and absolute paths lead to unexpected behavior for
|
|
// many users. We can help them out when they expect file:// URIs to
|
|
// behave like it would if they were running a local HTTP server. See
|
|
// https://bugzilla.mozilla.org/show_bug.cgi?id=885597.
|
|
var fileUriAbsPath = relativeSource.replace(/^file:\/\//, "");
|
|
if (url.scheme == "file"
|
|
&& this._sources.has(fileUriAbsPath)) {
|
|
return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)]
|
|
}
|
|
|
|
if ((!url.path || url.path == "/")
|
|
&& this._sources.has("/" + relativeSource)) {
|
|
return this.sourcesContent[this._sources.indexOf("/" + relativeSource)];
|
|
}
|
|
}
|
|
|
|
// This function is used recursively from
|
|
// IndexedSourceMapConsumer.prototype.sourceContentFor. In that case, we
|
|
// don't want to throw if we can't find the source - we just want to
|
|
// return null, so we provide a flag to exit gracefully.
|
|
if (nullOnMissing) {
|
|
return null;
|
|
}
|
|
else {
|
|
throw new Error('"' + relativeSource + '" is not in the SourceMap.');
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Returns the generated line and column information for the original source,
|
|
* line, and column positions provided. The only argument is an object with
|
|
* the following properties:
|
|
*
|
|
* - source: The filename of the original source.
|
|
* - line: The line number in the original source. The line number
|
|
* is 1-based.
|
|
* - column: The column number in the original source. The column
|
|
* number is 0-based.
|
|
* - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or
|
|
* 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the
|
|
* closest element that is smaller than or greater than the one we are
|
|
* searching for, respectively, if the exact element cannot be found.
|
|
* Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'.
|
|
*
|
|
* and an object is returned with the following properties:
|
|
*
|
|
* - line: The line number in the generated source, or null. The
|
|
* line number is 1-based.
|
|
* - column: The column number in the generated source, or null.
|
|
* The column number is 0-based.
|
|
*/
|
|
BasicSourceMapConsumer.prototype.generatedPositionFor =
|
|
function SourceMapConsumer_generatedPositionFor(aArgs) {
|
|
var source = util.getArg(aArgs, 'source');
|
|
source = this._findSourceIndex(source);
|
|
if (source < 0) {
|
|
return {
|
|
line: null,
|
|
column: null,
|
|
lastColumn: null
|
|
};
|
|
}
|
|
|
|
var needle = {
|
|
source: source,
|
|
originalLine: util.getArg(aArgs, 'line'),
|
|
originalColumn: util.getArg(aArgs, 'column')
|
|
};
|
|
|
|
var index = this._findMapping(
|
|
needle,
|
|
this._originalMappings,
|
|
"originalLine",
|
|
"originalColumn",
|
|
util.compareByOriginalPositions,
|
|
util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND)
|
|
);
|
|
|
|
if (index >= 0) {
|
|
var mapping = this._originalMappings[index];
|
|
|
|
if (mapping.source === needle.source) {
|
|
return {
|
|
line: util.getArg(mapping, 'generatedLine', null),
|
|
column: util.getArg(mapping, 'generatedColumn', null),
|
|
lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null)
|
|
};
|
|
}
|
|
}
|
|
|
|
return {
|
|
line: null,
|
|
column: null,
|
|
lastColumn: null
|
|
};
|
|
};
|
|
|
|
sourceMapConsumer.BasicSourceMapConsumer = BasicSourceMapConsumer;
|
|
|
|
/**
|
|
* An IndexedSourceMapConsumer instance represents a parsed source map which
|
|
* we can query for information. It differs from BasicSourceMapConsumer in
|
|
* that it takes "indexed" source maps (i.e. ones with a "sections" field) as
|
|
* input.
|
|
*
|
|
* The first parameter is a raw source map (either as a JSON string, or already
|
|
* parsed to an object). According to the spec for indexed source maps, they
|
|
* have the following attributes:
|
|
*
|
|
* - version: Which version of the source map spec this map is following.
|
|
* - file: Optional. The generated file this source map is associated with.
|
|
* - sections: A list of section definitions.
|
|
*
|
|
* Each value under the "sections" field has two fields:
|
|
* - offset: The offset into the original specified at which this section
|
|
* begins to apply, defined as an object with a "line" and "column"
|
|
* field.
|
|
* - map: A source map definition. This source map could also be indexed,
|
|
* but doesn't have to be.
|
|
*
|
|
* Instead of the "map" field, it's also possible to have a "url" field
|
|
* specifying a URL to retrieve a source map from, but that's currently
|
|
* unsupported.
|
|
*
|
|
* Here's an example source map, taken from the source map spec[0], but
|
|
* modified to omit a section which uses the "url" field.
|
|
*
|
|
* {
|
|
* version : 3,
|
|
* file: "app.js",
|
|
* sections: [{
|
|
* offset: {line:100, column:10},
|
|
* map: {
|
|
* version : 3,
|
|
* file: "section.js",
|
|
* sources: ["foo.js", "bar.js"],
|
|
* names: ["src", "maps", "are", "fun"],
|
|
* mappings: "AAAA,E;;ABCDE;"
|
|
* }
|
|
* }],
|
|
* }
|
|
*
|
|
* The second parameter, if given, is a string whose value is the URL
|
|
* at which the source map was found. This URL is used to compute the
|
|
* sources array.
|
|
*
|
|
* [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#heading=h.535es3xeprgt
|
|
*/
|
|
function IndexedSourceMapConsumer(aSourceMap, aSourceMapURL) {
|
|
var sourceMap = aSourceMap;
|
|
if (typeof aSourceMap === 'string') {
|
|
sourceMap = util.parseSourceMapInput(aSourceMap);
|
|
}
|
|
|
|
var version = util.getArg(sourceMap, 'version');
|
|
var sections = util.getArg(sourceMap, 'sections');
|
|
|
|
if (version != this._version) {
|
|
throw new Error('Unsupported version: ' + version);
|
|
}
|
|
|
|
this._sources = new ArraySet();
|
|
this._names = new ArraySet();
|
|
|
|
var lastOffset = {
|
|
line: -1,
|
|
column: 0
|
|
};
|
|
this._sections = sections.map(function (s) {
|
|
if (s.url) {
|
|
// The url field will require support for asynchronicity.
|
|
// See https://github.com/mozilla/source-map/issues/16
|
|
throw new Error('Support for url field in sections not implemented.');
|
|
}
|
|
var offset = util.getArg(s, 'offset');
|
|
var offsetLine = util.getArg(offset, 'line');
|
|
var offsetColumn = util.getArg(offset, 'column');
|
|
|
|
if (offsetLine < lastOffset.line ||
|
|
(offsetLine === lastOffset.line && offsetColumn < lastOffset.column)) {
|
|
throw new Error('Section offsets must be ordered and non-overlapping.');
|
|
}
|
|
lastOffset = offset;
|
|
|
|
return {
|
|
generatedOffset: {
|
|
// The offset fields are 0-based, but we use 1-based indices when
|
|
// encoding/decoding from VLQ.
|
|
generatedLine: offsetLine + 1,
|
|
generatedColumn: offsetColumn + 1
|
|
},
|
|
consumer: new SourceMapConsumer(util.getArg(s, 'map'), aSourceMapURL)
|
|
}
|
|
});
|
|
}
|
|
|
|
IndexedSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype);
|
|
IndexedSourceMapConsumer.prototype.constructor = SourceMapConsumer;
|
|
|
|
/**
|
|
* The version of the source mapping spec that we are consuming.
|
|
*/
|
|
IndexedSourceMapConsumer.prototype._version = 3;
|
|
|
|
/**
|
|
* The list of original sources.
|
|
*/
|
|
Object.defineProperty(IndexedSourceMapConsumer.prototype, 'sources', {
|
|
get: function () {
|
|
var sources = [];
|
|
for (var i = 0; i < this._sections.length; i++) {
|
|
for (var j = 0; j < this._sections[i].consumer.sources.length; j++) {
|
|
sources.push(this._sections[i].consumer.sources[j]);
|
|
}
|
|
}
|
|
return sources;
|
|
}
|
|
});
|
|
|
|
/**
|
|
* Returns the original source, line, and column information for the generated
|
|
* source's line and column positions provided. The only argument is an object
|
|
* with the following properties:
|
|
*
|
|
* - line: The line number in the generated source. The line number
|
|
* is 1-based.
|
|
* - column: The column number in the generated source. The column
|
|
* number is 0-based.
|
|
*
|
|
* and an object is returned with the following properties:
|
|
*
|
|
* - source: The original source file, or null.
|
|
* - line: The line number in the original source, or null. The
|
|
* line number is 1-based.
|
|
* - column: The column number in the original source, or null. The
|
|
* column number is 0-based.
|
|
* - name: The original identifier, or null.
|
|
*/
|
|
IndexedSourceMapConsumer.prototype.originalPositionFor =
|
|
function IndexedSourceMapConsumer_originalPositionFor(aArgs) {
|
|
var needle = {
|
|
generatedLine: util.getArg(aArgs, 'line'),
|
|
generatedColumn: util.getArg(aArgs, 'column')
|
|
};
|
|
|
|
// Find the section containing the generated position we're trying to map
|
|
// to an original position.
|
|
var sectionIndex = binarySearch.search(needle, this._sections,
|
|
function(needle, section) {
|
|
var cmp = needle.generatedLine - section.generatedOffset.generatedLine;
|
|
if (cmp) {
|
|
return cmp;
|
|
}
|
|
|
|
return (needle.generatedColumn -
|
|
section.generatedOffset.generatedColumn);
|
|
});
|
|
var section = this._sections[sectionIndex];
|
|
|
|
if (!section) {
|
|
return {
|
|
source: null,
|
|
line: null,
|
|
column: null,
|
|
name: null
|
|
};
|
|
}
|
|
|
|
return section.consumer.originalPositionFor({
|
|
line: needle.generatedLine -
|
|
(section.generatedOffset.generatedLine - 1),
|
|
column: needle.generatedColumn -
|
|
(section.generatedOffset.generatedLine === needle.generatedLine
|
|
? section.generatedOffset.generatedColumn - 1
|
|
: 0),
|
|
bias: aArgs.bias
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Return true if we have the source content for every source in the source
|
|
* map, false otherwise.
|
|
*/
|
|
IndexedSourceMapConsumer.prototype.hasContentsOfAllSources =
|
|
function IndexedSourceMapConsumer_hasContentsOfAllSources() {
|
|
return this._sections.every(function (s) {
|
|
return s.consumer.hasContentsOfAllSources();
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Returns the original source content. The only argument is the url of the
|
|
* original source file. Returns null if no original source content is
|
|
* available.
|
|
*/
|
|
IndexedSourceMapConsumer.prototype.sourceContentFor =
|
|
function IndexedSourceMapConsumer_sourceContentFor(aSource, nullOnMissing) {
|
|
for (var i = 0; i < this._sections.length; i++) {
|
|
var section = this._sections[i];
|
|
|
|
var content = section.consumer.sourceContentFor(aSource, true);
|
|
if (content) {
|
|
return content;
|
|
}
|
|
}
|
|
if (nullOnMissing) {
|
|
return null;
|
|
}
|
|
else {
|
|
throw new Error('"' + aSource + '" is not in the SourceMap.');
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Returns the generated line and column information for the original source,
|
|
* line, and column positions provided. The only argument is an object with
|
|
* the following properties:
|
|
*
|
|
* - source: The filename of the original source.
|
|
* - line: The line number in the original source. The line number
|
|
* is 1-based.
|
|
* - column: The column number in the original source. The column
|
|
* number is 0-based.
|
|
*
|
|
* and an object is returned with the following properties:
|
|
*
|
|
* - line: The line number in the generated source, or null. The
|
|
* line number is 1-based.
|
|
* - column: The column number in the generated source, or null.
|
|
* The column number is 0-based.
|
|
*/
|
|
IndexedSourceMapConsumer.prototype.generatedPositionFor =
|
|
function IndexedSourceMapConsumer_generatedPositionFor(aArgs) {
|
|
for (var i = 0; i < this._sections.length; i++) {
|
|
var section = this._sections[i];
|
|
|
|
// Only consider this section if the requested source is in the list of
|
|
// sources of the consumer.
|
|
if (section.consumer._findSourceIndex(util.getArg(aArgs, 'source')) === -1) {
|
|
continue;
|
|
}
|
|
var generatedPosition = section.consumer.generatedPositionFor(aArgs);
|
|
if (generatedPosition) {
|
|
var ret = {
|
|
line: generatedPosition.line +
|
|
(section.generatedOffset.generatedLine - 1),
|
|
column: generatedPosition.column +
|
|
(section.generatedOffset.generatedLine === generatedPosition.line
|
|
? section.generatedOffset.generatedColumn - 1
|
|
: 0)
|
|
};
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
return {
|
|
line: null,
|
|
column: null
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Parse the mappings in a string in to a data structure which we can easily
|
|
* query (the ordered arrays in the `this.__generatedMappings` and
|
|
* `this.__originalMappings` properties).
|
|
*/
|
|
IndexedSourceMapConsumer.prototype._parseMappings =
|
|
function IndexedSourceMapConsumer_parseMappings(aStr, aSourceRoot) {
|
|
this.__generatedMappings = [];
|
|
this.__originalMappings = [];
|
|
for (var i = 0; i < this._sections.length; i++) {
|
|
var section = this._sections[i];
|
|
var sectionMappings = section.consumer._generatedMappings;
|
|
for (var j = 0; j < sectionMappings.length; j++) {
|
|
var mapping = sectionMappings[j];
|
|
|
|
var source = section.consumer._sources.at(mapping.source);
|
|
source = util.computeSourceURL(section.consumer.sourceRoot, source, this._sourceMapURL);
|
|
this._sources.add(source);
|
|
source = this._sources.indexOf(source);
|
|
|
|
var name = null;
|
|
if (mapping.name) {
|
|
name = section.consumer._names.at(mapping.name);
|
|
this._names.add(name);
|
|
name = this._names.indexOf(name);
|
|
}
|
|
|
|
// The mappings coming from the consumer for the section have
|
|
// generated positions relative to the start of the section, so we
|
|
// need to offset them to be relative to the start of the concatenated
|
|
// generated file.
|
|
var adjustedMapping = {
|
|
source: source,
|
|
generatedLine: mapping.generatedLine +
|
|
(section.generatedOffset.generatedLine - 1),
|
|
generatedColumn: mapping.generatedColumn +
|
|
(section.generatedOffset.generatedLine === mapping.generatedLine
|
|
? section.generatedOffset.generatedColumn - 1
|
|
: 0),
|
|
originalLine: mapping.originalLine,
|
|
originalColumn: mapping.originalColumn,
|
|
name: name
|
|
};
|
|
|
|
this.__generatedMappings.push(adjustedMapping);
|
|
if (typeof adjustedMapping.originalLine === 'number') {
|
|
this.__originalMappings.push(adjustedMapping);
|
|
}
|
|
}
|
|
}
|
|
|
|
quickSort(this.__generatedMappings, util.compareByGeneratedPositionsDeflated);
|
|
quickSort(this.__originalMappings, util.compareByOriginalPositions);
|
|
};
|
|
|
|
sourceMapConsumer.IndexedSourceMapConsumer = IndexedSourceMapConsumer;
|
|
return sourceMapConsumer;
|
|
}
|
|
|
|
var sourceNode = {};
|
|
|
|
/* -*- Mode: js; js-indent-level: 2; -*- */
|
|
|
|
var hasRequiredSourceNode;
|
|
|
|
function requireSourceNode () {
|
|
if (hasRequiredSourceNode) return sourceNode;
|
|
hasRequiredSourceNode = 1;
|
|
/*
|
|
* Copyright 2011 Mozilla Foundation and contributors
|
|
* Licensed under the New BSD license. See LICENSE or:
|
|
* http://opensource.org/licenses/BSD-3-Clause
|
|
*/
|
|
|
|
var SourceMapGenerator = requireSourceMapGenerator().SourceMapGenerator;
|
|
var util = requireUtil$1();
|
|
|
|
// Matches a Windows-style `\r\n` newline or a `\n` newline used by all other
|
|
// operating systems these days (capturing the result).
|
|
var REGEX_NEWLINE = /(\r?\n)/;
|
|
|
|
// Newline character code for charCodeAt() comparisons
|
|
var NEWLINE_CODE = 10;
|
|
|
|
// Private symbol for identifying `SourceNode`s when multiple versions of
|
|
// the source-map library are loaded. This MUST NOT CHANGE across
|
|
// versions!
|
|
var isSourceNode = "$$$isSourceNode$$$";
|
|
|
|
/**
|
|
* SourceNodes provide a way to abstract over interpolating/concatenating
|
|
* snippets of generated JavaScript source code while maintaining the line and
|
|
* column information associated with the original source code.
|
|
*
|
|
* @param aLine The original line number.
|
|
* @param aColumn The original column number.
|
|
* @param aSource The original source's filename.
|
|
* @param aChunks Optional. An array of strings which are snippets of
|
|
* generated JS, or other SourceNodes.
|
|
* @param aName The original identifier.
|
|
*/
|
|
function SourceNode(aLine, aColumn, aSource, aChunks, aName) {
|
|
this.children = [];
|
|
this.sourceContents = {};
|
|
this.line = aLine == null ? null : aLine;
|
|
this.column = aColumn == null ? null : aColumn;
|
|
this.source = aSource == null ? null : aSource;
|
|
this.name = aName == null ? null : aName;
|
|
this[isSourceNode] = true;
|
|
if (aChunks != null) this.add(aChunks);
|
|
}
|
|
|
|
/**
|
|
* Creates a SourceNode from generated code and a SourceMapConsumer.
|
|
*
|
|
* @param aGeneratedCode The generated code
|
|
* @param aSourceMapConsumer The SourceMap for the generated code
|
|
* @param aRelativePath Optional. The path that relative sources in the
|
|
* SourceMapConsumer should be relative to.
|
|
*/
|
|
SourceNode.fromStringWithSourceMap =
|
|
function SourceNode_fromStringWithSourceMap(aGeneratedCode, aSourceMapConsumer, aRelativePath) {
|
|
// The SourceNode we want to fill with the generated code
|
|
// and the SourceMap
|
|
var node = new SourceNode();
|
|
|
|
// All even indices of this array are one line of the generated code,
|
|
// while all odd indices are the newlines between two adjacent lines
|
|
// (since `REGEX_NEWLINE` captures its match).
|
|
// Processed fragments are accessed by calling `shiftNextLine`.
|
|
var remainingLines = aGeneratedCode.split(REGEX_NEWLINE);
|
|
var remainingLinesIndex = 0;
|
|
var shiftNextLine = function() {
|
|
var lineContents = getNextLine();
|
|
// The last line of a file might not have a newline.
|
|
var newLine = getNextLine() || "";
|
|
return lineContents + newLine;
|
|
|
|
function getNextLine() {
|
|
return remainingLinesIndex < remainingLines.length ?
|
|
remainingLines[remainingLinesIndex++] : undefined;
|
|
}
|
|
};
|
|
|
|
// We need to remember the position of "remainingLines"
|
|
var lastGeneratedLine = 1, lastGeneratedColumn = 0;
|
|
|
|
// The generate SourceNodes we need a code range.
|
|
// To extract it current and last mapping is used.
|
|
// Here we store the last mapping.
|
|
var lastMapping = null;
|
|
|
|
aSourceMapConsumer.eachMapping(function (mapping) {
|
|
if (lastMapping !== null) {
|
|
// We add the code from "lastMapping" to "mapping":
|
|
// First check if there is a new line in between.
|
|
if (lastGeneratedLine < mapping.generatedLine) {
|
|
// Associate first line with "lastMapping"
|
|
addMappingWithCode(lastMapping, shiftNextLine());
|
|
lastGeneratedLine++;
|
|
lastGeneratedColumn = 0;
|
|
// The remaining code is added without mapping
|
|
} else {
|
|
// There is no new line in between.
|
|
// Associate the code between "lastGeneratedColumn" and
|
|
// "mapping.generatedColumn" with "lastMapping"
|
|
var nextLine = remainingLines[remainingLinesIndex] || '';
|
|
var code = nextLine.substr(0, mapping.generatedColumn -
|
|
lastGeneratedColumn);
|
|
remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn -
|
|
lastGeneratedColumn);
|
|
lastGeneratedColumn = mapping.generatedColumn;
|
|
addMappingWithCode(lastMapping, code);
|
|
// No more remaining code, continue
|
|
lastMapping = mapping;
|
|
return;
|
|
}
|
|
}
|
|
// We add the generated code until the first mapping
|
|
// to the SourceNode without any mapping.
|
|
// Each line is added as separate string.
|
|
while (lastGeneratedLine < mapping.generatedLine) {
|
|
node.add(shiftNextLine());
|
|
lastGeneratedLine++;
|
|
}
|
|
if (lastGeneratedColumn < mapping.generatedColumn) {
|
|
var nextLine = remainingLines[remainingLinesIndex] || '';
|
|
node.add(nextLine.substr(0, mapping.generatedColumn));
|
|
remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn);
|
|
lastGeneratedColumn = mapping.generatedColumn;
|
|
}
|
|
lastMapping = mapping;
|
|
}, this);
|
|
// We have processed all mappings.
|
|
if (remainingLinesIndex < remainingLines.length) {
|
|
if (lastMapping) {
|
|
// Associate the remaining code in the current line with "lastMapping"
|
|
addMappingWithCode(lastMapping, shiftNextLine());
|
|
}
|
|
// and add the remaining lines without any mapping
|
|
node.add(remainingLines.splice(remainingLinesIndex).join(""));
|
|
}
|
|
|
|
// Copy sourcesContent into SourceNode
|
|
aSourceMapConsumer.sources.forEach(function (sourceFile) {
|
|
var content = aSourceMapConsumer.sourceContentFor(sourceFile);
|
|
if (content != null) {
|
|
if (aRelativePath != null) {
|
|
sourceFile = util.join(aRelativePath, sourceFile);
|
|
}
|
|
node.setSourceContent(sourceFile, content);
|
|
}
|
|
});
|
|
|
|
return node;
|
|
|
|
function addMappingWithCode(mapping, code) {
|
|
if (mapping === null || mapping.source === undefined) {
|
|
node.add(code);
|
|
} else {
|
|
var source = aRelativePath
|
|
? util.join(aRelativePath, mapping.source)
|
|
: mapping.source;
|
|
node.add(new SourceNode(mapping.originalLine,
|
|
mapping.originalColumn,
|
|
source,
|
|
code,
|
|
mapping.name));
|
|
}
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Add a chunk of generated JS to this source node.
|
|
*
|
|
* @param aChunk A string snippet of generated JS code, another instance of
|
|
* SourceNode, or an array where each member is one of those things.
|
|
*/
|
|
SourceNode.prototype.add = function SourceNode_add(aChunk) {
|
|
if (Array.isArray(aChunk)) {
|
|
aChunk.forEach(function (chunk) {
|
|
this.add(chunk);
|
|
}, this);
|
|
}
|
|
else if (aChunk[isSourceNode] || typeof aChunk === "string") {
|
|
if (aChunk) {
|
|
this.children.push(aChunk);
|
|
}
|
|
}
|
|
else {
|
|
throw new TypeError(
|
|
"Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk
|
|
);
|
|
}
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* Add a chunk of generated JS to the beginning of this source node.
|
|
*
|
|
* @param aChunk A string snippet of generated JS code, another instance of
|
|
* SourceNode, or an array where each member is one of those things.
|
|
*/
|
|
SourceNode.prototype.prepend = function SourceNode_prepend(aChunk) {
|
|
if (Array.isArray(aChunk)) {
|
|
for (var i = aChunk.length-1; i >= 0; i--) {
|
|
this.prepend(aChunk[i]);
|
|
}
|
|
}
|
|
else if (aChunk[isSourceNode] || typeof aChunk === "string") {
|
|
this.children.unshift(aChunk);
|
|
}
|
|
else {
|
|
throw new TypeError(
|
|
"Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk
|
|
);
|
|
}
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* Walk over the tree of JS snippets in this node and its children. The
|
|
* walking function is called once for each snippet of JS and is passed that
|
|
* snippet and the its original associated source's line/column location.
|
|
*
|
|
* @param aFn The traversal function.
|
|
*/
|
|
SourceNode.prototype.walk = function SourceNode_walk(aFn) {
|
|
var chunk;
|
|
for (var i = 0, len = this.children.length; i < len; i++) {
|
|
chunk = this.children[i];
|
|
if (chunk[isSourceNode]) {
|
|
chunk.walk(aFn);
|
|
}
|
|
else {
|
|
if (chunk !== '') {
|
|
aFn(chunk, { source: this.source,
|
|
line: this.line,
|
|
column: this.column,
|
|
name: this.name });
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Like `String.prototype.join` except for SourceNodes. Inserts `aStr` between
|
|
* each of `this.children`.
|
|
*
|
|
* @param aSep The separator.
|
|
*/
|
|
SourceNode.prototype.join = function SourceNode_join(aSep) {
|
|
var newChildren;
|
|
var i;
|
|
var len = this.children.length;
|
|
if (len > 0) {
|
|
newChildren = [];
|
|
for (i = 0; i < len-1; i++) {
|
|
newChildren.push(this.children[i]);
|
|
newChildren.push(aSep);
|
|
}
|
|
newChildren.push(this.children[i]);
|
|
this.children = newChildren;
|
|
}
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* Call String.prototype.replace on the very right-most source snippet. Useful
|
|
* for trimming whitespace from the end of a source node, etc.
|
|
*
|
|
* @param aPattern The pattern to replace.
|
|
* @param aReplacement The thing to replace the pattern with.
|
|
*/
|
|
SourceNode.prototype.replaceRight = function SourceNode_replaceRight(aPattern, aReplacement) {
|
|
var lastChild = this.children[this.children.length - 1];
|
|
if (lastChild[isSourceNode]) {
|
|
lastChild.replaceRight(aPattern, aReplacement);
|
|
}
|
|
else if (typeof lastChild === 'string') {
|
|
this.children[this.children.length - 1] = lastChild.replace(aPattern, aReplacement);
|
|
}
|
|
else {
|
|
this.children.push(''.replace(aPattern, aReplacement));
|
|
}
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* Set the source content for a source file. This will be added to the SourceMapGenerator
|
|
* in the sourcesContent field.
|
|
*
|
|
* @param aSourceFile The filename of the source file
|
|
* @param aSourceContent The content of the source file
|
|
*/
|
|
SourceNode.prototype.setSourceContent =
|
|
function SourceNode_setSourceContent(aSourceFile, aSourceContent) {
|
|
this.sourceContents[util.toSetString(aSourceFile)] = aSourceContent;
|
|
};
|
|
|
|
/**
|
|
* Walk over the tree of SourceNodes. The walking function is called for each
|
|
* source file content and is passed the filename and source content.
|
|
*
|
|
* @param aFn The traversal function.
|
|
*/
|
|
SourceNode.prototype.walkSourceContents =
|
|
function SourceNode_walkSourceContents(aFn) {
|
|
for (var i = 0, len = this.children.length; i < len; i++) {
|
|
if (this.children[i][isSourceNode]) {
|
|
this.children[i].walkSourceContents(aFn);
|
|
}
|
|
}
|
|
|
|
var sources = Object.keys(this.sourceContents);
|
|
for (var i = 0, len = sources.length; i < len; i++) {
|
|
aFn(util.fromSetString(sources[i]), this.sourceContents[sources[i]]);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Return the string representation of this source node. Walks over the tree
|
|
* and concatenates all the various snippets together to one string.
|
|
*/
|
|
SourceNode.prototype.toString = function SourceNode_toString() {
|
|
var str = "";
|
|
this.walk(function (chunk) {
|
|
str += chunk;
|
|
});
|
|
return str;
|
|
};
|
|
|
|
/**
|
|
* Returns the string representation of this source node along with a source
|
|
* map.
|
|
*/
|
|
SourceNode.prototype.toStringWithSourceMap = function SourceNode_toStringWithSourceMap(aArgs) {
|
|
var generated = {
|
|
code: "",
|
|
line: 1,
|
|
column: 0
|
|
};
|
|
var map = new SourceMapGenerator(aArgs);
|
|
var sourceMappingActive = false;
|
|
var lastOriginalSource = null;
|
|
var lastOriginalLine = null;
|
|
var lastOriginalColumn = null;
|
|
var lastOriginalName = null;
|
|
this.walk(function (chunk, original) {
|
|
generated.code += chunk;
|
|
if (original.source !== null
|
|
&& original.line !== null
|
|
&& original.column !== null) {
|
|
if(lastOriginalSource !== original.source
|
|
|| lastOriginalLine !== original.line
|
|
|| lastOriginalColumn !== original.column
|
|
|| lastOriginalName !== original.name) {
|
|
map.addMapping({
|
|
source: original.source,
|
|
original: {
|
|
line: original.line,
|
|
column: original.column
|
|
},
|
|
generated: {
|
|
line: generated.line,
|
|
column: generated.column
|
|
},
|
|
name: original.name
|
|
});
|
|
}
|
|
lastOriginalSource = original.source;
|
|
lastOriginalLine = original.line;
|
|
lastOriginalColumn = original.column;
|
|
lastOriginalName = original.name;
|
|
sourceMappingActive = true;
|
|
} else if (sourceMappingActive) {
|
|
map.addMapping({
|
|
generated: {
|
|
line: generated.line,
|
|
column: generated.column
|
|
}
|
|
});
|
|
lastOriginalSource = null;
|
|
sourceMappingActive = false;
|
|
}
|
|
for (var idx = 0, length = chunk.length; idx < length; idx++) {
|
|
if (chunk.charCodeAt(idx) === NEWLINE_CODE) {
|
|
generated.line++;
|
|
generated.column = 0;
|
|
// Mappings end at eol
|
|
if (idx + 1 === length) {
|
|
lastOriginalSource = null;
|
|
sourceMappingActive = false;
|
|
} else if (sourceMappingActive) {
|
|
map.addMapping({
|
|
source: original.source,
|
|
original: {
|
|
line: original.line,
|
|
column: original.column
|
|
},
|
|
generated: {
|
|
line: generated.line,
|
|
column: generated.column
|
|
},
|
|
name: original.name
|
|
});
|
|
}
|
|
} else {
|
|
generated.column++;
|
|
}
|
|
}
|
|
});
|
|
this.walkSourceContents(function (sourceFile, sourceContent) {
|
|
map.setSourceContent(sourceFile, sourceContent);
|
|
});
|
|
|
|
return { code: generated.code, map: map };
|
|
};
|
|
|
|
sourceNode.SourceNode = SourceNode;
|
|
return sourceNode;
|
|
}
|
|
|
|
/*
|
|
* Copyright 2009-2011 Mozilla Foundation and contributors
|
|
* Licensed under the New BSD license. See LICENSE.txt or:
|
|
* http://opensource.org/licenses/BSD-3-Clause
|
|
*/
|
|
|
|
var hasRequiredSourceMap;
|
|
|
|
function requireSourceMap () {
|
|
if (hasRequiredSourceMap) return sourceMap;
|
|
hasRequiredSourceMap = 1;
|
|
sourceMap.SourceMapGenerator = requireSourceMapGenerator().SourceMapGenerator;
|
|
sourceMap.SourceMapConsumer = requireSourceMapConsumer().SourceMapConsumer;
|
|
sourceMap.SourceNode = requireSourceNode().SourceNode;
|
|
return sourceMap;
|
|
}
|
|
|
|
var hasRequiredUtil;
|
|
|
|
function requireUtil () {
|
|
if (hasRequiredUtil) return util$1;
|
|
hasRequiredUtil = 1;
|
|
Object.defineProperty(util$1, "__esModule", { value: true });
|
|
util$1.isTrailingCommaEnabled = util$1.getParentExportDeclaration = util$1.isExportDeclaration = util$1.fixFaultyLocations = util$1.getTrueLoc = util$1.composeSourceMaps = util$1.copyPos = util$1.comparePos = util$1.getUnionOfKeys = util$1.getOption = util$1.isBrowser = util$1.getLineTerminator = void 0;
|
|
var tslib_1 = require$$0;
|
|
var tiny_invariant_1 = tslib_1.__importDefault(/*@__PURE__*/ requireTinyInvariant_cjs());
|
|
var types = tslib_1.__importStar(requireMain$1());
|
|
var n = types.namedTypes;
|
|
var source_map_1 = tslib_1.__importDefault(requireSourceMap());
|
|
var SourceMapConsumer = source_map_1.default.SourceMapConsumer;
|
|
var SourceMapGenerator = source_map_1.default.SourceMapGenerator;
|
|
var hasOwn = Object.prototype.hasOwnProperty;
|
|
function getLineTerminator() {
|
|
return isBrowser() ? "\n" : require$$4.EOL || "\n";
|
|
}
|
|
util$1.getLineTerminator = getLineTerminator;
|
|
function isBrowser() {
|
|
return (typeof window !== "undefined" && typeof window.document !== "undefined");
|
|
}
|
|
util$1.isBrowser = isBrowser;
|
|
function getOption(options, key, defaultValue) {
|
|
if (options && hasOwn.call(options, key)) {
|
|
return options[key];
|
|
}
|
|
return defaultValue;
|
|
}
|
|
util$1.getOption = getOption;
|
|
function getUnionOfKeys() {
|
|
var args = [];
|
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
args[_i] = arguments[_i];
|
|
}
|
|
var result = {};
|
|
var argc = args.length;
|
|
for (var i = 0; i < argc; ++i) {
|
|
var keys = Object.keys(args[i]);
|
|
var keyCount = keys.length;
|
|
for (var j = 0; j < keyCount; ++j) {
|
|
result[keys[j]] = true;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
util$1.getUnionOfKeys = getUnionOfKeys;
|
|
function comparePos(pos1, pos2) {
|
|
return pos1.line - pos2.line || pos1.column - pos2.column;
|
|
}
|
|
util$1.comparePos = comparePos;
|
|
function copyPos(pos) {
|
|
return {
|
|
line: pos.line,
|
|
column: pos.column,
|
|
};
|
|
}
|
|
util$1.copyPos = copyPos;
|
|
function composeSourceMaps(formerMap, latterMap) {
|
|
if (formerMap) {
|
|
if (!latterMap) {
|
|
return formerMap;
|
|
}
|
|
}
|
|
else {
|
|
return latterMap || null;
|
|
}
|
|
var smcFormer = new SourceMapConsumer(formerMap);
|
|
var smcLatter = new SourceMapConsumer(latterMap);
|
|
var smg = new SourceMapGenerator({
|
|
file: latterMap.file,
|
|
sourceRoot: latterMap.sourceRoot,
|
|
});
|
|
var sourcesToContents = {};
|
|
smcLatter.eachMapping(function (mapping) {
|
|
var origPos = smcFormer.originalPositionFor({
|
|
line: mapping.originalLine,
|
|
column: mapping.originalColumn,
|
|
});
|
|
var sourceName = origPos.source;
|
|
if (sourceName === null) {
|
|
return;
|
|
}
|
|
smg.addMapping({
|
|
source: sourceName,
|
|
original: copyPos(origPos),
|
|
generated: {
|
|
line: mapping.generatedLine,
|
|
column: mapping.generatedColumn,
|
|
},
|
|
name: mapping.name,
|
|
});
|
|
var sourceContent = smcFormer.sourceContentFor(sourceName);
|
|
if (sourceContent && !hasOwn.call(sourcesToContents, sourceName)) {
|
|
sourcesToContents[sourceName] = sourceContent;
|
|
smg.setSourceContent(sourceName, sourceContent);
|
|
}
|
|
});
|
|
return smg.toJSON();
|
|
}
|
|
util$1.composeSourceMaps = composeSourceMaps;
|
|
function getTrueLoc(node, lines) {
|
|
// It's possible that node is newly-created (not parsed by Esprima),
|
|
// in which case it probably won't have a .loc property (or an
|
|
// .original property for that matter). That's fine; we'll just
|
|
// pretty-print it as usual.
|
|
if (!node.loc) {
|
|
return null;
|
|
}
|
|
var result = {
|
|
start: node.loc.start,
|
|
end: node.loc.end,
|
|
};
|
|
function include(node) {
|
|
expandLoc(result, node.loc);
|
|
}
|
|
// If the node is an export declaration and its .declaration has any
|
|
// decorators, their locations might contribute to the true start/end
|
|
// positions of the export declaration node.
|
|
if (node.declaration &&
|
|
node.declaration.decorators &&
|
|
isExportDeclaration(node)) {
|
|
node.declaration.decorators.forEach(include);
|
|
}
|
|
if (comparePos(result.start, result.end) < 0) {
|
|
// Trim leading whitespace.
|
|
result.start = copyPos(result.start);
|
|
lines.skipSpaces(result.start, false, true);
|
|
if (comparePos(result.start, result.end) < 0) {
|
|
// Trim trailing whitespace, if the end location is not already the
|
|
// same as the start location.
|
|
result.end = copyPos(result.end);
|
|
lines.skipSpaces(result.end, true, true);
|
|
}
|
|
}
|
|
// If the node has any comments, their locations might contribute to
|
|
// the true start/end positions of the node.
|
|
if (node.comments) {
|
|
node.comments.forEach(include);
|
|
}
|
|
return result;
|
|
}
|
|
util$1.getTrueLoc = getTrueLoc;
|
|
function expandLoc(parentLoc, childLoc) {
|
|
if (parentLoc && childLoc) {
|
|
if (comparePos(childLoc.start, parentLoc.start) < 0) {
|
|
parentLoc.start = childLoc.start;
|
|
}
|
|
if (comparePos(parentLoc.end, childLoc.end) < 0) {
|
|
parentLoc.end = childLoc.end;
|
|
}
|
|
}
|
|
}
|
|
function fixFaultyLocations(node, lines) {
|
|
var loc = node.loc;
|
|
if (loc) {
|
|
if (loc.start.line < 1) {
|
|
loc.start.line = 1;
|
|
}
|
|
if (loc.end.line < 1) {
|
|
loc.end.line = 1;
|
|
}
|
|
}
|
|
if (node.type === "File") {
|
|
// Babylon returns File nodes whose .loc.{start,end} do not include
|
|
// leading or trailing whitespace.
|
|
loc.start = lines.firstPos();
|
|
loc.end = lines.lastPos();
|
|
}
|
|
fixForLoopHead(node, lines);
|
|
fixTemplateLiteral(node, lines);
|
|
if (loc && node.decorators) {
|
|
// Expand the .loc of the node responsible for printing the decorators
|
|
// (here, the decorated node) so that it includes node.decorators.
|
|
node.decorators.forEach(function (decorator) {
|
|
expandLoc(loc, decorator.loc);
|
|
});
|
|
}
|
|
else if (node.declaration && isExportDeclaration(node)) {
|
|
// Nullify .loc information for the child declaration so that we never
|
|
// try to reprint it without also reprinting the export declaration.
|
|
node.declaration.loc = null;
|
|
// Expand the .loc of the node responsible for printing the decorators
|
|
// (here, the export declaration) so that it includes node.decorators.
|
|
var decorators = node.declaration.decorators;
|
|
if (decorators) {
|
|
decorators.forEach(function (decorator) {
|
|
expandLoc(loc, decorator.loc);
|
|
});
|
|
}
|
|
}
|
|
else if ((n.MethodDefinition && n.MethodDefinition.check(node)) ||
|
|
(n.Property.check(node) && (node.method || node.shorthand))) {
|
|
// If the node is a MethodDefinition or a .method or .shorthand
|
|
// Property, then the location information stored in
|
|
// node.value.loc is very likely untrustworthy (just the {body}
|
|
// part of a method, or nothing in the case of shorthand
|
|
// properties), so we null out that information to prevent
|
|
// accidental reuse of bogus source code during reprinting.
|
|
node.value.loc = null;
|
|
if (n.FunctionExpression.check(node.value)) {
|
|
// FunctionExpression method values should be anonymous,
|
|
// because their .id fields are ignored anyway.
|
|
node.value.id = null;
|
|
}
|
|
}
|
|
else if (node.type === "ObjectTypeProperty") {
|
|
var loc_1 = node.loc;
|
|
var end = loc_1 && loc_1.end;
|
|
if (end) {
|
|
end = copyPos(end);
|
|
if (lines.prevPos(end) && lines.charAt(end) === ",") {
|
|
// Some parsers accidentally include trailing commas in the
|
|
// .loc.end information for ObjectTypeProperty nodes.
|
|
if ((end = lines.skipSpaces(end, true, true))) {
|
|
loc_1.end = end;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
util$1.fixFaultyLocations = fixFaultyLocations;
|
|
function fixForLoopHead(node, lines) {
|
|
if (node.type !== "ForStatement") {
|
|
return;
|
|
}
|
|
function fix(child) {
|
|
var loc = child && child.loc;
|
|
var start = loc && loc.start;
|
|
var end = loc && copyPos(loc.end);
|
|
while (start && end && comparePos(start, end) < 0) {
|
|
lines.prevPos(end);
|
|
if (lines.charAt(end) === ";") {
|
|
// Update child.loc.end to *exclude* the ';' character.
|
|
loc.end.line = end.line;
|
|
loc.end.column = end.column;
|
|
}
|
|
else {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
fix(node.init);
|
|
fix(node.test);
|
|
fix(node.update);
|
|
}
|
|
function fixTemplateLiteral(node, lines) {
|
|
if (node.type !== "TemplateLiteral") {
|
|
return;
|
|
}
|
|
if (node.quasis.length === 0) {
|
|
// If there are no quasi elements, then there is nothing to fix.
|
|
return;
|
|
}
|
|
// node.loc is not present when using export default with a template literal
|
|
if (node.loc) {
|
|
// First we need to exclude the opening ` from the .loc of the first
|
|
// quasi element, in case the parser accidentally decided to include it.
|
|
var afterLeftBackTickPos = copyPos(node.loc.start);
|
|
(0, tiny_invariant_1.default)(lines.charAt(afterLeftBackTickPos) === "`");
|
|
(0, tiny_invariant_1.default)(lines.nextPos(afterLeftBackTickPos));
|
|
var firstQuasi = node.quasis[0];
|
|
if (comparePos(firstQuasi.loc.start, afterLeftBackTickPos) < 0) {
|
|
firstQuasi.loc.start = afterLeftBackTickPos;
|
|
}
|
|
// Next we need to exclude the closing ` from the .loc of the last quasi
|
|
// element, in case the parser accidentally decided to include it.
|
|
var rightBackTickPos = copyPos(node.loc.end);
|
|
(0, tiny_invariant_1.default)(lines.prevPos(rightBackTickPos));
|
|
(0, tiny_invariant_1.default)(lines.charAt(rightBackTickPos) === "`");
|
|
var lastQuasi = node.quasis[node.quasis.length - 1];
|
|
if (comparePos(rightBackTickPos, lastQuasi.loc.end) < 0) {
|
|
lastQuasi.loc.end = rightBackTickPos;
|
|
}
|
|
}
|
|
// Now we need to exclude ${ and } characters from the .loc's of all
|
|
// quasi elements, since some parsers accidentally include them.
|
|
node.expressions.forEach(function (expr, i) {
|
|
// Rewind from expr.loc.start over any whitespace and the ${ that
|
|
// precedes the expression. The position of the $ should be the same
|
|
// as the .loc.end of the preceding quasi element, but some parsers
|
|
// accidentally include the ${ in the .loc of the quasi element.
|
|
var dollarCurlyPos = lines.skipSpaces(expr.loc.start, true, false);
|
|
if (lines.prevPos(dollarCurlyPos) &&
|
|
lines.charAt(dollarCurlyPos) === "{" &&
|
|
lines.prevPos(dollarCurlyPos) &&
|
|
lines.charAt(dollarCurlyPos) === "$") {
|
|
var quasiBefore = node.quasis[i];
|
|
if (comparePos(dollarCurlyPos, quasiBefore.loc.end) < 0) {
|
|
quasiBefore.loc.end = dollarCurlyPos;
|
|
}
|
|
}
|
|
// Likewise, some parsers accidentally include the } that follows
|
|
// the expression in the .loc of the following quasi element.
|
|
var rightCurlyPos = lines.skipSpaces(expr.loc.end, false, false);
|
|
if (lines.charAt(rightCurlyPos) === "}") {
|
|
(0, tiny_invariant_1.default)(lines.nextPos(rightCurlyPos));
|
|
// Now rightCurlyPos is technically the position just after the }.
|
|
var quasiAfter = node.quasis[i + 1];
|
|
if (comparePos(quasiAfter.loc.start, rightCurlyPos) < 0) {
|
|
quasiAfter.loc.start = rightCurlyPos;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
function isExportDeclaration(node) {
|
|
if (node)
|
|
switch (node.type) {
|
|
case "ExportDeclaration":
|
|
case "ExportDefaultDeclaration":
|
|
case "ExportDefaultSpecifier":
|
|
case "DeclareExportDeclaration":
|
|
case "ExportNamedDeclaration":
|
|
case "ExportAllDeclaration":
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
util$1.isExportDeclaration = isExportDeclaration;
|
|
function getParentExportDeclaration(path) {
|
|
var parentNode = path.getParentNode();
|
|
if (path.getName() === "declaration" && isExportDeclaration(parentNode)) {
|
|
return parentNode;
|
|
}
|
|
return null;
|
|
}
|
|
util$1.getParentExportDeclaration = getParentExportDeclaration;
|
|
function isTrailingCommaEnabled(options, context) {
|
|
var trailingComma = options.trailingComma;
|
|
if (typeof trailingComma === "object") {
|
|
return !!trailingComma[context];
|
|
}
|
|
return !!trailingComma;
|
|
}
|
|
util$1.isTrailingCommaEnabled = isTrailingCommaEnabled;
|
|
return util$1;
|
|
}
|
|
|
|
var esprima$2 = {};
|
|
|
|
var esprima$1 = {exports: {}};
|
|
|
|
var esprima = esprima$1.exports;
|
|
|
|
var hasRequiredEsprima$1;
|
|
|
|
function requireEsprima$1 () {
|
|
if (hasRequiredEsprima$1) return esprima$1.exports;
|
|
hasRequiredEsprima$1 = 1;
|
|
(function (module, exports$1) {
|
|
(function webpackUniversalModuleDefinition(root, factory) {
|
|
/* istanbul ignore next */
|
|
module.exports = factory();
|
|
})(esprima, function() {
|
|
return /******/ (function(modules) { // webpackBootstrap
|
|
/******/ // The module cache
|
|
/******/ var installedModules = {};
|
|
|
|
/******/ // The require function
|
|
/******/ function __webpack_require__(moduleId) {
|
|
|
|
/******/ // Check if module is in cache
|
|
/* istanbul ignore if */
|
|
/******/ if(installedModules[moduleId])
|
|
/******/ return installedModules[moduleId].exports;
|
|
|
|
/******/ // Create a new module (and put it into the cache)
|
|
/******/ var module = installedModules[moduleId] = {
|
|
/******/ exports: {},
|
|
/******/ id: moduleId,
|
|
/******/ loaded: false
|
|
/******/ };
|
|
|
|
/******/ // Execute the module function
|
|
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
|
|
|
/******/ // Flag the module as loaded
|
|
/******/ module.loaded = true;
|
|
|
|
/******/ // Return the exports of the module
|
|
/******/ return module.exports;
|
|
/******/ }
|
|
|
|
|
|
/******/ // expose the modules object (__webpack_modules__)
|
|
/******/ __webpack_require__.m = modules;
|
|
|
|
/******/ // expose the module cache
|
|
/******/ __webpack_require__.c = installedModules;
|
|
|
|
/******/ // __webpack_public_path__
|
|
/******/ __webpack_require__.p = "";
|
|
|
|
/******/ // Load entry module and return exports
|
|
/******/ return __webpack_require__(0);
|
|
/******/ })
|
|
/************************************************************************/
|
|
/******/ ([
|
|
/* 0 */
|
|
/***/ function(module, exports$1, __webpack_require__) {
|
|
/*
|
|
Copyright JS Foundation and other contributors, https://js.foundation/
|
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
modification, are permitted provided that the following conditions are met:
|
|
|
|
* Redistributions of source code must retain the above copyright
|
|
notice, this list of conditions and the following disclaimer.
|
|
* Redistributions in binary form must reproduce the above copyright
|
|
notice, this list of conditions and the following disclaimer in the
|
|
documentation and/or other materials provided with the distribution.
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
|
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
var comment_handler_1 = __webpack_require__(1);
|
|
var jsx_parser_1 = __webpack_require__(3);
|
|
var parser_1 = __webpack_require__(8);
|
|
var tokenizer_1 = __webpack_require__(15);
|
|
function parse(code, options, delegate) {
|
|
var commentHandler = null;
|
|
var proxyDelegate = function (node, metadata) {
|
|
if (delegate) {
|
|
delegate(node, metadata);
|
|
}
|
|
if (commentHandler) {
|
|
commentHandler.visit(node, metadata);
|
|
}
|
|
};
|
|
var parserDelegate = (typeof delegate === 'function') ? proxyDelegate : null;
|
|
var collectComment = false;
|
|
if (options) {
|
|
collectComment = (typeof options.comment === 'boolean' && options.comment);
|
|
var attachComment = (typeof options.attachComment === 'boolean' && options.attachComment);
|
|
if (collectComment || attachComment) {
|
|
commentHandler = new comment_handler_1.CommentHandler();
|
|
commentHandler.attach = attachComment;
|
|
options.comment = true;
|
|
parserDelegate = proxyDelegate;
|
|
}
|
|
}
|
|
var isModule = false;
|
|
if (options && typeof options.sourceType === 'string') {
|
|
isModule = (options.sourceType === 'module');
|
|
}
|
|
var parser;
|
|
if (options && typeof options.jsx === 'boolean' && options.jsx) {
|
|
parser = new jsx_parser_1.JSXParser(code, options, parserDelegate);
|
|
}
|
|
else {
|
|
parser = new parser_1.Parser(code, options, parserDelegate);
|
|
}
|
|
var program = isModule ? parser.parseModule() : parser.parseScript();
|
|
var ast = program;
|
|
if (collectComment && commentHandler) {
|
|
ast.comments = commentHandler.comments;
|
|
}
|
|
if (parser.config.tokens) {
|
|
ast.tokens = parser.tokens;
|
|
}
|
|
if (parser.config.tolerant) {
|
|
ast.errors = parser.errorHandler.errors;
|
|
}
|
|
return ast;
|
|
}
|
|
exports$1.parse = parse;
|
|
function parseModule(code, options, delegate) {
|
|
var parsingOptions = options || {};
|
|
parsingOptions.sourceType = 'module';
|
|
return parse(code, parsingOptions, delegate);
|
|
}
|
|
exports$1.parseModule = parseModule;
|
|
function parseScript(code, options, delegate) {
|
|
var parsingOptions = options || {};
|
|
parsingOptions.sourceType = 'script';
|
|
return parse(code, parsingOptions, delegate);
|
|
}
|
|
exports$1.parseScript = parseScript;
|
|
function tokenize(code, options, delegate) {
|
|
var tokenizer = new tokenizer_1.Tokenizer(code, options);
|
|
var tokens;
|
|
tokens = [];
|
|
try {
|
|
while (true) {
|
|
var token = tokenizer.getNextToken();
|
|
if (!token) {
|
|
break;
|
|
}
|
|
if (delegate) {
|
|
token = delegate(token);
|
|
}
|
|
tokens.push(token);
|
|
}
|
|
}
|
|
catch (e) {
|
|
tokenizer.errorHandler.tolerate(e);
|
|
}
|
|
if (tokenizer.errorHandler.tolerant) {
|
|
tokens.errors = tokenizer.errors();
|
|
}
|
|
return tokens;
|
|
}
|
|
exports$1.tokenize = tokenize;
|
|
var syntax_1 = __webpack_require__(2);
|
|
exports$1.Syntax = syntax_1.Syntax;
|
|
// Sync with *.json manifests.
|
|
exports$1.version = '4.0.1';
|
|
|
|
|
|
/***/ },
|
|
/* 1 */
|
|
/***/ function(module, exports$1, __webpack_require__) {
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
var syntax_1 = __webpack_require__(2);
|
|
var CommentHandler = (function () {
|
|
function CommentHandler() {
|
|
this.attach = false;
|
|
this.comments = [];
|
|
this.stack = [];
|
|
this.leading = [];
|
|
this.trailing = [];
|
|
}
|
|
CommentHandler.prototype.insertInnerComments = function (node, metadata) {
|
|
// innnerComments for properties empty block
|
|
// `function a() {/** comments **\/}`
|
|
if (node.type === syntax_1.Syntax.BlockStatement && node.body.length === 0) {
|
|
var innerComments = [];
|
|
for (var i = this.leading.length - 1; i >= 0; --i) {
|
|
var entry = this.leading[i];
|
|
if (metadata.end.offset >= entry.start) {
|
|
innerComments.unshift(entry.comment);
|
|
this.leading.splice(i, 1);
|
|
this.trailing.splice(i, 1);
|
|
}
|
|
}
|
|
if (innerComments.length) {
|
|
node.innerComments = innerComments;
|
|
}
|
|
}
|
|
};
|
|
CommentHandler.prototype.findTrailingComments = function (metadata) {
|
|
var trailingComments = [];
|
|
if (this.trailing.length > 0) {
|
|
for (var i = this.trailing.length - 1; i >= 0; --i) {
|
|
var entry_1 = this.trailing[i];
|
|
if (entry_1.start >= metadata.end.offset) {
|
|
trailingComments.unshift(entry_1.comment);
|
|
}
|
|
}
|
|
this.trailing.length = 0;
|
|
return trailingComments;
|
|
}
|
|
var entry = this.stack[this.stack.length - 1];
|
|
if (entry && entry.node.trailingComments) {
|
|
var firstComment = entry.node.trailingComments[0];
|
|
if (firstComment && firstComment.range[0] >= metadata.end.offset) {
|
|
trailingComments = entry.node.trailingComments;
|
|
delete entry.node.trailingComments;
|
|
}
|
|
}
|
|
return trailingComments;
|
|
};
|
|
CommentHandler.prototype.findLeadingComments = function (metadata) {
|
|
var leadingComments = [];
|
|
var target;
|
|
while (this.stack.length > 0) {
|
|
var entry = this.stack[this.stack.length - 1];
|
|
if (entry && entry.start >= metadata.start.offset) {
|
|
target = entry.node;
|
|
this.stack.pop();
|
|
}
|
|
else {
|
|
break;
|
|
}
|
|
}
|
|
if (target) {
|
|
var count = target.leadingComments ? target.leadingComments.length : 0;
|
|
for (var i = count - 1; i >= 0; --i) {
|
|
var comment = target.leadingComments[i];
|
|
if (comment.range[1] <= metadata.start.offset) {
|
|
leadingComments.unshift(comment);
|
|
target.leadingComments.splice(i, 1);
|
|
}
|
|
}
|
|
if (target.leadingComments && target.leadingComments.length === 0) {
|
|
delete target.leadingComments;
|
|
}
|
|
return leadingComments;
|
|
}
|
|
for (var i = this.leading.length - 1; i >= 0; --i) {
|
|
var entry = this.leading[i];
|
|
if (entry.start <= metadata.start.offset) {
|
|
leadingComments.unshift(entry.comment);
|
|
this.leading.splice(i, 1);
|
|
}
|
|
}
|
|
return leadingComments;
|
|
};
|
|
CommentHandler.prototype.visitNode = function (node, metadata) {
|
|
if (node.type === syntax_1.Syntax.Program && node.body.length > 0) {
|
|
return;
|
|
}
|
|
this.insertInnerComments(node, metadata);
|
|
var trailingComments = this.findTrailingComments(metadata);
|
|
var leadingComments = this.findLeadingComments(metadata);
|
|
if (leadingComments.length > 0) {
|
|
node.leadingComments = leadingComments;
|
|
}
|
|
if (trailingComments.length > 0) {
|
|
node.trailingComments = trailingComments;
|
|
}
|
|
this.stack.push({
|
|
node: node,
|
|
start: metadata.start.offset
|
|
});
|
|
};
|
|
CommentHandler.prototype.visitComment = function (node, metadata) {
|
|
var type = (node.type[0] === 'L') ? 'Line' : 'Block';
|
|
var comment = {
|
|
type: type,
|
|
value: node.value
|
|
};
|
|
if (node.range) {
|
|
comment.range = node.range;
|
|
}
|
|
if (node.loc) {
|
|
comment.loc = node.loc;
|
|
}
|
|
this.comments.push(comment);
|
|
if (this.attach) {
|
|
var entry = {
|
|
comment: {
|
|
type: type,
|
|
value: node.value,
|
|
range: [metadata.start.offset, metadata.end.offset]
|
|
},
|
|
start: metadata.start.offset
|
|
};
|
|
if (node.loc) {
|
|
entry.comment.loc = node.loc;
|
|
}
|
|
node.type = type;
|
|
this.leading.push(entry);
|
|
this.trailing.push(entry);
|
|
}
|
|
};
|
|
CommentHandler.prototype.visit = function (node, metadata) {
|
|
if (node.type === 'LineComment') {
|
|
this.visitComment(node, metadata);
|
|
}
|
|
else if (node.type === 'BlockComment') {
|
|
this.visitComment(node, metadata);
|
|
}
|
|
else if (this.attach) {
|
|
this.visitNode(node, metadata);
|
|
}
|
|
};
|
|
return CommentHandler;
|
|
}());
|
|
exports$1.CommentHandler = CommentHandler;
|
|
|
|
|
|
/***/ },
|
|
/* 2 */
|
|
/***/ function(module, exports$1) {
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
exports$1.Syntax = {
|
|
AssignmentExpression: 'AssignmentExpression',
|
|
AssignmentPattern: 'AssignmentPattern',
|
|
ArrayExpression: 'ArrayExpression',
|
|
ArrayPattern: 'ArrayPattern',
|
|
ArrowFunctionExpression: 'ArrowFunctionExpression',
|
|
AwaitExpression: 'AwaitExpression',
|
|
BlockStatement: 'BlockStatement',
|
|
BinaryExpression: 'BinaryExpression',
|
|
BreakStatement: 'BreakStatement',
|
|
CallExpression: 'CallExpression',
|
|
CatchClause: 'CatchClause',
|
|
ClassBody: 'ClassBody',
|
|
ClassDeclaration: 'ClassDeclaration',
|
|
ClassExpression: 'ClassExpression',
|
|
ConditionalExpression: 'ConditionalExpression',
|
|
ContinueStatement: 'ContinueStatement',
|
|
DoWhileStatement: 'DoWhileStatement',
|
|
DebuggerStatement: 'DebuggerStatement',
|
|
EmptyStatement: 'EmptyStatement',
|
|
ExportAllDeclaration: 'ExportAllDeclaration',
|
|
ExportDefaultDeclaration: 'ExportDefaultDeclaration',
|
|
ExportNamedDeclaration: 'ExportNamedDeclaration',
|
|
ExportSpecifier: 'ExportSpecifier',
|
|
ExpressionStatement: 'ExpressionStatement',
|
|
ForStatement: 'ForStatement',
|
|
ForOfStatement: 'ForOfStatement',
|
|
ForInStatement: 'ForInStatement',
|
|
FunctionDeclaration: 'FunctionDeclaration',
|
|
FunctionExpression: 'FunctionExpression',
|
|
Identifier: 'Identifier',
|
|
IfStatement: 'IfStatement',
|
|
ImportDeclaration: 'ImportDeclaration',
|
|
ImportDefaultSpecifier: 'ImportDefaultSpecifier',
|
|
ImportNamespaceSpecifier: 'ImportNamespaceSpecifier',
|
|
ImportSpecifier: 'ImportSpecifier',
|
|
Literal: 'Literal',
|
|
LabeledStatement: 'LabeledStatement',
|
|
LogicalExpression: 'LogicalExpression',
|
|
MemberExpression: 'MemberExpression',
|
|
MetaProperty: 'MetaProperty',
|
|
MethodDefinition: 'MethodDefinition',
|
|
NewExpression: 'NewExpression',
|
|
ObjectExpression: 'ObjectExpression',
|
|
ObjectPattern: 'ObjectPattern',
|
|
Program: 'Program',
|
|
Property: 'Property',
|
|
RestElement: 'RestElement',
|
|
ReturnStatement: 'ReturnStatement',
|
|
SequenceExpression: 'SequenceExpression',
|
|
SpreadElement: 'SpreadElement',
|
|
Super: 'Super',
|
|
SwitchCase: 'SwitchCase',
|
|
SwitchStatement: 'SwitchStatement',
|
|
TaggedTemplateExpression: 'TaggedTemplateExpression',
|
|
TemplateElement: 'TemplateElement',
|
|
TemplateLiteral: 'TemplateLiteral',
|
|
ThisExpression: 'ThisExpression',
|
|
ThrowStatement: 'ThrowStatement',
|
|
TryStatement: 'TryStatement',
|
|
UnaryExpression: 'UnaryExpression',
|
|
UpdateExpression: 'UpdateExpression',
|
|
VariableDeclaration: 'VariableDeclaration',
|
|
VariableDeclarator: 'VariableDeclarator',
|
|
WhileStatement: 'WhileStatement',
|
|
WithStatement: 'WithStatement',
|
|
YieldExpression: 'YieldExpression'
|
|
};
|
|
|
|
|
|
/***/ },
|
|
/* 3 */
|
|
/***/ function(module, exports$1, __webpack_require__) {
|
|
/* istanbul ignore next */
|
|
var __extends = (this && this.__extends) || (function () {
|
|
var extendStatics = Object.setPrototypeOf ||
|
|
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
|
return function (d, b) {
|
|
extendStatics(d, b);
|
|
function __() { this.constructor = d; }
|
|
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
};
|
|
})();
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
var character_1 = __webpack_require__(4);
|
|
var JSXNode = __webpack_require__(5);
|
|
var jsx_syntax_1 = __webpack_require__(6);
|
|
var Node = __webpack_require__(7);
|
|
var parser_1 = __webpack_require__(8);
|
|
var token_1 = __webpack_require__(13);
|
|
var xhtml_entities_1 = __webpack_require__(14);
|
|
token_1.TokenName[100 /* Identifier */] = 'JSXIdentifier';
|
|
token_1.TokenName[101 /* Text */] = 'JSXText';
|
|
// Fully qualified element name, e.g. <svg:path> returns "svg:path"
|
|
function getQualifiedElementName(elementName) {
|
|
var qualifiedName;
|
|
switch (elementName.type) {
|
|
case jsx_syntax_1.JSXSyntax.JSXIdentifier:
|
|
var id = elementName;
|
|
qualifiedName = id.name;
|
|
break;
|
|
case jsx_syntax_1.JSXSyntax.JSXNamespacedName:
|
|
var ns = elementName;
|
|
qualifiedName = getQualifiedElementName(ns.namespace) + ':' +
|
|
getQualifiedElementName(ns.name);
|
|
break;
|
|
case jsx_syntax_1.JSXSyntax.JSXMemberExpression:
|
|
var expr = elementName;
|
|
qualifiedName = getQualifiedElementName(expr.object) + '.' +
|
|
getQualifiedElementName(expr.property);
|
|
break;
|
|
}
|
|
return qualifiedName;
|
|
}
|
|
var JSXParser = (function (_super) {
|
|
__extends(JSXParser, _super);
|
|
function JSXParser(code, options, delegate) {
|
|
return _super.call(this, code, options, delegate) || this;
|
|
}
|
|
JSXParser.prototype.parsePrimaryExpression = function () {
|
|
return this.match('<') ? this.parseJSXRoot() : _super.prototype.parsePrimaryExpression.call(this);
|
|
};
|
|
JSXParser.prototype.startJSX = function () {
|
|
// Unwind the scanner before the lookahead token.
|
|
this.scanner.index = this.startMarker.index;
|
|
this.scanner.lineNumber = this.startMarker.line;
|
|
this.scanner.lineStart = this.startMarker.index - this.startMarker.column;
|
|
};
|
|
JSXParser.prototype.finishJSX = function () {
|
|
// Prime the next lookahead.
|
|
this.nextToken();
|
|
};
|
|
JSXParser.prototype.reenterJSX = function () {
|
|
this.startJSX();
|
|
this.expectJSX('}');
|
|
// Pop the closing '}' added from the lookahead.
|
|
if (this.config.tokens) {
|
|
this.tokens.pop();
|
|
}
|
|
};
|
|
JSXParser.prototype.createJSXNode = function () {
|
|
this.collectComments();
|
|
return {
|
|
index: this.scanner.index,
|
|
line: this.scanner.lineNumber,
|
|
column: this.scanner.index - this.scanner.lineStart
|
|
};
|
|
};
|
|
JSXParser.prototype.createJSXChildNode = function () {
|
|
return {
|
|
index: this.scanner.index,
|
|
line: this.scanner.lineNumber,
|
|
column: this.scanner.index - this.scanner.lineStart
|
|
};
|
|
};
|
|
JSXParser.prototype.scanXHTMLEntity = function (quote) {
|
|
var result = '&';
|
|
var valid = true;
|
|
var terminated = false;
|
|
var numeric = false;
|
|
var hex = false;
|
|
while (!this.scanner.eof() && valid && !terminated) {
|
|
var ch = this.scanner.source[this.scanner.index];
|
|
if (ch === quote) {
|
|
break;
|
|
}
|
|
terminated = (ch === ';');
|
|
result += ch;
|
|
++this.scanner.index;
|
|
if (!terminated) {
|
|
switch (result.length) {
|
|
case 2:
|
|
// e.g. '{'
|
|
numeric = (ch === '#');
|
|
break;
|
|
case 3:
|
|
if (numeric) {
|
|
// e.g. 'A'
|
|
hex = (ch === 'x');
|
|
valid = hex || character_1.Character.isDecimalDigit(ch.charCodeAt(0));
|
|
numeric = numeric && !hex;
|
|
}
|
|
break;
|
|
default:
|
|
valid = valid && !(numeric && !character_1.Character.isDecimalDigit(ch.charCodeAt(0)));
|
|
valid = valid && !(hex && !character_1.Character.isHexDigit(ch.charCodeAt(0)));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (valid && terminated && result.length > 2) {
|
|
// e.g. 'A' becomes just '#x41'
|
|
var str = result.substr(1, result.length - 2);
|
|
if (numeric && str.length > 1) {
|
|
result = String.fromCharCode(parseInt(str.substr(1), 10));
|
|
}
|
|
else if (hex && str.length > 2) {
|
|
result = String.fromCharCode(parseInt('0' + str.substr(1), 16));
|
|
}
|
|
else if (!numeric && !hex && xhtml_entities_1.XHTMLEntities[str]) {
|
|
result = xhtml_entities_1.XHTMLEntities[str];
|
|
}
|
|
}
|
|
return result;
|
|
};
|
|
// Scan the next JSX token. This replaces Scanner#lex when in JSX mode.
|
|
JSXParser.prototype.lexJSX = function () {
|
|
var cp = this.scanner.source.charCodeAt(this.scanner.index);
|
|
// < > / : = { }
|
|
if (cp === 60 || cp === 62 || cp === 47 || cp === 58 || cp === 61 || cp === 123 || cp === 125) {
|
|
var value = this.scanner.source[this.scanner.index++];
|
|
return {
|
|
type: 7 /* Punctuator */,
|
|
value: value,
|
|
lineNumber: this.scanner.lineNumber,
|
|
lineStart: this.scanner.lineStart,
|
|
start: this.scanner.index - 1,
|
|
end: this.scanner.index
|
|
};
|
|
}
|
|
// " '
|
|
if (cp === 34 || cp === 39) {
|
|
var start = this.scanner.index;
|
|
var quote = this.scanner.source[this.scanner.index++];
|
|
var str = '';
|
|
while (!this.scanner.eof()) {
|
|
var ch = this.scanner.source[this.scanner.index++];
|
|
if (ch === quote) {
|
|
break;
|
|
}
|
|
else if (ch === '&') {
|
|
str += this.scanXHTMLEntity(quote);
|
|
}
|
|
else {
|
|
str += ch;
|
|
}
|
|
}
|
|
return {
|
|
type: 8 /* StringLiteral */,
|
|
value: str,
|
|
lineNumber: this.scanner.lineNumber,
|
|
lineStart: this.scanner.lineStart,
|
|
start: start,
|
|
end: this.scanner.index
|
|
};
|
|
}
|
|
// ... or .
|
|
if (cp === 46) {
|
|
var n1 = this.scanner.source.charCodeAt(this.scanner.index + 1);
|
|
var n2 = this.scanner.source.charCodeAt(this.scanner.index + 2);
|
|
var value = (n1 === 46 && n2 === 46) ? '...' : '.';
|
|
var start = this.scanner.index;
|
|
this.scanner.index += value.length;
|
|
return {
|
|
type: 7 /* Punctuator */,
|
|
value: value,
|
|
lineNumber: this.scanner.lineNumber,
|
|
lineStart: this.scanner.lineStart,
|
|
start: start,
|
|
end: this.scanner.index
|
|
};
|
|
}
|
|
// `
|
|
if (cp === 96) {
|
|
// Only placeholder, since it will be rescanned as a real assignment expression.
|
|
return {
|
|
type: 10 /* Template */,
|
|
value: '',
|
|
lineNumber: this.scanner.lineNumber,
|
|
lineStart: this.scanner.lineStart,
|
|
start: this.scanner.index,
|
|
end: this.scanner.index
|
|
};
|
|
}
|
|
// Identifer can not contain backslash (char code 92).
|
|
if (character_1.Character.isIdentifierStart(cp) && (cp !== 92)) {
|
|
var start = this.scanner.index;
|
|
++this.scanner.index;
|
|
while (!this.scanner.eof()) {
|
|
var ch = this.scanner.source.charCodeAt(this.scanner.index);
|
|
if (character_1.Character.isIdentifierPart(ch) && (ch !== 92)) {
|
|
++this.scanner.index;
|
|
}
|
|
else if (ch === 45) {
|
|
// Hyphen (char code 45) can be part of an identifier.
|
|
++this.scanner.index;
|
|
}
|
|
else {
|
|
break;
|
|
}
|
|
}
|
|
var id = this.scanner.source.slice(start, this.scanner.index);
|
|
return {
|
|
type: 100 /* Identifier */,
|
|
value: id,
|
|
lineNumber: this.scanner.lineNumber,
|
|
lineStart: this.scanner.lineStart,
|
|
start: start,
|
|
end: this.scanner.index
|
|
};
|
|
}
|
|
return this.scanner.lex();
|
|
};
|
|
JSXParser.prototype.nextJSXToken = function () {
|
|
this.collectComments();
|
|
this.startMarker.index = this.scanner.index;
|
|
this.startMarker.line = this.scanner.lineNumber;
|
|
this.startMarker.column = this.scanner.index - this.scanner.lineStart;
|
|
var token = this.lexJSX();
|
|
this.lastMarker.index = this.scanner.index;
|
|
this.lastMarker.line = this.scanner.lineNumber;
|
|
this.lastMarker.column = this.scanner.index - this.scanner.lineStart;
|
|
if (this.config.tokens) {
|
|
this.tokens.push(this.convertToken(token));
|
|
}
|
|
return token;
|
|
};
|
|
JSXParser.prototype.nextJSXText = function () {
|
|
this.startMarker.index = this.scanner.index;
|
|
this.startMarker.line = this.scanner.lineNumber;
|
|
this.startMarker.column = this.scanner.index - this.scanner.lineStart;
|
|
var start = this.scanner.index;
|
|
var text = '';
|
|
while (!this.scanner.eof()) {
|
|
var ch = this.scanner.source[this.scanner.index];
|
|
if (ch === '{' || ch === '<') {
|
|
break;
|
|
}
|
|
++this.scanner.index;
|
|
text += ch;
|
|
if (character_1.Character.isLineTerminator(ch.charCodeAt(0))) {
|
|
++this.scanner.lineNumber;
|
|
if (ch === '\r' && this.scanner.source[this.scanner.index] === '\n') {
|
|
++this.scanner.index;
|
|
}
|
|
this.scanner.lineStart = this.scanner.index;
|
|
}
|
|
}
|
|
this.lastMarker.index = this.scanner.index;
|
|
this.lastMarker.line = this.scanner.lineNumber;
|
|
this.lastMarker.column = this.scanner.index - this.scanner.lineStart;
|
|
var token = {
|
|
type: 101 /* Text */,
|
|
value: text,
|
|
lineNumber: this.scanner.lineNumber,
|
|
lineStart: this.scanner.lineStart,
|
|
start: start,
|
|
end: this.scanner.index
|
|
};
|
|
if ((text.length > 0) && this.config.tokens) {
|
|
this.tokens.push(this.convertToken(token));
|
|
}
|
|
return token;
|
|
};
|
|
JSXParser.prototype.peekJSXToken = function () {
|
|
var state = this.scanner.saveState();
|
|
this.scanner.scanComments();
|
|
var next = this.lexJSX();
|
|
this.scanner.restoreState(state);
|
|
return next;
|
|
};
|
|
// Expect the next JSX token to match the specified punctuator.
|
|
// If not, an exception will be thrown.
|
|
JSXParser.prototype.expectJSX = function (value) {
|
|
var token = this.nextJSXToken();
|
|
if (token.type !== 7 /* Punctuator */ || token.value !== value) {
|
|
this.throwUnexpectedToken(token);
|
|
}
|
|
};
|
|
// Return true if the next JSX token matches the specified punctuator.
|
|
JSXParser.prototype.matchJSX = function (value) {
|
|
var next = this.peekJSXToken();
|
|
return next.type === 7 /* Punctuator */ && next.value === value;
|
|
};
|
|
JSXParser.prototype.parseJSXIdentifier = function () {
|
|
var node = this.createJSXNode();
|
|
var token = this.nextJSXToken();
|
|
if (token.type !== 100 /* Identifier */) {
|
|
this.throwUnexpectedToken(token);
|
|
}
|
|
return this.finalize(node, new JSXNode.JSXIdentifier(token.value));
|
|
};
|
|
JSXParser.prototype.parseJSXElementName = function () {
|
|
var node = this.createJSXNode();
|
|
var elementName = this.parseJSXIdentifier();
|
|
if (this.matchJSX(':')) {
|
|
var namespace = elementName;
|
|
this.expectJSX(':');
|
|
var name_1 = this.parseJSXIdentifier();
|
|
elementName = this.finalize(node, new JSXNode.JSXNamespacedName(namespace, name_1));
|
|
}
|
|
else if (this.matchJSX('.')) {
|
|
while (this.matchJSX('.')) {
|
|
var object = elementName;
|
|
this.expectJSX('.');
|
|
var property = this.parseJSXIdentifier();
|
|
elementName = this.finalize(node, new JSXNode.JSXMemberExpression(object, property));
|
|
}
|
|
}
|
|
return elementName;
|
|
};
|
|
JSXParser.prototype.parseJSXAttributeName = function () {
|
|
var node = this.createJSXNode();
|
|
var attributeName;
|
|
var identifier = this.parseJSXIdentifier();
|
|
if (this.matchJSX(':')) {
|
|
var namespace = identifier;
|
|
this.expectJSX(':');
|
|
var name_2 = this.parseJSXIdentifier();
|
|
attributeName = this.finalize(node, new JSXNode.JSXNamespacedName(namespace, name_2));
|
|
}
|
|
else {
|
|
attributeName = identifier;
|
|
}
|
|
return attributeName;
|
|
};
|
|
JSXParser.prototype.parseJSXStringLiteralAttribute = function () {
|
|
var node = this.createJSXNode();
|
|
var token = this.nextJSXToken();
|
|
if (token.type !== 8 /* StringLiteral */) {
|
|
this.throwUnexpectedToken(token);
|
|
}
|
|
var raw = this.getTokenRaw(token);
|
|
return this.finalize(node, new Node.Literal(token.value, raw));
|
|
};
|
|
JSXParser.prototype.parseJSXExpressionAttribute = function () {
|
|
var node = this.createJSXNode();
|
|
this.expectJSX('{');
|
|
this.finishJSX();
|
|
if (this.match('}')) {
|
|
this.tolerateError('JSX attributes must only be assigned a non-empty expression');
|
|
}
|
|
var expression = this.parseAssignmentExpression();
|
|
this.reenterJSX();
|
|
return this.finalize(node, new JSXNode.JSXExpressionContainer(expression));
|
|
};
|
|
JSXParser.prototype.parseJSXAttributeValue = function () {
|
|
return this.matchJSX('{') ? this.parseJSXExpressionAttribute() :
|
|
this.matchJSX('<') ? this.parseJSXElement() : this.parseJSXStringLiteralAttribute();
|
|
};
|
|
JSXParser.prototype.parseJSXNameValueAttribute = function () {
|
|
var node = this.createJSXNode();
|
|
var name = this.parseJSXAttributeName();
|
|
var value = null;
|
|
if (this.matchJSX('=')) {
|
|
this.expectJSX('=');
|
|
value = this.parseJSXAttributeValue();
|
|
}
|
|
return this.finalize(node, new JSXNode.JSXAttribute(name, value));
|
|
};
|
|
JSXParser.prototype.parseJSXSpreadAttribute = function () {
|
|
var node = this.createJSXNode();
|
|
this.expectJSX('{');
|
|
this.expectJSX('...');
|
|
this.finishJSX();
|
|
var argument = this.parseAssignmentExpression();
|
|
this.reenterJSX();
|
|
return this.finalize(node, new JSXNode.JSXSpreadAttribute(argument));
|
|
};
|
|
JSXParser.prototype.parseJSXAttributes = function () {
|
|
var attributes = [];
|
|
while (!this.matchJSX('/') && !this.matchJSX('>')) {
|
|
var attribute = this.matchJSX('{') ? this.parseJSXSpreadAttribute() :
|
|
this.parseJSXNameValueAttribute();
|
|
attributes.push(attribute);
|
|
}
|
|
return attributes;
|
|
};
|
|
JSXParser.prototype.parseJSXOpeningElement = function () {
|
|
var node = this.createJSXNode();
|
|
this.expectJSX('<');
|
|
var name = this.parseJSXElementName();
|
|
var attributes = this.parseJSXAttributes();
|
|
var selfClosing = this.matchJSX('/');
|
|
if (selfClosing) {
|
|
this.expectJSX('/');
|
|
}
|
|
this.expectJSX('>');
|
|
return this.finalize(node, new JSXNode.JSXOpeningElement(name, selfClosing, attributes));
|
|
};
|
|
JSXParser.prototype.parseJSXBoundaryElement = function () {
|
|
var node = this.createJSXNode();
|
|
this.expectJSX('<');
|
|
if (this.matchJSX('/')) {
|
|
this.expectJSX('/');
|
|
var name_3 = this.parseJSXElementName();
|
|
this.expectJSX('>');
|
|
return this.finalize(node, new JSXNode.JSXClosingElement(name_3));
|
|
}
|
|
var name = this.parseJSXElementName();
|
|
var attributes = this.parseJSXAttributes();
|
|
var selfClosing = this.matchJSX('/');
|
|
if (selfClosing) {
|
|
this.expectJSX('/');
|
|
}
|
|
this.expectJSX('>');
|
|
return this.finalize(node, new JSXNode.JSXOpeningElement(name, selfClosing, attributes));
|
|
};
|
|
JSXParser.prototype.parseJSXEmptyExpression = function () {
|
|
var node = this.createJSXChildNode();
|
|
this.collectComments();
|
|
this.lastMarker.index = this.scanner.index;
|
|
this.lastMarker.line = this.scanner.lineNumber;
|
|
this.lastMarker.column = this.scanner.index - this.scanner.lineStart;
|
|
return this.finalize(node, new JSXNode.JSXEmptyExpression());
|
|
};
|
|
JSXParser.prototype.parseJSXExpressionContainer = function () {
|
|
var node = this.createJSXNode();
|
|
this.expectJSX('{');
|
|
var expression;
|
|
if (this.matchJSX('}')) {
|
|
expression = this.parseJSXEmptyExpression();
|
|
this.expectJSX('}');
|
|
}
|
|
else {
|
|
this.finishJSX();
|
|
expression = this.parseAssignmentExpression();
|
|
this.reenterJSX();
|
|
}
|
|
return this.finalize(node, new JSXNode.JSXExpressionContainer(expression));
|
|
};
|
|
JSXParser.prototype.parseJSXChildren = function () {
|
|
var children = [];
|
|
while (!this.scanner.eof()) {
|
|
var node = this.createJSXChildNode();
|
|
var token = this.nextJSXText();
|
|
if (token.start < token.end) {
|
|
var raw = this.getTokenRaw(token);
|
|
var child = this.finalize(node, new JSXNode.JSXText(token.value, raw));
|
|
children.push(child);
|
|
}
|
|
if (this.scanner.source[this.scanner.index] === '{') {
|
|
var container = this.parseJSXExpressionContainer();
|
|
children.push(container);
|
|
}
|
|
else {
|
|
break;
|
|
}
|
|
}
|
|
return children;
|
|
};
|
|
JSXParser.prototype.parseComplexJSXElement = function (el) {
|
|
var stack = [];
|
|
while (!this.scanner.eof()) {
|
|
el.children = el.children.concat(this.parseJSXChildren());
|
|
var node = this.createJSXChildNode();
|
|
var element = this.parseJSXBoundaryElement();
|
|
if (element.type === jsx_syntax_1.JSXSyntax.JSXOpeningElement) {
|
|
var opening = element;
|
|
if (opening.selfClosing) {
|
|
var child = this.finalize(node, new JSXNode.JSXElement(opening, [], null));
|
|
el.children.push(child);
|
|
}
|
|
else {
|
|
stack.push(el);
|
|
el = { node: node, opening: opening, closing: null, children: [] };
|
|
}
|
|
}
|
|
if (element.type === jsx_syntax_1.JSXSyntax.JSXClosingElement) {
|
|
el.closing = element;
|
|
var open_1 = getQualifiedElementName(el.opening.name);
|
|
var close_1 = getQualifiedElementName(el.closing.name);
|
|
if (open_1 !== close_1) {
|
|
this.tolerateError('Expected corresponding JSX closing tag for %0', open_1);
|
|
}
|
|
if (stack.length > 0) {
|
|
var child = this.finalize(el.node, new JSXNode.JSXElement(el.opening, el.children, el.closing));
|
|
el = stack[stack.length - 1];
|
|
el.children.push(child);
|
|
stack.pop();
|
|
}
|
|
else {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return el;
|
|
};
|
|
JSXParser.prototype.parseJSXElement = function () {
|
|
var node = this.createJSXNode();
|
|
var opening = this.parseJSXOpeningElement();
|
|
var children = [];
|
|
var closing = null;
|
|
if (!opening.selfClosing) {
|
|
var el = this.parseComplexJSXElement({ node: node, opening: opening, closing: closing, children: children });
|
|
children = el.children;
|
|
closing = el.closing;
|
|
}
|
|
return this.finalize(node, new JSXNode.JSXElement(opening, children, closing));
|
|
};
|
|
JSXParser.prototype.parseJSXRoot = function () {
|
|
// Pop the opening '<' added from the lookahead.
|
|
if (this.config.tokens) {
|
|
this.tokens.pop();
|
|
}
|
|
this.startJSX();
|
|
var element = this.parseJSXElement();
|
|
this.finishJSX();
|
|
return element;
|
|
};
|
|
JSXParser.prototype.isStartOfExpression = function () {
|
|
return _super.prototype.isStartOfExpression.call(this) || this.match('<');
|
|
};
|
|
return JSXParser;
|
|
}(parser_1.Parser));
|
|
exports$1.JSXParser = JSXParser;
|
|
|
|
|
|
/***/ },
|
|
/* 4 */
|
|
/***/ function(module, exports$1) {
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
// See also tools/generate-unicode-regex.js.
|
|
var Regex = {
|
|
// Unicode v8.0.0 NonAsciiIdentifierStart:
|
|
NonAsciiIdentifierStart: /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B4\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309B-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1]|\uD87E[\uDC00-\uDE1D]/,
|
|
// Unicode v8.0.0 NonAsciiIdentifierPart:
|
|
NonAsciiIdentifierPart: /[\xAA\xB5\xB7\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u08A0-\u08B4\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C81-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D01-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1369-\u1371\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1CD0-\u1CD2\u1CD4-\u1CF6\u1CF8\u1CF9\u1D00-\u1DF5\u1DFC-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/
|
|
};
|
|
exports$1.Character = {
|
|
/* tslint:disable:no-bitwise */
|
|
fromCodePoint: function (cp) {
|
|
return (cp < 0x10000) ? String.fromCharCode(cp) :
|
|
String.fromCharCode(0xD800 + ((cp - 0x10000) >> 10)) +
|
|
String.fromCharCode(0xDC00 + ((cp - 0x10000) & 1023));
|
|
},
|
|
// https://tc39.github.io/ecma262/#sec-white-space
|
|
isWhiteSpace: function (cp) {
|
|
return (cp === 0x20) || (cp === 0x09) || (cp === 0x0B) || (cp === 0x0C) || (cp === 0xA0) ||
|
|
(cp >= 0x1680 && [0x1680, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x202F, 0x205F, 0x3000, 0xFEFF].indexOf(cp) >= 0);
|
|
},
|
|
// https://tc39.github.io/ecma262/#sec-line-terminators
|
|
isLineTerminator: function (cp) {
|
|
return (cp === 0x0A) || (cp === 0x0D) || (cp === 0x2028) || (cp === 0x2029);
|
|
},
|
|
// https://tc39.github.io/ecma262/#sec-names-and-keywords
|
|
isIdentifierStart: function (cp) {
|
|
return (cp === 0x24) || (cp === 0x5F) ||
|
|
(cp >= 0x41 && cp <= 0x5A) ||
|
|
(cp >= 0x61 && cp <= 0x7A) ||
|
|
(cp === 0x5C) ||
|
|
((cp >= 0x80) && Regex.NonAsciiIdentifierStart.test(exports$1.Character.fromCodePoint(cp)));
|
|
},
|
|
isIdentifierPart: function (cp) {
|
|
return (cp === 0x24) || (cp === 0x5F) ||
|
|
(cp >= 0x41 && cp <= 0x5A) ||
|
|
(cp >= 0x61 && cp <= 0x7A) ||
|
|
(cp >= 0x30 && cp <= 0x39) ||
|
|
(cp === 0x5C) ||
|
|
((cp >= 0x80) && Regex.NonAsciiIdentifierPart.test(exports$1.Character.fromCodePoint(cp)));
|
|
},
|
|
// https://tc39.github.io/ecma262/#sec-literals-numeric-literals
|
|
isDecimalDigit: function (cp) {
|
|
return (cp >= 0x30 && cp <= 0x39); // 0..9
|
|
},
|
|
isHexDigit: function (cp) {
|
|
return (cp >= 0x30 && cp <= 0x39) ||
|
|
(cp >= 0x41 && cp <= 0x46) ||
|
|
(cp >= 0x61 && cp <= 0x66); // a..f
|
|
},
|
|
isOctalDigit: function (cp) {
|
|
return (cp >= 0x30 && cp <= 0x37); // 0..7
|
|
}
|
|
};
|
|
|
|
|
|
/***/ },
|
|
/* 5 */
|
|
/***/ function(module, exports$1, __webpack_require__) {
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
var jsx_syntax_1 = __webpack_require__(6);
|
|
/* tslint:disable:max-classes-per-file */
|
|
var JSXClosingElement = (function () {
|
|
function JSXClosingElement(name) {
|
|
this.type = jsx_syntax_1.JSXSyntax.JSXClosingElement;
|
|
this.name = name;
|
|
}
|
|
return JSXClosingElement;
|
|
}());
|
|
exports$1.JSXClosingElement = JSXClosingElement;
|
|
var JSXElement = (function () {
|
|
function JSXElement(openingElement, children, closingElement) {
|
|
this.type = jsx_syntax_1.JSXSyntax.JSXElement;
|
|
this.openingElement = openingElement;
|
|
this.children = children;
|
|
this.closingElement = closingElement;
|
|
}
|
|
return JSXElement;
|
|
}());
|
|
exports$1.JSXElement = JSXElement;
|
|
var JSXEmptyExpression = (function () {
|
|
function JSXEmptyExpression() {
|
|
this.type = jsx_syntax_1.JSXSyntax.JSXEmptyExpression;
|
|
}
|
|
return JSXEmptyExpression;
|
|
}());
|
|
exports$1.JSXEmptyExpression = JSXEmptyExpression;
|
|
var JSXExpressionContainer = (function () {
|
|
function JSXExpressionContainer(expression) {
|
|
this.type = jsx_syntax_1.JSXSyntax.JSXExpressionContainer;
|
|
this.expression = expression;
|
|
}
|
|
return JSXExpressionContainer;
|
|
}());
|
|
exports$1.JSXExpressionContainer = JSXExpressionContainer;
|
|
var JSXIdentifier = (function () {
|
|
function JSXIdentifier(name) {
|
|
this.type = jsx_syntax_1.JSXSyntax.JSXIdentifier;
|
|
this.name = name;
|
|
}
|
|
return JSXIdentifier;
|
|
}());
|
|
exports$1.JSXIdentifier = JSXIdentifier;
|
|
var JSXMemberExpression = (function () {
|
|
function JSXMemberExpression(object, property) {
|
|
this.type = jsx_syntax_1.JSXSyntax.JSXMemberExpression;
|
|
this.object = object;
|
|
this.property = property;
|
|
}
|
|
return JSXMemberExpression;
|
|
}());
|
|
exports$1.JSXMemberExpression = JSXMemberExpression;
|
|
var JSXAttribute = (function () {
|
|
function JSXAttribute(name, value) {
|
|
this.type = jsx_syntax_1.JSXSyntax.JSXAttribute;
|
|
this.name = name;
|
|
this.value = value;
|
|
}
|
|
return JSXAttribute;
|
|
}());
|
|
exports$1.JSXAttribute = JSXAttribute;
|
|
var JSXNamespacedName = (function () {
|
|
function JSXNamespacedName(namespace, name) {
|
|
this.type = jsx_syntax_1.JSXSyntax.JSXNamespacedName;
|
|
this.namespace = namespace;
|
|
this.name = name;
|
|
}
|
|
return JSXNamespacedName;
|
|
}());
|
|
exports$1.JSXNamespacedName = JSXNamespacedName;
|
|
var JSXOpeningElement = (function () {
|
|
function JSXOpeningElement(name, selfClosing, attributes) {
|
|
this.type = jsx_syntax_1.JSXSyntax.JSXOpeningElement;
|
|
this.name = name;
|
|
this.selfClosing = selfClosing;
|
|
this.attributes = attributes;
|
|
}
|
|
return JSXOpeningElement;
|
|
}());
|
|
exports$1.JSXOpeningElement = JSXOpeningElement;
|
|
var JSXSpreadAttribute = (function () {
|
|
function JSXSpreadAttribute(argument) {
|
|
this.type = jsx_syntax_1.JSXSyntax.JSXSpreadAttribute;
|
|
this.argument = argument;
|
|
}
|
|
return JSXSpreadAttribute;
|
|
}());
|
|
exports$1.JSXSpreadAttribute = JSXSpreadAttribute;
|
|
var JSXText = (function () {
|
|
function JSXText(value, raw) {
|
|
this.type = jsx_syntax_1.JSXSyntax.JSXText;
|
|
this.value = value;
|
|
this.raw = raw;
|
|
}
|
|
return JSXText;
|
|
}());
|
|
exports$1.JSXText = JSXText;
|
|
|
|
|
|
/***/ },
|
|
/* 6 */
|
|
/***/ function(module, exports$1) {
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
exports$1.JSXSyntax = {
|
|
JSXAttribute: 'JSXAttribute',
|
|
JSXClosingElement: 'JSXClosingElement',
|
|
JSXElement: 'JSXElement',
|
|
JSXEmptyExpression: 'JSXEmptyExpression',
|
|
JSXExpressionContainer: 'JSXExpressionContainer',
|
|
JSXIdentifier: 'JSXIdentifier',
|
|
JSXMemberExpression: 'JSXMemberExpression',
|
|
JSXNamespacedName: 'JSXNamespacedName',
|
|
JSXOpeningElement: 'JSXOpeningElement',
|
|
JSXSpreadAttribute: 'JSXSpreadAttribute',
|
|
JSXText: 'JSXText'
|
|
};
|
|
|
|
|
|
/***/ },
|
|
/* 7 */
|
|
/***/ function(module, exports$1, __webpack_require__) {
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
var syntax_1 = __webpack_require__(2);
|
|
/* tslint:disable:max-classes-per-file */
|
|
var ArrayExpression = (function () {
|
|
function ArrayExpression(elements) {
|
|
this.type = syntax_1.Syntax.ArrayExpression;
|
|
this.elements = elements;
|
|
}
|
|
return ArrayExpression;
|
|
}());
|
|
exports$1.ArrayExpression = ArrayExpression;
|
|
var ArrayPattern = (function () {
|
|
function ArrayPattern(elements) {
|
|
this.type = syntax_1.Syntax.ArrayPattern;
|
|
this.elements = elements;
|
|
}
|
|
return ArrayPattern;
|
|
}());
|
|
exports$1.ArrayPattern = ArrayPattern;
|
|
var ArrowFunctionExpression = (function () {
|
|
function ArrowFunctionExpression(params, body, expression) {
|
|
this.type = syntax_1.Syntax.ArrowFunctionExpression;
|
|
this.id = null;
|
|
this.params = params;
|
|
this.body = body;
|
|
this.generator = false;
|
|
this.expression = expression;
|
|
this.async = false;
|
|
}
|
|
return ArrowFunctionExpression;
|
|
}());
|
|
exports$1.ArrowFunctionExpression = ArrowFunctionExpression;
|
|
var AssignmentExpression = (function () {
|
|
function AssignmentExpression(operator, left, right) {
|
|
this.type = syntax_1.Syntax.AssignmentExpression;
|
|
this.operator = operator;
|
|
this.left = left;
|
|
this.right = right;
|
|
}
|
|
return AssignmentExpression;
|
|
}());
|
|
exports$1.AssignmentExpression = AssignmentExpression;
|
|
var AssignmentPattern = (function () {
|
|
function AssignmentPattern(left, right) {
|
|
this.type = syntax_1.Syntax.AssignmentPattern;
|
|
this.left = left;
|
|
this.right = right;
|
|
}
|
|
return AssignmentPattern;
|
|
}());
|
|
exports$1.AssignmentPattern = AssignmentPattern;
|
|
var AsyncArrowFunctionExpression = (function () {
|
|
function AsyncArrowFunctionExpression(params, body, expression) {
|
|
this.type = syntax_1.Syntax.ArrowFunctionExpression;
|
|
this.id = null;
|
|
this.params = params;
|
|
this.body = body;
|
|
this.generator = false;
|
|
this.expression = expression;
|
|
this.async = true;
|
|
}
|
|
return AsyncArrowFunctionExpression;
|
|
}());
|
|
exports$1.AsyncArrowFunctionExpression = AsyncArrowFunctionExpression;
|
|
var AsyncFunctionDeclaration = (function () {
|
|
function AsyncFunctionDeclaration(id, params, body) {
|
|
this.type = syntax_1.Syntax.FunctionDeclaration;
|
|
this.id = id;
|
|
this.params = params;
|
|
this.body = body;
|
|
this.generator = false;
|
|
this.expression = false;
|
|
this.async = true;
|
|
}
|
|
return AsyncFunctionDeclaration;
|
|
}());
|
|
exports$1.AsyncFunctionDeclaration = AsyncFunctionDeclaration;
|
|
var AsyncFunctionExpression = (function () {
|
|
function AsyncFunctionExpression(id, params, body) {
|
|
this.type = syntax_1.Syntax.FunctionExpression;
|
|
this.id = id;
|
|
this.params = params;
|
|
this.body = body;
|
|
this.generator = false;
|
|
this.expression = false;
|
|
this.async = true;
|
|
}
|
|
return AsyncFunctionExpression;
|
|
}());
|
|
exports$1.AsyncFunctionExpression = AsyncFunctionExpression;
|
|
var AwaitExpression = (function () {
|
|
function AwaitExpression(argument) {
|
|
this.type = syntax_1.Syntax.AwaitExpression;
|
|
this.argument = argument;
|
|
}
|
|
return AwaitExpression;
|
|
}());
|
|
exports$1.AwaitExpression = AwaitExpression;
|
|
var BinaryExpression = (function () {
|
|
function BinaryExpression(operator, left, right) {
|
|
var logical = (operator === '||' || operator === '&&');
|
|
this.type = logical ? syntax_1.Syntax.LogicalExpression : syntax_1.Syntax.BinaryExpression;
|
|
this.operator = operator;
|
|
this.left = left;
|
|
this.right = right;
|
|
}
|
|
return BinaryExpression;
|
|
}());
|
|
exports$1.BinaryExpression = BinaryExpression;
|
|
var BlockStatement = (function () {
|
|
function BlockStatement(body) {
|
|
this.type = syntax_1.Syntax.BlockStatement;
|
|
this.body = body;
|
|
}
|
|
return BlockStatement;
|
|
}());
|
|
exports$1.BlockStatement = BlockStatement;
|
|
var BreakStatement = (function () {
|
|
function BreakStatement(label) {
|
|
this.type = syntax_1.Syntax.BreakStatement;
|
|
this.label = label;
|
|
}
|
|
return BreakStatement;
|
|
}());
|
|
exports$1.BreakStatement = BreakStatement;
|
|
var CallExpression = (function () {
|
|
function CallExpression(callee, args) {
|
|
this.type = syntax_1.Syntax.CallExpression;
|
|
this.callee = callee;
|
|
this.arguments = args;
|
|
}
|
|
return CallExpression;
|
|
}());
|
|
exports$1.CallExpression = CallExpression;
|
|
var CatchClause = (function () {
|
|
function CatchClause(param, body) {
|
|
this.type = syntax_1.Syntax.CatchClause;
|
|
this.param = param;
|
|
this.body = body;
|
|
}
|
|
return CatchClause;
|
|
}());
|
|
exports$1.CatchClause = CatchClause;
|
|
var ClassBody = (function () {
|
|
function ClassBody(body) {
|
|
this.type = syntax_1.Syntax.ClassBody;
|
|
this.body = body;
|
|
}
|
|
return ClassBody;
|
|
}());
|
|
exports$1.ClassBody = ClassBody;
|
|
var ClassDeclaration = (function () {
|
|
function ClassDeclaration(id, superClass, body) {
|
|
this.type = syntax_1.Syntax.ClassDeclaration;
|
|
this.id = id;
|
|
this.superClass = superClass;
|
|
this.body = body;
|
|
}
|
|
return ClassDeclaration;
|
|
}());
|
|
exports$1.ClassDeclaration = ClassDeclaration;
|
|
var ClassExpression = (function () {
|
|
function ClassExpression(id, superClass, body) {
|
|
this.type = syntax_1.Syntax.ClassExpression;
|
|
this.id = id;
|
|
this.superClass = superClass;
|
|
this.body = body;
|
|
}
|
|
return ClassExpression;
|
|
}());
|
|
exports$1.ClassExpression = ClassExpression;
|
|
var ComputedMemberExpression = (function () {
|
|
function ComputedMemberExpression(object, property) {
|
|
this.type = syntax_1.Syntax.MemberExpression;
|
|
this.computed = true;
|
|
this.object = object;
|
|
this.property = property;
|
|
}
|
|
return ComputedMemberExpression;
|
|
}());
|
|
exports$1.ComputedMemberExpression = ComputedMemberExpression;
|
|
var ConditionalExpression = (function () {
|
|
function ConditionalExpression(test, consequent, alternate) {
|
|
this.type = syntax_1.Syntax.ConditionalExpression;
|
|
this.test = test;
|
|
this.consequent = consequent;
|
|
this.alternate = alternate;
|
|
}
|
|
return ConditionalExpression;
|
|
}());
|
|
exports$1.ConditionalExpression = ConditionalExpression;
|
|
var ContinueStatement = (function () {
|
|
function ContinueStatement(label) {
|
|
this.type = syntax_1.Syntax.ContinueStatement;
|
|
this.label = label;
|
|
}
|
|
return ContinueStatement;
|
|
}());
|
|
exports$1.ContinueStatement = ContinueStatement;
|
|
var DebuggerStatement = (function () {
|
|
function DebuggerStatement() {
|
|
this.type = syntax_1.Syntax.DebuggerStatement;
|
|
}
|
|
return DebuggerStatement;
|
|
}());
|
|
exports$1.DebuggerStatement = DebuggerStatement;
|
|
var Directive = (function () {
|
|
function Directive(expression, directive) {
|
|
this.type = syntax_1.Syntax.ExpressionStatement;
|
|
this.expression = expression;
|
|
this.directive = directive;
|
|
}
|
|
return Directive;
|
|
}());
|
|
exports$1.Directive = Directive;
|
|
var DoWhileStatement = (function () {
|
|
function DoWhileStatement(body, test) {
|
|
this.type = syntax_1.Syntax.DoWhileStatement;
|
|
this.body = body;
|
|
this.test = test;
|
|
}
|
|
return DoWhileStatement;
|
|
}());
|
|
exports$1.DoWhileStatement = DoWhileStatement;
|
|
var EmptyStatement = (function () {
|
|
function EmptyStatement() {
|
|
this.type = syntax_1.Syntax.EmptyStatement;
|
|
}
|
|
return EmptyStatement;
|
|
}());
|
|
exports$1.EmptyStatement = EmptyStatement;
|
|
var ExportAllDeclaration = (function () {
|
|
function ExportAllDeclaration(source) {
|
|
this.type = syntax_1.Syntax.ExportAllDeclaration;
|
|
this.source = source;
|
|
}
|
|
return ExportAllDeclaration;
|
|
}());
|
|
exports$1.ExportAllDeclaration = ExportAllDeclaration;
|
|
var ExportDefaultDeclaration = (function () {
|
|
function ExportDefaultDeclaration(declaration) {
|
|
this.type = syntax_1.Syntax.ExportDefaultDeclaration;
|
|
this.declaration = declaration;
|
|
}
|
|
return ExportDefaultDeclaration;
|
|
}());
|
|
exports$1.ExportDefaultDeclaration = ExportDefaultDeclaration;
|
|
var ExportNamedDeclaration = (function () {
|
|
function ExportNamedDeclaration(declaration, specifiers, source) {
|
|
this.type = syntax_1.Syntax.ExportNamedDeclaration;
|
|
this.declaration = declaration;
|
|
this.specifiers = specifiers;
|
|
this.source = source;
|
|
}
|
|
return ExportNamedDeclaration;
|
|
}());
|
|
exports$1.ExportNamedDeclaration = ExportNamedDeclaration;
|
|
var ExportSpecifier = (function () {
|
|
function ExportSpecifier(local, exported) {
|
|
this.type = syntax_1.Syntax.ExportSpecifier;
|
|
this.exported = exported;
|
|
this.local = local;
|
|
}
|
|
return ExportSpecifier;
|
|
}());
|
|
exports$1.ExportSpecifier = ExportSpecifier;
|
|
var ExpressionStatement = (function () {
|
|
function ExpressionStatement(expression) {
|
|
this.type = syntax_1.Syntax.ExpressionStatement;
|
|
this.expression = expression;
|
|
}
|
|
return ExpressionStatement;
|
|
}());
|
|
exports$1.ExpressionStatement = ExpressionStatement;
|
|
var ForInStatement = (function () {
|
|
function ForInStatement(left, right, body) {
|
|
this.type = syntax_1.Syntax.ForInStatement;
|
|
this.left = left;
|
|
this.right = right;
|
|
this.body = body;
|
|
this.each = false;
|
|
}
|
|
return ForInStatement;
|
|
}());
|
|
exports$1.ForInStatement = ForInStatement;
|
|
var ForOfStatement = (function () {
|
|
function ForOfStatement(left, right, body) {
|
|
this.type = syntax_1.Syntax.ForOfStatement;
|
|
this.left = left;
|
|
this.right = right;
|
|
this.body = body;
|
|
}
|
|
return ForOfStatement;
|
|
}());
|
|
exports$1.ForOfStatement = ForOfStatement;
|
|
var ForStatement = (function () {
|
|
function ForStatement(init, test, update, body) {
|
|
this.type = syntax_1.Syntax.ForStatement;
|
|
this.init = init;
|
|
this.test = test;
|
|
this.update = update;
|
|
this.body = body;
|
|
}
|
|
return ForStatement;
|
|
}());
|
|
exports$1.ForStatement = ForStatement;
|
|
var FunctionDeclaration = (function () {
|
|
function FunctionDeclaration(id, params, body, generator) {
|
|
this.type = syntax_1.Syntax.FunctionDeclaration;
|
|
this.id = id;
|
|
this.params = params;
|
|
this.body = body;
|
|
this.generator = generator;
|
|
this.expression = false;
|
|
this.async = false;
|
|
}
|
|
return FunctionDeclaration;
|
|
}());
|
|
exports$1.FunctionDeclaration = FunctionDeclaration;
|
|
var FunctionExpression = (function () {
|
|
function FunctionExpression(id, params, body, generator) {
|
|
this.type = syntax_1.Syntax.FunctionExpression;
|
|
this.id = id;
|
|
this.params = params;
|
|
this.body = body;
|
|
this.generator = generator;
|
|
this.expression = false;
|
|
this.async = false;
|
|
}
|
|
return FunctionExpression;
|
|
}());
|
|
exports$1.FunctionExpression = FunctionExpression;
|
|
var Identifier = (function () {
|
|
function Identifier(name) {
|
|
this.type = syntax_1.Syntax.Identifier;
|
|
this.name = name;
|
|
}
|
|
return Identifier;
|
|
}());
|
|
exports$1.Identifier = Identifier;
|
|
var IfStatement = (function () {
|
|
function IfStatement(test, consequent, alternate) {
|
|
this.type = syntax_1.Syntax.IfStatement;
|
|
this.test = test;
|
|
this.consequent = consequent;
|
|
this.alternate = alternate;
|
|
}
|
|
return IfStatement;
|
|
}());
|
|
exports$1.IfStatement = IfStatement;
|
|
var ImportDeclaration = (function () {
|
|
function ImportDeclaration(specifiers, source) {
|
|
this.type = syntax_1.Syntax.ImportDeclaration;
|
|
this.specifiers = specifiers;
|
|
this.source = source;
|
|
}
|
|
return ImportDeclaration;
|
|
}());
|
|
exports$1.ImportDeclaration = ImportDeclaration;
|
|
var ImportDefaultSpecifier = (function () {
|
|
function ImportDefaultSpecifier(local) {
|
|
this.type = syntax_1.Syntax.ImportDefaultSpecifier;
|
|
this.local = local;
|
|
}
|
|
return ImportDefaultSpecifier;
|
|
}());
|
|
exports$1.ImportDefaultSpecifier = ImportDefaultSpecifier;
|
|
var ImportNamespaceSpecifier = (function () {
|
|
function ImportNamespaceSpecifier(local) {
|
|
this.type = syntax_1.Syntax.ImportNamespaceSpecifier;
|
|
this.local = local;
|
|
}
|
|
return ImportNamespaceSpecifier;
|
|
}());
|
|
exports$1.ImportNamespaceSpecifier = ImportNamespaceSpecifier;
|
|
var ImportSpecifier = (function () {
|
|
function ImportSpecifier(local, imported) {
|
|
this.type = syntax_1.Syntax.ImportSpecifier;
|
|
this.local = local;
|
|
this.imported = imported;
|
|
}
|
|
return ImportSpecifier;
|
|
}());
|
|
exports$1.ImportSpecifier = ImportSpecifier;
|
|
var LabeledStatement = (function () {
|
|
function LabeledStatement(label, body) {
|
|
this.type = syntax_1.Syntax.LabeledStatement;
|
|
this.label = label;
|
|
this.body = body;
|
|
}
|
|
return LabeledStatement;
|
|
}());
|
|
exports$1.LabeledStatement = LabeledStatement;
|
|
var Literal = (function () {
|
|
function Literal(value, raw) {
|
|
this.type = syntax_1.Syntax.Literal;
|
|
this.value = value;
|
|
this.raw = raw;
|
|
}
|
|
return Literal;
|
|
}());
|
|
exports$1.Literal = Literal;
|
|
var MetaProperty = (function () {
|
|
function MetaProperty(meta, property) {
|
|
this.type = syntax_1.Syntax.MetaProperty;
|
|
this.meta = meta;
|
|
this.property = property;
|
|
}
|
|
return MetaProperty;
|
|
}());
|
|
exports$1.MetaProperty = MetaProperty;
|
|
var MethodDefinition = (function () {
|
|
function MethodDefinition(key, computed, value, kind, isStatic) {
|
|
this.type = syntax_1.Syntax.MethodDefinition;
|
|
this.key = key;
|
|
this.computed = computed;
|
|
this.value = value;
|
|
this.kind = kind;
|
|
this.static = isStatic;
|
|
}
|
|
return MethodDefinition;
|
|
}());
|
|
exports$1.MethodDefinition = MethodDefinition;
|
|
var Module = (function () {
|
|
function Module(body) {
|
|
this.type = syntax_1.Syntax.Program;
|
|
this.body = body;
|
|
this.sourceType = 'module';
|
|
}
|
|
return Module;
|
|
}());
|
|
exports$1.Module = Module;
|
|
var NewExpression = (function () {
|
|
function NewExpression(callee, args) {
|
|
this.type = syntax_1.Syntax.NewExpression;
|
|
this.callee = callee;
|
|
this.arguments = args;
|
|
}
|
|
return NewExpression;
|
|
}());
|
|
exports$1.NewExpression = NewExpression;
|
|
var ObjectExpression = (function () {
|
|
function ObjectExpression(properties) {
|
|
this.type = syntax_1.Syntax.ObjectExpression;
|
|
this.properties = properties;
|
|
}
|
|
return ObjectExpression;
|
|
}());
|
|
exports$1.ObjectExpression = ObjectExpression;
|
|
var ObjectPattern = (function () {
|
|
function ObjectPattern(properties) {
|
|
this.type = syntax_1.Syntax.ObjectPattern;
|
|
this.properties = properties;
|
|
}
|
|
return ObjectPattern;
|
|
}());
|
|
exports$1.ObjectPattern = ObjectPattern;
|
|
var Property = (function () {
|
|
function Property(kind, key, computed, value, method, shorthand) {
|
|
this.type = syntax_1.Syntax.Property;
|
|
this.key = key;
|
|
this.computed = computed;
|
|
this.value = value;
|
|
this.kind = kind;
|
|
this.method = method;
|
|
this.shorthand = shorthand;
|
|
}
|
|
return Property;
|
|
}());
|
|
exports$1.Property = Property;
|
|
var RegexLiteral = (function () {
|
|
function RegexLiteral(value, raw, pattern, flags) {
|
|
this.type = syntax_1.Syntax.Literal;
|
|
this.value = value;
|
|
this.raw = raw;
|
|
this.regex = { pattern: pattern, flags: flags };
|
|
}
|
|
return RegexLiteral;
|
|
}());
|
|
exports$1.RegexLiteral = RegexLiteral;
|
|
var RestElement = (function () {
|
|
function RestElement(argument) {
|
|
this.type = syntax_1.Syntax.RestElement;
|
|
this.argument = argument;
|
|
}
|
|
return RestElement;
|
|
}());
|
|
exports$1.RestElement = RestElement;
|
|
var ReturnStatement = (function () {
|
|
function ReturnStatement(argument) {
|
|
this.type = syntax_1.Syntax.ReturnStatement;
|
|
this.argument = argument;
|
|
}
|
|
return ReturnStatement;
|
|
}());
|
|
exports$1.ReturnStatement = ReturnStatement;
|
|
var Script = (function () {
|
|
function Script(body) {
|
|
this.type = syntax_1.Syntax.Program;
|
|
this.body = body;
|
|
this.sourceType = 'script';
|
|
}
|
|
return Script;
|
|
}());
|
|
exports$1.Script = Script;
|
|
var SequenceExpression = (function () {
|
|
function SequenceExpression(expressions) {
|
|
this.type = syntax_1.Syntax.SequenceExpression;
|
|
this.expressions = expressions;
|
|
}
|
|
return SequenceExpression;
|
|
}());
|
|
exports$1.SequenceExpression = SequenceExpression;
|
|
var SpreadElement = (function () {
|
|
function SpreadElement(argument) {
|
|
this.type = syntax_1.Syntax.SpreadElement;
|
|
this.argument = argument;
|
|
}
|
|
return SpreadElement;
|
|
}());
|
|
exports$1.SpreadElement = SpreadElement;
|
|
var StaticMemberExpression = (function () {
|
|
function StaticMemberExpression(object, property) {
|
|
this.type = syntax_1.Syntax.MemberExpression;
|
|
this.computed = false;
|
|
this.object = object;
|
|
this.property = property;
|
|
}
|
|
return StaticMemberExpression;
|
|
}());
|
|
exports$1.StaticMemberExpression = StaticMemberExpression;
|
|
var Super = (function () {
|
|
function Super() {
|
|
this.type = syntax_1.Syntax.Super;
|
|
}
|
|
return Super;
|
|
}());
|
|
exports$1.Super = Super;
|
|
var SwitchCase = (function () {
|
|
function SwitchCase(test, consequent) {
|
|
this.type = syntax_1.Syntax.SwitchCase;
|
|
this.test = test;
|
|
this.consequent = consequent;
|
|
}
|
|
return SwitchCase;
|
|
}());
|
|
exports$1.SwitchCase = SwitchCase;
|
|
var SwitchStatement = (function () {
|
|
function SwitchStatement(discriminant, cases) {
|
|
this.type = syntax_1.Syntax.SwitchStatement;
|
|
this.discriminant = discriminant;
|
|
this.cases = cases;
|
|
}
|
|
return SwitchStatement;
|
|
}());
|
|
exports$1.SwitchStatement = SwitchStatement;
|
|
var TaggedTemplateExpression = (function () {
|
|
function TaggedTemplateExpression(tag, quasi) {
|
|
this.type = syntax_1.Syntax.TaggedTemplateExpression;
|
|
this.tag = tag;
|
|
this.quasi = quasi;
|
|
}
|
|
return TaggedTemplateExpression;
|
|
}());
|
|
exports$1.TaggedTemplateExpression = TaggedTemplateExpression;
|
|
var TemplateElement = (function () {
|
|
function TemplateElement(value, tail) {
|
|
this.type = syntax_1.Syntax.TemplateElement;
|
|
this.value = value;
|
|
this.tail = tail;
|
|
}
|
|
return TemplateElement;
|
|
}());
|
|
exports$1.TemplateElement = TemplateElement;
|
|
var TemplateLiteral = (function () {
|
|
function TemplateLiteral(quasis, expressions) {
|
|
this.type = syntax_1.Syntax.TemplateLiteral;
|
|
this.quasis = quasis;
|
|
this.expressions = expressions;
|
|
}
|
|
return TemplateLiteral;
|
|
}());
|
|
exports$1.TemplateLiteral = TemplateLiteral;
|
|
var ThisExpression = (function () {
|
|
function ThisExpression() {
|
|
this.type = syntax_1.Syntax.ThisExpression;
|
|
}
|
|
return ThisExpression;
|
|
}());
|
|
exports$1.ThisExpression = ThisExpression;
|
|
var ThrowStatement = (function () {
|
|
function ThrowStatement(argument) {
|
|
this.type = syntax_1.Syntax.ThrowStatement;
|
|
this.argument = argument;
|
|
}
|
|
return ThrowStatement;
|
|
}());
|
|
exports$1.ThrowStatement = ThrowStatement;
|
|
var TryStatement = (function () {
|
|
function TryStatement(block, handler, finalizer) {
|
|
this.type = syntax_1.Syntax.TryStatement;
|
|
this.block = block;
|
|
this.handler = handler;
|
|
this.finalizer = finalizer;
|
|
}
|
|
return TryStatement;
|
|
}());
|
|
exports$1.TryStatement = TryStatement;
|
|
var UnaryExpression = (function () {
|
|
function UnaryExpression(operator, argument) {
|
|
this.type = syntax_1.Syntax.UnaryExpression;
|
|
this.operator = operator;
|
|
this.argument = argument;
|
|
this.prefix = true;
|
|
}
|
|
return UnaryExpression;
|
|
}());
|
|
exports$1.UnaryExpression = UnaryExpression;
|
|
var UpdateExpression = (function () {
|
|
function UpdateExpression(operator, argument, prefix) {
|
|
this.type = syntax_1.Syntax.UpdateExpression;
|
|
this.operator = operator;
|
|
this.argument = argument;
|
|
this.prefix = prefix;
|
|
}
|
|
return UpdateExpression;
|
|
}());
|
|
exports$1.UpdateExpression = UpdateExpression;
|
|
var VariableDeclaration = (function () {
|
|
function VariableDeclaration(declarations, kind) {
|
|
this.type = syntax_1.Syntax.VariableDeclaration;
|
|
this.declarations = declarations;
|
|
this.kind = kind;
|
|
}
|
|
return VariableDeclaration;
|
|
}());
|
|
exports$1.VariableDeclaration = VariableDeclaration;
|
|
var VariableDeclarator = (function () {
|
|
function VariableDeclarator(id, init) {
|
|
this.type = syntax_1.Syntax.VariableDeclarator;
|
|
this.id = id;
|
|
this.init = init;
|
|
}
|
|
return VariableDeclarator;
|
|
}());
|
|
exports$1.VariableDeclarator = VariableDeclarator;
|
|
var WhileStatement = (function () {
|
|
function WhileStatement(test, body) {
|
|
this.type = syntax_1.Syntax.WhileStatement;
|
|
this.test = test;
|
|
this.body = body;
|
|
}
|
|
return WhileStatement;
|
|
}());
|
|
exports$1.WhileStatement = WhileStatement;
|
|
var WithStatement = (function () {
|
|
function WithStatement(object, body) {
|
|
this.type = syntax_1.Syntax.WithStatement;
|
|
this.object = object;
|
|
this.body = body;
|
|
}
|
|
return WithStatement;
|
|
}());
|
|
exports$1.WithStatement = WithStatement;
|
|
var YieldExpression = (function () {
|
|
function YieldExpression(argument, delegate) {
|
|
this.type = syntax_1.Syntax.YieldExpression;
|
|
this.argument = argument;
|
|
this.delegate = delegate;
|
|
}
|
|
return YieldExpression;
|
|
}());
|
|
exports$1.YieldExpression = YieldExpression;
|
|
|
|
|
|
/***/ },
|
|
/* 8 */
|
|
/***/ function(module, exports$1, __webpack_require__) {
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
var assert_1 = __webpack_require__(9);
|
|
var error_handler_1 = __webpack_require__(10);
|
|
var messages_1 = __webpack_require__(11);
|
|
var Node = __webpack_require__(7);
|
|
var scanner_1 = __webpack_require__(12);
|
|
var syntax_1 = __webpack_require__(2);
|
|
var token_1 = __webpack_require__(13);
|
|
var ArrowParameterPlaceHolder = 'ArrowParameterPlaceHolder';
|
|
var Parser = (function () {
|
|
function Parser(code, options, delegate) {
|
|
if (options === void 0) { options = {}; }
|
|
this.config = {
|
|
range: (typeof options.range === 'boolean') && options.range,
|
|
loc: (typeof options.loc === 'boolean') && options.loc,
|
|
source: null,
|
|
tokens: (typeof options.tokens === 'boolean') && options.tokens,
|
|
comment: (typeof options.comment === 'boolean') && options.comment,
|
|
tolerant: (typeof options.tolerant === 'boolean') && options.tolerant
|
|
};
|
|
if (this.config.loc && options.source && options.source !== null) {
|
|
this.config.source = String(options.source);
|
|
}
|
|
this.delegate = delegate;
|
|
this.errorHandler = new error_handler_1.ErrorHandler();
|
|
this.errorHandler.tolerant = this.config.tolerant;
|
|
this.scanner = new scanner_1.Scanner(code, this.errorHandler);
|
|
this.scanner.trackComment = this.config.comment;
|
|
this.operatorPrecedence = {
|
|
')': 0,
|
|
';': 0,
|
|
',': 0,
|
|
'=': 0,
|
|
']': 0,
|
|
'||': 1,
|
|
'&&': 2,
|
|
'|': 3,
|
|
'^': 4,
|
|
'&': 5,
|
|
'==': 6,
|
|
'!=': 6,
|
|
'===': 6,
|
|
'!==': 6,
|
|
'<': 7,
|
|
'>': 7,
|
|
'<=': 7,
|
|
'>=': 7,
|
|
'<<': 8,
|
|
'>>': 8,
|
|
'>>>': 8,
|
|
'+': 9,
|
|
'-': 9,
|
|
'*': 11,
|
|
'/': 11,
|
|
'%': 11
|
|
};
|
|
this.lookahead = {
|
|
type: 2 /* EOF */,
|
|
value: '',
|
|
lineNumber: this.scanner.lineNumber,
|
|
lineStart: 0,
|
|
start: 0,
|
|
end: 0
|
|
};
|
|
this.hasLineTerminator = false;
|
|
this.context = {
|
|
isModule: false,
|
|
await: false,
|
|
allowIn: true,
|
|
allowStrictDirective: true,
|
|
allowYield: true,
|
|
firstCoverInitializedNameError: null,
|
|
isAssignmentTarget: false,
|
|
isBindingElement: false,
|
|
inFunctionBody: false,
|
|
inIteration: false,
|
|
inSwitch: false,
|
|
labelSet: {},
|
|
strict: false
|
|
};
|
|
this.tokens = [];
|
|
this.startMarker = {
|
|
index: 0,
|
|
line: this.scanner.lineNumber,
|
|
column: 0
|
|
};
|
|
this.lastMarker = {
|
|
index: 0,
|
|
line: this.scanner.lineNumber,
|
|
column: 0
|
|
};
|
|
this.nextToken();
|
|
this.lastMarker = {
|
|
index: this.scanner.index,
|
|
line: this.scanner.lineNumber,
|
|
column: this.scanner.index - this.scanner.lineStart
|
|
};
|
|
}
|
|
Parser.prototype.throwError = function (messageFormat) {
|
|
var args = Array.prototype.slice.call(arguments, 1);
|
|
var msg = messageFormat.replace(/%(\d)/g, function (whole, idx) {
|
|
assert_1.assert(idx < args.length, 'Message reference must be in range');
|
|
return args[idx];
|
|
});
|
|
var index = this.lastMarker.index;
|
|
var line = this.lastMarker.line;
|
|
var column = this.lastMarker.column + 1;
|
|
throw this.errorHandler.createError(index, line, column, msg);
|
|
};
|
|
Parser.prototype.tolerateError = function (messageFormat) {
|
|
var args = Array.prototype.slice.call(arguments, 1);
|
|
var msg = messageFormat.replace(/%(\d)/g, function (whole, idx) {
|
|
assert_1.assert(idx < args.length, 'Message reference must be in range');
|
|
return args[idx];
|
|
});
|
|
var index = this.lastMarker.index;
|
|
var line = this.scanner.lineNumber;
|
|
var column = this.lastMarker.column + 1;
|
|
this.errorHandler.tolerateError(index, line, column, msg);
|
|
};
|
|
// Throw an exception because of the token.
|
|
Parser.prototype.unexpectedTokenError = function (token, message) {
|
|
var msg = message || messages_1.Messages.UnexpectedToken;
|
|
var value;
|
|
if (token) {
|
|
if (!message) {
|
|
msg = (token.type === 2 /* EOF */) ? messages_1.Messages.UnexpectedEOS :
|
|
(token.type === 3 /* Identifier */) ? messages_1.Messages.UnexpectedIdentifier :
|
|
(token.type === 6 /* NumericLiteral */) ? messages_1.Messages.UnexpectedNumber :
|
|
(token.type === 8 /* StringLiteral */) ? messages_1.Messages.UnexpectedString :
|
|
(token.type === 10 /* Template */) ? messages_1.Messages.UnexpectedTemplate :
|
|
messages_1.Messages.UnexpectedToken;
|
|
if (token.type === 4 /* Keyword */) {
|
|
if (this.scanner.isFutureReservedWord(token.value)) {
|
|
msg = messages_1.Messages.UnexpectedReserved;
|
|
}
|
|
else if (this.context.strict && this.scanner.isStrictModeReservedWord(token.value)) {
|
|
msg = messages_1.Messages.StrictReservedWord;
|
|
}
|
|
}
|
|
}
|
|
value = token.value;
|
|
}
|
|
else {
|
|
value = 'ILLEGAL';
|
|
}
|
|
msg = msg.replace('%0', value);
|
|
if (token && typeof token.lineNumber === 'number') {
|
|
var index = token.start;
|
|
var line = token.lineNumber;
|
|
var lastMarkerLineStart = this.lastMarker.index - this.lastMarker.column;
|
|
var column = token.start - lastMarkerLineStart + 1;
|
|
return this.errorHandler.createError(index, line, column, msg);
|
|
}
|
|
else {
|
|
var index = this.lastMarker.index;
|
|
var line = this.lastMarker.line;
|
|
var column = this.lastMarker.column + 1;
|
|
return this.errorHandler.createError(index, line, column, msg);
|
|
}
|
|
};
|
|
Parser.prototype.throwUnexpectedToken = function (token, message) {
|
|
throw this.unexpectedTokenError(token, message);
|
|
};
|
|
Parser.prototype.tolerateUnexpectedToken = function (token, message) {
|
|
this.errorHandler.tolerate(this.unexpectedTokenError(token, message));
|
|
};
|
|
Parser.prototype.collectComments = function () {
|
|
if (!this.config.comment) {
|
|
this.scanner.scanComments();
|
|
}
|
|
else {
|
|
var comments = this.scanner.scanComments();
|
|
if (comments.length > 0 && this.delegate) {
|
|
for (var i = 0; i < comments.length; ++i) {
|
|
var e = comments[i];
|
|
var node = void 0;
|
|
node = {
|
|
type: e.multiLine ? 'BlockComment' : 'LineComment',
|
|
value: this.scanner.source.slice(e.slice[0], e.slice[1])
|
|
};
|
|
if (this.config.range) {
|
|
node.range = e.range;
|
|
}
|
|
if (this.config.loc) {
|
|
node.loc = e.loc;
|
|
}
|
|
var metadata = {
|
|
start: {
|
|
line: e.loc.start.line,
|
|
column: e.loc.start.column,
|
|
offset: e.range[0]
|
|
},
|
|
end: {
|
|
line: e.loc.end.line,
|
|
column: e.loc.end.column,
|
|
offset: e.range[1]
|
|
}
|
|
};
|
|
this.delegate(node, metadata);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
// From internal representation to an external structure
|
|
Parser.prototype.getTokenRaw = function (token) {
|
|
return this.scanner.source.slice(token.start, token.end);
|
|
};
|
|
Parser.prototype.convertToken = function (token) {
|
|
var t = {
|
|
type: token_1.TokenName[token.type],
|
|
value: this.getTokenRaw(token)
|
|
};
|
|
if (this.config.range) {
|
|
t.range = [token.start, token.end];
|
|
}
|
|
if (this.config.loc) {
|
|
t.loc = {
|
|
start: {
|
|
line: this.startMarker.line,
|
|
column: this.startMarker.column
|
|
},
|
|
end: {
|
|
line: this.scanner.lineNumber,
|
|
column: this.scanner.index - this.scanner.lineStart
|
|
}
|
|
};
|
|
}
|
|
if (token.type === 9 /* RegularExpression */) {
|
|
var pattern = token.pattern;
|
|
var flags = token.flags;
|
|
t.regex = { pattern: pattern, flags: flags };
|
|
}
|
|
return t;
|
|
};
|
|
Parser.prototype.nextToken = function () {
|
|
var token = this.lookahead;
|
|
this.lastMarker.index = this.scanner.index;
|
|
this.lastMarker.line = this.scanner.lineNumber;
|
|
this.lastMarker.column = this.scanner.index - this.scanner.lineStart;
|
|
this.collectComments();
|
|
if (this.scanner.index !== this.startMarker.index) {
|
|
this.startMarker.index = this.scanner.index;
|
|
this.startMarker.line = this.scanner.lineNumber;
|
|
this.startMarker.column = this.scanner.index - this.scanner.lineStart;
|
|
}
|
|
var next = this.scanner.lex();
|
|
this.hasLineTerminator = (token.lineNumber !== next.lineNumber);
|
|
if (next && this.context.strict && next.type === 3 /* Identifier */) {
|
|
if (this.scanner.isStrictModeReservedWord(next.value)) {
|
|
next.type = 4 /* Keyword */;
|
|
}
|
|
}
|
|
this.lookahead = next;
|
|
if (this.config.tokens && next.type !== 2 /* EOF */) {
|
|
this.tokens.push(this.convertToken(next));
|
|
}
|
|
return token;
|
|
};
|
|
Parser.prototype.nextRegexToken = function () {
|
|
this.collectComments();
|
|
var token = this.scanner.scanRegExp();
|
|
if (this.config.tokens) {
|
|
// Pop the previous token, '/' or '/='
|
|
// This is added from the lookahead token.
|
|
this.tokens.pop();
|
|
this.tokens.push(this.convertToken(token));
|
|
}
|
|
// Prime the next lookahead.
|
|
this.lookahead = token;
|
|
this.nextToken();
|
|
return token;
|
|
};
|
|
Parser.prototype.createNode = function () {
|
|
return {
|
|
index: this.startMarker.index,
|
|
line: this.startMarker.line,
|
|
column: this.startMarker.column
|
|
};
|
|
};
|
|
Parser.prototype.startNode = function (token, lastLineStart) {
|
|
if (lastLineStart === void 0) { lastLineStart = 0; }
|
|
var column = token.start - token.lineStart;
|
|
var line = token.lineNumber;
|
|
if (column < 0) {
|
|
column += lastLineStart;
|
|
line--;
|
|
}
|
|
return {
|
|
index: token.start,
|
|
line: line,
|
|
column: column
|
|
};
|
|
};
|
|
Parser.prototype.finalize = function (marker, node) {
|
|
if (this.config.range) {
|
|
node.range = [marker.index, this.lastMarker.index];
|
|
}
|
|
if (this.config.loc) {
|
|
node.loc = {
|
|
start: {
|
|
line: marker.line,
|
|
column: marker.column,
|
|
},
|
|
end: {
|
|
line: this.lastMarker.line,
|
|
column: this.lastMarker.column
|
|
}
|
|
};
|
|
if (this.config.source) {
|
|
node.loc.source = this.config.source;
|
|
}
|
|
}
|
|
if (this.delegate) {
|
|
var metadata = {
|
|
start: {
|
|
line: marker.line,
|
|
column: marker.column,
|
|
offset: marker.index
|
|
},
|
|
end: {
|
|
line: this.lastMarker.line,
|
|
column: this.lastMarker.column,
|
|
offset: this.lastMarker.index
|
|
}
|
|
};
|
|
this.delegate(node, metadata);
|
|
}
|
|
return node;
|
|
};
|
|
// Expect the next token to match the specified punctuator.
|
|
// If not, an exception will be thrown.
|
|
Parser.prototype.expect = function (value) {
|
|
var token = this.nextToken();
|
|
if (token.type !== 7 /* Punctuator */ || token.value !== value) {
|
|
this.throwUnexpectedToken(token);
|
|
}
|
|
};
|
|
// Quietly expect a comma when in tolerant mode, otherwise delegates to expect().
|
|
Parser.prototype.expectCommaSeparator = function () {
|
|
if (this.config.tolerant) {
|
|
var token = this.lookahead;
|
|
if (token.type === 7 /* Punctuator */ && token.value === ',') {
|
|
this.nextToken();
|
|
}
|
|
else if (token.type === 7 /* Punctuator */ && token.value === ';') {
|
|
this.nextToken();
|
|
this.tolerateUnexpectedToken(token);
|
|
}
|
|
else {
|
|
this.tolerateUnexpectedToken(token, messages_1.Messages.UnexpectedToken);
|
|
}
|
|
}
|
|
else {
|
|
this.expect(',');
|
|
}
|
|
};
|
|
// Expect the next token to match the specified keyword.
|
|
// If not, an exception will be thrown.
|
|
Parser.prototype.expectKeyword = function (keyword) {
|
|
var token = this.nextToken();
|
|
if (token.type !== 4 /* Keyword */ || token.value !== keyword) {
|
|
this.throwUnexpectedToken(token);
|
|
}
|
|
};
|
|
// Return true if the next token matches the specified punctuator.
|
|
Parser.prototype.match = function (value) {
|
|
return this.lookahead.type === 7 /* Punctuator */ && this.lookahead.value === value;
|
|
};
|
|
// Return true if the next token matches the specified keyword
|
|
Parser.prototype.matchKeyword = function (keyword) {
|
|
return this.lookahead.type === 4 /* Keyword */ && this.lookahead.value === keyword;
|
|
};
|
|
// Return true if the next token matches the specified contextual keyword
|
|
// (where an identifier is sometimes a keyword depending on the context)
|
|
Parser.prototype.matchContextualKeyword = function (keyword) {
|
|
return this.lookahead.type === 3 /* Identifier */ && this.lookahead.value === keyword;
|
|
};
|
|
// Return true if the next token is an assignment operator
|
|
Parser.prototype.matchAssign = function () {
|
|
if (this.lookahead.type !== 7 /* Punctuator */) {
|
|
return false;
|
|
}
|
|
var op = this.lookahead.value;
|
|
return op === '=' ||
|
|
op === '*=' ||
|
|
op === '**=' ||
|
|
op === '/=' ||
|
|
op === '%=' ||
|
|
op === '+=' ||
|
|
op === '-=' ||
|
|
op === '<<=' ||
|
|
op === '>>=' ||
|
|
op === '>>>=' ||
|
|
op === '&=' ||
|
|
op === '^=' ||
|
|
op === '|=';
|
|
};
|
|
// Cover grammar support.
|
|
//
|
|
// When an assignment expression position starts with an left parenthesis, the determination of the type
|
|
// of the syntax is to be deferred arbitrarily long until the end of the parentheses pair (plus a lookahead)
|
|
// or the first comma. This situation also defers the determination of all the expressions nested in the pair.
|
|
//
|
|
// There are three productions that can be parsed in a parentheses pair that needs to be determined
|
|
// after the outermost pair is closed. They are:
|
|
//
|
|
// 1. AssignmentExpression
|
|
// 2. BindingElements
|
|
// 3. AssignmentTargets
|
|
//
|
|
// In order to avoid exponential backtracking, we use two flags to denote if the production can be
|
|
// binding element or assignment target.
|
|
//
|
|
// The three productions have the relationship:
|
|
//
|
|
// BindingElements ⊆ AssignmentTargets ⊆ AssignmentExpression
|
|
//
|
|
// with a single exception that CoverInitializedName when used directly in an Expression, generates
|
|
// an early error. Therefore, we need the third state, firstCoverInitializedNameError, to track the
|
|
// first usage of CoverInitializedName and report it when we reached the end of the parentheses pair.
|
|
//
|
|
// isolateCoverGrammar function runs the given parser function with a new cover grammar context, and it does not
|
|
// effect the current flags. This means the production the parser parses is only used as an expression. Therefore
|
|
// the CoverInitializedName check is conducted.
|
|
//
|
|
// inheritCoverGrammar function runs the given parse function with a new cover grammar context, and it propagates
|
|
// the flags outside of the parser. This means the production the parser parses is used as a part of a potential
|
|
// pattern. The CoverInitializedName check is deferred.
|
|
Parser.prototype.isolateCoverGrammar = function (parseFunction) {
|
|
var previousIsBindingElement = this.context.isBindingElement;
|
|
var previousIsAssignmentTarget = this.context.isAssignmentTarget;
|
|
var previousFirstCoverInitializedNameError = this.context.firstCoverInitializedNameError;
|
|
this.context.isBindingElement = true;
|
|
this.context.isAssignmentTarget = true;
|
|
this.context.firstCoverInitializedNameError = null;
|
|
var result = parseFunction.call(this);
|
|
if (this.context.firstCoverInitializedNameError !== null) {
|
|
this.throwUnexpectedToken(this.context.firstCoverInitializedNameError);
|
|
}
|
|
this.context.isBindingElement = previousIsBindingElement;
|
|
this.context.isAssignmentTarget = previousIsAssignmentTarget;
|
|
this.context.firstCoverInitializedNameError = previousFirstCoverInitializedNameError;
|
|
return result;
|
|
};
|
|
Parser.prototype.inheritCoverGrammar = function (parseFunction) {
|
|
var previousIsBindingElement = this.context.isBindingElement;
|
|
var previousIsAssignmentTarget = this.context.isAssignmentTarget;
|
|
var previousFirstCoverInitializedNameError = this.context.firstCoverInitializedNameError;
|
|
this.context.isBindingElement = true;
|
|
this.context.isAssignmentTarget = true;
|
|
this.context.firstCoverInitializedNameError = null;
|
|
var result = parseFunction.call(this);
|
|
this.context.isBindingElement = this.context.isBindingElement && previousIsBindingElement;
|
|
this.context.isAssignmentTarget = this.context.isAssignmentTarget && previousIsAssignmentTarget;
|
|
this.context.firstCoverInitializedNameError = previousFirstCoverInitializedNameError || this.context.firstCoverInitializedNameError;
|
|
return result;
|
|
};
|
|
Parser.prototype.consumeSemicolon = function () {
|
|
if (this.match(';')) {
|
|
this.nextToken();
|
|
}
|
|
else if (!this.hasLineTerminator) {
|
|
if (this.lookahead.type !== 2 /* EOF */ && !this.match('}')) {
|
|
this.throwUnexpectedToken(this.lookahead);
|
|
}
|
|
this.lastMarker.index = this.startMarker.index;
|
|
this.lastMarker.line = this.startMarker.line;
|
|
this.lastMarker.column = this.startMarker.column;
|
|
}
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-primary-expression
|
|
Parser.prototype.parsePrimaryExpression = function () {
|
|
var node = this.createNode();
|
|
var expr;
|
|
var token, raw;
|
|
switch (this.lookahead.type) {
|
|
case 3 /* Identifier */:
|
|
if ((this.context.isModule || this.context.await) && this.lookahead.value === 'await') {
|
|
this.tolerateUnexpectedToken(this.lookahead);
|
|
}
|
|
expr = this.matchAsyncFunction() ? this.parseFunctionExpression() : this.finalize(node, new Node.Identifier(this.nextToken().value));
|
|
break;
|
|
case 6 /* NumericLiteral */:
|
|
case 8 /* StringLiteral */:
|
|
if (this.context.strict && this.lookahead.octal) {
|
|
this.tolerateUnexpectedToken(this.lookahead, messages_1.Messages.StrictOctalLiteral);
|
|
}
|
|
this.context.isAssignmentTarget = false;
|
|
this.context.isBindingElement = false;
|
|
token = this.nextToken();
|
|
raw = this.getTokenRaw(token);
|
|
expr = this.finalize(node, new Node.Literal(token.value, raw));
|
|
break;
|
|
case 1 /* BooleanLiteral */:
|
|
this.context.isAssignmentTarget = false;
|
|
this.context.isBindingElement = false;
|
|
token = this.nextToken();
|
|
raw = this.getTokenRaw(token);
|
|
expr = this.finalize(node, new Node.Literal(token.value === 'true', raw));
|
|
break;
|
|
case 5 /* NullLiteral */:
|
|
this.context.isAssignmentTarget = false;
|
|
this.context.isBindingElement = false;
|
|
token = this.nextToken();
|
|
raw = this.getTokenRaw(token);
|
|
expr = this.finalize(node, new Node.Literal(null, raw));
|
|
break;
|
|
case 10 /* Template */:
|
|
expr = this.parseTemplateLiteral();
|
|
break;
|
|
case 7 /* Punctuator */:
|
|
switch (this.lookahead.value) {
|
|
case '(':
|
|
this.context.isBindingElement = false;
|
|
expr = this.inheritCoverGrammar(this.parseGroupExpression);
|
|
break;
|
|
case '[':
|
|
expr = this.inheritCoverGrammar(this.parseArrayInitializer);
|
|
break;
|
|
case '{':
|
|
expr = this.inheritCoverGrammar(this.parseObjectInitializer);
|
|
break;
|
|
case '/':
|
|
case '/=':
|
|
this.context.isAssignmentTarget = false;
|
|
this.context.isBindingElement = false;
|
|
this.scanner.index = this.startMarker.index;
|
|
token = this.nextRegexToken();
|
|
raw = this.getTokenRaw(token);
|
|
expr = this.finalize(node, new Node.RegexLiteral(token.regex, raw, token.pattern, token.flags));
|
|
break;
|
|
default:
|
|
expr = this.throwUnexpectedToken(this.nextToken());
|
|
}
|
|
break;
|
|
case 4 /* Keyword */:
|
|
if (!this.context.strict && this.context.allowYield && this.matchKeyword('yield')) {
|
|
expr = this.parseIdentifierName();
|
|
}
|
|
else if (!this.context.strict && this.matchKeyword('let')) {
|
|
expr = this.finalize(node, new Node.Identifier(this.nextToken().value));
|
|
}
|
|
else {
|
|
this.context.isAssignmentTarget = false;
|
|
this.context.isBindingElement = false;
|
|
if (this.matchKeyword('function')) {
|
|
expr = this.parseFunctionExpression();
|
|
}
|
|
else if (this.matchKeyword('this')) {
|
|
this.nextToken();
|
|
expr = this.finalize(node, new Node.ThisExpression());
|
|
}
|
|
else if (this.matchKeyword('class')) {
|
|
expr = this.parseClassExpression();
|
|
}
|
|
else {
|
|
expr = this.throwUnexpectedToken(this.nextToken());
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
expr = this.throwUnexpectedToken(this.nextToken());
|
|
}
|
|
return expr;
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-array-initializer
|
|
Parser.prototype.parseSpreadElement = function () {
|
|
var node = this.createNode();
|
|
this.expect('...');
|
|
var arg = this.inheritCoverGrammar(this.parseAssignmentExpression);
|
|
return this.finalize(node, new Node.SpreadElement(arg));
|
|
};
|
|
Parser.prototype.parseArrayInitializer = function () {
|
|
var node = this.createNode();
|
|
var elements = [];
|
|
this.expect('[');
|
|
while (!this.match(']')) {
|
|
if (this.match(',')) {
|
|
this.nextToken();
|
|
elements.push(null);
|
|
}
|
|
else if (this.match('...')) {
|
|
var element = this.parseSpreadElement();
|
|
if (!this.match(']')) {
|
|
this.context.isAssignmentTarget = false;
|
|
this.context.isBindingElement = false;
|
|
this.expect(',');
|
|
}
|
|
elements.push(element);
|
|
}
|
|
else {
|
|
elements.push(this.inheritCoverGrammar(this.parseAssignmentExpression));
|
|
if (!this.match(']')) {
|
|
this.expect(',');
|
|
}
|
|
}
|
|
}
|
|
this.expect(']');
|
|
return this.finalize(node, new Node.ArrayExpression(elements));
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-object-initializer
|
|
Parser.prototype.parsePropertyMethod = function (params) {
|
|
this.context.isAssignmentTarget = false;
|
|
this.context.isBindingElement = false;
|
|
var previousStrict = this.context.strict;
|
|
var previousAllowStrictDirective = this.context.allowStrictDirective;
|
|
this.context.allowStrictDirective = params.simple;
|
|
var body = this.isolateCoverGrammar(this.parseFunctionSourceElements);
|
|
if (this.context.strict && params.firstRestricted) {
|
|
this.tolerateUnexpectedToken(params.firstRestricted, params.message);
|
|
}
|
|
if (this.context.strict && params.stricted) {
|
|
this.tolerateUnexpectedToken(params.stricted, params.message);
|
|
}
|
|
this.context.strict = previousStrict;
|
|
this.context.allowStrictDirective = previousAllowStrictDirective;
|
|
return body;
|
|
};
|
|
Parser.prototype.parsePropertyMethodFunction = function () {
|
|
var isGenerator = false;
|
|
var node = this.createNode();
|
|
var previousAllowYield = this.context.allowYield;
|
|
this.context.allowYield = true;
|
|
var params = this.parseFormalParameters();
|
|
var method = this.parsePropertyMethod(params);
|
|
this.context.allowYield = previousAllowYield;
|
|
return this.finalize(node, new Node.FunctionExpression(null, params.params, method, isGenerator));
|
|
};
|
|
Parser.prototype.parsePropertyMethodAsyncFunction = function () {
|
|
var node = this.createNode();
|
|
var previousAllowYield = this.context.allowYield;
|
|
var previousAwait = this.context.await;
|
|
this.context.allowYield = false;
|
|
this.context.await = true;
|
|
var params = this.parseFormalParameters();
|
|
var method = this.parsePropertyMethod(params);
|
|
this.context.allowYield = previousAllowYield;
|
|
this.context.await = previousAwait;
|
|
return this.finalize(node, new Node.AsyncFunctionExpression(null, params.params, method));
|
|
};
|
|
Parser.prototype.parseObjectPropertyKey = function () {
|
|
var node = this.createNode();
|
|
var token = this.nextToken();
|
|
var key;
|
|
switch (token.type) {
|
|
case 8 /* StringLiteral */:
|
|
case 6 /* NumericLiteral */:
|
|
if (this.context.strict && token.octal) {
|
|
this.tolerateUnexpectedToken(token, messages_1.Messages.StrictOctalLiteral);
|
|
}
|
|
var raw = this.getTokenRaw(token);
|
|
key = this.finalize(node, new Node.Literal(token.value, raw));
|
|
break;
|
|
case 3 /* Identifier */:
|
|
case 1 /* BooleanLiteral */:
|
|
case 5 /* NullLiteral */:
|
|
case 4 /* Keyword */:
|
|
key = this.finalize(node, new Node.Identifier(token.value));
|
|
break;
|
|
case 7 /* Punctuator */:
|
|
if (token.value === '[') {
|
|
key = this.isolateCoverGrammar(this.parseAssignmentExpression);
|
|
this.expect(']');
|
|
}
|
|
else {
|
|
key = this.throwUnexpectedToken(token);
|
|
}
|
|
break;
|
|
default:
|
|
key = this.throwUnexpectedToken(token);
|
|
}
|
|
return key;
|
|
};
|
|
Parser.prototype.isPropertyKey = function (key, value) {
|
|
return (key.type === syntax_1.Syntax.Identifier && key.name === value) ||
|
|
(key.type === syntax_1.Syntax.Literal && key.value === value);
|
|
};
|
|
Parser.prototype.parseObjectProperty = function (hasProto) {
|
|
var node = this.createNode();
|
|
var token = this.lookahead;
|
|
var kind;
|
|
var key = null;
|
|
var value = null;
|
|
var computed = false;
|
|
var method = false;
|
|
var shorthand = false;
|
|
var isAsync = false;
|
|
if (token.type === 3 /* Identifier */) {
|
|
var id = token.value;
|
|
this.nextToken();
|
|
computed = this.match('[');
|
|
isAsync = !this.hasLineTerminator && (id === 'async') &&
|
|
!this.match(':') && !this.match('(') && !this.match('*') && !this.match(',');
|
|
key = isAsync ? this.parseObjectPropertyKey() : this.finalize(node, new Node.Identifier(id));
|
|
}
|
|
else if (this.match('*')) {
|
|
this.nextToken();
|
|
}
|
|
else {
|
|
computed = this.match('[');
|
|
key = this.parseObjectPropertyKey();
|
|
}
|
|
var lookaheadPropertyKey = this.qualifiedPropertyName(this.lookahead);
|
|
if (token.type === 3 /* Identifier */ && !isAsync && token.value === 'get' && lookaheadPropertyKey) {
|
|
kind = 'get';
|
|
computed = this.match('[');
|
|
key = this.parseObjectPropertyKey();
|
|
this.context.allowYield = false;
|
|
value = this.parseGetterMethod();
|
|
}
|
|
else if (token.type === 3 /* Identifier */ && !isAsync && token.value === 'set' && lookaheadPropertyKey) {
|
|
kind = 'set';
|
|
computed = this.match('[');
|
|
key = this.parseObjectPropertyKey();
|
|
value = this.parseSetterMethod();
|
|
}
|
|
else if (token.type === 7 /* Punctuator */ && token.value === '*' && lookaheadPropertyKey) {
|
|
kind = 'init';
|
|
computed = this.match('[');
|
|
key = this.parseObjectPropertyKey();
|
|
value = this.parseGeneratorMethod();
|
|
method = true;
|
|
}
|
|
else {
|
|
if (!key) {
|
|
this.throwUnexpectedToken(this.lookahead);
|
|
}
|
|
kind = 'init';
|
|
if (this.match(':') && !isAsync) {
|
|
if (!computed && this.isPropertyKey(key, '__proto__')) {
|
|
if (hasProto.value) {
|
|
this.tolerateError(messages_1.Messages.DuplicateProtoProperty);
|
|
}
|
|
hasProto.value = true;
|
|
}
|
|
this.nextToken();
|
|
value = this.inheritCoverGrammar(this.parseAssignmentExpression);
|
|
}
|
|
else if (this.match('(')) {
|
|
value = isAsync ? this.parsePropertyMethodAsyncFunction() : this.parsePropertyMethodFunction();
|
|
method = true;
|
|
}
|
|
else if (token.type === 3 /* Identifier */) {
|
|
var id = this.finalize(node, new Node.Identifier(token.value));
|
|
if (this.match('=')) {
|
|
this.context.firstCoverInitializedNameError = this.lookahead;
|
|
this.nextToken();
|
|
shorthand = true;
|
|
var init = this.isolateCoverGrammar(this.parseAssignmentExpression);
|
|
value = this.finalize(node, new Node.AssignmentPattern(id, init));
|
|
}
|
|
else {
|
|
shorthand = true;
|
|
value = id;
|
|
}
|
|
}
|
|
else {
|
|
this.throwUnexpectedToken(this.nextToken());
|
|
}
|
|
}
|
|
return this.finalize(node, new Node.Property(kind, key, computed, value, method, shorthand));
|
|
};
|
|
Parser.prototype.parseObjectInitializer = function () {
|
|
var node = this.createNode();
|
|
this.expect('{');
|
|
var properties = [];
|
|
var hasProto = { value: false };
|
|
while (!this.match('}')) {
|
|
properties.push(this.parseObjectProperty(hasProto));
|
|
if (!this.match('}')) {
|
|
this.expectCommaSeparator();
|
|
}
|
|
}
|
|
this.expect('}');
|
|
return this.finalize(node, new Node.ObjectExpression(properties));
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-template-literals
|
|
Parser.prototype.parseTemplateHead = function () {
|
|
assert_1.assert(this.lookahead.head, 'Template literal must start with a template head');
|
|
var node = this.createNode();
|
|
var token = this.nextToken();
|
|
var raw = token.value;
|
|
var cooked = token.cooked;
|
|
return this.finalize(node, new Node.TemplateElement({ raw: raw, cooked: cooked }, token.tail));
|
|
};
|
|
Parser.prototype.parseTemplateElement = function () {
|
|
if (this.lookahead.type !== 10 /* Template */) {
|
|
this.throwUnexpectedToken();
|
|
}
|
|
var node = this.createNode();
|
|
var token = this.nextToken();
|
|
var raw = token.value;
|
|
var cooked = token.cooked;
|
|
return this.finalize(node, new Node.TemplateElement({ raw: raw, cooked: cooked }, token.tail));
|
|
};
|
|
Parser.prototype.parseTemplateLiteral = function () {
|
|
var node = this.createNode();
|
|
var expressions = [];
|
|
var quasis = [];
|
|
var quasi = this.parseTemplateHead();
|
|
quasis.push(quasi);
|
|
while (!quasi.tail) {
|
|
expressions.push(this.parseExpression());
|
|
quasi = this.parseTemplateElement();
|
|
quasis.push(quasi);
|
|
}
|
|
return this.finalize(node, new Node.TemplateLiteral(quasis, expressions));
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-grouping-operator
|
|
Parser.prototype.reinterpretExpressionAsPattern = function (expr) {
|
|
switch (expr.type) {
|
|
case syntax_1.Syntax.Identifier:
|
|
case syntax_1.Syntax.MemberExpression:
|
|
case syntax_1.Syntax.RestElement:
|
|
case syntax_1.Syntax.AssignmentPattern:
|
|
break;
|
|
case syntax_1.Syntax.SpreadElement:
|
|
expr.type = syntax_1.Syntax.RestElement;
|
|
this.reinterpretExpressionAsPattern(expr.argument);
|
|
break;
|
|
case syntax_1.Syntax.ArrayExpression:
|
|
expr.type = syntax_1.Syntax.ArrayPattern;
|
|
for (var i = 0; i < expr.elements.length; i++) {
|
|
if (expr.elements[i] !== null) {
|
|
this.reinterpretExpressionAsPattern(expr.elements[i]);
|
|
}
|
|
}
|
|
break;
|
|
case syntax_1.Syntax.ObjectExpression:
|
|
expr.type = syntax_1.Syntax.ObjectPattern;
|
|
for (var i = 0; i < expr.properties.length; i++) {
|
|
this.reinterpretExpressionAsPattern(expr.properties[i].value);
|
|
}
|
|
break;
|
|
case syntax_1.Syntax.AssignmentExpression:
|
|
expr.type = syntax_1.Syntax.AssignmentPattern;
|
|
delete expr.operator;
|
|
this.reinterpretExpressionAsPattern(expr.left);
|
|
break;
|
|
}
|
|
};
|
|
Parser.prototype.parseGroupExpression = function () {
|
|
var expr;
|
|
this.expect('(');
|
|
if (this.match(')')) {
|
|
this.nextToken();
|
|
if (!this.match('=>')) {
|
|
this.expect('=>');
|
|
}
|
|
expr = {
|
|
type: ArrowParameterPlaceHolder,
|
|
params: [],
|
|
async: false
|
|
};
|
|
}
|
|
else {
|
|
var startToken = this.lookahead;
|
|
var params = [];
|
|
if (this.match('...')) {
|
|
expr = this.parseRestElement(params);
|
|
this.expect(')');
|
|
if (!this.match('=>')) {
|
|
this.expect('=>');
|
|
}
|
|
expr = {
|
|
type: ArrowParameterPlaceHolder,
|
|
params: [expr],
|
|
async: false
|
|
};
|
|
}
|
|
else {
|
|
var arrow = false;
|
|
this.context.isBindingElement = true;
|
|
expr = this.inheritCoverGrammar(this.parseAssignmentExpression);
|
|
if (this.match(',')) {
|
|
var expressions = [];
|
|
this.context.isAssignmentTarget = false;
|
|
expressions.push(expr);
|
|
while (this.lookahead.type !== 2 /* EOF */) {
|
|
if (!this.match(',')) {
|
|
break;
|
|
}
|
|
this.nextToken();
|
|
if (this.match(')')) {
|
|
this.nextToken();
|
|
for (var i = 0; i < expressions.length; i++) {
|
|
this.reinterpretExpressionAsPattern(expressions[i]);
|
|
}
|
|
arrow = true;
|
|
expr = {
|
|
type: ArrowParameterPlaceHolder,
|
|
params: expressions,
|
|
async: false
|
|
};
|
|
}
|
|
else if (this.match('...')) {
|
|
if (!this.context.isBindingElement) {
|
|
this.throwUnexpectedToken(this.lookahead);
|
|
}
|
|
expressions.push(this.parseRestElement(params));
|
|
this.expect(')');
|
|
if (!this.match('=>')) {
|
|
this.expect('=>');
|
|
}
|
|
this.context.isBindingElement = false;
|
|
for (var i = 0; i < expressions.length; i++) {
|
|
this.reinterpretExpressionAsPattern(expressions[i]);
|
|
}
|
|
arrow = true;
|
|
expr = {
|
|
type: ArrowParameterPlaceHolder,
|
|
params: expressions,
|
|
async: false
|
|
};
|
|
}
|
|
else {
|
|
expressions.push(this.inheritCoverGrammar(this.parseAssignmentExpression));
|
|
}
|
|
if (arrow) {
|
|
break;
|
|
}
|
|
}
|
|
if (!arrow) {
|
|
expr = this.finalize(this.startNode(startToken), new Node.SequenceExpression(expressions));
|
|
}
|
|
}
|
|
if (!arrow) {
|
|
this.expect(')');
|
|
if (this.match('=>')) {
|
|
if (expr.type === syntax_1.Syntax.Identifier && expr.name === 'yield') {
|
|
arrow = true;
|
|
expr = {
|
|
type: ArrowParameterPlaceHolder,
|
|
params: [expr],
|
|
async: false
|
|
};
|
|
}
|
|
if (!arrow) {
|
|
if (!this.context.isBindingElement) {
|
|
this.throwUnexpectedToken(this.lookahead);
|
|
}
|
|
if (expr.type === syntax_1.Syntax.SequenceExpression) {
|
|
for (var i = 0; i < expr.expressions.length; i++) {
|
|
this.reinterpretExpressionAsPattern(expr.expressions[i]);
|
|
}
|
|
}
|
|
else {
|
|
this.reinterpretExpressionAsPattern(expr);
|
|
}
|
|
var parameters = (expr.type === syntax_1.Syntax.SequenceExpression ? expr.expressions : [expr]);
|
|
expr = {
|
|
type: ArrowParameterPlaceHolder,
|
|
params: parameters,
|
|
async: false
|
|
};
|
|
}
|
|
}
|
|
this.context.isBindingElement = false;
|
|
}
|
|
}
|
|
}
|
|
return expr;
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-left-hand-side-expressions
|
|
Parser.prototype.parseArguments = function () {
|
|
this.expect('(');
|
|
var args = [];
|
|
if (!this.match(')')) {
|
|
while (true) {
|
|
var expr = this.match('...') ? this.parseSpreadElement() :
|
|
this.isolateCoverGrammar(this.parseAssignmentExpression);
|
|
args.push(expr);
|
|
if (this.match(')')) {
|
|
break;
|
|
}
|
|
this.expectCommaSeparator();
|
|
if (this.match(')')) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
this.expect(')');
|
|
return args;
|
|
};
|
|
Parser.prototype.isIdentifierName = function (token) {
|
|
return token.type === 3 /* Identifier */ ||
|
|
token.type === 4 /* Keyword */ ||
|
|
token.type === 1 /* BooleanLiteral */ ||
|
|
token.type === 5 /* NullLiteral */;
|
|
};
|
|
Parser.prototype.parseIdentifierName = function () {
|
|
var node = this.createNode();
|
|
var token = this.nextToken();
|
|
if (!this.isIdentifierName(token)) {
|
|
this.throwUnexpectedToken(token);
|
|
}
|
|
return this.finalize(node, new Node.Identifier(token.value));
|
|
};
|
|
Parser.prototype.parseNewExpression = function () {
|
|
var node = this.createNode();
|
|
var id = this.parseIdentifierName();
|
|
assert_1.assert(id.name === 'new', 'New expression must start with `new`');
|
|
var expr;
|
|
if (this.match('.')) {
|
|
this.nextToken();
|
|
if (this.lookahead.type === 3 /* Identifier */ && this.context.inFunctionBody && this.lookahead.value === 'target') {
|
|
var property = this.parseIdentifierName();
|
|
expr = new Node.MetaProperty(id, property);
|
|
}
|
|
else {
|
|
this.throwUnexpectedToken(this.lookahead);
|
|
}
|
|
}
|
|
else {
|
|
var callee = this.isolateCoverGrammar(this.parseLeftHandSideExpression);
|
|
var args = this.match('(') ? this.parseArguments() : [];
|
|
expr = new Node.NewExpression(callee, args);
|
|
this.context.isAssignmentTarget = false;
|
|
this.context.isBindingElement = false;
|
|
}
|
|
return this.finalize(node, expr);
|
|
};
|
|
Parser.prototype.parseAsyncArgument = function () {
|
|
var arg = this.parseAssignmentExpression();
|
|
this.context.firstCoverInitializedNameError = null;
|
|
return arg;
|
|
};
|
|
Parser.prototype.parseAsyncArguments = function () {
|
|
this.expect('(');
|
|
var args = [];
|
|
if (!this.match(')')) {
|
|
while (true) {
|
|
var expr = this.match('...') ? this.parseSpreadElement() :
|
|
this.isolateCoverGrammar(this.parseAsyncArgument);
|
|
args.push(expr);
|
|
if (this.match(')')) {
|
|
break;
|
|
}
|
|
this.expectCommaSeparator();
|
|
if (this.match(')')) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
this.expect(')');
|
|
return args;
|
|
};
|
|
Parser.prototype.parseLeftHandSideExpressionAllowCall = function () {
|
|
var startToken = this.lookahead;
|
|
var maybeAsync = this.matchContextualKeyword('async');
|
|
var previousAllowIn = this.context.allowIn;
|
|
this.context.allowIn = true;
|
|
var expr;
|
|
if (this.matchKeyword('super') && this.context.inFunctionBody) {
|
|
expr = this.createNode();
|
|
this.nextToken();
|
|
expr = this.finalize(expr, new Node.Super());
|
|
if (!this.match('(') && !this.match('.') && !this.match('[')) {
|
|
this.throwUnexpectedToken(this.lookahead);
|
|
}
|
|
}
|
|
else {
|
|
expr = this.inheritCoverGrammar(this.matchKeyword('new') ? this.parseNewExpression : this.parsePrimaryExpression);
|
|
}
|
|
while (true) {
|
|
if (this.match('.')) {
|
|
this.context.isBindingElement = false;
|
|
this.context.isAssignmentTarget = true;
|
|
this.expect('.');
|
|
var property = this.parseIdentifierName();
|
|
expr = this.finalize(this.startNode(startToken), new Node.StaticMemberExpression(expr, property));
|
|
}
|
|
else if (this.match('(')) {
|
|
var asyncArrow = maybeAsync && (startToken.lineNumber === this.lookahead.lineNumber);
|
|
this.context.isBindingElement = false;
|
|
this.context.isAssignmentTarget = false;
|
|
var args = asyncArrow ? this.parseAsyncArguments() : this.parseArguments();
|
|
expr = this.finalize(this.startNode(startToken), new Node.CallExpression(expr, args));
|
|
if (asyncArrow && this.match('=>')) {
|
|
for (var i = 0; i < args.length; ++i) {
|
|
this.reinterpretExpressionAsPattern(args[i]);
|
|
}
|
|
expr = {
|
|
type: ArrowParameterPlaceHolder,
|
|
params: args,
|
|
async: true
|
|
};
|
|
}
|
|
}
|
|
else if (this.match('[')) {
|
|
this.context.isBindingElement = false;
|
|
this.context.isAssignmentTarget = true;
|
|
this.expect('[');
|
|
var property = this.isolateCoverGrammar(this.parseExpression);
|
|
this.expect(']');
|
|
expr = this.finalize(this.startNode(startToken), new Node.ComputedMemberExpression(expr, property));
|
|
}
|
|
else if (this.lookahead.type === 10 /* Template */ && this.lookahead.head) {
|
|
var quasi = this.parseTemplateLiteral();
|
|
expr = this.finalize(this.startNode(startToken), new Node.TaggedTemplateExpression(expr, quasi));
|
|
}
|
|
else {
|
|
break;
|
|
}
|
|
}
|
|
this.context.allowIn = previousAllowIn;
|
|
return expr;
|
|
};
|
|
Parser.prototype.parseSuper = function () {
|
|
var node = this.createNode();
|
|
this.expectKeyword('super');
|
|
if (!this.match('[') && !this.match('.')) {
|
|
this.throwUnexpectedToken(this.lookahead);
|
|
}
|
|
return this.finalize(node, new Node.Super());
|
|
};
|
|
Parser.prototype.parseLeftHandSideExpression = function () {
|
|
assert_1.assert(this.context.allowIn, 'callee of new expression always allow in keyword.');
|
|
var node = this.startNode(this.lookahead);
|
|
var expr = (this.matchKeyword('super') && this.context.inFunctionBody) ? this.parseSuper() :
|
|
this.inheritCoverGrammar(this.matchKeyword('new') ? this.parseNewExpression : this.parsePrimaryExpression);
|
|
while (true) {
|
|
if (this.match('[')) {
|
|
this.context.isBindingElement = false;
|
|
this.context.isAssignmentTarget = true;
|
|
this.expect('[');
|
|
var property = this.isolateCoverGrammar(this.parseExpression);
|
|
this.expect(']');
|
|
expr = this.finalize(node, new Node.ComputedMemberExpression(expr, property));
|
|
}
|
|
else if (this.match('.')) {
|
|
this.context.isBindingElement = false;
|
|
this.context.isAssignmentTarget = true;
|
|
this.expect('.');
|
|
var property = this.parseIdentifierName();
|
|
expr = this.finalize(node, new Node.StaticMemberExpression(expr, property));
|
|
}
|
|
else if (this.lookahead.type === 10 /* Template */ && this.lookahead.head) {
|
|
var quasi = this.parseTemplateLiteral();
|
|
expr = this.finalize(node, new Node.TaggedTemplateExpression(expr, quasi));
|
|
}
|
|
else {
|
|
break;
|
|
}
|
|
}
|
|
return expr;
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-update-expressions
|
|
Parser.prototype.parseUpdateExpression = function () {
|
|
var expr;
|
|
var startToken = this.lookahead;
|
|
if (this.match('++') || this.match('--')) {
|
|
var node = this.startNode(startToken);
|
|
var token = this.nextToken();
|
|
expr = this.inheritCoverGrammar(this.parseUnaryExpression);
|
|
if (this.context.strict && expr.type === syntax_1.Syntax.Identifier && this.scanner.isRestrictedWord(expr.name)) {
|
|
this.tolerateError(messages_1.Messages.StrictLHSPrefix);
|
|
}
|
|
if (!this.context.isAssignmentTarget) {
|
|
this.tolerateError(messages_1.Messages.InvalidLHSInAssignment);
|
|
}
|
|
var prefix = true;
|
|
expr = this.finalize(node, new Node.UpdateExpression(token.value, expr, prefix));
|
|
this.context.isAssignmentTarget = false;
|
|
this.context.isBindingElement = false;
|
|
}
|
|
else {
|
|
expr = this.inheritCoverGrammar(this.parseLeftHandSideExpressionAllowCall);
|
|
if (!this.hasLineTerminator && this.lookahead.type === 7 /* Punctuator */) {
|
|
if (this.match('++') || this.match('--')) {
|
|
if (this.context.strict && expr.type === syntax_1.Syntax.Identifier && this.scanner.isRestrictedWord(expr.name)) {
|
|
this.tolerateError(messages_1.Messages.StrictLHSPostfix);
|
|
}
|
|
if (!this.context.isAssignmentTarget) {
|
|
this.tolerateError(messages_1.Messages.InvalidLHSInAssignment);
|
|
}
|
|
this.context.isAssignmentTarget = false;
|
|
this.context.isBindingElement = false;
|
|
var operator = this.nextToken().value;
|
|
var prefix = false;
|
|
expr = this.finalize(this.startNode(startToken), new Node.UpdateExpression(operator, expr, prefix));
|
|
}
|
|
}
|
|
}
|
|
return expr;
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-unary-operators
|
|
Parser.prototype.parseAwaitExpression = function () {
|
|
var node = this.createNode();
|
|
this.nextToken();
|
|
var argument = this.parseUnaryExpression();
|
|
return this.finalize(node, new Node.AwaitExpression(argument));
|
|
};
|
|
Parser.prototype.parseUnaryExpression = function () {
|
|
var expr;
|
|
if (this.match('+') || this.match('-') || this.match('~') || this.match('!') ||
|
|
this.matchKeyword('delete') || this.matchKeyword('void') || this.matchKeyword('typeof')) {
|
|
var node = this.startNode(this.lookahead);
|
|
var token = this.nextToken();
|
|
expr = this.inheritCoverGrammar(this.parseUnaryExpression);
|
|
expr = this.finalize(node, new Node.UnaryExpression(token.value, expr));
|
|
if (this.context.strict && expr.operator === 'delete' && expr.argument.type === syntax_1.Syntax.Identifier) {
|
|
this.tolerateError(messages_1.Messages.StrictDelete);
|
|
}
|
|
this.context.isAssignmentTarget = false;
|
|
this.context.isBindingElement = false;
|
|
}
|
|
else if (this.context.await && this.matchContextualKeyword('await')) {
|
|
expr = this.parseAwaitExpression();
|
|
}
|
|
else {
|
|
expr = this.parseUpdateExpression();
|
|
}
|
|
return expr;
|
|
};
|
|
Parser.prototype.parseExponentiationExpression = function () {
|
|
var startToken = this.lookahead;
|
|
var expr = this.inheritCoverGrammar(this.parseUnaryExpression);
|
|
if (expr.type !== syntax_1.Syntax.UnaryExpression && this.match('**')) {
|
|
this.nextToken();
|
|
this.context.isAssignmentTarget = false;
|
|
this.context.isBindingElement = false;
|
|
var left = expr;
|
|
var right = this.isolateCoverGrammar(this.parseExponentiationExpression);
|
|
expr = this.finalize(this.startNode(startToken), new Node.BinaryExpression('**', left, right));
|
|
}
|
|
return expr;
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-exp-operator
|
|
// https://tc39.github.io/ecma262/#sec-multiplicative-operators
|
|
// https://tc39.github.io/ecma262/#sec-additive-operators
|
|
// https://tc39.github.io/ecma262/#sec-bitwise-shift-operators
|
|
// https://tc39.github.io/ecma262/#sec-relational-operators
|
|
// https://tc39.github.io/ecma262/#sec-equality-operators
|
|
// https://tc39.github.io/ecma262/#sec-binary-bitwise-operators
|
|
// https://tc39.github.io/ecma262/#sec-binary-logical-operators
|
|
Parser.prototype.binaryPrecedence = function (token) {
|
|
var op = token.value;
|
|
var precedence;
|
|
if (token.type === 7 /* Punctuator */) {
|
|
precedence = this.operatorPrecedence[op] || 0;
|
|
}
|
|
else if (token.type === 4 /* Keyword */) {
|
|
precedence = (op === 'instanceof' || (this.context.allowIn && op === 'in')) ? 7 : 0;
|
|
}
|
|
else {
|
|
precedence = 0;
|
|
}
|
|
return precedence;
|
|
};
|
|
Parser.prototype.parseBinaryExpression = function () {
|
|
var startToken = this.lookahead;
|
|
var expr = this.inheritCoverGrammar(this.parseExponentiationExpression);
|
|
var token = this.lookahead;
|
|
var prec = this.binaryPrecedence(token);
|
|
if (prec > 0) {
|
|
this.nextToken();
|
|
this.context.isAssignmentTarget = false;
|
|
this.context.isBindingElement = false;
|
|
var markers = [startToken, this.lookahead];
|
|
var left = expr;
|
|
var right = this.isolateCoverGrammar(this.parseExponentiationExpression);
|
|
var stack = [left, token.value, right];
|
|
var precedences = [prec];
|
|
while (true) {
|
|
prec = this.binaryPrecedence(this.lookahead);
|
|
if (prec <= 0) {
|
|
break;
|
|
}
|
|
// Reduce: make a binary expression from the three topmost entries.
|
|
while ((stack.length > 2) && (prec <= precedences[precedences.length - 1])) {
|
|
right = stack.pop();
|
|
var operator = stack.pop();
|
|
precedences.pop();
|
|
left = stack.pop();
|
|
markers.pop();
|
|
var node = this.startNode(markers[markers.length - 1]);
|
|
stack.push(this.finalize(node, new Node.BinaryExpression(operator, left, right)));
|
|
}
|
|
// Shift.
|
|
stack.push(this.nextToken().value);
|
|
precedences.push(prec);
|
|
markers.push(this.lookahead);
|
|
stack.push(this.isolateCoverGrammar(this.parseExponentiationExpression));
|
|
}
|
|
// Final reduce to clean-up the stack.
|
|
var i = stack.length - 1;
|
|
expr = stack[i];
|
|
var lastMarker = markers.pop();
|
|
while (i > 1) {
|
|
var marker = markers.pop();
|
|
var lastLineStart = lastMarker && lastMarker.lineStart;
|
|
var node = this.startNode(marker, lastLineStart);
|
|
var operator = stack[i - 1];
|
|
expr = this.finalize(node, new Node.BinaryExpression(operator, stack[i - 2], expr));
|
|
i -= 2;
|
|
lastMarker = marker;
|
|
}
|
|
}
|
|
return expr;
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-conditional-operator
|
|
Parser.prototype.parseConditionalExpression = function () {
|
|
var startToken = this.lookahead;
|
|
var expr = this.inheritCoverGrammar(this.parseBinaryExpression);
|
|
if (this.match('?')) {
|
|
this.nextToken();
|
|
var previousAllowIn = this.context.allowIn;
|
|
this.context.allowIn = true;
|
|
var consequent = this.isolateCoverGrammar(this.parseAssignmentExpression);
|
|
this.context.allowIn = previousAllowIn;
|
|
this.expect(':');
|
|
var alternate = this.isolateCoverGrammar(this.parseAssignmentExpression);
|
|
expr = this.finalize(this.startNode(startToken), new Node.ConditionalExpression(expr, consequent, alternate));
|
|
this.context.isAssignmentTarget = false;
|
|
this.context.isBindingElement = false;
|
|
}
|
|
return expr;
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-assignment-operators
|
|
Parser.prototype.checkPatternParam = function (options, param) {
|
|
switch (param.type) {
|
|
case syntax_1.Syntax.Identifier:
|
|
this.validateParam(options, param, param.name);
|
|
break;
|
|
case syntax_1.Syntax.RestElement:
|
|
this.checkPatternParam(options, param.argument);
|
|
break;
|
|
case syntax_1.Syntax.AssignmentPattern:
|
|
this.checkPatternParam(options, param.left);
|
|
break;
|
|
case syntax_1.Syntax.ArrayPattern:
|
|
for (var i = 0; i < param.elements.length; i++) {
|
|
if (param.elements[i] !== null) {
|
|
this.checkPatternParam(options, param.elements[i]);
|
|
}
|
|
}
|
|
break;
|
|
case syntax_1.Syntax.ObjectPattern:
|
|
for (var i = 0; i < param.properties.length; i++) {
|
|
this.checkPatternParam(options, param.properties[i].value);
|
|
}
|
|
break;
|
|
}
|
|
options.simple = options.simple && (param instanceof Node.Identifier);
|
|
};
|
|
Parser.prototype.reinterpretAsCoverFormalsList = function (expr) {
|
|
var params = [expr];
|
|
var options;
|
|
var asyncArrow = false;
|
|
switch (expr.type) {
|
|
case syntax_1.Syntax.Identifier:
|
|
break;
|
|
case ArrowParameterPlaceHolder:
|
|
params = expr.params;
|
|
asyncArrow = expr.async;
|
|
break;
|
|
default:
|
|
return null;
|
|
}
|
|
options = {
|
|
simple: true,
|
|
paramSet: {}
|
|
};
|
|
for (var i = 0; i < params.length; ++i) {
|
|
var param = params[i];
|
|
if (param.type === syntax_1.Syntax.AssignmentPattern) {
|
|
if (param.right.type === syntax_1.Syntax.YieldExpression) {
|
|
if (param.right.argument) {
|
|
this.throwUnexpectedToken(this.lookahead);
|
|
}
|
|
param.right.type = syntax_1.Syntax.Identifier;
|
|
param.right.name = 'yield';
|
|
delete param.right.argument;
|
|
delete param.right.delegate;
|
|
}
|
|
}
|
|
else if (asyncArrow && param.type === syntax_1.Syntax.Identifier && param.name === 'await') {
|
|
this.throwUnexpectedToken(this.lookahead);
|
|
}
|
|
this.checkPatternParam(options, param);
|
|
params[i] = param;
|
|
}
|
|
if (this.context.strict || !this.context.allowYield) {
|
|
for (var i = 0; i < params.length; ++i) {
|
|
var param = params[i];
|
|
if (param.type === syntax_1.Syntax.YieldExpression) {
|
|
this.throwUnexpectedToken(this.lookahead);
|
|
}
|
|
}
|
|
}
|
|
if (options.message === messages_1.Messages.StrictParamDupe) {
|
|
var token = this.context.strict ? options.stricted : options.firstRestricted;
|
|
this.throwUnexpectedToken(token, options.message);
|
|
}
|
|
return {
|
|
simple: options.simple,
|
|
params: params,
|
|
stricted: options.stricted,
|
|
firstRestricted: options.firstRestricted,
|
|
message: options.message
|
|
};
|
|
};
|
|
Parser.prototype.parseAssignmentExpression = function () {
|
|
var expr;
|
|
if (!this.context.allowYield && this.matchKeyword('yield')) {
|
|
expr = this.parseYieldExpression();
|
|
}
|
|
else {
|
|
var startToken = this.lookahead;
|
|
var token = startToken;
|
|
expr = this.parseConditionalExpression();
|
|
if (token.type === 3 /* Identifier */ && (token.lineNumber === this.lookahead.lineNumber) && token.value === 'async') {
|
|
if (this.lookahead.type === 3 /* Identifier */ || this.matchKeyword('yield')) {
|
|
var arg = this.parsePrimaryExpression();
|
|
this.reinterpretExpressionAsPattern(arg);
|
|
expr = {
|
|
type: ArrowParameterPlaceHolder,
|
|
params: [arg],
|
|
async: true
|
|
};
|
|
}
|
|
}
|
|
if (expr.type === ArrowParameterPlaceHolder || this.match('=>')) {
|
|
// https://tc39.github.io/ecma262/#sec-arrow-function-definitions
|
|
this.context.isAssignmentTarget = false;
|
|
this.context.isBindingElement = false;
|
|
var isAsync = expr.async;
|
|
var list = this.reinterpretAsCoverFormalsList(expr);
|
|
if (list) {
|
|
if (this.hasLineTerminator) {
|
|
this.tolerateUnexpectedToken(this.lookahead);
|
|
}
|
|
this.context.firstCoverInitializedNameError = null;
|
|
var previousStrict = this.context.strict;
|
|
var previousAllowStrictDirective = this.context.allowStrictDirective;
|
|
this.context.allowStrictDirective = list.simple;
|
|
var previousAllowYield = this.context.allowYield;
|
|
var previousAwait = this.context.await;
|
|
this.context.allowYield = true;
|
|
this.context.await = isAsync;
|
|
var node = this.startNode(startToken);
|
|
this.expect('=>');
|
|
var body = void 0;
|
|
if (this.match('{')) {
|
|
var previousAllowIn = this.context.allowIn;
|
|
this.context.allowIn = true;
|
|
body = this.parseFunctionSourceElements();
|
|
this.context.allowIn = previousAllowIn;
|
|
}
|
|
else {
|
|
body = this.isolateCoverGrammar(this.parseAssignmentExpression);
|
|
}
|
|
var expression = body.type !== syntax_1.Syntax.BlockStatement;
|
|
if (this.context.strict && list.firstRestricted) {
|
|
this.throwUnexpectedToken(list.firstRestricted, list.message);
|
|
}
|
|
if (this.context.strict && list.stricted) {
|
|
this.tolerateUnexpectedToken(list.stricted, list.message);
|
|
}
|
|
expr = isAsync ? this.finalize(node, new Node.AsyncArrowFunctionExpression(list.params, body, expression)) :
|
|
this.finalize(node, new Node.ArrowFunctionExpression(list.params, body, expression));
|
|
this.context.strict = previousStrict;
|
|
this.context.allowStrictDirective = previousAllowStrictDirective;
|
|
this.context.allowYield = previousAllowYield;
|
|
this.context.await = previousAwait;
|
|
}
|
|
}
|
|
else {
|
|
if (this.matchAssign()) {
|
|
if (!this.context.isAssignmentTarget) {
|
|
this.tolerateError(messages_1.Messages.InvalidLHSInAssignment);
|
|
}
|
|
if (this.context.strict && expr.type === syntax_1.Syntax.Identifier) {
|
|
var id = expr;
|
|
if (this.scanner.isRestrictedWord(id.name)) {
|
|
this.tolerateUnexpectedToken(token, messages_1.Messages.StrictLHSAssignment);
|
|
}
|
|
if (this.scanner.isStrictModeReservedWord(id.name)) {
|
|
this.tolerateUnexpectedToken(token, messages_1.Messages.StrictReservedWord);
|
|
}
|
|
}
|
|
if (!this.match('=')) {
|
|
this.context.isAssignmentTarget = false;
|
|
this.context.isBindingElement = false;
|
|
}
|
|
else {
|
|
this.reinterpretExpressionAsPattern(expr);
|
|
}
|
|
token = this.nextToken();
|
|
var operator = token.value;
|
|
var right = this.isolateCoverGrammar(this.parseAssignmentExpression);
|
|
expr = this.finalize(this.startNode(startToken), new Node.AssignmentExpression(operator, expr, right));
|
|
this.context.firstCoverInitializedNameError = null;
|
|
}
|
|
}
|
|
}
|
|
return expr;
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-comma-operator
|
|
Parser.prototype.parseExpression = function () {
|
|
var startToken = this.lookahead;
|
|
var expr = this.isolateCoverGrammar(this.parseAssignmentExpression);
|
|
if (this.match(',')) {
|
|
var expressions = [];
|
|
expressions.push(expr);
|
|
while (this.lookahead.type !== 2 /* EOF */) {
|
|
if (!this.match(',')) {
|
|
break;
|
|
}
|
|
this.nextToken();
|
|
expressions.push(this.isolateCoverGrammar(this.parseAssignmentExpression));
|
|
}
|
|
expr = this.finalize(this.startNode(startToken), new Node.SequenceExpression(expressions));
|
|
}
|
|
return expr;
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-block
|
|
Parser.prototype.parseStatementListItem = function () {
|
|
var statement;
|
|
this.context.isAssignmentTarget = true;
|
|
this.context.isBindingElement = true;
|
|
if (this.lookahead.type === 4 /* Keyword */) {
|
|
switch (this.lookahead.value) {
|
|
case 'export':
|
|
if (!this.context.isModule) {
|
|
this.tolerateUnexpectedToken(this.lookahead, messages_1.Messages.IllegalExportDeclaration);
|
|
}
|
|
statement = this.parseExportDeclaration();
|
|
break;
|
|
case 'import':
|
|
if (!this.context.isModule) {
|
|
this.tolerateUnexpectedToken(this.lookahead, messages_1.Messages.IllegalImportDeclaration);
|
|
}
|
|
statement = this.parseImportDeclaration();
|
|
break;
|
|
case 'const':
|
|
statement = this.parseLexicalDeclaration({ inFor: false });
|
|
break;
|
|
case 'function':
|
|
statement = this.parseFunctionDeclaration();
|
|
break;
|
|
case 'class':
|
|
statement = this.parseClassDeclaration();
|
|
break;
|
|
case 'let':
|
|
statement = this.isLexicalDeclaration() ? this.parseLexicalDeclaration({ inFor: false }) : this.parseStatement();
|
|
break;
|
|
default:
|
|
statement = this.parseStatement();
|
|
break;
|
|
}
|
|
}
|
|
else {
|
|
statement = this.parseStatement();
|
|
}
|
|
return statement;
|
|
};
|
|
Parser.prototype.parseBlock = function () {
|
|
var node = this.createNode();
|
|
this.expect('{');
|
|
var block = [];
|
|
while (true) {
|
|
if (this.match('}')) {
|
|
break;
|
|
}
|
|
block.push(this.parseStatementListItem());
|
|
}
|
|
this.expect('}');
|
|
return this.finalize(node, new Node.BlockStatement(block));
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-let-and-const-declarations
|
|
Parser.prototype.parseLexicalBinding = function (kind, options) {
|
|
var node = this.createNode();
|
|
var params = [];
|
|
var id = this.parsePattern(params, kind);
|
|
if (this.context.strict && id.type === syntax_1.Syntax.Identifier) {
|
|
if (this.scanner.isRestrictedWord(id.name)) {
|
|
this.tolerateError(messages_1.Messages.StrictVarName);
|
|
}
|
|
}
|
|
var init = null;
|
|
if (kind === 'const') {
|
|
if (!this.matchKeyword('in') && !this.matchContextualKeyword('of')) {
|
|
if (this.match('=')) {
|
|
this.nextToken();
|
|
init = this.isolateCoverGrammar(this.parseAssignmentExpression);
|
|
}
|
|
else {
|
|
this.throwError(messages_1.Messages.DeclarationMissingInitializer, 'const');
|
|
}
|
|
}
|
|
}
|
|
else if ((!options.inFor && id.type !== syntax_1.Syntax.Identifier) || this.match('=')) {
|
|
this.expect('=');
|
|
init = this.isolateCoverGrammar(this.parseAssignmentExpression);
|
|
}
|
|
return this.finalize(node, new Node.VariableDeclarator(id, init));
|
|
};
|
|
Parser.prototype.parseBindingList = function (kind, options) {
|
|
var list = [this.parseLexicalBinding(kind, options)];
|
|
while (this.match(',')) {
|
|
this.nextToken();
|
|
list.push(this.parseLexicalBinding(kind, options));
|
|
}
|
|
return list;
|
|
};
|
|
Parser.prototype.isLexicalDeclaration = function () {
|
|
var state = this.scanner.saveState();
|
|
this.scanner.scanComments();
|
|
var next = this.scanner.lex();
|
|
this.scanner.restoreState(state);
|
|
return (next.type === 3 /* Identifier */) ||
|
|
(next.type === 7 /* Punctuator */ && next.value === '[') ||
|
|
(next.type === 7 /* Punctuator */ && next.value === '{') ||
|
|
(next.type === 4 /* Keyword */ && next.value === 'let') ||
|
|
(next.type === 4 /* Keyword */ && next.value === 'yield');
|
|
};
|
|
Parser.prototype.parseLexicalDeclaration = function (options) {
|
|
var node = this.createNode();
|
|
var kind = this.nextToken().value;
|
|
assert_1.assert(kind === 'let' || kind === 'const', 'Lexical declaration must be either let or const');
|
|
var declarations = this.parseBindingList(kind, options);
|
|
this.consumeSemicolon();
|
|
return this.finalize(node, new Node.VariableDeclaration(declarations, kind));
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-destructuring-binding-patterns
|
|
Parser.prototype.parseBindingRestElement = function (params, kind) {
|
|
var node = this.createNode();
|
|
this.expect('...');
|
|
var arg = this.parsePattern(params, kind);
|
|
return this.finalize(node, new Node.RestElement(arg));
|
|
};
|
|
Parser.prototype.parseArrayPattern = function (params, kind) {
|
|
var node = this.createNode();
|
|
this.expect('[');
|
|
var elements = [];
|
|
while (!this.match(']')) {
|
|
if (this.match(',')) {
|
|
this.nextToken();
|
|
elements.push(null);
|
|
}
|
|
else {
|
|
if (this.match('...')) {
|
|
elements.push(this.parseBindingRestElement(params, kind));
|
|
break;
|
|
}
|
|
else {
|
|
elements.push(this.parsePatternWithDefault(params, kind));
|
|
}
|
|
if (!this.match(']')) {
|
|
this.expect(',');
|
|
}
|
|
}
|
|
}
|
|
this.expect(']');
|
|
return this.finalize(node, new Node.ArrayPattern(elements));
|
|
};
|
|
Parser.prototype.parsePropertyPattern = function (params, kind) {
|
|
var node = this.createNode();
|
|
var computed = false;
|
|
var shorthand = false;
|
|
var method = false;
|
|
var key;
|
|
var value;
|
|
if (this.lookahead.type === 3 /* Identifier */) {
|
|
var keyToken = this.lookahead;
|
|
key = this.parseVariableIdentifier();
|
|
var init = this.finalize(node, new Node.Identifier(keyToken.value));
|
|
if (this.match('=')) {
|
|
params.push(keyToken);
|
|
shorthand = true;
|
|
this.nextToken();
|
|
var expr = this.parseAssignmentExpression();
|
|
value = this.finalize(this.startNode(keyToken), new Node.AssignmentPattern(init, expr));
|
|
}
|
|
else if (!this.match(':')) {
|
|
params.push(keyToken);
|
|
shorthand = true;
|
|
value = init;
|
|
}
|
|
else {
|
|
this.expect(':');
|
|
value = this.parsePatternWithDefault(params, kind);
|
|
}
|
|
}
|
|
else {
|
|
computed = this.match('[');
|
|
key = this.parseObjectPropertyKey();
|
|
this.expect(':');
|
|
value = this.parsePatternWithDefault(params, kind);
|
|
}
|
|
return this.finalize(node, new Node.Property('init', key, computed, value, method, shorthand));
|
|
};
|
|
Parser.prototype.parseObjectPattern = function (params, kind) {
|
|
var node = this.createNode();
|
|
var properties = [];
|
|
this.expect('{');
|
|
while (!this.match('}')) {
|
|
properties.push(this.parsePropertyPattern(params, kind));
|
|
if (!this.match('}')) {
|
|
this.expect(',');
|
|
}
|
|
}
|
|
this.expect('}');
|
|
return this.finalize(node, new Node.ObjectPattern(properties));
|
|
};
|
|
Parser.prototype.parsePattern = function (params, kind) {
|
|
var pattern;
|
|
if (this.match('[')) {
|
|
pattern = this.parseArrayPattern(params, kind);
|
|
}
|
|
else if (this.match('{')) {
|
|
pattern = this.parseObjectPattern(params, kind);
|
|
}
|
|
else {
|
|
if (this.matchKeyword('let') && (kind === 'const' || kind === 'let')) {
|
|
this.tolerateUnexpectedToken(this.lookahead, messages_1.Messages.LetInLexicalBinding);
|
|
}
|
|
params.push(this.lookahead);
|
|
pattern = this.parseVariableIdentifier(kind);
|
|
}
|
|
return pattern;
|
|
};
|
|
Parser.prototype.parsePatternWithDefault = function (params, kind) {
|
|
var startToken = this.lookahead;
|
|
var pattern = this.parsePattern(params, kind);
|
|
if (this.match('=')) {
|
|
this.nextToken();
|
|
var previousAllowYield = this.context.allowYield;
|
|
this.context.allowYield = true;
|
|
var right = this.isolateCoverGrammar(this.parseAssignmentExpression);
|
|
this.context.allowYield = previousAllowYield;
|
|
pattern = this.finalize(this.startNode(startToken), new Node.AssignmentPattern(pattern, right));
|
|
}
|
|
return pattern;
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-variable-statement
|
|
Parser.prototype.parseVariableIdentifier = function (kind) {
|
|
var node = this.createNode();
|
|
var token = this.nextToken();
|
|
if (token.type === 4 /* Keyword */ && token.value === 'yield') {
|
|
if (this.context.strict) {
|
|
this.tolerateUnexpectedToken(token, messages_1.Messages.StrictReservedWord);
|
|
}
|
|
else if (!this.context.allowYield) {
|
|
this.throwUnexpectedToken(token);
|
|
}
|
|
}
|
|
else if (token.type !== 3 /* Identifier */) {
|
|
if (this.context.strict && token.type === 4 /* Keyword */ && this.scanner.isStrictModeReservedWord(token.value)) {
|
|
this.tolerateUnexpectedToken(token, messages_1.Messages.StrictReservedWord);
|
|
}
|
|
else {
|
|
if (this.context.strict || token.value !== 'let' || kind !== 'var') {
|
|
this.throwUnexpectedToken(token);
|
|
}
|
|
}
|
|
}
|
|
else if ((this.context.isModule || this.context.await) && token.type === 3 /* Identifier */ && token.value === 'await') {
|
|
this.tolerateUnexpectedToken(token);
|
|
}
|
|
return this.finalize(node, new Node.Identifier(token.value));
|
|
};
|
|
Parser.prototype.parseVariableDeclaration = function (options) {
|
|
var node = this.createNode();
|
|
var params = [];
|
|
var id = this.parsePattern(params, 'var');
|
|
if (this.context.strict && id.type === syntax_1.Syntax.Identifier) {
|
|
if (this.scanner.isRestrictedWord(id.name)) {
|
|
this.tolerateError(messages_1.Messages.StrictVarName);
|
|
}
|
|
}
|
|
var init = null;
|
|
if (this.match('=')) {
|
|
this.nextToken();
|
|
init = this.isolateCoverGrammar(this.parseAssignmentExpression);
|
|
}
|
|
else if (id.type !== syntax_1.Syntax.Identifier && !options.inFor) {
|
|
this.expect('=');
|
|
}
|
|
return this.finalize(node, new Node.VariableDeclarator(id, init));
|
|
};
|
|
Parser.prototype.parseVariableDeclarationList = function (options) {
|
|
var opt = { inFor: options.inFor };
|
|
var list = [];
|
|
list.push(this.parseVariableDeclaration(opt));
|
|
while (this.match(',')) {
|
|
this.nextToken();
|
|
list.push(this.parseVariableDeclaration(opt));
|
|
}
|
|
return list;
|
|
};
|
|
Parser.prototype.parseVariableStatement = function () {
|
|
var node = this.createNode();
|
|
this.expectKeyword('var');
|
|
var declarations = this.parseVariableDeclarationList({ inFor: false });
|
|
this.consumeSemicolon();
|
|
return this.finalize(node, new Node.VariableDeclaration(declarations, 'var'));
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-empty-statement
|
|
Parser.prototype.parseEmptyStatement = function () {
|
|
var node = this.createNode();
|
|
this.expect(';');
|
|
return this.finalize(node, new Node.EmptyStatement());
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-expression-statement
|
|
Parser.prototype.parseExpressionStatement = function () {
|
|
var node = this.createNode();
|
|
var expr = this.parseExpression();
|
|
this.consumeSemicolon();
|
|
return this.finalize(node, new Node.ExpressionStatement(expr));
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-if-statement
|
|
Parser.prototype.parseIfClause = function () {
|
|
if (this.context.strict && this.matchKeyword('function')) {
|
|
this.tolerateError(messages_1.Messages.StrictFunction);
|
|
}
|
|
return this.parseStatement();
|
|
};
|
|
Parser.prototype.parseIfStatement = function () {
|
|
var node = this.createNode();
|
|
var consequent;
|
|
var alternate = null;
|
|
this.expectKeyword('if');
|
|
this.expect('(');
|
|
var test = this.parseExpression();
|
|
if (!this.match(')') && this.config.tolerant) {
|
|
this.tolerateUnexpectedToken(this.nextToken());
|
|
consequent = this.finalize(this.createNode(), new Node.EmptyStatement());
|
|
}
|
|
else {
|
|
this.expect(')');
|
|
consequent = this.parseIfClause();
|
|
if (this.matchKeyword('else')) {
|
|
this.nextToken();
|
|
alternate = this.parseIfClause();
|
|
}
|
|
}
|
|
return this.finalize(node, new Node.IfStatement(test, consequent, alternate));
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-do-while-statement
|
|
Parser.prototype.parseDoWhileStatement = function () {
|
|
var node = this.createNode();
|
|
this.expectKeyword('do');
|
|
var previousInIteration = this.context.inIteration;
|
|
this.context.inIteration = true;
|
|
var body = this.parseStatement();
|
|
this.context.inIteration = previousInIteration;
|
|
this.expectKeyword('while');
|
|
this.expect('(');
|
|
var test = this.parseExpression();
|
|
if (!this.match(')') && this.config.tolerant) {
|
|
this.tolerateUnexpectedToken(this.nextToken());
|
|
}
|
|
else {
|
|
this.expect(')');
|
|
if (this.match(';')) {
|
|
this.nextToken();
|
|
}
|
|
}
|
|
return this.finalize(node, new Node.DoWhileStatement(body, test));
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-while-statement
|
|
Parser.prototype.parseWhileStatement = function () {
|
|
var node = this.createNode();
|
|
var body;
|
|
this.expectKeyword('while');
|
|
this.expect('(');
|
|
var test = this.parseExpression();
|
|
if (!this.match(')') && this.config.tolerant) {
|
|
this.tolerateUnexpectedToken(this.nextToken());
|
|
body = this.finalize(this.createNode(), new Node.EmptyStatement());
|
|
}
|
|
else {
|
|
this.expect(')');
|
|
var previousInIteration = this.context.inIteration;
|
|
this.context.inIteration = true;
|
|
body = this.parseStatement();
|
|
this.context.inIteration = previousInIteration;
|
|
}
|
|
return this.finalize(node, new Node.WhileStatement(test, body));
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-for-statement
|
|
// https://tc39.github.io/ecma262/#sec-for-in-and-for-of-statements
|
|
Parser.prototype.parseForStatement = function () {
|
|
var init = null;
|
|
var test = null;
|
|
var update = null;
|
|
var forIn = true;
|
|
var left, right;
|
|
var node = this.createNode();
|
|
this.expectKeyword('for');
|
|
this.expect('(');
|
|
if (this.match(';')) {
|
|
this.nextToken();
|
|
}
|
|
else {
|
|
if (this.matchKeyword('var')) {
|
|
init = this.createNode();
|
|
this.nextToken();
|
|
var previousAllowIn = this.context.allowIn;
|
|
this.context.allowIn = false;
|
|
var declarations = this.parseVariableDeclarationList({ inFor: true });
|
|
this.context.allowIn = previousAllowIn;
|
|
if (declarations.length === 1 && this.matchKeyword('in')) {
|
|
var decl = declarations[0];
|
|
if (decl.init && (decl.id.type === syntax_1.Syntax.ArrayPattern || decl.id.type === syntax_1.Syntax.ObjectPattern || this.context.strict)) {
|
|
this.tolerateError(messages_1.Messages.ForInOfLoopInitializer, 'for-in');
|
|
}
|
|
init = this.finalize(init, new Node.VariableDeclaration(declarations, 'var'));
|
|
this.nextToken();
|
|
left = init;
|
|
right = this.parseExpression();
|
|
init = null;
|
|
}
|
|
else if (declarations.length === 1 && declarations[0].init === null && this.matchContextualKeyword('of')) {
|
|
init = this.finalize(init, new Node.VariableDeclaration(declarations, 'var'));
|
|
this.nextToken();
|
|
left = init;
|
|
right = this.parseAssignmentExpression();
|
|
init = null;
|
|
forIn = false;
|
|
}
|
|
else {
|
|
init = this.finalize(init, new Node.VariableDeclaration(declarations, 'var'));
|
|
this.expect(';');
|
|
}
|
|
}
|
|
else if (this.matchKeyword('const') || this.matchKeyword('let')) {
|
|
init = this.createNode();
|
|
var kind = this.nextToken().value;
|
|
if (!this.context.strict && this.lookahead.value === 'in') {
|
|
init = this.finalize(init, new Node.Identifier(kind));
|
|
this.nextToken();
|
|
left = init;
|
|
right = this.parseExpression();
|
|
init = null;
|
|
}
|
|
else {
|
|
var previousAllowIn = this.context.allowIn;
|
|
this.context.allowIn = false;
|
|
var declarations = this.parseBindingList(kind, { inFor: true });
|
|
this.context.allowIn = previousAllowIn;
|
|
if (declarations.length === 1 && declarations[0].init === null && this.matchKeyword('in')) {
|
|
init = this.finalize(init, new Node.VariableDeclaration(declarations, kind));
|
|
this.nextToken();
|
|
left = init;
|
|
right = this.parseExpression();
|
|
init = null;
|
|
}
|
|
else if (declarations.length === 1 && declarations[0].init === null && this.matchContextualKeyword('of')) {
|
|
init = this.finalize(init, new Node.VariableDeclaration(declarations, kind));
|
|
this.nextToken();
|
|
left = init;
|
|
right = this.parseAssignmentExpression();
|
|
init = null;
|
|
forIn = false;
|
|
}
|
|
else {
|
|
this.consumeSemicolon();
|
|
init = this.finalize(init, new Node.VariableDeclaration(declarations, kind));
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
var initStartToken = this.lookahead;
|
|
var previousAllowIn = this.context.allowIn;
|
|
this.context.allowIn = false;
|
|
init = this.inheritCoverGrammar(this.parseAssignmentExpression);
|
|
this.context.allowIn = previousAllowIn;
|
|
if (this.matchKeyword('in')) {
|
|
if (!this.context.isAssignmentTarget || init.type === syntax_1.Syntax.AssignmentExpression) {
|
|
this.tolerateError(messages_1.Messages.InvalidLHSInForIn);
|
|
}
|
|
this.nextToken();
|
|
this.reinterpretExpressionAsPattern(init);
|
|
left = init;
|
|
right = this.parseExpression();
|
|
init = null;
|
|
}
|
|
else if (this.matchContextualKeyword('of')) {
|
|
if (!this.context.isAssignmentTarget || init.type === syntax_1.Syntax.AssignmentExpression) {
|
|
this.tolerateError(messages_1.Messages.InvalidLHSInForLoop);
|
|
}
|
|
this.nextToken();
|
|
this.reinterpretExpressionAsPattern(init);
|
|
left = init;
|
|
right = this.parseAssignmentExpression();
|
|
init = null;
|
|
forIn = false;
|
|
}
|
|
else {
|
|
if (this.match(',')) {
|
|
var initSeq = [init];
|
|
while (this.match(',')) {
|
|
this.nextToken();
|
|
initSeq.push(this.isolateCoverGrammar(this.parseAssignmentExpression));
|
|
}
|
|
init = this.finalize(this.startNode(initStartToken), new Node.SequenceExpression(initSeq));
|
|
}
|
|
this.expect(';');
|
|
}
|
|
}
|
|
}
|
|
if (typeof left === 'undefined') {
|
|
if (!this.match(';')) {
|
|
test = this.parseExpression();
|
|
}
|
|
this.expect(';');
|
|
if (!this.match(')')) {
|
|
update = this.parseExpression();
|
|
}
|
|
}
|
|
var body;
|
|
if (!this.match(')') && this.config.tolerant) {
|
|
this.tolerateUnexpectedToken(this.nextToken());
|
|
body = this.finalize(this.createNode(), new Node.EmptyStatement());
|
|
}
|
|
else {
|
|
this.expect(')');
|
|
var previousInIteration = this.context.inIteration;
|
|
this.context.inIteration = true;
|
|
body = this.isolateCoverGrammar(this.parseStatement);
|
|
this.context.inIteration = previousInIteration;
|
|
}
|
|
return (typeof left === 'undefined') ?
|
|
this.finalize(node, new Node.ForStatement(init, test, update, body)) :
|
|
forIn ? this.finalize(node, new Node.ForInStatement(left, right, body)) :
|
|
this.finalize(node, new Node.ForOfStatement(left, right, body));
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-continue-statement
|
|
Parser.prototype.parseContinueStatement = function () {
|
|
var node = this.createNode();
|
|
this.expectKeyword('continue');
|
|
var label = null;
|
|
if (this.lookahead.type === 3 /* Identifier */ && !this.hasLineTerminator) {
|
|
var id = this.parseVariableIdentifier();
|
|
label = id;
|
|
var key = '$' + id.name;
|
|
if (!Object.prototype.hasOwnProperty.call(this.context.labelSet, key)) {
|
|
this.throwError(messages_1.Messages.UnknownLabel, id.name);
|
|
}
|
|
}
|
|
this.consumeSemicolon();
|
|
if (label === null && !this.context.inIteration) {
|
|
this.throwError(messages_1.Messages.IllegalContinue);
|
|
}
|
|
return this.finalize(node, new Node.ContinueStatement(label));
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-break-statement
|
|
Parser.prototype.parseBreakStatement = function () {
|
|
var node = this.createNode();
|
|
this.expectKeyword('break');
|
|
var label = null;
|
|
if (this.lookahead.type === 3 /* Identifier */ && !this.hasLineTerminator) {
|
|
var id = this.parseVariableIdentifier();
|
|
var key = '$' + id.name;
|
|
if (!Object.prototype.hasOwnProperty.call(this.context.labelSet, key)) {
|
|
this.throwError(messages_1.Messages.UnknownLabel, id.name);
|
|
}
|
|
label = id;
|
|
}
|
|
this.consumeSemicolon();
|
|
if (label === null && !this.context.inIteration && !this.context.inSwitch) {
|
|
this.throwError(messages_1.Messages.IllegalBreak);
|
|
}
|
|
return this.finalize(node, new Node.BreakStatement(label));
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-return-statement
|
|
Parser.prototype.parseReturnStatement = function () {
|
|
if (!this.context.inFunctionBody) {
|
|
this.tolerateError(messages_1.Messages.IllegalReturn);
|
|
}
|
|
var node = this.createNode();
|
|
this.expectKeyword('return');
|
|
var hasArgument = (!this.match(';') && !this.match('}') &&
|
|
!this.hasLineTerminator && this.lookahead.type !== 2 /* EOF */) ||
|
|
this.lookahead.type === 8 /* StringLiteral */ ||
|
|
this.lookahead.type === 10 /* Template */;
|
|
var argument = hasArgument ? this.parseExpression() : null;
|
|
this.consumeSemicolon();
|
|
return this.finalize(node, new Node.ReturnStatement(argument));
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-with-statement
|
|
Parser.prototype.parseWithStatement = function () {
|
|
if (this.context.strict) {
|
|
this.tolerateError(messages_1.Messages.StrictModeWith);
|
|
}
|
|
var node = this.createNode();
|
|
var body;
|
|
this.expectKeyword('with');
|
|
this.expect('(');
|
|
var object = this.parseExpression();
|
|
if (!this.match(')') && this.config.tolerant) {
|
|
this.tolerateUnexpectedToken(this.nextToken());
|
|
body = this.finalize(this.createNode(), new Node.EmptyStatement());
|
|
}
|
|
else {
|
|
this.expect(')');
|
|
body = this.parseStatement();
|
|
}
|
|
return this.finalize(node, new Node.WithStatement(object, body));
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-switch-statement
|
|
Parser.prototype.parseSwitchCase = function () {
|
|
var node = this.createNode();
|
|
var test;
|
|
if (this.matchKeyword('default')) {
|
|
this.nextToken();
|
|
test = null;
|
|
}
|
|
else {
|
|
this.expectKeyword('case');
|
|
test = this.parseExpression();
|
|
}
|
|
this.expect(':');
|
|
var consequent = [];
|
|
while (true) {
|
|
if (this.match('}') || this.matchKeyword('default') || this.matchKeyword('case')) {
|
|
break;
|
|
}
|
|
consequent.push(this.parseStatementListItem());
|
|
}
|
|
return this.finalize(node, new Node.SwitchCase(test, consequent));
|
|
};
|
|
Parser.prototype.parseSwitchStatement = function () {
|
|
var node = this.createNode();
|
|
this.expectKeyword('switch');
|
|
this.expect('(');
|
|
var discriminant = this.parseExpression();
|
|
this.expect(')');
|
|
var previousInSwitch = this.context.inSwitch;
|
|
this.context.inSwitch = true;
|
|
var cases = [];
|
|
var defaultFound = false;
|
|
this.expect('{');
|
|
while (true) {
|
|
if (this.match('}')) {
|
|
break;
|
|
}
|
|
var clause = this.parseSwitchCase();
|
|
if (clause.test === null) {
|
|
if (defaultFound) {
|
|
this.throwError(messages_1.Messages.MultipleDefaultsInSwitch);
|
|
}
|
|
defaultFound = true;
|
|
}
|
|
cases.push(clause);
|
|
}
|
|
this.expect('}');
|
|
this.context.inSwitch = previousInSwitch;
|
|
return this.finalize(node, new Node.SwitchStatement(discriminant, cases));
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-labelled-statements
|
|
Parser.prototype.parseLabelledStatement = function () {
|
|
var node = this.createNode();
|
|
var expr = this.parseExpression();
|
|
var statement;
|
|
if ((expr.type === syntax_1.Syntax.Identifier) && this.match(':')) {
|
|
this.nextToken();
|
|
var id = expr;
|
|
var key = '$' + id.name;
|
|
if (Object.prototype.hasOwnProperty.call(this.context.labelSet, key)) {
|
|
this.throwError(messages_1.Messages.Redeclaration, 'Label', id.name);
|
|
}
|
|
this.context.labelSet[key] = true;
|
|
var body = void 0;
|
|
if (this.matchKeyword('class')) {
|
|
this.tolerateUnexpectedToken(this.lookahead);
|
|
body = this.parseClassDeclaration();
|
|
}
|
|
else if (this.matchKeyword('function')) {
|
|
var token = this.lookahead;
|
|
var declaration = this.parseFunctionDeclaration();
|
|
if (this.context.strict) {
|
|
this.tolerateUnexpectedToken(token, messages_1.Messages.StrictFunction);
|
|
}
|
|
else if (declaration.generator) {
|
|
this.tolerateUnexpectedToken(token, messages_1.Messages.GeneratorInLegacyContext);
|
|
}
|
|
body = declaration;
|
|
}
|
|
else {
|
|
body = this.parseStatement();
|
|
}
|
|
delete this.context.labelSet[key];
|
|
statement = new Node.LabeledStatement(id, body);
|
|
}
|
|
else {
|
|
this.consumeSemicolon();
|
|
statement = new Node.ExpressionStatement(expr);
|
|
}
|
|
return this.finalize(node, statement);
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-throw-statement
|
|
Parser.prototype.parseThrowStatement = function () {
|
|
var node = this.createNode();
|
|
this.expectKeyword('throw');
|
|
if (this.hasLineTerminator) {
|
|
this.throwError(messages_1.Messages.NewlineAfterThrow);
|
|
}
|
|
var argument = this.parseExpression();
|
|
this.consumeSemicolon();
|
|
return this.finalize(node, new Node.ThrowStatement(argument));
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-try-statement
|
|
Parser.prototype.parseCatchClause = function () {
|
|
var node = this.createNode();
|
|
this.expectKeyword('catch');
|
|
this.expect('(');
|
|
if (this.match(')')) {
|
|
this.throwUnexpectedToken(this.lookahead);
|
|
}
|
|
var params = [];
|
|
var param = this.parsePattern(params);
|
|
var paramMap = {};
|
|
for (var i = 0; i < params.length; i++) {
|
|
var key = '$' + params[i].value;
|
|
if (Object.prototype.hasOwnProperty.call(paramMap, key)) {
|
|
this.tolerateError(messages_1.Messages.DuplicateBinding, params[i].value);
|
|
}
|
|
paramMap[key] = true;
|
|
}
|
|
if (this.context.strict && param.type === syntax_1.Syntax.Identifier) {
|
|
if (this.scanner.isRestrictedWord(param.name)) {
|
|
this.tolerateError(messages_1.Messages.StrictCatchVariable);
|
|
}
|
|
}
|
|
this.expect(')');
|
|
var body = this.parseBlock();
|
|
return this.finalize(node, new Node.CatchClause(param, body));
|
|
};
|
|
Parser.prototype.parseFinallyClause = function () {
|
|
this.expectKeyword('finally');
|
|
return this.parseBlock();
|
|
};
|
|
Parser.prototype.parseTryStatement = function () {
|
|
var node = this.createNode();
|
|
this.expectKeyword('try');
|
|
var block = this.parseBlock();
|
|
var handler = this.matchKeyword('catch') ? this.parseCatchClause() : null;
|
|
var finalizer = this.matchKeyword('finally') ? this.parseFinallyClause() : null;
|
|
if (!handler && !finalizer) {
|
|
this.throwError(messages_1.Messages.NoCatchOrFinally);
|
|
}
|
|
return this.finalize(node, new Node.TryStatement(block, handler, finalizer));
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-debugger-statement
|
|
Parser.prototype.parseDebuggerStatement = function () {
|
|
var node = this.createNode();
|
|
this.expectKeyword('debugger');
|
|
this.consumeSemicolon();
|
|
return this.finalize(node, new Node.DebuggerStatement());
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-ecmascript-language-statements-and-declarations
|
|
Parser.prototype.parseStatement = function () {
|
|
var statement;
|
|
switch (this.lookahead.type) {
|
|
case 1 /* BooleanLiteral */:
|
|
case 5 /* NullLiteral */:
|
|
case 6 /* NumericLiteral */:
|
|
case 8 /* StringLiteral */:
|
|
case 10 /* Template */:
|
|
case 9 /* RegularExpression */:
|
|
statement = this.parseExpressionStatement();
|
|
break;
|
|
case 7 /* Punctuator */:
|
|
var value = this.lookahead.value;
|
|
if (value === '{') {
|
|
statement = this.parseBlock();
|
|
}
|
|
else if (value === '(') {
|
|
statement = this.parseExpressionStatement();
|
|
}
|
|
else if (value === ';') {
|
|
statement = this.parseEmptyStatement();
|
|
}
|
|
else {
|
|
statement = this.parseExpressionStatement();
|
|
}
|
|
break;
|
|
case 3 /* Identifier */:
|
|
statement = this.matchAsyncFunction() ? this.parseFunctionDeclaration() : this.parseLabelledStatement();
|
|
break;
|
|
case 4 /* Keyword */:
|
|
switch (this.lookahead.value) {
|
|
case 'break':
|
|
statement = this.parseBreakStatement();
|
|
break;
|
|
case 'continue':
|
|
statement = this.parseContinueStatement();
|
|
break;
|
|
case 'debugger':
|
|
statement = this.parseDebuggerStatement();
|
|
break;
|
|
case 'do':
|
|
statement = this.parseDoWhileStatement();
|
|
break;
|
|
case 'for':
|
|
statement = this.parseForStatement();
|
|
break;
|
|
case 'function':
|
|
statement = this.parseFunctionDeclaration();
|
|
break;
|
|
case 'if':
|
|
statement = this.parseIfStatement();
|
|
break;
|
|
case 'return':
|
|
statement = this.parseReturnStatement();
|
|
break;
|
|
case 'switch':
|
|
statement = this.parseSwitchStatement();
|
|
break;
|
|
case 'throw':
|
|
statement = this.parseThrowStatement();
|
|
break;
|
|
case 'try':
|
|
statement = this.parseTryStatement();
|
|
break;
|
|
case 'var':
|
|
statement = this.parseVariableStatement();
|
|
break;
|
|
case 'while':
|
|
statement = this.parseWhileStatement();
|
|
break;
|
|
case 'with':
|
|
statement = this.parseWithStatement();
|
|
break;
|
|
default:
|
|
statement = this.parseExpressionStatement();
|
|
break;
|
|
}
|
|
break;
|
|
default:
|
|
statement = this.throwUnexpectedToken(this.lookahead);
|
|
}
|
|
return statement;
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-function-definitions
|
|
Parser.prototype.parseFunctionSourceElements = function () {
|
|
var node = this.createNode();
|
|
this.expect('{');
|
|
var body = this.parseDirectivePrologues();
|
|
var previousLabelSet = this.context.labelSet;
|
|
var previousInIteration = this.context.inIteration;
|
|
var previousInSwitch = this.context.inSwitch;
|
|
var previousInFunctionBody = this.context.inFunctionBody;
|
|
this.context.labelSet = {};
|
|
this.context.inIteration = false;
|
|
this.context.inSwitch = false;
|
|
this.context.inFunctionBody = true;
|
|
while (this.lookahead.type !== 2 /* EOF */) {
|
|
if (this.match('}')) {
|
|
break;
|
|
}
|
|
body.push(this.parseStatementListItem());
|
|
}
|
|
this.expect('}');
|
|
this.context.labelSet = previousLabelSet;
|
|
this.context.inIteration = previousInIteration;
|
|
this.context.inSwitch = previousInSwitch;
|
|
this.context.inFunctionBody = previousInFunctionBody;
|
|
return this.finalize(node, new Node.BlockStatement(body));
|
|
};
|
|
Parser.prototype.validateParam = function (options, param, name) {
|
|
var key = '$' + name;
|
|
if (this.context.strict) {
|
|
if (this.scanner.isRestrictedWord(name)) {
|
|
options.stricted = param;
|
|
options.message = messages_1.Messages.StrictParamName;
|
|
}
|
|
if (Object.prototype.hasOwnProperty.call(options.paramSet, key)) {
|
|
options.stricted = param;
|
|
options.message = messages_1.Messages.StrictParamDupe;
|
|
}
|
|
}
|
|
else if (!options.firstRestricted) {
|
|
if (this.scanner.isRestrictedWord(name)) {
|
|
options.firstRestricted = param;
|
|
options.message = messages_1.Messages.StrictParamName;
|
|
}
|
|
else if (this.scanner.isStrictModeReservedWord(name)) {
|
|
options.firstRestricted = param;
|
|
options.message = messages_1.Messages.StrictReservedWord;
|
|
}
|
|
else if (Object.prototype.hasOwnProperty.call(options.paramSet, key)) {
|
|
options.stricted = param;
|
|
options.message = messages_1.Messages.StrictParamDupe;
|
|
}
|
|
}
|
|
/* istanbul ignore next */
|
|
if (typeof Object.defineProperty === 'function') {
|
|
Object.defineProperty(options.paramSet, key, { value: true, enumerable: true, writable: true, configurable: true });
|
|
}
|
|
else {
|
|
options.paramSet[key] = true;
|
|
}
|
|
};
|
|
Parser.prototype.parseRestElement = function (params) {
|
|
var node = this.createNode();
|
|
this.expect('...');
|
|
var arg = this.parsePattern(params);
|
|
if (this.match('=')) {
|
|
this.throwError(messages_1.Messages.DefaultRestParameter);
|
|
}
|
|
if (!this.match(')')) {
|
|
this.throwError(messages_1.Messages.ParameterAfterRestParameter);
|
|
}
|
|
return this.finalize(node, new Node.RestElement(arg));
|
|
};
|
|
Parser.prototype.parseFormalParameter = function (options) {
|
|
var params = [];
|
|
var param = this.match('...') ? this.parseRestElement(params) : this.parsePatternWithDefault(params);
|
|
for (var i = 0; i < params.length; i++) {
|
|
this.validateParam(options, params[i], params[i].value);
|
|
}
|
|
options.simple = options.simple && (param instanceof Node.Identifier);
|
|
options.params.push(param);
|
|
};
|
|
Parser.prototype.parseFormalParameters = function (firstRestricted) {
|
|
var options;
|
|
options = {
|
|
simple: true,
|
|
params: [],
|
|
firstRestricted: firstRestricted
|
|
};
|
|
this.expect('(');
|
|
if (!this.match(')')) {
|
|
options.paramSet = {};
|
|
while (this.lookahead.type !== 2 /* EOF */) {
|
|
this.parseFormalParameter(options);
|
|
if (this.match(')')) {
|
|
break;
|
|
}
|
|
this.expect(',');
|
|
if (this.match(')')) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
this.expect(')');
|
|
return {
|
|
simple: options.simple,
|
|
params: options.params,
|
|
stricted: options.stricted,
|
|
firstRestricted: options.firstRestricted,
|
|
message: options.message
|
|
};
|
|
};
|
|
Parser.prototype.matchAsyncFunction = function () {
|
|
var match = this.matchContextualKeyword('async');
|
|
if (match) {
|
|
var state = this.scanner.saveState();
|
|
this.scanner.scanComments();
|
|
var next = this.scanner.lex();
|
|
this.scanner.restoreState(state);
|
|
match = (state.lineNumber === next.lineNumber) && (next.type === 4 /* Keyword */) && (next.value === 'function');
|
|
}
|
|
return match;
|
|
};
|
|
Parser.prototype.parseFunctionDeclaration = function (identifierIsOptional) {
|
|
var node = this.createNode();
|
|
var isAsync = this.matchContextualKeyword('async');
|
|
if (isAsync) {
|
|
this.nextToken();
|
|
}
|
|
this.expectKeyword('function');
|
|
var isGenerator = isAsync ? false : this.match('*');
|
|
if (isGenerator) {
|
|
this.nextToken();
|
|
}
|
|
var message;
|
|
var id = null;
|
|
var firstRestricted = null;
|
|
if (!identifierIsOptional || !this.match('(')) {
|
|
var token = this.lookahead;
|
|
id = this.parseVariableIdentifier();
|
|
if (this.context.strict) {
|
|
if (this.scanner.isRestrictedWord(token.value)) {
|
|
this.tolerateUnexpectedToken(token, messages_1.Messages.StrictFunctionName);
|
|
}
|
|
}
|
|
else {
|
|
if (this.scanner.isRestrictedWord(token.value)) {
|
|
firstRestricted = token;
|
|
message = messages_1.Messages.StrictFunctionName;
|
|
}
|
|
else if (this.scanner.isStrictModeReservedWord(token.value)) {
|
|
firstRestricted = token;
|
|
message = messages_1.Messages.StrictReservedWord;
|
|
}
|
|
}
|
|
}
|
|
var previousAllowAwait = this.context.await;
|
|
var previousAllowYield = this.context.allowYield;
|
|
this.context.await = isAsync;
|
|
this.context.allowYield = !isGenerator;
|
|
var formalParameters = this.parseFormalParameters(firstRestricted);
|
|
var params = formalParameters.params;
|
|
var stricted = formalParameters.stricted;
|
|
firstRestricted = formalParameters.firstRestricted;
|
|
if (formalParameters.message) {
|
|
message = formalParameters.message;
|
|
}
|
|
var previousStrict = this.context.strict;
|
|
var previousAllowStrictDirective = this.context.allowStrictDirective;
|
|
this.context.allowStrictDirective = formalParameters.simple;
|
|
var body = this.parseFunctionSourceElements();
|
|
if (this.context.strict && firstRestricted) {
|
|
this.throwUnexpectedToken(firstRestricted, message);
|
|
}
|
|
if (this.context.strict && stricted) {
|
|
this.tolerateUnexpectedToken(stricted, message);
|
|
}
|
|
this.context.strict = previousStrict;
|
|
this.context.allowStrictDirective = previousAllowStrictDirective;
|
|
this.context.await = previousAllowAwait;
|
|
this.context.allowYield = previousAllowYield;
|
|
return isAsync ? this.finalize(node, new Node.AsyncFunctionDeclaration(id, params, body)) :
|
|
this.finalize(node, new Node.FunctionDeclaration(id, params, body, isGenerator));
|
|
};
|
|
Parser.prototype.parseFunctionExpression = function () {
|
|
var node = this.createNode();
|
|
var isAsync = this.matchContextualKeyword('async');
|
|
if (isAsync) {
|
|
this.nextToken();
|
|
}
|
|
this.expectKeyword('function');
|
|
var isGenerator = isAsync ? false : this.match('*');
|
|
if (isGenerator) {
|
|
this.nextToken();
|
|
}
|
|
var message;
|
|
var id = null;
|
|
var firstRestricted;
|
|
var previousAllowAwait = this.context.await;
|
|
var previousAllowYield = this.context.allowYield;
|
|
this.context.await = isAsync;
|
|
this.context.allowYield = !isGenerator;
|
|
if (!this.match('(')) {
|
|
var token = this.lookahead;
|
|
id = (!this.context.strict && !isGenerator && this.matchKeyword('yield')) ? this.parseIdentifierName() : this.parseVariableIdentifier();
|
|
if (this.context.strict) {
|
|
if (this.scanner.isRestrictedWord(token.value)) {
|
|
this.tolerateUnexpectedToken(token, messages_1.Messages.StrictFunctionName);
|
|
}
|
|
}
|
|
else {
|
|
if (this.scanner.isRestrictedWord(token.value)) {
|
|
firstRestricted = token;
|
|
message = messages_1.Messages.StrictFunctionName;
|
|
}
|
|
else if (this.scanner.isStrictModeReservedWord(token.value)) {
|
|
firstRestricted = token;
|
|
message = messages_1.Messages.StrictReservedWord;
|
|
}
|
|
}
|
|
}
|
|
var formalParameters = this.parseFormalParameters(firstRestricted);
|
|
var params = formalParameters.params;
|
|
var stricted = formalParameters.stricted;
|
|
firstRestricted = formalParameters.firstRestricted;
|
|
if (formalParameters.message) {
|
|
message = formalParameters.message;
|
|
}
|
|
var previousStrict = this.context.strict;
|
|
var previousAllowStrictDirective = this.context.allowStrictDirective;
|
|
this.context.allowStrictDirective = formalParameters.simple;
|
|
var body = this.parseFunctionSourceElements();
|
|
if (this.context.strict && firstRestricted) {
|
|
this.throwUnexpectedToken(firstRestricted, message);
|
|
}
|
|
if (this.context.strict && stricted) {
|
|
this.tolerateUnexpectedToken(stricted, message);
|
|
}
|
|
this.context.strict = previousStrict;
|
|
this.context.allowStrictDirective = previousAllowStrictDirective;
|
|
this.context.await = previousAllowAwait;
|
|
this.context.allowYield = previousAllowYield;
|
|
return isAsync ? this.finalize(node, new Node.AsyncFunctionExpression(id, params, body)) :
|
|
this.finalize(node, new Node.FunctionExpression(id, params, body, isGenerator));
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-directive-prologues-and-the-use-strict-directive
|
|
Parser.prototype.parseDirective = function () {
|
|
var token = this.lookahead;
|
|
var node = this.createNode();
|
|
var expr = this.parseExpression();
|
|
var directive = (expr.type === syntax_1.Syntax.Literal) ? this.getTokenRaw(token).slice(1, -1) : null;
|
|
this.consumeSemicolon();
|
|
return this.finalize(node, directive ? new Node.Directive(expr, directive) : new Node.ExpressionStatement(expr));
|
|
};
|
|
Parser.prototype.parseDirectivePrologues = function () {
|
|
var firstRestricted = null;
|
|
var body = [];
|
|
while (true) {
|
|
var token = this.lookahead;
|
|
if (token.type !== 8 /* StringLiteral */) {
|
|
break;
|
|
}
|
|
var statement = this.parseDirective();
|
|
body.push(statement);
|
|
var directive = statement.directive;
|
|
if (typeof directive !== 'string') {
|
|
break;
|
|
}
|
|
if (directive === 'use strict') {
|
|
this.context.strict = true;
|
|
if (firstRestricted) {
|
|
this.tolerateUnexpectedToken(firstRestricted, messages_1.Messages.StrictOctalLiteral);
|
|
}
|
|
if (!this.context.allowStrictDirective) {
|
|
this.tolerateUnexpectedToken(token, messages_1.Messages.IllegalLanguageModeDirective);
|
|
}
|
|
}
|
|
else {
|
|
if (!firstRestricted && token.octal) {
|
|
firstRestricted = token;
|
|
}
|
|
}
|
|
}
|
|
return body;
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-method-definitions
|
|
Parser.prototype.qualifiedPropertyName = function (token) {
|
|
switch (token.type) {
|
|
case 3 /* Identifier */:
|
|
case 8 /* StringLiteral */:
|
|
case 1 /* BooleanLiteral */:
|
|
case 5 /* NullLiteral */:
|
|
case 6 /* NumericLiteral */:
|
|
case 4 /* Keyword */:
|
|
return true;
|
|
case 7 /* Punctuator */:
|
|
return token.value === '[';
|
|
}
|
|
return false;
|
|
};
|
|
Parser.prototype.parseGetterMethod = function () {
|
|
var node = this.createNode();
|
|
var isGenerator = false;
|
|
var previousAllowYield = this.context.allowYield;
|
|
this.context.allowYield = !isGenerator;
|
|
var formalParameters = this.parseFormalParameters();
|
|
if (formalParameters.params.length > 0) {
|
|
this.tolerateError(messages_1.Messages.BadGetterArity);
|
|
}
|
|
var method = this.parsePropertyMethod(formalParameters);
|
|
this.context.allowYield = previousAllowYield;
|
|
return this.finalize(node, new Node.FunctionExpression(null, formalParameters.params, method, isGenerator));
|
|
};
|
|
Parser.prototype.parseSetterMethod = function () {
|
|
var node = this.createNode();
|
|
var isGenerator = false;
|
|
var previousAllowYield = this.context.allowYield;
|
|
this.context.allowYield = !isGenerator;
|
|
var formalParameters = this.parseFormalParameters();
|
|
if (formalParameters.params.length !== 1) {
|
|
this.tolerateError(messages_1.Messages.BadSetterArity);
|
|
}
|
|
else if (formalParameters.params[0] instanceof Node.RestElement) {
|
|
this.tolerateError(messages_1.Messages.BadSetterRestParameter);
|
|
}
|
|
var method = this.parsePropertyMethod(formalParameters);
|
|
this.context.allowYield = previousAllowYield;
|
|
return this.finalize(node, new Node.FunctionExpression(null, formalParameters.params, method, isGenerator));
|
|
};
|
|
Parser.prototype.parseGeneratorMethod = function () {
|
|
var node = this.createNode();
|
|
var isGenerator = true;
|
|
var previousAllowYield = this.context.allowYield;
|
|
this.context.allowYield = true;
|
|
var params = this.parseFormalParameters();
|
|
this.context.allowYield = false;
|
|
var method = this.parsePropertyMethod(params);
|
|
this.context.allowYield = previousAllowYield;
|
|
return this.finalize(node, new Node.FunctionExpression(null, params.params, method, isGenerator));
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-generator-function-definitions
|
|
Parser.prototype.isStartOfExpression = function () {
|
|
var start = true;
|
|
var value = this.lookahead.value;
|
|
switch (this.lookahead.type) {
|
|
case 7 /* Punctuator */:
|
|
start = (value === '[') || (value === '(') || (value === '{') ||
|
|
(value === '+') || (value === '-') ||
|
|
(value === '!') || (value === '~') ||
|
|
(value === '++') || (value === '--') ||
|
|
(value === '/') || (value === '/='); // regular expression literal
|
|
break;
|
|
case 4 /* Keyword */:
|
|
start = (value === 'class') || (value === 'delete') ||
|
|
(value === 'function') || (value === 'let') || (value === 'new') ||
|
|
(value === 'super') || (value === 'this') || (value === 'typeof') ||
|
|
(value === 'void') || (value === 'yield');
|
|
break;
|
|
}
|
|
return start;
|
|
};
|
|
Parser.prototype.parseYieldExpression = function () {
|
|
var node = this.createNode();
|
|
this.expectKeyword('yield');
|
|
var argument = null;
|
|
var delegate = false;
|
|
if (!this.hasLineTerminator) {
|
|
var previousAllowYield = this.context.allowYield;
|
|
this.context.allowYield = false;
|
|
delegate = this.match('*');
|
|
if (delegate) {
|
|
this.nextToken();
|
|
argument = this.parseAssignmentExpression();
|
|
}
|
|
else if (this.isStartOfExpression()) {
|
|
argument = this.parseAssignmentExpression();
|
|
}
|
|
this.context.allowYield = previousAllowYield;
|
|
}
|
|
return this.finalize(node, new Node.YieldExpression(argument, delegate));
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-class-definitions
|
|
Parser.prototype.parseClassElement = function (hasConstructor) {
|
|
var token = this.lookahead;
|
|
var node = this.createNode();
|
|
var kind = '';
|
|
var key = null;
|
|
var value = null;
|
|
var computed = false;
|
|
var method = false;
|
|
var isStatic = false;
|
|
var isAsync = false;
|
|
if (this.match('*')) {
|
|
this.nextToken();
|
|
}
|
|
else {
|
|
computed = this.match('[');
|
|
key = this.parseObjectPropertyKey();
|
|
var id = key;
|
|
if (id.name === 'static' && (this.qualifiedPropertyName(this.lookahead) || this.match('*'))) {
|
|
token = this.lookahead;
|
|
isStatic = true;
|
|
computed = this.match('[');
|
|
if (this.match('*')) {
|
|
this.nextToken();
|
|
}
|
|
else {
|
|
key = this.parseObjectPropertyKey();
|
|
}
|
|
}
|
|
if ((token.type === 3 /* Identifier */) && !this.hasLineTerminator && (token.value === 'async')) {
|
|
var punctuator = this.lookahead.value;
|
|
if (punctuator !== ':' && punctuator !== '(' && punctuator !== '*') {
|
|
isAsync = true;
|
|
token = this.lookahead;
|
|
key = this.parseObjectPropertyKey();
|
|
if (token.type === 3 /* Identifier */ && token.value === 'constructor') {
|
|
this.tolerateUnexpectedToken(token, messages_1.Messages.ConstructorIsAsync);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
var lookaheadPropertyKey = this.qualifiedPropertyName(this.lookahead);
|
|
if (token.type === 3 /* Identifier */) {
|
|
if (token.value === 'get' && lookaheadPropertyKey) {
|
|
kind = 'get';
|
|
computed = this.match('[');
|
|
key = this.parseObjectPropertyKey();
|
|
this.context.allowYield = false;
|
|
value = this.parseGetterMethod();
|
|
}
|
|
else if (token.value === 'set' && lookaheadPropertyKey) {
|
|
kind = 'set';
|
|
computed = this.match('[');
|
|
key = this.parseObjectPropertyKey();
|
|
value = this.parseSetterMethod();
|
|
}
|
|
}
|
|
else if (token.type === 7 /* Punctuator */ && token.value === '*' && lookaheadPropertyKey) {
|
|
kind = 'init';
|
|
computed = this.match('[');
|
|
key = this.parseObjectPropertyKey();
|
|
value = this.parseGeneratorMethod();
|
|
method = true;
|
|
}
|
|
if (!kind && key && this.match('(')) {
|
|
kind = 'init';
|
|
value = isAsync ? this.parsePropertyMethodAsyncFunction() : this.parsePropertyMethodFunction();
|
|
method = true;
|
|
}
|
|
if (!kind) {
|
|
this.throwUnexpectedToken(this.lookahead);
|
|
}
|
|
if (kind === 'init') {
|
|
kind = 'method';
|
|
}
|
|
if (!computed) {
|
|
if (isStatic && this.isPropertyKey(key, 'prototype')) {
|
|
this.throwUnexpectedToken(token, messages_1.Messages.StaticPrototype);
|
|
}
|
|
if (!isStatic && this.isPropertyKey(key, 'constructor')) {
|
|
if (kind !== 'method' || !method || (value && value.generator)) {
|
|
this.throwUnexpectedToken(token, messages_1.Messages.ConstructorSpecialMethod);
|
|
}
|
|
if (hasConstructor.value) {
|
|
this.throwUnexpectedToken(token, messages_1.Messages.DuplicateConstructor);
|
|
}
|
|
else {
|
|
hasConstructor.value = true;
|
|
}
|
|
kind = 'constructor';
|
|
}
|
|
}
|
|
return this.finalize(node, new Node.MethodDefinition(key, computed, value, kind, isStatic));
|
|
};
|
|
Parser.prototype.parseClassElementList = function () {
|
|
var body = [];
|
|
var hasConstructor = { value: false };
|
|
this.expect('{');
|
|
while (!this.match('}')) {
|
|
if (this.match(';')) {
|
|
this.nextToken();
|
|
}
|
|
else {
|
|
body.push(this.parseClassElement(hasConstructor));
|
|
}
|
|
}
|
|
this.expect('}');
|
|
return body;
|
|
};
|
|
Parser.prototype.parseClassBody = function () {
|
|
var node = this.createNode();
|
|
var elementList = this.parseClassElementList();
|
|
return this.finalize(node, new Node.ClassBody(elementList));
|
|
};
|
|
Parser.prototype.parseClassDeclaration = function (identifierIsOptional) {
|
|
var node = this.createNode();
|
|
var previousStrict = this.context.strict;
|
|
this.context.strict = true;
|
|
this.expectKeyword('class');
|
|
var id = (identifierIsOptional && (this.lookahead.type !== 3 /* Identifier */)) ? null : this.parseVariableIdentifier();
|
|
var superClass = null;
|
|
if (this.matchKeyword('extends')) {
|
|
this.nextToken();
|
|
superClass = this.isolateCoverGrammar(this.parseLeftHandSideExpressionAllowCall);
|
|
}
|
|
var classBody = this.parseClassBody();
|
|
this.context.strict = previousStrict;
|
|
return this.finalize(node, new Node.ClassDeclaration(id, superClass, classBody));
|
|
};
|
|
Parser.prototype.parseClassExpression = function () {
|
|
var node = this.createNode();
|
|
var previousStrict = this.context.strict;
|
|
this.context.strict = true;
|
|
this.expectKeyword('class');
|
|
var id = (this.lookahead.type === 3 /* Identifier */) ? this.parseVariableIdentifier() : null;
|
|
var superClass = null;
|
|
if (this.matchKeyword('extends')) {
|
|
this.nextToken();
|
|
superClass = this.isolateCoverGrammar(this.parseLeftHandSideExpressionAllowCall);
|
|
}
|
|
var classBody = this.parseClassBody();
|
|
this.context.strict = previousStrict;
|
|
return this.finalize(node, new Node.ClassExpression(id, superClass, classBody));
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-scripts
|
|
// https://tc39.github.io/ecma262/#sec-modules
|
|
Parser.prototype.parseModule = function () {
|
|
this.context.strict = true;
|
|
this.context.isModule = true;
|
|
this.scanner.isModule = true;
|
|
var node = this.createNode();
|
|
var body = this.parseDirectivePrologues();
|
|
while (this.lookahead.type !== 2 /* EOF */) {
|
|
body.push(this.parseStatementListItem());
|
|
}
|
|
return this.finalize(node, new Node.Module(body));
|
|
};
|
|
Parser.prototype.parseScript = function () {
|
|
var node = this.createNode();
|
|
var body = this.parseDirectivePrologues();
|
|
while (this.lookahead.type !== 2 /* EOF */) {
|
|
body.push(this.parseStatementListItem());
|
|
}
|
|
return this.finalize(node, new Node.Script(body));
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-imports
|
|
Parser.prototype.parseModuleSpecifier = function () {
|
|
var node = this.createNode();
|
|
if (this.lookahead.type !== 8 /* StringLiteral */) {
|
|
this.throwError(messages_1.Messages.InvalidModuleSpecifier);
|
|
}
|
|
var token = this.nextToken();
|
|
var raw = this.getTokenRaw(token);
|
|
return this.finalize(node, new Node.Literal(token.value, raw));
|
|
};
|
|
// import {<foo as bar>} ...;
|
|
Parser.prototype.parseImportSpecifier = function () {
|
|
var node = this.createNode();
|
|
var imported;
|
|
var local;
|
|
if (this.lookahead.type === 3 /* Identifier */) {
|
|
imported = this.parseVariableIdentifier();
|
|
local = imported;
|
|
if (this.matchContextualKeyword('as')) {
|
|
this.nextToken();
|
|
local = this.parseVariableIdentifier();
|
|
}
|
|
}
|
|
else {
|
|
imported = this.parseIdentifierName();
|
|
local = imported;
|
|
if (this.matchContextualKeyword('as')) {
|
|
this.nextToken();
|
|
local = this.parseVariableIdentifier();
|
|
}
|
|
else {
|
|
this.throwUnexpectedToken(this.nextToken());
|
|
}
|
|
}
|
|
return this.finalize(node, new Node.ImportSpecifier(local, imported));
|
|
};
|
|
// {foo, bar as bas}
|
|
Parser.prototype.parseNamedImports = function () {
|
|
this.expect('{');
|
|
var specifiers = [];
|
|
while (!this.match('}')) {
|
|
specifiers.push(this.parseImportSpecifier());
|
|
if (!this.match('}')) {
|
|
this.expect(',');
|
|
}
|
|
}
|
|
this.expect('}');
|
|
return specifiers;
|
|
};
|
|
// import <foo> ...;
|
|
Parser.prototype.parseImportDefaultSpecifier = function () {
|
|
var node = this.createNode();
|
|
var local = this.parseIdentifierName();
|
|
return this.finalize(node, new Node.ImportDefaultSpecifier(local));
|
|
};
|
|
// import <* as foo> ...;
|
|
Parser.prototype.parseImportNamespaceSpecifier = function () {
|
|
var node = this.createNode();
|
|
this.expect('*');
|
|
if (!this.matchContextualKeyword('as')) {
|
|
this.throwError(messages_1.Messages.NoAsAfterImportNamespace);
|
|
}
|
|
this.nextToken();
|
|
var local = this.parseIdentifierName();
|
|
return this.finalize(node, new Node.ImportNamespaceSpecifier(local));
|
|
};
|
|
Parser.prototype.parseImportDeclaration = function () {
|
|
if (this.context.inFunctionBody) {
|
|
this.throwError(messages_1.Messages.IllegalImportDeclaration);
|
|
}
|
|
var node = this.createNode();
|
|
this.expectKeyword('import');
|
|
var src;
|
|
var specifiers = [];
|
|
if (this.lookahead.type === 8 /* StringLiteral */) {
|
|
// import 'foo';
|
|
src = this.parseModuleSpecifier();
|
|
}
|
|
else {
|
|
if (this.match('{')) {
|
|
// import {bar}
|
|
specifiers = specifiers.concat(this.parseNamedImports());
|
|
}
|
|
else if (this.match('*')) {
|
|
// import * as foo
|
|
specifiers.push(this.parseImportNamespaceSpecifier());
|
|
}
|
|
else if (this.isIdentifierName(this.lookahead) && !this.matchKeyword('default')) {
|
|
// import foo
|
|
specifiers.push(this.parseImportDefaultSpecifier());
|
|
if (this.match(',')) {
|
|
this.nextToken();
|
|
if (this.match('*')) {
|
|
// import foo, * as foo
|
|
specifiers.push(this.parseImportNamespaceSpecifier());
|
|
}
|
|
else if (this.match('{')) {
|
|
// import foo, {bar}
|
|
specifiers = specifiers.concat(this.parseNamedImports());
|
|
}
|
|
else {
|
|
this.throwUnexpectedToken(this.lookahead);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
this.throwUnexpectedToken(this.nextToken());
|
|
}
|
|
if (!this.matchContextualKeyword('from')) {
|
|
var message = this.lookahead.value ? messages_1.Messages.UnexpectedToken : messages_1.Messages.MissingFromClause;
|
|
this.throwError(message, this.lookahead.value);
|
|
}
|
|
this.nextToken();
|
|
src = this.parseModuleSpecifier();
|
|
}
|
|
this.consumeSemicolon();
|
|
return this.finalize(node, new Node.ImportDeclaration(specifiers, src));
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-exports
|
|
Parser.prototype.parseExportSpecifier = function () {
|
|
var node = this.createNode();
|
|
var local = this.parseIdentifierName();
|
|
var exported = local;
|
|
if (this.matchContextualKeyword('as')) {
|
|
this.nextToken();
|
|
exported = this.parseIdentifierName();
|
|
}
|
|
return this.finalize(node, new Node.ExportSpecifier(local, exported));
|
|
};
|
|
Parser.prototype.parseExportDeclaration = function () {
|
|
if (this.context.inFunctionBody) {
|
|
this.throwError(messages_1.Messages.IllegalExportDeclaration);
|
|
}
|
|
var node = this.createNode();
|
|
this.expectKeyword('export');
|
|
var exportDeclaration;
|
|
if (this.matchKeyword('default')) {
|
|
// export default ...
|
|
this.nextToken();
|
|
if (this.matchKeyword('function')) {
|
|
// export default function foo () {}
|
|
// export default function () {}
|
|
var declaration = this.parseFunctionDeclaration(true);
|
|
exportDeclaration = this.finalize(node, new Node.ExportDefaultDeclaration(declaration));
|
|
}
|
|
else if (this.matchKeyword('class')) {
|
|
// export default class foo {}
|
|
var declaration = this.parseClassDeclaration(true);
|
|
exportDeclaration = this.finalize(node, new Node.ExportDefaultDeclaration(declaration));
|
|
}
|
|
else if (this.matchContextualKeyword('async')) {
|
|
// export default async function f () {}
|
|
// export default async function () {}
|
|
// export default async x => x
|
|
var declaration = this.matchAsyncFunction() ? this.parseFunctionDeclaration(true) : this.parseAssignmentExpression();
|
|
exportDeclaration = this.finalize(node, new Node.ExportDefaultDeclaration(declaration));
|
|
}
|
|
else {
|
|
if (this.matchContextualKeyword('from')) {
|
|
this.throwError(messages_1.Messages.UnexpectedToken, this.lookahead.value);
|
|
}
|
|
// export default {};
|
|
// export default [];
|
|
// export default (1 + 2);
|
|
var declaration = this.match('{') ? this.parseObjectInitializer() :
|
|
this.match('[') ? this.parseArrayInitializer() : this.parseAssignmentExpression();
|
|
this.consumeSemicolon();
|
|
exportDeclaration = this.finalize(node, new Node.ExportDefaultDeclaration(declaration));
|
|
}
|
|
}
|
|
else if (this.match('*')) {
|
|
// export * from 'foo';
|
|
this.nextToken();
|
|
if (!this.matchContextualKeyword('from')) {
|
|
var message = this.lookahead.value ? messages_1.Messages.UnexpectedToken : messages_1.Messages.MissingFromClause;
|
|
this.throwError(message, this.lookahead.value);
|
|
}
|
|
this.nextToken();
|
|
var src = this.parseModuleSpecifier();
|
|
this.consumeSemicolon();
|
|
exportDeclaration = this.finalize(node, new Node.ExportAllDeclaration(src));
|
|
}
|
|
else if (this.lookahead.type === 4 /* Keyword */) {
|
|
// export var f = 1;
|
|
var declaration = void 0;
|
|
switch (this.lookahead.value) {
|
|
case 'let':
|
|
case 'const':
|
|
declaration = this.parseLexicalDeclaration({ inFor: false });
|
|
break;
|
|
case 'var':
|
|
case 'class':
|
|
case 'function':
|
|
declaration = this.parseStatementListItem();
|
|
break;
|
|
default:
|
|
this.throwUnexpectedToken(this.lookahead);
|
|
}
|
|
exportDeclaration = this.finalize(node, new Node.ExportNamedDeclaration(declaration, [], null));
|
|
}
|
|
else if (this.matchAsyncFunction()) {
|
|
var declaration = this.parseFunctionDeclaration();
|
|
exportDeclaration = this.finalize(node, new Node.ExportNamedDeclaration(declaration, [], null));
|
|
}
|
|
else {
|
|
var specifiers = [];
|
|
var source = null;
|
|
var isExportFromIdentifier = false;
|
|
this.expect('{');
|
|
while (!this.match('}')) {
|
|
isExportFromIdentifier = isExportFromIdentifier || this.matchKeyword('default');
|
|
specifiers.push(this.parseExportSpecifier());
|
|
if (!this.match('}')) {
|
|
this.expect(',');
|
|
}
|
|
}
|
|
this.expect('}');
|
|
if (this.matchContextualKeyword('from')) {
|
|
// export {default} from 'foo';
|
|
// export {foo} from 'foo';
|
|
this.nextToken();
|
|
source = this.parseModuleSpecifier();
|
|
this.consumeSemicolon();
|
|
}
|
|
else if (isExportFromIdentifier) {
|
|
// export {default}; // missing fromClause
|
|
var message = this.lookahead.value ? messages_1.Messages.UnexpectedToken : messages_1.Messages.MissingFromClause;
|
|
this.throwError(message, this.lookahead.value);
|
|
}
|
|
else {
|
|
// export {foo};
|
|
this.consumeSemicolon();
|
|
}
|
|
exportDeclaration = this.finalize(node, new Node.ExportNamedDeclaration(null, specifiers, source));
|
|
}
|
|
return exportDeclaration;
|
|
};
|
|
return Parser;
|
|
}());
|
|
exports$1.Parser = Parser;
|
|
|
|
|
|
/***/ },
|
|
/* 9 */
|
|
/***/ function(module, exports$1) {
|
|
// Ensure the condition is true, otherwise throw an error.
|
|
// This is only to have a better contract semantic, i.e. another safety net
|
|
// to catch a logic error. The condition shall be fulfilled in normal case.
|
|
// Do NOT use this to enforce a certain condition on any user input.
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
function assert(condition, message) {
|
|
/* istanbul ignore if */
|
|
if (!condition) {
|
|
throw new Error('ASSERT: ' + message);
|
|
}
|
|
}
|
|
exports$1.assert = assert;
|
|
|
|
|
|
/***/ },
|
|
/* 10 */
|
|
/***/ function(module, exports$1) {
|
|
/* tslint:disable:max-classes-per-file */
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
var ErrorHandler = (function () {
|
|
function ErrorHandler() {
|
|
this.errors = [];
|
|
this.tolerant = false;
|
|
}
|
|
ErrorHandler.prototype.recordError = function (error) {
|
|
this.errors.push(error);
|
|
};
|
|
ErrorHandler.prototype.tolerate = function (error) {
|
|
if (this.tolerant) {
|
|
this.recordError(error);
|
|
}
|
|
else {
|
|
throw error;
|
|
}
|
|
};
|
|
ErrorHandler.prototype.constructError = function (msg, column) {
|
|
var error = new Error(msg);
|
|
try {
|
|
throw error;
|
|
}
|
|
catch (base) {
|
|
/* istanbul ignore else */
|
|
if (Object.create && Object.defineProperty) {
|
|
error = Object.create(base);
|
|
Object.defineProperty(error, 'column', { value: column });
|
|
}
|
|
}
|
|
/* istanbul ignore next */
|
|
return error;
|
|
};
|
|
ErrorHandler.prototype.createError = function (index, line, col, description) {
|
|
var msg = 'Line ' + line + ': ' + description;
|
|
var error = this.constructError(msg, col);
|
|
error.index = index;
|
|
error.lineNumber = line;
|
|
error.description = description;
|
|
return error;
|
|
};
|
|
ErrorHandler.prototype.throwError = function (index, line, col, description) {
|
|
throw this.createError(index, line, col, description);
|
|
};
|
|
ErrorHandler.prototype.tolerateError = function (index, line, col, description) {
|
|
var error = this.createError(index, line, col, description);
|
|
if (this.tolerant) {
|
|
this.recordError(error);
|
|
}
|
|
else {
|
|
throw error;
|
|
}
|
|
};
|
|
return ErrorHandler;
|
|
}());
|
|
exports$1.ErrorHandler = ErrorHandler;
|
|
|
|
|
|
/***/ },
|
|
/* 11 */
|
|
/***/ function(module, exports$1) {
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
// Error messages should be identical to V8.
|
|
exports$1.Messages = {
|
|
BadGetterArity: 'Getter must not have any formal parameters',
|
|
BadSetterArity: 'Setter must have exactly one formal parameter',
|
|
BadSetterRestParameter: 'Setter function argument must not be a rest parameter',
|
|
ConstructorIsAsync: 'Class constructor may not be an async method',
|
|
ConstructorSpecialMethod: 'Class constructor may not be an accessor',
|
|
DeclarationMissingInitializer: 'Missing initializer in %0 declaration',
|
|
DefaultRestParameter: 'Unexpected token =',
|
|
DuplicateBinding: 'Duplicate binding %0',
|
|
DuplicateConstructor: 'A class may only have one constructor',
|
|
DuplicateProtoProperty: 'Duplicate __proto__ fields are not allowed in object literals',
|
|
ForInOfLoopInitializer: '%0 loop variable declaration may not have an initializer',
|
|
GeneratorInLegacyContext: 'Generator declarations are not allowed in legacy contexts',
|
|
IllegalBreak: 'Illegal break statement',
|
|
IllegalContinue: 'Illegal continue statement',
|
|
IllegalExportDeclaration: 'Unexpected token',
|
|
IllegalImportDeclaration: 'Unexpected token',
|
|
IllegalLanguageModeDirective: 'Illegal \'use strict\' directive in function with non-simple parameter list',
|
|
IllegalReturn: 'Illegal return statement',
|
|
InvalidEscapedReservedWord: 'Keyword must not contain escaped characters',
|
|
InvalidHexEscapeSequence: 'Invalid hexadecimal escape sequence',
|
|
InvalidLHSInAssignment: 'Invalid left-hand side in assignment',
|
|
InvalidLHSInForIn: 'Invalid left-hand side in for-in',
|
|
InvalidLHSInForLoop: 'Invalid left-hand side in for-loop',
|
|
InvalidModuleSpecifier: 'Unexpected token',
|
|
InvalidRegExp: 'Invalid regular expression',
|
|
LetInLexicalBinding: 'let is disallowed as a lexically bound name',
|
|
MissingFromClause: 'Unexpected token',
|
|
MultipleDefaultsInSwitch: 'More than one default clause in switch statement',
|
|
NewlineAfterThrow: 'Illegal newline after throw',
|
|
NoAsAfterImportNamespace: 'Unexpected token',
|
|
NoCatchOrFinally: 'Missing catch or finally after try',
|
|
ParameterAfterRestParameter: 'Rest parameter must be last formal parameter',
|
|
Redeclaration: '%0 \'%1\' has already been declared',
|
|
StaticPrototype: 'Classes may not have static property named prototype',
|
|
StrictCatchVariable: 'Catch variable may not be eval or arguments in strict mode',
|
|
StrictDelete: 'Delete of an unqualified identifier in strict mode.',
|
|
StrictFunction: 'In strict mode code, functions can only be declared at top level or inside a block',
|
|
StrictFunctionName: 'Function name may not be eval or arguments in strict mode',
|
|
StrictLHSAssignment: 'Assignment to eval or arguments is not allowed in strict mode',
|
|
StrictLHSPostfix: 'Postfix increment/decrement may not have eval or arguments operand in strict mode',
|
|
StrictLHSPrefix: 'Prefix increment/decrement may not have eval or arguments operand in strict mode',
|
|
StrictModeWith: 'Strict mode code may not include a with statement',
|
|
StrictOctalLiteral: 'Octal literals are not allowed in strict mode.',
|
|
StrictParamDupe: 'Strict mode function may not have duplicate parameter names',
|
|
StrictParamName: 'Parameter name eval or arguments is not allowed in strict mode',
|
|
StrictReservedWord: 'Use of future reserved word in strict mode',
|
|
StrictVarName: 'Variable name may not be eval or arguments in strict mode',
|
|
TemplateOctalLiteral: 'Octal literals are not allowed in template strings.',
|
|
UnexpectedEOS: 'Unexpected end of input',
|
|
UnexpectedIdentifier: 'Unexpected identifier',
|
|
UnexpectedNumber: 'Unexpected number',
|
|
UnexpectedReserved: 'Unexpected reserved word',
|
|
UnexpectedString: 'Unexpected string',
|
|
UnexpectedTemplate: 'Unexpected quasi %0',
|
|
UnexpectedToken: 'Unexpected token %0',
|
|
UnexpectedTokenIllegal: 'Unexpected token ILLEGAL',
|
|
UnknownLabel: 'Undefined label \'%0\'',
|
|
UnterminatedRegExp: 'Invalid regular expression: missing /'
|
|
};
|
|
|
|
|
|
/***/ },
|
|
/* 12 */
|
|
/***/ function(module, exports$1, __webpack_require__) {
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
var assert_1 = __webpack_require__(9);
|
|
var character_1 = __webpack_require__(4);
|
|
var messages_1 = __webpack_require__(11);
|
|
function hexValue(ch) {
|
|
return '0123456789abcdef'.indexOf(ch.toLowerCase());
|
|
}
|
|
function octalValue(ch) {
|
|
return '01234567'.indexOf(ch);
|
|
}
|
|
var Scanner = (function () {
|
|
function Scanner(code, handler) {
|
|
this.source = code;
|
|
this.errorHandler = handler;
|
|
this.trackComment = false;
|
|
this.isModule = false;
|
|
this.length = code.length;
|
|
this.index = 0;
|
|
this.lineNumber = (code.length > 0) ? 1 : 0;
|
|
this.lineStart = 0;
|
|
this.curlyStack = [];
|
|
}
|
|
Scanner.prototype.saveState = function () {
|
|
return {
|
|
index: this.index,
|
|
lineNumber: this.lineNumber,
|
|
lineStart: this.lineStart
|
|
};
|
|
};
|
|
Scanner.prototype.restoreState = function (state) {
|
|
this.index = state.index;
|
|
this.lineNumber = state.lineNumber;
|
|
this.lineStart = state.lineStart;
|
|
};
|
|
Scanner.prototype.eof = function () {
|
|
return this.index >= this.length;
|
|
};
|
|
Scanner.prototype.throwUnexpectedToken = function (message) {
|
|
if (message === void 0) { message = messages_1.Messages.UnexpectedTokenIllegal; }
|
|
return this.errorHandler.throwError(this.index, this.lineNumber, this.index - this.lineStart + 1, message);
|
|
};
|
|
Scanner.prototype.tolerateUnexpectedToken = function (message) {
|
|
if (message === void 0) { message = messages_1.Messages.UnexpectedTokenIllegal; }
|
|
this.errorHandler.tolerateError(this.index, this.lineNumber, this.index - this.lineStart + 1, message);
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-comments
|
|
Scanner.prototype.skipSingleLineComment = function (offset) {
|
|
var comments = [];
|
|
var start, loc;
|
|
if (this.trackComment) {
|
|
comments = [];
|
|
start = this.index - offset;
|
|
loc = {
|
|
start: {
|
|
line: this.lineNumber,
|
|
column: this.index - this.lineStart - offset
|
|
},
|
|
end: {}
|
|
};
|
|
}
|
|
while (!this.eof()) {
|
|
var ch = this.source.charCodeAt(this.index);
|
|
++this.index;
|
|
if (character_1.Character.isLineTerminator(ch)) {
|
|
if (this.trackComment) {
|
|
loc.end = {
|
|
line: this.lineNumber,
|
|
column: this.index - this.lineStart - 1
|
|
};
|
|
var entry = {
|
|
multiLine: false,
|
|
slice: [start + offset, this.index - 1],
|
|
range: [start, this.index - 1],
|
|
loc: loc
|
|
};
|
|
comments.push(entry);
|
|
}
|
|
if (ch === 13 && this.source.charCodeAt(this.index) === 10) {
|
|
++this.index;
|
|
}
|
|
++this.lineNumber;
|
|
this.lineStart = this.index;
|
|
return comments;
|
|
}
|
|
}
|
|
if (this.trackComment) {
|
|
loc.end = {
|
|
line: this.lineNumber,
|
|
column: this.index - this.lineStart
|
|
};
|
|
var entry = {
|
|
multiLine: false,
|
|
slice: [start + offset, this.index],
|
|
range: [start, this.index],
|
|
loc: loc
|
|
};
|
|
comments.push(entry);
|
|
}
|
|
return comments;
|
|
};
|
|
Scanner.prototype.skipMultiLineComment = function () {
|
|
var comments = [];
|
|
var start, loc;
|
|
if (this.trackComment) {
|
|
comments = [];
|
|
start = this.index - 2;
|
|
loc = {
|
|
start: {
|
|
line: this.lineNumber,
|
|
column: this.index - this.lineStart - 2
|
|
},
|
|
end: {}
|
|
};
|
|
}
|
|
while (!this.eof()) {
|
|
var ch = this.source.charCodeAt(this.index);
|
|
if (character_1.Character.isLineTerminator(ch)) {
|
|
if (ch === 0x0D && this.source.charCodeAt(this.index + 1) === 0x0A) {
|
|
++this.index;
|
|
}
|
|
++this.lineNumber;
|
|
++this.index;
|
|
this.lineStart = this.index;
|
|
}
|
|
else if (ch === 0x2A) {
|
|
// Block comment ends with '*/'.
|
|
if (this.source.charCodeAt(this.index + 1) === 0x2F) {
|
|
this.index += 2;
|
|
if (this.trackComment) {
|
|
loc.end = {
|
|
line: this.lineNumber,
|
|
column: this.index - this.lineStart
|
|
};
|
|
var entry = {
|
|
multiLine: true,
|
|
slice: [start + 2, this.index - 2],
|
|
range: [start, this.index],
|
|
loc: loc
|
|
};
|
|
comments.push(entry);
|
|
}
|
|
return comments;
|
|
}
|
|
++this.index;
|
|
}
|
|
else {
|
|
++this.index;
|
|
}
|
|
}
|
|
// Ran off the end of the file - the whole thing is a comment
|
|
if (this.trackComment) {
|
|
loc.end = {
|
|
line: this.lineNumber,
|
|
column: this.index - this.lineStart
|
|
};
|
|
var entry = {
|
|
multiLine: true,
|
|
slice: [start + 2, this.index],
|
|
range: [start, this.index],
|
|
loc: loc
|
|
};
|
|
comments.push(entry);
|
|
}
|
|
this.tolerateUnexpectedToken();
|
|
return comments;
|
|
};
|
|
Scanner.prototype.scanComments = function () {
|
|
var comments;
|
|
if (this.trackComment) {
|
|
comments = [];
|
|
}
|
|
var start = (this.index === 0);
|
|
while (!this.eof()) {
|
|
var ch = this.source.charCodeAt(this.index);
|
|
if (character_1.Character.isWhiteSpace(ch)) {
|
|
++this.index;
|
|
}
|
|
else if (character_1.Character.isLineTerminator(ch)) {
|
|
++this.index;
|
|
if (ch === 0x0D && this.source.charCodeAt(this.index) === 0x0A) {
|
|
++this.index;
|
|
}
|
|
++this.lineNumber;
|
|
this.lineStart = this.index;
|
|
start = true;
|
|
}
|
|
else if (ch === 0x2F) {
|
|
ch = this.source.charCodeAt(this.index + 1);
|
|
if (ch === 0x2F) {
|
|
this.index += 2;
|
|
var comment = this.skipSingleLineComment(2);
|
|
if (this.trackComment) {
|
|
comments = comments.concat(comment);
|
|
}
|
|
start = true;
|
|
}
|
|
else if (ch === 0x2A) {
|
|
this.index += 2;
|
|
var comment = this.skipMultiLineComment();
|
|
if (this.trackComment) {
|
|
comments = comments.concat(comment);
|
|
}
|
|
}
|
|
else {
|
|
break;
|
|
}
|
|
}
|
|
else if (start && ch === 0x2D) {
|
|
// U+003E is '>'
|
|
if ((this.source.charCodeAt(this.index + 1) === 0x2D) && (this.source.charCodeAt(this.index + 2) === 0x3E)) {
|
|
// '-->' is a single-line comment
|
|
this.index += 3;
|
|
var comment = this.skipSingleLineComment(3);
|
|
if (this.trackComment) {
|
|
comments = comments.concat(comment);
|
|
}
|
|
}
|
|
else {
|
|
break;
|
|
}
|
|
}
|
|
else if (ch === 0x3C && !this.isModule) {
|
|
if (this.source.slice(this.index + 1, this.index + 4) === '!--') {
|
|
this.index += 4; // `<!--`
|
|
var comment = this.skipSingleLineComment(4);
|
|
if (this.trackComment) {
|
|
comments = comments.concat(comment);
|
|
}
|
|
}
|
|
else {
|
|
break;
|
|
}
|
|
}
|
|
else {
|
|
break;
|
|
}
|
|
}
|
|
return comments;
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-future-reserved-words
|
|
Scanner.prototype.isFutureReservedWord = function (id) {
|
|
switch (id) {
|
|
case 'enum':
|
|
case 'export':
|
|
case 'import':
|
|
case 'super':
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
};
|
|
Scanner.prototype.isStrictModeReservedWord = function (id) {
|
|
switch (id) {
|
|
case 'implements':
|
|
case 'interface':
|
|
case 'package':
|
|
case 'private':
|
|
case 'protected':
|
|
case 'public':
|
|
case 'static':
|
|
case 'yield':
|
|
case 'let':
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
};
|
|
Scanner.prototype.isRestrictedWord = function (id) {
|
|
return id === 'eval' || id === 'arguments';
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-keywords
|
|
Scanner.prototype.isKeyword = function (id) {
|
|
switch (id.length) {
|
|
case 2:
|
|
return (id === 'if') || (id === 'in') || (id === 'do');
|
|
case 3:
|
|
return (id === 'var') || (id === 'for') || (id === 'new') ||
|
|
(id === 'try') || (id === 'let');
|
|
case 4:
|
|
return (id === 'this') || (id === 'else') || (id === 'case') ||
|
|
(id === 'void') || (id === 'with') || (id === 'enum');
|
|
case 5:
|
|
return (id === 'while') || (id === 'break') || (id === 'catch') ||
|
|
(id === 'throw') || (id === 'const') || (id === 'yield') ||
|
|
(id === 'class') || (id === 'super');
|
|
case 6:
|
|
return (id === 'return') || (id === 'typeof') || (id === 'delete') ||
|
|
(id === 'switch') || (id === 'export') || (id === 'import');
|
|
case 7:
|
|
return (id === 'default') || (id === 'finally') || (id === 'extends');
|
|
case 8:
|
|
return (id === 'function') || (id === 'continue') || (id === 'debugger');
|
|
case 10:
|
|
return (id === 'instanceof');
|
|
default:
|
|
return false;
|
|
}
|
|
};
|
|
Scanner.prototype.codePointAt = function (i) {
|
|
var cp = this.source.charCodeAt(i);
|
|
if (cp >= 0xD800 && cp <= 0xDBFF) {
|
|
var second = this.source.charCodeAt(i + 1);
|
|
if (second >= 0xDC00 && second <= 0xDFFF) {
|
|
var first = cp;
|
|
cp = (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
|
|
}
|
|
}
|
|
return cp;
|
|
};
|
|
Scanner.prototype.scanHexEscape = function (prefix) {
|
|
var len = (prefix === 'u') ? 4 : 2;
|
|
var code = 0;
|
|
for (var i = 0; i < len; ++i) {
|
|
if (!this.eof() && character_1.Character.isHexDigit(this.source.charCodeAt(this.index))) {
|
|
code = code * 16 + hexValue(this.source[this.index++]);
|
|
}
|
|
else {
|
|
return null;
|
|
}
|
|
}
|
|
return String.fromCharCode(code);
|
|
};
|
|
Scanner.prototype.scanUnicodeCodePointEscape = function () {
|
|
var ch = this.source[this.index];
|
|
var code = 0;
|
|
// At least, one hex digit is required.
|
|
if (ch === '}') {
|
|
this.throwUnexpectedToken();
|
|
}
|
|
while (!this.eof()) {
|
|
ch = this.source[this.index++];
|
|
if (!character_1.Character.isHexDigit(ch.charCodeAt(0))) {
|
|
break;
|
|
}
|
|
code = code * 16 + hexValue(ch);
|
|
}
|
|
if (code > 0x10FFFF || ch !== '}') {
|
|
this.throwUnexpectedToken();
|
|
}
|
|
return character_1.Character.fromCodePoint(code);
|
|
};
|
|
Scanner.prototype.getIdentifier = function () {
|
|
var start = this.index++;
|
|
while (!this.eof()) {
|
|
var ch = this.source.charCodeAt(this.index);
|
|
if (ch === 0x5C) {
|
|
// Blackslash (U+005C) marks Unicode escape sequence.
|
|
this.index = start;
|
|
return this.getComplexIdentifier();
|
|
}
|
|
else if (ch >= 0xD800 && ch < 0xDFFF) {
|
|
// Need to handle surrogate pairs.
|
|
this.index = start;
|
|
return this.getComplexIdentifier();
|
|
}
|
|
if (character_1.Character.isIdentifierPart(ch)) {
|
|
++this.index;
|
|
}
|
|
else {
|
|
break;
|
|
}
|
|
}
|
|
return this.source.slice(start, this.index);
|
|
};
|
|
Scanner.prototype.getComplexIdentifier = function () {
|
|
var cp = this.codePointAt(this.index);
|
|
var id = character_1.Character.fromCodePoint(cp);
|
|
this.index += id.length;
|
|
// '\u' (U+005C, U+0075) denotes an escaped character.
|
|
var ch;
|
|
if (cp === 0x5C) {
|
|
if (this.source.charCodeAt(this.index) !== 0x75) {
|
|
this.throwUnexpectedToken();
|
|
}
|
|
++this.index;
|
|
if (this.source[this.index] === '{') {
|
|
++this.index;
|
|
ch = this.scanUnicodeCodePointEscape();
|
|
}
|
|
else {
|
|
ch = this.scanHexEscape('u');
|
|
if (ch === null || ch === '\\' || !character_1.Character.isIdentifierStart(ch.charCodeAt(0))) {
|
|
this.throwUnexpectedToken();
|
|
}
|
|
}
|
|
id = ch;
|
|
}
|
|
while (!this.eof()) {
|
|
cp = this.codePointAt(this.index);
|
|
if (!character_1.Character.isIdentifierPart(cp)) {
|
|
break;
|
|
}
|
|
ch = character_1.Character.fromCodePoint(cp);
|
|
id += ch;
|
|
this.index += ch.length;
|
|
// '\u' (U+005C, U+0075) denotes an escaped character.
|
|
if (cp === 0x5C) {
|
|
id = id.substr(0, id.length - 1);
|
|
if (this.source.charCodeAt(this.index) !== 0x75) {
|
|
this.throwUnexpectedToken();
|
|
}
|
|
++this.index;
|
|
if (this.source[this.index] === '{') {
|
|
++this.index;
|
|
ch = this.scanUnicodeCodePointEscape();
|
|
}
|
|
else {
|
|
ch = this.scanHexEscape('u');
|
|
if (ch === null || ch === '\\' || !character_1.Character.isIdentifierPart(ch.charCodeAt(0))) {
|
|
this.throwUnexpectedToken();
|
|
}
|
|
}
|
|
id += ch;
|
|
}
|
|
}
|
|
return id;
|
|
};
|
|
Scanner.prototype.octalToDecimal = function (ch) {
|
|
// \0 is not octal escape sequence
|
|
var octal = (ch !== '0');
|
|
var code = octalValue(ch);
|
|
if (!this.eof() && character_1.Character.isOctalDigit(this.source.charCodeAt(this.index))) {
|
|
octal = true;
|
|
code = code * 8 + octalValue(this.source[this.index++]);
|
|
// 3 digits are only allowed when string starts
|
|
// with 0, 1, 2, 3
|
|
if ('0123'.indexOf(ch) >= 0 && !this.eof() && character_1.Character.isOctalDigit(this.source.charCodeAt(this.index))) {
|
|
code = code * 8 + octalValue(this.source[this.index++]);
|
|
}
|
|
}
|
|
return {
|
|
code: code,
|
|
octal: octal
|
|
};
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-names-and-keywords
|
|
Scanner.prototype.scanIdentifier = function () {
|
|
var type;
|
|
var start = this.index;
|
|
// Backslash (U+005C) starts an escaped character.
|
|
var id = (this.source.charCodeAt(start) === 0x5C) ? this.getComplexIdentifier() : this.getIdentifier();
|
|
// There is no keyword or literal with only one character.
|
|
// Thus, it must be an identifier.
|
|
if (id.length === 1) {
|
|
type = 3 /* Identifier */;
|
|
}
|
|
else if (this.isKeyword(id)) {
|
|
type = 4 /* Keyword */;
|
|
}
|
|
else if (id === 'null') {
|
|
type = 5 /* NullLiteral */;
|
|
}
|
|
else if (id === 'true' || id === 'false') {
|
|
type = 1 /* BooleanLiteral */;
|
|
}
|
|
else {
|
|
type = 3 /* Identifier */;
|
|
}
|
|
if (type !== 3 /* Identifier */ && (start + id.length !== this.index)) {
|
|
var restore = this.index;
|
|
this.index = start;
|
|
this.tolerateUnexpectedToken(messages_1.Messages.InvalidEscapedReservedWord);
|
|
this.index = restore;
|
|
}
|
|
return {
|
|
type: type,
|
|
value: id,
|
|
lineNumber: this.lineNumber,
|
|
lineStart: this.lineStart,
|
|
start: start,
|
|
end: this.index
|
|
};
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-punctuators
|
|
Scanner.prototype.scanPunctuator = function () {
|
|
var start = this.index;
|
|
// Check for most common single-character punctuators.
|
|
var str = this.source[this.index];
|
|
switch (str) {
|
|
case '(':
|
|
case '{':
|
|
if (str === '{') {
|
|
this.curlyStack.push('{');
|
|
}
|
|
++this.index;
|
|
break;
|
|
case '.':
|
|
++this.index;
|
|
if (this.source[this.index] === '.' && this.source[this.index + 1] === '.') {
|
|
// Spread operator: ...
|
|
this.index += 2;
|
|
str = '...';
|
|
}
|
|
break;
|
|
case '}':
|
|
++this.index;
|
|
this.curlyStack.pop();
|
|
break;
|
|
case ')':
|
|
case ';':
|
|
case ',':
|
|
case '[':
|
|
case ']':
|
|
case ':':
|
|
case '?':
|
|
case '~':
|
|
++this.index;
|
|
break;
|
|
default:
|
|
// 4-character punctuator.
|
|
str = this.source.substr(this.index, 4);
|
|
if (str === '>>>=') {
|
|
this.index += 4;
|
|
}
|
|
else {
|
|
// 3-character punctuators.
|
|
str = str.substr(0, 3);
|
|
if (str === '===' || str === '!==' || str === '>>>' ||
|
|
str === '<<=' || str === '>>=' || str === '**=') {
|
|
this.index += 3;
|
|
}
|
|
else {
|
|
// 2-character punctuators.
|
|
str = str.substr(0, 2);
|
|
if (str === '&&' || str === '||' || str === '==' || str === '!=' ||
|
|
str === '+=' || str === '-=' || str === '*=' || str === '/=' ||
|
|
str === '++' || str === '--' || str === '<<' || str === '>>' ||
|
|
str === '&=' || str === '|=' || str === '^=' || str === '%=' ||
|
|
str === '<=' || str === '>=' || str === '=>' || str === '**') {
|
|
this.index += 2;
|
|
}
|
|
else {
|
|
// 1-character punctuators.
|
|
str = this.source[this.index];
|
|
if ('<>=!+-*%&|^/'.indexOf(str) >= 0) {
|
|
++this.index;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (this.index === start) {
|
|
this.throwUnexpectedToken();
|
|
}
|
|
return {
|
|
type: 7 /* Punctuator */,
|
|
value: str,
|
|
lineNumber: this.lineNumber,
|
|
lineStart: this.lineStart,
|
|
start: start,
|
|
end: this.index
|
|
};
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-literals-numeric-literals
|
|
Scanner.prototype.scanHexLiteral = function (start) {
|
|
var num = '';
|
|
while (!this.eof()) {
|
|
if (!character_1.Character.isHexDigit(this.source.charCodeAt(this.index))) {
|
|
break;
|
|
}
|
|
num += this.source[this.index++];
|
|
}
|
|
if (num.length === 0) {
|
|
this.throwUnexpectedToken();
|
|
}
|
|
if (character_1.Character.isIdentifierStart(this.source.charCodeAt(this.index))) {
|
|
this.throwUnexpectedToken();
|
|
}
|
|
return {
|
|
type: 6 /* NumericLiteral */,
|
|
value: parseInt('0x' + num, 16),
|
|
lineNumber: this.lineNumber,
|
|
lineStart: this.lineStart,
|
|
start: start,
|
|
end: this.index
|
|
};
|
|
};
|
|
Scanner.prototype.scanBinaryLiteral = function (start) {
|
|
var num = '';
|
|
var ch;
|
|
while (!this.eof()) {
|
|
ch = this.source[this.index];
|
|
if (ch !== '0' && ch !== '1') {
|
|
break;
|
|
}
|
|
num += this.source[this.index++];
|
|
}
|
|
if (num.length === 0) {
|
|
// only 0b or 0B
|
|
this.throwUnexpectedToken();
|
|
}
|
|
if (!this.eof()) {
|
|
ch = this.source.charCodeAt(this.index);
|
|
/* istanbul ignore else */
|
|
if (character_1.Character.isIdentifierStart(ch) || character_1.Character.isDecimalDigit(ch)) {
|
|
this.throwUnexpectedToken();
|
|
}
|
|
}
|
|
return {
|
|
type: 6 /* NumericLiteral */,
|
|
value: parseInt(num, 2),
|
|
lineNumber: this.lineNumber,
|
|
lineStart: this.lineStart,
|
|
start: start,
|
|
end: this.index
|
|
};
|
|
};
|
|
Scanner.prototype.scanOctalLiteral = function (prefix, start) {
|
|
var num = '';
|
|
var octal = false;
|
|
if (character_1.Character.isOctalDigit(prefix.charCodeAt(0))) {
|
|
octal = true;
|
|
num = '0' + this.source[this.index++];
|
|
}
|
|
else {
|
|
++this.index;
|
|
}
|
|
while (!this.eof()) {
|
|
if (!character_1.Character.isOctalDigit(this.source.charCodeAt(this.index))) {
|
|
break;
|
|
}
|
|
num += this.source[this.index++];
|
|
}
|
|
if (!octal && num.length === 0) {
|
|
// only 0o or 0O
|
|
this.throwUnexpectedToken();
|
|
}
|
|
if (character_1.Character.isIdentifierStart(this.source.charCodeAt(this.index)) || character_1.Character.isDecimalDigit(this.source.charCodeAt(this.index))) {
|
|
this.throwUnexpectedToken();
|
|
}
|
|
return {
|
|
type: 6 /* NumericLiteral */,
|
|
value: parseInt(num, 8),
|
|
octal: octal,
|
|
lineNumber: this.lineNumber,
|
|
lineStart: this.lineStart,
|
|
start: start,
|
|
end: this.index
|
|
};
|
|
};
|
|
Scanner.prototype.isImplicitOctalLiteral = function () {
|
|
// Implicit octal, unless there is a non-octal digit.
|
|
// (Annex B.1.1 on Numeric Literals)
|
|
for (var i = this.index + 1; i < this.length; ++i) {
|
|
var ch = this.source[i];
|
|
if (ch === '8' || ch === '9') {
|
|
return false;
|
|
}
|
|
if (!character_1.Character.isOctalDigit(ch.charCodeAt(0))) {
|
|
return true;
|
|
}
|
|
}
|
|
return true;
|
|
};
|
|
Scanner.prototype.scanNumericLiteral = function () {
|
|
var start = this.index;
|
|
var ch = this.source[start];
|
|
assert_1.assert(character_1.Character.isDecimalDigit(ch.charCodeAt(0)) || (ch === '.'), 'Numeric literal must start with a decimal digit or a decimal point');
|
|
var num = '';
|
|
if (ch !== '.') {
|
|
num = this.source[this.index++];
|
|
ch = this.source[this.index];
|
|
// Hex number starts with '0x'.
|
|
// Octal number starts with '0'.
|
|
// Octal number in ES6 starts with '0o'.
|
|
// Binary number in ES6 starts with '0b'.
|
|
if (num === '0') {
|
|
if (ch === 'x' || ch === 'X') {
|
|
++this.index;
|
|
return this.scanHexLiteral(start);
|
|
}
|
|
if (ch === 'b' || ch === 'B') {
|
|
++this.index;
|
|
return this.scanBinaryLiteral(start);
|
|
}
|
|
if (ch === 'o' || ch === 'O') {
|
|
return this.scanOctalLiteral(ch, start);
|
|
}
|
|
if (ch && character_1.Character.isOctalDigit(ch.charCodeAt(0))) {
|
|
if (this.isImplicitOctalLiteral()) {
|
|
return this.scanOctalLiteral(ch, start);
|
|
}
|
|
}
|
|
}
|
|
while (character_1.Character.isDecimalDigit(this.source.charCodeAt(this.index))) {
|
|
num += this.source[this.index++];
|
|
}
|
|
ch = this.source[this.index];
|
|
}
|
|
if (ch === '.') {
|
|
num += this.source[this.index++];
|
|
while (character_1.Character.isDecimalDigit(this.source.charCodeAt(this.index))) {
|
|
num += this.source[this.index++];
|
|
}
|
|
ch = this.source[this.index];
|
|
}
|
|
if (ch === 'e' || ch === 'E') {
|
|
num += this.source[this.index++];
|
|
ch = this.source[this.index];
|
|
if (ch === '+' || ch === '-') {
|
|
num += this.source[this.index++];
|
|
}
|
|
if (character_1.Character.isDecimalDigit(this.source.charCodeAt(this.index))) {
|
|
while (character_1.Character.isDecimalDigit(this.source.charCodeAt(this.index))) {
|
|
num += this.source[this.index++];
|
|
}
|
|
}
|
|
else {
|
|
this.throwUnexpectedToken();
|
|
}
|
|
}
|
|
if (character_1.Character.isIdentifierStart(this.source.charCodeAt(this.index))) {
|
|
this.throwUnexpectedToken();
|
|
}
|
|
return {
|
|
type: 6 /* NumericLiteral */,
|
|
value: parseFloat(num),
|
|
lineNumber: this.lineNumber,
|
|
lineStart: this.lineStart,
|
|
start: start,
|
|
end: this.index
|
|
};
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-literals-string-literals
|
|
Scanner.prototype.scanStringLiteral = function () {
|
|
var start = this.index;
|
|
var quote = this.source[start];
|
|
assert_1.assert((quote === '\'' || quote === '"'), 'String literal must starts with a quote');
|
|
++this.index;
|
|
var octal = false;
|
|
var str = '';
|
|
while (!this.eof()) {
|
|
var ch = this.source[this.index++];
|
|
if (ch === quote) {
|
|
quote = '';
|
|
break;
|
|
}
|
|
else if (ch === '\\') {
|
|
ch = this.source[this.index++];
|
|
if (!ch || !character_1.Character.isLineTerminator(ch.charCodeAt(0))) {
|
|
switch (ch) {
|
|
case 'u':
|
|
if (this.source[this.index] === '{') {
|
|
++this.index;
|
|
str += this.scanUnicodeCodePointEscape();
|
|
}
|
|
else {
|
|
var unescaped_1 = this.scanHexEscape(ch);
|
|
if (unescaped_1 === null) {
|
|
this.throwUnexpectedToken();
|
|
}
|
|
str += unescaped_1;
|
|
}
|
|
break;
|
|
case 'x':
|
|
var unescaped = this.scanHexEscape(ch);
|
|
if (unescaped === null) {
|
|
this.throwUnexpectedToken(messages_1.Messages.InvalidHexEscapeSequence);
|
|
}
|
|
str += unescaped;
|
|
break;
|
|
case 'n':
|
|
str += '\n';
|
|
break;
|
|
case 'r':
|
|
str += '\r';
|
|
break;
|
|
case 't':
|
|
str += '\t';
|
|
break;
|
|
case 'b':
|
|
str += '\b';
|
|
break;
|
|
case 'f':
|
|
str += '\f';
|
|
break;
|
|
case 'v':
|
|
str += '\x0B';
|
|
break;
|
|
case '8':
|
|
case '9':
|
|
str += ch;
|
|
this.tolerateUnexpectedToken();
|
|
break;
|
|
default:
|
|
if (ch && character_1.Character.isOctalDigit(ch.charCodeAt(0))) {
|
|
var octToDec = this.octalToDecimal(ch);
|
|
octal = octToDec.octal || octal;
|
|
str += String.fromCharCode(octToDec.code);
|
|
}
|
|
else {
|
|
str += ch;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
else {
|
|
++this.lineNumber;
|
|
if (ch === '\r' && this.source[this.index] === '\n') {
|
|
++this.index;
|
|
}
|
|
this.lineStart = this.index;
|
|
}
|
|
}
|
|
else if (character_1.Character.isLineTerminator(ch.charCodeAt(0))) {
|
|
break;
|
|
}
|
|
else {
|
|
str += ch;
|
|
}
|
|
}
|
|
if (quote !== '') {
|
|
this.index = start;
|
|
this.throwUnexpectedToken();
|
|
}
|
|
return {
|
|
type: 8 /* StringLiteral */,
|
|
value: str,
|
|
octal: octal,
|
|
lineNumber: this.lineNumber,
|
|
lineStart: this.lineStart,
|
|
start: start,
|
|
end: this.index
|
|
};
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-template-literal-lexical-components
|
|
Scanner.prototype.scanTemplate = function () {
|
|
var cooked = '';
|
|
var terminated = false;
|
|
var start = this.index;
|
|
var head = (this.source[start] === '`');
|
|
var tail = false;
|
|
var rawOffset = 2;
|
|
++this.index;
|
|
while (!this.eof()) {
|
|
var ch = this.source[this.index++];
|
|
if (ch === '`') {
|
|
rawOffset = 1;
|
|
tail = true;
|
|
terminated = true;
|
|
break;
|
|
}
|
|
else if (ch === '$') {
|
|
if (this.source[this.index] === '{') {
|
|
this.curlyStack.push('${');
|
|
++this.index;
|
|
terminated = true;
|
|
break;
|
|
}
|
|
cooked += ch;
|
|
}
|
|
else if (ch === '\\') {
|
|
ch = this.source[this.index++];
|
|
if (!character_1.Character.isLineTerminator(ch.charCodeAt(0))) {
|
|
switch (ch) {
|
|
case 'n':
|
|
cooked += '\n';
|
|
break;
|
|
case 'r':
|
|
cooked += '\r';
|
|
break;
|
|
case 't':
|
|
cooked += '\t';
|
|
break;
|
|
case 'u':
|
|
if (this.source[this.index] === '{') {
|
|
++this.index;
|
|
cooked += this.scanUnicodeCodePointEscape();
|
|
}
|
|
else {
|
|
var restore = this.index;
|
|
var unescaped_2 = this.scanHexEscape(ch);
|
|
if (unescaped_2 !== null) {
|
|
cooked += unescaped_2;
|
|
}
|
|
else {
|
|
this.index = restore;
|
|
cooked += ch;
|
|
}
|
|
}
|
|
break;
|
|
case 'x':
|
|
var unescaped = this.scanHexEscape(ch);
|
|
if (unescaped === null) {
|
|
this.throwUnexpectedToken(messages_1.Messages.InvalidHexEscapeSequence);
|
|
}
|
|
cooked += unescaped;
|
|
break;
|
|
case 'b':
|
|
cooked += '\b';
|
|
break;
|
|
case 'f':
|
|
cooked += '\f';
|
|
break;
|
|
case 'v':
|
|
cooked += '\v';
|
|
break;
|
|
default:
|
|
if (ch === '0') {
|
|
if (character_1.Character.isDecimalDigit(this.source.charCodeAt(this.index))) {
|
|
// Illegal: \01 \02 and so on
|
|
this.throwUnexpectedToken(messages_1.Messages.TemplateOctalLiteral);
|
|
}
|
|
cooked += '\0';
|
|
}
|
|
else if (character_1.Character.isOctalDigit(ch.charCodeAt(0))) {
|
|
// Illegal: \1 \2
|
|
this.throwUnexpectedToken(messages_1.Messages.TemplateOctalLiteral);
|
|
}
|
|
else {
|
|
cooked += ch;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
else {
|
|
++this.lineNumber;
|
|
if (ch === '\r' && this.source[this.index] === '\n') {
|
|
++this.index;
|
|
}
|
|
this.lineStart = this.index;
|
|
}
|
|
}
|
|
else if (character_1.Character.isLineTerminator(ch.charCodeAt(0))) {
|
|
++this.lineNumber;
|
|
if (ch === '\r' && this.source[this.index] === '\n') {
|
|
++this.index;
|
|
}
|
|
this.lineStart = this.index;
|
|
cooked += '\n';
|
|
}
|
|
else {
|
|
cooked += ch;
|
|
}
|
|
}
|
|
if (!terminated) {
|
|
this.throwUnexpectedToken();
|
|
}
|
|
if (!head) {
|
|
this.curlyStack.pop();
|
|
}
|
|
return {
|
|
type: 10 /* Template */,
|
|
value: this.source.slice(start + 1, this.index - rawOffset),
|
|
cooked: cooked,
|
|
head: head,
|
|
tail: tail,
|
|
lineNumber: this.lineNumber,
|
|
lineStart: this.lineStart,
|
|
start: start,
|
|
end: this.index
|
|
};
|
|
};
|
|
// https://tc39.github.io/ecma262/#sec-literals-regular-expression-literals
|
|
Scanner.prototype.testRegExp = function (pattern, flags) {
|
|
// The BMP character to use as a replacement for astral symbols when
|
|
// translating an ES6 "u"-flagged pattern to an ES5-compatible
|
|
// approximation.
|
|
// Note: replacing with '\uFFFF' enables false positives in unlikely
|
|
// scenarios. For example, `[\u{1044f}-\u{10440}]` is an invalid
|
|
// pattern that would not be detected by this substitution.
|
|
var astralSubstitute = '\uFFFF';
|
|
var tmp = pattern;
|
|
var self = this;
|
|
if (flags.indexOf('u') >= 0) {
|
|
tmp = tmp
|
|
.replace(/\\u\{([0-9a-fA-F]+)\}|\\u([a-fA-F0-9]{4})/g, function ($0, $1, $2) {
|
|
var codePoint = parseInt($1 || $2, 16);
|
|
if (codePoint > 0x10FFFF) {
|
|
self.throwUnexpectedToken(messages_1.Messages.InvalidRegExp);
|
|
}
|
|
if (codePoint <= 0xFFFF) {
|
|
return String.fromCharCode(codePoint);
|
|
}
|
|
return astralSubstitute;
|
|
})
|
|
.replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g, astralSubstitute);
|
|
}
|
|
// First, detect invalid regular expressions.
|
|
try {
|
|
RegExp(tmp);
|
|
}
|
|
catch (e) {
|
|
this.throwUnexpectedToken(messages_1.Messages.InvalidRegExp);
|
|
}
|
|
// Return a regular expression object for this pattern-flag pair, or
|
|
// `null` in case the current environment doesn't support the flags it
|
|
// uses.
|
|
try {
|
|
return new RegExp(pattern, flags);
|
|
}
|
|
catch (exception) {
|
|
/* istanbul ignore next */
|
|
return null;
|
|
}
|
|
};
|
|
Scanner.prototype.scanRegExpBody = function () {
|
|
var ch = this.source[this.index];
|
|
assert_1.assert(ch === '/', 'Regular expression literal must start with a slash');
|
|
var str = this.source[this.index++];
|
|
var classMarker = false;
|
|
var terminated = false;
|
|
while (!this.eof()) {
|
|
ch = this.source[this.index++];
|
|
str += ch;
|
|
if (ch === '\\') {
|
|
ch = this.source[this.index++];
|
|
// https://tc39.github.io/ecma262/#sec-literals-regular-expression-literals
|
|
if (character_1.Character.isLineTerminator(ch.charCodeAt(0))) {
|
|
this.throwUnexpectedToken(messages_1.Messages.UnterminatedRegExp);
|
|
}
|
|
str += ch;
|
|
}
|
|
else if (character_1.Character.isLineTerminator(ch.charCodeAt(0))) {
|
|
this.throwUnexpectedToken(messages_1.Messages.UnterminatedRegExp);
|
|
}
|
|
else if (classMarker) {
|
|
if (ch === ']') {
|
|
classMarker = false;
|
|
}
|
|
}
|
|
else {
|
|
if (ch === '/') {
|
|
terminated = true;
|
|
break;
|
|
}
|
|
else if (ch === '[') {
|
|
classMarker = true;
|
|
}
|
|
}
|
|
}
|
|
if (!terminated) {
|
|
this.throwUnexpectedToken(messages_1.Messages.UnterminatedRegExp);
|
|
}
|
|
// Exclude leading and trailing slash.
|
|
return str.substr(1, str.length - 2);
|
|
};
|
|
Scanner.prototype.scanRegExpFlags = function () {
|
|
var str = '';
|
|
var flags = '';
|
|
while (!this.eof()) {
|
|
var ch = this.source[this.index];
|
|
if (!character_1.Character.isIdentifierPart(ch.charCodeAt(0))) {
|
|
break;
|
|
}
|
|
++this.index;
|
|
if (ch === '\\' && !this.eof()) {
|
|
ch = this.source[this.index];
|
|
if (ch === 'u') {
|
|
++this.index;
|
|
var restore = this.index;
|
|
var char = this.scanHexEscape('u');
|
|
if (char !== null) {
|
|
flags += char;
|
|
for (str += '\\u'; restore < this.index; ++restore) {
|
|
str += this.source[restore];
|
|
}
|
|
}
|
|
else {
|
|
this.index = restore;
|
|
flags += 'u';
|
|
str += '\\u';
|
|
}
|
|
this.tolerateUnexpectedToken();
|
|
}
|
|
else {
|
|
str += '\\';
|
|
this.tolerateUnexpectedToken();
|
|
}
|
|
}
|
|
else {
|
|
flags += ch;
|
|
str += ch;
|
|
}
|
|
}
|
|
return flags;
|
|
};
|
|
Scanner.prototype.scanRegExp = function () {
|
|
var start = this.index;
|
|
var pattern = this.scanRegExpBody();
|
|
var flags = this.scanRegExpFlags();
|
|
var value = this.testRegExp(pattern, flags);
|
|
return {
|
|
type: 9 /* RegularExpression */,
|
|
value: '',
|
|
pattern: pattern,
|
|
flags: flags,
|
|
regex: value,
|
|
lineNumber: this.lineNumber,
|
|
lineStart: this.lineStart,
|
|
start: start,
|
|
end: this.index
|
|
};
|
|
};
|
|
Scanner.prototype.lex = function () {
|
|
if (this.eof()) {
|
|
return {
|
|
type: 2 /* EOF */,
|
|
value: '',
|
|
lineNumber: this.lineNumber,
|
|
lineStart: this.lineStart,
|
|
start: this.index,
|
|
end: this.index
|
|
};
|
|
}
|
|
var cp = this.source.charCodeAt(this.index);
|
|
if (character_1.Character.isIdentifierStart(cp)) {
|
|
return this.scanIdentifier();
|
|
}
|
|
// Very common: ( and ) and ;
|
|
if (cp === 0x28 || cp === 0x29 || cp === 0x3B) {
|
|
return this.scanPunctuator();
|
|
}
|
|
// String literal starts with single quote (U+0027) or double quote (U+0022).
|
|
if (cp === 0x27 || cp === 0x22) {
|
|
return this.scanStringLiteral();
|
|
}
|
|
// Dot (.) U+002E can also start a floating-point number, hence the need
|
|
// to check the next character.
|
|
if (cp === 0x2E) {
|
|
if (character_1.Character.isDecimalDigit(this.source.charCodeAt(this.index + 1))) {
|
|
return this.scanNumericLiteral();
|
|
}
|
|
return this.scanPunctuator();
|
|
}
|
|
if (character_1.Character.isDecimalDigit(cp)) {
|
|
return this.scanNumericLiteral();
|
|
}
|
|
// Template literals start with ` (U+0060) for template head
|
|
// or } (U+007D) for template middle or template tail.
|
|
if (cp === 0x60 || (cp === 0x7D && this.curlyStack[this.curlyStack.length - 1] === '${')) {
|
|
return this.scanTemplate();
|
|
}
|
|
// Possible identifier start in a surrogate pair.
|
|
if (cp >= 0xD800 && cp < 0xDFFF) {
|
|
if (character_1.Character.isIdentifierStart(this.codePointAt(this.index))) {
|
|
return this.scanIdentifier();
|
|
}
|
|
}
|
|
return this.scanPunctuator();
|
|
};
|
|
return Scanner;
|
|
}());
|
|
exports$1.Scanner = Scanner;
|
|
|
|
|
|
/***/ },
|
|
/* 13 */
|
|
/***/ function(module, exports$1) {
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
exports$1.TokenName = {};
|
|
exports$1.TokenName[1 /* BooleanLiteral */] = 'Boolean';
|
|
exports$1.TokenName[2 /* EOF */] = '<end>';
|
|
exports$1.TokenName[3 /* Identifier */] = 'Identifier';
|
|
exports$1.TokenName[4 /* Keyword */] = 'Keyword';
|
|
exports$1.TokenName[5 /* NullLiteral */] = 'Null';
|
|
exports$1.TokenName[6 /* NumericLiteral */] = 'Numeric';
|
|
exports$1.TokenName[7 /* Punctuator */] = 'Punctuator';
|
|
exports$1.TokenName[8 /* StringLiteral */] = 'String';
|
|
exports$1.TokenName[9 /* RegularExpression */] = 'RegularExpression';
|
|
exports$1.TokenName[10 /* Template */] = 'Template';
|
|
|
|
|
|
/***/ },
|
|
/* 14 */
|
|
/***/ function(module, exports$1) {
|
|
// Generated by generate-xhtml-entities.js. DO NOT MODIFY!
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
exports$1.XHTMLEntities = {
|
|
quot: '\u0022',
|
|
amp: '\u0026',
|
|
apos: '\u0027',
|
|
gt: '\u003E',
|
|
nbsp: '\u00A0',
|
|
iexcl: '\u00A1',
|
|
cent: '\u00A2',
|
|
pound: '\u00A3',
|
|
curren: '\u00A4',
|
|
yen: '\u00A5',
|
|
brvbar: '\u00A6',
|
|
sect: '\u00A7',
|
|
uml: '\u00A8',
|
|
copy: '\u00A9',
|
|
ordf: '\u00AA',
|
|
laquo: '\u00AB',
|
|
not: '\u00AC',
|
|
shy: '\u00AD',
|
|
reg: '\u00AE',
|
|
macr: '\u00AF',
|
|
deg: '\u00B0',
|
|
plusmn: '\u00B1',
|
|
sup2: '\u00B2',
|
|
sup3: '\u00B3',
|
|
acute: '\u00B4',
|
|
micro: '\u00B5',
|
|
para: '\u00B6',
|
|
middot: '\u00B7',
|
|
cedil: '\u00B8',
|
|
sup1: '\u00B9',
|
|
ordm: '\u00BA',
|
|
raquo: '\u00BB',
|
|
frac14: '\u00BC',
|
|
frac12: '\u00BD',
|
|
frac34: '\u00BE',
|
|
iquest: '\u00BF',
|
|
Agrave: '\u00C0',
|
|
Aacute: '\u00C1',
|
|
Acirc: '\u00C2',
|
|
Atilde: '\u00C3',
|
|
Auml: '\u00C4',
|
|
Aring: '\u00C5',
|
|
AElig: '\u00C6',
|
|
Ccedil: '\u00C7',
|
|
Egrave: '\u00C8',
|
|
Eacute: '\u00C9',
|
|
Ecirc: '\u00CA',
|
|
Euml: '\u00CB',
|
|
Igrave: '\u00CC',
|
|
Iacute: '\u00CD',
|
|
Icirc: '\u00CE',
|
|
Iuml: '\u00CF',
|
|
ETH: '\u00D0',
|
|
Ntilde: '\u00D1',
|
|
Ograve: '\u00D2',
|
|
Oacute: '\u00D3',
|
|
Ocirc: '\u00D4',
|
|
Otilde: '\u00D5',
|
|
Ouml: '\u00D6',
|
|
times: '\u00D7',
|
|
Oslash: '\u00D8',
|
|
Ugrave: '\u00D9',
|
|
Uacute: '\u00DA',
|
|
Ucirc: '\u00DB',
|
|
Uuml: '\u00DC',
|
|
Yacute: '\u00DD',
|
|
THORN: '\u00DE',
|
|
szlig: '\u00DF',
|
|
agrave: '\u00E0',
|
|
aacute: '\u00E1',
|
|
acirc: '\u00E2',
|
|
atilde: '\u00E3',
|
|
auml: '\u00E4',
|
|
aring: '\u00E5',
|
|
aelig: '\u00E6',
|
|
ccedil: '\u00E7',
|
|
egrave: '\u00E8',
|
|
eacute: '\u00E9',
|
|
ecirc: '\u00EA',
|
|
euml: '\u00EB',
|
|
igrave: '\u00EC',
|
|
iacute: '\u00ED',
|
|
icirc: '\u00EE',
|
|
iuml: '\u00EF',
|
|
eth: '\u00F0',
|
|
ntilde: '\u00F1',
|
|
ograve: '\u00F2',
|
|
oacute: '\u00F3',
|
|
ocirc: '\u00F4',
|
|
otilde: '\u00F5',
|
|
ouml: '\u00F6',
|
|
divide: '\u00F7',
|
|
oslash: '\u00F8',
|
|
ugrave: '\u00F9',
|
|
uacute: '\u00FA',
|
|
ucirc: '\u00FB',
|
|
uuml: '\u00FC',
|
|
yacute: '\u00FD',
|
|
thorn: '\u00FE',
|
|
yuml: '\u00FF',
|
|
OElig: '\u0152',
|
|
oelig: '\u0153',
|
|
Scaron: '\u0160',
|
|
scaron: '\u0161',
|
|
Yuml: '\u0178',
|
|
fnof: '\u0192',
|
|
circ: '\u02C6',
|
|
tilde: '\u02DC',
|
|
Alpha: '\u0391',
|
|
Beta: '\u0392',
|
|
Gamma: '\u0393',
|
|
Delta: '\u0394',
|
|
Epsilon: '\u0395',
|
|
Zeta: '\u0396',
|
|
Eta: '\u0397',
|
|
Theta: '\u0398',
|
|
Iota: '\u0399',
|
|
Kappa: '\u039A',
|
|
Lambda: '\u039B',
|
|
Mu: '\u039C',
|
|
Nu: '\u039D',
|
|
Xi: '\u039E',
|
|
Omicron: '\u039F',
|
|
Pi: '\u03A0',
|
|
Rho: '\u03A1',
|
|
Sigma: '\u03A3',
|
|
Tau: '\u03A4',
|
|
Upsilon: '\u03A5',
|
|
Phi: '\u03A6',
|
|
Chi: '\u03A7',
|
|
Psi: '\u03A8',
|
|
Omega: '\u03A9',
|
|
alpha: '\u03B1',
|
|
beta: '\u03B2',
|
|
gamma: '\u03B3',
|
|
delta: '\u03B4',
|
|
epsilon: '\u03B5',
|
|
zeta: '\u03B6',
|
|
eta: '\u03B7',
|
|
theta: '\u03B8',
|
|
iota: '\u03B9',
|
|
kappa: '\u03BA',
|
|
lambda: '\u03BB',
|
|
mu: '\u03BC',
|
|
nu: '\u03BD',
|
|
xi: '\u03BE',
|
|
omicron: '\u03BF',
|
|
pi: '\u03C0',
|
|
rho: '\u03C1',
|
|
sigmaf: '\u03C2',
|
|
sigma: '\u03C3',
|
|
tau: '\u03C4',
|
|
upsilon: '\u03C5',
|
|
phi: '\u03C6',
|
|
chi: '\u03C7',
|
|
psi: '\u03C8',
|
|
omega: '\u03C9',
|
|
thetasym: '\u03D1',
|
|
upsih: '\u03D2',
|
|
piv: '\u03D6',
|
|
ensp: '\u2002',
|
|
emsp: '\u2003',
|
|
thinsp: '\u2009',
|
|
zwnj: '\u200C',
|
|
zwj: '\u200D',
|
|
lrm: '\u200E',
|
|
rlm: '\u200F',
|
|
ndash: '\u2013',
|
|
mdash: '\u2014',
|
|
lsquo: '\u2018',
|
|
rsquo: '\u2019',
|
|
sbquo: '\u201A',
|
|
ldquo: '\u201C',
|
|
rdquo: '\u201D',
|
|
bdquo: '\u201E',
|
|
dagger: '\u2020',
|
|
Dagger: '\u2021',
|
|
bull: '\u2022',
|
|
hellip: '\u2026',
|
|
permil: '\u2030',
|
|
prime: '\u2032',
|
|
Prime: '\u2033',
|
|
lsaquo: '\u2039',
|
|
rsaquo: '\u203A',
|
|
oline: '\u203E',
|
|
frasl: '\u2044',
|
|
euro: '\u20AC',
|
|
image: '\u2111',
|
|
weierp: '\u2118',
|
|
real: '\u211C',
|
|
trade: '\u2122',
|
|
alefsym: '\u2135',
|
|
larr: '\u2190',
|
|
uarr: '\u2191',
|
|
rarr: '\u2192',
|
|
darr: '\u2193',
|
|
harr: '\u2194',
|
|
crarr: '\u21B5',
|
|
lArr: '\u21D0',
|
|
uArr: '\u21D1',
|
|
rArr: '\u21D2',
|
|
dArr: '\u21D3',
|
|
hArr: '\u21D4',
|
|
forall: '\u2200',
|
|
part: '\u2202',
|
|
exist: '\u2203',
|
|
empty: '\u2205',
|
|
nabla: '\u2207',
|
|
isin: '\u2208',
|
|
notin: '\u2209',
|
|
ni: '\u220B',
|
|
prod: '\u220F',
|
|
sum: '\u2211',
|
|
minus: '\u2212',
|
|
lowast: '\u2217',
|
|
radic: '\u221A',
|
|
prop: '\u221D',
|
|
infin: '\u221E',
|
|
ang: '\u2220',
|
|
and: '\u2227',
|
|
or: '\u2228',
|
|
cap: '\u2229',
|
|
cup: '\u222A',
|
|
int: '\u222B',
|
|
there4: '\u2234',
|
|
sim: '\u223C',
|
|
cong: '\u2245',
|
|
asymp: '\u2248',
|
|
ne: '\u2260',
|
|
equiv: '\u2261',
|
|
le: '\u2264',
|
|
ge: '\u2265',
|
|
sub: '\u2282',
|
|
sup: '\u2283',
|
|
nsub: '\u2284',
|
|
sube: '\u2286',
|
|
supe: '\u2287',
|
|
oplus: '\u2295',
|
|
otimes: '\u2297',
|
|
perp: '\u22A5',
|
|
sdot: '\u22C5',
|
|
lceil: '\u2308',
|
|
rceil: '\u2309',
|
|
lfloor: '\u230A',
|
|
rfloor: '\u230B',
|
|
loz: '\u25CA',
|
|
spades: '\u2660',
|
|
clubs: '\u2663',
|
|
hearts: '\u2665',
|
|
diams: '\u2666',
|
|
lang: '\u27E8',
|
|
rang: '\u27E9'
|
|
};
|
|
|
|
|
|
/***/ },
|
|
/* 15 */
|
|
/***/ function(module, exports$1, __webpack_require__) {
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
var error_handler_1 = __webpack_require__(10);
|
|
var scanner_1 = __webpack_require__(12);
|
|
var token_1 = __webpack_require__(13);
|
|
var Reader = (function () {
|
|
function Reader() {
|
|
this.values = [];
|
|
this.curly = this.paren = -1;
|
|
}
|
|
// A function following one of those tokens is an expression.
|
|
Reader.prototype.beforeFunctionExpression = function (t) {
|
|
return ['(', '{', '[', 'in', 'typeof', 'instanceof', 'new',
|
|
'return', 'case', 'delete', 'throw', 'void',
|
|
// assignment operators
|
|
'=', '+=', '-=', '*=', '**=', '/=', '%=', '<<=', '>>=', '>>>=',
|
|
'&=', '|=', '^=', ',',
|
|
// binary/unary operators
|
|
'+', '-', '*', '**', '/', '%', '++', '--', '<<', '>>', '>>>', '&',
|
|
'|', '^', '!', '~', '&&', '||', '?', ':', '===', '==', '>=',
|
|
'<=', '<', '>', '!=', '!=='].indexOf(t) >= 0;
|
|
};
|
|
// Determine if forward slash (/) is an operator or part of a regular expression
|
|
// https://github.com/mozilla/sweet.js/wiki/design
|
|
Reader.prototype.isRegexStart = function () {
|
|
var previous = this.values[this.values.length - 1];
|
|
var regex = (previous !== null);
|
|
switch (previous) {
|
|
case 'this':
|
|
case ']':
|
|
regex = false;
|
|
break;
|
|
case ')':
|
|
var keyword = this.values[this.paren - 1];
|
|
regex = (keyword === 'if' || keyword === 'while' || keyword === 'for' || keyword === 'with');
|
|
break;
|
|
case '}':
|
|
// Dividing a function by anything makes little sense,
|
|
// but we have to check for that.
|
|
regex = false;
|
|
if (this.values[this.curly - 3] === 'function') {
|
|
// Anonymous function, e.g. function(){} /42
|
|
var check = this.values[this.curly - 4];
|
|
regex = check ? !this.beforeFunctionExpression(check) : false;
|
|
}
|
|
else if (this.values[this.curly - 4] === 'function') {
|
|
// Named function, e.g. function f(){} /42/
|
|
var check = this.values[this.curly - 5];
|
|
regex = check ? !this.beforeFunctionExpression(check) : true;
|
|
}
|
|
break;
|
|
}
|
|
return regex;
|
|
};
|
|
Reader.prototype.push = function (token) {
|
|
if (token.type === 7 /* Punctuator */ || token.type === 4 /* Keyword */) {
|
|
if (token.value === '{') {
|
|
this.curly = this.values.length;
|
|
}
|
|
else if (token.value === '(') {
|
|
this.paren = this.values.length;
|
|
}
|
|
this.values.push(token.value);
|
|
}
|
|
else {
|
|
this.values.push(null);
|
|
}
|
|
};
|
|
return Reader;
|
|
}());
|
|
var Tokenizer = (function () {
|
|
function Tokenizer(code, config) {
|
|
this.errorHandler = new error_handler_1.ErrorHandler();
|
|
this.errorHandler.tolerant = config ? (typeof config.tolerant === 'boolean' && config.tolerant) : false;
|
|
this.scanner = new scanner_1.Scanner(code, this.errorHandler);
|
|
this.scanner.trackComment = config ? (typeof config.comment === 'boolean' && config.comment) : false;
|
|
this.trackRange = config ? (typeof config.range === 'boolean' && config.range) : false;
|
|
this.trackLoc = config ? (typeof config.loc === 'boolean' && config.loc) : false;
|
|
this.buffer = [];
|
|
this.reader = new Reader();
|
|
}
|
|
Tokenizer.prototype.errors = function () {
|
|
return this.errorHandler.errors;
|
|
};
|
|
Tokenizer.prototype.getNextToken = function () {
|
|
if (this.buffer.length === 0) {
|
|
var comments = this.scanner.scanComments();
|
|
if (this.scanner.trackComment) {
|
|
for (var i = 0; i < comments.length; ++i) {
|
|
var e = comments[i];
|
|
var value = this.scanner.source.slice(e.slice[0], e.slice[1]);
|
|
var comment = {
|
|
type: e.multiLine ? 'BlockComment' : 'LineComment',
|
|
value: value
|
|
};
|
|
if (this.trackRange) {
|
|
comment.range = e.range;
|
|
}
|
|
if (this.trackLoc) {
|
|
comment.loc = e.loc;
|
|
}
|
|
this.buffer.push(comment);
|
|
}
|
|
}
|
|
if (!this.scanner.eof()) {
|
|
var loc = void 0;
|
|
if (this.trackLoc) {
|
|
loc = {
|
|
start: {
|
|
line: this.scanner.lineNumber,
|
|
column: this.scanner.index - this.scanner.lineStart
|
|
},
|
|
end: {}
|
|
};
|
|
}
|
|
var startRegex = (this.scanner.source[this.scanner.index] === '/') && this.reader.isRegexStart();
|
|
var token = startRegex ? this.scanner.scanRegExp() : this.scanner.lex();
|
|
this.reader.push(token);
|
|
var entry = {
|
|
type: token_1.TokenName[token.type],
|
|
value: this.scanner.source.slice(token.start, token.end)
|
|
};
|
|
if (this.trackRange) {
|
|
entry.range = [token.start, token.end];
|
|
}
|
|
if (this.trackLoc) {
|
|
loc.end = {
|
|
line: this.scanner.lineNumber,
|
|
column: this.scanner.index - this.scanner.lineStart
|
|
};
|
|
entry.loc = loc;
|
|
}
|
|
if (token.type === 9 /* RegularExpression */) {
|
|
var pattern = token.pattern;
|
|
var flags = token.flags;
|
|
entry.regex = { pattern: pattern, flags: flags };
|
|
}
|
|
this.buffer.push(entry);
|
|
}
|
|
}
|
|
return this.buffer.shift();
|
|
};
|
|
return Tokenizer;
|
|
}());
|
|
exports$1.Tokenizer = Tokenizer;
|
|
|
|
|
|
/***/ }
|
|
/******/ ])
|
|
});
|
|
} (esprima$1));
|
|
return esprima$1.exports;
|
|
}
|
|
|
|
var hasRequiredEsprima;
|
|
|
|
function requireEsprima () {
|
|
if (hasRequiredEsprima) return esprima$2;
|
|
hasRequiredEsprima = 1;
|
|
Object.defineProperty(esprima$2, "__esModule", { value: true });
|
|
esprima$2.parse = void 0;
|
|
// This module is suitable for passing as options.parser when calling
|
|
// recast.parse to process ECMAScript code with Esprima:
|
|
//
|
|
// const ast = recast.parse(source, {
|
|
// parser: require("recast/parsers/esprima")
|
|
// });
|
|
//
|
|
var util_1 = requireUtil();
|
|
function parse(source, options) {
|
|
var comments = [];
|
|
var ast = requireEsprima$1().parse(source, {
|
|
loc: true,
|
|
locations: true,
|
|
comment: true,
|
|
onComment: comments,
|
|
range: (0, util_1.getOption)(options, "range", false),
|
|
tolerant: (0, util_1.getOption)(options, "tolerant", true),
|
|
tokens: true,
|
|
jsx: (0, util_1.getOption)(options, "jsx", false),
|
|
sourceType: (0, util_1.getOption)(options, "sourceType", "module"),
|
|
});
|
|
if (!Array.isArray(ast.comments)) {
|
|
ast.comments = comments;
|
|
}
|
|
return ast;
|
|
}
|
|
esprima$2.parse = parse;
|
|
return esprima$2;
|
|
}
|
|
|
|
var hasRequiredOptions;
|
|
|
|
function requireOptions () {
|
|
if (hasRequiredOptions) return options;
|
|
hasRequiredOptions = 1;
|
|
Object.defineProperty(options, "__esModule", { value: true });
|
|
options.normalize = void 0;
|
|
var util_1 = requireUtil();
|
|
var defaults = {
|
|
parser: requireEsprima(),
|
|
tabWidth: 4,
|
|
useTabs: false,
|
|
reuseWhitespace: true,
|
|
lineTerminator: (0, util_1.getLineTerminator)(),
|
|
wrapColumn: 74,
|
|
sourceFileName: null,
|
|
sourceMapName: null,
|
|
sourceRoot: null,
|
|
inputSourceMap: null,
|
|
range: false,
|
|
tolerant: true,
|
|
quote: null,
|
|
trailingComma: false,
|
|
arrayBracketSpacing: false,
|
|
objectCurlySpacing: true,
|
|
arrowParensAlways: false,
|
|
flowObjectCommas: true,
|
|
tokens: true,
|
|
};
|
|
var hasOwn = defaults.hasOwnProperty;
|
|
// Copy options and fill in default values.
|
|
function normalize(opts) {
|
|
var options = opts || defaults;
|
|
function get(key) {
|
|
return hasOwn.call(options, key) ? options[key] : defaults[key];
|
|
}
|
|
return {
|
|
tabWidth: +get("tabWidth"),
|
|
useTabs: !!get("useTabs"),
|
|
reuseWhitespace: !!get("reuseWhitespace"),
|
|
lineTerminator: get("lineTerminator"),
|
|
wrapColumn: Math.max(get("wrapColumn"), 0),
|
|
sourceFileName: get("sourceFileName"),
|
|
sourceMapName: get("sourceMapName"),
|
|
sourceRoot: get("sourceRoot"),
|
|
inputSourceMap: get("inputSourceMap"),
|
|
parser: get("esprima") || get("parser"),
|
|
range: get("range"),
|
|
tolerant: get("tolerant"),
|
|
quote: get("quote"),
|
|
trailingComma: get("trailingComma"),
|
|
arrayBracketSpacing: get("arrayBracketSpacing"),
|
|
objectCurlySpacing: get("objectCurlySpacing"),
|
|
arrowParensAlways: get("arrowParensAlways"),
|
|
flowObjectCommas: get("flowObjectCommas"),
|
|
tokens: !!get("tokens"),
|
|
};
|
|
}
|
|
options.normalize = normalize;
|
|
return options;
|
|
}
|
|
|
|
var lines = {};
|
|
|
|
var mapping = {};
|
|
|
|
var hasRequiredMapping;
|
|
|
|
function requireMapping () {
|
|
if (hasRequiredMapping) return mapping;
|
|
hasRequiredMapping = 1;
|
|
Object.defineProperty(mapping, "__esModule", { value: true });
|
|
var tslib_1 = require$$0;
|
|
var tiny_invariant_1 = tslib_1.__importDefault(/*@__PURE__*/ requireTinyInvariant_cjs());
|
|
var util_1 = requireUtil();
|
|
var Mapping = /** @class */ (function () {
|
|
function Mapping(sourceLines, sourceLoc, targetLoc) {
|
|
if (targetLoc === void 0) { targetLoc = sourceLoc; }
|
|
this.sourceLines = sourceLines;
|
|
this.sourceLoc = sourceLoc;
|
|
this.targetLoc = targetLoc;
|
|
}
|
|
Mapping.prototype.slice = function (lines, start, end) {
|
|
if (end === void 0) { end = lines.lastPos(); }
|
|
var sourceLines = this.sourceLines;
|
|
var sourceLoc = this.sourceLoc;
|
|
var targetLoc = this.targetLoc;
|
|
function skip(name) {
|
|
var sourceFromPos = sourceLoc[name];
|
|
var targetFromPos = targetLoc[name];
|
|
var targetToPos = start;
|
|
if (name === "end") {
|
|
targetToPos = end;
|
|
}
|
|
else {
|
|
(0, tiny_invariant_1.default)(name === "start");
|
|
}
|
|
return skipChars(sourceLines, sourceFromPos, lines, targetFromPos, targetToPos);
|
|
}
|
|
if ((0, util_1.comparePos)(start, targetLoc.start) <= 0) {
|
|
if ((0, util_1.comparePos)(targetLoc.end, end) <= 0) {
|
|
targetLoc = {
|
|
start: subtractPos(targetLoc.start, start.line, start.column),
|
|
end: subtractPos(targetLoc.end, start.line, start.column),
|
|
};
|
|
// The sourceLoc can stay the same because the contents of the
|
|
// targetLoc have not changed.
|
|
}
|
|
else if ((0, util_1.comparePos)(end, targetLoc.start) <= 0) {
|
|
return null;
|
|
}
|
|
else {
|
|
sourceLoc = {
|
|
start: sourceLoc.start,
|
|
end: skip("end"),
|
|
};
|
|
targetLoc = {
|
|
start: subtractPos(targetLoc.start, start.line, start.column),
|
|
end: subtractPos(end, start.line, start.column),
|
|
};
|
|
}
|
|
}
|
|
else {
|
|
if ((0, util_1.comparePos)(targetLoc.end, start) <= 0) {
|
|
return null;
|
|
}
|
|
if ((0, util_1.comparePos)(targetLoc.end, end) <= 0) {
|
|
sourceLoc = {
|
|
start: skip("start"),
|
|
end: sourceLoc.end,
|
|
};
|
|
targetLoc = {
|
|
// Same as subtractPos(start, start.line, start.column):
|
|
start: { line: 1, column: 0 },
|
|
end: subtractPos(targetLoc.end, start.line, start.column),
|
|
};
|
|
}
|
|
else {
|
|
sourceLoc = {
|
|
start: skip("start"),
|
|
end: skip("end"),
|
|
};
|
|
targetLoc = {
|
|
// Same as subtractPos(start, start.line, start.column):
|
|
start: { line: 1, column: 0 },
|
|
end: subtractPos(end, start.line, start.column),
|
|
};
|
|
}
|
|
}
|
|
return new Mapping(this.sourceLines, sourceLoc, targetLoc);
|
|
};
|
|
Mapping.prototype.add = function (line, column) {
|
|
return new Mapping(this.sourceLines, this.sourceLoc, {
|
|
start: addPos(this.targetLoc.start, line, column),
|
|
end: addPos(this.targetLoc.end, line, column),
|
|
});
|
|
};
|
|
Mapping.prototype.subtract = function (line, column) {
|
|
return new Mapping(this.sourceLines, this.sourceLoc, {
|
|
start: subtractPos(this.targetLoc.start, line, column),
|
|
end: subtractPos(this.targetLoc.end, line, column),
|
|
});
|
|
};
|
|
Mapping.prototype.indent = function (by, skipFirstLine, noNegativeColumns) {
|
|
if (skipFirstLine === void 0) { skipFirstLine = false; }
|
|
if (noNegativeColumns === void 0) { noNegativeColumns = false; }
|
|
if (by === 0) {
|
|
return this;
|
|
}
|
|
var targetLoc = this.targetLoc;
|
|
var startLine = targetLoc.start.line;
|
|
var endLine = targetLoc.end.line;
|
|
if (skipFirstLine && startLine === 1 && endLine === 1) {
|
|
return this;
|
|
}
|
|
targetLoc = {
|
|
start: targetLoc.start,
|
|
end: targetLoc.end,
|
|
};
|
|
if (!skipFirstLine || startLine > 1) {
|
|
var startColumn = targetLoc.start.column + by;
|
|
targetLoc.start = {
|
|
line: startLine,
|
|
column: noNegativeColumns ? Math.max(0, startColumn) : startColumn,
|
|
};
|
|
}
|
|
if (!skipFirstLine || endLine > 1) {
|
|
var endColumn = targetLoc.end.column + by;
|
|
targetLoc.end = {
|
|
line: endLine,
|
|
column: noNegativeColumns ? Math.max(0, endColumn) : endColumn,
|
|
};
|
|
}
|
|
return new Mapping(this.sourceLines, this.sourceLoc, targetLoc);
|
|
};
|
|
return Mapping;
|
|
}());
|
|
mapping.default = Mapping;
|
|
function addPos(toPos, line, column) {
|
|
return {
|
|
line: toPos.line + line - 1,
|
|
column: toPos.line === 1 ? toPos.column + column : toPos.column,
|
|
};
|
|
}
|
|
function subtractPos(fromPos, line, column) {
|
|
return {
|
|
line: fromPos.line - line + 1,
|
|
column: fromPos.line === line ? fromPos.column - column : fromPos.column,
|
|
};
|
|
}
|
|
function skipChars(sourceLines, sourceFromPos, targetLines, targetFromPos, targetToPos) {
|
|
var targetComparison = (0, util_1.comparePos)(targetFromPos, targetToPos);
|
|
if (targetComparison === 0) {
|
|
// Trivial case: no characters to skip.
|
|
return sourceFromPos;
|
|
}
|
|
var sourceCursor, targetCursor;
|
|
if (targetComparison < 0) {
|
|
// Skipping forward.
|
|
sourceCursor =
|
|
sourceLines.skipSpaces(sourceFromPos) || sourceLines.lastPos();
|
|
targetCursor =
|
|
targetLines.skipSpaces(targetFromPos) || targetLines.lastPos();
|
|
var lineDiff = targetToPos.line - targetCursor.line;
|
|
sourceCursor.line += lineDiff;
|
|
targetCursor.line += lineDiff;
|
|
if (lineDiff > 0) {
|
|
// If jumping to later lines, reset columns to the beginnings
|
|
// of those lines.
|
|
sourceCursor.column = 0;
|
|
targetCursor.column = 0;
|
|
}
|
|
else {
|
|
(0, tiny_invariant_1.default)(lineDiff === 0);
|
|
}
|
|
while ((0, util_1.comparePos)(targetCursor, targetToPos) < 0 &&
|
|
targetLines.nextPos(targetCursor, true)) {
|
|
(0, tiny_invariant_1.default)(sourceLines.nextPos(sourceCursor, true));
|
|
(0, tiny_invariant_1.default)(sourceLines.charAt(sourceCursor) === targetLines.charAt(targetCursor));
|
|
}
|
|
}
|
|
else {
|
|
// Skipping backward.
|
|
sourceCursor =
|
|
sourceLines.skipSpaces(sourceFromPos, true) || sourceLines.firstPos();
|
|
targetCursor =
|
|
targetLines.skipSpaces(targetFromPos, true) || targetLines.firstPos();
|
|
var lineDiff = targetToPos.line - targetCursor.line;
|
|
sourceCursor.line += lineDiff;
|
|
targetCursor.line += lineDiff;
|
|
if (lineDiff < 0) {
|
|
// If jumping to earlier lines, reset columns to the ends of
|
|
// those lines.
|
|
sourceCursor.column = sourceLines.getLineLength(sourceCursor.line);
|
|
targetCursor.column = targetLines.getLineLength(targetCursor.line);
|
|
}
|
|
else {
|
|
(0, tiny_invariant_1.default)(lineDiff === 0);
|
|
}
|
|
while ((0, util_1.comparePos)(targetToPos, targetCursor) < 0 &&
|
|
targetLines.prevPos(targetCursor, true)) {
|
|
(0, tiny_invariant_1.default)(sourceLines.prevPos(sourceCursor, true));
|
|
(0, tiny_invariant_1.default)(sourceLines.charAt(sourceCursor) === targetLines.charAt(targetCursor));
|
|
}
|
|
}
|
|
return sourceCursor;
|
|
}
|
|
return mapping;
|
|
}
|
|
|
|
var hasRequiredLines;
|
|
|
|
function requireLines () {
|
|
if (hasRequiredLines) return lines;
|
|
hasRequiredLines = 1;
|
|
Object.defineProperty(lines, "__esModule", { value: true });
|
|
lines.concat = lines.fromString = lines.countSpaces = lines.Lines = void 0;
|
|
var tslib_1 = require$$0;
|
|
var tiny_invariant_1 = tslib_1.__importDefault(/*@__PURE__*/ requireTinyInvariant_cjs());
|
|
var source_map_1 = tslib_1.__importDefault(requireSourceMap());
|
|
var options_1 = requireOptions();
|
|
var util_1 = requireUtil();
|
|
var mapping_1 = tslib_1.__importDefault(requireMapping());
|
|
var Lines = /** @class */ (function () {
|
|
function Lines(infos, sourceFileName) {
|
|
if (sourceFileName === void 0) { sourceFileName = null; }
|
|
this.infos = infos;
|
|
this.mappings = [];
|
|
this.cachedSourceMap = null;
|
|
this.cachedTabWidth = void 0;
|
|
(0, tiny_invariant_1.default)(infos.length > 0);
|
|
this.length = infos.length;
|
|
this.name = sourceFileName || null;
|
|
if (this.name) {
|
|
this.mappings.push(new mapping_1.default(this, {
|
|
start: this.firstPos(),
|
|
end: this.lastPos(),
|
|
}));
|
|
}
|
|
}
|
|
Lines.prototype.toString = function (options) {
|
|
return this.sliceString(this.firstPos(), this.lastPos(), options);
|
|
};
|
|
Lines.prototype.getSourceMap = function (sourceMapName, sourceRoot) {
|
|
if (!sourceMapName) {
|
|
// Although we could make up a name or generate an anonymous
|
|
// source map, instead we assume that any consumer who does not
|
|
// provide a name does not actually want a source map.
|
|
return null;
|
|
}
|
|
var targetLines = this;
|
|
function updateJSON(json) {
|
|
json = json || {};
|
|
json.file = sourceMapName;
|
|
if (sourceRoot) {
|
|
json.sourceRoot = sourceRoot;
|
|
}
|
|
return json;
|
|
}
|
|
if (targetLines.cachedSourceMap) {
|
|
// Since Lines objects are immutable, we can reuse any source map
|
|
// that was previously generated. Nevertheless, we return a new
|
|
// JSON object here to protect the cached source map from outside
|
|
// modification.
|
|
return updateJSON(targetLines.cachedSourceMap.toJSON());
|
|
}
|
|
var smg = new source_map_1.default.SourceMapGenerator(updateJSON());
|
|
var sourcesToContents = {};
|
|
targetLines.mappings.forEach(function (mapping) {
|
|
var sourceCursor = mapping.sourceLines.skipSpaces(mapping.sourceLoc.start) ||
|
|
mapping.sourceLines.lastPos();
|
|
var targetCursor = targetLines.skipSpaces(mapping.targetLoc.start) ||
|
|
targetLines.lastPos();
|
|
while ((0, util_1.comparePos)(sourceCursor, mapping.sourceLoc.end) < 0 &&
|
|
(0, util_1.comparePos)(targetCursor, mapping.targetLoc.end) < 0) {
|
|
var sourceChar = mapping.sourceLines.charAt(sourceCursor);
|
|
var targetChar = targetLines.charAt(targetCursor);
|
|
(0, tiny_invariant_1.default)(sourceChar === targetChar);
|
|
var sourceName = mapping.sourceLines.name;
|
|
// Add mappings one character at a time for maximum resolution.
|
|
smg.addMapping({
|
|
source: sourceName,
|
|
original: { line: sourceCursor.line, column: sourceCursor.column },
|
|
generated: { line: targetCursor.line, column: targetCursor.column },
|
|
});
|
|
if (!hasOwn.call(sourcesToContents, sourceName)) {
|
|
var sourceContent = mapping.sourceLines.toString();
|
|
smg.setSourceContent(sourceName, sourceContent);
|
|
sourcesToContents[sourceName] = sourceContent;
|
|
}
|
|
targetLines.nextPos(targetCursor, true);
|
|
mapping.sourceLines.nextPos(sourceCursor, true);
|
|
}
|
|
});
|
|
targetLines.cachedSourceMap = smg;
|
|
return smg.toJSON();
|
|
};
|
|
Lines.prototype.bootstrapCharAt = function (pos) {
|
|
(0, tiny_invariant_1.default)(typeof pos === "object");
|
|
(0, tiny_invariant_1.default)(typeof pos.line === "number");
|
|
(0, tiny_invariant_1.default)(typeof pos.column === "number");
|
|
var line = pos.line, column = pos.column, strings = this.toString().split(lineTerminatorSeqExp), string = strings[line - 1];
|
|
if (typeof string === "undefined")
|
|
return "";
|
|
if (column === string.length && line < strings.length)
|
|
return "\n";
|
|
if (column >= string.length)
|
|
return "";
|
|
return string.charAt(column);
|
|
};
|
|
Lines.prototype.charAt = function (pos) {
|
|
(0, tiny_invariant_1.default)(typeof pos === "object");
|
|
(0, tiny_invariant_1.default)(typeof pos.line === "number");
|
|
(0, tiny_invariant_1.default)(typeof pos.column === "number");
|
|
var line = pos.line, column = pos.column, secret = this, infos = secret.infos, info = infos[line - 1], c = column;
|
|
if (typeof info === "undefined" || c < 0)
|
|
return "";
|
|
var indent = this.getIndentAt(line);
|
|
if (c < indent)
|
|
return " ";
|
|
c += info.sliceStart - indent;
|
|
if (c === info.sliceEnd && line < this.length)
|
|
return "\n";
|
|
if (c >= info.sliceEnd)
|
|
return "";
|
|
return info.line.charAt(c);
|
|
};
|
|
Lines.prototype.stripMargin = function (width, skipFirstLine) {
|
|
if (width === 0)
|
|
return this;
|
|
(0, tiny_invariant_1.default)(width > 0, "negative margin: " + width);
|
|
if (skipFirstLine && this.length === 1)
|
|
return this;
|
|
var lines = new Lines(this.infos.map(function (info, i) {
|
|
if (info.line && (i > 0 || !skipFirstLine)) {
|
|
info = tslib_1.__assign(tslib_1.__assign({}, info), { indent: Math.max(0, info.indent - width) });
|
|
}
|
|
return info;
|
|
}));
|
|
if (this.mappings.length > 0) {
|
|
var newMappings_1 = lines.mappings;
|
|
(0, tiny_invariant_1.default)(newMappings_1.length === 0);
|
|
this.mappings.forEach(function (mapping) {
|
|
newMappings_1.push(mapping.indent(width, skipFirstLine, true));
|
|
});
|
|
}
|
|
return lines;
|
|
};
|
|
Lines.prototype.indent = function (by) {
|
|
if (by === 0) {
|
|
return this;
|
|
}
|
|
var lines = new Lines(this.infos.map(function (info) {
|
|
if (info.line && !info.locked) {
|
|
info = tslib_1.__assign(tslib_1.__assign({}, info), { indent: info.indent + by });
|
|
}
|
|
return info;
|
|
}));
|
|
if (this.mappings.length > 0) {
|
|
var newMappings_2 = lines.mappings;
|
|
(0, tiny_invariant_1.default)(newMappings_2.length === 0);
|
|
this.mappings.forEach(function (mapping) {
|
|
newMappings_2.push(mapping.indent(by));
|
|
});
|
|
}
|
|
return lines;
|
|
};
|
|
Lines.prototype.indentTail = function (by) {
|
|
if (by === 0) {
|
|
return this;
|
|
}
|
|
if (this.length < 2) {
|
|
return this;
|
|
}
|
|
var lines = new Lines(this.infos.map(function (info, i) {
|
|
if (i > 0 && info.line && !info.locked) {
|
|
info = tslib_1.__assign(tslib_1.__assign({}, info), { indent: info.indent + by });
|
|
}
|
|
return info;
|
|
}));
|
|
if (this.mappings.length > 0) {
|
|
var newMappings_3 = lines.mappings;
|
|
(0, tiny_invariant_1.default)(newMappings_3.length === 0);
|
|
this.mappings.forEach(function (mapping) {
|
|
newMappings_3.push(mapping.indent(by, true));
|
|
});
|
|
}
|
|
return lines;
|
|
};
|
|
Lines.prototype.lockIndentTail = function () {
|
|
if (this.length < 2) {
|
|
return this;
|
|
}
|
|
return new Lines(this.infos.map(function (info, i) { return (tslib_1.__assign(tslib_1.__assign({}, info), { locked: i > 0 })); }));
|
|
};
|
|
Lines.prototype.getIndentAt = function (line) {
|
|
(0, tiny_invariant_1.default)(line >= 1, "no line " + line + " (line numbers start from 1)");
|
|
return Math.max(this.infos[line - 1].indent, 0);
|
|
};
|
|
Lines.prototype.guessTabWidth = function () {
|
|
if (typeof this.cachedTabWidth === "number") {
|
|
return this.cachedTabWidth;
|
|
}
|
|
var counts = []; // Sparse array.
|
|
var lastIndent = 0;
|
|
for (var line = 1, last = this.length; line <= last; ++line) {
|
|
var info = this.infos[line - 1];
|
|
var sliced = info.line.slice(info.sliceStart, info.sliceEnd);
|
|
// Whitespace-only lines don't tell us much about the likely tab
|
|
// width of this code.
|
|
if (isOnlyWhitespace(sliced)) {
|
|
continue;
|
|
}
|
|
var diff = Math.abs(info.indent - lastIndent);
|
|
counts[diff] = ~~counts[diff] + 1;
|
|
lastIndent = info.indent;
|
|
}
|
|
var maxCount = -1;
|
|
var result = 2;
|
|
for (var tabWidth = 1; tabWidth < counts.length; tabWidth += 1) {
|
|
if (hasOwn.call(counts, tabWidth) && counts[tabWidth] > maxCount) {
|
|
maxCount = counts[tabWidth];
|
|
result = tabWidth;
|
|
}
|
|
}
|
|
return (this.cachedTabWidth = result);
|
|
};
|
|
// Determine if the list of lines has a first line that starts with a //
|
|
// or /* comment. If this is the case, the code may need to be wrapped in
|
|
// parens to avoid ASI issues.
|
|
Lines.prototype.startsWithComment = function () {
|
|
if (this.infos.length === 0) {
|
|
return false;
|
|
}
|
|
var firstLineInfo = this.infos[0], sliceStart = firstLineInfo.sliceStart, sliceEnd = firstLineInfo.sliceEnd, firstLine = firstLineInfo.line.slice(sliceStart, sliceEnd).trim();
|
|
return (firstLine.length === 0 ||
|
|
firstLine.slice(0, 2) === "//" ||
|
|
firstLine.slice(0, 2) === "/*");
|
|
};
|
|
Lines.prototype.isOnlyWhitespace = function () {
|
|
return isOnlyWhitespace(this.toString());
|
|
};
|
|
Lines.prototype.isPrecededOnlyByWhitespace = function (pos) {
|
|
var info = this.infos[pos.line - 1];
|
|
var indent = Math.max(info.indent, 0);
|
|
var diff = pos.column - indent;
|
|
if (diff <= 0) {
|
|
// If pos.column does not exceed the indentation amount, then
|
|
// there must be only whitespace before it.
|
|
return true;
|
|
}
|
|
var start = info.sliceStart;
|
|
var end = Math.min(start + diff, info.sliceEnd);
|
|
var prefix = info.line.slice(start, end);
|
|
return isOnlyWhitespace(prefix);
|
|
};
|
|
Lines.prototype.getLineLength = function (line) {
|
|
var info = this.infos[line - 1];
|
|
return this.getIndentAt(line) + info.sliceEnd - info.sliceStart;
|
|
};
|
|
Lines.prototype.nextPos = function (pos, skipSpaces) {
|
|
if (skipSpaces === void 0) { skipSpaces = false; }
|
|
var l = Math.max(pos.line, 0), c = Math.max(pos.column, 0);
|
|
if (c < this.getLineLength(l)) {
|
|
pos.column += 1;
|
|
return skipSpaces ? !!this.skipSpaces(pos, false, true) : true;
|
|
}
|
|
if (l < this.length) {
|
|
pos.line += 1;
|
|
pos.column = 0;
|
|
return skipSpaces ? !!this.skipSpaces(pos, false, true) : true;
|
|
}
|
|
return false;
|
|
};
|
|
Lines.prototype.prevPos = function (pos, skipSpaces) {
|
|
if (skipSpaces === void 0) { skipSpaces = false; }
|
|
var l = pos.line, c = pos.column;
|
|
if (c < 1) {
|
|
l -= 1;
|
|
if (l < 1)
|
|
return false;
|
|
c = this.getLineLength(l);
|
|
}
|
|
else {
|
|
c = Math.min(c - 1, this.getLineLength(l));
|
|
}
|
|
pos.line = l;
|
|
pos.column = c;
|
|
return skipSpaces ? !!this.skipSpaces(pos, true, true) : true;
|
|
};
|
|
Lines.prototype.firstPos = function () {
|
|
// Trivial, but provided for completeness.
|
|
return { line: 1, column: 0 };
|
|
};
|
|
Lines.prototype.lastPos = function () {
|
|
return {
|
|
line: this.length,
|
|
column: this.getLineLength(this.length),
|
|
};
|
|
};
|
|
Lines.prototype.skipSpaces = function (pos, backward, modifyInPlace) {
|
|
if (backward === void 0) { backward = false; }
|
|
if (modifyInPlace === void 0) { modifyInPlace = false; }
|
|
if (pos) {
|
|
pos = modifyInPlace
|
|
? pos
|
|
: {
|
|
line: pos.line,
|
|
column: pos.column,
|
|
};
|
|
}
|
|
else if (backward) {
|
|
pos = this.lastPos();
|
|
}
|
|
else {
|
|
pos = this.firstPos();
|
|
}
|
|
if (backward) {
|
|
while (this.prevPos(pos)) {
|
|
if (!isOnlyWhitespace(this.charAt(pos)) && this.nextPos(pos)) {
|
|
return pos;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
else {
|
|
while (isOnlyWhitespace(this.charAt(pos))) {
|
|
if (!this.nextPos(pos)) {
|
|
return null;
|
|
}
|
|
}
|
|
return pos;
|
|
}
|
|
};
|
|
Lines.prototype.trimLeft = function () {
|
|
var pos = this.skipSpaces(this.firstPos(), false, true);
|
|
return pos ? this.slice(pos) : emptyLines;
|
|
};
|
|
Lines.prototype.trimRight = function () {
|
|
var pos = this.skipSpaces(this.lastPos(), true, true);
|
|
return pos ? this.slice(this.firstPos(), pos) : emptyLines;
|
|
};
|
|
Lines.prototype.trim = function () {
|
|
var start = this.skipSpaces(this.firstPos(), false, true);
|
|
if (start === null) {
|
|
return emptyLines;
|
|
}
|
|
var end = this.skipSpaces(this.lastPos(), true, true);
|
|
if (end === null) {
|
|
return emptyLines;
|
|
}
|
|
return this.slice(start, end);
|
|
};
|
|
Lines.prototype.eachPos = function (callback, startPos, skipSpaces) {
|
|
if (startPos === void 0) { startPos = this.firstPos(); }
|
|
if (skipSpaces === void 0) { skipSpaces = false; }
|
|
var pos = this.firstPos();
|
|
if (startPos) {
|
|
(pos.line = startPos.line), (pos.column = startPos.column);
|
|
}
|
|
if (skipSpaces && !this.skipSpaces(pos, false, true)) {
|
|
return; // Encountered nothing but spaces.
|
|
}
|
|
do
|
|
callback.call(this, pos);
|
|
while (this.nextPos(pos, skipSpaces));
|
|
};
|
|
Lines.prototype.bootstrapSlice = function (start, end) {
|
|
var strings = this.toString()
|
|
.split(lineTerminatorSeqExp)
|
|
.slice(start.line - 1, end.line);
|
|
if (strings.length > 0) {
|
|
strings.push(strings.pop().slice(0, end.column));
|
|
strings[0] = strings[0].slice(start.column);
|
|
}
|
|
return fromString(strings.join("\n"));
|
|
};
|
|
Lines.prototype.slice = function (start, end) {
|
|
if (!end) {
|
|
if (!start) {
|
|
// The client seems to want a copy of this Lines object, but
|
|
// Lines objects are immutable, so it's perfectly adequate to
|
|
// return the same object.
|
|
return this;
|
|
}
|
|
// Slice to the end if no end position was provided.
|
|
end = this.lastPos();
|
|
}
|
|
if (!start) {
|
|
throw new Error("cannot slice with end but not start");
|
|
}
|
|
var sliced = this.infos.slice(start.line - 1, end.line);
|
|
if (start.line === end.line) {
|
|
sliced[0] = sliceInfo(sliced[0], start.column, end.column);
|
|
}
|
|
else {
|
|
(0, tiny_invariant_1.default)(start.line < end.line);
|
|
sliced[0] = sliceInfo(sliced[0], start.column);
|
|
sliced.push(sliceInfo(sliced.pop(), 0, end.column));
|
|
}
|
|
var lines = new Lines(sliced);
|
|
if (this.mappings.length > 0) {
|
|
var newMappings_4 = lines.mappings;
|
|
(0, tiny_invariant_1.default)(newMappings_4.length === 0);
|
|
this.mappings.forEach(function (mapping) {
|
|
var sliced = mapping.slice(this, start, end);
|
|
if (sliced) {
|
|
newMappings_4.push(sliced);
|
|
}
|
|
}, this);
|
|
}
|
|
return lines;
|
|
};
|
|
Lines.prototype.bootstrapSliceString = function (start, end, options) {
|
|
return this.slice(start, end).toString(options);
|
|
};
|
|
Lines.prototype.sliceString = function (start, end, options) {
|
|
if (start === void 0) { start = this.firstPos(); }
|
|
if (end === void 0) { end = this.lastPos(); }
|
|
var _a = (0, options_1.normalize)(options), tabWidth = _a.tabWidth, useTabs = _a.useTabs, reuseWhitespace = _a.reuseWhitespace, lineTerminator = _a.lineTerminator;
|
|
var parts = [];
|
|
for (var line = start.line; line <= end.line; ++line) {
|
|
var info = this.infos[line - 1];
|
|
if (line === start.line) {
|
|
if (line === end.line) {
|
|
info = sliceInfo(info, start.column, end.column);
|
|
}
|
|
else {
|
|
info = sliceInfo(info, start.column);
|
|
}
|
|
}
|
|
else if (line === end.line) {
|
|
info = sliceInfo(info, 0, end.column);
|
|
}
|
|
var indent = Math.max(info.indent, 0);
|
|
var before_1 = info.line.slice(0, info.sliceStart);
|
|
if (reuseWhitespace &&
|
|
isOnlyWhitespace(before_1) &&
|
|
countSpaces(before_1, tabWidth) === indent) {
|
|
// Reuse original spaces if the indentation is correct.
|
|
parts.push(info.line.slice(0, info.sliceEnd));
|
|
continue;
|
|
}
|
|
var tabs = 0;
|
|
var spaces = indent;
|
|
if (useTabs) {
|
|
tabs = Math.floor(indent / tabWidth);
|
|
spaces -= tabs * tabWidth;
|
|
}
|
|
var result = "";
|
|
if (tabs > 0) {
|
|
result += new Array(tabs + 1).join("\t");
|
|
}
|
|
if (spaces > 0) {
|
|
result += new Array(spaces + 1).join(" ");
|
|
}
|
|
result += info.line.slice(info.sliceStart, info.sliceEnd);
|
|
parts.push(result);
|
|
}
|
|
return parts.join(lineTerminator);
|
|
};
|
|
Lines.prototype.isEmpty = function () {
|
|
return this.length < 2 && this.getLineLength(1) < 1;
|
|
};
|
|
Lines.prototype.join = function (elements) {
|
|
var separator = this;
|
|
var infos = [];
|
|
var mappings = [];
|
|
var prevInfo;
|
|
function appendLines(linesOrNull) {
|
|
if (linesOrNull === null) {
|
|
return;
|
|
}
|
|
if (prevInfo) {
|
|
var info = linesOrNull.infos[0];
|
|
var indent = new Array(info.indent + 1).join(" ");
|
|
var prevLine_1 = infos.length;
|
|
var prevColumn_1 = Math.max(prevInfo.indent, 0) +
|
|
prevInfo.sliceEnd -
|
|
prevInfo.sliceStart;
|
|
prevInfo.line =
|
|
prevInfo.line.slice(0, prevInfo.sliceEnd) +
|
|
indent +
|
|
info.line.slice(info.sliceStart, info.sliceEnd);
|
|
// If any part of a line is indentation-locked, the whole line
|
|
// will be indentation-locked.
|
|
prevInfo.locked = prevInfo.locked || info.locked;
|
|
prevInfo.sliceEnd = prevInfo.line.length;
|
|
if (linesOrNull.mappings.length > 0) {
|
|
linesOrNull.mappings.forEach(function (mapping) {
|
|
mappings.push(mapping.add(prevLine_1, prevColumn_1));
|
|
});
|
|
}
|
|
}
|
|
else if (linesOrNull.mappings.length > 0) {
|
|
mappings.push.apply(mappings, linesOrNull.mappings);
|
|
}
|
|
linesOrNull.infos.forEach(function (info, i) {
|
|
if (!prevInfo || i > 0) {
|
|
prevInfo = tslib_1.__assign({}, info);
|
|
infos.push(prevInfo);
|
|
}
|
|
});
|
|
}
|
|
function appendWithSeparator(linesOrNull, i) {
|
|
if (i > 0)
|
|
appendLines(separator);
|
|
appendLines(linesOrNull);
|
|
}
|
|
elements
|
|
.map(function (elem) {
|
|
var lines = fromString(elem);
|
|
if (lines.isEmpty())
|
|
return null;
|
|
return lines;
|
|
})
|
|
.forEach(function (linesOrNull, i) {
|
|
if (separator.isEmpty()) {
|
|
appendLines(linesOrNull);
|
|
}
|
|
else {
|
|
appendWithSeparator(linesOrNull, i);
|
|
}
|
|
});
|
|
if (infos.length < 1)
|
|
return emptyLines;
|
|
var lines = new Lines(infos);
|
|
lines.mappings = mappings;
|
|
return lines;
|
|
};
|
|
Lines.prototype.concat = function () {
|
|
var args = [];
|
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
args[_i] = arguments[_i];
|
|
}
|
|
var list = [this];
|
|
list.push.apply(list, args);
|
|
(0, tiny_invariant_1.default)(list.length === args.length + 1);
|
|
return emptyLines.join(list);
|
|
};
|
|
return Lines;
|
|
}());
|
|
lines.Lines = Lines;
|
|
var fromStringCache = {};
|
|
var hasOwn = fromStringCache.hasOwnProperty;
|
|
var maxCacheKeyLen = 10;
|
|
function countSpaces(spaces, tabWidth) {
|
|
var count = 0;
|
|
var len = spaces.length;
|
|
for (var i = 0; i < len; ++i) {
|
|
switch (spaces.charCodeAt(i)) {
|
|
case 9: {
|
|
// '\t'
|
|
(0, tiny_invariant_1.default)(typeof tabWidth === "number");
|
|
(0, tiny_invariant_1.default)(tabWidth > 0);
|
|
var next = Math.ceil(count / tabWidth) * tabWidth;
|
|
if (next === count) {
|
|
count += tabWidth;
|
|
}
|
|
else {
|
|
count = next;
|
|
}
|
|
break;
|
|
}
|
|
case 11: // '\v'
|
|
case 12: // '\f'
|
|
case 13: // '\r'
|
|
case 0xfeff: // zero-width non-breaking space
|
|
// These characters contribute nothing to indentation.
|
|
break;
|
|
case 32: // ' '
|
|
default:
|
|
// Treat all other whitespace like ' '.
|
|
count += 1;
|
|
break;
|
|
}
|
|
}
|
|
return count;
|
|
}
|
|
lines.countSpaces = countSpaces;
|
|
var leadingSpaceExp = /^\s*/;
|
|
// As specified here: http://www.ecma-international.org/ecma-262/6.0/#sec-line-terminators
|
|
var lineTerminatorSeqExp = /\u000D\u000A|\u000D(?!\u000A)|\u000A|\u2028|\u2029/;
|
|
/**
|
|
* @param {Object} options - Options object that configures printing.
|
|
*/
|
|
function fromString(string, options) {
|
|
if (string instanceof Lines)
|
|
return string;
|
|
string += "";
|
|
var tabWidth = options && options.tabWidth;
|
|
var tabless = string.indexOf("\t") < 0;
|
|
var cacheable = !options && tabless && string.length <= maxCacheKeyLen;
|
|
(0, tiny_invariant_1.default)(tabWidth || tabless, "No tab width specified but encountered tabs in string\n" + string);
|
|
if (cacheable && hasOwn.call(fromStringCache, string))
|
|
return fromStringCache[string];
|
|
var lines = new Lines(string.split(lineTerminatorSeqExp).map(function (line) {
|
|
// TODO: handle null exec result
|
|
var spaces = leadingSpaceExp.exec(line)[0];
|
|
return {
|
|
line: line,
|
|
indent: countSpaces(spaces, tabWidth),
|
|
// Boolean indicating whether this line can be reindented.
|
|
locked: false,
|
|
sliceStart: spaces.length,
|
|
sliceEnd: line.length,
|
|
};
|
|
}), (0, options_1.normalize)(options).sourceFileName);
|
|
if (cacheable)
|
|
fromStringCache[string] = lines;
|
|
return lines;
|
|
}
|
|
lines.fromString = fromString;
|
|
function isOnlyWhitespace(string) {
|
|
return !/\S/.test(string);
|
|
}
|
|
function sliceInfo(info, startCol, endCol) {
|
|
var sliceStart = info.sliceStart;
|
|
var sliceEnd = info.sliceEnd;
|
|
var indent = Math.max(info.indent, 0);
|
|
var lineLength = indent + sliceEnd - sliceStart;
|
|
if (typeof endCol === "undefined") {
|
|
endCol = lineLength;
|
|
}
|
|
startCol = Math.max(startCol, 0);
|
|
endCol = Math.min(endCol, lineLength);
|
|
endCol = Math.max(endCol, startCol);
|
|
if (endCol < indent) {
|
|
indent = endCol;
|
|
sliceEnd = sliceStart;
|
|
}
|
|
else {
|
|
sliceEnd -= lineLength - endCol;
|
|
}
|
|
lineLength = endCol;
|
|
lineLength -= startCol;
|
|
if (startCol < indent) {
|
|
indent -= startCol;
|
|
}
|
|
else {
|
|
startCol -= indent;
|
|
indent = 0;
|
|
sliceStart += startCol;
|
|
}
|
|
(0, tiny_invariant_1.default)(indent >= 0);
|
|
(0, tiny_invariant_1.default)(sliceStart <= sliceEnd);
|
|
(0, tiny_invariant_1.default)(lineLength === indent + sliceEnd - sliceStart);
|
|
if (info.indent === indent &&
|
|
info.sliceStart === sliceStart &&
|
|
info.sliceEnd === sliceEnd) {
|
|
return info;
|
|
}
|
|
return {
|
|
line: info.line,
|
|
indent: indent,
|
|
// A destructive slice always unlocks indentation.
|
|
locked: false,
|
|
sliceStart: sliceStart,
|
|
sliceEnd: sliceEnd,
|
|
};
|
|
}
|
|
function concat(elements) {
|
|
return emptyLines.join(elements);
|
|
}
|
|
lines.concat = concat;
|
|
// The emptyLines object needs to be created all the way down here so that
|
|
// Lines.prototype will be fully populated.
|
|
var emptyLines = fromString("");
|
|
return lines;
|
|
}
|
|
|
|
var comments = {};
|
|
|
|
var hasRequiredComments;
|
|
|
|
function requireComments () {
|
|
if (hasRequiredComments) return comments;
|
|
hasRequiredComments = 1;
|
|
Object.defineProperty(comments, "__esModule", { value: true });
|
|
comments.printComments = comments.attach = void 0;
|
|
var tslib_1 = require$$0;
|
|
var tiny_invariant_1 = tslib_1.__importDefault(/*@__PURE__*/ requireTinyInvariant_cjs());
|
|
var types = tslib_1.__importStar(requireMain$1());
|
|
var n = types.namedTypes;
|
|
var isArray = types.builtInTypes.array;
|
|
var isObject = types.builtInTypes.object;
|
|
var lines_1 = requireLines();
|
|
var util_1 = requireUtil();
|
|
var childNodesCache = new WeakMap();
|
|
// TODO Move a non-caching implementation of this function into ast-types,
|
|
// and implement a caching wrapper function here.
|
|
function getSortedChildNodes(node, lines, resultArray) {
|
|
if (!node) {
|
|
return resultArray;
|
|
}
|
|
// The .loc checks below are sensitive to some of the problems that
|
|
// are fixed by this utility function. Specifically, if it decides to
|
|
// set node.loc to null, indicating that the node's .loc information
|
|
// is unreliable, then we don't want to add node to the resultArray.
|
|
(0, util_1.fixFaultyLocations)(node, lines);
|
|
if (resultArray) {
|
|
if (n.Node.check(node) && n.SourceLocation.check(node.loc)) {
|
|
// This reverse insertion sort almost always takes constant
|
|
// time because we almost always (maybe always?) append the
|
|
// nodes in order anyway.
|
|
var i = resultArray.length - 1;
|
|
for (; i >= 0; --i) {
|
|
var child = resultArray[i];
|
|
if (child &&
|
|
child.loc &&
|
|
(0, util_1.comparePos)(child.loc.end, node.loc.start) <= 0) {
|
|
break;
|
|
}
|
|
}
|
|
resultArray.splice(i + 1, 0, node);
|
|
return resultArray;
|
|
}
|
|
}
|
|
else {
|
|
var childNodes = childNodesCache.get(node);
|
|
if (childNodes) {
|
|
return childNodes;
|
|
}
|
|
}
|
|
var names;
|
|
if (isArray.check(node)) {
|
|
names = Object.keys(node);
|
|
}
|
|
else if (isObject.check(node)) {
|
|
names = types.getFieldNames(node);
|
|
}
|
|
else {
|
|
return resultArray;
|
|
}
|
|
if (!resultArray) {
|
|
childNodesCache.set(node, (resultArray = []));
|
|
}
|
|
for (var i = 0, nameCount = names.length; i < nameCount; ++i) {
|
|
getSortedChildNodes(node[names[i]], lines, resultArray);
|
|
}
|
|
return resultArray;
|
|
}
|
|
// As efficiently as possible, decorate the comment object with
|
|
// .precedingNode, .enclosingNode, and/or .followingNode properties, at
|
|
// least one of which is guaranteed to be defined.
|
|
function decorateComment(node, comment, lines) {
|
|
var childNodes = getSortedChildNodes(node, lines);
|
|
// Time to dust off the old binary search robes and wizard hat.
|
|
var left = 0;
|
|
var right = childNodes && childNodes.length;
|
|
var precedingNode;
|
|
var followingNode;
|
|
while (typeof right === "number" && left < right) {
|
|
var middle = (left + right) >> 1;
|
|
var child = childNodes[middle];
|
|
if ((0, util_1.comparePos)(child.loc.start, comment.loc.start) <= 0 &&
|
|
(0, util_1.comparePos)(comment.loc.end, child.loc.end) <= 0) {
|
|
// The comment is completely contained by this child node.
|
|
decorateComment((comment.enclosingNode = child), comment, lines);
|
|
return; // Abandon the binary search at this level.
|
|
}
|
|
if ((0, util_1.comparePos)(child.loc.end, comment.loc.start) <= 0) {
|
|
// This child node falls completely before the comment.
|
|
// Because we will never consider this node or any nodes
|
|
// before it again, this node must be the closest preceding
|
|
// node we have encountered so far.
|
|
precedingNode = child;
|
|
left = middle + 1;
|
|
continue;
|
|
}
|
|
if ((0, util_1.comparePos)(comment.loc.end, child.loc.start) <= 0) {
|
|
// This child node falls completely after the comment.
|
|
// Because we will never consider this node or any nodes after
|
|
// it again, this node must be the closest following node we
|
|
// have encountered so far.
|
|
followingNode = child;
|
|
right = middle;
|
|
continue;
|
|
}
|
|
throw new Error("Comment location overlaps with node location");
|
|
}
|
|
if (precedingNode) {
|
|
comment.precedingNode = precedingNode;
|
|
}
|
|
if (followingNode) {
|
|
comment.followingNode = followingNode;
|
|
}
|
|
}
|
|
function attach(comments, ast, lines) {
|
|
if (!isArray.check(comments)) {
|
|
return;
|
|
}
|
|
var tiesToBreak = [];
|
|
comments.forEach(function (comment) {
|
|
comment.loc.lines = lines;
|
|
decorateComment(ast, comment, lines);
|
|
var pn = comment.precedingNode;
|
|
var en = comment.enclosingNode;
|
|
var fn = comment.followingNode;
|
|
if (pn && fn) {
|
|
var tieCount = tiesToBreak.length;
|
|
if (tieCount > 0) {
|
|
var lastTie = tiesToBreak[tieCount - 1];
|
|
(0, tiny_invariant_1.default)((lastTie.precedingNode === comment.precedingNode) ===
|
|
(lastTie.followingNode === comment.followingNode));
|
|
if (lastTie.followingNode !== comment.followingNode) {
|
|
breakTies(tiesToBreak, lines);
|
|
}
|
|
}
|
|
tiesToBreak.push(comment);
|
|
}
|
|
else if (pn) {
|
|
// No contest: we have a trailing comment.
|
|
breakTies(tiesToBreak, lines);
|
|
addTrailingComment(pn, comment);
|
|
}
|
|
else if (fn) {
|
|
// No contest: we have a leading comment.
|
|
breakTies(tiesToBreak, lines);
|
|
addLeadingComment(fn, comment);
|
|
}
|
|
else if (en) {
|
|
// The enclosing node has no child nodes at all, so what we
|
|
// have here is a dangling comment, e.g. [/* crickets */].
|
|
breakTies(tiesToBreak, lines);
|
|
addDanglingComment(en, comment);
|
|
}
|
|
else {
|
|
throw new Error("AST contains no nodes at all?");
|
|
}
|
|
});
|
|
breakTies(tiesToBreak, lines);
|
|
comments.forEach(function (comment) {
|
|
// These node references were useful for breaking ties, but we
|
|
// don't need them anymore, and they create cycles in the AST that
|
|
// may lead to infinite recursion if we don't delete them here.
|
|
delete comment.precedingNode;
|
|
delete comment.enclosingNode;
|
|
delete comment.followingNode;
|
|
});
|
|
}
|
|
comments.attach = attach;
|
|
function breakTies(tiesToBreak, lines) {
|
|
var tieCount = tiesToBreak.length;
|
|
if (tieCount === 0) {
|
|
return;
|
|
}
|
|
var pn = tiesToBreak[0].precedingNode;
|
|
var fn = tiesToBreak[0].followingNode;
|
|
var gapEndPos = fn.loc.start;
|
|
// Iterate backwards through tiesToBreak, examining the gaps
|
|
// between the tied comments. In order to qualify as leading, a
|
|
// comment must be separated from fn by an unbroken series of
|
|
// whitespace-only gaps (or other comments).
|
|
var indexOfFirstLeadingComment = tieCount;
|
|
var comment;
|
|
for (; indexOfFirstLeadingComment > 0; --indexOfFirstLeadingComment) {
|
|
comment = tiesToBreak[indexOfFirstLeadingComment - 1];
|
|
(0, tiny_invariant_1.default)(comment.precedingNode === pn);
|
|
(0, tiny_invariant_1.default)(comment.followingNode === fn);
|
|
var gap = lines.sliceString(comment.loc.end, gapEndPos);
|
|
if (/\S/.test(gap)) {
|
|
// The gap string contained something other than whitespace.
|
|
break;
|
|
}
|
|
gapEndPos = comment.loc.start;
|
|
}
|
|
while (indexOfFirstLeadingComment <= tieCount &&
|
|
(comment = tiesToBreak[indexOfFirstLeadingComment]) &&
|
|
// If the comment is a //-style comment and indented more
|
|
// deeply than the node itself, reconsider it as trailing.
|
|
(comment.type === "Line" || comment.type === "CommentLine") &&
|
|
comment.loc.start.column > fn.loc.start.column) {
|
|
++indexOfFirstLeadingComment;
|
|
}
|
|
if (indexOfFirstLeadingComment) {
|
|
var enclosingNode = tiesToBreak[indexOfFirstLeadingComment - 1].enclosingNode;
|
|
if ((enclosingNode === null || enclosingNode === void 0 ? void 0 : enclosingNode.type) === "CallExpression") {
|
|
--indexOfFirstLeadingComment;
|
|
}
|
|
}
|
|
tiesToBreak.forEach(function (comment, i) {
|
|
if (i < indexOfFirstLeadingComment) {
|
|
addTrailingComment(pn, comment);
|
|
}
|
|
else {
|
|
addLeadingComment(fn, comment);
|
|
}
|
|
});
|
|
tiesToBreak.length = 0;
|
|
}
|
|
function addCommentHelper(node, comment) {
|
|
var comments = node.comments || (node.comments = []);
|
|
comments.push(comment);
|
|
}
|
|
function addLeadingComment(node, comment) {
|
|
comment.leading = true;
|
|
comment.trailing = false;
|
|
addCommentHelper(node, comment);
|
|
}
|
|
function addDanglingComment(node, comment) {
|
|
comment.leading = false;
|
|
comment.trailing = false;
|
|
addCommentHelper(node, comment);
|
|
}
|
|
function addTrailingComment(node, comment) {
|
|
comment.leading = false;
|
|
comment.trailing = true;
|
|
addCommentHelper(node, comment);
|
|
}
|
|
function printLeadingComment(commentPath, print) {
|
|
var comment = commentPath.getValue();
|
|
n.Comment.assert(comment);
|
|
var loc = comment.loc;
|
|
var lines = loc && loc.lines;
|
|
var parts = [print(commentPath)];
|
|
if (comment.trailing) {
|
|
// When we print trailing comments as leading comments, we don't
|
|
// want to bring any trailing spaces along.
|
|
parts.push("\n");
|
|
}
|
|
else if (lines instanceof lines_1.Lines) {
|
|
var trailingSpace = lines.slice(loc.end, lines.skipSpaces(loc.end) || lines.lastPos());
|
|
if (trailingSpace.length === 1) {
|
|
// If the trailing space contains no newlines, then we want to
|
|
// preserve it exactly as we found it.
|
|
parts.push(trailingSpace);
|
|
}
|
|
else {
|
|
// If the trailing space contains newlines, then replace it
|
|
// with just that many newlines, with all other spaces removed.
|
|
parts.push(new Array(trailingSpace.length).join("\n"));
|
|
}
|
|
}
|
|
else {
|
|
parts.push("\n");
|
|
}
|
|
return (0, lines_1.concat)(parts);
|
|
}
|
|
function printTrailingComment(commentPath, print) {
|
|
var comment = commentPath.getValue(commentPath);
|
|
n.Comment.assert(comment);
|
|
var loc = comment.loc;
|
|
var lines = loc && loc.lines;
|
|
var parts = [];
|
|
if (lines instanceof lines_1.Lines) {
|
|
var fromPos = lines.skipSpaces(loc.start, true) || lines.firstPos();
|
|
var leadingSpace = lines.slice(fromPos, loc.start);
|
|
if (leadingSpace.length === 1) {
|
|
// If the leading space contains no newlines, then we want to
|
|
// preserve it exactly as we found it.
|
|
parts.push(leadingSpace);
|
|
}
|
|
else {
|
|
// If the leading space contains newlines, then replace it
|
|
// with just that many newlines, sans all other spaces.
|
|
parts.push(new Array(leadingSpace.length).join("\n"));
|
|
}
|
|
}
|
|
parts.push(print(commentPath));
|
|
return (0, lines_1.concat)(parts);
|
|
}
|
|
function printComments(path, print) {
|
|
var value = path.getValue();
|
|
var innerLines = print(path);
|
|
var comments = n.Node.check(value) && types.getFieldValue(value, "comments");
|
|
if (!comments || comments.length === 0) {
|
|
return innerLines;
|
|
}
|
|
var leadingParts = [];
|
|
var trailingParts = [innerLines];
|
|
path.each(function (commentPath) {
|
|
var comment = commentPath.getValue();
|
|
var leading = types.getFieldValue(comment, "leading");
|
|
var trailing = types.getFieldValue(comment, "trailing");
|
|
if (leading ||
|
|
(trailing &&
|
|
!(n.Statement.check(value) ||
|
|
comment.type === "Block" ||
|
|
comment.type === "CommentBlock"))) {
|
|
leadingParts.push(printLeadingComment(commentPath, print));
|
|
}
|
|
else if (trailing) {
|
|
trailingParts.push(printTrailingComment(commentPath, print));
|
|
}
|
|
}, "comments");
|
|
leadingParts.push.apply(leadingParts, trailingParts);
|
|
return (0, lines_1.concat)(leadingParts);
|
|
}
|
|
comments.printComments = printComments;
|
|
return comments;
|
|
}
|
|
|
|
var hasRequiredParser;
|
|
|
|
function requireParser () {
|
|
if (hasRequiredParser) return parser$1;
|
|
hasRequiredParser = 1;
|
|
Object.defineProperty(parser$1, "__esModule", { value: true });
|
|
parser$1.parse = void 0;
|
|
var tslib_1 = require$$0;
|
|
var tiny_invariant_1 = tslib_1.__importDefault(/*@__PURE__*/ requireTinyInvariant_cjs());
|
|
var types = tslib_1.__importStar(requireMain$1());
|
|
var b = types.builders;
|
|
var isObject = types.builtInTypes.object;
|
|
var isArray = types.builtInTypes.array;
|
|
var options_1 = requireOptions();
|
|
var lines_1 = requireLines();
|
|
var comments_1 = requireComments();
|
|
var util = tslib_1.__importStar(requireUtil());
|
|
function parse(source, options) {
|
|
options = (0, options_1.normalize)(options);
|
|
var lines = (0, lines_1.fromString)(source, options);
|
|
var sourceWithoutTabs = lines.toString({
|
|
tabWidth: options.tabWidth,
|
|
reuseWhitespace: false,
|
|
useTabs: false,
|
|
});
|
|
var comments = [];
|
|
var ast = options.parser.parse(sourceWithoutTabs, {
|
|
jsx: true,
|
|
loc: true,
|
|
locations: true,
|
|
range: options.range,
|
|
comment: true,
|
|
onComment: comments,
|
|
tolerant: util.getOption(options, "tolerant", true),
|
|
ecmaVersion: 6,
|
|
sourceType: util.getOption(options, "sourceType", "module"),
|
|
});
|
|
// Use ast.tokens if possible, and otherwise fall back to the Esprima
|
|
// tokenizer. All the preconfigured ../parsers/* expose ast.tokens
|
|
// automatically, but custom parsers might need additional configuration
|
|
// to avoid this fallback.
|
|
var tokens = Array.isArray(ast.tokens)
|
|
? ast.tokens
|
|
: requireEsprima$1().tokenize(sourceWithoutTabs, {
|
|
loc: true,
|
|
});
|
|
// We will reattach the tokens array to the file object below.
|
|
delete ast.tokens;
|
|
// Make sure every token has a token.value string.
|
|
tokens.forEach(function (token) {
|
|
if (typeof token.value !== "string") {
|
|
token.value = lines.sliceString(token.loc.start, token.loc.end);
|
|
}
|
|
});
|
|
if (Array.isArray(ast.comments)) {
|
|
comments = ast.comments;
|
|
delete ast.comments;
|
|
}
|
|
if (ast.loc) {
|
|
// If the source was empty, some parsers give loc.{start,end}.line
|
|
// values of 0, instead of the minimum of 1.
|
|
util.fixFaultyLocations(ast, lines);
|
|
}
|
|
else {
|
|
ast.loc = {
|
|
start: lines.firstPos(),
|
|
end: lines.lastPos(),
|
|
};
|
|
}
|
|
ast.loc.lines = lines;
|
|
ast.loc.indent = 0;
|
|
var file;
|
|
var program;
|
|
if (ast.type === "Program") {
|
|
program = ast;
|
|
// In order to ensure we reprint leading and trailing program
|
|
// comments, wrap the original Program node with a File node. Only
|
|
// ESTree parsers (Acorn and Esprima) return a Program as the root AST
|
|
// node. Most other (Babylon-like) parsers return a File.
|
|
file = b.file(ast, options.sourceFileName || null);
|
|
file.loc = {
|
|
start: lines.firstPos(),
|
|
end: lines.lastPos(),
|
|
lines: lines,
|
|
indent: 0,
|
|
};
|
|
}
|
|
else if (ast.type === "File") {
|
|
file = ast;
|
|
program = file.program;
|
|
}
|
|
// Expose file.tokens unless the caller passed false for options.tokens.
|
|
if (options.tokens) {
|
|
file.tokens = tokens;
|
|
}
|
|
// Expand the Program's .loc to include all comments (not just those
|
|
// attached to the Program node, as its children may have comments as
|
|
// well), since sometimes program.loc.{start,end} will coincide with the
|
|
// .loc.{start,end} of the first and last *statements*, mistakenly
|
|
// excluding comments that fall outside that region.
|
|
var trueProgramLoc = util.getTrueLoc({
|
|
type: program.type,
|
|
loc: program.loc,
|
|
body: [],
|
|
comments: comments,
|
|
}, lines);
|
|
program.loc.start = trueProgramLoc.start;
|
|
program.loc.end = trueProgramLoc.end;
|
|
// Passing file.program here instead of just file means that initial
|
|
// comments will be attached to program.body[0] instead of program.
|
|
(0, comments_1.attach)(comments, program.body.length ? file.program : file, lines);
|
|
// Return a copy of the original AST so that any changes made may be
|
|
// compared to the original.
|
|
return new TreeCopier(lines, tokens).copy(file);
|
|
}
|
|
parser$1.parse = parse;
|
|
var TreeCopier = function TreeCopier(lines, tokens) {
|
|
(0, tiny_invariant_1.default)(this instanceof TreeCopier);
|
|
this.lines = lines;
|
|
this.tokens = tokens;
|
|
this.startTokenIndex = 0;
|
|
this.endTokenIndex = tokens.length;
|
|
this.indent = 0;
|
|
this.seen = new Map();
|
|
};
|
|
var TCp = TreeCopier.prototype;
|
|
TCp.copy = function (node) {
|
|
if (this.seen.has(node)) {
|
|
return this.seen.get(node);
|
|
}
|
|
if (isArray.check(node)) {
|
|
var copy_1 = new Array(node.length);
|
|
this.seen.set(node, copy_1);
|
|
node.forEach(function (item, i) {
|
|
copy_1[i] = this.copy(item);
|
|
}, this);
|
|
return copy_1;
|
|
}
|
|
if (!isObject.check(node)) {
|
|
return node;
|
|
}
|
|
util.fixFaultyLocations(node, this.lines);
|
|
var copy = Object.create(Object.getPrototypeOf(node), {
|
|
original: {
|
|
// Provide a link from the copy to the original.
|
|
value: node,
|
|
configurable: false,
|
|
enumerable: false,
|
|
writable: true,
|
|
},
|
|
});
|
|
this.seen.set(node, copy);
|
|
var loc = node.loc;
|
|
var oldIndent = this.indent;
|
|
var newIndent = oldIndent;
|
|
var oldStartTokenIndex = this.startTokenIndex;
|
|
var oldEndTokenIndex = this.endTokenIndex;
|
|
if (loc) {
|
|
// When node is a comment, we set node.loc.indent to
|
|
// node.loc.start.column so that, when/if we print the comment by
|
|
// itself, we can strip that much whitespace from the left margin of
|
|
// the comment. This only really matters for multiline Block comments,
|
|
// but it doesn't hurt for Line comments.
|
|
if (node.type === "Block" ||
|
|
node.type === "Line" ||
|
|
node.type === "CommentBlock" ||
|
|
node.type === "CommentLine" ||
|
|
this.lines.isPrecededOnlyByWhitespace(loc.start)) {
|
|
newIndent = this.indent = loc.start.column;
|
|
}
|
|
// Every node.loc has a reference to the original source lines as well
|
|
// as a complete list of source tokens.
|
|
loc.lines = this.lines;
|
|
loc.tokens = this.tokens;
|
|
loc.indent = newIndent;
|
|
// Set loc.start.token and loc.end.token such that
|
|
// loc.tokens.slice(loc.start.token, loc.end.token) returns a list of
|
|
// all the tokens that make up this node.
|
|
this.findTokenRange(loc);
|
|
}
|
|
var keys = Object.keys(node);
|
|
var keyCount = keys.length;
|
|
for (var i = 0; i < keyCount; ++i) {
|
|
var key = keys[i];
|
|
if (key === "loc") {
|
|
copy[key] = node[key];
|
|
}
|
|
else if (key === "tokens" && node.type === "File") {
|
|
// Preserve file.tokens (uncopied) in case client code cares about
|
|
// it, even though Recast ignores it when reprinting.
|
|
copy[key] = node[key];
|
|
}
|
|
else {
|
|
copy[key] = this.copy(node[key]);
|
|
}
|
|
}
|
|
this.indent = oldIndent;
|
|
this.startTokenIndex = oldStartTokenIndex;
|
|
this.endTokenIndex = oldEndTokenIndex;
|
|
return copy;
|
|
};
|
|
// If we didn't have any idea where in loc.tokens to look for tokens
|
|
// contained by this loc, a binary search would be appropriate, but
|
|
// because we maintain this.startTokenIndex and this.endTokenIndex as we
|
|
// traverse the AST, we only need to make small (linear) adjustments to
|
|
// those indexes with each recursive iteration.
|
|
TCp.findTokenRange = function (loc) {
|
|
// In the unlikely event that loc.tokens[this.startTokenIndex] starts
|
|
// *after* loc.start, we need to rewind this.startTokenIndex first.
|
|
while (this.startTokenIndex > 0) {
|
|
var token = loc.tokens[this.startTokenIndex];
|
|
if (util.comparePos(loc.start, token.loc.start) < 0) {
|
|
--this.startTokenIndex;
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
// In the unlikely event that loc.tokens[this.endTokenIndex - 1] ends
|
|
// *before* loc.end, we need to fast-forward this.endTokenIndex first.
|
|
while (this.endTokenIndex < loc.tokens.length) {
|
|
var token = loc.tokens[this.endTokenIndex];
|
|
if (util.comparePos(token.loc.end, loc.end) < 0) {
|
|
++this.endTokenIndex;
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
// Increment this.startTokenIndex until we've found the first token
|
|
// contained by this node.
|
|
while (this.startTokenIndex < this.endTokenIndex) {
|
|
var token = loc.tokens[this.startTokenIndex];
|
|
if (util.comparePos(token.loc.start, loc.start) < 0) {
|
|
++this.startTokenIndex;
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
// Index into loc.tokens of the first token within this node.
|
|
loc.start.token = this.startTokenIndex;
|
|
// Decrement this.endTokenIndex until we've found the first token after
|
|
// this node (not contained by the node).
|
|
while (this.endTokenIndex > this.startTokenIndex) {
|
|
var token = loc.tokens[this.endTokenIndex - 1];
|
|
if (util.comparePos(loc.end, token.loc.end) < 0) {
|
|
--this.endTokenIndex;
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
// Index into loc.tokens of the first token *after* this node.
|
|
// If loc.start.token === loc.end.token, the node contains no tokens,
|
|
// and the index is that of the next token following this node.
|
|
loc.end.token = this.endTokenIndex;
|
|
};
|
|
return parser$1;
|
|
}
|
|
|
|
var printer = {};
|
|
|
|
var fastPath = {};
|
|
|
|
var hasRequiredFastPath;
|
|
|
|
function requireFastPath () {
|
|
if (hasRequiredFastPath) return fastPath;
|
|
hasRequiredFastPath = 1;
|
|
Object.defineProperty(fastPath, "__esModule", { value: true });
|
|
var tslib_1 = require$$0;
|
|
var tiny_invariant_1 = tslib_1.__importDefault(/*@__PURE__*/ requireTinyInvariant_cjs());
|
|
var types = tslib_1.__importStar(requireMain$1());
|
|
var util = tslib_1.__importStar(requireUtil());
|
|
var n = types.namedTypes;
|
|
var isArray = types.builtInTypes.array;
|
|
var isNumber = types.builtInTypes.number;
|
|
var PRECEDENCE = {};
|
|
[
|
|
["??"],
|
|
["||"],
|
|
["&&"],
|
|
["|"],
|
|
["^"],
|
|
["&"],
|
|
["==", "===", "!=", "!=="],
|
|
["<", ">", "<=", ">=", "in", "instanceof"],
|
|
[">>", "<<", ">>>"],
|
|
["+", "-"],
|
|
["*", "/", "%"],
|
|
["**"],
|
|
].forEach(function (tier, i) {
|
|
tier.forEach(function (op) {
|
|
PRECEDENCE[op] = i;
|
|
});
|
|
});
|
|
var FastPath = function FastPath(value) {
|
|
(0, tiny_invariant_1.default)(this instanceof FastPath);
|
|
this.stack = [value];
|
|
};
|
|
var FPp = FastPath.prototype;
|
|
// Static convenience function for coercing a value to a FastPath.
|
|
FastPath.from = function (obj) {
|
|
if (obj instanceof FastPath) {
|
|
// Return a defensive copy of any existing FastPath instances.
|
|
return obj.copy();
|
|
}
|
|
if (obj instanceof types.NodePath) {
|
|
// For backwards compatibility, unroll NodePath instances into
|
|
// lightweight FastPath [..., name, value] stacks.
|
|
var copy = Object.create(FastPath.prototype);
|
|
var stack = [obj.value];
|
|
for (var pp = void 0; (pp = obj.parentPath); obj = pp)
|
|
stack.push(obj.name, pp.value);
|
|
copy.stack = stack.reverse();
|
|
return copy;
|
|
}
|
|
// Otherwise use obj as the value of the new FastPath instance.
|
|
return new FastPath(obj);
|
|
};
|
|
FPp.copy = function copy() {
|
|
var copy = Object.create(FastPath.prototype);
|
|
copy.stack = this.stack.slice(0);
|
|
return copy;
|
|
};
|
|
// The name of the current property is always the penultimate element of
|
|
// this.stack, and always a String.
|
|
FPp.getName = function getName() {
|
|
var s = this.stack;
|
|
var len = s.length;
|
|
if (len > 1) {
|
|
return s[len - 2];
|
|
}
|
|
// Since the name is always a string, null is a safe sentinel value to
|
|
// return if we do not know the name of the (root) value.
|
|
return null;
|
|
};
|
|
// The value of the current property is always the final element of
|
|
// this.stack.
|
|
FPp.getValue = function getValue() {
|
|
var s = this.stack;
|
|
return s[s.length - 1];
|
|
};
|
|
FPp.valueIsDuplicate = function () {
|
|
var s = this.stack;
|
|
var valueIndex = s.length - 1;
|
|
return s.lastIndexOf(s[valueIndex], valueIndex - 1) >= 0;
|
|
};
|
|
function getNodeHelper(path, count) {
|
|
var s = path.stack;
|
|
for (var i = s.length - 1; i >= 0; i -= 2) {
|
|
var value = s[i];
|
|
if (n.Node.check(value) && --count < 0) {
|
|
return value;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
FPp.getNode = function getNode(count) {
|
|
if (count === void 0) { count = 0; }
|
|
return getNodeHelper(this, ~~count);
|
|
};
|
|
FPp.getParentNode = function getParentNode(count) {
|
|
if (count === void 0) { count = 0; }
|
|
return getNodeHelper(this, ~~count + 1);
|
|
};
|
|
// The length of the stack can be either even or odd, depending on whether
|
|
// or not we have a name for the root value. The difference between the
|
|
// index of the root value and the index of the final value is always
|
|
// even, though, which allows us to return the root value in constant time
|
|
// (i.e. without iterating backwards through the stack).
|
|
FPp.getRootValue = function getRootValue() {
|
|
var s = this.stack;
|
|
if (s.length % 2 === 0) {
|
|
return s[1];
|
|
}
|
|
return s[0];
|
|
};
|
|
// Temporarily push properties named by string arguments given after the
|
|
// callback function onto this.stack, then call the callback with a
|
|
// reference to this (modified) FastPath object. Note that the stack will
|
|
// be restored to its original state after the callback is finished, so it
|
|
// is probably a mistake to retain a reference to the path.
|
|
FPp.call = function call(callback /*, name1, name2, ... */) {
|
|
var s = this.stack;
|
|
var origLen = s.length;
|
|
var value = s[origLen - 1];
|
|
var argc = arguments.length;
|
|
for (var i = 1; i < argc; ++i) {
|
|
var name = arguments[i];
|
|
value = value[name];
|
|
s.push(name, value);
|
|
}
|
|
var result = callback(this);
|
|
s.length = origLen;
|
|
return result;
|
|
};
|
|
// Similar to FastPath.prototype.call, except that the value obtained by
|
|
// accessing this.getValue()[name1][name2]... should be array-like. The
|
|
// callback will be called with a reference to this path object for each
|
|
// element of the array.
|
|
FPp.each = function each(callback /*, name1, name2, ... */) {
|
|
var s = this.stack;
|
|
var origLen = s.length;
|
|
var value = s[origLen - 1];
|
|
var argc = arguments.length;
|
|
for (var i = 1; i < argc; ++i) {
|
|
var name = arguments[i];
|
|
value = value[name];
|
|
s.push(name, value);
|
|
}
|
|
for (var i = 0; i < value.length; ++i) {
|
|
if (i in value) {
|
|
s.push(i, value[i]);
|
|
// If the callback needs to know the value of i, call
|
|
// path.getName(), assuming path is the parameter name.
|
|
callback(this);
|
|
s.length -= 2;
|
|
}
|
|
}
|
|
s.length = origLen;
|
|
};
|
|
// Similar to FastPath.prototype.each, except that the results of the
|
|
// callback function invocations are stored in an array and returned at
|
|
// the end of the iteration.
|
|
FPp.map = function map(callback /*, name1, name2, ... */) {
|
|
var s = this.stack;
|
|
var origLen = s.length;
|
|
var value = s[origLen - 1];
|
|
var argc = arguments.length;
|
|
for (var i = 1; i < argc; ++i) {
|
|
var name = arguments[i];
|
|
value = value[name];
|
|
s.push(name, value);
|
|
}
|
|
var result = new Array(value.length);
|
|
for (var i = 0; i < value.length; ++i) {
|
|
if (i in value) {
|
|
s.push(i, value[i]);
|
|
result[i] = callback(this, i);
|
|
s.length -= 2;
|
|
}
|
|
}
|
|
s.length = origLen;
|
|
return result;
|
|
};
|
|
// Returns true if the node at the tip of the path is wrapped with
|
|
// parentheses, OR if the only reason the node needed parentheses was that
|
|
// it couldn't be the first expression in the enclosing statement (see
|
|
// FastPath#canBeFirstInStatement), and it has an opening `(` character.
|
|
// For example, the FunctionExpression in `(function(){}())` appears to
|
|
// need parentheses only because it's the first expression in the AST, but
|
|
// since it happens to be preceded by a `(` (which is not apparent from
|
|
// the AST but can be determined using FastPath#getPrevToken), there is no
|
|
// ambiguity about how to parse it, so it counts as having parentheses,
|
|
// even though it is not immediately followed by a `)`.
|
|
FPp.hasParens = function () {
|
|
var node = this.getNode();
|
|
var prevToken = this.getPrevToken(node);
|
|
if (!prevToken) {
|
|
return false;
|
|
}
|
|
var nextToken = this.getNextToken(node);
|
|
if (!nextToken) {
|
|
return false;
|
|
}
|
|
if (prevToken.value === "(") {
|
|
if (nextToken.value === ")") {
|
|
// If the node preceded by a `(` token and followed by a `)` token,
|
|
// then of course it has parentheses.
|
|
return true;
|
|
}
|
|
// If this is one of the few Expression types that can't come first in
|
|
// the enclosing statement because of parsing ambiguities (namely,
|
|
// FunctionExpression, ObjectExpression, and ClassExpression) and
|
|
// this.firstInStatement() returns true, and the node would not need
|
|
// parentheses in an expression context because this.needsParens(true)
|
|
// returns false, then it just needs an opening parenthesis to resolve
|
|
// the parsing ambiguity that made it appear to need parentheses.
|
|
var justNeedsOpeningParen = !this.canBeFirstInStatement() &&
|
|
this.firstInStatement() &&
|
|
!this.needsParens(true);
|
|
if (justNeedsOpeningParen) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
};
|
|
FPp.getPrevToken = function (node) {
|
|
node = node || this.getNode();
|
|
var loc = node && node.loc;
|
|
var tokens = loc && loc.tokens;
|
|
if (tokens && loc.start.token > 0) {
|
|
var token = tokens[loc.start.token - 1];
|
|
if (token) {
|
|
// Do not return tokens that fall outside the root subtree.
|
|
var rootLoc = this.getRootValue().loc;
|
|
if (util.comparePos(rootLoc.start, token.loc.start) <= 0) {
|
|
return token;
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
FPp.getNextToken = function (node) {
|
|
node = node || this.getNode();
|
|
var loc = node && node.loc;
|
|
var tokens = loc && loc.tokens;
|
|
if (tokens && loc.end.token < tokens.length) {
|
|
var token = tokens[loc.end.token];
|
|
if (token) {
|
|
// Do not return tokens that fall outside the root subtree.
|
|
var rootLoc = this.getRootValue().loc;
|
|
if (util.comparePos(token.loc.end, rootLoc.end) <= 0) {
|
|
return token;
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
// Inspired by require("ast-types").NodePath.prototype.needsParens, but
|
|
// more efficient because we're iterating backwards through a stack.
|
|
FPp.needsParens = function (assumeExpressionContext) {
|
|
var node = this.getNode();
|
|
// This needs to come before `if (!parent) { return false }` because
|
|
// an object destructuring assignment requires parens for
|
|
// correctness even when it's the topmost expression.
|
|
if (node.type === "AssignmentExpression" &&
|
|
node.left.type === "ObjectPattern") {
|
|
return true;
|
|
}
|
|
var parent = this.getParentNode();
|
|
var name = this.getName();
|
|
// If the value of this path is some child of a Node and not a Node
|
|
// itself, then it doesn't need parentheses. Only Node objects (in fact,
|
|
// only Expression nodes) need parentheses.
|
|
if (this.getValue() !== node) {
|
|
return false;
|
|
}
|
|
// Only statements don't need parentheses.
|
|
if (n.Statement.check(node)) {
|
|
return false;
|
|
}
|
|
// Identifiers never need parentheses.
|
|
if (node.type === "Identifier") {
|
|
return false;
|
|
}
|
|
if (parent && parent.type === "ParenthesizedExpression") {
|
|
return false;
|
|
}
|
|
if (node.extra && node.extra.parenthesized) {
|
|
return true;
|
|
}
|
|
if (!parent)
|
|
return false;
|
|
// Wrap e.g. `-1` in parentheses inside `(-1) ** 2`.
|
|
if (node.type === "UnaryExpression" &&
|
|
parent.type === "BinaryExpression" &&
|
|
name === "left" &&
|
|
parent.left === node &&
|
|
parent.operator === "**") {
|
|
return true;
|
|
}
|
|
switch (node.type) {
|
|
case "UnaryExpression":
|
|
case "SpreadElement":
|
|
case "SpreadProperty":
|
|
return (parent.type === "MemberExpression" &&
|
|
name === "object" &&
|
|
parent.object === node);
|
|
case "BinaryExpression":
|
|
case "LogicalExpression":
|
|
switch (parent.type) {
|
|
case "CallExpression":
|
|
return name === "callee" && parent.callee === node;
|
|
case "UnaryExpression":
|
|
case "SpreadElement":
|
|
case "SpreadProperty":
|
|
return true;
|
|
case "MemberExpression":
|
|
return name === "object" && parent.object === node;
|
|
case "BinaryExpression":
|
|
case "LogicalExpression": {
|
|
var po = parent.operator;
|
|
var pp = PRECEDENCE[po];
|
|
var no = node.operator;
|
|
var np = PRECEDENCE[no];
|
|
if (pp > np) {
|
|
return true;
|
|
}
|
|
if (pp === np && name === "right") {
|
|
(0, tiny_invariant_1.default)(parent.right === node);
|
|
return true;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
return false;
|
|
}
|
|
break;
|
|
case "SequenceExpression":
|
|
switch (parent.type) {
|
|
case "ReturnStatement":
|
|
return false;
|
|
case "ForStatement":
|
|
// Although parentheses wouldn't hurt around sequence expressions in
|
|
// the head of for loops, traditional style dictates that e.g. i++,
|
|
// j++ should not be wrapped with parentheses.
|
|
return false;
|
|
case "ExpressionStatement":
|
|
return name !== "expression";
|
|
default:
|
|
// Otherwise err on the side of overparenthesization, adding
|
|
// explicit exceptions above if this proves overzealous.
|
|
return true;
|
|
}
|
|
case "OptionalIndexedAccessType":
|
|
return node.optional && parent.type === "IndexedAccessType";
|
|
case "IntersectionTypeAnnotation":
|
|
case "UnionTypeAnnotation":
|
|
return parent.type === "NullableTypeAnnotation";
|
|
case "Literal":
|
|
return (parent.type === "MemberExpression" &&
|
|
isNumber.check(node.value) &&
|
|
name === "object" &&
|
|
parent.object === node);
|
|
// Babel 6 Literal split
|
|
case "NumericLiteral":
|
|
return (parent.type === "MemberExpression" &&
|
|
name === "object" &&
|
|
parent.object === node);
|
|
case "YieldExpression":
|
|
case "AwaitExpression":
|
|
case "AssignmentExpression":
|
|
case "ConditionalExpression":
|
|
switch (parent.type) {
|
|
case "UnaryExpression":
|
|
case "SpreadElement":
|
|
case "SpreadProperty":
|
|
case "BinaryExpression":
|
|
case "LogicalExpression":
|
|
return true;
|
|
case "CallExpression":
|
|
case "NewExpression":
|
|
return name === "callee" && parent.callee === node;
|
|
case "ConditionalExpression":
|
|
return name === "test" && parent.test === node;
|
|
case "MemberExpression":
|
|
return name === "object" && parent.object === node;
|
|
default:
|
|
return false;
|
|
}
|
|
case "ArrowFunctionExpression":
|
|
if (n.CallExpression.check(parent) &&
|
|
name === "callee" &&
|
|
parent.callee === node) {
|
|
return true;
|
|
}
|
|
if (n.MemberExpression.check(parent) &&
|
|
name === "object" &&
|
|
parent.object === node) {
|
|
return true;
|
|
}
|
|
if (n.TSAsExpression &&
|
|
n.TSAsExpression.check(parent) &&
|
|
name === "expression" &&
|
|
parent.expression === node) {
|
|
return true;
|
|
}
|
|
return isBinary(parent);
|
|
case "ObjectExpression":
|
|
if (parent.type === "ArrowFunctionExpression" &&
|
|
name === "body" &&
|
|
parent.body === node) {
|
|
return true;
|
|
}
|
|
break;
|
|
case "TSAsExpression":
|
|
if (parent.type === "ArrowFunctionExpression" &&
|
|
name === "body" &&
|
|
parent.body === node &&
|
|
node.expression.type === "ObjectExpression") {
|
|
return true;
|
|
}
|
|
break;
|
|
case "CallExpression":
|
|
if (name === "declaration" &&
|
|
n.ExportDefaultDeclaration.check(parent) &&
|
|
n.FunctionExpression.check(node.callee)) {
|
|
return true;
|
|
}
|
|
}
|
|
if (parent.type === "NewExpression" &&
|
|
name === "callee" &&
|
|
parent.callee === node) {
|
|
return containsCallExpression(node);
|
|
}
|
|
if (assumeExpressionContext !== true &&
|
|
!this.canBeFirstInStatement() &&
|
|
this.firstInStatement()) {
|
|
return true;
|
|
}
|
|
return false;
|
|
};
|
|
function isBinary(node) {
|
|
return n.BinaryExpression.check(node) || n.LogicalExpression.check(node);
|
|
}
|
|
function containsCallExpression(node) {
|
|
if (n.CallExpression.check(node)) {
|
|
return true;
|
|
}
|
|
if (isArray.check(node)) {
|
|
return node.some(containsCallExpression);
|
|
}
|
|
if (n.Node.check(node)) {
|
|
return types.someField(node, function (_name, child) {
|
|
return containsCallExpression(child);
|
|
});
|
|
}
|
|
return false;
|
|
}
|
|
FPp.canBeFirstInStatement = function () {
|
|
var node = this.getNode();
|
|
if (n.FunctionExpression.check(node)) {
|
|
return false;
|
|
}
|
|
if (n.ObjectExpression.check(node)) {
|
|
return false;
|
|
}
|
|
if (n.ClassExpression.check(node)) {
|
|
return false;
|
|
}
|
|
return true;
|
|
};
|
|
FPp.firstInStatement = function () {
|
|
var s = this.stack;
|
|
var parentName, parent;
|
|
var childName, child;
|
|
for (var i = s.length - 1; i >= 0; i -= 2) {
|
|
if (n.Node.check(s[i])) {
|
|
childName = parentName;
|
|
child = parent;
|
|
parentName = s[i - 1];
|
|
parent = s[i];
|
|
}
|
|
if (!parent || !child) {
|
|
continue;
|
|
}
|
|
if (n.BlockStatement.check(parent) &&
|
|
parentName === "body" &&
|
|
childName === 0) {
|
|
(0, tiny_invariant_1.default)(parent.body[0] === child);
|
|
return true;
|
|
}
|
|
if (n.ExpressionStatement.check(parent) && childName === "expression") {
|
|
(0, tiny_invariant_1.default)(parent.expression === child);
|
|
return true;
|
|
}
|
|
if (n.AssignmentExpression.check(parent) && childName === "left") {
|
|
(0, tiny_invariant_1.default)(parent.left === child);
|
|
return true;
|
|
}
|
|
if (n.ArrowFunctionExpression.check(parent) && childName === "body") {
|
|
(0, tiny_invariant_1.default)(parent.body === child);
|
|
return true;
|
|
}
|
|
// s[i + 1] and s[i + 2] represent the array between the parent
|
|
// SequenceExpression node and its child nodes
|
|
if (n.SequenceExpression.check(parent) &&
|
|
s[i + 1] === "expressions" &&
|
|
childName === 0) {
|
|
(0, tiny_invariant_1.default)(parent.expressions[0] === child);
|
|
continue;
|
|
}
|
|
if (n.CallExpression.check(parent) && childName === "callee") {
|
|
(0, tiny_invariant_1.default)(parent.callee === child);
|
|
continue;
|
|
}
|
|
if (n.MemberExpression.check(parent) && childName === "object") {
|
|
(0, tiny_invariant_1.default)(parent.object === child);
|
|
continue;
|
|
}
|
|
if (n.ConditionalExpression.check(parent) && childName === "test") {
|
|
(0, tiny_invariant_1.default)(parent.test === child);
|
|
continue;
|
|
}
|
|
if (isBinary(parent) && childName === "left") {
|
|
(0, tiny_invariant_1.default)(parent.left === child);
|
|
continue;
|
|
}
|
|
if (n.UnaryExpression.check(parent) &&
|
|
!parent.prefix &&
|
|
childName === "argument") {
|
|
(0, tiny_invariant_1.default)(parent.argument === child);
|
|
continue;
|
|
}
|
|
return false;
|
|
}
|
|
return true;
|
|
};
|
|
fastPath.default = FastPath;
|
|
return fastPath;
|
|
}
|
|
|
|
var patcher = {};
|
|
|
|
var hasRequiredPatcher;
|
|
|
|
function requirePatcher () {
|
|
if (hasRequiredPatcher) return patcher;
|
|
hasRequiredPatcher = 1;
|
|
Object.defineProperty(patcher, "__esModule", { value: true });
|
|
patcher.getReprinter = patcher.Patcher = void 0;
|
|
var tslib_1 = require$$0;
|
|
var tiny_invariant_1 = tslib_1.__importDefault(/*@__PURE__*/ requireTinyInvariant_cjs());
|
|
var linesModule = tslib_1.__importStar(requireLines());
|
|
var types = tslib_1.__importStar(requireMain$1());
|
|
var Printable = types.namedTypes.Printable;
|
|
var Expression = types.namedTypes.Expression;
|
|
var ReturnStatement = types.namedTypes.ReturnStatement;
|
|
var SourceLocation = types.namedTypes.SourceLocation;
|
|
var util_1 = requireUtil();
|
|
var fast_path_1 = tslib_1.__importDefault(requireFastPath());
|
|
var isObject = types.builtInTypes.object;
|
|
var isArray = types.builtInTypes.array;
|
|
var isString = types.builtInTypes.string;
|
|
var riskyAdjoiningCharExp = /[0-9a-z_$]/i;
|
|
var Patcher = function Patcher(lines) {
|
|
(0, tiny_invariant_1.default)(this instanceof Patcher);
|
|
(0, tiny_invariant_1.default)(lines instanceof linesModule.Lines);
|
|
var self = this, replacements = [];
|
|
self.replace = function (loc, lines) {
|
|
if (isString.check(lines))
|
|
lines = linesModule.fromString(lines);
|
|
replacements.push({
|
|
lines: lines,
|
|
start: loc.start,
|
|
end: loc.end,
|
|
});
|
|
};
|
|
self.get = function (loc) {
|
|
// If no location is provided, return the complete Lines object.
|
|
loc = loc || {
|
|
start: { line: 1, column: 0 },
|
|
end: { line: lines.length, column: lines.getLineLength(lines.length) },
|
|
};
|
|
var sliceFrom = loc.start, toConcat = [];
|
|
function pushSlice(from, to) {
|
|
(0, tiny_invariant_1.default)((0, util_1.comparePos)(from, to) <= 0);
|
|
toConcat.push(lines.slice(from, to));
|
|
}
|
|
replacements
|
|
.sort(function (a, b) { return (0, util_1.comparePos)(a.start, b.start); })
|
|
.forEach(function (rep) {
|
|
if ((0, util_1.comparePos)(sliceFrom, rep.start) > 0) ;
|
|
else {
|
|
pushSlice(sliceFrom, rep.start);
|
|
toConcat.push(rep.lines);
|
|
sliceFrom = rep.end;
|
|
}
|
|
});
|
|
pushSlice(sliceFrom, loc.end);
|
|
return linesModule.concat(toConcat);
|
|
};
|
|
};
|
|
patcher.Patcher = Patcher;
|
|
var Pp = Patcher.prototype;
|
|
Pp.tryToReprintComments = function (newNode, oldNode, print) {
|
|
var patcher = this;
|
|
if (!newNode.comments && !oldNode.comments) {
|
|
// We were (vacuously) able to reprint all the comments!
|
|
return true;
|
|
}
|
|
var newPath = fast_path_1.default.from(newNode);
|
|
var oldPath = fast_path_1.default.from(oldNode);
|
|
newPath.stack.push("comments", getSurroundingComments(newNode));
|
|
oldPath.stack.push("comments", getSurroundingComments(oldNode));
|
|
var reprints = [];
|
|
var ableToReprintComments = findArrayReprints(newPath, oldPath, reprints);
|
|
// No need to pop anything from newPath.stack or oldPath.stack, since
|
|
// newPath and oldPath are fresh local variables.
|
|
if (ableToReprintComments && reprints.length > 0) {
|
|
reprints.forEach(function (reprint) {
|
|
var oldComment = reprint.oldPath.getValue();
|
|
(0, tiny_invariant_1.default)(oldComment.leading || oldComment.trailing);
|
|
patcher.replace(oldComment.loc,
|
|
// Comments can't have .comments, so it doesn't matter whether we
|
|
// print with comments or without.
|
|
print(reprint.newPath).indentTail(oldComment.loc.indent));
|
|
});
|
|
}
|
|
return ableToReprintComments;
|
|
};
|
|
// Get all comments that are either leading or trailing, ignoring any
|
|
// comments that occur inside node.loc. Returns an empty array for nodes
|
|
// with no leading or trailing comments.
|
|
function getSurroundingComments(node) {
|
|
var result = [];
|
|
if (node.comments && node.comments.length > 0) {
|
|
node.comments.forEach(function (comment) {
|
|
if (comment.leading || comment.trailing) {
|
|
result.push(comment);
|
|
}
|
|
});
|
|
}
|
|
return result;
|
|
}
|
|
Pp.deleteComments = function (node) {
|
|
if (!node.comments) {
|
|
return;
|
|
}
|
|
var patcher = this;
|
|
node.comments.forEach(function (comment) {
|
|
if (comment.leading) {
|
|
// Delete leading comments along with any trailing whitespace they
|
|
// might have.
|
|
patcher.replace({
|
|
start: comment.loc.start,
|
|
end: node.loc.lines.skipSpaces(comment.loc.end, false, false),
|
|
}, "");
|
|
}
|
|
else if (comment.trailing) {
|
|
// Delete trailing comments along with any leading whitespace they
|
|
// might have.
|
|
patcher.replace({
|
|
start: node.loc.lines.skipSpaces(comment.loc.start, true, false),
|
|
end: comment.loc.end,
|
|
}, "");
|
|
}
|
|
});
|
|
};
|
|
function getReprinter(path) {
|
|
(0, tiny_invariant_1.default)(path instanceof fast_path_1.default);
|
|
// Make sure that this path refers specifically to a Node, rather than
|
|
// some non-Node subproperty of a Node.
|
|
var node = path.getValue();
|
|
if (!Printable.check(node))
|
|
return;
|
|
var orig = node.original;
|
|
var origLoc = orig && orig.loc;
|
|
var lines = origLoc && origLoc.lines;
|
|
var reprints = [];
|
|
if (!lines || !findReprints(path, reprints))
|
|
return;
|
|
return function (print) {
|
|
var patcher = new Patcher(lines);
|
|
reprints.forEach(function (reprint) {
|
|
var newNode = reprint.newPath.getValue();
|
|
var oldNode = reprint.oldPath.getValue();
|
|
SourceLocation.assert(oldNode.loc, true);
|
|
var needToPrintNewPathWithComments = !patcher.tryToReprintComments(newNode, oldNode, print);
|
|
if (needToPrintNewPathWithComments) {
|
|
// Since we were not able to preserve all leading/trailing
|
|
// comments, we delete oldNode's comments, print newPath with
|
|
// comments, and then patch the resulting lines where oldNode used
|
|
// to be.
|
|
patcher.deleteComments(oldNode);
|
|
}
|
|
var newLines = print(reprint.newPath, {
|
|
includeComments: needToPrintNewPathWithComments,
|
|
// If the oldNode we're replacing already had parentheses, we may
|
|
// not need to print the new node with any extra parentheses,
|
|
// because the existing parentheses will suffice. However, if the
|
|
// newNode has a different type than the oldNode, let the printer
|
|
// decide if reprint.newPath needs parentheses, as usual.
|
|
avoidRootParens: oldNode.type === newNode.type && reprint.oldPath.hasParens(),
|
|
}).indentTail(oldNode.loc.indent);
|
|
var nls = needsLeadingSpace(lines, oldNode.loc, newLines);
|
|
var nts = needsTrailingSpace(lines, oldNode.loc, newLines);
|
|
// If we try to replace the argument of a ReturnStatement like
|
|
// return"asdf" with e.g. a literal null expression, we run the risk
|
|
// of ending up with returnnull, so we need to add an extra leading
|
|
// space in situations where that might happen. Likewise for
|
|
// "asdf"in obj. See #170.
|
|
if (nls || nts) {
|
|
var newParts = [];
|
|
nls && newParts.push(" ");
|
|
newParts.push(newLines);
|
|
nts && newParts.push(" ");
|
|
newLines = linesModule.concat(newParts);
|
|
}
|
|
patcher.replace(oldNode.loc, newLines);
|
|
});
|
|
// Recall that origLoc is the .loc of an ancestor node that is
|
|
// guaranteed to contain all the reprinted nodes and comments.
|
|
var patchedLines = patcher.get(origLoc).indentTail(-orig.loc.indent);
|
|
if (path.needsParens()) {
|
|
return linesModule.concat(["(", patchedLines, ")"]);
|
|
}
|
|
return patchedLines;
|
|
};
|
|
}
|
|
patcher.getReprinter = getReprinter;
|
|
// If the last character before oldLoc and the first character of newLines
|
|
// are both identifier characters, they must be separated by a space,
|
|
// otherwise they will most likely get fused together into a single token.
|
|
function needsLeadingSpace(oldLines, oldLoc, newLines) {
|
|
var posBeforeOldLoc = (0, util_1.copyPos)(oldLoc.start);
|
|
// The character just before the location occupied by oldNode.
|
|
var charBeforeOldLoc = oldLines.prevPos(posBeforeOldLoc) && oldLines.charAt(posBeforeOldLoc);
|
|
// First character of the reprinted node.
|
|
var newFirstChar = newLines.charAt(newLines.firstPos());
|
|
return (charBeforeOldLoc &&
|
|
riskyAdjoiningCharExp.test(charBeforeOldLoc) &&
|
|
newFirstChar &&
|
|
riskyAdjoiningCharExp.test(newFirstChar));
|
|
}
|
|
// If the last character of newLines and the first character after oldLoc
|
|
// are both identifier characters, they must be separated by a space,
|
|
// otherwise they will most likely get fused together into a single token.
|
|
function needsTrailingSpace(oldLines, oldLoc, newLines) {
|
|
// The character just after the location occupied by oldNode.
|
|
var charAfterOldLoc = oldLines.charAt(oldLoc.end);
|
|
var newLastPos = newLines.lastPos();
|
|
// Last character of the reprinted node.
|
|
var newLastChar = newLines.prevPos(newLastPos) && newLines.charAt(newLastPos);
|
|
return (newLastChar &&
|
|
riskyAdjoiningCharExp.test(newLastChar) &&
|
|
charAfterOldLoc &&
|
|
riskyAdjoiningCharExp.test(charAfterOldLoc));
|
|
}
|
|
function findReprints(newPath, reprints) {
|
|
var newNode = newPath.getValue();
|
|
Printable.assert(newNode);
|
|
var oldNode = newNode.original;
|
|
Printable.assert(oldNode);
|
|
(0, tiny_invariant_1.default)(reprints.length === 0);
|
|
if (newNode.type !== oldNode.type) {
|
|
return false;
|
|
}
|
|
var oldPath = new fast_path_1.default(oldNode);
|
|
var canReprint = findChildReprints(newPath, oldPath, reprints);
|
|
if (!canReprint) {
|
|
// Make absolutely sure the calling code does not attempt to reprint
|
|
// any nodes.
|
|
reprints.length = 0;
|
|
}
|
|
return canReprint;
|
|
}
|
|
function findAnyReprints(newPath, oldPath, reprints) {
|
|
var newNode = newPath.getValue();
|
|
var oldNode = oldPath.getValue();
|
|
if (newNode === oldNode)
|
|
return true;
|
|
if (isArray.check(newNode))
|
|
return findArrayReprints(newPath, oldPath, reprints);
|
|
if (isObject.check(newNode))
|
|
return findObjectReprints(newPath, oldPath, reprints);
|
|
return false;
|
|
}
|
|
function findArrayReprints(newPath, oldPath, reprints) {
|
|
var newNode = newPath.getValue();
|
|
var oldNode = oldPath.getValue();
|
|
if (newNode === oldNode ||
|
|
newPath.valueIsDuplicate() ||
|
|
oldPath.valueIsDuplicate()) {
|
|
return true;
|
|
}
|
|
isArray.assert(newNode);
|
|
var len = newNode.length;
|
|
if (!(isArray.check(oldNode) && oldNode.length === len))
|
|
return false;
|
|
for (var i = 0; i < len; ++i) {
|
|
newPath.stack.push(i, newNode[i]);
|
|
oldPath.stack.push(i, oldNode[i]);
|
|
var canReprint = findAnyReprints(newPath, oldPath, reprints);
|
|
newPath.stack.length -= 2;
|
|
oldPath.stack.length -= 2;
|
|
if (!canReprint) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
function findObjectReprints(newPath, oldPath, reprints) {
|
|
var newNode = newPath.getValue();
|
|
isObject.assert(newNode);
|
|
if (newNode.original === null) {
|
|
// If newNode.original node was set to null, reprint the node.
|
|
return false;
|
|
}
|
|
var oldNode = oldPath.getValue();
|
|
if (!isObject.check(oldNode))
|
|
return false;
|
|
if (newNode === oldNode ||
|
|
newPath.valueIsDuplicate() ||
|
|
oldPath.valueIsDuplicate()) {
|
|
return true;
|
|
}
|
|
if (Printable.check(newNode)) {
|
|
if (!Printable.check(oldNode)) {
|
|
return false;
|
|
}
|
|
var newParentNode = newPath.getParentNode();
|
|
var oldParentNode = oldPath.getParentNode();
|
|
if (oldParentNode !== null &&
|
|
oldParentNode.type === "FunctionTypeAnnotation" &&
|
|
newParentNode !== null &&
|
|
newParentNode.type === "FunctionTypeAnnotation") {
|
|
var oldNeedsParens = oldParentNode.params.length !== 1 || !!oldParentNode.params[0].name;
|
|
var newNeedParens = newParentNode.params.length !== 1 || !!newParentNode.params[0].name;
|
|
if (!oldNeedsParens && newNeedParens) {
|
|
return false;
|
|
}
|
|
}
|
|
// Here we need to decide whether the reprinted code for newNode is
|
|
// appropriate for patching into the location of oldNode.
|
|
if (newNode.type === oldNode.type) {
|
|
var childReprints = [];
|
|
if (findChildReprints(newPath, oldPath, childReprints)) {
|
|
reprints.push.apply(reprints, childReprints);
|
|
}
|
|
else if (oldNode.loc) {
|
|
// If we have no .loc information for oldNode, then we won't be
|
|
// able to reprint it.
|
|
reprints.push({
|
|
oldPath: oldPath.copy(),
|
|
newPath: newPath.copy(),
|
|
});
|
|
}
|
|
else {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
if (Expression.check(newNode) &&
|
|
Expression.check(oldNode) &&
|
|
// If we have no .loc information for oldNode, then we won't be
|
|
// able to reprint it.
|
|
oldNode.loc) {
|
|
// If both nodes are subtypes of Expression, then we should be able
|
|
// to fill the location occupied by the old node with code printed
|
|
// for the new node with no ill consequences.
|
|
reprints.push({
|
|
oldPath: oldPath.copy(),
|
|
newPath: newPath.copy(),
|
|
});
|
|
return true;
|
|
}
|
|
// The nodes have different types, and at least one of the types is
|
|
// not a subtype of the Expression type, so we cannot safely assume
|
|
// the nodes are syntactically interchangeable.
|
|
return false;
|
|
}
|
|
return findChildReprints(newPath, oldPath, reprints);
|
|
}
|
|
function findChildReprints(newPath, oldPath, reprints) {
|
|
var newNode = newPath.getValue();
|
|
var oldNode = oldPath.getValue();
|
|
isObject.assert(newNode);
|
|
isObject.assert(oldNode);
|
|
if (newNode.original === null) {
|
|
// If newNode.original node was set to null, reprint the node.
|
|
return false;
|
|
}
|
|
// If this node needs parentheses and will not be wrapped with
|
|
// parentheses when reprinted, then return false to skip reprinting and
|
|
// let it be printed generically.
|
|
if (newPath.needsParens() && !oldPath.hasParens()) {
|
|
return false;
|
|
}
|
|
var keys = (0, util_1.getUnionOfKeys)(oldNode, newNode);
|
|
if (oldNode.type === "File" || newNode.type === "File") {
|
|
// Don't bother traversing file.tokens, an often very large array
|
|
// returned by Babylon, and useless for our purposes.
|
|
delete keys.tokens;
|
|
}
|
|
// Don't bother traversing .loc objects looking for reprintable nodes.
|
|
delete keys.loc;
|
|
var originalReprintCount = reprints.length;
|
|
for (var k in keys) {
|
|
if (k.charAt(0) === "_") {
|
|
// Ignore "private" AST properties added by e.g. Babel plugins and
|
|
// parsers like Babylon.
|
|
continue;
|
|
}
|
|
newPath.stack.push(k, types.getFieldValue(newNode, k));
|
|
oldPath.stack.push(k, types.getFieldValue(oldNode, k));
|
|
var canReprint = findAnyReprints(newPath, oldPath, reprints);
|
|
newPath.stack.length -= 2;
|
|
oldPath.stack.length -= 2;
|
|
if (!canReprint) {
|
|
return false;
|
|
}
|
|
}
|
|
// Return statements might end up running into ASI issues due to
|
|
// comments inserted deep within the tree, so reprint them if anything
|
|
// changed within them.
|
|
if (ReturnStatement.check(newPath.getNode()) &&
|
|
reprints.length > originalReprintCount) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
return patcher;
|
|
}
|
|
|
|
var hasRequiredPrinter;
|
|
|
|
function requirePrinter () {
|
|
if (hasRequiredPrinter) return printer;
|
|
hasRequiredPrinter = 1;
|
|
Object.defineProperty(printer, "__esModule", { value: true });
|
|
printer.Printer = void 0;
|
|
var tslib_1 = require$$0;
|
|
var tiny_invariant_1 = tslib_1.__importDefault(/*@__PURE__*/ requireTinyInvariant_cjs());
|
|
var types = tslib_1.__importStar(requireMain$1());
|
|
var comments_1 = requireComments();
|
|
var fast_path_1 = tslib_1.__importDefault(requireFastPath());
|
|
var lines_1 = requireLines();
|
|
var options_1 = requireOptions();
|
|
var patcher_1 = requirePatcher();
|
|
var util = tslib_1.__importStar(requireUtil());
|
|
var namedTypes = types.namedTypes;
|
|
var isString = types.builtInTypes.string;
|
|
var isObject = types.builtInTypes.object;
|
|
var PrintResult = function PrintResult(code, sourceMap) {
|
|
(0, tiny_invariant_1.default)(this instanceof PrintResult);
|
|
isString.assert(code);
|
|
this.code = code;
|
|
if (sourceMap) {
|
|
isObject.assert(sourceMap);
|
|
this.map = sourceMap;
|
|
}
|
|
};
|
|
var PRp = PrintResult.prototype;
|
|
var warnedAboutToString = false;
|
|
PRp.toString = function () {
|
|
if (!warnedAboutToString) {
|
|
console.warn("Deprecation warning: recast.print now returns an object with " +
|
|
"a .code property. You appear to be treating the object as a " +
|
|
"string, which might still work but is strongly discouraged.");
|
|
warnedAboutToString = true;
|
|
}
|
|
return this.code;
|
|
};
|
|
var emptyPrintResult = new PrintResult("");
|
|
var Printer = function Printer(config) {
|
|
(0, tiny_invariant_1.default)(this instanceof Printer);
|
|
var explicitTabWidth = config && config.tabWidth;
|
|
config = (0, options_1.normalize)(config);
|
|
// It's common for client code to pass the same options into both
|
|
// recast.parse and recast.print, but the Printer doesn't need (and
|
|
// can be confused by) config.sourceFileName, so we null it out.
|
|
config.sourceFileName = null;
|
|
// Non-destructively modifies options with overrides, and returns a
|
|
// new print function that uses the modified options.
|
|
function makePrintFunctionWith(options, overrides) {
|
|
options = Object.assign({}, options, overrides);
|
|
return function (path) { return print(path, options); };
|
|
}
|
|
function print(path, options) {
|
|
(0, tiny_invariant_1.default)(path instanceof fast_path_1.default);
|
|
options = options || {};
|
|
if (options.includeComments) {
|
|
return (0, comments_1.printComments)(path, makePrintFunctionWith(options, {
|
|
includeComments: false,
|
|
}));
|
|
}
|
|
var oldTabWidth = config.tabWidth;
|
|
if (!explicitTabWidth) {
|
|
var loc = path.getNode().loc;
|
|
if (loc && loc.lines && loc.lines.guessTabWidth) {
|
|
config.tabWidth = loc.lines.guessTabWidth();
|
|
}
|
|
}
|
|
var reprinter = (0, patcher_1.getReprinter)(path);
|
|
var lines = reprinter
|
|
? // Since the print function that we pass to the reprinter will
|
|
// be used to print "new" nodes, it's tempting to think we
|
|
// should pass printRootGenerically instead of print, to avoid
|
|
// calling maybeReprint again, but that would be a mistake
|
|
// because the new nodes might not be entirely new, but merely
|
|
// moved from elsewhere in the AST. The print function is the
|
|
// right choice because it gives us the opportunity to reprint
|
|
// such nodes using their original source.
|
|
reprinter(print)
|
|
: genericPrint(path, config, options, makePrintFunctionWith(options, {
|
|
includeComments: true,
|
|
avoidRootParens: false,
|
|
}));
|
|
config.tabWidth = oldTabWidth;
|
|
return lines;
|
|
}
|
|
this.print = function (ast) {
|
|
if (!ast) {
|
|
return emptyPrintResult;
|
|
}
|
|
var lines = print(fast_path_1.default.from(ast), {
|
|
includeComments: true,
|
|
avoidRootParens: false,
|
|
});
|
|
return new PrintResult(lines.toString(config), util.composeSourceMaps(config.inputSourceMap, lines.getSourceMap(config.sourceMapName, config.sourceRoot)));
|
|
};
|
|
this.printGenerically = function (ast) {
|
|
if (!ast) {
|
|
return emptyPrintResult;
|
|
}
|
|
// Print the entire AST generically.
|
|
function printGenerically(path) {
|
|
return (0, comments_1.printComments)(path, function (path) {
|
|
return genericPrint(path, config, {
|
|
avoidRootParens: false,
|
|
}, printGenerically);
|
|
});
|
|
}
|
|
var path = fast_path_1.default.from(ast);
|
|
var oldReuseWhitespace = config.reuseWhitespace;
|
|
// Do not reuse whitespace (or anything else, for that matter)
|
|
// when printing generically.
|
|
config.reuseWhitespace = false;
|
|
// TODO Allow printing of comments?
|
|
var pr = new PrintResult(printGenerically(path).toString(config));
|
|
config.reuseWhitespace = oldReuseWhitespace;
|
|
return pr;
|
|
};
|
|
};
|
|
printer.Printer = Printer;
|
|
function genericPrint(path, config, options, printPath) {
|
|
(0, tiny_invariant_1.default)(path instanceof fast_path_1.default);
|
|
var node = path.getValue();
|
|
var parts = [];
|
|
var linesWithoutParens = genericPrintNoParens(path, config, printPath);
|
|
if (!node || linesWithoutParens.isEmpty()) {
|
|
return linesWithoutParens;
|
|
}
|
|
var shouldAddParens = false;
|
|
var decoratorsLines = printDecorators(path, printPath);
|
|
if (decoratorsLines.isEmpty()) {
|
|
// Nodes with decorators can't have parentheses, so we can avoid
|
|
// computing path.needsParens() except in this case.
|
|
if (!options.avoidRootParens) {
|
|
shouldAddParens = path.needsParens();
|
|
}
|
|
}
|
|
else {
|
|
parts.push(decoratorsLines);
|
|
}
|
|
if (shouldAddParens) {
|
|
parts.unshift("(");
|
|
}
|
|
parts.push(linesWithoutParens);
|
|
if (shouldAddParens) {
|
|
parts.push(")");
|
|
}
|
|
return (0, lines_1.concat)(parts);
|
|
}
|
|
// Note that the `options` parameter of this function is what other
|
|
// functions in this file call the `config` object (that is, the
|
|
// configuration object originally passed into the Printer constructor).
|
|
// Its properties are documented in lib/options.js.
|
|
function genericPrintNoParens(path, options, print) {
|
|
var _a, _b, _c;
|
|
var n = path.getValue();
|
|
if (!n) {
|
|
return (0, lines_1.fromString)("");
|
|
}
|
|
if (typeof n === "string") {
|
|
return (0, lines_1.fromString)(n, options);
|
|
}
|
|
namedTypes.Printable.assert(n);
|
|
var parts = [];
|
|
switch (n.type) {
|
|
case "File":
|
|
return path.call(print, "program");
|
|
case "Program":
|
|
// Babel 6
|
|
if (n.directives) {
|
|
path.each(function (childPath) {
|
|
parts.push(print(childPath), ";\n");
|
|
}, "directives");
|
|
}
|
|
if (n.interpreter) {
|
|
parts.push(path.call(print, "interpreter"));
|
|
}
|
|
parts.push(path.call(function (bodyPath) { return printStatementSequence(bodyPath, options, print); }, "body"));
|
|
return (0, lines_1.concat)(parts);
|
|
case "Noop": // Babel extension.
|
|
case "EmptyStatement":
|
|
return (0, lines_1.fromString)("");
|
|
case "ExpressionStatement":
|
|
return (0, lines_1.concat)([path.call(print, "expression"), ";"]);
|
|
case "ParenthesizedExpression": // Babel extension.
|
|
return (0, lines_1.concat)(["(", path.call(print, "expression"), ")"]);
|
|
case "BinaryExpression":
|
|
case "LogicalExpression":
|
|
case "AssignmentExpression":
|
|
return (0, lines_1.fromString)(" ").join([
|
|
path.call(print, "left"),
|
|
n.operator,
|
|
path.call(print, "right"),
|
|
]);
|
|
case "AssignmentPattern":
|
|
return (0, lines_1.concat)([
|
|
path.call(print, "left"),
|
|
" = ",
|
|
path.call(print, "right"),
|
|
]);
|
|
case "MemberExpression":
|
|
case "OptionalMemberExpression": {
|
|
parts.push(path.call(print, "object"));
|
|
var property = path.call(print, "property");
|
|
// Like n.optional, except with defaults applied, so optional
|
|
// defaults to true for OptionalMemberExpression nodes.
|
|
var optional = types.getFieldValue(n, "optional");
|
|
if (n.computed) {
|
|
parts.push(optional ? "?.[" : "[", property, "]");
|
|
}
|
|
else {
|
|
parts.push(optional ? "?." : ".", property);
|
|
}
|
|
return (0, lines_1.concat)(parts);
|
|
}
|
|
case "ChainExpression":
|
|
return path.call(print, "expression");
|
|
case "MetaProperty":
|
|
return (0, lines_1.concat)([
|
|
path.call(print, "meta"),
|
|
".",
|
|
path.call(print, "property"),
|
|
]);
|
|
case "BindExpression":
|
|
if (n.object) {
|
|
parts.push(path.call(print, "object"));
|
|
}
|
|
parts.push("::", path.call(print, "callee"));
|
|
return (0, lines_1.concat)(parts);
|
|
case "Path":
|
|
return (0, lines_1.fromString)(".").join(n.body);
|
|
case "Identifier":
|
|
return (0, lines_1.concat)([
|
|
(0, lines_1.fromString)(n.name, options),
|
|
n.optional ? "?" : "",
|
|
path.call(print, "typeAnnotation"),
|
|
]);
|
|
case "SpreadElement":
|
|
case "SpreadElementPattern":
|
|
case "RestProperty": // Babel 6 for ObjectPattern
|
|
case "SpreadProperty":
|
|
case "SpreadPropertyPattern":
|
|
case "ObjectTypeSpreadProperty":
|
|
case "RestElement":
|
|
return (0, lines_1.concat)([
|
|
"...",
|
|
path.call(print, "argument"),
|
|
path.call(print, "typeAnnotation"),
|
|
]);
|
|
case "FunctionDeclaration":
|
|
case "FunctionExpression":
|
|
case "TSDeclareFunction":
|
|
if (n.declare) {
|
|
parts.push("declare ");
|
|
}
|
|
if (n.async) {
|
|
parts.push("async ");
|
|
}
|
|
parts.push("function");
|
|
if (n.generator)
|
|
parts.push("*");
|
|
if (n.id) {
|
|
parts.push(" ", path.call(print, "id"), path.call(print, "typeParameters"));
|
|
}
|
|
else {
|
|
if (n.typeParameters) {
|
|
parts.push(path.call(print, "typeParameters"));
|
|
}
|
|
}
|
|
parts.push("(", printFunctionParams(path, options, print), ")", path.call(print, "returnType"));
|
|
if (n.body) {
|
|
parts.push(" ", path.call(print, "body"));
|
|
}
|
|
return (0, lines_1.concat)(parts);
|
|
case "ArrowFunctionExpression":
|
|
if (n.async) {
|
|
parts.push("async ");
|
|
}
|
|
if (n.typeParameters) {
|
|
parts.push(path.call(print, "typeParameters"));
|
|
}
|
|
if (!options.arrowParensAlways &&
|
|
n.params.length === 1 &&
|
|
!n.rest &&
|
|
n.params[0].type === "Identifier" &&
|
|
!n.params[0].typeAnnotation &&
|
|
!n.returnType) {
|
|
parts.push(path.call(print, "params", 0));
|
|
}
|
|
else {
|
|
parts.push("(", printFunctionParams(path, options, print), ")", path.call(print, "returnType"));
|
|
}
|
|
parts.push(" => ", path.call(print, "body"));
|
|
return (0, lines_1.concat)(parts);
|
|
case "MethodDefinition":
|
|
return printMethod(path, options, print);
|
|
case "YieldExpression":
|
|
parts.push("yield");
|
|
if (n.delegate)
|
|
parts.push("*");
|
|
if (n.argument)
|
|
parts.push(" ", path.call(print, "argument"));
|
|
return (0, lines_1.concat)(parts);
|
|
case "AwaitExpression":
|
|
parts.push("await");
|
|
if (n.all)
|
|
parts.push("*");
|
|
if (n.argument)
|
|
parts.push(" ", path.call(print, "argument"));
|
|
return (0, lines_1.concat)(parts);
|
|
case "ModuleExpression":
|
|
return (0, lines_1.concat)([
|
|
"module {\n",
|
|
path.call(print, "body").indent(options.tabWidth),
|
|
"\n}",
|
|
]);
|
|
case "ModuleDeclaration":
|
|
parts.push("module", path.call(print, "id"));
|
|
if (n.source) {
|
|
(0, tiny_invariant_1.default)(!n.body);
|
|
parts.push("from", path.call(print, "source"));
|
|
}
|
|
else {
|
|
parts.push(path.call(print, "body"));
|
|
}
|
|
return (0, lines_1.fromString)(" ").join(parts);
|
|
case "ImportSpecifier":
|
|
if (n.importKind && n.importKind !== "value") {
|
|
parts.push(n.importKind + " ");
|
|
}
|
|
if (n.imported) {
|
|
parts.push(path.call(print, "imported"));
|
|
if (n.local && n.local.name !== n.imported.name) {
|
|
parts.push(" as ", path.call(print, "local"));
|
|
}
|
|
}
|
|
else if (n.id) {
|
|
parts.push(path.call(print, "id"));
|
|
if (n.name) {
|
|
parts.push(" as ", path.call(print, "name"));
|
|
}
|
|
}
|
|
return (0, lines_1.concat)(parts);
|
|
case "ExportSpecifier":
|
|
if (n.exportKind && n.exportKind !== "value") {
|
|
parts.push(n.exportKind + " ");
|
|
}
|
|
if (n.local) {
|
|
parts.push(path.call(print, "local"));
|
|
if (n.exported && n.exported.name !== n.local.name) {
|
|
parts.push(" as ", path.call(print, "exported"));
|
|
}
|
|
}
|
|
else if (n.id) {
|
|
parts.push(path.call(print, "id"));
|
|
if (n.name) {
|
|
parts.push(" as ", path.call(print, "name"));
|
|
}
|
|
}
|
|
return (0, lines_1.concat)(parts);
|
|
case "ExportBatchSpecifier":
|
|
return (0, lines_1.fromString)("*");
|
|
case "ImportNamespaceSpecifier":
|
|
parts.push("* as ");
|
|
if (n.local) {
|
|
parts.push(path.call(print, "local"));
|
|
}
|
|
else if (n.id) {
|
|
parts.push(path.call(print, "id"));
|
|
}
|
|
return (0, lines_1.concat)(parts);
|
|
case "ImportDefaultSpecifier":
|
|
if (n.local) {
|
|
return path.call(print, "local");
|
|
}
|
|
return path.call(print, "id");
|
|
case "TSExportAssignment":
|
|
return (0, lines_1.concat)(["export = ", path.call(print, "expression")]);
|
|
case "ExportDeclaration":
|
|
case "ExportDefaultDeclaration":
|
|
case "ExportNamedDeclaration":
|
|
return printExportDeclaration(path, options, print);
|
|
case "ExportAllDeclaration":
|
|
parts.push("export *");
|
|
if (n.exported) {
|
|
parts.push(" as ", path.call(print, "exported"));
|
|
}
|
|
parts.push(" from ", path.call(print, "source"), ";");
|
|
return (0, lines_1.concat)(parts);
|
|
case "TSNamespaceExportDeclaration":
|
|
parts.push("export as namespace ", path.call(print, "id"));
|
|
return maybeAddSemicolon((0, lines_1.concat)(parts));
|
|
case "ExportNamespaceSpecifier":
|
|
return (0, lines_1.concat)(["* as ", path.call(print, "exported")]);
|
|
case "ExportDefaultSpecifier":
|
|
return path.call(print, "exported");
|
|
case "Import":
|
|
return (0, lines_1.fromString)("import", options);
|
|
// Recast and ast-types currently support dynamic import(...) using
|
|
// either this dedicated ImportExpression type or a CallExpression
|
|
// whose callee has type Import.
|
|
// https://github.com/benjamn/ast-types/pull/365#issuecomment-605214486
|
|
case "ImportExpression":
|
|
return (0, lines_1.concat)(["import(", path.call(print, "source"), ")"]);
|
|
case "ImportDeclaration": {
|
|
parts.push("import ");
|
|
if (n.importKind && n.importKind !== "value") {
|
|
parts.push(n.importKind + " ");
|
|
}
|
|
if (n.specifiers && n.specifiers.length > 0) {
|
|
var unbracedSpecifiers_1 = [];
|
|
var bracedSpecifiers_1 = [];
|
|
path.each(function (specifierPath) {
|
|
var spec = specifierPath.getValue();
|
|
if (spec.type === "ImportSpecifier") {
|
|
bracedSpecifiers_1.push(print(specifierPath));
|
|
}
|
|
else if (spec.type === "ImportDefaultSpecifier" ||
|
|
spec.type === "ImportNamespaceSpecifier") {
|
|
unbracedSpecifiers_1.push(print(specifierPath));
|
|
}
|
|
}, "specifiers");
|
|
unbracedSpecifiers_1.forEach(function (lines, i) {
|
|
if (i > 0) {
|
|
parts.push(", ");
|
|
}
|
|
parts.push(lines);
|
|
});
|
|
if (bracedSpecifiers_1.length > 0) {
|
|
var lines = (0, lines_1.fromString)(", ").join(bracedSpecifiers_1);
|
|
if (lines.getLineLength(1) > options.wrapColumn) {
|
|
lines = (0, lines_1.concat)([
|
|
(0, lines_1.fromString)(",\n").join(bracedSpecifiers_1).indent(options.tabWidth),
|
|
",",
|
|
]);
|
|
}
|
|
if (unbracedSpecifiers_1.length > 0) {
|
|
parts.push(", ");
|
|
}
|
|
if (lines.length > 1) {
|
|
parts.push("{\n", lines, "\n}");
|
|
}
|
|
else if (options.objectCurlySpacing) {
|
|
parts.push("{ ", lines, " }");
|
|
}
|
|
else {
|
|
parts.push("{", lines, "}");
|
|
}
|
|
}
|
|
parts.push(" from ");
|
|
}
|
|
parts.push(path.call(print, "source"), maybePrintImportAssertions(path, options, print), ";");
|
|
return (0, lines_1.concat)(parts);
|
|
}
|
|
case "ImportAttribute":
|
|
return (0, lines_1.concat)([path.call(print, "key"), ": ", path.call(print, "value")]);
|
|
case "StaticBlock":
|
|
parts.push("static ");
|
|
// Intentionally fall through to BlockStatement below.
|
|
case "BlockStatement": {
|
|
var naked_1 = path.call(function (bodyPath) { return printStatementSequence(bodyPath, options, print); }, "body");
|
|
if (naked_1.isEmpty()) {
|
|
if (!n.directives || n.directives.length === 0) {
|
|
parts.push("{}");
|
|
return (0, lines_1.concat)(parts);
|
|
}
|
|
}
|
|
parts.push("{\n");
|
|
// Babel 6
|
|
if (n.directives) {
|
|
path.each(function (childPath) {
|
|
parts.push(maybeAddSemicolon(print(childPath).indent(options.tabWidth)), n.directives.length > 1 || !naked_1.isEmpty() ? "\n" : "");
|
|
}, "directives");
|
|
}
|
|
parts.push(naked_1.indent(options.tabWidth));
|
|
parts.push("\n}");
|
|
return (0, lines_1.concat)(parts);
|
|
}
|
|
case "ReturnStatement": {
|
|
parts.push("return");
|
|
if (n.argument) {
|
|
var argIsJsxElement = ((_a = namedTypes.JSXElement) === null || _a === void 0 ? void 0 : _a.check(n.argument)) ||
|
|
((_b = namedTypes.JSXFragment) === null || _b === void 0 ? void 0 : _b.check(n.argument));
|
|
var argLines = path.call(print, "argument");
|
|
if (argLines.startsWithComment() ||
|
|
(argLines.length > 1 && argIsJsxElement)) {
|
|
// Babel: regenerate parenthesized jsxElements so we don't double parentheses
|
|
if (argIsJsxElement && ((_c = n.argument.extra) === null || _c === void 0 ? void 0 : _c.parenthesized)) {
|
|
n.argument.extra.parenthesized = false;
|
|
argLines = path.call(print, "argument");
|
|
n.argument.extra.parenthesized = true;
|
|
}
|
|
parts.push(" ", (0, lines_1.concat)(["(\n", argLines]).indentTail(options.tabWidth), "\n)");
|
|
}
|
|
else {
|
|
parts.push(" ", argLines);
|
|
}
|
|
}
|
|
parts.push(";");
|
|
return (0, lines_1.concat)(parts);
|
|
}
|
|
case "CallExpression":
|
|
case "OptionalCallExpression":
|
|
parts.push(path.call(print, "callee"));
|
|
if (n.typeParameters) {
|
|
parts.push(path.call(print, "typeParameters"));
|
|
}
|
|
if (n.typeArguments) {
|
|
parts.push(path.call(print, "typeArguments"));
|
|
}
|
|
// Like n.optional, but defaults to true for OptionalCallExpression
|
|
// nodes that are missing an n.optional property (unusual),
|
|
// according to the OptionalCallExpression definition in ast-types.
|
|
if (types.getFieldValue(n, "optional")) {
|
|
parts.push("?.");
|
|
}
|
|
parts.push(printArgumentsList(path, options, print));
|
|
return (0, lines_1.concat)(parts);
|
|
case "RecordExpression":
|
|
parts.push("#");
|
|
// Intentionally fall through to printing the object literal...
|
|
case "ObjectExpression":
|
|
case "ObjectPattern":
|
|
case "ObjectTypeAnnotation": {
|
|
var isTypeAnnotation_1 = n.type === "ObjectTypeAnnotation";
|
|
var separator_1 = options.flowObjectCommas
|
|
? ","
|
|
: isTypeAnnotation_1
|
|
? ";"
|
|
: ",";
|
|
var fields = [];
|
|
var allowBreak_1 = false;
|
|
if (isTypeAnnotation_1) {
|
|
fields.push("indexers", "callProperties");
|
|
if (n.internalSlots != null) {
|
|
fields.push("internalSlots");
|
|
}
|
|
}
|
|
fields.push("properties");
|
|
var len_1 = 0;
|
|
fields.forEach(function (field) {
|
|
len_1 += n[field].length;
|
|
});
|
|
var oneLine_1 = (isTypeAnnotation_1 && len_1 === 1) || len_1 === 0;
|
|
var leftBrace = n.exact ? "{|" : "{";
|
|
var rightBrace = n.exact ? "|}" : "}";
|
|
parts.push(oneLine_1 ? leftBrace : leftBrace + "\n");
|
|
var leftBraceIndex = parts.length - 1;
|
|
var i_1 = 0;
|
|
fields.forEach(function (field) {
|
|
path.each(function (childPath) {
|
|
var lines = print(childPath);
|
|
if (!oneLine_1) {
|
|
lines = lines.indent(options.tabWidth);
|
|
}
|
|
var multiLine = !isTypeAnnotation_1 && lines.length > 1;
|
|
if (multiLine && allowBreak_1) {
|
|
// Similar to the logic for BlockStatement.
|
|
parts.push("\n");
|
|
}
|
|
parts.push(lines);
|
|
if (i_1 < len_1 - 1) {
|
|
// Add an extra line break if the previous object property
|
|
// had a multi-line value.
|
|
parts.push(separator_1 + (multiLine ? "\n\n" : "\n"));
|
|
allowBreak_1 = !multiLine;
|
|
}
|
|
else if (len_1 !== 1 && isTypeAnnotation_1) {
|
|
parts.push(separator_1);
|
|
}
|
|
else if (!oneLine_1 &&
|
|
util.isTrailingCommaEnabled(options, "objects") &&
|
|
childPath.getValue().type !== "RestElement") {
|
|
parts.push(separator_1);
|
|
}
|
|
i_1++;
|
|
}, field);
|
|
});
|
|
if (n.inexact) {
|
|
var line = (0, lines_1.fromString)("...", options);
|
|
if (oneLine_1) {
|
|
if (len_1 > 0) {
|
|
parts.push(separator_1, " ");
|
|
}
|
|
parts.push(line);
|
|
}
|
|
else {
|
|
// No trailing separator after ... to maintain parity with prettier.
|
|
parts.push("\n", line.indent(options.tabWidth));
|
|
}
|
|
}
|
|
parts.push(oneLine_1 ? rightBrace : "\n" + rightBrace);
|
|
if (i_1 !== 0 && oneLine_1 && options.objectCurlySpacing) {
|
|
parts[leftBraceIndex] = leftBrace + " ";
|
|
parts[parts.length - 1] = " " + rightBrace;
|
|
}
|
|
if (n.typeAnnotation) {
|
|
parts.push(path.call(print, "typeAnnotation"));
|
|
}
|
|
return (0, lines_1.concat)(parts);
|
|
}
|
|
case "PropertyPattern":
|
|
return (0, lines_1.concat)([
|
|
path.call(print, "key"),
|
|
": ",
|
|
path.call(print, "pattern"),
|
|
]);
|
|
case "ObjectProperty": // Babel 6
|
|
case "Property": {
|
|
// Non-standard AST node type.
|
|
if (n.method || n.kind === "get" || n.kind === "set") {
|
|
return printMethod(path, options, print);
|
|
}
|
|
if (n.shorthand && n.value.type === "AssignmentPattern") {
|
|
return path.call(print, "value");
|
|
}
|
|
var key = path.call(print, "key");
|
|
if (n.computed) {
|
|
parts.push("[", key, "]");
|
|
}
|
|
else {
|
|
parts.push(key);
|
|
}
|
|
if (!n.shorthand || n.key.name !== n.value.name) {
|
|
parts.push(": ", path.call(print, "value"));
|
|
}
|
|
return (0, lines_1.concat)(parts);
|
|
}
|
|
case "ClassMethod": // Babel 6
|
|
case "ObjectMethod": // Babel 6
|
|
case "ClassPrivateMethod":
|
|
case "TSDeclareMethod":
|
|
return printMethod(path, options, print);
|
|
case "PrivateName":
|
|
return (0, lines_1.concat)(["#", path.call(print, "id")]);
|
|
case "Decorator":
|
|
return (0, lines_1.concat)(["@", path.call(print, "expression")]);
|
|
case "TupleExpression":
|
|
parts.push("#");
|
|
// Intentionally fall through to printing the tuple elements...
|
|
case "ArrayExpression":
|
|
case "ArrayPattern": {
|
|
var elems = n.elements;
|
|
var len_2 = elems.length;
|
|
var printed_1 = path.map(print, "elements");
|
|
var joined = (0, lines_1.fromString)(", ").join(printed_1);
|
|
var oneLine_2 = joined.getLineLength(1) <= options.wrapColumn;
|
|
if (oneLine_2) {
|
|
if (options.arrayBracketSpacing) {
|
|
parts.push("[ ");
|
|
}
|
|
else {
|
|
parts.push("[");
|
|
}
|
|
}
|
|
else {
|
|
parts.push("[\n");
|
|
}
|
|
path.each(function (elemPath) {
|
|
var i = elemPath.getName();
|
|
var elem = elemPath.getValue();
|
|
if (!elem) {
|
|
// If the array expression ends with a hole, that hole
|
|
// will be ignored by the interpreter, but if it ends with
|
|
// two (or more) holes, we need to write out two (or more)
|
|
// commas so that the resulting code is interpreted with
|
|
// both (all) of the holes.
|
|
parts.push(",");
|
|
}
|
|
else {
|
|
var lines = printed_1[i];
|
|
if (oneLine_2) {
|
|
if (i > 0)
|
|
parts.push(" ");
|
|
}
|
|
else {
|
|
lines = lines.indent(options.tabWidth);
|
|
}
|
|
parts.push(lines);
|
|
if (i < len_2 - 1 ||
|
|
(!oneLine_2 && util.isTrailingCommaEnabled(options, "arrays")))
|
|
parts.push(",");
|
|
if (!oneLine_2)
|
|
parts.push("\n");
|
|
}
|
|
}, "elements");
|
|
if (oneLine_2 && options.arrayBracketSpacing) {
|
|
parts.push(" ]");
|
|
}
|
|
else {
|
|
parts.push("]");
|
|
}
|
|
if (n.typeAnnotation) {
|
|
parts.push(path.call(print, "typeAnnotation"));
|
|
}
|
|
return (0, lines_1.concat)(parts);
|
|
}
|
|
case "SequenceExpression":
|
|
return (0, lines_1.fromString)(", ").join(path.map(print, "expressions"));
|
|
case "ThisExpression":
|
|
return (0, lines_1.fromString)("this");
|
|
case "Super":
|
|
return (0, lines_1.fromString)("super");
|
|
case "NullLiteral": // Babel 6 Literal split
|
|
return (0, lines_1.fromString)("null");
|
|
case "RegExpLiteral": // Babel 6 Literal split
|
|
return (0, lines_1.fromString)(getPossibleRaw(n) || "/".concat(n.pattern, "/").concat(n.flags || ""), options);
|
|
case "BigIntLiteral": // Babel 7 Literal split
|
|
return (0, lines_1.fromString)(getPossibleRaw(n) || n.value + "n", options);
|
|
case "NumericLiteral": // Babel 6 Literal Split
|
|
return (0, lines_1.fromString)(getPossibleRaw(n) || n.value, options);
|
|
case "DecimalLiteral":
|
|
return (0, lines_1.fromString)(getPossibleRaw(n) || n.value + "m", options);
|
|
case "StringLiteral":
|
|
return (0, lines_1.fromString)(nodeStr(n.value, options));
|
|
case "BooleanLiteral": // Babel 6 Literal split
|
|
case "Literal":
|
|
return (0, lines_1.fromString)(getPossibleRaw(n) ||
|
|
(typeof n.value === "string" ? nodeStr(n.value, options) : n.value), options);
|
|
case "Directive": // Babel 6
|
|
return path.call(print, "value");
|
|
case "DirectiveLiteral": // Babel 6
|
|
return (0, lines_1.fromString)(getPossibleRaw(n) || nodeStr(n.value, options), options);
|
|
case "InterpreterDirective":
|
|
return (0, lines_1.fromString)("#!".concat(n.value, "\n"), options);
|
|
case "ModuleSpecifier":
|
|
if (n.local) {
|
|
throw new Error("The ESTree ModuleSpecifier type should be abstract");
|
|
}
|
|
// The Esprima ModuleSpecifier type is just a string-valued
|
|
// Literal identifying the imported-from module.
|
|
return (0, lines_1.fromString)(nodeStr(n.value, options), options);
|
|
case "UnaryExpression":
|
|
parts.push(n.operator);
|
|
if (/[a-z]$/.test(n.operator))
|
|
parts.push(" ");
|
|
parts.push(path.call(print, "argument"));
|
|
return (0, lines_1.concat)(parts);
|
|
case "UpdateExpression":
|
|
parts.push(path.call(print, "argument"), n.operator);
|
|
if (n.prefix)
|
|
parts.reverse();
|
|
return (0, lines_1.concat)(parts);
|
|
case "ConditionalExpression":
|
|
return (0, lines_1.concat)([
|
|
path.call(print, "test"),
|
|
" ? ",
|
|
path.call(print, "consequent"),
|
|
" : ",
|
|
path.call(print, "alternate"),
|
|
]);
|
|
case "NewExpression": {
|
|
parts.push("new ", path.call(print, "callee"));
|
|
if (n.typeParameters) {
|
|
parts.push(path.call(print, "typeParameters"));
|
|
}
|
|
if (n.typeArguments) {
|
|
parts.push(path.call(print, "typeArguments"));
|
|
}
|
|
var args = n.arguments;
|
|
if (args) {
|
|
parts.push(printArgumentsList(path, options, print));
|
|
}
|
|
return (0, lines_1.concat)(parts);
|
|
}
|
|
case "VariableDeclaration": {
|
|
if (n.declare) {
|
|
parts.push("declare ");
|
|
}
|
|
parts.push(n.kind, " ");
|
|
var maxLen_1 = 0;
|
|
var printed = path.map(function (childPath) {
|
|
var lines = print(childPath);
|
|
maxLen_1 = Math.max(lines.length, maxLen_1);
|
|
return lines;
|
|
}, "declarations");
|
|
if (maxLen_1 === 1) {
|
|
parts.push((0, lines_1.fromString)(", ").join(printed));
|
|
}
|
|
else if (printed.length > 1) {
|
|
parts.push((0, lines_1.fromString)(",\n")
|
|
.join(printed)
|
|
.indentTail(n.kind.length + 1));
|
|
}
|
|
else {
|
|
parts.push(printed[0]);
|
|
}
|
|
// We generally want to terminate all variable declarations with a
|
|
// semicolon, except when they are children of for loops.
|
|
var parentNode = path.getParentNode();
|
|
if (!namedTypes.ForStatement.check(parentNode) &&
|
|
!namedTypes.ForInStatement.check(parentNode) &&
|
|
!(namedTypes.ForOfStatement &&
|
|
namedTypes.ForOfStatement.check(parentNode)) &&
|
|
!(namedTypes.ForAwaitStatement &&
|
|
namedTypes.ForAwaitStatement.check(parentNode))) {
|
|
parts.push(";");
|
|
}
|
|
return (0, lines_1.concat)(parts);
|
|
}
|
|
case "VariableDeclarator":
|
|
return n.init
|
|
? (0, lines_1.fromString)(" = ").join([
|
|
path.call(print, "id"),
|
|
path.call(print, "init"),
|
|
])
|
|
: path.call(print, "id");
|
|
case "WithStatement":
|
|
return (0, lines_1.concat)([
|
|
"with (",
|
|
path.call(print, "object"),
|
|
") ",
|
|
path.call(print, "body"),
|
|
]);
|
|
case "IfStatement": {
|
|
var con = adjustClause(path.call(print, "consequent"), options);
|
|
parts.push("if (", path.call(print, "test"), ")", con);
|
|
if (n.alternate)
|
|
parts.push(endsWithBrace(con) ? " else" : "\nelse", adjustClause(path.call(print, "alternate"), options));
|
|
return (0, lines_1.concat)(parts);
|
|
}
|
|
case "ForStatement": {
|
|
// TODO Get the for (;;) case right.
|
|
var init = path.call(print, "init");
|
|
var sep = init.length > 1 ? ";\n" : "; ";
|
|
var forParen = "for (";
|
|
var indented = (0, lines_1.fromString)(sep)
|
|
.join([init, path.call(print, "test"), path.call(print, "update")])
|
|
.indentTail(forParen.length);
|
|
var head = (0, lines_1.concat)([forParen, indented, ")"]);
|
|
var clause = adjustClause(path.call(print, "body"), options);
|
|
parts.push(head);
|
|
if (head.length > 1) {
|
|
parts.push("\n");
|
|
clause = clause.trimLeft();
|
|
}
|
|
parts.push(clause);
|
|
return (0, lines_1.concat)(parts);
|
|
}
|
|
case "WhileStatement":
|
|
return (0, lines_1.concat)([
|
|
"while (",
|
|
path.call(print, "test"),
|
|
")",
|
|
adjustClause(path.call(print, "body"), options),
|
|
]);
|
|
case "ForInStatement":
|
|
// Note: esprima can't actually parse "for each (".
|
|
return (0, lines_1.concat)([
|
|
n.each ? "for each (" : "for (",
|
|
path.call(print, "left"),
|
|
" in ",
|
|
path.call(print, "right"),
|
|
")",
|
|
adjustClause(path.call(print, "body"), options),
|
|
]);
|
|
case "ForOfStatement":
|
|
case "ForAwaitStatement":
|
|
parts.push("for ");
|
|
if (n.await || n.type === "ForAwaitStatement") {
|
|
parts.push("await ");
|
|
}
|
|
parts.push("(", path.call(print, "left"), " of ", path.call(print, "right"), ")", adjustClause(path.call(print, "body"), options));
|
|
return (0, lines_1.concat)(parts);
|
|
case "DoWhileStatement": {
|
|
var doBody = (0, lines_1.concat)([
|
|
"do",
|
|
adjustClause(path.call(print, "body"), options),
|
|
]);
|
|
parts.push(doBody);
|
|
if (endsWithBrace(doBody))
|
|
parts.push(" while");
|
|
else
|
|
parts.push("\nwhile");
|
|
parts.push(" (", path.call(print, "test"), ");");
|
|
return (0, lines_1.concat)(parts);
|
|
}
|
|
case "DoExpression": {
|
|
var statements = path.call(function (bodyPath) { return printStatementSequence(bodyPath, options, print); }, "body");
|
|
return (0, lines_1.concat)(["do {\n", statements.indent(options.tabWidth), "\n}"]);
|
|
}
|
|
case "BreakStatement":
|
|
parts.push("break");
|
|
if (n.label)
|
|
parts.push(" ", path.call(print, "label"));
|
|
parts.push(";");
|
|
return (0, lines_1.concat)(parts);
|
|
case "ContinueStatement":
|
|
parts.push("continue");
|
|
if (n.label)
|
|
parts.push(" ", path.call(print, "label"));
|
|
parts.push(";");
|
|
return (0, lines_1.concat)(parts);
|
|
case "LabeledStatement":
|
|
return (0, lines_1.concat)([
|
|
path.call(print, "label"),
|
|
":\n",
|
|
path.call(print, "body"),
|
|
]);
|
|
case "TryStatement":
|
|
parts.push("try ", path.call(print, "block"));
|
|
if (n.handler) {
|
|
parts.push(" ", path.call(print, "handler"));
|
|
}
|
|
else if (n.handlers) {
|
|
path.each(function (handlerPath) {
|
|
parts.push(" ", print(handlerPath));
|
|
}, "handlers");
|
|
}
|
|
if (n.finalizer) {
|
|
parts.push(" finally ", path.call(print, "finalizer"));
|
|
}
|
|
return (0, lines_1.concat)(parts);
|
|
case "CatchClause":
|
|
parts.push("catch ");
|
|
if (n.param) {
|
|
parts.push("(", path.call(print, "param"));
|
|
}
|
|
if (n.guard) {
|
|
// Note: esprima does not recognize conditional catch clauses.
|
|
parts.push(" if ", path.call(print, "guard"));
|
|
}
|
|
if (n.param) {
|
|
parts.push(") ");
|
|
}
|
|
parts.push(path.call(print, "body"));
|
|
return (0, lines_1.concat)(parts);
|
|
case "ThrowStatement":
|
|
return (0, lines_1.concat)(["throw ", path.call(print, "argument"), ";"]);
|
|
case "SwitchStatement":
|
|
return (0, lines_1.concat)([
|
|
"switch (",
|
|
path.call(print, "discriminant"),
|
|
") {\n",
|
|
(0, lines_1.fromString)("\n").join(path.map(print, "cases")),
|
|
"\n}",
|
|
]);
|
|
// Note: ignoring n.lexical because it has no printing consequences.
|
|
case "SwitchCase":
|
|
if (n.test)
|
|
parts.push("case ", path.call(print, "test"), ":");
|
|
else
|
|
parts.push("default:");
|
|
if (n.consequent.length > 0) {
|
|
parts.push("\n", path
|
|
.call(function (consequentPath) {
|
|
return printStatementSequence(consequentPath, options, print);
|
|
}, "consequent")
|
|
.indent(options.tabWidth));
|
|
}
|
|
return (0, lines_1.concat)(parts);
|
|
case "DebuggerStatement":
|
|
return (0, lines_1.fromString)("debugger;");
|
|
// JSX extensions below.
|
|
case "JSXAttribute":
|
|
parts.push(path.call(print, "name"));
|
|
if (n.value)
|
|
parts.push("=", path.call(print, "value"));
|
|
return (0, lines_1.concat)(parts);
|
|
case "JSXIdentifier":
|
|
return (0, lines_1.fromString)(n.name, options);
|
|
case "JSXNamespacedName":
|
|
return (0, lines_1.fromString)(":").join([
|
|
path.call(print, "namespace"),
|
|
path.call(print, "name"),
|
|
]);
|
|
case "JSXMemberExpression":
|
|
return (0, lines_1.fromString)(".").join([
|
|
path.call(print, "object"),
|
|
path.call(print, "property"),
|
|
]);
|
|
case "JSXSpreadAttribute":
|
|
return (0, lines_1.concat)(["{...", path.call(print, "argument"), "}"]);
|
|
case "JSXSpreadChild":
|
|
return (0, lines_1.concat)(["{...", path.call(print, "expression"), "}"]);
|
|
case "JSXExpressionContainer":
|
|
return (0, lines_1.concat)(["{", path.call(print, "expression"), "}"]);
|
|
case "JSXElement":
|
|
case "JSXFragment": {
|
|
var openingPropName = "opening" + (n.type === "JSXElement" ? "Element" : "Fragment");
|
|
var closingPropName = "closing" + (n.type === "JSXElement" ? "Element" : "Fragment");
|
|
var openingLines = path.call(print, openingPropName);
|
|
if (n[openingPropName].selfClosing) {
|
|
(0, tiny_invariant_1.default)(!n[closingPropName], "unexpected " +
|
|
closingPropName +
|
|
" element in self-closing " +
|
|
n.type);
|
|
return openingLines;
|
|
}
|
|
var childLines = (0, lines_1.concat)(path.map(function (childPath) {
|
|
var child = childPath.getValue();
|
|
if (namedTypes.Literal.check(child) &&
|
|
typeof child.value === "string") {
|
|
if (/\S/.test(child.value)) {
|
|
return child.value.replace(/^\s+/g, "");
|
|
}
|
|
else if (/\n/.test(child.value)) {
|
|
return "\n";
|
|
}
|
|
}
|
|
return print(childPath);
|
|
}, "children")).indentTail(options.tabWidth);
|
|
var closingLines = path.call(print, closingPropName);
|
|
return (0, lines_1.concat)([openingLines, childLines, closingLines]);
|
|
}
|
|
case "JSXOpeningElement": {
|
|
parts.push("<", path.call(print, "name"));
|
|
var typeDefPart = path.call(print, "typeParameters");
|
|
if (typeDefPart.length)
|
|
parts.push(typeDefPart);
|
|
var attrParts_1 = [];
|
|
path.each(function (attrPath) {
|
|
attrParts_1.push(" ", print(attrPath));
|
|
}, "attributes");
|
|
var attrLines = (0, lines_1.concat)(attrParts_1);
|
|
var needLineWrap = attrLines.length > 1 || attrLines.getLineLength(1) > options.wrapColumn;
|
|
if (needLineWrap) {
|
|
attrParts_1.forEach(function (part, i) {
|
|
if (part === " ") {
|
|
(0, tiny_invariant_1.default)(i % 2 === 0);
|
|
attrParts_1[i] = "\n";
|
|
}
|
|
});
|
|
attrLines = (0, lines_1.concat)(attrParts_1).indentTail(options.tabWidth);
|
|
}
|
|
parts.push(attrLines, n.selfClosing ? " />" : ">");
|
|
return (0, lines_1.concat)(parts);
|
|
}
|
|
case "JSXClosingElement":
|
|
return (0, lines_1.concat)(["</", path.call(print, "name"), ">"]);
|
|
case "JSXOpeningFragment":
|
|
return (0, lines_1.fromString)("<>");
|
|
case "JSXClosingFragment":
|
|
return (0, lines_1.fromString)("</>");
|
|
case "JSXText":
|
|
return (0, lines_1.fromString)(n.value, options);
|
|
case "JSXEmptyExpression":
|
|
return (0, lines_1.fromString)("");
|
|
case "TypeAnnotatedIdentifier":
|
|
return (0, lines_1.concat)([
|
|
path.call(print, "annotation"),
|
|
" ",
|
|
path.call(print, "identifier"),
|
|
]);
|
|
case "ClassBody":
|
|
if (n.body.length === 0) {
|
|
return (0, lines_1.fromString)("{}");
|
|
}
|
|
return (0, lines_1.concat)([
|
|
"{\n",
|
|
path
|
|
.call(function (bodyPath) { return printStatementSequence(bodyPath, options, print); }, "body")
|
|
.indent(options.tabWidth),
|
|
"\n}",
|
|
]);
|
|
case "ClassPropertyDefinition":
|
|
parts.push("static ", path.call(print, "definition"));
|
|
if (!namedTypes.MethodDefinition.check(n.definition))
|
|
parts.push(";");
|
|
return (0, lines_1.concat)(parts);
|
|
case "ClassProperty": {
|
|
if (n.declare) {
|
|
parts.push("declare ");
|
|
}
|
|
var access = n.accessibility || n.access;
|
|
if (typeof access === "string") {
|
|
parts.push(access, " ");
|
|
}
|
|
if (n.static) {
|
|
parts.push("static ");
|
|
}
|
|
if (n.abstract) {
|
|
parts.push("abstract ");
|
|
}
|
|
if (n.readonly) {
|
|
parts.push("readonly ");
|
|
}
|
|
var key = path.call(print, "key");
|
|
if (n.computed) {
|
|
key = (0, lines_1.concat)(["[", key, "]"]);
|
|
}
|
|
if (n.variance) {
|
|
key = (0, lines_1.concat)([printVariance(path, print), key]);
|
|
}
|
|
parts.push(key);
|
|
if (n.optional) {
|
|
parts.push("?");
|
|
}
|
|
if (n.definite) {
|
|
parts.push("!");
|
|
}
|
|
if (n.typeAnnotation) {
|
|
parts.push(path.call(print, "typeAnnotation"));
|
|
}
|
|
if (n.value) {
|
|
parts.push(" = ", path.call(print, "value"));
|
|
}
|
|
parts.push(";");
|
|
return (0, lines_1.concat)(parts);
|
|
}
|
|
case "ClassPrivateProperty":
|
|
if (n.static) {
|
|
parts.push("static ");
|
|
}
|
|
parts.push(path.call(print, "key"));
|
|
if (n.typeAnnotation) {
|
|
parts.push(path.call(print, "typeAnnotation"));
|
|
}
|
|
if (n.value) {
|
|
parts.push(" = ", path.call(print, "value"));
|
|
}
|
|
parts.push(";");
|
|
return (0, lines_1.concat)(parts);
|
|
case "ClassAccessorProperty": {
|
|
parts.push.apply(parts, tslib_1.__spreadArray(tslib_1.__spreadArray([], printClassMemberModifiers(n), false), ["accessor "], false));
|
|
if (n.computed) {
|
|
parts.push("[", path.call(print, "key"), "]");
|
|
}
|
|
else {
|
|
parts.push(path.call(print, "key"));
|
|
}
|
|
if (n.optional) {
|
|
parts.push("?");
|
|
}
|
|
if (n.definite) {
|
|
parts.push("!");
|
|
}
|
|
if (n.typeAnnotation) {
|
|
parts.push(path.call(print, "typeAnnotation"));
|
|
}
|
|
if (n.value) {
|
|
parts.push(" = ", path.call(print, "value"));
|
|
}
|
|
parts.push(";");
|
|
return (0, lines_1.concat)(parts);
|
|
}
|
|
case "ClassDeclaration":
|
|
case "ClassExpression":
|
|
case "DeclareClass":
|
|
if (n.declare) {
|
|
parts.push("declare ");
|
|
}
|
|
if (n.abstract) {
|
|
parts.push("abstract ");
|
|
}
|
|
parts.push("class");
|
|
if (n.id) {
|
|
parts.push(" ", path.call(print, "id"));
|
|
}
|
|
if (n.typeParameters) {
|
|
parts.push(path.call(print, "typeParameters"));
|
|
}
|
|
if (n.superClass) {
|
|
// ClassDeclaration and ClassExpression only
|
|
parts.push(" extends ", path.call(print, "superClass"), path.call(print, "superTypeParameters"));
|
|
}
|
|
if (n.extends && n.extends.length > 0) {
|
|
// DeclareClass only
|
|
parts.push(" extends ", (0, lines_1.fromString)(", ").join(path.map(print, "extends")));
|
|
}
|
|
if (n["implements"] && n["implements"].length > 0) {
|
|
parts.push(" implements ", (0, lines_1.fromString)(", ").join(path.map(print, "implements")));
|
|
}
|
|
parts.push(" ", path.call(print, "body"));
|
|
if (n.type === "DeclareClass") {
|
|
return printFlowDeclaration(path, parts);
|
|
}
|
|
else {
|
|
return (0, lines_1.concat)(parts);
|
|
}
|
|
case "TemplateElement":
|
|
return (0, lines_1.fromString)(n.value.raw, options).lockIndentTail();
|
|
case "TemplateLiteral": {
|
|
var expressions_1 = path.map(print, "expressions");
|
|
parts.push("`");
|
|
path.each(function (childPath) {
|
|
var i = childPath.getName();
|
|
parts.push(print(childPath));
|
|
if (i < expressions_1.length) {
|
|
parts.push("${", expressions_1[i], "}");
|
|
}
|
|
}, "quasis");
|
|
parts.push("`");
|
|
return (0, lines_1.concat)(parts).lockIndentTail();
|
|
}
|
|
case "TaggedTemplateExpression":
|
|
parts.push(path.call(print, "tag"));
|
|
if (n.typeParameters) {
|
|
parts.push(path.call(print, "typeParameters"));
|
|
}
|
|
parts.push(path.call(print, "quasi"));
|
|
return (0, lines_1.concat)(parts);
|
|
// These types are unprintable because they serve as abstract
|
|
// supertypes for other (printable) types.
|
|
case "Node":
|
|
case "Printable":
|
|
case "SourceLocation":
|
|
case "Position":
|
|
case "Statement":
|
|
case "Function":
|
|
case "Pattern":
|
|
case "Expression":
|
|
case "Declaration":
|
|
case "Specifier":
|
|
case "NamedSpecifier":
|
|
case "Comment": // Supertype of Block and Line
|
|
case "Flow": // Supertype of all Flow AST node types
|
|
case "FlowType": // Supertype of all Flow types
|
|
case "FlowPredicate": // Supertype of InferredPredicate and DeclaredPredicate
|
|
case "MemberTypeAnnotation": // Flow
|
|
case "Type": // Flow
|
|
case "TSHasOptionalTypeParameterInstantiation":
|
|
case "TSHasOptionalTypeParameters":
|
|
case "TSHasOptionalTypeAnnotation":
|
|
case "ChainElement": // Supertype of MemberExpression and CallExpression
|
|
throw new Error("unprintable type: " + JSON.stringify(n.type));
|
|
case "CommentBlock": // Babel block comment.
|
|
case "Block": // Esprima block comment.
|
|
return (0, lines_1.concat)(["/*", (0, lines_1.fromString)(n.value, options), "*/"]);
|
|
case "CommentLine": // Babel line comment.
|
|
case "Line": // Esprima line comment.
|
|
return (0, lines_1.concat)(["//", (0, lines_1.fromString)(n.value, options)]);
|
|
// Type Annotations for Facebook Flow, typically stripped out or
|
|
// transformed away before printing.
|
|
case "TypeAnnotation":
|
|
if (n.typeAnnotation) {
|
|
if (n.typeAnnotation.type !== "FunctionTypeAnnotation") {
|
|
parts.push(": ");
|
|
}
|
|
parts.push(path.call(print, "typeAnnotation"));
|
|
return (0, lines_1.concat)(parts);
|
|
}
|
|
return (0, lines_1.fromString)("");
|
|
case "ExistentialTypeParam":
|
|
case "ExistsTypeAnnotation":
|
|
return (0, lines_1.fromString)("*", options);
|
|
case "EmptyTypeAnnotation":
|
|
return (0, lines_1.fromString)("empty", options);
|
|
case "AnyTypeAnnotation":
|
|
return (0, lines_1.fromString)("any", options);
|
|
case "MixedTypeAnnotation":
|
|
return (0, lines_1.fromString)("mixed", options);
|
|
case "ArrayTypeAnnotation":
|
|
return (0, lines_1.concat)([path.call(print, "elementType"), "[]"]);
|
|
case "TupleTypeAnnotation": {
|
|
var printed_2 = path.map(print, "types");
|
|
var joined = (0, lines_1.fromString)(", ").join(printed_2);
|
|
var oneLine_3 = joined.getLineLength(1) <= options.wrapColumn;
|
|
if (oneLine_3) {
|
|
if (options.arrayBracketSpacing) {
|
|
parts.push("[ ");
|
|
}
|
|
else {
|
|
parts.push("[");
|
|
}
|
|
}
|
|
else {
|
|
parts.push("[\n");
|
|
}
|
|
path.each(function (elemPath) {
|
|
var i = elemPath.getName();
|
|
var elem = elemPath.getValue();
|
|
if (!elem) {
|
|
// If the array expression ends with a hole, that hole
|
|
// will be ignored by the interpreter, but if it ends with
|
|
// two (or more) holes, we need to write out two (or more)
|
|
// commas so that the resulting code is interpreted with
|
|
// both (all) of the holes.
|
|
parts.push(",");
|
|
}
|
|
else {
|
|
var lines = printed_2[i];
|
|
if (oneLine_3) {
|
|
if (i > 0)
|
|
parts.push(" ");
|
|
}
|
|
else {
|
|
lines = lines.indent(options.tabWidth);
|
|
}
|
|
parts.push(lines);
|
|
if (i < n.types.length - 1 ||
|
|
(!oneLine_3 && util.isTrailingCommaEnabled(options, "arrays")))
|
|
parts.push(",");
|
|
if (!oneLine_3)
|
|
parts.push("\n");
|
|
}
|
|
}, "types");
|
|
if (oneLine_3 && options.arrayBracketSpacing) {
|
|
parts.push(" ]");
|
|
}
|
|
else {
|
|
parts.push("]");
|
|
}
|
|
return (0, lines_1.concat)(parts);
|
|
}
|
|
case "BooleanTypeAnnotation":
|
|
return (0, lines_1.fromString)("boolean", options);
|
|
case "BooleanLiteralTypeAnnotation":
|
|
(0, tiny_invariant_1.default)(typeof n.value === "boolean");
|
|
return (0, lines_1.fromString)("" + n.value, options);
|
|
case "InterfaceTypeAnnotation":
|
|
parts.push("interface");
|
|
if (n.extends && n.extends.length > 0) {
|
|
parts.push(" extends ", (0, lines_1.fromString)(", ").join(path.map(print, "extends")));
|
|
}
|
|
parts.push(" ", path.call(print, "body"));
|
|
return (0, lines_1.concat)(parts);
|
|
case "DeclareFunction":
|
|
return printFlowDeclaration(path, [
|
|
"function ",
|
|
path.call(print, "id"),
|
|
";",
|
|
]);
|
|
case "DeclareModule":
|
|
return printFlowDeclaration(path, [
|
|
"module ",
|
|
path.call(print, "id"),
|
|
" ",
|
|
path.call(print, "body"),
|
|
]);
|
|
case "DeclareModuleExports":
|
|
return printFlowDeclaration(path, [
|
|
"module.exports",
|
|
path.call(print, "typeAnnotation"),
|
|
]);
|
|
case "DeclareVariable":
|
|
return printFlowDeclaration(path, ["var ", path.call(print, "id"), ";"]);
|
|
case "DeclareExportDeclaration":
|
|
case "DeclareExportAllDeclaration":
|
|
return (0, lines_1.concat)(["declare ", printExportDeclaration(path, options, print)]);
|
|
case "EnumDeclaration":
|
|
return (0, lines_1.concat)([
|
|
"enum ",
|
|
path.call(print, "id"),
|
|
path.call(print, "body"),
|
|
]);
|
|
case "EnumBooleanBody":
|
|
case "EnumNumberBody":
|
|
case "EnumStringBody":
|
|
case "EnumSymbolBody": {
|
|
if (n.type === "EnumSymbolBody" || n.explicitType) {
|
|
parts.push(" of ",
|
|
// EnumBooleanBody => boolean, etc.
|
|
n.type.slice(4, -4).toLowerCase());
|
|
}
|
|
parts.push(" {\n", (0, lines_1.fromString)("\n")
|
|
.join(path.map(print, "members"))
|
|
.indent(options.tabWidth), "\n}");
|
|
return (0, lines_1.concat)(parts);
|
|
}
|
|
case "EnumDefaultedMember":
|
|
return (0, lines_1.concat)([path.call(print, "id"), ","]);
|
|
case "EnumBooleanMember":
|
|
case "EnumNumberMember":
|
|
case "EnumStringMember":
|
|
return (0, lines_1.concat)([
|
|
path.call(print, "id"),
|
|
" = ",
|
|
path.call(print, "init"),
|
|
",",
|
|
]);
|
|
case "InferredPredicate":
|
|
return (0, lines_1.fromString)("%checks", options);
|
|
case "DeclaredPredicate":
|
|
return (0, lines_1.concat)(["%checks(", path.call(print, "value"), ")"]);
|
|
case "FunctionTypeAnnotation": {
|
|
// FunctionTypeAnnotation is ambiguous:
|
|
// declare function(a: B): void; OR
|
|
// const A: (a: B) => void;
|
|
var parent = path.getParentNode(0);
|
|
var isArrowFunctionTypeAnnotation = !(namedTypes.ObjectTypeCallProperty.check(parent) ||
|
|
(namedTypes.ObjectTypeInternalSlot.check(parent) && parent.method) ||
|
|
namedTypes.DeclareFunction.check(path.getParentNode(2)));
|
|
var needsColon = isArrowFunctionTypeAnnotation &&
|
|
!namedTypes.FunctionTypeParam.check(parent) &&
|
|
!namedTypes.TypeAlias.check(parent);
|
|
if (needsColon) {
|
|
parts.push(": ");
|
|
}
|
|
var hasTypeParameters = !!n.typeParameters;
|
|
var needsParens = hasTypeParameters || n.params.length !== 1 || n.params[0].name;
|
|
parts.push(hasTypeParameters ? path.call(print, "typeParameters") : "", needsParens ? "(" : "", printFunctionParams(path, options, print), needsParens ? ")" : "");
|
|
// The returnType is not wrapped in a TypeAnnotation, so the colon
|
|
// needs to be added separately.
|
|
if (n.returnType) {
|
|
parts.push(isArrowFunctionTypeAnnotation ? " => " : ": ", path.call(print, "returnType"));
|
|
}
|
|
return (0, lines_1.concat)(parts);
|
|
}
|
|
case "FunctionTypeParam": {
|
|
var name = path.call(print, "name");
|
|
parts.push(name);
|
|
if (n.optional) {
|
|
parts.push("?");
|
|
}
|
|
if (name.infos[0].line) {
|
|
parts.push(": ");
|
|
}
|
|
parts.push(path.call(print, "typeAnnotation"));
|
|
return (0, lines_1.concat)(parts);
|
|
}
|
|
case "GenericTypeAnnotation":
|
|
return (0, lines_1.concat)([
|
|
path.call(print, "id"),
|
|
path.call(print, "typeParameters"),
|
|
]);
|
|
case "DeclareInterface":
|
|
parts.push("declare ");
|
|
// Fall through to InterfaceDeclaration...
|
|
case "InterfaceDeclaration":
|
|
case "TSInterfaceDeclaration":
|
|
if (n.declare) {
|
|
parts.push("declare ");
|
|
}
|
|
parts.push("interface ", path.call(print, "id"), path.call(print, "typeParameters"), " ");
|
|
if (n["extends"] && n["extends"].length > 0) {
|
|
parts.push("extends ", (0, lines_1.fromString)(", ").join(path.map(print, "extends")), " ");
|
|
}
|
|
if (n.body) {
|
|
parts.push(path.call(print, "body"));
|
|
}
|
|
return (0, lines_1.concat)(parts);
|
|
case "ClassImplements":
|
|
case "InterfaceExtends":
|
|
return (0, lines_1.concat)([
|
|
path.call(print, "id"),
|
|
path.call(print, "typeParameters"),
|
|
]);
|
|
case "IntersectionTypeAnnotation":
|
|
return (0, lines_1.fromString)(" & ").join(path.map(print, "types"));
|
|
case "NullableTypeAnnotation":
|
|
return (0, lines_1.concat)(["?", path.call(print, "typeAnnotation")]);
|
|
case "NullLiteralTypeAnnotation":
|
|
return (0, lines_1.fromString)("null", options);
|
|
case "ThisTypeAnnotation":
|
|
return (0, lines_1.fromString)("this", options);
|
|
case "NumberTypeAnnotation":
|
|
return (0, lines_1.fromString)("number", options);
|
|
case "ObjectTypeCallProperty":
|
|
return path.call(print, "value");
|
|
case "ObjectTypeIndexer":
|
|
if (n.static) {
|
|
parts.push("static ");
|
|
}
|
|
parts.push(printVariance(path, print), "[");
|
|
if (n.id) {
|
|
parts.push(path.call(print, "id"), ": ");
|
|
}
|
|
parts.push(path.call(print, "key"), "]: ", path.call(print, "value"));
|
|
return (0, lines_1.concat)(parts);
|
|
case "ObjectTypeProperty":
|
|
return (0, lines_1.concat)([
|
|
printVariance(path, print),
|
|
path.call(print, "key"),
|
|
n.optional ? "?" : "",
|
|
": ",
|
|
path.call(print, "value"),
|
|
]);
|
|
case "ObjectTypeInternalSlot":
|
|
return (0, lines_1.concat)([
|
|
n.static ? "static " : "",
|
|
"[[",
|
|
path.call(print, "id"),
|
|
"]]",
|
|
n.optional ? "?" : "",
|
|
n.value.type !== "FunctionTypeAnnotation" ? ": " : "",
|
|
path.call(print, "value"),
|
|
]);
|
|
case "QualifiedTypeIdentifier":
|
|
return (0, lines_1.concat)([
|
|
path.call(print, "qualification"),
|
|
".",
|
|
path.call(print, "id"),
|
|
]);
|
|
case "StringLiteralTypeAnnotation":
|
|
return (0, lines_1.fromString)(nodeStr(n.value, options), options);
|
|
case "NumberLiteralTypeAnnotation":
|
|
case "NumericLiteralTypeAnnotation":
|
|
(0, tiny_invariant_1.default)(typeof n.value === "number");
|
|
return (0, lines_1.fromString)(JSON.stringify(n.value), options);
|
|
case "BigIntLiteralTypeAnnotation":
|
|
return (0, lines_1.fromString)(n.raw, options);
|
|
case "StringTypeAnnotation":
|
|
return (0, lines_1.fromString)("string", options);
|
|
case "DeclareTypeAlias":
|
|
parts.push("declare ");
|
|
// Fall through to TypeAlias...
|
|
case "TypeAlias":
|
|
return (0, lines_1.concat)([
|
|
"type ",
|
|
path.call(print, "id"),
|
|
path.call(print, "typeParameters"),
|
|
" = ",
|
|
path.call(print, "right"),
|
|
";",
|
|
]);
|
|
case "DeclareOpaqueType":
|
|
parts.push("declare ");
|
|
// Fall through to OpaqueType...
|
|
case "OpaqueType":
|
|
parts.push("opaque type ", path.call(print, "id"), path.call(print, "typeParameters"));
|
|
if (n["supertype"]) {
|
|
parts.push(": ", path.call(print, "supertype"));
|
|
}
|
|
if (n["impltype"]) {
|
|
parts.push(" = ", path.call(print, "impltype"));
|
|
}
|
|
parts.push(";");
|
|
return (0, lines_1.concat)(parts);
|
|
case "TypeCastExpression":
|
|
return (0, lines_1.concat)([
|
|
"(",
|
|
path.call(print, "expression"),
|
|
path.call(print, "typeAnnotation"),
|
|
")",
|
|
]);
|
|
case "TypeParameterDeclaration":
|
|
case "TypeParameterInstantiation":
|
|
return (0, lines_1.concat)([
|
|
"<",
|
|
(0, lines_1.fromString)(", ").join(path.map(print, "params")),
|
|
">",
|
|
]);
|
|
case "Variance":
|
|
if (n.kind === "plus") {
|
|
return (0, lines_1.fromString)("+");
|
|
}
|
|
if (n.kind === "minus") {
|
|
return (0, lines_1.fromString)("-");
|
|
}
|
|
return (0, lines_1.fromString)("");
|
|
case "TypeParameter":
|
|
if (n.variance) {
|
|
parts.push(printVariance(path, print));
|
|
}
|
|
parts.push(path.call(print, "name"));
|
|
if (n.bound) {
|
|
parts.push(path.call(print, "bound"));
|
|
}
|
|
if (n["default"]) {
|
|
parts.push("=", path.call(print, "default"));
|
|
}
|
|
return (0, lines_1.concat)(parts);
|
|
case "TypeofTypeAnnotation":
|
|
return (0, lines_1.concat)([
|
|
(0, lines_1.fromString)("typeof ", options),
|
|
path.call(print, "argument"),
|
|
]);
|
|
case "IndexedAccessType":
|
|
case "OptionalIndexedAccessType":
|
|
return (0, lines_1.concat)([
|
|
path.call(print, "objectType"),
|
|
n.optional ? "?." : "",
|
|
"[",
|
|
path.call(print, "indexType"),
|
|
"]",
|
|
]);
|
|
case "UnionTypeAnnotation":
|
|
return (0, lines_1.fromString)(" | ").join(path.map(print, "types"));
|
|
case "VoidTypeAnnotation":
|
|
return (0, lines_1.fromString)("void", options);
|
|
case "NullTypeAnnotation":
|
|
return (0, lines_1.fromString)("null", options);
|
|
case "SymbolTypeAnnotation":
|
|
return (0, lines_1.fromString)("symbol", options);
|
|
case "BigIntTypeAnnotation":
|
|
return (0, lines_1.fromString)("bigint", options);
|
|
// Type Annotations for TypeScript (when using Babylon as parser)
|
|
case "TSType":
|
|
throw new Error("unprintable type: " + JSON.stringify(n.type));
|
|
case "TSNumberKeyword":
|
|
return (0, lines_1.fromString)("number", options);
|
|
case "TSBigIntKeyword":
|
|
return (0, lines_1.fromString)("bigint", options);
|
|
case "TSObjectKeyword":
|
|
return (0, lines_1.fromString)("object", options);
|
|
case "TSBooleanKeyword":
|
|
return (0, lines_1.fromString)("boolean", options);
|
|
case "TSStringKeyword":
|
|
return (0, lines_1.fromString)("string", options);
|
|
case "TSSymbolKeyword":
|
|
return (0, lines_1.fromString)("symbol", options);
|
|
case "TSAnyKeyword":
|
|
return (0, lines_1.fromString)("any", options);
|
|
case "TSVoidKeyword":
|
|
return (0, lines_1.fromString)("void", options);
|
|
case "TSIntrinsicKeyword":
|
|
return (0, lines_1.fromString)("intrinsic", options);
|
|
case "TSThisType":
|
|
return (0, lines_1.fromString)("this", options);
|
|
case "TSNullKeyword":
|
|
return (0, lines_1.fromString)("null", options);
|
|
case "TSUndefinedKeyword":
|
|
return (0, lines_1.fromString)("undefined", options);
|
|
case "TSUnknownKeyword":
|
|
return (0, lines_1.fromString)("unknown", options);
|
|
case "TSNeverKeyword":
|
|
return (0, lines_1.fromString)("never", options);
|
|
case "TSArrayType":
|
|
return (0, lines_1.concat)([path.call(print, "elementType"), "[]"]);
|
|
case "TSLiteralType":
|
|
return path.call(print, "literal");
|
|
case "TSUnionType":
|
|
return (0, lines_1.fromString)(" | ").join(path.map(print, "types"));
|
|
case "TSIntersectionType":
|
|
return (0, lines_1.fromString)(" & ").join(path.map(print, "types"));
|
|
case "TSConditionalType":
|
|
parts.push(path.call(print, "checkType"), " extends ", path.call(print, "extendsType"), " ? ", path.call(print, "trueType"), " : ", path.call(print, "falseType"));
|
|
return (0, lines_1.concat)(parts);
|
|
case "TSInferType":
|
|
parts.push("infer ", path.call(print, "typeParameter"));
|
|
return (0, lines_1.concat)(parts);
|
|
case "TSParenthesizedType":
|
|
return (0, lines_1.concat)(["(", path.call(print, "typeAnnotation"), ")"]);
|
|
case "TSFunctionType":
|
|
return (0, lines_1.concat)([
|
|
path.call(print, "typeParameters"),
|
|
"(",
|
|
printFunctionParams(path, options, print),
|
|
") => ",
|
|
path.call(print, "typeAnnotation", "typeAnnotation"),
|
|
]);
|
|
case "TSConstructorType":
|
|
return (0, lines_1.concat)([
|
|
"new ",
|
|
path.call(print, "typeParameters"),
|
|
"(",
|
|
printFunctionParams(path, options, print),
|
|
") => ",
|
|
path.call(print, "typeAnnotation", "typeAnnotation"),
|
|
]);
|
|
case "TSMappedType": {
|
|
parts.push(n.readonly ? "readonly " : "", "[", path.call(print, "typeParameter"), "]", n.optional ? "?" : "");
|
|
if (n.typeAnnotation) {
|
|
parts.push(": ", path.call(print, "typeAnnotation"), ";");
|
|
}
|
|
return (0, lines_1.concat)(["{\n", (0, lines_1.concat)(parts).indent(options.tabWidth), "\n}"]);
|
|
}
|
|
case "TSTupleType":
|
|
return (0, lines_1.concat)([
|
|
"[",
|
|
(0, lines_1.fromString)(", ").join(path.map(print, "elementTypes")),
|
|
"]",
|
|
]);
|
|
case "TSNamedTupleMember":
|
|
parts.push(path.call(print, "label"));
|
|
if (n.optional) {
|
|
parts.push("?");
|
|
}
|
|
parts.push(": ", path.call(print, "elementType"));
|
|
return (0, lines_1.concat)(parts);
|
|
case "TSRestType":
|
|
return (0, lines_1.concat)(["...", path.call(print, "typeAnnotation")]);
|
|
case "TSOptionalType":
|
|
return (0, lines_1.concat)([path.call(print, "typeAnnotation"), "?"]);
|
|
case "TSIndexedAccessType":
|
|
return (0, lines_1.concat)([
|
|
path.call(print, "objectType"),
|
|
"[",
|
|
path.call(print, "indexType"),
|
|
"]",
|
|
]);
|
|
case "TSTypeOperator":
|
|
return (0, lines_1.concat)([
|
|
path.call(print, "operator"),
|
|
" ",
|
|
path.call(print, "typeAnnotation"),
|
|
]);
|
|
case "TSTypeLiteral": {
|
|
var members = (0, lines_1.fromString)("\n").join(path.map(print, "members").map(function (member) {
|
|
if (lastNonSpaceCharacter(member) !== ";") {
|
|
return member.concat(";");
|
|
}
|
|
return member;
|
|
}));
|
|
if (members.isEmpty()) {
|
|
return (0, lines_1.fromString)("{}", options);
|
|
}
|
|
parts.push("{\n", members.indent(options.tabWidth), "\n}");
|
|
return (0, lines_1.concat)(parts);
|
|
}
|
|
case "TSEnumMember":
|
|
parts.push(path.call(print, "id"));
|
|
if (n.initializer) {
|
|
parts.push(" = ", path.call(print, "initializer"));
|
|
}
|
|
return (0, lines_1.concat)(parts);
|
|
case "TSTypeQuery":
|
|
return (0, lines_1.concat)(["typeof ", path.call(print, "exprName")]);
|
|
case "TSParameterProperty":
|
|
if (n.accessibility) {
|
|
parts.push(n.accessibility, " ");
|
|
}
|
|
if (n.export) {
|
|
parts.push("export ");
|
|
}
|
|
if (n.static) {
|
|
parts.push("static ");
|
|
}
|
|
if (n.readonly) {
|
|
parts.push("readonly ");
|
|
}
|
|
parts.push(path.call(print, "parameter"));
|
|
return (0, lines_1.concat)(parts);
|
|
case "TSTypeReference":
|
|
return (0, lines_1.concat)([
|
|
path.call(print, "typeName"),
|
|
path.call(print, "typeParameters"),
|
|
]);
|
|
case "TSQualifiedName":
|
|
return (0, lines_1.concat)([path.call(print, "left"), ".", path.call(print, "right")]);
|
|
case "TSAsExpression":
|
|
case "TSSatisfiesExpression": {
|
|
var expression = path.call(print, "expression");
|
|
parts.push(expression, n.type === "TSSatisfiesExpression" ? " satisfies " : " as ", path.call(print, "typeAnnotation"));
|
|
return (0, lines_1.concat)(parts);
|
|
}
|
|
case "TSTypeCastExpression":
|
|
return (0, lines_1.concat)([
|
|
path.call(print, "expression"),
|
|
path.call(print, "typeAnnotation"),
|
|
]);
|
|
case "TSNonNullExpression":
|
|
return (0, lines_1.concat)([path.call(print, "expression"), "!"]);
|
|
case "TSTypeAnnotation":
|
|
return (0, lines_1.concat)([": ", path.call(print, "typeAnnotation")]);
|
|
case "TSIndexSignature":
|
|
return (0, lines_1.concat)([
|
|
n.readonly ? "readonly " : "",
|
|
"[",
|
|
path.map(print, "parameters"),
|
|
"]",
|
|
path.call(print, "typeAnnotation"),
|
|
]);
|
|
case "TSPropertySignature":
|
|
parts.push(printVariance(path, print), n.readonly ? "readonly " : "");
|
|
if (n.computed) {
|
|
parts.push("[", path.call(print, "key"), "]");
|
|
}
|
|
else {
|
|
parts.push(path.call(print, "key"));
|
|
}
|
|
parts.push(n.optional ? "?" : "", path.call(print, "typeAnnotation"));
|
|
return (0, lines_1.concat)(parts);
|
|
case "TSMethodSignature":
|
|
if (n.kind === "get") {
|
|
parts.push("get ");
|
|
}
|
|
else if (n.kind === "set") {
|
|
parts.push("set ");
|
|
}
|
|
if (n.computed) {
|
|
parts.push("[", path.call(print, "key"), "]");
|
|
}
|
|
else {
|
|
parts.push(path.call(print, "key"));
|
|
}
|
|
if (n.optional) {
|
|
parts.push("?");
|
|
}
|
|
parts.push(path.call(print, "typeParameters"), "(", printFunctionParams(path, options, print), ")", path.call(print, "typeAnnotation"));
|
|
return (0, lines_1.concat)(parts);
|
|
case "TSTypePredicate":
|
|
if (n.asserts) {
|
|
parts.push("asserts ");
|
|
}
|
|
parts.push(path.call(print, "parameterName"));
|
|
if (n.typeAnnotation) {
|
|
parts.push(" is ", path.call(print, "typeAnnotation", "typeAnnotation"));
|
|
}
|
|
return (0, lines_1.concat)(parts);
|
|
case "TSCallSignatureDeclaration":
|
|
return (0, lines_1.concat)([
|
|
path.call(print, "typeParameters"),
|
|
"(",
|
|
printFunctionParams(path, options, print),
|
|
")",
|
|
path.call(print, "typeAnnotation"),
|
|
]);
|
|
case "TSConstructSignatureDeclaration":
|
|
if (n.typeParameters) {
|
|
parts.push("new", path.call(print, "typeParameters"));
|
|
}
|
|
else {
|
|
parts.push("new ");
|
|
}
|
|
parts.push("(", printFunctionParams(path, options, print), ")", path.call(print, "typeAnnotation"));
|
|
return (0, lines_1.concat)(parts);
|
|
case "TSTypeAliasDeclaration":
|
|
return (0, lines_1.concat)([
|
|
n.declare ? "declare " : "",
|
|
"type ",
|
|
path.call(print, "id"),
|
|
path.call(print, "typeParameters"),
|
|
" = ",
|
|
path.call(print, "typeAnnotation"),
|
|
";",
|
|
]);
|
|
case "TSTypeParameter": {
|
|
parts.push(path.call(print, "name"));
|
|
// ambiguous because of TSMappedType
|
|
var parent = path.getParentNode(0);
|
|
var isInMappedType = namedTypes.TSMappedType.check(parent);
|
|
if (n.constraint) {
|
|
parts.push(isInMappedType ? " in " : " extends ", path.call(print, "constraint"));
|
|
}
|
|
if (n["default"]) {
|
|
parts.push(" = ", path.call(print, "default"));
|
|
}
|
|
return (0, lines_1.concat)(parts);
|
|
}
|
|
case "TSTypeAssertion": {
|
|
parts.push("<", path.call(print, "typeAnnotation"), "> ", path.call(print, "expression"));
|
|
return (0, lines_1.concat)(parts);
|
|
}
|
|
case "TSTypeParameterDeclaration":
|
|
case "TSTypeParameterInstantiation":
|
|
return (0, lines_1.concat)([
|
|
"<",
|
|
(0, lines_1.fromString)(", ").join(path.map(print, "params")),
|
|
">",
|
|
]);
|
|
case "TSEnumDeclaration": {
|
|
parts.push(n.declare ? "declare " : "", n.const ? "const " : "", "enum ", path.call(print, "id"));
|
|
var memberLines = (0, lines_1.fromString)(",\n").join(path.map(print, "members"));
|
|
if (memberLines.isEmpty()) {
|
|
parts.push(" {}");
|
|
}
|
|
else {
|
|
parts.push(" {\n", memberLines.indent(options.tabWidth), "\n}");
|
|
}
|
|
return (0, lines_1.concat)(parts);
|
|
}
|
|
case "TSExpressionWithTypeArguments":
|
|
return (0, lines_1.concat)([
|
|
path.call(print, "expression"),
|
|
path.call(print, "typeParameters"),
|
|
]);
|
|
case "TSInterfaceBody": {
|
|
var lines = (0, lines_1.fromString)("\n").join(path.map(print, "body").map(function (element) {
|
|
if (lastNonSpaceCharacter(element) !== ";") {
|
|
return element.concat(";");
|
|
}
|
|
return element;
|
|
}));
|
|
if (lines.isEmpty()) {
|
|
return (0, lines_1.fromString)("{}", options);
|
|
}
|
|
return (0, lines_1.concat)(["{\n", lines.indent(options.tabWidth), "\n}"]);
|
|
}
|
|
case "TSImportType":
|
|
parts.push("import(", path.call(print, "argument"), ")");
|
|
if (n.qualifier) {
|
|
parts.push(".", path.call(print, "qualifier"));
|
|
}
|
|
if (n.typeParameters) {
|
|
parts.push(path.call(print, "typeParameters"));
|
|
}
|
|
return (0, lines_1.concat)(parts);
|
|
case "TSImportEqualsDeclaration":
|
|
if (n.isExport) {
|
|
parts.push("export ");
|
|
}
|
|
parts.push("import ", path.call(print, "id"), " = ", path.call(print, "moduleReference"));
|
|
return maybeAddSemicolon((0, lines_1.concat)(parts));
|
|
case "TSExternalModuleReference":
|
|
return (0, lines_1.concat)(["require(", path.call(print, "expression"), ")"]);
|
|
case "TSModuleDeclaration": {
|
|
var parent = path.getParentNode();
|
|
if (parent.type === "TSModuleDeclaration") {
|
|
parts.push(".");
|
|
}
|
|
else {
|
|
if (n.declare) {
|
|
parts.push("declare ");
|
|
}
|
|
if (!n.global) {
|
|
var isExternal = n.id.type === "StringLiteral" ||
|
|
(n.id.type === "Literal" && typeof n.id.value === "string");
|
|
if (isExternal) {
|
|
parts.push("module ");
|
|
}
|
|
else if (n.loc && n.loc.lines && n.id.loc) {
|
|
var prefix = n.loc.lines.sliceString(n.loc.start, n.id.loc.start);
|
|
// These keywords are fundamentally ambiguous in the
|
|
// Babylon parser, and not reflected in the AST, so
|
|
// the best we can do is to match the original code,
|
|
// when possible.
|
|
if (prefix.indexOf("module") >= 0) {
|
|
parts.push("module ");
|
|
}
|
|
else {
|
|
parts.push("namespace ");
|
|
}
|
|
}
|
|
else {
|
|
parts.push("namespace ");
|
|
}
|
|
}
|
|
}
|
|
parts.push(path.call(print, "id"));
|
|
if (n.body) {
|
|
parts.push(" ");
|
|
parts.push(path.call(print, "body"));
|
|
}
|
|
return (0, lines_1.concat)(parts);
|
|
}
|
|
case "TSModuleBlock": {
|
|
var naked = path.call(function (bodyPath) { return printStatementSequence(bodyPath, options, print); }, "body");
|
|
if (naked.isEmpty()) {
|
|
parts.push("{}");
|
|
}
|
|
else {
|
|
parts.push("{\n", naked.indent(options.tabWidth), "\n}");
|
|
}
|
|
return (0, lines_1.concat)(parts);
|
|
}
|
|
case "TSInstantiationExpression": {
|
|
parts.push(path.call(print, "expression"), path.call(print, "typeParameters"));
|
|
return (0, lines_1.concat)(parts);
|
|
}
|
|
// https://github.com/babel/babel/pull/10148
|
|
case "V8IntrinsicIdentifier":
|
|
return (0, lines_1.concat)(["%", path.call(print, "name")]);
|
|
// https://github.com/babel/babel/pull/13191
|
|
case "TopicReference":
|
|
return (0, lines_1.fromString)("#");
|
|
// Unhandled types below. If encountered, nodes of these types should
|
|
// be either left alone or desugared into AST types that are fully
|
|
// supported by the pretty-printer.
|
|
case "ClassHeritage": // TODO
|
|
case "ComprehensionBlock": // TODO
|
|
case "ComprehensionExpression": // TODO
|
|
case "Glob": // TODO
|
|
case "GeneratorExpression": // TODO
|
|
case "LetStatement": // TODO
|
|
case "LetExpression": // TODO
|
|
case "GraphExpression": // TODO
|
|
case "GraphIndexExpression": // TODO
|
|
case "XMLDefaultDeclaration":
|
|
case "XMLAnyName":
|
|
case "XMLQualifiedIdentifier":
|
|
case "XMLFunctionQualifiedIdentifier":
|
|
case "XMLAttributeSelector":
|
|
case "XMLFilterExpression":
|
|
case "XML":
|
|
case "XMLElement":
|
|
case "XMLList":
|
|
case "XMLEscape":
|
|
case "XMLText":
|
|
case "XMLStartTag":
|
|
case "XMLEndTag":
|
|
case "XMLPointTag":
|
|
case "XMLName":
|
|
case "XMLAttribute":
|
|
case "XMLCdata":
|
|
case "XMLComment":
|
|
case "XMLProcessingInstruction":
|
|
default:
|
|
debugger;
|
|
throw new Error("unknown type: " + JSON.stringify(n.type));
|
|
}
|
|
}
|
|
function printDecorators(path, printPath) {
|
|
var parts = [];
|
|
var node = path.getValue();
|
|
if (node.decorators &&
|
|
node.decorators.length > 0 &&
|
|
// If the parent node is an export declaration, it will be
|
|
// responsible for printing node.decorators.
|
|
!util.getParentExportDeclaration(path)) {
|
|
path.each(function (decoratorPath) {
|
|
parts.push(printPath(decoratorPath), "\n");
|
|
}, "decorators");
|
|
}
|
|
else if (util.isExportDeclaration(node) &&
|
|
node.declaration &&
|
|
node.declaration.decorators) {
|
|
// Export declarations are responsible for printing any decorators
|
|
// that logically apply to node.declaration.
|
|
path.each(function (decoratorPath) {
|
|
parts.push(printPath(decoratorPath), "\n");
|
|
}, "declaration", "decorators");
|
|
}
|
|
return (0, lines_1.concat)(parts);
|
|
}
|
|
function printStatementSequence(path, options, print) {
|
|
var filtered = [];
|
|
var sawComment = false;
|
|
var sawStatement = false;
|
|
path.each(function (stmtPath) {
|
|
var stmt = stmtPath.getValue();
|
|
// Just in case the AST has been modified to contain falsy
|
|
// "statements," it's safer simply to skip them.
|
|
if (!stmt) {
|
|
return;
|
|
}
|
|
// Skip printing EmptyStatement nodes to avoid leaving stray
|
|
// semicolons lying around.
|
|
if (stmt.type === "EmptyStatement" &&
|
|
!(stmt.comments && stmt.comments.length > 0)) {
|
|
return;
|
|
}
|
|
if (namedTypes.Comment.check(stmt)) {
|
|
// The pretty printer allows a dangling Comment node to act as
|
|
// a Statement when the Comment can't be attached to any other
|
|
// non-Comment node in the tree.
|
|
sawComment = true;
|
|
}
|
|
else if (namedTypes.Statement.check(stmt)) {
|
|
sawStatement = true;
|
|
}
|
|
else {
|
|
// When the pretty printer encounters a string instead of an
|
|
// AST node, it just prints the string. This behavior can be
|
|
// useful for fine-grained formatting decisions like inserting
|
|
// blank lines.
|
|
isString.assert(stmt);
|
|
}
|
|
// We can't hang onto stmtPath outside of this function, because
|
|
// it's just a reference to a mutable FastPath object, so we have
|
|
// to go ahead and print it here.
|
|
filtered.push({
|
|
node: stmt,
|
|
printed: print(stmtPath),
|
|
});
|
|
});
|
|
if (sawComment) {
|
|
(0, tiny_invariant_1.default)(sawStatement === false, "Comments may appear as statements in otherwise empty statement " +
|
|
"lists, but may not coexist with non-Comment nodes.");
|
|
}
|
|
var prevTrailingSpace = null;
|
|
var len = filtered.length;
|
|
var parts = [];
|
|
filtered.forEach(function (info, i) {
|
|
var printed = info.printed;
|
|
var stmt = info.node;
|
|
var multiLine = printed.length > 1;
|
|
var notFirst = i > 0;
|
|
var notLast = i < len - 1;
|
|
var leadingSpace;
|
|
var trailingSpace;
|
|
var lines = stmt && stmt.loc && stmt.loc.lines;
|
|
var trueLoc = lines && options.reuseWhitespace && util.getTrueLoc(stmt, lines);
|
|
if (notFirst) {
|
|
if (trueLoc) {
|
|
var beforeStart = lines.skipSpaces(trueLoc.start, true);
|
|
var beforeStartLine = beforeStart ? beforeStart.line : 1;
|
|
var leadingGap = trueLoc.start.line - beforeStartLine;
|
|
leadingSpace = Array(leadingGap + 1).join("\n");
|
|
}
|
|
else {
|
|
leadingSpace = multiLine ? "\n\n" : "\n";
|
|
}
|
|
}
|
|
else {
|
|
leadingSpace = "";
|
|
}
|
|
if (notLast) {
|
|
if (trueLoc) {
|
|
var afterEnd = lines.skipSpaces(trueLoc.end);
|
|
var afterEndLine = afterEnd ? afterEnd.line : lines.length;
|
|
var trailingGap = afterEndLine - trueLoc.end.line;
|
|
trailingSpace = Array(trailingGap + 1).join("\n");
|
|
}
|
|
else {
|
|
trailingSpace = multiLine ? "\n\n" : "\n";
|
|
}
|
|
}
|
|
else {
|
|
trailingSpace = "";
|
|
}
|
|
parts.push(maxSpace(prevTrailingSpace, leadingSpace), printed);
|
|
if (notLast) {
|
|
prevTrailingSpace = trailingSpace;
|
|
}
|
|
else if (trailingSpace) {
|
|
parts.push(trailingSpace);
|
|
}
|
|
});
|
|
return (0, lines_1.concat)(parts);
|
|
}
|
|
function maxSpace(s1, s2) {
|
|
if (!s1 && !s2) {
|
|
return (0, lines_1.fromString)("");
|
|
}
|
|
if (!s1) {
|
|
return (0, lines_1.fromString)(s2);
|
|
}
|
|
if (!s2) {
|
|
return (0, lines_1.fromString)(s1);
|
|
}
|
|
var spaceLines1 = (0, lines_1.fromString)(s1);
|
|
var spaceLines2 = (0, lines_1.fromString)(s2);
|
|
if (spaceLines2.length > spaceLines1.length) {
|
|
return spaceLines2;
|
|
}
|
|
return spaceLines1;
|
|
}
|
|
function printClassMemberModifiers(node) {
|
|
var parts = [];
|
|
if (node.declare) {
|
|
parts.push("declare ");
|
|
}
|
|
var access = node.accessibility || node.access;
|
|
if (typeof access === "string") {
|
|
parts.push(access, " ");
|
|
}
|
|
if (node.static) {
|
|
parts.push("static ");
|
|
}
|
|
if (node.override) {
|
|
parts.push("override ");
|
|
}
|
|
if (node.abstract) {
|
|
parts.push("abstract ");
|
|
}
|
|
if (node.readonly) {
|
|
parts.push("readonly ");
|
|
}
|
|
return parts;
|
|
}
|
|
function printMethod(path, options, print) {
|
|
var node = path.getNode();
|
|
var kind = node.kind;
|
|
var parts = [];
|
|
var nodeValue = node.value;
|
|
if (!namedTypes.FunctionExpression.check(nodeValue)) {
|
|
nodeValue = node;
|
|
}
|
|
parts.push.apply(parts, printClassMemberModifiers(node));
|
|
if (nodeValue.async) {
|
|
parts.push("async ");
|
|
}
|
|
if (nodeValue.generator) {
|
|
parts.push("*");
|
|
}
|
|
if (kind === "get" || kind === "set") {
|
|
parts.push(kind, " ");
|
|
}
|
|
var key = path.call(print, "key");
|
|
if (node.computed) {
|
|
key = (0, lines_1.concat)(["[", key, "]"]);
|
|
}
|
|
parts.push(key);
|
|
if (node.optional) {
|
|
parts.push("?");
|
|
}
|
|
if (node === nodeValue) {
|
|
parts.push(path.call(print, "typeParameters"), "(", printFunctionParams(path, options, print), ")", path.call(print, "returnType"));
|
|
if (node.body) {
|
|
parts.push(" ", path.call(print, "body"));
|
|
}
|
|
else {
|
|
parts.push(";");
|
|
}
|
|
}
|
|
else {
|
|
parts.push(path.call(print, "value", "typeParameters"), "(", path.call(function (valuePath) { return printFunctionParams(valuePath, options, print); }, "value"), ")", path.call(print, "value", "returnType"));
|
|
if (nodeValue.body) {
|
|
parts.push(" ", path.call(print, "value", "body"));
|
|
}
|
|
else {
|
|
parts.push(";");
|
|
}
|
|
}
|
|
return (0, lines_1.concat)(parts);
|
|
}
|
|
function printArgumentsList(path, options, print) {
|
|
var printed = path.map(print, "arguments");
|
|
var trailingComma = util.isTrailingCommaEnabled(options, "parameters");
|
|
var joined = (0, lines_1.fromString)(", ").join(printed);
|
|
if (joined.getLineLength(1) > options.wrapColumn) {
|
|
joined = (0, lines_1.fromString)(",\n").join(printed);
|
|
return (0, lines_1.concat)([
|
|
"(\n",
|
|
joined.indent(options.tabWidth),
|
|
trailingComma ? ",\n)" : "\n)",
|
|
]);
|
|
}
|
|
return (0, lines_1.concat)(["(", joined, ")"]);
|
|
}
|
|
function printFunctionParams(path, options, print) {
|
|
var fun = path.getValue();
|
|
var params;
|
|
var printed = [];
|
|
if (fun.params) {
|
|
params = fun.params;
|
|
printed = path.map(print, "params");
|
|
}
|
|
else if (fun.parameters) {
|
|
params = fun.parameters;
|
|
printed = path.map(print, "parameters");
|
|
}
|
|
if (fun.defaults) {
|
|
path.each(function (defExprPath) {
|
|
var i = defExprPath.getName();
|
|
var p = printed[i];
|
|
if (p && defExprPath.getValue()) {
|
|
printed[i] = (0, lines_1.concat)([p, " = ", print(defExprPath)]);
|
|
}
|
|
}, "defaults");
|
|
}
|
|
if (fun.rest) {
|
|
printed.push((0, lines_1.concat)(["...", path.call(print, "rest")]));
|
|
}
|
|
var joined = (0, lines_1.fromString)(", ").join(printed);
|
|
if (joined.length > 1 || joined.getLineLength(1) > options.wrapColumn) {
|
|
joined = (0, lines_1.fromString)(",\n").join(printed);
|
|
if (util.isTrailingCommaEnabled(options, "parameters") &&
|
|
!fun.rest &&
|
|
params[params.length - 1].type !== "RestElement") {
|
|
joined = (0, lines_1.concat)([joined, ",\n"]);
|
|
}
|
|
else {
|
|
joined = (0, lines_1.concat)([joined, "\n"]);
|
|
}
|
|
return (0, lines_1.concat)(["\n", joined.indent(options.tabWidth)]);
|
|
}
|
|
return joined;
|
|
}
|
|
function maybePrintImportAssertions(path, options, print) {
|
|
var n = path.getValue();
|
|
if (n.assertions && n.assertions.length > 0) {
|
|
var parts = [" assert {"];
|
|
var printed = path.map(print, "assertions");
|
|
var flat = (0, lines_1.fromString)(", ").join(printed);
|
|
if (flat.length > 1 || flat.getLineLength(1) > options.wrapColumn) {
|
|
parts.push("\n", (0, lines_1.fromString)(",\n").join(printed).indent(options.tabWidth), "\n}");
|
|
}
|
|
else {
|
|
parts.push(" ", flat, " }");
|
|
}
|
|
return (0, lines_1.concat)(parts);
|
|
}
|
|
return (0, lines_1.fromString)("");
|
|
}
|
|
function printExportDeclaration(path, options, print) {
|
|
var decl = path.getValue();
|
|
var parts = ["export "];
|
|
if (decl.exportKind && decl.exportKind === "type") {
|
|
if (!decl.declaration) {
|
|
parts.push("type ");
|
|
}
|
|
}
|
|
var shouldPrintSpaces = options.objectCurlySpacing;
|
|
namedTypes.Declaration.assert(decl);
|
|
if (decl["default"] || decl.type === "ExportDefaultDeclaration") {
|
|
parts.push("default ");
|
|
}
|
|
if (decl.declaration) {
|
|
parts.push(path.call(print, "declaration"));
|
|
}
|
|
else if (decl.specifiers) {
|
|
if (decl.specifiers.length === 1 &&
|
|
decl.specifiers[0].type === "ExportBatchSpecifier") {
|
|
parts.push("*");
|
|
}
|
|
else if (decl.specifiers.length === 0) {
|
|
parts.push("{}");
|
|
}
|
|
else if (decl.specifiers[0].type === "ExportDefaultSpecifier" ||
|
|
decl.specifiers[0].type === "ExportNamespaceSpecifier") {
|
|
var unbracedSpecifiers_2 = [];
|
|
var bracedSpecifiers_2 = [];
|
|
path.each(function (specifierPath) {
|
|
var spec = specifierPath.getValue();
|
|
if (spec.type === "ExportDefaultSpecifier" ||
|
|
spec.type === "ExportNamespaceSpecifier") {
|
|
unbracedSpecifiers_2.push(print(specifierPath));
|
|
}
|
|
else {
|
|
bracedSpecifiers_2.push(print(specifierPath));
|
|
}
|
|
}, "specifiers");
|
|
unbracedSpecifiers_2.forEach(function (lines, i) {
|
|
if (i > 0) {
|
|
parts.push(", ");
|
|
}
|
|
parts.push(lines);
|
|
});
|
|
if (bracedSpecifiers_2.length > 0) {
|
|
var lines_2 = (0, lines_1.fromString)(", ").join(bracedSpecifiers_2);
|
|
if (lines_2.getLineLength(1) > options.wrapColumn) {
|
|
lines_2 = (0, lines_1.concat)([
|
|
(0, lines_1.fromString)(",\n").join(bracedSpecifiers_2).indent(options.tabWidth),
|
|
",",
|
|
]);
|
|
}
|
|
if (unbracedSpecifiers_2.length > 0) {
|
|
parts.push(", ");
|
|
}
|
|
if (lines_2.length > 1) {
|
|
parts.push("{\n", lines_2, "\n}");
|
|
}
|
|
else if (options.objectCurlySpacing) {
|
|
parts.push("{ ", lines_2, " }");
|
|
}
|
|
else {
|
|
parts.push("{", lines_2, "}");
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
parts.push(shouldPrintSpaces ? "{ " : "{", (0, lines_1.fromString)(", ").join(path.map(print, "specifiers")), shouldPrintSpaces ? " }" : "}");
|
|
}
|
|
if (decl.source) {
|
|
parts.push(" from ", path.call(print, "source"), maybePrintImportAssertions(path, options, print));
|
|
}
|
|
}
|
|
var lines = (0, lines_1.concat)(parts);
|
|
if (lastNonSpaceCharacter(lines) !== ";" &&
|
|
!(decl.declaration &&
|
|
(decl.declaration.type === "FunctionDeclaration" ||
|
|
decl.declaration.type === "ClassDeclaration" ||
|
|
decl.declaration.type === "TSModuleDeclaration" ||
|
|
decl.declaration.type === "TSInterfaceDeclaration" ||
|
|
decl.declaration.type === "TSEnumDeclaration"))) {
|
|
lines = (0, lines_1.concat)([lines, ";"]);
|
|
}
|
|
return lines;
|
|
}
|
|
function printFlowDeclaration(path, parts) {
|
|
var parentExportDecl = util.getParentExportDeclaration(path);
|
|
if (parentExportDecl) {
|
|
(0, tiny_invariant_1.default)(parentExportDecl.type === "DeclareExportDeclaration");
|
|
}
|
|
else {
|
|
// If the parent node has type DeclareExportDeclaration, then it
|
|
// will be responsible for printing the "declare" token. Otherwise
|
|
// it needs to be printed with this non-exported declaration node.
|
|
parts.unshift("declare ");
|
|
}
|
|
return (0, lines_1.concat)(parts);
|
|
}
|
|
function printVariance(path, print) {
|
|
return path.call(function (variancePath) {
|
|
var value = variancePath.getValue();
|
|
if (value) {
|
|
if (value === "plus") {
|
|
return (0, lines_1.fromString)("+");
|
|
}
|
|
if (value === "minus") {
|
|
return (0, lines_1.fromString)("-");
|
|
}
|
|
return print(variancePath);
|
|
}
|
|
return (0, lines_1.fromString)("");
|
|
}, "variance");
|
|
}
|
|
function adjustClause(clause, options) {
|
|
if (clause.length > 1)
|
|
return (0, lines_1.concat)([" ", clause]);
|
|
return (0, lines_1.concat)(["\n", maybeAddSemicolon(clause).indent(options.tabWidth)]);
|
|
}
|
|
function lastNonSpaceCharacter(lines) {
|
|
var pos = lines.lastPos();
|
|
do {
|
|
var ch = lines.charAt(pos);
|
|
if (/\S/.test(ch))
|
|
return ch;
|
|
} while (lines.prevPos(pos));
|
|
}
|
|
function endsWithBrace(lines) {
|
|
return lastNonSpaceCharacter(lines) === "}";
|
|
}
|
|
function swapQuotes(str) {
|
|
return str.replace(/['"]/g, function (m) { return (m === '"' ? "'" : '"'); });
|
|
}
|
|
function getPossibleRaw(node) {
|
|
var value = types.getFieldValue(node, "value");
|
|
var extra = types.getFieldValue(node, "extra");
|
|
if (extra && typeof extra.raw === "string" && value == extra.rawValue) {
|
|
return extra.raw;
|
|
}
|
|
if (node.type === "Literal") {
|
|
var raw = node.raw;
|
|
if (typeof raw === "string" && value == raw) {
|
|
return raw;
|
|
}
|
|
}
|
|
}
|
|
function jsSafeStringify(str) {
|
|
return JSON.stringify(str).replace(/[\u2028\u2029]/g, function (m) {
|
|
return "\\u" + m.charCodeAt(0).toString(16);
|
|
});
|
|
}
|
|
function nodeStr(str, options) {
|
|
isString.assert(str);
|
|
switch (options.quote) {
|
|
case "auto": {
|
|
var double = jsSafeStringify(str);
|
|
var single = swapQuotes(jsSafeStringify(swapQuotes(str)));
|
|
return double.length > single.length ? single : double;
|
|
}
|
|
case "single":
|
|
return swapQuotes(jsSafeStringify(swapQuotes(str)));
|
|
case "double":
|
|
default:
|
|
return jsSafeStringify(str);
|
|
}
|
|
}
|
|
function maybeAddSemicolon(lines) {
|
|
var eoc = lastNonSpaceCharacter(lines);
|
|
if (!eoc || "\n};".indexOf(eoc) < 0)
|
|
return (0, lines_1.concat)([lines, ";"]);
|
|
return lines;
|
|
}
|
|
return printer;
|
|
}
|
|
|
|
var hasRequiredMain;
|
|
|
|
function requireMain () {
|
|
if (hasRequiredMain) return main$1;
|
|
hasRequiredMain = 1;
|
|
(function (exports$1) {
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
exports$1.run = exports$1.prettyPrint = exports$1.print = exports$1.visit = exports$1.types = exports$1.parse = void 0;
|
|
var tslib_1 = require$$0;
|
|
var fs_1 = tslib_1.__importDefault(fs);
|
|
var types = tslib_1.__importStar(requireMain$1());
|
|
exports$1.types = types;
|
|
var parser_1 = requireParser();
|
|
Object.defineProperty(exports$1, "parse", { enumerable: true, get: function () { return parser_1.parse; } });
|
|
var printer_1 = requirePrinter();
|
|
/**
|
|
* Traverse and potentially modify an abstract syntax tree using a
|
|
* convenient visitor syntax:
|
|
*
|
|
* recast.visit(ast, {
|
|
* names: [],
|
|
* visitIdentifier: function(path) {
|
|
* var node = path.value;
|
|
* this.visitor.names.push(node.name);
|
|
* this.traverse(path);
|
|
* }
|
|
* });
|
|
*/
|
|
var ast_types_1 = requireMain$1();
|
|
Object.defineProperty(exports$1, "visit", { enumerable: true, get: function () { return ast_types_1.visit; } });
|
|
/**
|
|
* Reprint a modified syntax tree using as much of the original source
|
|
* code as possible.
|
|
*/
|
|
function print(node, options) {
|
|
return new printer_1.Printer(options).print(node);
|
|
}
|
|
exports$1.print = print;
|
|
/**
|
|
* Print without attempting to reuse any original source code.
|
|
*/
|
|
function prettyPrint(node, options) {
|
|
return new printer_1.Printer(options).printGenerically(node);
|
|
}
|
|
exports$1.prettyPrint = prettyPrint;
|
|
/**
|
|
* Convenient command-line interface (see e.g. example/add-braces).
|
|
*/
|
|
function run(transformer, options) {
|
|
return runFile(process.argv[2], transformer, options);
|
|
}
|
|
exports$1.run = run;
|
|
function runFile(path, transformer, options) {
|
|
fs_1.default.readFile(path, "utf-8", function (err, code) {
|
|
if (err) {
|
|
console.error(err);
|
|
return;
|
|
}
|
|
runString(code, transformer, options);
|
|
});
|
|
}
|
|
function defaultWriteback(output) {
|
|
process.stdout.write(output);
|
|
}
|
|
function runString(code, transformer, options) {
|
|
var writeback = (options && options.writeback) || defaultWriteback;
|
|
transformer((0, parser_1.parse)(code, options), function (node) {
|
|
writeback(print(node, options).code);
|
|
});
|
|
}
|
|
} (main$1));
|
|
return main$1;
|
|
}
|
|
|
|
var mainExports = requireMain();
|
|
|
|
var babelTs$1 = {};
|
|
|
|
var babel = {};
|
|
|
|
var _babel_options = {};
|
|
|
|
var hasRequired_babel_options;
|
|
|
|
function require_babel_options () {
|
|
if (hasRequired_babel_options) return _babel_options;
|
|
hasRequired_babel_options = 1;
|
|
Object.defineProperty(_babel_options, "__esModule", { value: true });
|
|
var util_1 = requireUtil();
|
|
function getBabelOptions(options) {
|
|
// The goal here is to tolerate as much syntax as possible, since Recast
|
|
// is not in the business of forbidding anything. If you want your
|
|
// parser to be more restrictive for some reason, you can always pass
|
|
// your own parser object to recast.parse.
|
|
return {
|
|
sourceType: (0, util_1.getOption)(options, "sourceType", "module"),
|
|
strictMode: (0, util_1.getOption)(options, "strictMode", false),
|
|
allowImportExportEverywhere: true,
|
|
allowReturnOutsideFunction: true,
|
|
startLine: 1,
|
|
tokens: true,
|
|
plugins: [
|
|
"asyncGenerators",
|
|
"bigInt",
|
|
"classPrivateMethods",
|
|
"classPrivateProperties",
|
|
"classProperties",
|
|
"classStaticBlock",
|
|
"decimal",
|
|
"decorators-legacy",
|
|
"doExpressions",
|
|
"dynamicImport",
|
|
"exportDefaultFrom",
|
|
"exportExtensions",
|
|
"exportNamespaceFrom",
|
|
"functionBind",
|
|
"functionSent",
|
|
"importAssertions",
|
|
"importMeta",
|
|
"nullishCoalescingOperator",
|
|
"numericSeparator",
|
|
"objectRestSpread",
|
|
"optionalCatchBinding",
|
|
"optionalChaining",
|
|
[
|
|
"pipelineOperator",
|
|
{
|
|
proposal: "minimal",
|
|
},
|
|
],
|
|
[
|
|
"recordAndTuple",
|
|
{
|
|
syntaxType: "hash",
|
|
},
|
|
],
|
|
"throwExpressions",
|
|
"topLevelAwait",
|
|
"v8intrinsic",
|
|
],
|
|
};
|
|
}
|
|
_babel_options.default = getBabelOptions;
|
|
return _babel_options;
|
|
}
|
|
|
|
var lib = {};
|
|
|
|
var hasRequiredLib;
|
|
|
|
function requireLib () {
|
|
if (hasRequiredLib) return lib;
|
|
hasRequiredLib = 1;
|
|
|
|
Object.defineProperty(lib, '__esModule', {
|
|
value: true
|
|
});
|
|
function _objectWithoutPropertiesLoose(r, e) {
|
|
if (null == r) return {};
|
|
var t = {};
|
|
for (var n in r) if ({}.hasOwnProperty.call(r, n)) {
|
|
if (-1 !== e.indexOf(n)) continue;
|
|
t[n] = r[n];
|
|
}
|
|
return t;
|
|
}
|
|
class Position {
|
|
constructor(line, col, index) {
|
|
this.line = void 0;
|
|
this.column = void 0;
|
|
this.index = void 0;
|
|
this.line = line;
|
|
this.column = col;
|
|
this.index = index;
|
|
}
|
|
}
|
|
class SourceLocation {
|
|
constructor(start, end) {
|
|
this.start = void 0;
|
|
this.end = void 0;
|
|
this.filename = void 0;
|
|
this.identifierName = void 0;
|
|
this.start = start;
|
|
this.end = end;
|
|
}
|
|
}
|
|
function createPositionWithColumnOffset(position, columnOffset) {
|
|
const {
|
|
line,
|
|
column,
|
|
index
|
|
} = position;
|
|
return new Position(line, column + columnOffset, index + columnOffset);
|
|
}
|
|
const code = "BABEL_PARSER_SOURCETYPE_MODULE_REQUIRED";
|
|
var ModuleErrors = {
|
|
ImportMetaOutsideModule: {
|
|
message: `import.meta may appear only with 'sourceType: "module"'`,
|
|
code
|
|
},
|
|
ImportOutsideModule: {
|
|
message: `'import' and 'export' may appear only with 'sourceType: "module"'`,
|
|
code
|
|
}
|
|
};
|
|
const NodeDescriptions = {
|
|
ArrayPattern: "array destructuring pattern",
|
|
AssignmentExpression: "assignment expression",
|
|
AssignmentPattern: "assignment expression",
|
|
ArrowFunctionExpression: "arrow function expression",
|
|
ConditionalExpression: "conditional expression",
|
|
CatchClause: "catch clause",
|
|
ForOfStatement: "for-of statement",
|
|
ForInStatement: "for-in statement",
|
|
ForStatement: "for-loop",
|
|
FormalParameters: "function parameter list",
|
|
Identifier: "identifier",
|
|
ImportSpecifier: "import specifier",
|
|
ImportDefaultSpecifier: "import default specifier",
|
|
ImportNamespaceSpecifier: "import namespace specifier",
|
|
ObjectPattern: "object destructuring pattern",
|
|
ParenthesizedExpression: "parenthesized expression",
|
|
RestElement: "rest element",
|
|
UpdateExpression: {
|
|
true: "prefix operation",
|
|
false: "postfix operation"
|
|
},
|
|
VariableDeclarator: "variable declaration",
|
|
YieldExpression: "yield expression"
|
|
};
|
|
const toNodeDescription = node => node.type === "UpdateExpression" ? NodeDescriptions.UpdateExpression[`${node.prefix}`] : NodeDescriptions[node.type];
|
|
var StandardErrors = {
|
|
AccessorIsGenerator: ({
|
|
kind
|
|
}) => `A ${kind}ter cannot be a generator.`,
|
|
ArgumentsInClass: "'arguments' is only allowed in functions and class methods.",
|
|
AsyncFunctionInSingleStatementContext: "Async functions can only be declared at the top level or inside a block.",
|
|
AwaitBindingIdentifier: "Can not use 'await' as identifier inside an async function.",
|
|
AwaitBindingIdentifierInStaticBlock: "Can not use 'await' as identifier inside a static block.",
|
|
AwaitExpressionFormalParameter: "'await' is not allowed in async function parameters.",
|
|
AwaitUsingNotInAsyncContext: "'await using' is only allowed within async functions and at the top levels of modules.",
|
|
AwaitNotInAsyncContext: "'await' is only allowed within async functions and at the top levels of modules.",
|
|
BadGetterArity: "A 'get' accessor must not have any formal parameters.",
|
|
BadSetterArity: "A 'set' accessor must have exactly one formal parameter.",
|
|
BadSetterRestParameter: "A 'set' accessor function argument must not be a rest parameter.",
|
|
ConstructorClassField: "Classes may not have a field named 'constructor'.",
|
|
ConstructorClassPrivateField: "Classes may not have a private field named '#constructor'.",
|
|
ConstructorIsAccessor: "Class constructor may not be an accessor.",
|
|
ConstructorIsAsync: "Constructor can't be an async function.",
|
|
ConstructorIsGenerator: "Constructor can't be a generator.",
|
|
DeclarationMissingInitializer: ({
|
|
kind
|
|
}) => `Missing initializer in ${kind} declaration.`,
|
|
DecoratorArgumentsOutsideParentheses: "Decorator arguments must be moved inside parentheses: use '@(decorator(args))' instead of '@(decorator)(args)'.",
|
|
DecoratorBeforeExport: "Decorators must be placed *before* the 'export' keyword. Remove the 'decoratorsBeforeExport: true' option to use the 'export @decorator class {}' syntax.",
|
|
DecoratorsBeforeAfterExport: "Decorators can be placed *either* before or after the 'export' keyword, but not in both locations at the same time.",
|
|
DecoratorConstructor: "Decorators can't be used with a constructor. Did you mean '@dec class { ... }'?",
|
|
DecoratorExportClass: "Decorators must be placed *after* the 'export' keyword. Remove the 'decoratorsBeforeExport: false' option to use the '@decorator export class {}' syntax.",
|
|
DecoratorSemicolon: "Decorators must not be followed by a semicolon.",
|
|
DecoratorStaticBlock: "Decorators can't be used with a static block.",
|
|
DeferImportRequiresNamespace: 'Only `import defer * as x from "./module"` is valid.',
|
|
DeletePrivateField: "Deleting a private field is not allowed.",
|
|
DestructureNamedImport: "ES2015 named imports do not destructure. Use another statement for destructuring after the import.",
|
|
DuplicateConstructor: "Duplicate constructor in the same class.",
|
|
DuplicateDefaultExport: "Only one default export allowed per module.",
|
|
DuplicateExport: ({
|
|
exportName
|
|
}) => `\`${exportName}\` has already been exported. Exported identifiers must be unique.`,
|
|
DuplicateProto: "Redefinition of __proto__ property.",
|
|
DuplicateRegExpFlags: "Duplicate regular expression flag.",
|
|
ElementAfterRest: "Rest element must be last element.",
|
|
EscapedCharNotAnIdentifier: "Invalid Unicode escape.",
|
|
ExportBindingIsString: ({
|
|
localName,
|
|
exportName
|
|
}) => `A string literal cannot be used as an exported binding without \`from\`.\n- Did you mean \`export { '${localName}' as '${exportName}' } from 'some-module'\`?`,
|
|
ExportDefaultFromAsIdentifier: "'from' is not allowed as an identifier after 'export default'.",
|
|
ForInOfLoopInitializer: ({
|
|
type
|
|
}) => `'${type === "ForInStatement" ? "for-in" : "for-of"}' loop variable declaration may not have an initializer.`,
|
|
ForInUsing: "For-in loop may not start with 'using' declaration.",
|
|
ForOfAsync: "The left-hand side of a for-of loop may not be 'async'.",
|
|
ForOfLet: "The left-hand side of a for-of loop may not start with 'let'.",
|
|
GeneratorInSingleStatementContext: "Generators can only be declared at the top level or inside a block.",
|
|
IllegalBreakContinue: ({
|
|
type
|
|
}) => `Unsyntactic ${type === "BreakStatement" ? "break" : "continue"}.`,
|
|
IllegalLanguageModeDirective: "Illegal 'use strict' directive in function with non-simple parameter list.",
|
|
IllegalReturn: "'return' outside of function.",
|
|
ImportAttributesUseAssert: "The `assert` keyword in import attributes is deprecated and it has been replaced by the `with` keyword. You can enable the `deprecatedImportAssert` parser plugin to suppress this error.",
|
|
ImportBindingIsString: ({
|
|
importName
|
|
}) => `A string literal cannot be used as an imported binding.\n- Did you mean \`import { "${importName}" as foo }\`?`,
|
|
ImportCallArity: `\`import()\` requires exactly one or two arguments.`,
|
|
ImportCallNotNewExpression: "Cannot use new with import(...).",
|
|
ImportCallSpreadArgument: "`...` is not allowed in `import()`.",
|
|
ImportJSONBindingNotDefault: "A JSON module can only be imported with `default`.",
|
|
ImportReflectionHasAssertion: "`import module x` cannot have assertions.",
|
|
ImportReflectionNotBinding: 'Only `import module x from "./module"` is valid.',
|
|
IncompatibleRegExpUVFlags: "The 'u' and 'v' regular expression flags cannot be enabled at the same time.",
|
|
InvalidBigIntLiteral: "Invalid BigIntLiteral.",
|
|
InvalidCodePoint: "Code point out of bounds.",
|
|
InvalidCoverDiscardElement: "'void' must be followed by an expression when not used in a binding position.",
|
|
InvalidCoverInitializedName: "Invalid shorthand property initializer.",
|
|
InvalidDecimal: "Invalid decimal.",
|
|
InvalidDigit: ({
|
|
radix
|
|
}) => `Expected number in radix ${radix}.`,
|
|
InvalidEscapeSequence: "Bad character escape sequence.",
|
|
InvalidEscapeSequenceTemplate: "Invalid escape sequence in template.",
|
|
InvalidEscapedReservedWord: ({
|
|
reservedWord
|
|
}) => `Escape sequence in keyword ${reservedWord}.`,
|
|
InvalidIdentifier: ({
|
|
identifierName
|
|
}) => `Invalid identifier ${identifierName}.`,
|
|
InvalidLhs: ({
|
|
ancestor
|
|
}) => `Invalid left-hand side in ${toNodeDescription(ancestor)}.`,
|
|
InvalidLhsBinding: ({
|
|
ancestor
|
|
}) => `Binding invalid left-hand side in ${toNodeDescription(ancestor)}.`,
|
|
InvalidLhsOptionalChaining: ({
|
|
ancestor
|
|
}) => `Invalid optional chaining in the left-hand side of ${toNodeDescription(ancestor)}.`,
|
|
InvalidNumber: "Invalid number.",
|
|
InvalidOrMissingExponent: "Floating-point numbers require a valid exponent after the 'e'.",
|
|
InvalidOrUnexpectedToken: ({
|
|
unexpected
|
|
}) => `Unexpected character '${unexpected}'.`,
|
|
InvalidParenthesizedAssignment: "Invalid parenthesized assignment pattern.",
|
|
InvalidPrivateFieldResolution: ({
|
|
identifierName
|
|
}) => `Private name #${identifierName} is not defined.`,
|
|
InvalidPropertyBindingPattern: "Binding member expression.",
|
|
InvalidRecordProperty: "Only properties and spread elements are allowed in record definitions.",
|
|
InvalidRestAssignmentPattern: "Invalid rest operator's argument.",
|
|
LabelRedeclaration: ({
|
|
labelName
|
|
}) => `Label '${labelName}' is already declared.`,
|
|
LetInLexicalBinding: "'let' is disallowed as a lexically bound name.",
|
|
LineTerminatorBeforeArrow: "No line break is allowed before '=>'.",
|
|
MalformedRegExpFlags: "Invalid regular expression flag.",
|
|
MissingClassName: "A class name is required.",
|
|
MissingEqInAssignment: "Only '=' operator can be used for specifying default value.",
|
|
MissingSemicolon: "Missing semicolon.",
|
|
MissingPlugin: ({
|
|
missingPlugin
|
|
}) => `This experimental syntax requires enabling the parser plugin: ${missingPlugin.map(name => JSON.stringify(name)).join(", ")}.`,
|
|
MissingOneOfPlugins: ({
|
|
missingPlugin
|
|
}) => `This experimental syntax requires enabling one of the following parser plugin(s): ${missingPlugin.map(name => JSON.stringify(name)).join(", ")}.`,
|
|
MissingUnicodeEscape: "Expecting Unicode escape sequence \\uXXXX.",
|
|
MixingCoalesceWithLogical: "Nullish coalescing operator(??) requires parens when mixing with logical operators.",
|
|
ModuleAttributeDifferentFromType: "The only accepted module attribute is `type`.",
|
|
ModuleAttributeInvalidValue: "Only string literals are allowed as module attribute values.",
|
|
ModuleAttributesWithDuplicateKeys: ({
|
|
key
|
|
}) => `Duplicate key "${key}" is not allowed in module attributes.`,
|
|
ModuleExportNameHasLoneSurrogate: ({
|
|
surrogateCharCode
|
|
}) => `An export name cannot include a lone surrogate, found '\\u${surrogateCharCode.toString(16)}'.`,
|
|
ModuleExportUndefined: ({
|
|
localName
|
|
}) => `Export '${localName}' is not defined.`,
|
|
MultipleDefaultsInSwitch: "Multiple default clauses.",
|
|
NewlineAfterThrow: "Illegal newline after throw.",
|
|
NoCatchOrFinally: "Missing catch or finally clause.",
|
|
NumberIdentifier: "Identifier directly after number.",
|
|
NumericSeparatorInEscapeSequence: "Numeric separators are not allowed inside unicode escape sequences or hex escape sequences.",
|
|
ObsoleteAwaitStar: "'await*' has been removed from the async functions proposal. Use Promise.all() instead.",
|
|
OptionalChainingNoNew: "Constructors in/after an Optional Chain are not allowed.",
|
|
OptionalChainingNoTemplate: "Tagged Template Literals are not allowed in optionalChain.",
|
|
OverrideOnConstructor: "'override' modifier cannot appear on a constructor declaration.",
|
|
ParamDupe: "Argument name clash.",
|
|
PatternHasAccessor: "Object pattern can't contain getter or setter.",
|
|
PatternHasMethod: "Object pattern can't contain methods.",
|
|
PrivateInExpectedIn: ({
|
|
identifierName
|
|
}) => `Private names are only allowed in property accesses (\`obj.#${identifierName}\`) or in \`in\` expressions (\`#${identifierName} in obj\`).`,
|
|
PrivateNameRedeclaration: ({
|
|
identifierName
|
|
}) => `Duplicate private name #${identifierName}.`,
|
|
RecordExpressionBarIncorrectEndSyntaxType: "Record expressions ending with '|}' are only allowed when the 'syntaxType' option of the 'recordAndTuple' plugin is set to 'bar'.",
|
|
RecordExpressionBarIncorrectStartSyntaxType: "Record expressions starting with '{|' are only allowed when the 'syntaxType' option of the 'recordAndTuple' plugin is set to 'bar'.",
|
|
RecordExpressionHashIncorrectStartSyntaxType: "Record expressions starting with '#{' are only allowed when the 'syntaxType' option of the 'recordAndTuple' plugin is set to 'hash'.",
|
|
RecordNoProto: "'__proto__' is not allowed in Record expressions.",
|
|
RestTrailingComma: "Unexpected trailing comma after rest element.",
|
|
SloppyFunction: "In non-strict mode code, functions can only be declared at top level or inside a block.",
|
|
SloppyFunctionAnnexB: "In non-strict mode code, functions can only be declared at top level, inside a block, or as the body of an if statement.",
|
|
SourcePhaseImportRequiresDefault: 'Only `import source x from "./module"` is valid.',
|
|
StaticPrototype: "Classes may not have static property named prototype.",
|
|
SuperNotAllowed: "`super()` is only valid inside a class constructor of a subclass. Maybe a typo in the method name ('constructor') or not extending another class?",
|
|
SuperPrivateField: "Private fields can't be accessed on super.",
|
|
TrailingDecorator: "Decorators must be attached to a class element.",
|
|
TupleExpressionBarIncorrectEndSyntaxType: "Tuple expressions ending with '|]' are only allowed when the 'syntaxType' option of the 'recordAndTuple' plugin is set to 'bar'.",
|
|
TupleExpressionBarIncorrectStartSyntaxType: "Tuple expressions starting with '[|' are only allowed when the 'syntaxType' option of the 'recordAndTuple' plugin is set to 'bar'.",
|
|
TupleExpressionHashIncorrectStartSyntaxType: "Tuple expressions starting with '#[' are only allowed when the 'syntaxType' option of the 'recordAndTuple' plugin is set to 'hash'.",
|
|
UnexpectedArgumentPlaceholder: "Unexpected argument placeholder.",
|
|
UnexpectedAwaitAfterPipelineBody: 'Unexpected "await" after pipeline body; await must have parentheses in minimal proposal.',
|
|
UnexpectedDigitAfterHash: "Unexpected digit after hash token.",
|
|
UnexpectedImportExport: "'import' and 'export' may only appear at the top level.",
|
|
UnexpectedKeyword: ({
|
|
keyword
|
|
}) => `Unexpected keyword '${keyword}'.`,
|
|
UnexpectedLeadingDecorator: "Leading decorators must be attached to a class declaration.",
|
|
UnexpectedLexicalDeclaration: "Lexical declaration cannot appear in a single-statement context.",
|
|
UnexpectedNewTarget: "`new.target` can only be used in functions or class properties.",
|
|
UnexpectedNumericSeparator: "A numeric separator is only allowed between two digits.",
|
|
UnexpectedPrivateField: "Unexpected private name.",
|
|
UnexpectedReservedWord: ({
|
|
reservedWord
|
|
}) => `Unexpected reserved word '${reservedWord}'.`,
|
|
UnexpectedSuper: "'super' is only allowed in object methods and classes.",
|
|
UnexpectedToken: ({
|
|
expected,
|
|
unexpected
|
|
}) => `Unexpected token${unexpected ? ` '${unexpected}'.` : ""}${expected ? `, expected "${expected}"` : ""}`,
|
|
UnexpectedTokenUnaryExponentiation: "Illegal expression. Wrap left hand side or entire exponentiation in parentheses.",
|
|
UnexpectedUsingDeclaration: "Using declaration cannot appear in the top level when source type is `script` or in the bare case statement.",
|
|
UnexpectedVoidPattern: "Unexpected void binding.",
|
|
UnsupportedBind: "Binding should be performed on object property.",
|
|
UnsupportedDecoratorExport: "A decorated export must export a class declaration.",
|
|
UnsupportedDefaultExport: "Only expressions, functions or classes are allowed as the `default` export.",
|
|
UnsupportedImport: "`import` can only be used in `import()` or `import.meta`.",
|
|
UnsupportedMetaProperty: ({
|
|
target,
|
|
onlyValidPropertyName
|
|
}) => `The only valid meta property for ${target} is ${target}.${onlyValidPropertyName}.`,
|
|
UnsupportedParameterDecorator: "Decorators cannot be used to decorate parameters.",
|
|
UnsupportedPropertyDecorator: "Decorators cannot be used to decorate object literal properties.",
|
|
UnsupportedSuper: "'super' can only be used with function calls (i.e. super()) or in property accesses (i.e. super.prop or super[prop]).",
|
|
UnterminatedComment: "Unterminated comment.",
|
|
UnterminatedRegExp: "Unterminated regular expression.",
|
|
UnterminatedString: "Unterminated string constant.",
|
|
UnterminatedTemplate: "Unterminated template.",
|
|
UsingDeclarationExport: "Using declaration cannot be exported.",
|
|
UsingDeclarationHasBindingPattern: "Using declaration cannot have destructuring patterns.",
|
|
VarRedeclaration: ({
|
|
identifierName
|
|
}) => `Identifier '${identifierName}' has already been declared.`,
|
|
VoidPatternCatchClauseParam: "A void binding can not be the catch clause parameter. Use `try { ... } catch { ... }` if you want to discard the caught error.",
|
|
VoidPatternInitializer: "A void binding may not have an initializer.",
|
|
YieldBindingIdentifier: "Can not use 'yield' as identifier inside a generator.",
|
|
YieldInParameter: "Yield expression is not allowed in formal parameters.",
|
|
YieldNotInGeneratorFunction: "'yield' is only allowed within generator functions.",
|
|
ZeroDigitNumericSeparator: "Numeric separator can not be used after leading 0."
|
|
};
|
|
var StrictModeErrors = {
|
|
StrictDelete: "Deleting local variable in strict mode.",
|
|
StrictEvalArguments: ({
|
|
referenceName
|
|
}) => `Assigning to '${referenceName}' in strict mode.`,
|
|
StrictEvalArgumentsBinding: ({
|
|
bindingName
|
|
}) => `Binding '${bindingName}' in strict mode.`,
|
|
StrictFunction: "In strict mode code, functions can only be declared at top level or inside a block.",
|
|
StrictNumericEscape: "The only valid numeric escape in strict mode is '\\0'.",
|
|
StrictOctalLiteral: "Legacy octal literals are not allowed in strict mode.",
|
|
StrictWith: "'with' in strict mode."
|
|
};
|
|
var ParseExpressionErrors = {
|
|
ParseExpressionEmptyInput: "Unexpected parseExpression() input: The input is empty or contains only comments.",
|
|
ParseExpressionExpectsEOF: ({
|
|
unexpected
|
|
}) => `Unexpected parseExpression() input: The input should contain exactly one expression, but the first expression is followed by the unexpected character \`${String.fromCodePoint(unexpected)}\`.`
|
|
};
|
|
const UnparenthesizedPipeBodyDescriptions = new Set(["ArrowFunctionExpression", "AssignmentExpression", "ConditionalExpression", "YieldExpression"]);
|
|
var PipelineOperatorErrors = Object.assign({
|
|
PipeBodyIsTighter: "Unexpected yield after pipeline body; any yield expression acting as Hack-style pipe body must be parenthesized due to its loose operator precedence.",
|
|
PipeTopicRequiresHackPipes: 'Topic reference is used, but the pipelineOperator plugin was not passed a "proposal": "hack" or "smart" option.',
|
|
PipeTopicUnbound: "Topic reference is unbound; it must be inside a pipe body.",
|
|
PipeTopicUnconfiguredToken: ({
|
|
token
|
|
}) => `Invalid topic token ${token}. In order to use ${token} as a topic reference, the pipelineOperator plugin must be configured with { "proposal": "hack", "topicToken": "${token}" }.`,
|
|
PipeTopicUnused: "Hack-style pipe body does not contain a topic reference; Hack-style pipes must use topic at least once.",
|
|
PipeUnparenthesizedBody: ({
|
|
type
|
|
}) => `Hack-style pipe body cannot be an unparenthesized ${toNodeDescription({
|
|
type
|
|
})}; please wrap it in parentheses.`
|
|
}, {
|
|
PipelineBodyNoArrow: 'Unexpected arrow "=>" after pipeline body; arrow function in pipeline body must be parenthesized.',
|
|
PipelineBodySequenceExpression: "Pipeline body may not be a comma-separated sequence expression.",
|
|
PipelineHeadSequenceExpression: "Pipeline head should not be a comma-separated sequence expression.",
|
|
PipelineTopicUnused: "Pipeline is in topic style but does not use topic reference.",
|
|
PrimaryTopicNotAllowed: "Topic reference was used in a lexical context without topic binding.",
|
|
PrimaryTopicRequiresSmartPipeline: 'Topic reference is used, but the pipelineOperator plugin was not passed a "proposal": "hack" or "smart" option.'
|
|
});
|
|
const _excluded = ["message"];
|
|
function defineHidden(obj, key, value) {
|
|
Object.defineProperty(obj, key, {
|
|
enumerable: false,
|
|
configurable: true,
|
|
value
|
|
});
|
|
}
|
|
function toParseErrorConstructor({
|
|
toMessage,
|
|
code,
|
|
reasonCode,
|
|
syntaxPlugin
|
|
}) {
|
|
const hasMissingPlugin = reasonCode === "MissingPlugin" || reasonCode === "MissingOneOfPlugins";
|
|
{
|
|
const oldReasonCodes = {
|
|
AccessorCannotDeclareThisParameter: "AccesorCannotDeclareThisParameter",
|
|
AccessorCannotHaveTypeParameters: "AccesorCannotHaveTypeParameters",
|
|
ConstInitializerMustBeStringOrNumericLiteralOrLiteralEnumReference: "ConstInitiailizerMustBeStringOrNumericLiteralOrLiteralEnumReference",
|
|
SetAccessorCannotHaveOptionalParameter: "SetAccesorCannotHaveOptionalParameter",
|
|
SetAccessorCannotHaveRestParameter: "SetAccesorCannotHaveRestParameter",
|
|
SetAccessorCannotHaveReturnType: "SetAccesorCannotHaveReturnType"
|
|
};
|
|
if (oldReasonCodes[reasonCode]) {
|
|
reasonCode = oldReasonCodes[reasonCode];
|
|
}
|
|
}
|
|
return function constructor(loc, details) {
|
|
const error = new SyntaxError();
|
|
error.code = code;
|
|
error.reasonCode = reasonCode;
|
|
error.loc = loc;
|
|
error.pos = loc.index;
|
|
error.syntaxPlugin = syntaxPlugin;
|
|
if (hasMissingPlugin) {
|
|
error.missingPlugin = details.missingPlugin;
|
|
}
|
|
defineHidden(error, "clone", function clone(overrides = {}) {
|
|
var _overrides$loc;
|
|
const {
|
|
line,
|
|
column,
|
|
index
|
|
} = (_overrides$loc = overrides.loc) != null ? _overrides$loc : loc;
|
|
return constructor(new Position(line, column, index), Object.assign({}, details, overrides.details));
|
|
});
|
|
defineHidden(error, "details", details);
|
|
Object.defineProperty(error, "message", {
|
|
configurable: true,
|
|
get() {
|
|
const message = `${toMessage(details)} (${loc.line}:${loc.column})`;
|
|
this.message = message;
|
|
return message;
|
|
},
|
|
set(value) {
|
|
Object.defineProperty(this, "message", {
|
|
value,
|
|
writable: true
|
|
});
|
|
}
|
|
});
|
|
return error;
|
|
};
|
|
}
|
|
function ParseErrorEnum(argument, syntaxPlugin) {
|
|
if (Array.isArray(argument)) {
|
|
return parseErrorTemplates => ParseErrorEnum(parseErrorTemplates, argument[0]);
|
|
}
|
|
const ParseErrorConstructors = {};
|
|
for (const reasonCode of Object.keys(argument)) {
|
|
const template = argument[reasonCode];
|
|
const _ref = typeof template === "string" ? {
|
|
message: () => template
|
|
} : typeof template === "function" ? {
|
|
message: template
|
|
} : template,
|
|
{
|
|
message
|
|
} = _ref,
|
|
rest = _objectWithoutPropertiesLoose(_ref, _excluded);
|
|
const toMessage = typeof message === "string" ? () => message : message;
|
|
ParseErrorConstructors[reasonCode] = toParseErrorConstructor(Object.assign({
|
|
code: "BABEL_PARSER_SYNTAX_ERROR",
|
|
reasonCode,
|
|
toMessage
|
|
}, syntaxPlugin ? {
|
|
syntaxPlugin
|
|
} : {}, rest));
|
|
}
|
|
return ParseErrorConstructors;
|
|
}
|
|
const Errors = Object.assign({}, ParseErrorEnum(ModuleErrors), ParseErrorEnum(StandardErrors), ParseErrorEnum(StrictModeErrors), ParseErrorEnum(ParseExpressionErrors), ParseErrorEnum`pipelineOperator`(PipelineOperatorErrors));
|
|
function createDefaultOptions() {
|
|
return {
|
|
sourceType: "script",
|
|
sourceFilename: undefined,
|
|
startIndex: 0,
|
|
startColumn: 0,
|
|
startLine: 1,
|
|
allowAwaitOutsideFunction: false,
|
|
allowReturnOutsideFunction: false,
|
|
allowNewTargetOutsideFunction: false,
|
|
allowImportExportEverywhere: false,
|
|
allowSuperOutsideMethod: false,
|
|
allowUndeclaredExports: false,
|
|
allowYieldOutsideFunction: false,
|
|
plugins: [],
|
|
strictMode: undefined,
|
|
ranges: false,
|
|
tokens: false,
|
|
createImportExpressions: false,
|
|
createParenthesizedExpressions: false,
|
|
errorRecovery: false,
|
|
attachComment: true,
|
|
annexB: true
|
|
};
|
|
}
|
|
function getOptions(opts) {
|
|
const options = createDefaultOptions();
|
|
if (opts == null) {
|
|
return options;
|
|
}
|
|
if (opts.annexB != null && opts.annexB !== false) {
|
|
throw new Error("The `annexB` option can only be set to `false`.");
|
|
}
|
|
for (const key of Object.keys(options)) {
|
|
if (opts[key] != null) options[key] = opts[key];
|
|
}
|
|
if (options.startLine === 1) {
|
|
if (opts.startIndex == null && options.startColumn > 0) {
|
|
options.startIndex = options.startColumn;
|
|
} else if (opts.startColumn == null && options.startIndex > 0) {
|
|
options.startColumn = options.startIndex;
|
|
}
|
|
} else if (opts.startColumn == null || opts.startIndex == null) {
|
|
if (opts.startIndex != null) {
|
|
throw new Error("With a `startLine > 1` you must also specify `startIndex` and `startColumn`.");
|
|
}
|
|
}
|
|
if (options.sourceType === "commonjs") {
|
|
if (opts.allowAwaitOutsideFunction != null) {
|
|
throw new Error("The `allowAwaitOutsideFunction` option cannot be used with `sourceType: 'commonjs'`.");
|
|
}
|
|
if (opts.allowReturnOutsideFunction != null) {
|
|
throw new Error("`sourceType: 'commonjs'` implies `allowReturnOutsideFunction: true`, please remove the `allowReturnOutsideFunction` option or use `sourceType: 'script'`.");
|
|
}
|
|
if (opts.allowNewTargetOutsideFunction != null) {
|
|
throw new Error("`sourceType: 'commonjs'` implies `allowNewTargetOutsideFunction: true`, please remove the `allowNewTargetOutsideFunction` option or use `sourceType: 'script'`.");
|
|
}
|
|
}
|
|
return options;
|
|
}
|
|
const {
|
|
defineProperty
|
|
} = Object;
|
|
const toUnenumerable = (object, key) => {
|
|
if (object) {
|
|
defineProperty(object, key, {
|
|
enumerable: false,
|
|
value: object[key]
|
|
});
|
|
}
|
|
};
|
|
function toESTreeLocation(node) {
|
|
toUnenumerable(node.loc.start, "index");
|
|
toUnenumerable(node.loc.end, "index");
|
|
return node;
|
|
}
|
|
var estree = superClass => class ESTreeParserMixin extends superClass {
|
|
parse() {
|
|
const file = toESTreeLocation(super.parse());
|
|
if (this.optionFlags & 256) {
|
|
file.tokens = file.tokens.map(toESTreeLocation);
|
|
}
|
|
return file;
|
|
}
|
|
parseRegExpLiteral({
|
|
pattern,
|
|
flags
|
|
}) {
|
|
let regex = null;
|
|
try {
|
|
regex = new RegExp(pattern, flags);
|
|
} catch (_) {}
|
|
const node = this.estreeParseLiteral(regex);
|
|
node.regex = {
|
|
pattern,
|
|
flags
|
|
};
|
|
return node;
|
|
}
|
|
parseBigIntLiteral(value) {
|
|
let bigInt;
|
|
try {
|
|
bigInt = BigInt(value);
|
|
} catch (_unused) {
|
|
bigInt = null;
|
|
}
|
|
const node = this.estreeParseLiteral(bigInt);
|
|
node.bigint = String(node.value || value);
|
|
return node;
|
|
}
|
|
parseDecimalLiteral(value) {
|
|
const decimal = null;
|
|
const node = this.estreeParseLiteral(decimal);
|
|
node.decimal = String(node.value || value);
|
|
return node;
|
|
}
|
|
estreeParseLiteral(value) {
|
|
return this.parseLiteral(value, "Literal");
|
|
}
|
|
parseStringLiteral(value) {
|
|
return this.estreeParseLiteral(value);
|
|
}
|
|
parseNumericLiteral(value) {
|
|
return this.estreeParseLiteral(value);
|
|
}
|
|
parseNullLiteral() {
|
|
return this.estreeParseLiteral(null);
|
|
}
|
|
parseBooleanLiteral(value) {
|
|
return this.estreeParseLiteral(value);
|
|
}
|
|
estreeParseChainExpression(node, endLoc) {
|
|
const chain = this.startNodeAtNode(node);
|
|
chain.expression = node;
|
|
return this.finishNodeAt(chain, "ChainExpression", endLoc);
|
|
}
|
|
directiveToStmt(directive) {
|
|
const expression = directive.value;
|
|
delete directive.value;
|
|
this.castNodeTo(expression, "Literal");
|
|
expression.raw = expression.extra.raw;
|
|
expression.value = expression.extra.expressionValue;
|
|
const stmt = this.castNodeTo(directive, "ExpressionStatement");
|
|
stmt.expression = expression;
|
|
stmt.directive = expression.extra.rawValue;
|
|
delete expression.extra;
|
|
return stmt;
|
|
}
|
|
fillOptionalPropertiesForTSESLint(node) {}
|
|
cloneEstreeStringLiteral(node) {
|
|
const {
|
|
start,
|
|
end,
|
|
loc,
|
|
range,
|
|
raw,
|
|
value
|
|
} = node;
|
|
const cloned = Object.create(node.constructor.prototype);
|
|
cloned.type = "Literal";
|
|
cloned.start = start;
|
|
cloned.end = end;
|
|
cloned.loc = loc;
|
|
cloned.range = range;
|
|
cloned.raw = raw;
|
|
cloned.value = value;
|
|
return cloned;
|
|
}
|
|
initFunction(node, isAsync) {
|
|
super.initFunction(node, isAsync);
|
|
node.expression = false;
|
|
}
|
|
checkDeclaration(node) {
|
|
if (node != null && this.isObjectProperty(node)) {
|
|
this.checkDeclaration(node.value);
|
|
} else {
|
|
super.checkDeclaration(node);
|
|
}
|
|
}
|
|
getObjectOrClassMethodParams(method) {
|
|
return method.value.params;
|
|
}
|
|
isValidDirective(stmt) {
|
|
var _stmt$expression$extr;
|
|
return stmt.type === "ExpressionStatement" && stmt.expression.type === "Literal" && typeof stmt.expression.value === "string" && !((_stmt$expression$extr = stmt.expression.extra) != null && _stmt$expression$extr.parenthesized);
|
|
}
|
|
parseBlockBody(node, allowDirectives, topLevel, end, afterBlockParse) {
|
|
super.parseBlockBody(node, allowDirectives, topLevel, end, afterBlockParse);
|
|
const directiveStatements = node.directives.map(d => this.directiveToStmt(d));
|
|
node.body = directiveStatements.concat(node.body);
|
|
delete node.directives;
|
|
}
|
|
parsePrivateName() {
|
|
const node = super.parsePrivateName();
|
|
{
|
|
if (!this.getPluginOption("estree", "classFeatures")) {
|
|
return node;
|
|
}
|
|
}
|
|
return this.convertPrivateNameToPrivateIdentifier(node);
|
|
}
|
|
convertPrivateNameToPrivateIdentifier(node) {
|
|
const name = super.getPrivateNameSV(node);
|
|
delete node.id;
|
|
node.name = name;
|
|
return this.castNodeTo(node, "PrivateIdentifier");
|
|
}
|
|
isPrivateName(node) {
|
|
{
|
|
if (!this.getPluginOption("estree", "classFeatures")) {
|
|
return super.isPrivateName(node);
|
|
}
|
|
}
|
|
return node.type === "PrivateIdentifier";
|
|
}
|
|
getPrivateNameSV(node) {
|
|
{
|
|
if (!this.getPluginOption("estree", "classFeatures")) {
|
|
return super.getPrivateNameSV(node);
|
|
}
|
|
}
|
|
return node.name;
|
|
}
|
|
parseLiteral(value, type) {
|
|
const node = super.parseLiteral(value, type);
|
|
node.raw = node.extra.raw;
|
|
delete node.extra;
|
|
return node;
|
|
}
|
|
parseFunctionBody(node, allowExpression, isMethod = false) {
|
|
super.parseFunctionBody(node, allowExpression, isMethod);
|
|
node.expression = node.body.type !== "BlockStatement";
|
|
}
|
|
parseMethod(node, isGenerator, isAsync, isConstructor, allowDirectSuper, type, inClassScope = false) {
|
|
let funcNode = this.startNode();
|
|
funcNode.kind = node.kind;
|
|
funcNode = super.parseMethod(funcNode, isGenerator, isAsync, isConstructor, allowDirectSuper, type, inClassScope);
|
|
delete funcNode.kind;
|
|
const {
|
|
typeParameters
|
|
} = node;
|
|
if (typeParameters) {
|
|
delete node.typeParameters;
|
|
funcNode.typeParameters = typeParameters;
|
|
this.resetStartLocationFromNode(funcNode, typeParameters);
|
|
}
|
|
const valueNode = this.castNodeTo(funcNode, "FunctionExpression");
|
|
node.value = valueNode;
|
|
if (type === "ClassPrivateMethod") {
|
|
node.computed = false;
|
|
}
|
|
if (type === "ObjectMethod") {
|
|
if (node.kind === "method") {
|
|
node.kind = "init";
|
|
}
|
|
node.shorthand = false;
|
|
return this.finishNode(node, "Property");
|
|
} else {
|
|
return this.finishNode(node, "MethodDefinition");
|
|
}
|
|
}
|
|
nameIsConstructor(key) {
|
|
if (key.type === "Literal") return key.value === "constructor";
|
|
return super.nameIsConstructor(key);
|
|
}
|
|
parseClassProperty(...args) {
|
|
const propertyNode = super.parseClassProperty(...args);
|
|
{
|
|
if (!this.getPluginOption("estree", "classFeatures")) {
|
|
return propertyNode;
|
|
}
|
|
}
|
|
{
|
|
this.castNodeTo(propertyNode, "PropertyDefinition");
|
|
}
|
|
return propertyNode;
|
|
}
|
|
parseClassPrivateProperty(...args) {
|
|
const propertyNode = super.parseClassPrivateProperty(...args);
|
|
{
|
|
if (!this.getPluginOption("estree", "classFeatures")) {
|
|
return propertyNode;
|
|
}
|
|
}
|
|
{
|
|
this.castNodeTo(propertyNode, "PropertyDefinition");
|
|
}
|
|
propertyNode.computed = false;
|
|
return propertyNode;
|
|
}
|
|
parseClassAccessorProperty(node) {
|
|
const accessorPropertyNode = super.parseClassAccessorProperty(node);
|
|
{
|
|
if (!this.getPluginOption("estree", "classFeatures")) {
|
|
return accessorPropertyNode;
|
|
}
|
|
}
|
|
if (accessorPropertyNode.abstract && this.hasPlugin("typescript")) {
|
|
delete accessorPropertyNode.abstract;
|
|
this.castNodeTo(accessorPropertyNode, "TSAbstractAccessorProperty");
|
|
} else {
|
|
this.castNodeTo(accessorPropertyNode, "AccessorProperty");
|
|
}
|
|
return accessorPropertyNode;
|
|
}
|
|
parseObjectProperty(prop, startLoc, isPattern, refExpressionErrors) {
|
|
const node = super.parseObjectProperty(prop, startLoc, isPattern, refExpressionErrors);
|
|
if (node) {
|
|
node.kind = "init";
|
|
this.castNodeTo(node, "Property");
|
|
}
|
|
return node;
|
|
}
|
|
finishObjectProperty(node) {
|
|
node.kind = "init";
|
|
return this.finishNode(node, "Property");
|
|
}
|
|
isValidLVal(type, disallowCallExpression, isUnparenthesizedInAssign, binding) {
|
|
return type === "Property" ? "value" : super.isValidLVal(type, disallowCallExpression, isUnparenthesizedInAssign, binding);
|
|
}
|
|
isAssignable(node, isBinding) {
|
|
if (node != null && this.isObjectProperty(node)) {
|
|
return this.isAssignable(node.value, isBinding);
|
|
}
|
|
return super.isAssignable(node, isBinding);
|
|
}
|
|
toAssignable(node, isLHS = false) {
|
|
if (node != null && this.isObjectProperty(node)) {
|
|
const {
|
|
key,
|
|
value
|
|
} = node;
|
|
if (this.isPrivateName(key)) {
|
|
this.classScope.usePrivateName(this.getPrivateNameSV(key), key.loc.start);
|
|
}
|
|
this.toAssignable(value, isLHS);
|
|
} else {
|
|
super.toAssignable(node, isLHS);
|
|
}
|
|
}
|
|
toAssignableObjectExpressionProp(prop, isLast, isLHS) {
|
|
if (prop.type === "Property" && (prop.kind === "get" || prop.kind === "set")) {
|
|
this.raise(Errors.PatternHasAccessor, prop.key);
|
|
} else if (prop.type === "Property" && prop.method) {
|
|
this.raise(Errors.PatternHasMethod, prop.key);
|
|
} else {
|
|
super.toAssignableObjectExpressionProp(prop, isLast, isLHS);
|
|
}
|
|
}
|
|
finishCallExpression(unfinished, optional) {
|
|
const node = super.finishCallExpression(unfinished, optional);
|
|
if (node.callee.type === "Import") {
|
|
var _ref;
|
|
this.castNodeTo(node, "ImportExpression");
|
|
node.source = node.arguments[0];
|
|
node.options = (_ref = node.arguments[1]) != null ? _ref : null;
|
|
{
|
|
var _ref2;
|
|
node.attributes = (_ref2 = node.arguments[1]) != null ? _ref2 : null;
|
|
}
|
|
delete node.arguments;
|
|
delete node.callee;
|
|
} else if (node.type === "OptionalCallExpression") {
|
|
this.castNodeTo(node, "CallExpression");
|
|
} else {
|
|
node.optional = false;
|
|
}
|
|
return node;
|
|
}
|
|
toReferencedArguments(node) {
|
|
if (node.type === "ImportExpression") {
|
|
return;
|
|
}
|
|
super.toReferencedArguments(node);
|
|
}
|
|
parseExport(unfinished, decorators) {
|
|
const exportStartLoc = this.state.lastTokStartLoc;
|
|
const node = super.parseExport(unfinished, decorators);
|
|
switch (node.type) {
|
|
case "ExportAllDeclaration":
|
|
node.exported = null;
|
|
break;
|
|
case "ExportNamedDeclaration":
|
|
if (node.specifiers.length === 1 && node.specifiers[0].type === "ExportNamespaceSpecifier") {
|
|
this.castNodeTo(node, "ExportAllDeclaration");
|
|
node.exported = node.specifiers[0].exported;
|
|
delete node.specifiers;
|
|
}
|
|
case "ExportDefaultDeclaration":
|
|
{
|
|
var _declaration$decorato;
|
|
const {
|
|
declaration
|
|
} = node;
|
|
if ((declaration == null ? void 0 : declaration.type) === "ClassDeclaration" && ((_declaration$decorato = declaration.decorators) == null ? void 0 : _declaration$decorato.length) > 0 && declaration.start === node.start) {
|
|
this.resetStartLocation(node, exportStartLoc);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
return node;
|
|
}
|
|
stopParseSubscript(base, state) {
|
|
const node = super.stopParseSubscript(base, state);
|
|
if (state.optionalChainMember) {
|
|
return this.estreeParseChainExpression(node, base.loc.end);
|
|
}
|
|
return node;
|
|
}
|
|
parseMember(base, startLoc, state, computed, optional) {
|
|
const node = super.parseMember(base, startLoc, state, computed, optional);
|
|
if (node.type === "OptionalMemberExpression") {
|
|
this.castNodeTo(node, "MemberExpression");
|
|
} else {
|
|
node.optional = false;
|
|
}
|
|
return node;
|
|
}
|
|
isOptionalMemberExpression(node) {
|
|
if (node.type === "ChainExpression") {
|
|
return node.expression.type === "MemberExpression";
|
|
}
|
|
return super.isOptionalMemberExpression(node);
|
|
}
|
|
hasPropertyAsPrivateName(node) {
|
|
if (node.type === "ChainExpression") {
|
|
node = node.expression;
|
|
}
|
|
return super.hasPropertyAsPrivateName(node);
|
|
}
|
|
isObjectProperty(node) {
|
|
return node.type === "Property" && node.kind === "init" && !node.method;
|
|
}
|
|
isObjectMethod(node) {
|
|
return node.type === "Property" && (node.method || node.kind === "get" || node.kind === "set");
|
|
}
|
|
castNodeTo(node, type) {
|
|
const result = super.castNodeTo(node, type);
|
|
this.fillOptionalPropertiesForTSESLint(result);
|
|
return result;
|
|
}
|
|
cloneIdentifier(node) {
|
|
const cloned = super.cloneIdentifier(node);
|
|
this.fillOptionalPropertiesForTSESLint(cloned);
|
|
return cloned;
|
|
}
|
|
cloneStringLiteral(node) {
|
|
if (node.type === "Literal") {
|
|
return this.cloneEstreeStringLiteral(node);
|
|
}
|
|
return super.cloneStringLiteral(node);
|
|
}
|
|
finishNodeAt(node, type, endLoc) {
|
|
return toESTreeLocation(super.finishNodeAt(node, type, endLoc));
|
|
}
|
|
finishNode(node, type) {
|
|
const result = super.finishNode(node, type);
|
|
this.fillOptionalPropertiesForTSESLint(result);
|
|
return result;
|
|
}
|
|
resetStartLocation(node, startLoc) {
|
|
super.resetStartLocation(node, startLoc);
|
|
toESTreeLocation(node);
|
|
}
|
|
resetEndLocation(node, endLoc = this.state.lastTokEndLoc) {
|
|
super.resetEndLocation(node, endLoc);
|
|
toESTreeLocation(node);
|
|
}
|
|
};
|
|
class TokContext {
|
|
constructor(token, preserveSpace) {
|
|
this.token = void 0;
|
|
this.preserveSpace = void 0;
|
|
this.token = token;
|
|
this.preserveSpace = !!preserveSpace;
|
|
}
|
|
}
|
|
const types = {
|
|
brace: new TokContext("{"),
|
|
j_oTag: new TokContext("<tag"),
|
|
j_cTag: new TokContext("</tag"),
|
|
j_expr: new TokContext("<tag>...</tag>", true)
|
|
};
|
|
{
|
|
types.template = new TokContext("`", true);
|
|
}
|
|
const beforeExpr = true;
|
|
const startsExpr = true;
|
|
const isLoop = true;
|
|
const isAssign = true;
|
|
const prefix = true;
|
|
const postfix = true;
|
|
class ExportedTokenType {
|
|
constructor(label, conf = {}) {
|
|
this.label = void 0;
|
|
this.keyword = void 0;
|
|
this.beforeExpr = void 0;
|
|
this.startsExpr = void 0;
|
|
this.rightAssociative = void 0;
|
|
this.isLoop = void 0;
|
|
this.isAssign = void 0;
|
|
this.prefix = void 0;
|
|
this.postfix = void 0;
|
|
this.binop = void 0;
|
|
this.label = label;
|
|
this.keyword = conf.keyword;
|
|
this.beforeExpr = !!conf.beforeExpr;
|
|
this.startsExpr = !!conf.startsExpr;
|
|
this.rightAssociative = !!conf.rightAssociative;
|
|
this.isLoop = !!conf.isLoop;
|
|
this.isAssign = !!conf.isAssign;
|
|
this.prefix = !!conf.prefix;
|
|
this.postfix = !!conf.postfix;
|
|
this.binop = conf.binop != null ? conf.binop : null;
|
|
{
|
|
this.updateContext = null;
|
|
}
|
|
}
|
|
}
|
|
const keywords$1 = new Map();
|
|
function createKeyword(name, options = {}) {
|
|
options.keyword = name;
|
|
const token = createToken(name, options);
|
|
keywords$1.set(name, token);
|
|
return token;
|
|
}
|
|
function createBinop(name, binop) {
|
|
return createToken(name, {
|
|
beforeExpr,
|
|
binop
|
|
});
|
|
}
|
|
let tokenTypeCounter = -1;
|
|
const tokenTypes = [];
|
|
const tokenLabels = [];
|
|
const tokenBinops = [];
|
|
const tokenBeforeExprs = [];
|
|
const tokenStartsExprs = [];
|
|
const tokenPrefixes = [];
|
|
function createToken(name, options = {}) {
|
|
var _options$binop, _options$beforeExpr, _options$startsExpr, _options$prefix;
|
|
++tokenTypeCounter;
|
|
tokenLabels.push(name);
|
|
tokenBinops.push((_options$binop = options.binop) != null ? _options$binop : -1);
|
|
tokenBeforeExprs.push((_options$beforeExpr = options.beforeExpr) != null ? _options$beforeExpr : false);
|
|
tokenStartsExprs.push((_options$startsExpr = options.startsExpr) != null ? _options$startsExpr : false);
|
|
tokenPrefixes.push((_options$prefix = options.prefix) != null ? _options$prefix : false);
|
|
tokenTypes.push(new ExportedTokenType(name, options));
|
|
return tokenTypeCounter;
|
|
}
|
|
function createKeywordLike(name, options = {}) {
|
|
var _options$binop2, _options$beforeExpr2, _options$startsExpr2, _options$prefix2;
|
|
++tokenTypeCounter;
|
|
keywords$1.set(name, tokenTypeCounter);
|
|
tokenLabels.push(name);
|
|
tokenBinops.push((_options$binop2 = options.binop) != null ? _options$binop2 : -1);
|
|
tokenBeforeExprs.push((_options$beforeExpr2 = options.beforeExpr) != null ? _options$beforeExpr2 : false);
|
|
tokenStartsExprs.push((_options$startsExpr2 = options.startsExpr) != null ? _options$startsExpr2 : false);
|
|
tokenPrefixes.push((_options$prefix2 = options.prefix) != null ? _options$prefix2 : false);
|
|
tokenTypes.push(new ExportedTokenType("name", options));
|
|
return tokenTypeCounter;
|
|
}
|
|
const tt = {
|
|
bracketL: createToken("[", {
|
|
beforeExpr,
|
|
startsExpr
|
|
}),
|
|
bracketHashL: createToken("#[", {
|
|
beforeExpr,
|
|
startsExpr
|
|
}),
|
|
bracketBarL: createToken("[|", {
|
|
beforeExpr,
|
|
startsExpr
|
|
}),
|
|
bracketR: createToken("]"),
|
|
bracketBarR: createToken("|]"),
|
|
braceL: createToken("{", {
|
|
beforeExpr,
|
|
startsExpr
|
|
}),
|
|
braceBarL: createToken("{|", {
|
|
beforeExpr,
|
|
startsExpr
|
|
}),
|
|
braceHashL: createToken("#{", {
|
|
beforeExpr,
|
|
startsExpr
|
|
}),
|
|
braceR: createToken("}"),
|
|
braceBarR: createToken("|}"),
|
|
parenL: createToken("(", {
|
|
beforeExpr,
|
|
startsExpr
|
|
}),
|
|
parenR: createToken(")"),
|
|
comma: createToken(",", {
|
|
beforeExpr
|
|
}),
|
|
semi: createToken(";", {
|
|
beforeExpr
|
|
}),
|
|
colon: createToken(":", {
|
|
beforeExpr
|
|
}),
|
|
doubleColon: createToken("::", {
|
|
beforeExpr
|
|
}),
|
|
dot: createToken("."),
|
|
question: createToken("?", {
|
|
beforeExpr
|
|
}),
|
|
questionDot: createToken("?."),
|
|
arrow: createToken("=>", {
|
|
beforeExpr
|
|
}),
|
|
template: createToken("template"),
|
|
ellipsis: createToken("...", {
|
|
beforeExpr
|
|
}),
|
|
backQuote: createToken("`", {
|
|
startsExpr
|
|
}),
|
|
dollarBraceL: createToken("${", {
|
|
beforeExpr,
|
|
startsExpr
|
|
}),
|
|
templateTail: createToken("...`", {
|
|
startsExpr
|
|
}),
|
|
templateNonTail: createToken("...${", {
|
|
beforeExpr,
|
|
startsExpr
|
|
}),
|
|
at: createToken("@"),
|
|
hash: createToken("#", {
|
|
startsExpr
|
|
}),
|
|
interpreterDirective: createToken("#!..."),
|
|
eq: createToken("=", {
|
|
beforeExpr,
|
|
isAssign
|
|
}),
|
|
assign: createToken("_=", {
|
|
beforeExpr,
|
|
isAssign
|
|
}),
|
|
slashAssign: createToken("_=", {
|
|
beforeExpr,
|
|
isAssign
|
|
}),
|
|
xorAssign: createToken("_=", {
|
|
beforeExpr,
|
|
isAssign
|
|
}),
|
|
moduloAssign: createToken("_=", {
|
|
beforeExpr,
|
|
isAssign
|
|
}),
|
|
incDec: createToken("++/--", {
|
|
prefix,
|
|
postfix,
|
|
startsExpr
|
|
}),
|
|
bang: createToken("!", {
|
|
beforeExpr,
|
|
prefix,
|
|
startsExpr
|
|
}),
|
|
tilde: createToken("~", {
|
|
beforeExpr,
|
|
prefix,
|
|
startsExpr
|
|
}),
|
|
doubleCaret: createToken("^^", {
|
|
startsExpr
|
|
}),
|
|
doubleAt: createToken("@@", {
|
|
startsExpr
|
|
}),
|
|
pipeline: createBinop("|>", 0),
|
|
nullishCoalescing: createBinop("??", 1),
|
|
logicalOR: createBinop("||", 1),
|
|
logicalAND: createBinop("&&", 2),
|
|
bitwiseOR: createBinop("|", 3),
|
|
bitwiseXOR: createBinop("^", 4),
|
|
bitwiseAND: createBinop("&", 5),
|
|
equality: createBinop("==/!=/===/!==", 6),
|
|
lt: createBinop("</>/<=/>=", 7),
|
|
gt: createBinop("</>/<=/>=", 7),
|
|
relational: createBinop("</>/<=/>=", 7),
|
|
bitShift: createBinop("<</>>/>>>", 8),
|
|
bitShiftL: createBinop("<</>>/>>>", 8),
|
|
bitShiftR: createBinop("<</>>/>>>", 8),
|
|
plusMin: createToken("+/-", {
|
|
beforeExpr,
|
|
binop: 9,
|
|
prefix,
|
|
startsExpr
|
|
}),
|
|
modulo: createToken("%", {
|
|
binop: 10,
|
|
startsExpr
|
|
}),
|
|
star: createToken("*", {
|
|
binop: 10
|
|
}),
|
|
slash: createBinop("/", 10),
|
|
exponent: createToken("**", {
|
|
beforeExpr,
|
|
binop: 11,
|
|
rightAssociative: true
|
|
}),
|
|
_in: createKeyword("in", {
|
|
beforeExpr,
|
|
binop: 7
|
|
}),
|
|
_instanceof: createKeyword("instanceof", {
|
|
beforeExpr,
|
|
binop: 7
|
|
}),
|
|
_break: createKeyword("break"),
|
|
_case: createKeyword("case", {
|
|
beforeExpr
|
|
}),
|
|
_catch: createKeyword("catch"),
|
|
_continue: createKeyword("continue"),
|
|
_debugger: createKeyword("debugger"),
|
|
_default: createKeyword("default", {
|
|
beforeExpr
|
|
}),
|
|
_else: createKeyword("else", {
|
|
beforeExpr
|
|
}),
|
|
_finally: createKeyword("finally"),
|
|
_function: createKeyword("function", {
|
|
startsExpr
|
|
}),
|
|
_if: createKeyword("if"),
|
|
_return: createKeyword("return", {
|
|
beforeExpr
|
|
}),
|
|
_switch: createKeyword("switch"),
|
|
_throw: createKeyword("throw", {
|
|
beforeExpr,
|
|
prefix,
|
|
startsExpr
|
|
}),
|
|
_try: createKeyword("try"),
|
|
_var: createKeyword("var"),
|
|
_const: createKeyword("const"),
|
|
_with: createKeyword("with"),
|
|
_new: createKeyword("new", {
|
|
beforeExpr,
|
|
startsExpr
|
|
}),
|
|
_this: createKeyword("this", {
|
|
startsExpr
|
|
}),
|
|
_super: createKeyword("super", {
|
|
startsExpr
|
|
}),
|
|
_class: createKeyword("class", {
|
|
startsExpr
|
|
}),
|
|
_extends: createKeyword("extends", {
|
|
beforeExpr
|
|
}),
|
|
_export: createKeyword("export"),
|
|
_import: createKeyword("import", {
|
|
startsExpr
|
|
}),
|
|
_null: createKeyword("null", {
|
|
startsExpr
|
|
}),
|
|
_true: createKeyword("true", {
|
|
startsExpr
|
|
}),
|
|
_false: createKeyword("false", {
|
|
startsExpr
|
|
}),
|
|
_typeof: createKeyword("typeof", {
|
|
beforeExpr,
|
|
prefix,
|
|
startsExpr
|
|
}),
|
|
_void: createKeyword("void", {
|
|
beforeExpr,
|
|
prefix,
|
|
startsExpr
|
|
}),
|
|
_delete: createKeyword("delete", {
|
|
beforeExpr,
|
|
prefix,
|
|
startsExpr
|
|
}),
|
|
_do: createKeyword("do", {
|
|
isLoop,
|
|
beforeExpr
|
|
}),
|
|
_for: createKeyword("for", {
|
|
isLoop
|
|
}),
|
|
_while: createKeyword("while", {
|
|
isLoop
|
|
}),
|
|
_as: createKeywordLike("as", {
|
|
startsExpr
|
|
}),
|
|
_assert: createKeywordLike("assert", {
|
|
startsExpr
|
|
}),
|
|
_async: createKeywordLike("async", {
|
|
startsExpr
|
|
}),
|
|
_await: createKeywordLike("await", {
|
|
startsExpr
|
|
}),
|
|
_defer: createKeywordLike("defer", {
|
|
startsExpr
|
|
}),
|
|
_from: createKeywordLike("from", {
|
|
startsExpr
|
|
}),
|
|
_get: createKeywordLike("get", {
|
|
startsExpr
|
|
}),
|
|
_let: createKeywordLike("let", {
|
|
startsExpr
|
|
}),
|
|
_meta: createKeywordLike("meta", {
|
|
startsExpr
|
|
}),
|
|
_of: createKeywordLike("of", {
|
|
startsExpr
|
|
}),
|
|
_sent: createKeywordLike("sent", {
|
|
startsExpr
|
|
}),
|
|
_set: createKeywordLike("set", {
|
|
startsExpr
|
|
}),
|
|
_source: createKeywordLike("source", {
|
|
startsExpr
|
|
}),
|
|
_static: createKeywordLike("static", {
|
|
startsExpr
|
|
}),
|
|
_using: createKeywordLike("using", {
|
|
startsExpr
|
|
}),
|
|
_yield: createKeywordLike("yield", {
|
|
startsExpr
|
|
}),
|
|
_asserts: createKeywordLike("asserts", {
|
|
startsExpr
|
|
}),
|
|
_checks: createKeywordLike("checks", {
|
|
startsExpr
|
|
}),
|
|
_exports: createKeywordLike("exports", {
|
|
startsExpr
|
|
}),
|
|
_global: createKeywordLike("global", {
|
|
startsExpr
|
|
}),
|
|
_implements: createKeywordLike("implements", {
|
|
startsExpr
|
|
}),
|
|
_intrinsic: createKeywordLike("intrinsic", {
|
|
startsExpr
|
|
}),
|
|
_infer: createKeywordLike("infer", {
|
|
startsExpr
|
|
}),
|
|
_is: createKeywordLike("is", {
|
|
startsExpr
|
|
}),
|
|
_mixins: createKeywordLike("mixins", {
|
|
startsExpr
|
|
}),
|
|
_proto: createKeywordLike("proto", {
|
|
startsExpr
|
|
}),
|
|
_require: createKeywordLike("require", {
|
|
startsExpr
|
|
}),
|
|
_satisfies: createKeywordLike("satisfies", {
|
|
startsExpr
|
|
}),
|
|
_keyof: createKeywordLike("keyof", {
|
|
startsExpr
|
|
}),
|
|
_readonly: createKeywordLike("readonly", {
|
|
startsExpr
|
|
}),
|
|
_unique: createKeywordLike("unique", {
|
|
startsExpr
|
|
}),
|
|
_abstract: createKeywordLike("abstract", {
|
|
startsExpr
|
|
}),
|
|
_declare: createKeywordLike("declare", {
|
|
startsExpr
|
|
}),
|
|
_enum: createKeywordLike("enum", {
|
|
startsExpr
|
|
}),
|
|
_module: createKeywordLike("module", {
|
|
startsExpr
|
|
}),
|
|
_namespace: createKeywordLike("namespace", {
|
|
startsExpr
|
|
}),
|
|
_interface: createKeywordLike("interface", {
|
|
startsExpr
|
|
}),
|
|
_type: createKeywordLike("type", {
|
|
startsExpr
|
|
}),
|
|
_opaque: createKeywordLike("opaque", {
|
|
startsExpr
|
|
}),
|
|
name: createToken("name", {
|
|
startsExpr
|
|
}),
|
|
placeholder: createToken("%%", {
|
|
startsExpr
|
|
}),
|
|
string: createToken("string", {
|
|
startsExpr
|
|
}),
|
|
num: createToken("num", {
|
|
startsExpr
|
|
}),
|
|
bigint: createToken("bigint", {
|
|
startsExpr
|
|
}),
|
|
decimal: createToken("decimal", {
|
|
startsExpr
|
|
}),
|
|
regexp: createToken("regexp", {
|
|
startsExpr
|
|
}),
|
|
privateName: createToken("#name", {
|
|
startsExpr
|
|
}),
|
|
eof: createToken("eof"),
|
|
jsxName: createToken("jsxName"),
|
|
jsxText: createToken("jsxText", {
|
|
beforeExpr
|
|
}),
|
|
jsxTagStart: createToken("jsxTagStart", {
|
|
startsExpr
|
|
}),
|
|
jsxTagEnd: createToken("jsxTagEnd")
|
|
};
|
|
function tokenIsIdentifier(token) {
|
|
return token >= 93 && token <= 133;
|
|
}
|
|
function tokenKeywordOrIdentifierIsKeyword(token) {
|
|
return token <= 92;
|
|
}
|
|
function tokenIsKeywordOrIdentifier(token) {
|
|
return token >= 58 && token <= 133;
|
|
}
|
|
function tokenIsLiteralPropertyName(token) {
|
|
return token >= 58 && token <= 137;
|
|
}
|
|
function tokenComesBeforeExpression(token) {
|
|
return tokenBeforeExprs[token];
|
|
}
|
|
function tokenCanStartExpression(token) {
|
|
return tokenStartsExprs[token];
|
|
}
|
|
function tokenIsAssignment(token) {
|
|
return token >= 29 && token <= 33;
|
|
}
|
|
function tokenIsFlowInterfaceOrTypeOrOpaque(token) {
|
|
return token >= 129 && token <= 131;
|
|
}
|
|
function tokenIsLoop(token) {
|
|
return token >= 90 && token <= 92;
|
|
}
|
|
function tokenIsKeyword(token) {
|
|
return token >= 58 && token <= 92;
|
|
}
|
|
function tokenIsOperator(token) {
|
|
return token >= 39 && token <= 59;
|
|
}
|
|
function tokenIsPostfix(token) {
|
|
return token === 34;
|
|
}
|
|
function tokenIsPrefix(token) {
|
|
return tokenPrefixes[token];
|
|
}
|
|
function tokenIsTSTypeOperator(token) {
|
|
return token >= 121 && token <= 123;
|
|
}
|
|
function tokenIsTSDeclarationStart(token) {
|
|
return token >= 124 && token <= 130;
|
|
}
|
|
function tokenLabelName(token) {
|
|
return tokenLabels[token];
|
|
}
|
|
function tokenOperatorPrecedence(token) {
|
|
return tokenBinops[token];
|
|
}
|
|
function tokenIsRightAssociative(token) {
|
|
return token === 57;
|
|
}
|
|
function tokenIsTemplate(token) {
|
|
return token >= 24 && token <= 25;
|
|
}
|
|
function getExportedToken(token) {
|
|
return tokenTypes[token];
|
|
}
|
|
{
|
|
tokenTypes[8].updateContext = context => {
|
|
context.pop();
|
|
};
|
|
tokenTypes[5].updateContext = tokenTypes[7].updateContext = tokenTypes[23].updateContext = context => {
|
|
context.push(types.brace);
|
|
};
|
|
tokenTypes[22].updateContext = context => {
|
|
if (context[context.length - 1] === types.template) {
|
|
context.pop();
|
|
} else {
|
|
context.push(types.template);
|
|
}
|
|
};
|
|
tokenTypes[143].updateContext = context => {
|
|
context.push(types.j_expr, types.j_oTag);
|
|
};
|
|
}
|
|
let nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0560-\u0588\u05d0-\u05ea\u05ef-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u0860-\u086a\u0870-\u0887\u0889-\u088f\u08a0-\u08c9\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u09fc\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c5c\u0c5d\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cdc-\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d04-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e86-\u0e8a\u0e8c-\u0ea3\u0ea5\u0ea7-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u1711\u171f-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1878\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4c\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c8a\u1c90-\u1cba\u1cbd-\u1cbf\u1ce9-\u1cec\u1cee-\u1cf3\u1cf5\u1cf6\u1cfa\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312f\u3131-\u318e\u31a0-\u31bf\u31f0-\u31ff\u3400-\u4dbf\u4e00-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7dc\ua7f1-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua8fe\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab69\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc";
|
|
let nonASCIIidentifierChars = "\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u07fd\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u0897-\u089f\u08ca-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u09fe\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0afa-\u0aff\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b55-\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c04\u0c3c\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0cf3\u0d00-\u0d03\u0d3b\u0d3c\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d81-\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0ebc\u0ec8-\u0ece\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1715\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u180f-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1abf-\u1add\u1ae0-\u1aeb\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf4\u1cf7-\u1cf9\u1dc0-\u1dff\u200c\u200d\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\u30fb\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua82c\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua8ff-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f\uff65";
|
|
const nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]");
|
|
const nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]");
|
|
nonASCIIidentifierStartChars = nonASCIIidentifierChars = null;
|
|
const astralIdentifierStartCodes = [0, 11, 2, 25, 2, 18, 2, 1, 2, 14, 3, 13, 35, 122, 70, 52, 268, 28, 4, 48, 48, 31, 14, 29, 6, 37, 11, 29, 3, 35, 5, 7, 2, 4, 43, 157, 19, 35, 5, 35, 5, 39, 9, 51, 13, 10, 2, 14, 2, 6, 2, 1, 2, 10, 2, 14, 2, 6, 2, 1, 4, 51, 13, 310, 10, 21, 11, 7, 25, 5, 2, 41, 2, 8, 70, 5, 3, 0, 2, 43, 2, 1, 4, 0, 3, 22, 11, 22, 10, 30, 66, 18, 2, 1, 11, 21, 11, 25, 7, 25, 39, 55, 7, 1, 65, 0, 16, 3, 2, 2, 2, 28, 43, 28, 4, 28, 36, 7, 2, 27, 28, 53, 11, 21, 11, 18, 14, 17, 111, 72, 56, 50, 14, 50, 14, 35, 39, 27, 10, 22, 251, 41, 7, 1, 17, 5, 57, 28, 11, 0, 9, 21, 43, 17, 47, 20, 28, 22, 13, 52, 58, 1, 3, 0, 14, 44, 33, 24, 27, 35, 30, 0, 3, 0, 9, 34, 4, 0, 13, 47, 15, 3, 22, 0, 2, 0, 36, 17, 2, 24, 20, 1, 64, 6, 2, 0, 2, 3, 2, 14, 2, 9, 8, 46, 39, 7, 3, 1, 3, 21, 2, 6, 2, 1, 2, 4, 4, 0, 19, 0, 13, 4, 31, 9, 2, 0, 3, 0, 2, 37, 2, 0, 26, 0, 2, 0, 45, 52, 19, 3, 21, 2, 31, 47, 21, 1, 2, 0, 185, 46, 42, 3, 37, 47, 21, 0, 60, 42, 14, 0, 72, 26, 38, 6, 186, 43, 117, 63, 32, 7, 3, 0, 3, 7, 2, 1, 2, 23, 16, 0, 2, 0, 95, 7, 3, 38, 17, 0, 2, 0, 29, 0, 11, 39, 8, 0, 22, 0, 12, 45, 20, 0, 19, 72, 200, 32, 32, 8, 2, 36, 18, 0, 50, 29, 113, 6, 2, 1, 2, 37, 22, 0, 26, 5, 2, 1, 2, 31, 15, 0, 24, 43, 261, 18, 16, 0, 2, 12, 2, 33, 125, 0, 80, 921, 103, 110, 18, 195, 2637, 96, 16, 1071, 18, 5, 26, 3994, 6, 582, 6842, 29, 1763, 568, 8, 30, 18, 78, 18, 29, 19, 47, 17, 3, 32, 20, 6, 18, 433, 44, 212, 63, 33, 24, 3, 24, 45, 74, 6, 0, 67, 12, 65, 1, 2, 0, 15, 4, 10, 7381, 42, 31, 98, 114, 8702, 3, 2, 6, 2, 1, 2, 290, 16, 0, 30, 2, 3, 0, 15, 3, 9, 395, 2309, 106, 6, 12, 4, 8, 8, 9, 5991, 84, 2, 70, 2, 1, 3, 0, 3, 1, 3, 3, 2, 11, 2, 0, 2, 6, 2, 64, 2, 3, 3, 7, 2, 6, 2, 27, 2, 3, 2, 4, 2, 0, 4, 6, 2, 339, 3, 24, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 7, 1845, 30, 7, 5, 262, 61, 147, 44, 11, 6, 17, 0, 322, 29, 19, 43, 485, 27, 229, 29, 3, 0, 208, 30, 2, 2, 2, 1, 2, 6, 3, 4, 10, 1, 225, 6, 2, 3, 2, 1, 2, 14, 2, 196, 60, 67, 8, 0, 1205, 3, 2, 26, 2, 1, 2, 0, 3, 0, 2, 9, 2, 3, 2, 0, 2, 0, 7, 0, 5, 0, 2, 0, 2, 0, 2, 2, 2, 1, 2, 0, 3, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0, 3, 3, 2, 6, 2, 3, 2, 3, 2, 0, 2, 9, 2, 16, 6, 2, 2, 4, 2, 16, 4421, 42719, 33, 4381, 3, 5773, 3, 7472, 16, 621, 2467, 541, 1507, 4938, 6, 8489];
|
|
const astralIdentifierCodes = [509, 0, 227, 0, 150, 4, 294, 9, 1368, 2, 2, 1, 6, 3, 41, 2, 5, 0, 166, 1, 574, 3, 9, 9, 7, 9, 32, 4, 318, 1, 78, 5, 71, 10, 50, 3, 123, 2, 54, 14, 32, 10, 3, 1, 11, 3, 46, 10, 8, 0, 46, 9, 7, 2, 37, 13, 2, 9, 6, 1, 45, 0, 13, 2, 49, 13, 9, 3, 2, 11, 83, 11, 7, 0, 3, 0, 158, 11, 6, 9, 7, 3, 56, 1, 2, 6, 3, 1, 3, 2, 10, 0, 11, 1, 3, 6, 4, 4, 68, 8, 2, 0, 3, 0, 2, 3, 2, 4, 2, 0, 15, 1, 83, 17, 10, 9, 5, 0, 82, 19, 13, 9, 214, 6, 3, 8, 28, 1, 83, 16, 16, 9, 82, 12, 9, 9, 7, 19, 58, 14, 5, 9, 243, 14, 166, 9, 71, 5, 2, 1, 3, 3, 2, 0, 2, 1, 13, 9, 120, 6, 3, 6, 4, 0, 29, 9, 41, 6, 2, 3, 9, 0, 10, 10, 47, 15, 199, 7, 137, 9, 54, 7, 2, 7, 17, 9, 57, 21, 2, 13, 123, 5, 4, 0, 2, 1, 2, 6, 2, 0, 9, 9, 49, 4, 2, 1, 2, 4, 9, 9, 55, 9, 266, 3, 10, 1, 2, 0, 49, 6, 4, 4, 14, 10, 5350, 0, 7, 14, 11465, 27, 2343, 9, 87, 9, 39, 4, 60, 6, 26, 9, 535, 9, 470, 0, 2, 54, 8, 3, 82, 0, 12, 1, 19628, 1, 4178, 9, 519, 45, 3, 22, 543, 4, 4, 5, 9, 7, 3, 6, 31, 3, 149, 2, 1418, 49, 513, 54, 5, 49, 9, 0, 15, 0, 23, 4, 2, 14, 1361, 6, 2, 16, 3, 6, 2, 1, 2, 4, 101, 0, 161, 6, 10, 9, 357, 0, 62, 13, 499, 13, 245, 1, 2, 9, 233, 0, 3, 0, 8, 1, 6, 0, 475, 6, 110, 6, 6, 9, 4759, 9, 787719, 239];
|
|
function isInAstralSet(code, set) {
|
|
let pos = 0x10000;
|
|
for (let i = 0, length = set.length; i < length; i += 2) {
|
|
pos += set[i];
|
|
if (pos > code) return false;
|
|
pos += set[i + 1];
|
|
if (pos >= code) return true;
|
|
}
|
|
return false;
|
|
}
|
|
function isIdentifierStart(code) {
|
|
if (code < 65) return code === 36;
|
|
if (code <= 90) return true;
|
|
if (code < 97) return code === 95;
|
|
if (code <= 122) return true;
|
|
if (code <= 0xffff) {
|
|
return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code));
|
|
}
|
|
return isInAstralSet(code, astralIdentifierStartCodes);
|
|
}
|
|
function isIdentifierChar(code) {
|
|
if (code < 48) return code === 36;
|
|
if (code < 58) return true;
|
|
if (code < 65) return false;
|
|
if (code <= 90) return true;
|
|
if (code < 97) return code === 95;
|
|
if (code <= 122) return true;
|
|
if (code <= 0xffff) {
|
|
return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code));
|
|
}
|
|
return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes);
|
|
}
|
|
const reservedWords = {
|
|
keyword: ["break", "case", "catch", "continue", "debugger", "default", "do", "else", "finally", "for", "function", "if", "return", "switch", "throw", "try", "var", "const", "while", "with", "new", "this", "super", "class", "extends", "export", "import", "null", "true", "false", "in", "instanceof", "typeof", "void", "delete"],
|
|
strict: ["implements", "interface", "let", "package", "private", "protected", "public", "static", "yield"],
|
|
strictBind: ["eval", "arguments"]
|
|
};
|
|
const keywords = new Set(reservedWords.keyword);
|
|
const reservedWordsStrictSet = new Set(reservedWords.strict);
|
|
const reservedWordsStrictBindSet = new Set(reservedWords.strictBind);
|
|
function isReservedWord(word, inModule) {
|
|
return inModule && word === "await" || word === "enum";
|
|
}
|
|
function isStrictReservedWord(word, inModule) {
|
|
return isReservedWord(word, inModule) || reservedWordsStrictSet.has(word);
|
|
}
|
|
function isStrictBindOnlyReservedWord(word) {
|
|
return reservedWordsStrictBindSet.has(word);
|
|
}
|
|
function isStrictBindReservedWord(word, inModule) {
|
|
return isStrictReservedWord(word, inModule) || isStrictBindOnlyReservedWord(word);
|
|
}
|
|
function isKeyword(word) {
|
|
return keywords.has(word);
|
|
}
|
|
function isIteratorStart(current, next, next2) {
|
|
return current === 64 && next === 64 && isIdentifierStart(next2);
|
|
}
|
|
const reservedWordLikeSet = new Set(["break", "case", "catch", "continue", "debugger", "default", "do", "else", "finally", "for", "function", "if", "return", "switch", "throw", "try", "var", "const", "while", "with", "new", "this", "super", "class", "extends", "export", "import", "null", "true", "false", "in", "instanceof", "typeof", "void", "delete", "implements", "interface", "let", "package", "private", "protected", "public", "static", "yield", "eval", "arguments", "enum", "await"]);
|
|
function canBeReservedWord(word) {
|
|
return reservedWordLikeSet.has(word);
|
|
}
|
|
class Scope {
|
|
constructor(flags) {
|
|
this.flags = 0;
|
|
this.names = new Map();
|
|
this.firstLexicalName = "";
|
|
this.flags = flags;
|
|
}
|
|
}
|
|
class ScopeHandler {
|
|
constructor(parser, inModule) {
|
|
this.parser = void 0;
|
|
this.scopeStack = [];
|
|
this.inModule = void 0;
|
|
this.undefinedExports = new Map();
|
|
this.parser = parser;
|
|
this.inModule = inModule;
|
|
}
|
|
get inTopLevel() {
|
|
return (this.currentScope().flags & 1) > 0;
|
|
}
|
|
get inFunction() {
|
|
return (this.currentVarScopeFlags() & 2) > 0;
|
|
}
|
|
get allowSuper() {
|
|
return (this.currentThisScopeFlags() & 16) > 0;
|
|
}
|
|
get allowDirectSuper() {
|
|
return (this.currentThisScopeFlags() & 32) > 0;
|
|
}
|
|
get allowNewTarget() {
|
|
return (this.currentThisScopeFlags() & 512) > 0;
|
|
}
|
|
get inClass() {
|
|
return (this.currentThisScopeFlags() & 64) > 0;
|
|
}
|
|
get inClassAndNotInNonArrowFunction() {
|
|
const flags = this.currentThisScopeFlags();
|
|
return (flags & 64) > 0 && (flags & 2) === 0;
|
|
}
|
|
get inStaticBlock() {
|
|
for (let i = this.scopeStack.length - 1;; i--) {
|
|
const {
|
|
flags
|
|
} = this.scopeStack[i];
|
|
if (flags & 128) {
|
|
return true;
|
|
}
|
|
if (flags & (1667 | 64)) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
get inNonArrowFunction() {
|
|
return (this.currentThisScopeFlags() & 2) > 0;
|
|
}
|
|
get inBareCaseStatement() {
|
|
return (this.currentScope().flags & 256) > 0;
|
|
}
|
|
get treatFunctionsAsVar() {
|
|
return this.treatFunctionsAsVarInScope(this.currentScope());
|
|
}
|
|
createScope(flags) {
|
|
return new Scope(flags);
|
|
}
|
|
enter(flags) {
|
|
this.scopeStack.push(this.createScope(flags));
|
|
}
|
|
exit() {
|
|
const scope = this.scopeStack.pop();
|
|
return scope.flags;
|
|
}
|
|
treatFunctionsAsVarInScope(scope) {
|
|
return !!(scope.flags & (2 | 128) || !this.parser.inModule && scope.flags & 1);
|
|
}
|
|
declareName(name, bindingType, loc) {
|
|
let scope = this.currentScope();
|
|
if (bindingType & 8 || bindingType & 16) {
|
|
this.checkRedeclarationInScope(scope, name, bindingType, loc);
|
|
let type = scope.names.get(name) || 0;
|
|
if (bindingType & 16) {
|
|
type = type | 4;
|
|
} else {
|
|
if (!scope.firstLexicalName) {
|
|
scope.firstLexicalName = name;
|
|
}
|
|
type = type | 2;
|
|
}
|
|
scope.names.set(name, type);
|
|
if (bindingType & 8) {
|
|
this.maybeExportDefined(scope, name);
|
|
}
|
|
} else if (bindingType & 4) {
|
|
for (let i = this.scopeStack.length - 1; i >= 0; --i) {
|
|
scope = this.scopeStack[i];
|
|
this.checkRedeclarationInScope(scope, name, bindingType, loc);
|
|
scope.names.set(name, (scope.names.get(name) || 0) | 1);
|
|
this.maybeExportDefined(scope, name);
|
|
if (scope.flags & 1667) break;
|
|
}
|
|
}
|
|
if (this.parser.inModule && scope.flags & 1) {
|
|
this.undefinedExports.delete(name);
|
|
}
|
|
}
|
|
maybeExportDefined(scope, name) {
|
|
if (this.parser.inModule && scope.flags & 1) {
|
|
this.undefinedExports.delete(name);
|
|
}
|
|
}
|
|
checkRedeclarationInScope(scope, name, bindingType, loc) {
|
|
if (this.isRedeclaredInScope(scope, name, bindingType)) {
|
|
this.parser.raise(Errors.VarRedeclaration, loc, {
|
|
identifierName: name
|
|
});
|
|
}
|
|
}
|
|
isRedeclaredInScope(scope, name, bindingType) {
|
|
if (!(bindingType & 1)) return false;
|
|
if (bindingType & 8) {
|
|
return scope.names.has(name);
|
|
}
|
|
const type = scope.names.get(name) || 0;
|
|
if (bindingType & 16) {
|
|
return (type & 2) > 0 || !this.treatFunctionsAsVarInScope(scope) && (type & 1) > 0;
|
|
}
|
|
return (type & 2) > 0 && !(scope.flags & 8 && scope.firstLexicalName === name) || !this.treatFunctionsAsVarInScope(scope) && (type & 4) > 0;
|
|
}
|
|
checkLocalExport(id) {
|
|
const {
|
|
name
|
|
} = id;
|
|
const topLevelScope = this.scopeStack[0];
|
|
if (!topLevelScope.names.has(name)) {
|
|
this.undefinedExports.set(name, id.loc.start);
|
|
}
|
|
}
|
|
currentScope() {
|
|
return this.scopeStack[this.scopeStack.length - 1];
|
|
}
|
|
currentVarScopeFlags() {
|
|
for (let i = this.scopeStack.length - 1;; i--) {
|
|
const {
|
|
flags
|
|
} = this.scopeStack[i];
|
|
if (flags & 1667) {
|
|
return flags;
|
|
}
|
|
}
|
|
}
|
|
currentThisScopeFlags() {
|
|
for (let i = this.scopeStack.length - 1;; i--) {
|
|
const {
|
|
flags
|
|
} = this.scopeStack[i];
|
|
if (flags & (1667 | 64) && !(flags & 4)) {
|
|
return flags;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
class FlowScope extends Scope {
|
|
constructor(...args) {
|
|
super(...args);
|
|
this.declareFunctions = new Set();
|
|
}
|
|
}
|
|
class FlowScopeHandler extends ScopeHandler {
|
|
createScope(flags) {
|
|
return new FlowScope(flags);
|
|
}
|
|
declareName(name, bindingType, loc) {
|
|
const scope = this.currentScope();
|
|
if (bindingType & 2048) {
|
|
this.checkRedeclarationInScope(scope, name, bindingType, loc);
|
|
this.maybeExportDefined(scope, name);
|
|
scope.declareFunctions.add(name);
|
|
return;
|
|
}
|
|
super.declareName(name, bindingType, loc);
|
|
}
|
|
isRedeclaredInScope(scope, name, bindingType) {
|
|
if (super.isRedeclaredInScope(scope, name, bindingType)) return true;
|
|
if (bindingType & 2048 && !scope.declareFunctions.has(name)) {
|
|
const type = scope.names.get(name);
|
|
return (type & 4) > 0 || (type & 2) > 0;
|
|
}
|
|
return false;
|
|
}
|
|
checkLocalExport(id) {
|
|
if (!this.scopeStack[0].declareFunctions.has(id.name)) {
|
|
super.checkLocalExport(id);
|
|
}
|
|
}
|
|
}
|
|
const reservedTypes = new Set(["_", "any", "bool", "boolean", "empty", "extends", "false", "interface", "mixed", "null", "number", "static", "string", "true", "typeof", "void"]);
|
|
const FlowErrors = ParseErrorEnum`flow`({
|
|
AmbiguousConditionalArrow: "Ambiguous expression: wrap the arrow functions in parentheses to disambiguate.",
|
|
AmbiguousDeclareModuleKind: "Found both `declare module.exports` and `declare export` in the same module. Modules can only have 1 since they are either an ES module or they are a CommonJS module.",
|
|
AssignReservedType: ({
|
|
reservedType
|
|
}) => `Cannot overwrite reserved type ${reservedType}.`,
|
|
DeclareClassElement: "The `declare` modifier can only appear on class fields.",
|
|
DeclareClassFieldInitializer: "Initializers are not allowed in fields with the `declare` modifier.",
|
|
DuplicateDeclareModuleExports: "Duplicate `declare module.exports` statement.",
|
|
EnumBooleanMemberNotInitialized: ({
|
|
memberName,
|
|
enumName
|
|
}) => `Boolean enum members need to be initialized. Use either \`${memberName} = true,\` or \`${memberName} = false,\` in enum \`${enumName}\`.`,
|
|
EnumDuplicateMemberName: ({
|
|
memberName,
|
|
enumName
|
|
}) => `Enum member names need to be unique, but the name \`${memberName}\` has already been used before in enum \`${enumName}\`.`,
|
|
EnumInconsistentMemberValues: ({
|
|
enumName
|
|
}) => `Enum \`${enumName}\` has inconsistent member initializers. Either use no initializers, or consistently use literals (either booleans, numbers, or strings) for all member initializers.`,
|
|
EnumInvalidExplicitType: ({
|
|
invalidEnumType,
|
|
enumName
|
|
}) => `Enum type \`${invalidEnumType}\` is not valid. Use one of \`boolean\`, \`number\`, \`string\`, or \`symbol\` in enum \`${enumName}\`.`,
|
|
EnumInvalidExplicitTypeUnknownSupplied: ({
|
|
enumName
|
|
}) => `Supplied enum type is not valid. Use one of \`boolean\`, \`number\`, \`string\`, or \`symbol\` in enum \`${enumName}\`.`,
|
|
EnumInvalidMemberInitializerPrimaryType: ({
|
|
enumName,
|
|
memberName,
|
|
explicitType
|
|
}) => `Enum \`${enumName}\` has type \`${explicitType}\`, so the initializer of \`${memberName}\` needs to be a ${explicitType} literal.`,
|
|
EnumInvalidMemberInitializerSymbolType: ({
|
|
enumName,
|
|
memberName
|
|
}) => `Symbol enum members cannot be initialized. Use \`${memberName},\` in enum \`${enumName}\`.`,
|
|
EnumInvalidMemberInitializerUnknownType: ({
|
|
enumName,
|
|
memberName
|
|
}) => `The enum member initializer for \`${memberName}\` needs to be a literal (either a boolean, number, or string) in enum \`${enumName}\`.`,
|
|
EnumInvalidMemberName: ({
|
|
enumName,
|
|
memberName,
|
|
suggestion
|
|
}) => `Enum member names cannot start with lowercase 'a' through 'z'. Instead of using \`${memberName}\`, consider using \`${suggestion}\`, in enum \`${enumName}\`.`,
|
|
EnumNumberMemberNotInitialized: ({
|
|
enumName,
|
|
memberName
|
|
}) => `Number enum members need to be initialized, e.g. \`${memberName} = 1\` in enum \`${enumName}\`.`,
|
|
EnumStringMemberInconsistentlyInitialized: ({
|
|
enumName
|
|
}) => `String enum members need to consistently either all use initializers, or use no initializers, in enum \`${enumName}\`.`,
|
|
GetterMayNotHaveThisParam: "A getter cannot have a `this` parameter.",
|
|
ImportReflectionHasImportType: "An `import module` declaration can not use `type` or `typeof` keyword.",
|
|
ImportTypeShorthandOnlyInPureImport: "The `type` and `typeof` keywords on named imports can only be used on regular `import` statements. It cannot be used with `import type` or `import typeof` statements.",
|
|
InexactInsideExact: "Explicit inexact syntax cannot appear inside an explicit exact object type.",
|
|
InexactInsideNonObject: "Explicit inexact syntax cannot appear in class or interface definitions.",
|
|
InexactVariance: "Explicit inexact syntax cannot have variance.",
|
|
InvalidNonTypeImportInDeclareModule: "Imports within a `declare module` body must always be `import type` or `import typeof`.",
|
|
MissingTypeParamDefault: "Type parameter declaration needs a default, since a preceding type parameter declaration has a default.",
|
|
NestedDeclareModule: "`declare module` cannot be used inside another `declare module`.",
|
|
NestedFlowComment: "Cannot have a flow comment inside another flow comment.",
|
|
PatternIsOptional: Object.assign({
|
|
message: "A binding pattern parameter cannot be optional in an implementation signature."
|
|
}, {
|
|
reasonCode: "OptionalBindingPattern"
|
|
}),
|
|
SetterMayNotHaveThisParam: "A setter cannot have a `this` parameter.",
|
|
SpreadVariance: "Spread properties cannot have variance.",
|
|
ThisParamAnnotationRequired: "A type annotation is required for the `this` parameter.",
|
|
ThisParamBannedInConstructor: "Constructors cannot have a `this` parameter; constructors don't bind `this` like other functions.",
|
|
ThisParamMayNotBeOptional: "The `this` parameter cannot be optional.",
|
|
ThisParamMustBeFirst: "The `this` parameter must be the first function parameter.",
|
|
ThisParamNoDefault: "The `this` parameter may not have a default value.",
|
|
TypeBeforeInitializer: "Type annotations must come before default assignments, e.g. instead of `age = 25: number` use `age: number = 25`.",
|
|
TypeCastInPattern: "The type cast expression is expected to be wrapped with parenthesis.",
|
|
UnexpectedExplicitInexactInObject: "Explicit inexact syntax must appear at the end of an inexact object.",
|
|
UnexpectedReservedType: ({
|
|
reservedType
|
|
}) => `Unexpected reserved type ${reservedType}.`,
|
|
UnexpectedReservedUnderscore: "`_` is only allowed as a type argument to call or new.",
|
|
UnexpectedSpaceBetweenModuloChecks: "Spaces between `%` and `checks` are not allowed here.",
|
|
UnexpectedSpreadType: "Spread operator cannot appear in class or interface definitions.",
|
|
UnexpectedSubtractionOperand: 'Unexpected token, expected "number" or "bigint".',
|
|
UnexpectedTokenAfterTypeParameter: "Expected an arrow function after this type parameter declaration.",
|
|
UnexpectedTypeParameterBeforeAsyncArrowFunction: "Type parameters must come after the async keyword, e.g. instead of `<T> async () => {}`, use `async <T>() => {}`.",
|
|
UnsupportedDeclareExportKind: ({
|
|
unsupportedExportKind,
|
|
suggestion
|
|
}) => `\`declare export ${unsupportedExportKind}\` is not supported. Use \`${suggestion}\` instead.`,
|
|
UnsupportedStatementInDeclareModule: "Only declares and type imports are allowed inside declare module.",
|
|
UnterminatedFlowComment: "Unterminated flow-comment."
|
|
});
|
|
function isEsModuleType(bodyElement) {
|
|
return bodyElement.type === "DeclareExportAllDeclaration" || bodyElement.type === "DeclareExportDeclaration" && (!bodyElement.declaration || bodyElement.declaration.type !== "TypeAlias" && bodyElement.declaration.type !== "InterfaceDeclaration");
|
|
}
|
|
function hasTypeImportKind(node) {
|
|
return node.importKind === "type" || node.importKind === "typeof";
|
|
}
|
|
const exportSuggestions = {
|
|
const: "declare export var",
|
|
let: "declare export var",
|
|
type: "export type",
|
|
interface: "export interface"
|
|
};
|
|
function partition(list, test) {
|
|
const list1 = [];
|
|
const list2 = [];
|
|
for (let i = 0; i < list.length; i++) {
|
|
(test(list[i], i, list) ? list1 : list2).push(list[i]);
|
|
}
|
|
return [list1, list2];
|
|
}
|
|
const FLOW_PRAGMA_REGEX = /\*?\s*@((?:no)?flow)\b/;
|
|
var flow = superClass => class FlowParserMixin extends superClass {
|
|
constructor(...args) {
|
|
super(...args);
|
|
this.flowPragma = undefined;
|
|
}
|
|
getScopeHandler() {
|
|
return FlowScopeHandler;
|
|
}
|
|
shouldParseTypes() {
|
|
return this.getPluginOption("flow", "all") || this.flowPragma === "flow";
|
|
}
|
|
finishToken(type, val) {
|
|
if (type !== 134 && type !== 13 && type !== 28) {
|
|
if (this.flowPragma === undefined) {
|
|
this.flowPragma = null;
|
|
}
|
|
}
|
|
super.finishToken(type, val);
|
|
}
|
|
addComment(comment) {
|
|
if (this.flowPragma === undefined) {
|
|
const matches = FLOW_PRAGMA_REGEX.exec(comment.value);
|
|
if (!matches) ;else if (matches[1] === "flow") {
|
|
this.flowPragma = "flow";
|
|
} else if (matches[1] === "noflow") {
|
|
this.flowPragma = "noflow";
|
|
} else {
|
|
throw new Error("Unexpected flow pragma");
|
|
}
|
|
}
|
|
super.addComment(comment);
|
|
}
|
|
flowParseTypeInitialiser(tok) {
|
|
const oldInType = this.state.inType;
|
|
this.state.inType = true;
|
|
this.expect(tok || 14);
|
|
const type = this.flowParseType();
|
|
this.state.inType = oldInType;
|
|
return type;
|
|
}
|
|
flowParsePredicate() {
|
|
const node = this.startNode();
|
|
const moduloLoc = this.state.startLoc;
|
|
this.next();
|
|
this.expectContextual(110);
|
|
if (this.state.lastTokStartLoc.index > moduloLoc.index + 1) {
|
|
this.raise(FlowErrors.UnexpectedSpaceBetweenModuloChecks, moduloLoc);
|
|
}
|
|
if (this.eat(10)) {
|
|
node.value = super.parseExpression();
|
|
this.expect(11);
|
|
return this.finishNode(node, "DeclaredPredicate");
|
|
} else {
|
|
return this.finishNode(node, "InferredPredicate");
|
|
}
|
|
}
|
|
flowParseTypeAndPredicateInitialiser() {
|
|
const oldInType = this.state.inType;
|
|
this.state.inType = true;
|
|
this.expect(14);
|
|
let type = null;
|
|
let predicate = null;
|
|
if (this.match(54)) {
|
|
this.state.inType = oldInType;
|
|
predicate = this.flowParsePredicate();
|
|
} else {
|
|
type = this.flowParseType();
|
|
this.state.inType = oldInType;
|
|
if (this.match(54)) {
|
|
predicate = this.flowParsePredicate();
|
|
}
|
|
}
|
|
return [type, predicate];
|
|
}
|
|
flowParseDeclareClass(node) {
|
|
this.next();
|
|
this.flowParseInterfaceish(node, true);
|
|
return this.finishNode(node, "DeclareClass");
|
|
}
|
|
flowParseDeclareFunction(node) {
|
|
this.next();
|
|
const id = node.id = this.parseIdentifier();
|
|
const typeNode = this.startNode();
|
|
const typeContainer = this.startNode();
|
|
if (this.match(47)) {
|
|
typeNode.typeParameters = this.flowParseTypeParameterDeclaration();
|
|
} else {
|
|
typeNode.typeParameters = null;
|
|
}
|
|
this.expect(10);
|
|
const tmp = this.flowParseFunctionTypeParams();
|
|
typeNode.params = tmp.params;
|
|
typeNode.rest = tmp.rest;
|
|
typeNode.this = tmp._this;
|
|
this.expect(11);
|
|
[typeNode.returnType, node.predicate] = this.flowParseTypeAndPredicateInitialiser();
|
|
typeContainer.typeAnnotation = this.finishNode(typeNode, "FunctionTypeAnnotation");
|
|
id.typeAnnotation = this.finishNode(typeContainer, "TypeAnnotation");
|
|
this.resetEndLocation(id);
|
|
this.semicolon();
|
|
this.scope.declareName(node.id.name, 2048, node.id.loc.start);
|
|
return this.finishNode(node, "DeclareFunction");
|
|
}
|
|
flowParseDeclare(node, insideModule) {
|
|
if (this.match(80)) {
|
|
return this.flowParseDeclareClass(node);
|
|
} else if (this.match(68)) {
|
|
return this.flowParseDeclareFunction(node);
|
|
} else if (this.match(74)) {
|
|
return this.flowParseDeclareVariable(node);
|
|
} else if (this.eatContextual(127)) {
|
|
if (this.match(16)) {
|
|
return this.flowParseDeclareModuleExports(node);
|
|
} else {
|
|
if (insideModule) {
|
|
this.raise(FlowErrors.NestedDeclareModule, this.state.lastTokStartLoc);
|
|
}
|
|
return this.flowParseDeclareModule(node);
|
|
}
|
|
} else if (this.isContextual(130)) {
|
|
return this.flowParseDeclareTypeAlias(node);
|
|
} else if (this.isContextual(131)) {
|
|
return this.flowParseDeclareOpaqueType(node);
|
|
} else if (this.isContextual(129)) {
|
|
return this.flowParseDeclareInterface(node);
|
|
} else if (this.match(82)) {
|
|
return this.flowParseDeclareExportDeclaration(node, insideModule);
|
|
}
|
|
throw this.unexpected();
|
|
}
|
|
flowParseDeclareVariable(node) {
|
|
this.next();
|
|
node.id = this.flowParseTypeAnnotatableIdentifier(true);
|
|
this.scope.declareName(node.id.name, 5, node.id.loc.start);
|
|
this.semicolon();
|
|
return this.finishNode(node, "DeclareVariable");
|
|
}
|
|
flowParseDeclareModule(node) {
|
|
this.scope.enter(0);
|
|
if (this.match(134)) {
|
|
node.id = super.parseExprAtom();
|
|
} else {
|
|
node.id = this.parseIdentifier();
|
|
}
|
|
const bodyNode = node.body = this.startNode();
|
|
const body = bodyNode.body = [];
|
|
this.expect(5);
|
|
while (!this.match(8)) {
|
|
const bodyNode = this.startNode();
|
|
if (this.match(83)) {
|
|
this.next();
|
|
if (!this.isContextual(130) && !this.match(87)) {
|
|
this.raise(FlowErrors.InvalidNonTypeImportInDeclareModule, this.state.lastTokStartLoc);
|
|
}
|
|
body.push(super.parseImport(bodyNode));
|
|
} else {
|
|
this.expectContextual(125, FlowErrors.UnsupportedStatementInDeclareModule);
|
|
body.push(this.flowParseDeclare(bodyNode, true));
|
|
}
|
|
}
|
|
this.scope.exit();
|
|
this.expect(8);
|
|
this.finishNode(bodyNode, "BlockStatement");
|
|
let kind = null;
|
|
let hasModuleExport = false;
|
|
body.forEach(bodyElement => {
|
|
if (isEsModuleType(bodyElement)) {
|
|
if (kind === "CommonJS") {
|
|
this.raise(FlowErrors.AmbiguousDeclareModuleKind, bodyElement);
|
|
}
|
|
kind = "ES";
|
|
} else if (bodyElement.type === "DeclareModuleExports") {
|
|
if (hasModuleExport) {
|
|
this.raise(FlowErrors.DuplicateDeclareModuleExports, bodyElement);
|
|
}
|
|
if (kind === "ES") {
|
|
this.raise(FlowErrors.AmbiguousDeclareModuleKind, bodyElement);
|
|
}
|
|
kind = "CommonJS";
|
|
hasModuleExport = true;
|
|
}
|
|
});
|
|
node.kind = kind || "CommonJS";
|
|
return this.finishNode(node, "DeclareModule");
|
|
}
|
|
flowParseDeclareExportDeclaration(node, insideModule) {
|
|
this.expect(82);
|
|
if (this.eat(65)) {
|
|
if (this.match(68) || this.match(80)) {
|
|
node.declaration = this.flowParseDeclare(this.startNode());
|
|
} else {
|
|
node.declaration = this.flowParseType();
|
|
this.semicolon();
|
|
}
|
|
node.default = true;
|
|
return this.finishNode(node, "DeclareExportDeclaration");
|
|
} else {
|
|
if (this.match(75) || this.isLet() || (this.isContextual(130) || this.isContextual(129)) && !insideModule) {
|
|
const label = this.state.value;
|
|
throw this.raise(FlowErrors.UnsupportedDeclareExportKind, this.state.startLoc, {
|
|
unsupportedExportKind: label,
|
|
suggestion: exportSuggestions[label]
|
|
});
|
|
}
|
|
if (this.match(74) || this.match(68) || this.match(80) || this.isContextual(131)) {
|
|
node.declaration = this.flowParseDeclare(this.startNode());
|
|
node.default = false;
|
|
return this.finishNode(node, "DeclareExportDeclaration");
|
|
} else if (this.match(55) || this.match(5) || this.isContextual(129) || this.isContextual(130) || this.isContextual(131)) {
|
|
node = this.parseExport(node, null);
|
|
if (node.type === "ExportNamedDeclaration") {
|
|
node.default = false;
|
|
delete node.exportKind;
|
|
return this.castNodeTo(node, "DeclareExportDeclaration");
|
|
} else {
|
|
return this.castNodeTo(node, "DeclareExportAllDeclaration");
|
|
}
|
|
}
|
|
}
|
|
throw this.unexpected();
|
|
}
|
|
flowParseDeclareModuleExports(node) {
|
|
this.next();
|
|
this.expectContextual(111);
|
|
node.typeAnnotation = this.flowParseTypeAnnotation();
|
|
this.semicolon();
|
|
return this.finishNode(node, "DeclareModuleExports");
|
|
}
|
|
flowParseDeclareTypeAlias(node) {
|
|
this.next();
|
|
const finished = this.flowParseTypeAlias(node);
|
|
this.castNodeTo(finished, "DeclareTypeAlias");
|
|
return finished;
|
|
}
|
|
flowParseDeclareOpaqueType(node) {
|
|
this.next();
|
|
const finished = this.flowParseOpaqueType(node, true);
|
|
this.castNodeTo(finished, "DeclareOpaqueType");
|
|
return finished;
|
|
}
|
|
flowParseDeclareInterface(node) {
|
|
this.next();
|
|
this.flowParseInterfaceish(node, false);
|
|
return this.finishNode(node, "DeclareInterface");
|
|
}
|
|
flowParseInterfaceish(node, isClass) {
|
|
node.id = this.flowParseRestrictedIdentifier(!isClass, true);
|
|
this.scope.declareName(node.id.name, isClass ? 17 : 8201, node.id.loc.start);
|
|
if (this.match(47)) {
|
|
node.typeParameters = this.flowParseTypeParameterDeclaration();
|
|
} else {
|
|
node.typeParameters = null;
|
|
}
|
|
node.extends = [];
|
|
if (this.eat(81)) {
|
|
do {
|
|
node.extends.push(this.flowParseInterfaceExtends());
|
|
} while (!isClass && this.eat(12));
|
|
}
|
|
if (isClass) {
|
|
node.implements = [];
|
|
node.mixins = [];
|
|
if (this.eatContextual(117)) {
|
|
do {
|
|
node.mixins.push(this.flowParseInterfaceExtends());
|
|
} while (this.eat(12));
|
|
}
|
|
if (this.eatContextual(113)) {
|
|
do {
|
|
node.implements.push(this.flowParseInterfaceExtends());
|
|
} while (this.eat(12));
|
|
}
|
|
}
|
|
node.body = this.flowParseObjectType({
|
|
allowStatic: isClass,
|
|
allowExact: false,
|
|
allowSpread: false,
|
|
allowProto: isClass,
|
|
allowInexact: false
|
|
});
|
|
}
|
|
flowParseInterfaceExtends() {
|
|
const node = this.startNode();
|
|
node.id = this.flowParseQualifiedTypeIdentifier();
|
|
if (this.match(47)) {
|
|
node.typeParameters = this.flowParseTypeParameterInstantiation();
|
|
} else {
|
|
node.typeParameters = null;
|
|
}
|
|
return this.finishNode(node, "InterfaceExtends");
|
|
}
|
|
flowParseInterface(node) {
|
|
this.flowParseInterfaceish(node, false);
|
|
return this.finishNode(node, "InterfaceDeclaration");
|
|
}
|
|
checkNotUnderscore(word) {
|
|
if (word === "_") {
|
|
this.raise(FlowErrors.UnexpectedReservedUnderscore, this.state.startLoc);
|
|
}
|
|
}
|
|
checkReservedType(word, startLoc, declaration) {
|
|
if (!reservedTypes.has(word)) return;
|
|
this.raise(declaration ? FlowErrors.AssignReservedType : FlowErrors.UnexpectedReservedType, startLoc, {
|
|
reservedType: word
|
|
});
|
|
}
|
|
flowParseRestrictedIdentifier(liberal, declaration) {
|
|
this.checkReservedType(this.state.value, this.state.startLoc, declaration);
|
|
return this.parseIdentifier(liberal);
|
|
}
|
|
flowParseTypeAlias(node) {
|
|
node.id = this.flowParseRestrictedIdentifier(false, true);
|
|
this.scope.declareName(node.id.name, 8201, node.id.loc.start);
|
|
if (this.match(47)) {
|
|
node.typeParameters = this.flowParseTypeParameterDeclaration();
|
|
} else {
|
|
node.typeParameters = null;
|
|
}
|
|
node.right = this.flowParseTypeInitialiser(29);
|
|
this.semicolon();
|
|
return this.finishNode(node, "TypeAlias");
|
|
}
|
|
flowParseOpaqueType(node, declare) {
|
|
this.expectContextual(130);
|
|
node.id = this.flowParseRestrictedIdentifier(true, true);
|
|
this.scope.declareName(node.id.name, 8201, node.id.loc.start);
|
|
if (this.match(47)) {
|
|
node.typeParameters = this.flowParseTypeParameterDeclaration();
|
|
} else {
|
|
node.typeParameters = null;
|
|
}
|
|
node.supertype = null;
|
|
if (this.match(14)) {
|
|
node.supertype = this.flowParseTypeInitialiser(14);
|
|
}
|
|
node.impltype = null;
|
|
if (!declare) {
|
|
node.impltype = this.flowParseTypeInitialiser(29);
|
|
}
|
|
this.semicolon();
|
|
return this.finishNode(node, "OpaqueType");
|
|
}
|
|
flowParseTypeParameter(requireDefault = false) {
|
|
const nodeStartLoc = this.state.startLoc;
|
|
const node = this.startNode();
|
|
const variance = this.flowParseVariance();
|
|
const ident = this.flowParseTypeAnnotatableIdentifier();
|
|
node.name = ident.name;
|
|
node.variance = variance;
|
|
node.bound = ident.typeAnnotation;
|
|
if (this.match(29)) {
|
|
this.eat(29);
|
|
node.default = this.flowParseType();
|
|
} else {
|
|
if (requireDefault) {
|
|
this.raise(FlowErrors.MissingTypeParamDefault, nodeStartLoc);
|
|
}
|
|
}
|
|
return this.finishNode(node, "TypeParameter");
|
|
}
|
|
flowParseTypeParameterDeclaration() {
|
|
const oldInType = this.state.inType;
|
|
const node = this.startNode();
|
|
node.params = [];
|
|
this.state.inType = true;
|
|
if (this.match(47) || this.match(143)) {
|
|
this.next();
|
|
} else {
|
|
this.unexpected();
|
|
}
|
|
let defaultRequired = false;
|
|
do {
|
|
const typeParameter = this.flowParseTypeParameter(defaultRequired);
|
|
node.params.push(typeParameter);
|
|
if (typeParameter.default) {
|
|
defaultRequired = true;
|
|
}
|
|
if (!this.match(48)) {
|
|
this.expect(12);
|
|
}
|
|
} while (!this.match(48));
|
|
this.expect(48);
|
|
this.state.inType = oldInType;
|
|
return this.finishNode(node, "TypeParameterDeclaration");
|
|
}
|
|
flowInTopLevelContext(cb) {
|
|
if (this.curContext() !== types.brace) {
|
|
const oldContext = this.state.context;
|
|
this.state.context = [oldContext[0]];
|
|
try {
|
|
return cb();
|
|
} finally {
|
|
this.state.context = oldContext;
|
|
}
|
|
} else {
|
|
return cb();
|
|
}
|
|
}
|
|
flowParseTypeParameterInstantiationInExpression() {
|
|
if (this.reScan_lt() !== 47) return;
|
|
return this.flowParseTypeParameterInstantiation();
|
|
}
|
|
flowParseTypeParameterInstantiation() {
|
|
const node = this.startNode();
|
|
const oldInType = this.state.inType;
|
|
this.state.inType = true;
|
|
node.params = [];
|
|
this.flowInTopLevelContext(() => {
|
|
this.expect(47);
|
|
const oldNoAnonFunctionType = this.state.noAnonFunctionType;
|
|
this.state.noAnonFunctionType = false;
|
|
while (!this.match(48)) {
|
|
node.params.push(this.flowParseType());
|
|
if (!this.match(48)) {
|
|
this.expect(12);
|
|
}
|
|
}
|
|
this.state.noAnonFunctionType = oldNoAnonFunctionType;
|
|
});
|
|
this.state.inType = oldInType;
|
|
if (!this.state.inType && this.curContext() === types.brace) {
|
|
this.reScan_lt_gt();
|
|
}
|
|
this.expect(48);
|
|
return this.finishNode(node, "TypeParameterInstantiation");
|
|
}
|
|
flowParseTypeParameterInstantiationCallOrNew() {
|
|
if (this.reScan_lt() !== 47) return null;
|
|
const node = this.startNode();
|
|
const oldInType = this.state.inType;
|
|
node.params = [];
|
|
this.state.inType = true;
|
|
this.expect(47);
|
|
while (!this.match(48)) {
|
|
node.params.push(this.flowParseTypeOrImplicitInstantiation());
|
|
if (!this.match(48)) {
|
|
this.expect(12);
|
|
}
|
|
}
|
|
this.expect(48);
|
|
this.state.inType = oldInType;
|
|
return this.finishNode(node, "TypeParameterInstantiation");
|
|
}
|
|
flowParseInterfaceType() {
|
|
const node = this.startNode();
|
|
this.expectContextual(129);
|
|
node.extends = [];
|
|
if (this.eat(81)) {
|
|
do {
|
|
node.extends.push(this.flowParseInterfaceExtends());
|
|
} while (this.eat(12));
|
|
}
|
|
node.body = this.flowParseObjectType({
|
|
allowStatic: false,
|
|
allowExact: false,
|
|
allowSpread: false,
|
|
allowProto: false,
|
|
allowInexact: false
|
|
});
|
|
return this.finishNode(node, "InterfaceTypeAnnotation");
|
|
}
|
|
flowParseObjectPropertyKey() {
|
|
return this.match(135) || this.match(134) ? super.parseExprAtom() : this.parseIdentifier(true);
|
|
}
|
|
flowParseObjectTypeIndexer(node, isStatic, variance) {
|
|
node.static = isStatic;
|
|
if (this.lookahead().type === 14) {
|
|
node.id = this.flowParseObjectPropertyKey();
|
|
node.key = this.flowParseTypeInitialiser();
|
|
} else {
|
|
node.id = null;
|
|
node.key = this.flowParseType();
|
|
}
|
|
this.expect(3);
|
|
node.value = this.flowParseTypeInitialiser();
|
|
node.variance = variance;
|
|
return this.finishNode(node, "ObjectTypeIndexer");
|
|
}
|
|
flowParseObjectTypeInternalSlot(node, isStatic) {
|
|
node.static = isStatic;
|
|
node.id = this.flowParseObjectPropertyKey();
|
|
this.expect(3);
|
|
this.expect(3);
|
|
if (this.match(47) || this.match(10)) {
|
|
node.method = true;
|
|
node.optional = false;
|
|
node.value = this.flowParseObjectTypeMethodish(this.startNodeAt(node.loc.start));
|
|
} else {
|
|
node.method = false;
|
|
if (this.eat(17)) {
|
|
node.optional = true;
|
|
}
|
|
node.value = this.flowParseTypeInitialiser();
|
|
}
|
|
return this.finishNode(node, "ObjectTypeInternalSlot");
|
|
}
|
|
flowParseObjectTypeMethodish(node) {
|
|
node.params = [];
|
|
node.rest = null;
|
|
node.typeParameters = null;
|
|
node.this = null;
|
|
if (this.match(47)) {
|
|
node.typeParameters = this.flowParseTypeParameterDeclaration();
|
|
}
|
|
this.expect(10);
|
|
if (this.match(78)) {
|
|
node.this = this.flowParseFunctionTypeParam(true);
|
|
node.this.name = null;
|
|
if (!this.match(11)) {
|
|
this.expect(12);
|
|
}
|
|
}
|
|
while (!this.match(11) && !this.match(21)) {
|
|
node.params.push(this.flowParseFunctionTypeParam(false));
|
|
if (!this.match(11)) {
|
|
this.expect(12);
|
|
}
|
|
}
|
|
if (this.eat(21)) {
|
|
node.rest = this.flowParseFunctionTypeParam(false);
|
|
}
|
|
this.expect(11);
|
|
node.returnType = this.flowParseTypeInitialiser();
|
|
return this.finishNode(node, "FunctionTypeAnnotation");
|
|
}
|
|
flowParseObjectTypeCallProperty(node, isStatic) {
|
|
const valueNode = this.startNode();
|
|
node.static = isStatic;
|
|
node.value = this.flowParseObjectTypeMethodish(valueNode);
|
|
return this.finishNode(node, "ObjectTypeCallProperty");
|
|
}
|
|
flowParseObjectType({
|
|
allowStatic,
|
|
allowExact,
|
|
allowSpread,
|
|
allowProto,
|
|
allowInexact
|
|
}) {
|
|
const oldInType = this.state.inType;
|
|
this.state.inType = true;
|
|
const nodeStart = this.startNode();
|
|
nodeStart.callProperties = [];
|
|
nodeStart.properties = [];
|
|
nodeStart.indexers = [];
|
|
nodeStart.internalSlots = [];
|
|
let endDelim;
|
|
let exact;
|
|
let inexact = false;
|
|
if (allowExact && this.match(6)) {
|
|
this.expect(6);
|
|
endDelim = 9;
|
|
exact = true;
|
|
} else {
|
|
this.expect(5);
|
|
endDelim = 8;
|
|
exact = false;
|
|
}
|
|
nodeStart.exact = exact;
|
|
while (!this.match(endDelim)) {
|
|
let isStatic = false;
|
|
let protoStartLoc = null;
|
|
let inexactStartLoc = null;
|
|
const node = this.startNode();
|
|
if (allowProto && this.isContextual(118)) {
|
|
const lookahead = this.lookahead();
|
|
if (lookahead.type !== 14 && lookahead.type !== 17) {
|
|
this.next();
|
|
protoStartLoc = this.state.startLoc;
|
|
allowStatic = false;
|
|
}
|
|
}
|
|
if (allowStatic && this.isContextual(106)) {
|
|
const lookahead = this.lookahead();
|
|
if (lookahead.type !== 14 && lookahead.type !== 17) {
|
|
this.next();
|
|
isStatic = true;
|
|
}
|
|
}
|
|
const variance = this.flowParseVariance();
|
|
if (this.eat(0)) {
|
|
if (protoStartLoc != null) {
|
|
this.unexpected(protoStartLoc);
|
|
}
|
|
if (this.eat(0)) {
|
|
if (variance) {
|
|
this.unexpected(variance.loc.start);
|
|
}
|
|
nodeStart.internalSlots.push(this.flowParseObjectTypeInternalSlot(node, isStatic));
|
|
} else {
|
|
nodeStart.indexers.push(this.flowParseObjectTypeIndexer(node, isStatic, variance));
|
|
}
|
|
} else if (this.match(10) || this.match(47)) {
|
|
if (protoStartLoc != null) {
|
|
this.unexpected(protoStartLoc);
|
|
}
|
|
if (variance) {
|
|
this.unexpected(variance.loc.start);
|
|
}
|
|
nodeStart.callProperties.push(this.flowParseObjectTypeCallProperty(node, isStatic));
|
|
} else {
|
|
let kind = "init";
|
|
if (this.isContextual(99) || this.isContextual(104)) {
|
|
const lookahead = this.lookahead();
|
|
if (tokenIsLiteralPropertyName(lookahead.type)) {
|
|
kind = this.state.value;
|
|
this.next();
|
|
}
|
|
}
|
|
const propOrInexact = this.flowParseObjectTypeProperty(node, isStatic, protoStartLoc, variance, kind, allowSpread, allowInexact != null ? allowInexact : !exact);
|
|
if (propOrInexact === null) {
|
|
inexact = true;
|
|
inexactStartLoc = this.state.lastTokStartLoc;
|
|
} else {
|
|
nodeStart.properties.push(propOrInexact);
|
|
}
|
|
}
|
|
this.flowObjectTypeSemicolon();
|
|
if (inexactStartLoc && !this.match(8) && !this.match(9)) {
|
|
this.raise(FlowErrors.UnexpectedExplicitInexactInObject, inexactStartLoc);
|
|
}
|
|
}
|
|
this.expect(endDelim);
|
|
if (allowSpread) {
|
|
nodeStart.inexact = inexact;
|
|
}
|
|
const out = this.finishNode(nodeStart, "ObjectTypeAnnotation");
|
|
this.state.inType = oldInType;
|
|
return out;
|
|
}
|
|
flowParseObjectTypeProperty(node, isStatic, protoStartLoc, variance, kind, allowSpread, allowInexact) {
|
|
if (this.eat(21)) {
|
|
const isInexactToken = this.match(12) || this.match(13) || this.match(8) || this.match(9);
|
|
if (isInexactToken) {
|
|
if (!allowSpread) {
|
|
this.raise(FlowErrors.InexactInsideNonObject, this.state.lastTokStartLoc);
|
|
} else if (!allowInexact) {
|
|
this.raise(FlowErrors.InexactInsideExact, this.state.lastTokStartLoc);
|
|
}
|
|
if (variance) {
|
|
this.raise(FlowErrors.InexactVariance, variance);
|
|
}
|
|
return null;
|
|
}
|
|
if (!allowSpread) {
|
|
this.raise(FlowErrors.UnexpectedSpreadType, this.state.lastTokStartLoc);
|
|
}
|
|
if (protoStartLoc != null) {
|
|
this.unexpected(protoStartLoc);
|
|
}
|
|
if (variance) {
|
|
this.raise(FlowErrors.SpreadVariance, variance);
|
|
}
|
|
node.argument = this.flowParseType();
|
|
return this.finishNode(node, "ObjectTypeSpreadProperty");
|
|
} else {
|
|
node.key = this.flowParseObjectPropertyKey();
|
|
node.static = isStatic;
|
|
node.proto = protoStartLoc != null;
|
|
node.kind = kind;
|
|
let optional = false;
|
|
if (this.match(47) || this.match(10)) {
|
|
node.method = true;
|
|
if (protoStartLoc != null) {
|
|
this.unexpected(protoStartLoc);
|
|
}
|
|
if (variance) {
|
|
this.unexpected(variance.loc.start);
|
|
}
|
|
node.value = this.flowParseObjectTypeMethodish(this.startNodeAt(node.loc.start));
|
|
if (kind === "get" || kind === "set") {
|
|
this.flowCheckGetterSetterParams(node);
|
|
}
|
|
if (!allowSpread && node.key.name === "constructor" && node.value.this) {
|
|
this.raise(FlowErrors.ThisParamBannedInConstructor, node.value.this);
|
|
}
|
|
} else {
|
|
if (kind !== "init") this.unexpected();
|
|
node.method = false;
|
|
if (this.eat(17)) {
|
|
optional = true;
|
|
}
|
|
node.value = this.flowParseTypeInitialiser();
|
|
node.variance = variance;
|
|
}
|
|
node.optional = optional;
|
|
return this.finishNode(node, "ObjectTypeProperty");
|
|
}
|
|
}
|
|
flowCheckGetterSetterParams(property) {
|
|
const paramCount = property.kind === "get" ? 0 : 1;
|
|
const length = property.value.params.length + (property.value.rest ? 1 : 0);
|
|
if (property.value.this) {
|
|
this.raise(property.kind === "get" ? FlowErrors.GetterMayNotHaveThisParam : FlowErrors.SetterMayNotHaveThisParam, property.value.this);
|
|
}
|
|
if (length !== paramCount) {
|
|
this.raise(property.kind === "get" ? Errors.BadGetterArity : Errors.BadSetterArity, property);
|
|
}
|
|
if (property.kind === "set" && property.value.rest) {
|
|
this.raise(Errors.BadSetterRestParameter, property);
|
|
}
|
|
}
|
|
flowObjectTypeSemicolon() {
|
|
if (!this.eat(13) && !this.eat(12) && !this.match(8) && !this.match(9)) {
|
|
this.unexpected();
|
|
}
|
|
}
|
|
flowParseQualifiedTypeIdentifier(startLoc, id) {
|
|
startLoc != null ? startLoc : startLoc = this.state.startLoc;
|
|
let node = id || this.flowParseRestrictedIdentifier(true);
|
|
while (this.eat(16)) {
|
|
const node2 = this.startNodeAt(startLoc);
|
|
node2.qualification = node;
|
|
node2.id = this.flowParseRestrictedIdentifier(true);
|
|
node = this.finishNode(node2, "QualifiedTypeIdentifier");
|
|
}
|
|
return node;
|
|
}
|
|
flowParseGenericType(startLoc, id) {
|
|
const node = this.startNodeAt(startLoc);
|
|
node.typeParameters = null;
|
|
node.id = this.flowParseQualifiedTypeIdentifier(startLoc, id);
|
|
if (this.match(47)) {
|
|
node.typeParameters = this.flowParseTypeParameterInstantiation();
|
|
}
|
|
return this.finishNode(node, "GenericTypeAnnotation");
|
|
}
|
|
flowParseTypeofType() {
|
|
const node = this.startNode();
|
|
this.expect(87);
|
|
node.argument = this.flowParsePrimaryType();
|
|
return this.finishNode(node, "TypeofTypeAnnotation");
|
|
}
|
|
flowParseTupleType() {
|
|
const node = this.startNode();
|
|
node.types = [];
|
|
this.expect(0);
|
|
while (this.state.pos < this.length && !this.match(3)) {
|
|
node.types.push(this.flowParseType());
|
|
if (this.match(3)) break;
|
|
this.expect(12);
|
|
}
|
|
this.expect(3);
|
|
return this.finishNode(node, "TupleTypeAnnotation");
|
|
}
|
|
flowParseFunctionTypeParam(first) {
|
|
let name = null;
|
|
let optional = false;
|
|
let typeAnnotation = null;
|
|
const node = this.startNode();
|
|
const lh = this.lookahead();
|
|
const isThis = this.state.type === 78;
|
|
if (lh.type === 14 || lh.type === 17) {
|
|
if (isThis && !first) {
|
|
this.raise(FlowErrors.ThisParamMustBeFirst, node);
|
|
}
|
|
name = this.parseIdentifier(isThis);
|
|
if (this.eat(17)) {
|
|
optional = true;
|
|
if (isThis) {
|
|
this.raise(FlowErrors.ThisParamMayNotBeOptional, node);
|
|
}
|
|
}
|
|
typeAnnotation = this.flowParseTypeInitialiser();
|
|
} else {
|
|
typeAnnotation = this.flowParseType();
|
|
}
|
|
node.name = name;
|
|
node.optional = optional;
|
|
node.typeAnnotation = typeAnnotation;
|
|
return this.finishNode(node, "FunctionTypeParam");
|
|
}
|
|
reinterpretTypeAsFunctionTypeParam(type) {
|
|
const node = this.startNodeAt(type.loc.start);
|
|
node.name = null;
|
|
node.optional = false;
|
|
node.typeAnnotation = type;
|
|
return this.finishNode(node, "FunctionTypeParam");
|
|
}
|
|
flowParseFunctionTypeParams(params = []) {
|
|
let rest = null;
|
|
let _this = null;
|
|
if (this.match(78)) {
|
|
_this = this.flowParseFunctionTypeParam(true);
|
|
_this.name = null;
|
|
if (!this.match(11)) {
|
|
this.expect(12);
|
|
}
|
|
}
|
|
while (!this.match(11) && !this.match(21)) {
|
|
params.push(this.flowParseFunctionTypeParam(false));
|
|
if (!this.match(11)) {
|
|
this.expect(12);
|
|
}
|
|
}
|
|
if (this.eat(21)) {
|
|
rest = this.flowParseFunctionTypeParam(false);
|
|
}
|
|
return {
|
|
params,
|
|
rest,
|
|
_this
|
|
};
|
|
}
|
|
flowIdentToTypeAnnotation(startLoc, node, id) {
|
|
switch (id.name) {
|
|
case "any":
|
|
return this.finishNode(node, "AnyTypeAnnotation");
|
|
case "bool":
|
|
case "boolean":
|
|
return this.finishNode(node, "BooleanTypeAnnotation");
|
|
case "mixed":
|
|
return this.finishNode(node, "MixedTypeAnnotation");
|
|
case "empty":
|
|
return this.finishNode(node, "EmptyTypeAnnotation");
|
|
case "number":
|
|
return this.finishNode(node, "NumberTypeAnnotation");
|
|
case "string":
|
|
return this.finishNode(node, "StringTypeAnnotation");
|
|
case "symbol":
|
|
return this.finishNode(node, "SymbolTypeAnnotation");
|
|
default:
|
|
this.checkNotUnderscore(id.name);
|
|
return this.flowParseGenericType(startLoc, id);
|
|
}
|
|
}
|
|
flowParsePrimaryType() {
|
|
const startLoc = this.state.startLoc;
|
|
const node = this.startNode();
|
|
let tmp;
|
|
let type;
|
|
let isGroupedType = false;
|
|
const oldNoAnonFunctionType = this.state.noAnonFunctionType;
|
|
switch (this.state.type) {
|
|
case 5:
|
|
return this.flowParseObjectType({
|
|
allowStatic: false,
|
|
allowExact: false,
|
|
allowSpread: true,
|
|
allowProto: false,
|
|
allowInexact: true
|
|
});
|
|
case 6:
|
|
return this.flowParseObjectType({
|
|
allowStatic: false,
|
|
allowExact: true,
|
|
allowSpread: true,
|
|
allowProto: false,
|
|
allowInexact: false
|
|
});
|
|
case 0:
|
|
this.state.noAnonFunctionType = false;
|
|
type = this.flowParseTupleType();
|
|
this.state.noAnonFunctionType = oldNoAnonFunctionType;
|
|
return type;
|
|
case 47:
|
|
{
|
|
const node = this.startNode();
|
|
node.typeParameters = this.flowParseTypeParameterDeclaration();
|
|
this.expect(10);
|
|
tmp = this.flowParseFunctionTypeParams();
|
|
node.params = tmp.params;
|
|
node.rest = tmp.rest;
|
|
node.this = tmp._this;
|
|
this.expect(11);
|
|
this.expect(19);
|
|
node.returnType = this.flowParseType();
|
|
return this.finishNode(node, "FunctionTypeAnnotation");
|
|
}
|
|
case 10:
|
|
{
|
|
const node = this.startNode();
|
|
this.next();
|
|
if (!this.match(11) && !this.match(21)) {
|
|
if (tokenIsIdentifier(this.state.type) || this.match(78)) {
|
|
const token = this.lookahead().type;
|
|
isGroupedType = token !== 17 && token !== 14;
|
|
} else {
|
|
isGroupedType = true;
|
|
}
|
|
}
|
|
if (isGroupedType) {
|
|
this.state.noAnonFunctionType = false;
|
|
type = this.flowParseType();
|
|
this.state.noAnonFunctionType = oldNoAnonFunctionType;
|
|
if (this.state.noAnonFunctionType || !(this.match(12) || this.match(11) && this.lookahead().type === 19)) {
|
|
this.expect(11);
|
|
return type;
|
|
} else {
|
|
this.eat(12);
|
|
}
|
|
}
|
|
if (type) {
|
|
tmp = this.flowParseFunctionTypeParams([this.reinterpretTypeAsFunctionTypeParam(type)]);
|
|
} else {
|
|
tmp = this.flowParseFunctionTypeParams();
|
|
}
|
|
node.params = tmp.params;
|
|
node.rest = tmp.rest;
|
|
node.this = tmp._this;
|
|
this.expect(11);
|
|
this.expect(19);
|
|
node.returnType = this.flowParseType();
|
|
node.typeParameters = null;
|
|
return this.finishNode(node, "FunctionTypeAnnotation");
|
|
}
|
|
case 134:
|
|
return this.parseLiteral(this.state.value, "StringLiteralTypeAnnotation");
|
|
case 85:
|
|
case 86:
|
|
node.value = this.match(85);
|
|
this.next();
|
|
return this.finishNode(node, "BooleanLiteralTypeAnnotation");
|
|
case 53:
|
|
if (this.state.value === "-") {
|
|
this.next();
|
|
if (this.match(135)) {
|
|
return this.parseLiteralAtNode(-this.state.value, "NumberLiteralTypeAnnotation", node);
|
|
}
|
|
if (this.match(136)) {
|
|
return this.parseLiteralAtNode(-this.state.value, "BigIntLiteralTypeAnnotation", node);
|
|
}
|
|
throw this.raise(FlowErrors.UnexpectedSubtractionOperand, this.state.startLoc);
|
|
}
|
|
throw this.unexpected();
|
|
case 135:
|
|
return this.parseLiteral(this.state.value, "NumberLiteralTypeAnnotation");
|
|
case 136:
|
|
return this.parseLiteral(this.state.value, "BigIntLiteralTypeAnnotation");
|
|
case 88:
|
|
this.next();
|
|
return this.finishNode(node, "VoidTypeAnnotation");
|
|
case 84:
|
|
this.next();
|
|
return this.finishNode(node, "NullLiteralTypeAnnotation");
|
|
case 78:
|
|
this.next();
|
|
return this.finishNode(node, "ThisTypeAnnotation");
|
|
case 55:
|
|
this.next();
|
|
return this.finishNode(node, "ExistsTypeAnnotation");
|
|
case 87:
|
|
return this.flowParseTypeofType();
|
|
default:
|
|
if (tokenIsKeyword(this.state.type)) {
|
|
const label = tokenLabelName(this.state.type);
|
|
this.next();
|
|
return super.createIdentifier(node, label);
|
|
} else if (tokenIsIdentifier(this.state.type)) {
|
|
if (this.isContextual(129)) {
|
|
return this.flowParseInterfaceType();
|
|
}
|
|
return this.flowIdentToTypeAnnotation(startLoc, node, this.parseIdentifier());
|
|
}
|
|
}
|
|
throw this.unexpected();
|
|
}
|
|
flowParsePostfixType() {
|
|
const startLoc = this.state.startLoc;
|
|
let type = this.flowParsePrimaryType();
|
|
let seenOptionalIndexedAccess = false;
|
|
while ((this.match(0) || this.match(18)) && !this.canInsertSemicolon()) {
|
|
const node = this.startNodeAt(startLoc);
|
|
const optional = this.eat(18);
|
|
seenOptionalIndexedAccess = seenOptionalIndexedAccess || optional;
|
|
this.expect(0);
|
|
if (!optional && this.match(3)) {
|
|
node.elementType = type;
|
|
this.next();
|
|
type = this.finishNode(node, "ArrayTypeAnnotation");
|
|
} else {
|
|
node.objectType = type;
|
|
node.indexType = this.flowParseType();
|
|
this.expect(3);
|
|
if (seenOptionalIndexedAccess) {
|
|
node.optional = optional;
|
|
type = this.finishNode(node, "OptionalIndexedAccessType");
|
|
} else {
|
|
type = this.finishNode(node, "IndexedAccessType");
|
|
}
|
|
}
|
|
}
|
|
return type;
|
|
}
|
|
flowParsePrefixType() {
|
|
const node = this.startNode();
|
|
if (this.eat(17)) {
|
|
node.typeAnnotation = this.flowParsePrefixType();
|
|
return this.finishNode(node, "NullableTypeAnnotation");
|
|
} else {
|
|
return this.flowParsePostfixType();
|
|
}
|
|
}
|
|
flowParseAnonFunctionWithoutParens() {
|
|
const param = this.flowParsePrefixType();
|
|
if (!this.state.noAnonFunctionType && this.eat(19)) {
|
|
const node = this.startNodeAt(param.loc.start);
|
|
node.params = [this.reinterpretTypeAsFunctionTypeParam(param)];
|
|
node.rest = null;
|
|
node.this = null;
|
|
node.returnType = this.flowParseType();
|
|
node.typeParameters = null;
|
|
return this.finishNode(node, "FunctionTypeAnnotation");
|
|
}
|
|
return param;
|
|
}
|
|
flowParseIntersectionType() {
|
|
const node = this.startNode();
|
|
this.eat(45);
|
|
const type = this.flowParseAnonFunctionWithoutParens();
|
|
node.types = [type];
|
|
while (this.eat(45)) {
|
|
node.types.push(this.flowParseAnonFunctionWithoutParens());
|
|
}
|
|
return node.types.length === 1 ? type : this.finishNode(node, "IntersectionTypeAnnotation");
|
|
}
|
|
flowParseUnionType() {
|
|
const node = this.startNode();
|
|
this.eat(43);
|
|
const type = this.flowParseIntersectionType();
|
|
node.types = [type];
|
|
while (this.eat(43)) {
|
|
node.types.push(this.flowParseIntersectionType());
|
|
}
|
|
return node.types.length === 1 ? type : this.finishNode(node, "UnionTypeAnnotation");
|
|
}
|
|
flowParseType() {
|
|
const oldInType = this.state.inType;
|
|
this.state.inType = true;
|
|
const type = this.flowParseUnionType();
|
|
this.state.inType = oldInType;
|
|
return type;
|
|
}
|
|
flowParseTypeOrImplicitInstantiation() {
|
|
if (this.state.type === 132 && this.state.value === "_") {
|
|
const startLoc = this.state.startLoc;
|
|
const node = this.parseIdentifier();
|
|
return this.flowParseGenericType(startLoc, node);
|
|
} else {
|
|
return this.flowParseType();
|
|
}
|
|
}
|
|
flowParseTypeAnnotation() {
|
|
const node = this.startNode();
|
|
node.typeAnnotation = this.flowParseTypeInitialiser();
|
|
return this.finishNode(node, "TypeAnnotation");
|
|
}
|
|
flowParseTypeAnnotatableIdentifier(allowPrimitiveOverride) {
|
|
const ident = allowPrimitiveOverride ? this.parseIdentifier() : this.flowParseRestrictedIdentifier();
|
|
if (this.match(14)) {
|
|
ident.typeAnnotation = this.flowParseTypeAnnotation();
|
|
this.resetEndLocation(ident);
|
|
}
|
|
return ident;
|
|
}
|
|
typeCastToParameter(node) {
|
|
node.expression.typeAnnotation = node.typeAnnotation;
|
|
this.resetEndLocation(node.expression, node.typeAnnotation.loc.end);
|
|
return node.expression;
|
|
}
|
|
flowParseVariance() {
|
|
let variance = null;
|
|
if (this.match(53)) {
|
|
variance = this.startNode();
|
|
if (this.state.value === "+") {
|
|
variance.kind = "plus";
|
|
} else {
|
|
variance.kind = "minus";
|
|
}
|
|
this.next();
|
|
return this.finishNode(variance, "Variance");
|
|
}
|
|
return variance;
|
|
}
|
|
parseFunctionBody(node, allowExpressionBody, isMethod = false) {
|
|
if (allowExpressionBody) {
|
|
this.forwardNoArrowParamsConversionAt(node, () => super.parseFunctionBody(node, true, isMethod));
|
|
return;
|
|
}
|
|
super.parseFunctionBody(node, false, isMethod);
|
|
}
|
|
parseFunctionBodyAndFinish(node, type, isMethod = false) {
|
|
if (this.match(14)) {
|
|
const typeNode = this.startNode();
|
|
[typeNode.typeAnnotation, node.predicate] = this.flowParseTypeAndPredicateInitialiser();
|
|
node.returnType = typeNode.typeAnnotation ? this.finishNode(typeNode, "TypeAnnotation") : null;
|
|
}
|
|
return super.parseFunctionBodyAndFinish(node, type, isMethod);
|
|
}
|
|
parseStatementLike(flags) {
|
|
if (this.state.strict && this.isContextual(129)) {
|
|
const lookahead = this.lookahead();
|
|
if (tokenIsKeywordOrIdentifier(lookahead.type)) {
|
|
const node = this.startNode();
|
|
this.next();
|
|
return this.flowParseInterface(node);
|
|
}
|
|
} else if (this.isContextual(126)) {
|
|
const node = this.startNode();
|
|
this.next();
|
|
return this.flowParseEnumDeclaration(node);
|
|
}
|
|
const stmt = super.parseStatementLike(flags);
|
|
if (this.flowPragma === undefined && !this.isValidDirective(stmt)) {
|
|
this.flowPragma = null;
|
|
}
|
|
return stmt;
|
|
}
|
|
parseExpressionStatement(node, expr, decorators) {
|
|
if (expr.type === "Identifier") {
|
|
if (expr.name === "declare") {
|
|
if (this.match(80) || tokenIsIdentifier(this.state.type) || this.match(68) || this.match(74) || this.match(82)) {
|
|
return this.flowParseDeclare(node);
|
|
}
|
|
} else if (tokenIsIdentifier(this.state.type)) {
|
|
if (expr.name === "interface") {
|
|
return this.flowParseInterface(node);
|
|
} else if (expr.name === "type") {
|
|
return this.flowParseTypeAlias(node);
|
|
} else if (expr.name === "opaque") {
|
|
return this.flowParseOpaqueType(node, false);
|
|
}
|
|
}
|
|
}
|
|
return super.parseExpressionStatement(node, expr, decorators);
|
|
}
|
|
shouldParseExportDeclaration() {
|
|
const {
|
|
type
|
|
} = this.state;
|
|
if (type === 126 || tokenIsFlowInterfaceOrTypeOrOpaque(type)) {
|
|
return !this.state.containsEsc;
|
|
}
|
|
return super.shouldParseExportDeclaration();
|
|
}
|
|
isExportDefaultSpecifier() {
|
|
const {
|
|
type
|
|
} = this.state;
|
|
if (type === 126 || tokenIsFlowInterfaceOrTypeOrOpaque(type)) {
|
|
return this.state.containsEsc;
|
|
}
|
|
return super.isExportDefaultSpecifier();
|
|
}
|
|
parseExportDefaultExpression() {
|
|
if (this.isContextual(126)) {
|
|
const node = this.startNode();
|
|
this.next();
|
|
return this.flowParseEnumDeclaration(node);
|
|
}
|
|
return super.parseExportDefaultExpression();
|
|
}
|
|
parseConditional(expr, startLoc, refExpressionErrors) {
|
|
if (!this.match(17)) return expr;
|
|
if (this.state.maybeInArrowParameters) {
|
|
const nextCh = this.lookaheadCharCode();
|
|
if (nextCh === 44 || nextCh === 61 || nextCh === 58 || nextCh === 41) {
|
|
this.setOptionalParametersError(refExpressionErrors);
|
|
return expr;
|
|
}
|
|
}
|
|
this.expect(17);
|
|
const state = this.state.clone();
|
|
const originalNoArrowAt = this.state.noArrowAt;
|
|
const node = this.startNodeAt(startLoc);
|
|
let {
|
|
consequent,
|
|
failed
|
|
} = this.tryParseConditionalConsequent();
|
|
let [valid, invalid] = this.getArrowLikeExpressions(consequent);
|
|
if (failed || invalid.length > 0) {
|
|
const noArrowAt = [...originalNoArrowAt];
|
|
if (invalid.length > 0) {
|
|
this.state = state;
|
|
this.state.noArrowAt = noArrowAt;
|
|
for (let i = 0; i < invalid.length; i++) {
|
|
noArrowAt.push(invalid[i].start);
|
|
}
|
|
({
|
|
consequent,
|
|
failed
|
|
} = this.tryParseConditionalConsequent());
|
|
[valid, invalid] = this.getArrowLikeExpressions(consequent);
|
|
}
|
|
if (failed && valid.length > 1) {
|
|
this.raise(FlowErrors.AmbiguousConditionalArrow, state.startLoc);
|
|
}
|
|
if (failed && valid.length === 1) {
|
|
this.state = state;
|
|
noArrowAt.push(valid[0].start);
|
|
this.state.noArrowAt = noArrowAt;
|
|
({
|
|
consequent,
|
|
failed
|
|
} = this.tryParseConditionalConsequent());
|
|
}
|
|
}
|
|
this.getArrowLikeExpressions(consequent, true);
|
|
this.state.noArrowAt = originalNoArrowAt;
|
|
this.expect(14);
|
|
node.test = expr;
|
|
node.consequent = consequent;
|
|
node.alternate = this.forwardNoArrowParamsConversionAt(node, () => this.parseMaybeAssign(undefined, undefined));
|
|
return this.finishNode(node, "ConditionalExpression");
|
|
}
|
|
tryParseConditionalConsequent() {
|
|
this.state.noArrowParamsConversionAt.push(this.state.start);
|
|
const consequent = this.parseMaybeAssignAllowIn();
|
|
const failed = !this.match(14);
|
|
this.state.noArrowParamsConversionAt.pop();
|
|
return {
|
|
consequent,
|
|
failed
|
|
};
|
|
}
|
|
getArrowLikeExpressions(node, disallowInvalid) {
|
|
const stack = [node];
|
|
const arrows = [];
|
|
while (stack.length !== 0) {
|
|
const node = stack.pop();
|
|
if (node.type === "ArrowFunctionExpression" && node.body.type !== "BlockStatement") {
|
|
if (node.typeParameters || !node.returnType) {
|
|
this.finishArrowValidation(node);
|
|
} else {
|
|
arrows.push(node);
|
|
}
|
|
stack.push(node.body);
|
|
} else if (node.type === "ConditionalExpression") {
|
|
stack.push(node.consequent);
|
|
stack.push(node.alternate);
|
|
}
|
|
}
|
|
if (disallowInvalid) {
|
|
arrows.forEach(node => this.finishArrowValidation(node));
|
|
return [arrows, []];
|
|
}
|
|
return partition(arrows, node => node.params.every(param => this.isAssignable(param, true)));
|
|
}
|
|
finishArrowValidation(node) {
|
|
var _node$extra;
|
|
this.toAssignableList(node.params, (_node$extra = node.extra) == null ? void 0 : _node$extra.trailingCommaLoc, false);
|
|
this.scope.enter(514 | 4);
|
|
super.checkParams(node, false, true);
|
|
this.scope.exit();
|
|
}
|
|
forwardNoArrowParamsConversionAt(node, parse) {
|
|
let result;
|
|
if (this.state.noArrowParamsConversionAt.includes(this.offsetToSourcePos(node.start))) {
|
|
this.state.noArrowParamsConversionAt.push(this.state.start);
|
|
result = parse();
|
|
this.state.noArrowParamsConversionAt.pop();
|
|
} else {
|
|
result = parse();
|
|
}
|
|
return result;
|
|
}
|
|
parseParenItem(node, startLoc) {
|
|
const newNode = super.parseParenItem(node, startLoc);
|
|
if (this.eat(17)) {
|
|
newNode.optional = true;
|
|
this.resetEndLocation(node);
|
|
}
|
|
if (this.match(14)) {
|
|
const typeCastNode = this.startNodeAt(startLoc);
|
|
typeCastNode.expression = newNode;
|
|
typeCastNode.typeAnnotation = this.flowParseTypeAnnotation();
|
|
return this.finishNode(typeCastNode, "TypeCastExpression");
|
|
}
|
|
return newNode;
|
|
}
|
|
assertModuleNodeAllowed(node) {
|
|
if (node.type === "ImportDeclaration" && (node.importKind === "type" || node.importKind === "typeof") || node.type === "ExportNamedDeclaration" && node.exportKind === "type" || node.type === "ExportAllDeclaration" && node.exportKind === "type") {
|
|
return;
|
|
}
|
|
super.assertModuleNodeAllowed(node);
|
|
}
|
|
parseExportDeclaration(node) {
|
|
if (this.isContextual(130)) {
|
|
node.exportKind = "type";
|
|
const declarationNode = this.startNode();
|
|
this.next();
|
|
if (this.match(5)) {
|
|
node.specifiers = this.parseExportSpecifiers(true);
|
|
super.parseExportFrom(node);
|
|
return null;
|
|
} else {
|
|
return this.flowParseTypeAlias(declarationNode);
|
|
}
|
|
} else if (this.isContextual(131)) {
|
|
node.exportKind = "type";
|
|
const declarationNode = this.startNode();
|
|
this.next();
|
|
return this.flowParseOpaqueType(declarationNode, false);
|
|
} else if (this.isContextual(129)) {
|
|
node.exportKind = "type";
|
|
const declarationNode = this.startNode();
|
|
this.next();
|
|
return this.flowParseInterface(declarationNode);
|
|
} else if (this.isContextual(126)) {
|
|
node.exportKind = "value";
|
|
const declarationNode = this.startNode();
|
|
this.next();
|
|
return this.flowParseEnumDeclaration(declarationNode);
|
|
} else {
|
|
return super.parseExportDeclaration(node);
|
|
}
|
|
}
|
|
eatExportStar(node) {
|
|
if (super.eatExportStar(node)) return true;
|
|
if (this.isContextual(130) && this.lookahead().type === 55) {
|
|
node.exportKind = "type";
|
|
this.next();
|
|
this.next();
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
maybeParseExportNamespaceSpecifier(node) {
|
|
const {
|
|
startLoc
|
|
} = this.state;
|
|
const hasNamespace = super.maybeParseExportNamespaceSpecifier(node);
|
|
if (hasNamespace && node.exportKind === "type") {
|
|
this.unexpected(startLoc);
|
|
}
|
|
return hasNamespace;
|
|
}
|
|
parseClassId(node, isStatement, optionalId) {
|
|
super.parseClassId(node, isStatement, optionalId);
|
|
if (this.match(47)) {
|
|
node.typeParameters = this.flowParseTypeParameterDeclaration();
|
|
}
|
|
}
|
|
parseClassMember(classBody, member, state) {
|
|
const {
|
|
startLoc
|
|
} = this.state;
|
|
if (this.isContextual(125)) {
|
|
if (super.parseClassMemberFromModifier(classBody, member)) {
|
|
return;
|
|
}
|
|
member.declare = true;
|
|
}
|
|
super.parseClassMember(classBody, member, state);
|
|
if (member.declare) {
|
|
if (member.type !== "ClassProperty" && member.type !== "ClassPrivateProperty" && member.type !== "PropertyDefinition") {
|
|
this.raise(FlowErrors.DeclareClassElement, startLoc);
|
|
} else if (member.value) {
|
|
this.raise(FlowErrors.DeclareClassFieldInitializer, member.value);
|
|
}
|
|
}
|
|
}
|
|
isIterator(word) {
|
|
return word === "iterator" || word === "asyncIterator";
|
|
}
|
|
readIterator() {
|
|
const word = super.readWord1();
|
|
const fullWord = "@@" + word;
|
|
if (!this.isIterator(word) || !this.state.inType) {
|
|
this.raise(Errors.InvalidIdentifier, this.state.curPosition(), {
|
|
identifierName: fullWord
|
|
});
|
|
}
|
|
this.finishToken(132, fullWord);
|
|
}
|
|
getTokenFromCode(code) {
|
|
const next = this.input.charCodeAt(this.state.pos + 1);
|
|
if (code === 123 && next === 124) {
|
|
this.finishOp(6, 2);
|
|
} else if (this.state.inType && (code === 62 || code === 60)) {
|
|
this.finishOp(code === 62 ? 48 : 47, 1);
|
|
} else if (this.state.inType && code === 63) {
|
|
if (next === 46) {
|
|
this.finishOp(18, 2);
|
|
} else {
|
|
this.finishOp(17, 1);
|
|
}
|
|
} else if (isIteratorStart(code, next, this.input.charCodeAt(this.state.pos + 2))) {
|
|
this.state.pos += 2;
|
|
this.readIterator();
|
|
} else {
|
|
super.getTokenFromCode(code);
|
|
}
|
|
}
|
|
isAssignable(node, isBinding) {
|
|
if (node.type === "TypeCastExpression") {
|
|
return this.isAssignable(node.expression, isBinding);
|
|
} else {
|
|
return super.isAssignable(node, isBinding);
|
|
}
|
|
}
|
|
toAssignable(node, isLHS = false) {
|
|
if (!isLHS && node.type === "AssignmentExpression" && node.left.type === "TypeCastExpression") {
|
|
node.left = this.typeCastToParameter(node.left);
|
|
}
|
|
super.toAssignable(node, isLHS);
|
|
}
|
|
toAssignableList(exprList, trailingCommaLoc, isLHS) {
|
|
for (let i = 0; i < exprList.length; i++) {
|
|
const expr = exprList[i];
|
|
if ((expr == null ? void 0 : expr.type) === "TypeCastExpression") {
|
|
exprList[i] = this.typeCastToParameter(expr);
|
|
}
|
|
}
|
|
super.toAssignableList(exprList, trailingCommaLoc, isLHS);
|
|
}
|
|
toReferencedList(exprList, isParenthesizedExpr) {
|
|
for (let i = 0; i < exprList.length; i++) {
|
|
var _expr$extra;
|
|
const expr = exprList[i];
|
|
if (expr && expr.type === "TypeCastExpression" && !((_expr$extra = expr.extra) != null && _expr$extra.parenthesized) && (exprList.length > 1 || !isParenthesizedExpr)) {
|
|
this.raise(FlowErrors.TypeCastInPattern, expr.typeAnnotation);
|
|
}
|
|
}
|
|
return exprList;
|
|
}
|
|
parseArrayLike(close, isTuple, refExpressionErrors) {
|
|
const node = super.parseArrayLike(close, isTuple, refExpressionErrors);
|
|
if (refExpressionErrors != null && !this.state.maybeInArrowParameters) {
|
|
this.toReferencedList(node.elements);
|
|
}
|
|
return node;
|
|
}
|
|
isValidLVal(type, disallowCallExpression, isParenthesized, binding) {
|
|
return type === "TypeCastExpression" || super.isValidLVal(type, disallowCallExpression, isParenthesized, binding);
|
|
}
|
|
parseClassProperty(node) {
|
|
if (this.match(14)) {
|
|
node.typeAnnotation = this.flowParseTypeAnnotation();
|
|
}
|
|
return super.parseClassProperty(node);
|
|
}
|
|
parseClassPrivateProperty(node) {
|
|
if (this.match(14)) {
|
|
node.typeAnnotation = this.flowParseTypeAnnotation();
|
|
}
|
|
return super.parseClassPrivateProperty(node);
|
|
}
|
|
isClassMethod() {
|
|
return this.match(47) || super.isClassMethod();
|
|
}
|
|
isClassProperty() {
|
|
return this.match(14) || super.isClassProperty();
|
|
}
|
|
isNonstaticConstructor(method) {
|
|
return !this.match(14) && super.isNonstaticConstructor(method);
|
|
}
|
|
pushClassMethod(classBody, method, isGenerator, isAsync, isConstructor, allowsDirectSuper) {
|
|
if (method.variance) {
|
|
this.unexpected(method.variance.loc.start);
|
|
}
|
|
delete method.variance;
|
|
if (this.match(47)) {
|
|
method.typeParameters = this.flowParseTypeParameterDeclaration();
|
|
}
|
|
super.pushClassMethod(classBody, method, isGenerator, isAsync, isConstructor, allowsDirectSuper);
|
|
if (method.params && isConstructor) {
|
|
const params = method.params;
|
|
if (params.length > 0 && this.isThisParam(params[0])) {
|
|
this.raise(FlowErrors.ThisParamBannedInConstructor, method);
|
|
}
|
|
} else if (method.type === "MethodDefinition" && isConstructor && method.value.params) {
|
|
const params = method.value.params;
|
|
if (params.length > 0 && this.isThisParam(params[0])) {
|
|
this.raise(FlowErrors.ThisParamBannedInConstructor, method);
|
|
}
|
|
}
|
|
}
|
|
pushClassPrivateMethod(classBody, method, isGenerator, isAsync) {
|
|
if (method.variance) {
|
|
this.unexpected(method.variance.loc.start);
|
|
}
|
|
delete method.variance;
|
|
if (this.match(47)) {
|
|
method.typeParameters = this.flowParseTypeParameterDeclaration();
|
|
}
|
|
super.pushClassPrivateMethod(classBody, method, isGenerator, isAsync);
|
|
}
|
|
parseClassSuper(node) {
|
|
super.parseClassSuper(node);
|
|
if (node.superClass && (this.match(47) || this.match(51))) {
|
|
{
|
|
node.superTypeParameters = this.flowParseTypeParameterInstantiationInExpression();
|
|
}
|
|
}
|
|
if (this.isContextual(113)) {
|
|
this.next();
|
|
const implemented = node.implements = [];
|
|
do {
|
|
const node = this.startNode();
|
|
node.id = this.flowParseRestrictedIdentifier(true);
|
|
if (this.match(47)) {
|
|
node.typeParameters = this.flowParseTypeParameterInstantiation();
|
|
} else {
|
|
node.typeParameters = null;
|
|
}
|
|
implemented.push(this.finishNode(node, "ClassImplements"));
|
|
} while (this.eat(12));
|
|
}
|
|
}
|
|
checkGetterSetterParams(method) {
|
|
super.checkGetterSetterParams(method);
|
|
const params = this.getObjectOrClassMethodParams(method);
|
|
if (params.length > 0) {
|
|
const param = params[0];
|
|
if (this.isThisParam(param) && method.kind === "get") {
|
|
this.raise(FlowErrors.GetterMayNotHaveThisParam, param);
|
|
} else if (this.isThisParam(param)) {
|
|
this.raise(FlowErrors.SetterMayNotHaveThisParam, param);
|
|
}
|
|
}
|
|
}
|
|
parsePropertyNamePrefixOperator(node) {
|
|
node.variance = this.flowParseVariance();
|
|
}
|
|
parseObjPropValue(prop, startLoc, isGenerator, isAsync, isPattern, isAccessor, refExpressionErrors) {
|
|
if (prop.variance) {
|
|
this.unexpected(prop.variance.loc.start);
|
|
}
|
|
delete prop.variance;
|
|
let typeParameters;
|
|
if (this.match(47) && !isAccessor) {
|
|
typeParameters = this.flowParseTypeParameterDeclaration();
|
|
if (!this.match(10)) this.unexpected();
|
|
}
|
|
const result = super.parseObjPropValue(prop, startLoc, isGenerator, isAsync, isPattern, isAccessor, refExpressionErrors);
|
|
if (typeParameters) {
|
|
(result.value || result).typeParameters = typeParameters;
|
|
}
|
|
return result;
|
|
}
|
|
parseFunctionParamType(param) {
|
|
if (this.eat(17)) {
|
|
if (param.type !== "Identifier") {
|
|
this.raise(FlowErrors.PatternIsOptional, param);
|
|
}
|
|
if (this.isThisParam(param)) {
|
|
this.raise(FlowErrors.ThisParamMayNotBeOptional, param);
|
|
}
|
|
param.optional = true;
|
|
}
|
|
if (this.match(14)) {
|
|
param.typeAnnotation = this.flowParseTypeAnnotation();
|
|
} else if (this.isThisParam(param)) {
|
|
this.raise(FlowErrors.ThisParamAnnotationRequired, param);
|
|
}
|
|
if (this.match(29) && this.isThisParam(param)) {
|
|
this.raise(FlowErrors.ThisParamNoDefault, param);
|
|
}
|
|
this.resetEndLocation(param);
|
|
return param;
|
|
}
|
|
parseMaybeDefault(startLoc, left) {
|
|
const node = super.parseMaybeDefault(startLoc, left);
|
|
if (node.type === "AssignmentPattern" && node.typeAnnotation && node.right.start < node.typeAnnotation.start) {
|
|
this.raise(FlowErrors.TypeBeforeInitializer, node.typeAnnotation);
|
|
}
|
|
return node;
|
|
}
|
|
checkImportReflection(node) {
|
|
super.checkImportReflection(node);
|
|
if (node.module && node.importKind !== "value") {
|
|
this.raise(FlowErrors.ImportReflectionHasImportType, node.specifiers[0].loc.start);
|
|
}
|
|
}
|
|
parseImportSpecifierLocal(node, specifier, type) {
|
|
specifier.local = hasTypeImportKind(node) ? this.flowParseRestrictedIdentifier(true, true) : this.parseIdentifier();
|
|
node.specifiers.push(this.finishImportSpecifier(specifier, type));
|
|
}
|
|
isPotentialImportPhase(isExport) {
|
|
if (super.isPotentialImportPhase(isExport)) return true;
|
|
if (this.isContextual(130)) {
|
|
if (!isExport) return true;
|
|
const ch = this.lookaheadCharCode();
|
|
return ch === 123 || ch === 42;
|
|
}
|
|
return !isExport && this.isContextual(87);
|
|
}
|
|
applyImportPhase(node, isExport, phase, loc) {
|
|
super.applyImportPhase(node, isExport, phase, loc);
|
|
if (isExport) {
|
|
if (!phase && this.match(65)) {
|
|
return;
|
|
}
|
|
node.exportKind = phase === "type" ? phase : "value";
|
|
} else {
|
|
if (phase === "type" && this.match(55)) this.unexpected();
|
|
node.importKind = phase === "type" || phase === "typeof" ? phase : "value";
|
|
}
|
|
}
|
|
parseImportSpecifier(specifier, importedIsString, isInTypeOnlyImport, isMaybeTypeOnly, bindingType) {
|
|
const firstIdent = specifier.imported;
|
|
let specifierTypeKind = null;
|
|
if (firstIdent.type === "Identifier") {
|
|
if (firstIdent.name === "type") {
|
|
specifierTypeKind = "type";
|
|
} else if (firstIdent.name === "typeof") {
|
|
specifierTypeKind = "typeof";
|
|
}
|
|
}
|
|
let isBinding = false;
|
|
if (this.isContextual(93) && !this.isLookaheadContextual("as")) {
|
|
const as_ident = this.parseIdentifier(true);
|
|
if (specifierTypeKind !== null && !tokenIsKeywordOrIdentifier(this.state.type)) {
|
|
specifier.imported = as_ident;
|
|
specifier.importKind = specifierTypeKind;
|
|
specifier.local = this.cloneIdentifier(as_ident);
|
|
} else {
|
|
specifier.imported = firstIdent;
|
|
specifier.importKind = null;
|
|
specifier.local = this.parseIdentifier();
|
|
}
|
|
} else {
|
|
if (specifierTypeKind !== null && tokenIsKeywordOrIdentifier(this.state.type)) {
|
|
specifier.imported = this.parseIdentifier(true);
|
|
specifier.importKind = specifierTypeKind;
|
|
} else {
|
|
if (importedIsString) {
|
|
throw this.raise(Errors.ImportBindingIsString, specifier, {
|
|
importName: firstIdent.value
|
|
});
|
|
}
|
|
specifier.imported = firstIdent;
|
|
specifier.importKind = null;
|
|
}
|
|
if (this.eatContextual(93)) {
|
|
specifier.local = this.parseIdentifier();
|
|
} else {
|
|
isBinding = true;
|
|
specifier.local = this.cloneIdentifier(specifier.imported);
|
|
}
|
|
}
|
|
const specifierIsTypeImport = hasTypeImportKind(specifier);
|
|
if (isInTypeOnlyImport && specifierIsTypeImport) {
|
|
this.raise(FlowErrors.ImportTypeShorthandOnlyInPureImport, specifier);
|
|
}
|
|
if (isInTypeOnlyImport || specifierIsTypeImport) {
|
|
this.checkReservedType(specifier.local.name, specifier.local.loc.start, true);
|
|
}
|
|
if (isBinding && !isInTypeOnlyImport && !specifierIsTypeImport) {
|
|
this.checkReservedWord(specifier.local.name, specifier.loc.start, true, true);
|
|
}
|
|
return this.finishImportSpecifier(specifier, "ImportSpecifier");
|
|
}
|
|
parseBindingAtom() {
|
|
switch (this.state.type) {
|
|
case 78:
|
|
return this.parseIdentifier(true);
|
|
default:
|
|
return super.parseBindingAtom();
|
|
}
|
|
}
|
|
parseFunctionParams(node, isConstructor) {
|
|
const kind = node.kind;
|
|
if (kind !== "get" && kind !== "set" && this.match(47)) {
|
|
node.typeParameters = this.flowParseTypeParameterDeclaration();
|
|
}
|
|
super.parseFunctionParams(node, isConstructor);
|
|
}
|
|
parseVarId(decl, kind) {
|
|
super.parseVarId(decl, kind);
|
|
if (this.match(14)) {
|
|
decl.id.typeAnnotation = this.flowParseTypeAnnotation();
|
|
this.resetEndLocation(decl.id);
|
|
}
|
|
}
|
|
parseAsyncArrowFromCallExpression(node, call) {
|
|
if (this.match(14)) {
|
|
const oldNoAnonFunctionType = this.state.noAnonFunctionType;
|
|
this.state.noAnonFunctionType = true;
|
|
node.returnType = this.flowParseTypeAnnotation();
|
|
this.state.noAnonFunctionType = oldNoAnonFunctionType;
|
|
}
|
|
return super.parseAsyncArrowFromCallExpression(node, call);
|
|
}
|
|
shouldParseAsyncArrow() {
|
|
return this.match(14) || super.shouldParseAsyncArrow();
|
|
}
|
|
parseMaybeAssign(refExpressionErrors, afterLeftParse) {
|
|
var _jsx;
|
|
let state = null;
|
|
let jsx;
|
|
if (this.hasPlugin("jsx") && (this.match(143) || this.match(47))) {
|
|
state = this.state.clone();
|
|
jsx = this.tryParse(() => super.parseMaybeAssign(refExpressionErrors, afterLeftParse), state);
|
|
if (!jsx.error) return jsx.node;
|
|
const {
|
|
context
|
|
} = this.state;
|
|
const currentContext = context[context.length - 1];
|
|
if (currentContext === types.j_oTag || currentContext === types.j_expr) {
|
|
context.pop();
|
|
}
|
|
}
|
|
if ((_jsx = jsx) != null && _jsx.error || this.match(47)) {
|
|
var _jsx2, _jsx3;
|
|
state = state || this.state.clone();
|
|
let typeParameters;
|
|
const arrow = this.tryParse(abort => {
|
|
var _arrowExpression$extr;
|
|
typeParameters = this.flowParseTypeParameterDeclaration();
|
|
const arrowExpression = this.forwardNoArrowParamsConversionAt(typeParameters, () => {
|
|
const result = super.parseMaybeAssign(refExpressionErrors, afterLeftParse);
|
|
this.resetStartLocationFromNode(result, typeParameters);
|
|
return result;
|
|
});
|
|
if ((_arrowExpression$extr = arrowExpression.extra) != null && _arrowExpression$extr.parenthesized) abort();
|
|
const expr = this.maybeUnwrapTypeCastExpression(arrowExpression);
|
|
if (expr.type !== "ArrowFunctionExpression") abort();
|
|
expr.typeParameters = typeParameters;
|
|
this.resetStartLocationFromNode(expr, typeParameters);
|
|
return arrowExpression;
|
|
}, state);
|
|
let arrowExpression = null;
|
|
if (arrow.node && this.maybeUnwrapTypeCastExpression(arrow.node).type === "ArrowFunctionExpression") {
|
|
if (!arrow.error && !arrow.aborted) {
|
|
if (arrow.node.async) {
|
|
this.raise(FlowErrors.UnexpectedTypeParameterBeforeAsyncArrowFunction, typeParameters);
|
|
}
|
|
return arrow.node;
|
|
}
|
|
arrowExpression = arrow.node;
|
|
}
|
|
if ((_jsx2 = jsx) != null && _jsx2.node) {
|
|
this.state = jsx.failState;
|
|
return jsx.node;
|
|
}
|
|
if (arrowExpression) {
|
|
this.state = arrow.failState;
|
|
return arrowExpression;
|
|
}
|
|
if ((_jsx3 = jsx) != null && _jsx3.thrown) throw jsx.error;
|
|
if (arrow.thrown) throw arrow.error;
|
|
throw this.raise(FlowErrors.UnexpectedTokenAfterTypeParameter, typeParameters);
|
|
}
|
|
return super.parseMaybeAssign(refExpressionErrors, afterLeftParse);
|
|
}
|
|
parseArrow(node) {
|
|
if (this.match(14)) {
|
|
const result = this.tryParse(() => {
|
|
const oldNoAnonFunctionType = this.state.noAnonFunctionType;
|
|
this.state.noAnonFunctionType = true;
|
|
const typeNode = this.startNode();
|
|
[typeNode.typeAnnotation, node.predicate] = this.flowParseTypeAndPredicateInitialiser();
|
|
this.state.noAnonFunctionType = oldNoAnonFunctionType;
|
|
if (this.canInsertSemicolon()) this.unexpected();
|
|
if (!this.match(19)) this.unexpected();
|
|
return typeNode;
|
|
});
|
|
if (result.thrown) return null;
|
|
if (result.error) this.state = result.failState;
|
|
node.returnType = result.node.typeAnnotation ? this.finishNode(result.node, "TypeAnnotation") : null;
|
|
}
|
|
return super.parseArrow(node);
|
|
}
|
|
shouldParseArrow(params) {
|
|
return this.match(14) || super.shouldParseArrow(params);
|
|
}
|
|
setArrowFunctionParameters(node, params) {
|
|
if (this.state.noArrowParamsConversionAt.includes(this.offsetToSourcePos(node.start))) {
|
|
node.params = params;
|
|
} else {
|
|
super.setArrowFunctionParameters(node, params);
|
|
}
|
|
}
|
|
checkParams(node, allowDuplicates, isArrowFunction, strictModeChanged = true) {
|
|
if (isArrowFunction && this.state.noArrowParamsConversionAt.includes(this.offsetToSourcePos(node.start))) {
|
|
return;
|
|
}
|
|
for (let i = 0; i < node.params.length; i++) {
|
|
if (this.isThisParam(node.params[i]) && i > 0) {
|
|
this.raise(FlowErrors.ThisParamMustBeFirst, node.params[i]);
|
|
}
|
|
}
|
|
super.checkParams(node, allowDuplicates, isArrowFunction, strictModeChanged);
|
|
}
|
|
parseParenAndDistinguishExpression(canBeArrow) {
|
|
return super.parseParenAndDistinguishExpression(canBeArrow && !this.state.noArrowAt.includes(this.sourceToOffsetPos(this.state.start)));
|
|
}
|
|
parseSubscripts(base, startLoc, noCalls) {
|
|
if (base.type === "Identifier" && base.name === "async" && this.state.noArrowAt.includes(startLoc.index)) {
|
|
this.next();
|
|
const node = this.startNodeAt(startLoc);
|
|
node.callee = base;
|
|
node.arguments = super.parseCallExpressionArguments();
|
|
base = this.finishNode(node, "CallExpression");
|
|
} else if (base.type === "Identifier" && base.name === "async" && this.match(47)) {
|
|
const state = this.state.clone();
|
|
const arrow = this.tryParse(abort => this.parseAsyncArrowWithTypeParameters(startLoc) || abort(), state);
|
|
if (!arrow.error && !arrow.aborted) return arrow.node;
|
|
const result = this.tryParse(() => super.parseSubscripts(base, startLoc, noCalls), state);
|
|
if (result.node && !result.error) return result.node;
|
|
if (arrow.node) {
|
|
this.state = arrow.failState;
|
|
return arrow.node;
|
|
}
|
|
if (result.node) {
|
|
this.state = result.failState;
|
|
return result.node;
|
|
}
|
|
throw arrow.error || result.error;
|
|
}
|
|
return super.parseSubscripts(base, startLoc, noCalls);
|
|
}
|
|
parseSubscript(base, startLoc, noCalls, subscriptState) {
|
|
if (this.match(18) && this.isLookaheadToken_lt()) {
|
|
subscriptState.optionalChainMember = true;
|
|
if (noCalls) {
|
|
subscriptState.stop = true;
|
|
return base;
|
|
}
|
|
this.next();
|
|
const node = this.startNodeAt(startLoc);
|
|
node.callee = base;
|
|
node.typeArguments = this.flowParseTypeParameterInstantiationInExpression();
|
|
this.expect(10);
|
|
node.arguments = this.parseCallExpressionArguments();
|
|
node.optional = true;
|
|
return this.finishCallExpression(node, true);
|
|
} else if (!noCalls && this.shouldParseTypes() && (this.match(47) || this.match(51))) {
|
|
const node = this.startNodeAt(startLoc);
|
|
node.callee = base;
|
|
const result = this.tryParse(() => {
|
|
node.typeArguments = this.flowParseTypeParameterInstantiationCallOrNew();
|
|
this.expect(10);
|
|
node.arguments = super.parseCallExpressionArguments();
|
|
if (subscriptState.optionalChainMember) {
|
|
node.optional = false;
|
|
}
|
|
return this.finishCallExpression(node, subscriptState.optionalChainMember);
|
|
});
|
|
if (result.node) {
|
|
if (result.error) this.state = result.failState;
|
|
return result.node;
|
|
}
|
|
}
|
|
return super.parseSubscript(base, startLoc, noCalls, subscriptState);
|
|
}
|
|
parseNewCallee(node) {
|
|
super.parseNewCallee(node);
|
|
let targs = null;
|
|
if (this.shouldParseTypes() && this.match(47)) {
|
|
targs = this.tryParse(() => this.flowParseTypeParameterInstantiationCallOrNew()).node;
|
|
}
|
|
node.typeArguments = targs;
|
|
}
|
|
parseAsyncArrowWithTypeParameters(startLoc) {
|
|
const node = this.startNodeAt(startLoc);
|
|
this.parseFunctionParams(node, false);
|
|
if (!this.parseArrow(node)) return;
|
|
return super.parseArrowExpression(node, undefined, true);
|
|
}
|
|
readToken_mult_modulo(code) {
|
|
const next = this.input.charCodeAt(this.state.pos + 1);
|
|
if (code === 42 && next === 47 && this.state.hasFlowComment) {
|
|
this.state.hasFlowComment = false;
|
|
this.state.pos += 2;
|
|
this.nextToken();
|
|
return;
|
|
}
|
|
super.readToken_mult_modulo(code);
|
|
}
|
|
readToken_pipe_amp(code) {
|
|
const next = this.input.charCodeAt(this.state.pos + 1);
|
|
if (code === 124 && next === 125) {
|
|
this.finishOp(9, 2);
|
|
return;
|
|
}
|
|
super.readToken_pipe_amp(code);
|
|
}
|
|
parseTopLevel(file, program) {
|
|
const fileNode = super.parseTopLevel(file, program);
|
|
if (this.state.hasFlowComment) {
|
|
this.raise(FlowErrors.UnterminatedFlowComment, this.state.curPosition());
|
|
}
|
|
return fileNode;
|
|
}
|
|
skipBlockComment() {
|
|
if (this.hasPlugin("flowComments") && this.skipFlowComment()) {
|
|
if (this.state.hasFlowComment) {
|
|
throw this.raise(FlowErrors.NestedFlowComment, this.state.startLoc);
|
|
}
|
|
this.hasFlowCommentCompletion();
|
|
const commentSkip = this.skipFlowComment();
|
|
if (commentSkip) {
|
|
this.state.pos += commentSkip;
|
|
this.state.hasFlowComment = true;
|
|
}
|
|
return;
|
|
}
|
|
return super.skipBlockComment(this.state.hasFlowComment ? "*-/" : "*/");
|
|
}
|
|
skipFlowComment() {
|
|
const {
|
|
pos
|
|
} = this.state;
|
|
let shiftToFirstNonWhiteSpace = 2;
|
|
while ([32, 9].includes(this.input.charCodeAt(pos + shiftToFirstNonWhiteSpace))) {
|
|
shiftToFirstNonWhiteSpace++;
|
|
}
|
|
const ch2 = this.input.charCodeAt(shiftToFirstNonWhiteSpace + pos);
|
|
const ch3 = this.input.charCodeAt(shiftToFirstNonWhiteSpace + pos + 1);
|
|
if (ch2 === 58 && ch3 === 58) {
|
|
return shiftToFirstNonWhiteSpace + 2;
|
|
}
|
|
if (this.input.slice(shiftToFirstNonWhiteSpace + pos, shiftToFirstNonWhiteSpace + pos + 12) === "flow-include") {
|
|
return shiftToFirstNonWhiteSpace + 12;
|
|
}
|
|
if (ch2 === 58 && ch3 !== 58) {
|
|
return shiftToFirstNonWhiteSpace;
|
|
}
|
|
return false;
|
|
}
|
|
hasFlowCommentCompletion() {
|
|
const end = this.input.indexOf("*/", this.state.pos);
|
|
if (end === -1) {
|
|
throw this.raise(Errors.UnterminatedComment, this.state.curPosition());
|
|
}
|
|
}
|
|
flowEnumErrorBooleanMemberNotInitialized(loc, {
|
|
enumName,
|
|
memberName
|
|
}) {
|
|
this.raise(FlowErrors.EnumBooleanMemberNotInitialized, loc, {
|
|
memberName,
|
|
enumName
|
|
});
|
|
}
|
|
flowEnumErrorInvalidMemberInitializer(loc, enumContext) {
|
|
return this.raise(!enumContext.explicitType ? FlowErrors.EnumInvalidMemberInitializerUnknownType : enumContext.explicitType === "symbol" ? FlowErrors.EnumInvalidMemberInitializerSymbolType : FlowErrors.EnumInvalidMemberInitializerPrimaryType, loc, enumContext);
|
|
}
|
|
flowEnumErrorNumberMemberNotInitialized(loc, details) {
|
|
this.raise(FlowErrors.EnumNumberMemberNotInitialized, loc, details);
|
|
}
|
|
flowEnumErrorStringMemberInconsistentlyInitialized(node, details) {
|
|
this.raise(FlowErrors.EnumStringMemberInconsistentlyInitialized, node, details);
|
|
}
|
|
flowEnumMemberInit() {
|
|
const startLoc = this.state.startLoc;
|
|
const endOfInit = () => this.match(12) || this.match(8);
|
|
switch (this.state.type) {
|
|
case 135:
|
|
{
|
|
const literal = this.parseNumericLiteral(this.state.value);
|
|
if (endOfInit()) {
|
|
return {
|
|
type: "number",
|
|
loc: literal.loc.start,
|
|
value: literal
|
|
};
|
|
}
|
|
return {
|
|
type: "invalid",
|
|
loc: startLoc
|
|
};
|
|
}
|
|
case 134:
|
|
{
|
|
const literal = this.parseStringLiteral(this.state.value);
|
|
if (endOfInit()) {
|
|
return {
|
|
type: "string",
|
|
loc: literal.loc.start,
|
|
value: literal
|
|
};
|
|
}
|
|
return {
|
|
type: "invalid",
|
|
loc: startLoc
|
|
};
|
|
}
|
|
case 85:
|
|
case 86:
|
|
{
|
|
const literal = this.parseBooleanLiteral(this.match(85));
|
|
if (endOfInit()) {
|
|
return {
|
|
type: "boolean",
|
|
loc: literal.loc.start,
|
|
value: literal
|
|
};
|
|
}
|
|
return {
|
|
type: "invalid",
|
|
loc: startLoc
|
|
};
|
|
}
|
|
default:
|
|
return {
|
|
type: "invalid",
|
|
loc: startLoc
|
|
};
|
|
}
|
|
}
|
|
flowEnumMemberRaw() {
|
|
const loc = this.state.startLoc;
|
|
const id = this.parseIdentifier(true);
|
|
const init = this.eat(29) ? this.flowEnumMemberInit() : {
|
|
type: "none",
|
|
loc
|
|
};
|
|
return {
|
|
id,
|
|
init
|
|
};
|
|
}
|
|
flowEnumCheckExplicitTypeMismatch(loc, context, expectedType) {
|
|
const {
|
|
explicitType
|
|
} = context;
|
|
if (explicitType === null) {
|
|
return;
|
|
}
|
|
if (explicitType !== expectedType) {
|
|
this.flowEnumErrorInvalidMemberInitializer(loc, context);
|
|
}
|
|
}
|
|
flowEnumMembers({
|
|
enumName,
|
|
explicitType
|
|
}) {
|
|
const seenNames = new Set();
|
|
const members = {
|
|
booleanMembers: [],
|
|
numberMembers: [],
|
|
stringMembers: [],
|
|
defaultedMembers: []
|
|
};
|
|
let hasUnknownMembers = false;
|
|
while (!this.match(8)) {
|
|
if (this.eat(21)) {
|
|
hasUnknownMembers = true;
|
|
break;
|
|
}
|
|
const memberNode = this.startNode();
|
|
const {
|
|
id,
|
|
init
|
|
} = this.flowEnumMemberRaw();
|
|
const memberName = id.name;
|
|
if (memberName === "") {
|
|
continue;
|
|
}
|
|
if (/^[a-z]/.test(memberName)) {
|
|
this.raise(FlowErrors.EnumInvalidMemberName, id, {
|
|
memberName,
|
|
suggestion: memberName[0].toUpperCase() + memberName.slice(1),
|
|
enumName
|
|
});
|
|
}
|
|
if (seenNames.has(memberName)) {
|
|
this.raise(FlowErrors.EnumDuplicateMemberName, id, {
|
|
memberName,
|
|
enumName
|
|
});
|
|
}
|
|
seenNames.add(memberName);
|
|
const context = {
|
|
enumName,
|
|
explicitType,
|
|
memberName
|
|
};
|
|
memberNode.id = id;
|
|
switch (init.type) {
|
|
case "boolean":
|
|
{
|
|
this.flowEnumCheckExplicitTypeMismatch(init.loc, context, "boolean");
|
|
memberNode.init = init.value;
|
|
members.booleanMembers.push(this.finishNode(memberNode, "EnumBooleanMember"));
|
|
break;
|
|
}
|
|
case "number":
|
|
{
|
|
this.flowEnumCheckExplicitTypeMismatch(init.loc, context, "number");
|
|
memberNode.init = init.value;
|
|
members.numberMembers.push(this.finishNode(memberNode, "EnumNumberMember"));
|
|
break;
|
|
}
|
|
case "string":
|
|
{
|
|
this.flowEnumCheckExplicitTypeMismatch(init.loc, context, "string");
|
|
memberNode.init = init.value;
|
|
members.stringMembers.push(this.finishNode(memberNode, "EnumStringMember"));
|
|
break;
|
|
}
|
|
case "invalid":
|
|
{
|
|
throw this.flowEnumErrorInvalidMemberInitializer(init.loc, context);
|
|
}
|
|
case "none":
|
|
{
|
|
switch (explicitType) {
|
|
case "boolean":
|
|
this.flowEnumErrorBooleanMemberNotInitialized(init.loc, context);
|
|
break;
|
|
case "number":
|
|
this.flowEnumErrorNumberMemberNotInitialized(init.loc, context);
|
|
break;
|
|
default:
|
|
members.defaultedMembers.push(this.finishNode(memberNode, "EnumDefaultedMember"));
|
|
}
|
|
}
|
|
}
|
|
if (!this.match(8)) {
|
|
this.expect(12);
|
|
}
|
|
}
|
|
return {
|
|
members,
|
|
hasUnknownMembers
|
|
};
|
|
}
|
|
flowEnumStringMembers(initializedMembers, defaultedMembers, {
|
|
enumName
|
|
}) {
|
|
if (initializedMembers.length === 0) {
|
|
return defaultedMembers;
|
|
} else if (defaultedMembers.length === 0) {
|
|
return initializedMembers;
|
|
} else if (defaultedMembers.length > initializedMembers.length) {
|
|
for (const member of initializedMembers) {
|
|
this.flowEnumErrorStringMemberInconsistentlyInitialized(member, {
|
|
enumName
|
|
});
|
|
}
|
|
return defaultedMembers;
|
|
} else {
|
|
for (const member of defaultedMembers) {
|
|
this.flowEnumErrorStringMemberInconsistentlyInitialized(member, {
|
|
enumName
|
|
});
|
|
}
|
|
return initializedMembers;
|
|
}
|
|
}
|
|
flowEnumParseExplicitType({
|
|
enumName
|
|
}) {
|
|
if (!this.eatContextual(102)) return null;
|
|
if (!tokenIsIdentifier(this.state.type)) {
|
|
throw this.raise(FlowErrors.EnumInvalidExplicitTypeUnknownSupplied, this.state.startLoc, {
|
|
enumName
|
|
});
|
|
}
|
|
const {
|
|
value
|
|
} = this.state;
|
|
this.next();
|
|
if (value !== "boolean" && value !== "number" && value !== "string" && value !== "symbol") {
|
|
this.raise(FlowErrors.EnumInvalidExplicitType, this.state.startLoc, {
|
|
enumName,
|
|
invalidEnumType: value
|
|
});
|
|
}
|
|
return value;
|
|
}
|
|
flowEnumBody(node, id) {
|
|
const enumName = id.name;
|
|
const nameLoc = id.loc.start;
|
|
const explicitType = this.flowEnumParseExplicitType({
|
|
enumName
|
|
});
|
|
this.expect(5);
|
|
const {
|
|
members,
|
|
hasUnknownMembers
|
|
} = this.flowEnumMembers({
|
|
enumName,
|
|
explicitType
|
|
});
|
|
node.hasUnknownMembers = hasUnknownMembers;
|
|
switch (explicitType) {
|
|
case "boolean":
|
|
node.explicitType = true;
|
|
node.members = members.booleanMembers;
|
|
this.expect(8);
|
|
return this.finishNode(node, "EnumBooleanBody");
|
|
case "number":
|
|
node.explicitType = true;
|
|
node.members = members.numberMembers;
|
|
this.expect(8);
|
|
return this.finishNode(node, "EnumNumberBody");
|
|
case "string":
|
|
node.explicitType = true;
|
|
node.members = this.flowEnumStringMembers(members.stringMembers, members.defaultedMembers, {
|
|
enumName
|
|
});
|
|
this.expect(8);
|
|
return this.finishNode(node, "EnumStringBody");
|
|
case "symbol":
|
|
node.members = members.defaultedMembers;
|
|
this.expect(8);
|
|
return this.finishNode(node, "EnumSymbolBody");
|
|
default:
|
|
{
|
|
const empty = () => {
|
|
node.members = [];
|
|
this.expect(8);
|
|
return this.finishNode(node, "EnumStringBody");
|
|
};
|
|
node.explicitType = false;
|
|
const boolsLen = members.booleanMembers.length;
|
|
const numsLen = members.numberMembers.length;
|
|
const strsLen = members.stringMembers.length;
|
|
const defaultedLen = members.defaultedMembers.length;
|
|
if (!boolsLen && !numsLen && !strsLen && !defaultedLen) {
|
|
return empty();
|
|
} else if (!boolsLen && !numsLen) {
|
|
node.members = this.flowEnumStringMembers(members.stringMembers, members.defaultedMembers, {
|
|
enumName
|
|
});
|
|
this.expect(8);
|
|
return this.finishNode(node, "EnumStringBody");
|
|
} else if (!numsLen && !strsLen && boolsLen >= defaultedLen) {
|
|
for (const member of members.defaultedMembers) {
|
|
this.flowEnumErrorBooleanMemberNotInitialized(member.loc.start, {
|
|
enumName,
|
|
memberName: member.id.name
|
|
});
|
|
}
|
|
node.members = members.booleanMembers;
|
|
this.expect(8);
|
|
return this.finishNode(node, "EnumBooleanBody");
|
|
} else if (!boolsLen && !strsLen && numsLen >= defaultedLen) {
|
|
for (const member of members.defaultedMembers) {
|
|
this.flowEnumErrorNumberMemberNotInitialized(member.loc.start, {
|
|
enumName,
|
|
memberName: member.id.name
|
|
});
|
|
}
|
|
node.members = members.numberMembers;
|
|
this.expect(8);
|
|
return this.finishNode(node, "EnumNumberBody");
|
|
} else {
|
|
this.raise(FlowErrors.EnumInconsistentMemberValues, nameLoc, {
|
|
enumName
|
|
});
|
|
return empty();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
flowParseEnumDeclaration(node) {
|
|
const id = this.parseIdentifier();
|
|
node.id = id;
|
|
node.body = this.flowEnumBody(this.startNode(), id);
|
|
return this.finishNode(node, "EnumDeclaration");
|
|
}
|
|
jsxParseOpeningElementAfterName(node) {
|
|
if (this.shouldParseTypes()) {
|
|
if (this.match(47) || this.match(51)) {
|
|
node.typeArguments = this.flowParseTypeParameterInstantiationInExpression();
|
|
}
|
|
}
|
|
return super.jsxParseOpeningElementAfterName(node);
|
|
}
|
|
isLookaheadToken_lt() {
|
|
const next = this.nextTokenStart();
|
|
if (this.input.charCodeAt(next) === 60) {
|
|
const afterNext = this.input.charCodeAt(next + 1);
|
|
return afterNext !== 60 && afterNext !== 61;
|
|
}
|
|
return false;
|
|
}
|
|
reScan_lt_gt() {
|
|
const {
|
|
type
|
|
} = this.state;
|
|
if (type === 47) {
|
|
this.state.pos -= 1;
|
|
this.readToken_lt();
|
|
} else if (type === 48) {
|
|
this.state.pos -= 1;
|
|
this.readToken_gt();
|
|
}
|
|
}
|
|
reScan_lt() {
|
|
const {
|
|
type
|
|
} = this.state;
|
|
if (type === 51) {
|
|
this.state.pos -= 2;
|
|
this.finishOp(47, 1);
|
|
return 47;
|
|
}
|
|
return type;
|
|
}
|
|
maybeUnwrapTypeCastExpression(node) {
|
|
return node.type === "TypeCastExpression" ? node.expression : node;
|
|
}
|
|
};
|
|
const entities = {
|
|
__proto__: null,
|
|
quot: "\u0022",
|
|
amp: "&",
|
|
apos: "\u0027",
|
|
lt: "<",
|
|
gt: ">",
|
|
nbsp: "\u00A0",
|
|
iexcl: "\u00A1",
|
|
cent: "\u00A2",
|
|
pound: "\u00A3",
|
|
curren: "\u00A4",
|
|
yen: "\u00A5",
|
|
brvbar: "\u00A6",
|
|
sect: "\u00A7",
|
|
uml: "\u00A8",
|
|
copy: "\u00A9",
|
|
ordf: "\u00AA",
|
|
laquo: "\u00AB",
|
|
not: "\u00AC",
|
|
shy: "\u00AD",
|
|
reg: "\u00AE",
|
|
macr: "\u00AF",
|
|
deg: "\u00B0",
|
|
plusmn: "\u00B1",
|
|
sup2: "\u00B2",
|
|
sup3: "\u00B3",
|
|
acute: "\u00B4",
|
|
micro: "\u00B5",
|
|
para: "\u00B6",
|
|
middot: "\u00B7",
|
|
cedil: "\u00B8",
|
|
sup1: "\u00B9",
|
|
ordm: "\u00BA",
|
|
raquo: "\u00BB",
|
|
frac14: "\u00BC",
|
|
frac12: "\u00BD",
|
|
frac34: "\u00BE",
|
|
iquest: "\u00BF",
|
|
Agrave: "\u00C0",
|
|
Aacute: "\u00C1",
|
|
Acirc: "\u00C2",
|
|
Atilde: "\u00C3",
|
|
Auml: "\u00C4",
|
|
Aring: "\u00C5",
|
|
AElig: "\u00C6",
|
|
Ccedil: "\u00C7",
|
|
Egrave: "\u00C8",
|
|
Eacute: "\u00C9",
|
|
Ecirc: "\u00CA",
|
|
Euml: "\u00CB",
|
|
Igrave: "\u00CC",
|
|
Iacute: "\u00CD",
|
|
Icirc: "\u00CE",
|
|
Iuml: "\u00CF",
|
|
ETH: "\u00D0",
|
|
Ntilde: "\u00D1",
|
|
Ograve: "\u00D2",
|
|
Oacute: "\u00D3",
|
|
Ocirc: "\u00D4",
|
|
Otilde: "\u00D5",
|
|
Ouml: "\u00D6",
|
|
times: "\u00D7",
|
|
Oslash: "\u00D8",
|
|
Ugrave: "\u00D9",
|
|
Uacute: "\u00DA",
|
|
Ucirc: "\u00DB",
|
|
Uuml: "\u00DC",
|
|
Yacute: "\u00DD",
|
|
THORN: "\u00DE",
|
|
szlig: "\u00DF",
|
|
agrave: "\u00E0",
|
|
aacute: "\u00E1",
|
|
acirc: "\u00E2",
|
|
atilde: "\u00E3",
|
|
auml: "\u00E4",
|
|
aring: "\u00E5",
|
|
aelig: "\u00E6",
|
|
ccedil: "\u00E7",
|
|
egrave: "\u00E8",
|
|
eacute: "\u00E9",
|
|
ecirc: "\u00EA",
|
|
euml: "\u00EB",
|
|
igrave: "\u00EC",
|
|
iacute: "\u00ED",
|
|
icirc: "\u00EE",
|
|
iuml: "\u00EF",
|
|
eth: "\u00F0",
|
|
ntilde: "\u00F1",
|
|
ograve: "\u00F2",
|
|
oacute: "\u00F3",
|
|
ocirc: "\u00F4",
|
|
otilde: "\u00F5",
|
|
ouml: "\u00F6",
|
|
divide: "\u00F7",
|
|
oslash: "\u00F8",
|
|
ugrave: "\u00F9",
|
|
uacute: "\u00FA",
|
|
ucirc: "\u00FB",
|
|
uuml: "\u00FC",
|
|
yacute: "\u00FD",
|
|
thorn: "\u00FE",
|
|
yuml: "\u00FF",
|
|
OElig: "\u0152",
|
|
oelig: "\u0153",
|
|
Scaron: "\u0160",
|
|
scaron: "\u0161",
|
|
Yuml: "\u0178",
|
|
fnof: "\u0192",
|
|
circ: "\u02C6",
|
|
tilde: "\u02DC",
|
|
Alpha: "\u0391",
|
|
Beta: "\u0392",
|
|
Gamma: "\u0393",
|
|
Delta: "\u0394",
|
|
Epsilon: "\u0395",
|
|
Zeta: "\u0396",
|
|
Eta: "\u0397",
|
|
Theta: "\u0398",
|
|
Iota: "\u0399",
|
|
Kappa: "\u039A",
|
|
Lambda: "\u039B",
|
|
Mu: "\u039C",
|
|
Nu: "\u039D",
|
|
Xi: "\u039E",
|
|
Omicron: "\u039F",
|
|
Pi: "\u03A0",
|
|
Rho: "\u03A1",
|
|
Sigma: "\u03A3",
|
|
Tau: "\u03A4",
|
|
Upsilon: "\u03A5",
|
|
Phi: "\u03A6",
|
|
Chi: "\u03A7",
|
|
Psi: "\u03A8",
|
|
Omega: "\u03A9",
|
|
alpha: "\u03B1",
|
|
beta: "\u03B2",
|
|
gamma: "\u03B3",
|
|
delta: "\u03B4",
|
|
epsilon: "\u03B5",
|
|
zeta: "\u03B6",
|
|
eta: "\u03B7",
|
|
theta: "\u03B8",
|
|
iota: "\u03B9",
|
|
kappa: "\u03BA",
|
|
lambda: "\u03BB",
|
|
mu: "\u03BC",
|
|
nu: "\u03BD",
|
|
xi: "\u03BE",
|
|
omicron: "\u03BF",
|
|
pi: "\u03C0",
|
|
rho: "\u03C1",
|
|
sigmaf: "\u03C2",
|
|
sigma: "\u03C3",
|
|
tau: "\u03C4",
|
|
upsilon: "\u03C5",
|
|
phi: "\u03C6",
|
|
chi: "\u03C7",
|
|
psi: "\u03C8",
|
|
omega: "\u03C9",
|
|
thetasym: "\u03D1",
|
|
upsih: "\u03D2",
|
|
piv: "\u03D6",
|
|
ensp: "\u2002",
|
|
emsp: "\u2003",
|
|
thinsp: "\u2009",
|
|
zwnj: "\u200C",
|
|
zwj: "\u200D",
|
|
lrm: "\u200E",
|
|
rlm: "\u200F",
|
|
ndash: "\u2013",
|
|
mdash: "\u2014",
|
|
lsquo: "\u2018",
|
|
rsquo: "\u2019",
|
|
sbquo: "\u201A",
|
|
ldquo: "\u201C",
|
|
rdquo: "\u201D",
|
|
bdquo: "\u201E",
|
|
dagger: "\u2020",
|
|
Dagger: "\u2021",
|
|
bull: "\u2022",
|
|
hellip: "\u2026",
|
|
permil: "\u2030",
|
|
prime: "\u2032",
|
|
Prime: "\u2033",
|
|
lsaquo: "\u2039",
|
|
rsaquo: "\u203A",
|
|
oline: "\u203E",
|
|
frasl: "\u2044",
|
|
euro: "\u20AC",
|
|
image: "\u2111",
|
|
weierp: "\u2118",
|
|
real: "\u211C",
|
|
trade: "\u2122",
|
|
alefsym: "\u2135",
|
|
larr: "\u2190",
|
|
uarr: "\u2191",
|
|
rarr: "\u2192",
|
|
darr: "\u2193",
|
|
harr: "\u2194",
|
|
crarr: "\u21B5",
|
|
lArr: "\u21D0",
|
|
uArr: "\u21D1",
|
|
rArr: "\u21D2",
|
|
dArr: "\u21D3",
|
|
hArr: "\u21D4",
|
|
forall: "\u2200",
|
|
part: "\u2202",
|
|
exist: "\u2203",
|
|
empty: "\u2205",
|
|
nabla: "\u2207",
|
|
isin: "\u2208",
|
|
notin: "\u2209",
|
|
ni: "\u220B",
|
|
prod: "\u220F",
|
|
sum: "\u2211",
|
|
minus: "\u2212",
|
|
lowast: "\u2217",
|
|
radic: "\u221A",
|
|
prop: "\u221D",
|
|
infin: "\u221E",
|
|
ang: "\u2220",
|
|
and: "\u2227",
|
|
or: "\u2228",
|
|
cap: "\u2229",
|
|
cup: "\u222A",
|
|
int: "\u222B",
|
|
there4: "\u2234",
|
|
sim: "\u223C",
|
|
cong: "\u2245",
|
|
asymp: "\u2248",
|
|
ne: "\u2260",
|
|
equiv: "\u2261",
|
|
le: "\u2264",
|
|
ge: "\u2265",
|
|
sub: "\u2282",
|
|
sup: "\u2283",
|
|
nsub: "\u2284",
|
|
sube: "\u2286",
|
|
supe: "\u2287",
|
|
oplus: "\u2295",
|
|
otimes: "\u2297",
|
|
perp: "\u22A5",
|
|
sdot: "\u22C5",
|
|
lceil: "\u2308",
|
|
rceil: "\u2309",
|
|
lfloor: "\u230A",
|
|
rfloor: "\u230B",
|
|
lang: "\u2329",
|
|
rang: "\u232A",
|
|
loz: "\u25CA",
|
|
spades: "\u2660",
|
|
clubs: "\u2663",
|
|
hearts: "\u2665",
|
|
diams: "\u2666"
|
|
};
|
|
const lineBreak = /\r\n|[\r\n\u2028\u2029]/;
|
|
const lineBreakG = new RegExp(lineBreak.source, "g");
|
|
function isNewLine(code) {
|
|
switch (code) {
|
|
case 10:
|
|
case 13:
|
|
case 8232:
|
|
case 8233:
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
function hasNewLine(input, start, end) {
|
|
for (let i = start; i < end; i++) {
|
|
if (isNewLine(input.charCodeAt(i))) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
const skipWhiteSpace = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g;
|
|
const skipWhiteSpaceInLine = /(?:[^\S\n\r\u2028\u2029]|\/\/.*|\/\*.*?\*\/)*/g;
|
|
function isWhitespace(code) {
|
|
switch (code) {
|
|
case 0x0009:
|
|
case 0x000b:
|
|
case 0x000c:
|
|
case 32:
|
|
case 160:
|
|
case 5760:
|
|
case 0x2000:
|
|
case 0x2001:
|
|
case 0x2002:
|
|
case 0x2003:
|
|
case 0x2004:
|
|
case 0x2005:
|
|
case 0x2006:
|
|
case 0x2007:
|
|
case 0x2008:
|
|
case 0x2009:
|
|
case 0x200a:
|
|
case 0x202f:
|
|
case 0x205f:
|
|
case 0x3000:
|
|
case 0xfeff:
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
const JsxErrors = ParseErrorEnum`jsx`({
|
|
AttributeIsEmpty: "JSX attributes must only be assigned a non-empty expression.",
|
|
MissingClosingTagElement: ({
|
|
openingTagName
|
|
}) => `Expected corresponding JSX closing tag for <${openingTagName}>.`,
|
|
MissingClosingTagFragment: "Expected corresponding JSX closing tag for <>.",
|
|
UnexpectedSequenceExpression: "Sequence expressions cannot be directly nested inside JSX. Did you mean to wrap it in parentheses (...)?",
|
|
UnexpectedToken: ({
|
|
unexpected,
|
|
HTMLEntity
|
|
}) => `Unexpected token \`${unexpected}\`. Did you mean \`${HTMLEntity}\` or \`{'${unexpected}'}\`?`,
|
|
UnsupportedJsxValue: "JSX value should be either an expression or a quoted JSX text.",
|
|
UnterminatedJsxContent: "Unterminated JSX contents.",
|
|
UnwrappedAdjacentJSXElements: "Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>...</>?"
|
|
});
|
|
function isFragment(object) {
|
|
return object ? object.type === "JSXOpeningFragment" || object.type === "JSXClosingFragment" : false;
|
|
}
|
|
function getQualifiedJSXName(object) {
|
|
if (object.type === "JSXIdentifier") {
|
|
return object.name;
|
|
}
|
|
if (object.type === "JSXNamespacedName") {
|
|
return object.namespace.name + ":" + object.name.name;
|
|
}
|
|
if (object.type === "JSXMemberExpression") {
|
|
return getQualifiedJSXName(object.object) + "." + getQualifiedJSXName(object.property);
|
|
}
|
|
throw new Error("Node had unexpected type: " + object.type);
|
|
}
|
|
var jsx = superClass => class JSXParserMixin extends superClass {
|
|
jsxReadToken() {
|
|
let out = "";
|
|
let chunkStart = this.state.pos;
|
|
for (;;) {
|
|
if (this.state.pos >= this.length) {
|
|
throw this.raise(JsxErrors.UnterminatedJsxContent, this.state.startLoc);
|
|
}
|
|
const ch = this.input.charCodeAt(this.state.pos);
|
|
switch (ch) {
|
|
case 60:
|
|
case 123:
|
|
if (this.state.pos === this.state.start) {
|
|
if (ch === 60 && this.state.canStartJSXElement) {
|
|
++this.state.pos;
|
|
this.finishToken(143);
|
|
} else {
|
|
super.getTokenFromCode(ch);
|
|
}
|
|
return;
|
|
}
|
|
out += this.input.slice(chunkStart, this.state.pos);
|
|
this.finishToken(142, out);
|
|
return;
|
|
case 38:
|
|
out += this.input.slice(chunkStart, this.state.pos);
|
|
out += this.jsxReadEntity();
|
|
chunkStart = this.state.pos;
|
|
break;
|
|
case 62:
|
|
case 125:
|
|
default:
|
|
if (isNewLine(ch)) {
|
|
out += this.input.slice(chunkStart, this.state.pos);
|
|
out += this.jsxReadNewLine(true);
|
|
chunkStart = this.state.pos;
|
|
} else {
|
|
++this.state.pos;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
jsxReadNewLine(normalizeCRLF) {
|
|
const ch = this.input.charCodeAt(this.state.pos);
|
|
let out;
|
|
++this.state.pos;
|
|
if (ch === 13 && this.input.charCodeAt(this.state.pos) === 10) {
|
|
++this.state.pos;
|
|
out = normalizeCRLF ? "\n" : "\r\n";
|
|
} else {
|
|
out = String.fromCharCode(ch);
|
|
}
|
|
++this.state.curLine;
|
|
this.state.lineStart = this.state.pos;
|
|
return out;
|
|
}
|
|
jsxReadString(quote) {
|
|
let out = "";
|
|
let chunkStart = ++this.state.pos;
|
|
for (;;) {
|
|
if (this.state.pos >= this.length) {
|
|
throw this.raise(Errors.UnterminatedString, this.state.startLoc);
|
|
}
|
|
const ch = this.input.charCodeAt(this.state.pos);
|
|
if (ch === quote) break;
|
|
if (ch === 38) {
|
|
out += this.input.slice(chunkStart, this.state.pos);
|
|
out += this.jsxReadEntity();
|
|
chunkStart = this.state.pos;
|
|
} else if (isNewLine(ch)) {
|
|
out += this.input.slice(chunkStart, this.state.pos);
|
|
out += this.jsxReadNewLine(false);
|
|
chunkStart = this.state.pos;
|
|
} else {
|
|
++this.state.pos;
|
|
}
|
|
}
|
|
out += this.input.slice(chunkStart, this.state.pos++);
|
|
this.finishToken(134, out);
|
|
}
|
|
jsxReadEntity() {
|
|
const startPos = ++this.state.pos;
|
|
if (this.codePointAtPos(this.state.pos) === 35) {
|
|
++this.state.pos;
|
|
let radix = 10;
|
|
if (this.codePointAtPos(this.state.pos) === 120) {
|
|
radix = 16;
|
|
++this.state.pos;
|
|
}
|
|
const codePoint = this.readInt(radix, undefined, false, "bail");
|
|
if (codePoint !== null && this.codePointAtPos(this.state.pos) === 59) {
|
|
++this.state.pos;
|
|
return String.fromCodePoint(codePoint);
|
|
}
|
|
} else {
|
|
let count = 0;
|
|
let semi = false;
|
|
while (count++ < 10 && this.state.pos < this.length && !(semi = this.codePointAtPos(this.state.pos) === 59)) {
|
|
++this.state.pos;
|
|
}
|
|
if (semi) {
|
|
const desc = this.input.slice(startPos, this.state.pos);
|
|
const entity = entities[desc];
|
|
++this.state.pos;
|
|
if (entity) {
|
|
return entity;
|
|
}
|
|
}
|
|
}
|
|
this.state.pos = startPos;
|
|
return "&";
|
|
}
|
|
jsxReadWord() {
|
|
let ch;
|
|
const start = this.state.pos;
|
|
do {
|
|
ch = this.input.charCodeAt(++this.state.pos);
|
|
} while (isIdentifierChar(ch) || ch === 45);
|
|
this.finishToken(141, this.input.slice(start, this.state.pos));
|
|
}
|
|
jsxParseIdentifier() {
|
|
const node = this.startNode();
|
|
if (this.match(141)) {
|
|
node.name = this.state.value;
|
|
} else if (tokenIsKeyword(this.state.type)) {
|
|
node.name = tokenLabelName(this.state.type);
|
|
} else {
|
|
this.unexpected();
|
|
}
|
|
this.next();
|
|
return this.finishNode(node, "JSXIdentifier");
|
|
}
|
|
jsxParseNamespacedName() {
|
|
const startLoc = this.state.startLoc;
|
|
const name = this.jsxParseIdentifier();
|
|
if (!this.eat(14)) return name;
|
|
const node = this.startNodeAt(startLoc);
|
|
node.namespace = name;
|
|
node.name = this.jsxParseIdentifier();
|
|
return this.finishNode(node, "JSXNamespacedName");
|
|
}
|
|
jsxParseElementName() {
|
|
const startLoc = this.state.startLoc;
|
|
let node = this.jsxParseNamespacedName();
|
|
if (node.type === "JSXNamespacedName") {
|
|
return node;
|
|
}
|
|
while (this.eat(16)) {
|
|
const newNode = this.startNodeAt(startLoc);
|
|
newNode.object = node;
|
|
newNode.property = this.jsxParseIdentifier();
|
|
node = this.finishNode(newNode, "JSXMemberExpression");
|
|
}
|
|
return node;
|
|
}
|
|
jsxParseAttributeValue() {
|
|
let node;
|
|
switch (this.state.type) {
|
|
case 5:
|
|
node = this.startNode();
|
|
this.setContext(types.brace);
|
|
this.next();
|
|
node = this.jsxParseExpressionContainer(node, types.j_oTag);
|
|
if (node.expression.type === "JSXEmptyExpression") {
|
|
this.raise(JsxErrors.AttributeIsEmpty, node);
|
|
}
|
|
return node;
|
|
case 143:
|
|
case 134:
|
|
return this.parseExprAtom();
|
|
default:
|
|
throw this.raise(JsxErrors.UnsupportedJsxValue, this.state.startLoc);
|
|
}
|
|
}
|
|
jsxParseEmptyExpression() {
|
|
const node = this.startNodeAt(this.state.lastTokEndLoc);
|
|
return this.finishNodeAt(node, "JSXEmptyExpression", this.state.startLoc);
|
|
}
|
|
jsxParseSpreadChild(node) {
|
|
this.next();
|
|
node.expression = this.parseExpression();
|
|
this.setContext(types.j_expr);
|
|
this.state.canStartJSXElement = true;
|
|
this.expect(8);
|
|
return this.finishNode(node, "JSXSpreadChild");
|
|
}
|
|
jsxParseExpressionContainer(node, previousContext) {
|
|
if (this.match(8)) {
|
|
node.expression = this.jsxParseEmptyExpression();
|
|
} else {
|
|
const expression = this.parseExpression();
|
|
node.expression = expression;
|
|
}
|
|
this.setContext(previousContext);
|
|
this.state.canStartJSXElement = true;
|
|
this.expect(8);
|
|
return this.finishNode(node, "JSXExpressionContainer");
|
|
}
|
|
jsxParseAttribute() {
|
|
const node = this.startNode();
|
|
if (this.match(5)) {
|
|
this.setContext(types.brace);
|
|
this.next();
|
|
this.expect(21);
|
|
node.argument = this.parseMaybeAssignAllowIn();
|
|
this.setContext(types.j_oTag);
|
|
this.state.canStartJSXElement = true;
|
|
this.expect(8);
|
|
return this.finishNode(node, "JSXSpreadAttribute");
|
|
}
|
|
node.name = this.jsxParseNamespacedName();
|
|
node.value = this.eat(29) ? this.jsxParseAttributeValue() : null;
|
|
return this.finishNode(node, "JSXAttribute");
|
|
}
|
|
jsxParseOpeningElementAt(startLoc) {
|
|
const node = this.startNodeAt(startLoc);
|
|
if (this.eat(144)) {
|
|
return this.finishNode(node, "JSXOpeningFragment");
|
|
}
|
|
node.name = this.jsxParseElementName();
|
|
return this.jsxParseOpeningElementAfterName(node);
|
|
}
|
|
jsxParseOpeningElementAfterName(node) {
|
|
const attributes = [];
|
|
while (!this.match(56) && !this.match(144)) {
|
|
attributes.push(this.jsxParseAttribute());
|
|
}
|
|
node.attributes = attributes;
|
|
node.selfClosing = this.eat(56);
|
|
this.expect(144);
|
|
return this.finishNode(node, "JSXOpeningElement");
|
|
}
|
|
jsxParseClosingElementAt(startLoc) {
|
|
const node = this.startNodeAt(startLoc);
|
|
if (this.eat(144)) {
|
|
return this.finishNode(node, "JSXClosingFragment");
|
|
}
|
|
node.name = this.jsxParseElementName();
|
|
this.expect(144);
|
|
return this.finishNode(node, "JSXClosingElement");
|
|
}
|
|
jsxParseElementAt(startLoc) {
|
|
const node = this.startNodeAt(startLoc);
|
|
const children = [];
|
|
const openingElement = this.jsxParseOpeningElementAt(startLoc);
|
|
let closingElement = null;
|
|
if (!openingElement.selfClosing) {
|
|
contents: for (;;) {
|
|
switch (this.state.type) {
|
|
case 143:
|
|
startLoc = this.state.startLoc;
|
|
this.next();
|
|
if (this.eat(56)) {
|
|
closingElement = this.jsxParseClosingElementAt(startLoc);
|
|
break contents;
|
|
}
|
|
children.push(this.jsxParseElementAt(startLoc));
|
|
break;
|
|
case 142:
|
|
children.push(this.parseLiteral(this.state.value, "JSXText"));
|
|
break;
|
|
case 5:
|
|
{
|
|
const node = this.startNode();
|
|
this.setContext(types.brace);
|
|
this.next();
|
|
if (this.match(21)) {
|
|
children.push(this.jsxParseSpreadChild(node));
|
|
} else {
|
|
children.push(this.jsxParseExpressionContainer(node, types.j_expr));
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
this.unexpected();
|
|
}
|
|
}
|
|
if (isFragment(openingElement) && !isFragment(closingElement) && closingElement !== null) {
|
|
this.raise(JsxErrors.MissingClosingTagFragment, closingElement);
|
|
} else if (!isFragment(openingElement) && isFragment(closingElement)) {
|
|
this.raise(JsxErrors.MissingClosingTagElement, closingElement, {
|
|
openingTagName: getQualifiedJSXName(openingElement.name)
|
|
});
|
|
} else if (!isFragment(openingElement) && !isFragment(closingElement)) {
|
|
if (getQualifiedJSXName(closingElement.name) !== getQualifiedJSXName(openingElement.name)) {
|
|
this.raise(JsxErrors.MissingClosingTagElement, closingElement, {
|
|
openingTagName: getQualifiedJSXName(openingElement.name)
|
|
});
|
|
}
|
|
}
|
|
}
|
|
if (isFragment(openingElement)) {
|
|
node.openingFragment = openingElement;
|
|
node.closingFragment = closingElement;
|
|
} else {
|
|
node.openingElement = openingElement;
|
|
node.closingElement = closingElement;
|
|
}
|
|
node.children = children;
|
|
if (this.match(47)) {
|
|
throw this.raise(JsxErrors.UnwrappedAdjacentJSXElements, this.state.startLoc);
|
|
}
|
|
return isFragment(openingElement) ? this.finishNode(node, "JSXFragment") : this.finishNode(node, "JSXElement");
|
|
}
|
|
jsxParseElement() {
|
|
const startLoc = this.state.startLoc;
|
|
this.next();
|
|
return this.jsxParseElementAt(startLoc);
|
|
}
|
|
setContext(newContext) {
|
|
const {
|
|
context
|
|
} = this.state;
|
|
context[context.length - 1] = newContext;
|
|
}
|
|
parseExprAtom(refExpressionErrors) {
|
|
if (this.match(143)) {
|
|
return this.jsxParseElement();
|
|
} else if (this.match(47) && this.input.charCodeAt(this.state.pos) !== 33) {
|
|
this.replaceToken(143);
|
|
return this.jsxParseElement();
|
|
} else {
|
|
return super.parseExprAtom(refExpressionErrors);
|
|
}
|
|
}
|
|
skipSpace() {
|
|
const curContext = this.curContext();
|
|
if (!curContext.preserveSpace) super.skipSpace();
|
|
}
|
|
getTokenFromCode(code) {
|
|
const context = this.curContext();
|
|
if (context === types.j_expr) {
|
|
this.jsxReadToken();
|
|
return;
|
|
}
|
|
if (context === types.j_oTag || context === types.j_cTag) {
|
|
if (isIdentifierStart(code)) {
|
|
this.jsxReadWord();
|
|
return;
|
|
}
|
|
if (code === 62) {
|
|
++this.state.pos;
|
|
this.finishToken(144);
|
|
return;
|
|
}
|
|
if ((code === 34 || code === 39) && context === types.j_oTag) {
|
|
this.jsxReadString(code);
|
|
return;
|
|
}
|
|
}
|
|
if (code === 60 && this.state.canStartJSXElement && this.input.charCodeAt(this.state.pos + 1) !== 33) {
|
|
++this.state.pos;
|
|
this.finishToken(143);
|
|
return;
|
|
}
|
|
super.getTokenFromCode(code);
|
|
}
|
|
updateContext(prevType) {
|
|
const {
|
|
context,
|
|
type
|
|
} = this.state;
|
|
if (type === 56 && prevType === 143) {
|
|
context.splice(-2, 2, types.j_cTag);
|
|
this.state.canStartJSXElement = false;
|
|
} else if (type === 143) {
|
|
context.push(types.j_oTag);
|
|
} else if (type === 144) {
|
|
const out = context[context.length - 1];
|
|
if (out === types.j_oTag && prevType === 56 || out === types.j_cTag) {
|
|
context.pop();
|
|
this.state.canStartJSXElement = context[context.length - 1] === types.j_expr;
|
|
} else {
|
|
this.setContext(types.j_expr);
|
|
this.state.canStartJSXElement = true;
|
|
}
|
|
} else {
|
|
this.state.canStartJSXElement = tokenComesBeforeExpression(type);
|
|
}
|
|
}
|
|
};
|
|
class TypeScriptScope extends Scope {
|
|
constructor(...args) {
|
|
super(...args);
|
|
this.tsNames = new Map();
|
|
}
|
|
}
|
|
class TypeScriptScopeHandler extends ScopeHandler {
|
|
constructor(...args) {
|
|
super(...args);
|
|
this.importsStack = [];
|
|
}
|
|
createScope(flags) {
|
|
this.importsStack.push(new Set());
|
|
return new TypeScriptScope(flags);
|
|
}
|
|
enter(flags) {
|
|
if (flags === 1024) {
|
|
this.importsStack.push(new Set());
|
|
}
|
|
super.enter(flags);
|
|
}
|
|
exit() {
|
|
const flags = super.exit();
|
|
if (flags === 1024) {
|
|
this.importsStack.pop();
|
|
}
|
|
return flags;
|
|
}
|
|
hasImport(name, allowShadow) {
|
|
const len = this.importsStack.length;
|
|
if (this.importsStack[len - 1].has(name)) {
|
|
return true;
|
|
}
|
|
if (!allowShadow && len > 1) {
|
|
for (let i = 0; i < len - 1; i++) {
|
|
if (this.importsStack[i].has(name)) return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
declareName(name, bindingType, loc) {
|
|
if (bindingType & 4096) {
|
|
if (this.hasImport(name, true)) {
|
|
this.parser.raise(Errors.VarRedeclaration, loc, {
|
|
identifierName: name
|
|
});
|
|
}
|
|
this.importsStack[this.importsStack.length - 1].add(name);
|
|
return;
|
|
}
|
|
const scope = this.currentScope();
|
|
let type = scope.tsNames.get(name) || 0;
|
|
if (bindingType & 1024) {
|
|
this.maybeExportDefined(scope, name);
|
|
scope.tsNames.set(name, type | 16);
|
|
return;
|
|
}
|
|
super.declareName(name, bindingType, loc);
|
|
if (bindingType & 2) {
|
|
if (!(bindingType & 1)) {
|
|
this.checkRedeclarationInScope(scope, name, bindingType, loc);
|
|
this.maybeExportDefined(scope, name);
|
|
}
|
|
type = type | 1;
|
|
}
|
|
if (bindingType & 256) {
|
|
type = type | 2;
|
|
}
|
|
if (bindingType & 512) {
|
|
type = type | 4;
|
|
}
|
|
if (bindingType & 128) {
|
|
type = type | 8;
|
|
}
|
|
if (type) scope.tsNames.set(name, type);
|
|
}
|
|
isRedeclaredInScope(scope, name, bindingType) {
|
|
const type = scope.tsNames.get(name);
|
|
if ((type & 2) > 0) {
|
|
if (bindingType & 256) {
|
|
const isConst = !!(bindingType & 512);
|
|
const wasConst = (type & 4) > 0;
|
|
return isConst !== wasConst;
|
|
}
|
|
return true;
|
|
}
|
|
if (bindingType & 128 && (type & 8) > 0) {
|
|
if (scope.names.get(name) & 2) {
|
|
return !!(bindingType & 1);
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
if (bindingType & 2 && (type & 1) > 0) {
|
|
return true;
|
|
}
|
|
return super.isRedeclaredInScope(scope, name, bindingType);
|
|
}
|
|
checkLocalExport(id) {
|
|
const {
|
|
name
|
|
} = id;
|
|
if (this.hasImport(name)) return;
|
|
const len = this.scopeStack.length;
|
|
for (let i = len - 1; i >= 0; i--) {
|
|
const scope = this.scopeStack[i];
|
|
const type = scope.tsNames.get(name);
|
|
if ((type & 1) > 0 || (type & 16) > 0) {
|
|
return;
|
|
}
|
|
}
|
|
super.checkLocalExport(id);
|
|
}
|
|
}
|
|
class ProductionParameterHandler {
|
|
constructor() {
|
|
this.stacks = [];
|
|
}
|
|
enter(flags) {
|
|
this.stacks.push(flags);
|
|
}
|
|
exit() {
|
|
this.stacks.pop();
|
|
}
|
|
currentFlags() {
|
|
return this.stacks[this.stacks.length - 1];
|
|
}
|
|
get hasAwait() {
|
|
return (this.currentFlags() & 2) > 0;
|
|
}
|
|
get hasYield() {
|
|
return (this.currentFlags() & 1) > 0;
|
|
}
|
|
get hasReturn() {
|
|
return (this.currentFlags() & 4) > 0;
|
|
}
|
|
get hasIn() {
|
|
return (this.currentFlags() & 8) > 0;
|
|
}
|
|
}
|
|
function functionFlags(isAsync, isGenerator) {
|
|
return (isAsync ? 2 : 0) | (isGenerator ? 1 : 0);
|
|
}
|
|
class BaseParser {
|
|
constructor() {
|
|
this.sawUnambiguousESM = false;
|
|
this.ambiguousScriptDifferentAst = false;
|
|
}
|
|
sourceToOffsetPos(sourcePos) {
|
|
return sourcePos + this.startIndex;
|
|
}
|
|
offsetToSourcePos(offsetPos) {
|
|
return offsetPos - this.startIndex;
|
|
}
|
|
hasPlugin(pluginConfig) {
|
|
if (typeof pluginConfig === "string") {
|
|
return this.plugins.has(pluginConfig);
|
|
} else {
|
|
const [pluginName, pluginOptions] = pluginConfig;
|
|
if (!this.hasPlugin(pluginName)) {
|
|
return false;
|
|
}
|
|
const actualOptions = this.plugins.get(pluginName);
|
|
for (const key of Object.keys(pluginOptions)) {
|
|
if ((actualOptions == null ? void 0 : actualOptions[key]) !== pluginOptions[key]) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
getPluginOption(plugin, name) {
|
|
var _this$plugins$get;
|
|
return (_this$plugins$get = this.plugins.get(plugin)) == null ? void 0 : _this$plugins$get[name];
|
|
}
|
|
}
|
|
function setTrailingComments(node, comments) {
|
|
if (node.trailingComments === undefined) {
|
|
node.trailingComments = comments;
|
|
} else {
|
|
node.trailingComments.unshift(...comments);
|
|
}
|
|
}
|
|
function setLeadingComments(node, comments) {
|
|
if (node.leadingComments === undefined) {
|
|
node.leadingComments = comments;
|
|
} else {
|
|
node.leadingComments.unshift(...comments);
|
|
}
|
|
}
|
|
function setInnerComments(node, comments) {
|
|
if (node.innerComments === undefined) {
|
|
node.innerComments = comments;
|
|
} else {
|
|
node.innerComments.unshift(...comments);
|
|
}
|
|
}
|
|
function adjustInnerComments(node, elements, commentWS) {
|
|
let lastElement = null;
|
|
let i = elements.length;
|
|
while (lastElement === null && i > 0) {
|
|
lastElement = elements[--i];
|
|
}
|
|
if (lastElement === null || lastElement.start > commentWS.start) {
|
|
setInnerComments(node, commentWS.comments);
|
|
} else {
|
|
setTrailingComments(lastElement, commentWS.comments);
|
|
}
|
|
}
|
|
class CommentsParser extends BaseParser {
|
|
addComment(comment) {
|
|
if (this.filename) comment.loc.filename = this.filename;
|
|
const {
|
|
commentsLen
|
|
} = this.state;
|
|
if (this.comments.length !== commentsLen) {
|
|
this.comments.length = commentsLen;
|
|
}
|
|
this.comments.push(comment);
|
|
this.state.commentsLen++;
|
|
}
|
|
processComment(node) {
|
|
const {
|
|
commentStack
|
|
} = this.state;
|
|
const commentStackLength = commentStack.length;
|
|
if (commentStackLength === 0) return;
|
|
let i = commentStackLength - 1;
|
|
const lastCommentWS = commentStack[i];
|
|
if (lastCommentWS.start === node.end) {
|
|
lastCommentWS.leadingNode = node;
|
|
i--;
|
|
}
|
|
const {
|
|
start: nodeStart
|
|
} = node;
|
|
for (; i >= 0; i--) {
|
|
const commentWS = commentStack[i];
|
|
const commentEnd = commentWS.end;
|
|
if (commentEnd > nodeStart) {
|
|
commentWS.containingNode = node;
|
|
this.finalizeComment(commentWS);
|
|
commentStack.splice(i, 1);
|
|
} else {
|
|
if (commentEnd === nodeStart) {
|
|
commentWS.trailingNode = node;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
finalizeComment(commentWS) {
|
|
var _node$options;
|
|
const {
|
|
comments
|
|
} = commentWS;
|
|
if (commentWS.leadingNode !== null || commentWS.trailingNode !== null) {
|
|
if (commentWS.leadingNode !== null) {
|
|
setTrailingComments(commentWS.leadingNode, comments);
|
|
}
|
|
if (commentWS.trailingNode !== null) {
|
|
setLeadingComments(commentWS.trailingNode, comments);
|
|
}
|
|
} else {
|
|
const node = commentWS.containingNode;
|
|
const commentStart = commentWS.start;
|
|
if (this.input.charCodeAt(this.offsetToSourcePos(commentStart) - 1) === 44) {
|
|
switch (node.type) {
|
|
case "ObjectExpression":
|
|
case "ObjectPattern":
|
|
case "RecordExpression":
|
|
adjustInnerComments(node, node.properties, commentWS);
|
|
break;
|
|
case "CallExpression":
|
|
case "OptionalCallExpression":
|
|
adjustInnerComments(node, node.arguments, commentWS);
|
|
break;
|
|
case "ImportExpression":
|
|
adjustInnerComments(node, [node.source, (_node$options = node.options) != null ? _node$options : null], commentWS);
|
|
break;
|
|
case "FunctionDeclaration":
|
|
case "FunctionExpression":
|
|
case "ArrowFunctionExpression":
|
|
case "ObjectMethod":
|
|
case "ClassMethod":
|
|
case "ClassPrivateMethod":
|
|
adjustInnerComments(node, node.params, commentWS);
|
|
break;
|
|
case "ArrayExpression":
|
|
case "ArrayPattern":
|
|
case "TupleExpression":
|
|
adjustInnerComments(node, node.elements, commentWS);
|
|
break;
|
|
case "ExportNamedDeclaration":
|
|
case "ImportDeclaration":
|
|
adjustInnerComments(node, node.specifiers, commentWS);
|
|
break;
|
|
case "TSEnumDeclaration":
|
|
{
|
|
adjustInnerComments(node, node.members, commentWS);
|
|
}
|
|
break;
|
|
case "TSEnumBody":
|
|
adjustInnerComments(node, node.members, commentWS);
|
|
break;
|
|
default:
|
|
{
|
|
setInnerComments(node, comments);
|
|
}
|
|
}
|
|
} else {
|
|
setInnerComments(node, comments);
|
|
}
|
|
}
|
|
}
|
|
finalizeRemainingComments() {
|
|
const {
|
|
commentStack
|
|
} = this.state;
|
|
for (let i = commentStack.length - 1; i >= 0; i--) {
|
|
this.finalizeComment(commentStack[i]);
|
|
}
|
|
this.state.commentStack = [];
|
|
}
|
|
resetPreviousNodeTrailingComments(node) {
|
|
const {
|
|
commentStack
|
|
} = this.state;
|
|
const {
|
|
length
|
|
} = commentStack;
|
|
if (length === 0) return;
|
|
const commentWS = commentStack[length - 1];
|
|
if (commentWS.leadingNode === node) {
|
|
commentWS.leadingNode = null;
|
|
}
|
|
}
|
|
takeSurroundingComments(node, start, end) {
|
|
const {
|
|
commentStack
|
|
} = this.state;
|
|
const commentStackLength = commentStack.length;
|
|
if (commentStackLength === 0) return;
|
|
let i = commentStackLength - 1;
|
|
for (; i >= 0; i--) {
|
|
const commentWS = commentStack[i];
|
|
const commentEnd = commentWS.end;
|
|
const commentStart = commentWS.start;
|
|
if (commentStart === end) {
|
|
commentWS.leadingNode = node;
|
|
} else if (commentEnd === start) {
|
|
commentWS.trailingNode = node;
|
|
} else if (commentEnd < start) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
class State {
|
|
constructor() {
|
|
this.flags = 1024;
|
|
this.startIndex = void 0;
|
|
this.curLine = void 0;
|
|
this.lineStart = void 0;
|
|
this.startLoc = void 0;
|
|
this.endLoc = void 0;
|
|
this.errors = [];
|
|
this.potentialArrowAt = -1;
|
|
this.noArrowAt = [];
|
|
this.noArrowParamsConversionAt = [];
|
|
this.topicContext = {
|
|
maxNumOfResolvableTopics: 0,
|
|
maxTopicIndex: null
|
|
};
|
|
this.labels = [];
|
|
this.commentsLen = 0;
|
|
this.commentStack = [];
|
|
this.pos = 0;
|
|
this.type = 140;
|
|
this.value = null;
|
|
this.start = 0;
|
|
this.end = 0;
|
|
this.lastTokEndLoc = null;
|
|
this.lastTokStartLoc = null;
|
|
this.context = [types.brace];
|
|
this.firstInvalidTemplateEscapePos = null;
|
|
this.strictErrors = new Map();
|
|
this.tokensLength = 0;
|
|
}
|
|
get strict() {
|
|
return (this.flags & 1) > 0;
|
|
}
|
|
set strict(v) {
|
|
if (v) this.flags |= 1;else this.flags &= -2;
|
|
}
|
|
init({
|
|
strictMode,
|
|
sourceType,
|
|
startIndex,
|
|
startLine,
|
|
startColumn
|
|
}) {
|
|
this.strict = strictMode === false ? false : strictMode === true ? true : sourceType === "module";
|
|
this.startIndex = startIndex;
|
|
this.curLine = startLine;
|
|
this.lineStart = -startColumn;
|
|
this.startLoc = this.endLoc = new Position(startLine, startColumn, startIndex);
|
|
}
|
|
get maybeInArrowParameters() {
|
|
return (this.flags & 2) > 0;
|
|
}
|
|
set maybeInArrowParameters(v) {
|
|
if (v) this.flags |= 2;else this.flags &= -3;
|
|
}
|
|
get inType() {
|
|
return (this.flags & 4) > 0;
|
|
}
|
|
set inType(v) {
|
|
if (v) this.flags |= 4;else this.flags &= -5;
|
|
}
|
|
get noAnonFunctionType() {
|
|
return (this.flags & 8) > 0;
|
|
}
|
|
set noAnonFunctionType(v) {
|
|
if (v) this.flags |= 8;else this.flags &= -9;
|
|
}
|
|
get hasFlowComment() {
|
|
return (this.flags & 16) > 0;
|
|
}
|
|
set hasFlowComment(v) {
|
|
if (v) this.flags |= 16;else this.flags &= -17;
|
|
}
|
|
get isAmbientContext() {
|
|
return (this.flags & 32) > 0;
|
|
}
|
|
set isAmbientContext(v) {
|
|
if (v) this.flags |= 32;else this.flags &= -33;
|
|
}
|
|
get inAbstractClass() {
|
|
return (this.flags & 64) > 0;
|
|
}
|
|
set inAbstractClass(v) {
|
|
if (v) this.flags |= 64;else this.flags &= -65;
|
|
}
|
|
get inDisallowConditionalTypesContext() {
|
|
return (this.flags & 128) > 0;
|
|
}
|
|
set inDisallowConditionalTypesContext(v) {
|
|
if (v) this.flags |= 128;else this.flags &= -129;
|
|
}
|
|
get soloAwait() {
|
|
return (this.flags & 256) > 0;
|
|
}
|
|
set soloAwait(v) {
|
|
if (v) this.flags |= 256;else this.flags &= -257;
|
|
}
|
|
get inFSharpPipelineDirectBody() {
|
|
return (this.flags & 512) > 0;
|
|
}
|
|
set inFSharpPipelineDirectBody(v) {
|
|
if (v) this.flags |= 512;else this.flags &= -513;
|
|
}
|
|
get canStartJSXElement() {
|
|
return (this.flags & 1024) > 0;
|
|
}
|
|
set canStartJSXElement(v) {
|
|
if (v) this.flags |= 1024;else this.flags &= -1025;
|
|
}
|
|
get containsEsc() {
|
|
return (this.flags & 2048) > 0;
|
|
}
|
|
set containsEsc(v) {
|
|
if (v) this.flags |= 2048;else this.flags &= -2049;
|
|
}
|
|
get hasTopLevelAwait() {
|
|
return (this.flags & 4096) > 0;
|
|
}
|
|
set hasTopLevelAwait(v) {
|
|
if (v) this.flags |= 4096;else this.flags &= -4097;
|
|
}
|
|
curPosition() {
|
|
return new Position(this.curLine, this.pos - this.lineStart, this.pos + this.startIndex);
|
|
}
|
|
clone() {
|
|
const state = new State();
|
|
state.flags = this.flags;
|
|
state.startIndex = this.startIndex;
|
|
state.curLine = this.curLine;
|
|
state.lineStart = this.lineStart;
|
|
state.startLoc = this.startLoc;
|
|
state.endLoc = this.endLoc;
|
|
state.errors = this.errors.slice();
|
|
state.potentialArrowAt = this.potentialArrowAt;
|
|
state.noArrowAt = this.noArrowAt.slice();
|
|
state.noArrowParamsConversionAt = this.noArrowParamsConversionAt.slice();
|
|
state.topicContext = this.topicContext;
|
|
state.labels = this.labels.slice();
|
|
state.commentsLen = this.commentsLen;
|
|
state.commentStack = this.commentStack.slice();
|
|
state.pos = this.pos;
|
|
state.type = this.type;
|
|
state.value = this.value;
|
|
state.start = this.start;
|
|
state.end = this.end;
|
|
state.lastTokEndLoc = this.lastTokEndLoc;
|
|
state.lastTokStartLoc = this.lastTokStartLoc;
|
|
state.context = this.context.slice();
|
|
state.firstInvalidTemplateEscapePos = this.firstInvalidTemplateEscapePos;
|
|
state.strictErrors = this.strictErrors;
|
|
state.tokensLength = this.tokensLength;
|
|
return state;
|
|
}
|
|
}
|
|
var _isDigit = function isDigit(code) {
|
|
return code >= 48 && code <= 57;
|
|
};
|
|
const forbiddenNumericSeparatorSiblings = {
|
|
decBinOct: new Set([46, 66, 69, 79, 95, 98, 101, 111]),
|
|
hex: new Set([46, 88, 95, 120])
|
|
};
|
|
const isAllowedNumericSeparatorSibling = {
|
|
bin: ch => ch === 48 || ch === 49,
|
|
oct: ch => ch >= 48 && ch <= 55,
|
|
dec: ch => ch >= 48 && ch <= 57,
|
|
hex: ch => ch >= 48 && ch <= 57 || ch >= 65 && ch <= 70 || ch >= 97 && ch <= 102
|
|
};
|
|
function readStringContents(type, input, pos, lineStart, curLine, errors) {
|
|
const initialPos = pos;
|
|
const initialLineStart = lineStart;
|
|
const initialCurLine = curLine;
|
|
let out = "";
|
|
let firstInvalidLoc = null;
|
|
let chunkStart = pos;
|
|
const {
|
|
length
|
|
} = input;
|
|
for (;;) {
|
|
if (pos >= length) {
|
|
errors.unterminated(initialPos, initialLineStart, initialCurLine);
|
|
out += input.slice(chunkStart, pos);
|
|
break;
|
|
}
|
|
const ch = input.charCodeAt(pos);
|
|
if (isStringEnd(type, ch, input, pos)) {
|
|
out += input.slice(chunkStart, pos);
|
|
break;
|
|
}
|
|
if (ch === 92) {
|
|
out += input.slice(chunkStart, pos);
|
|
const res = readEscapedChar(input, pos, lineStart, curLine, type === "template", errors);
|
|
if (res.ch === null && !firstInvalidLoc) {
|
|
firstInvalidLoc = {
|
|
pos,
|
|
lineStart,
|
|
curLine
|
|
};
|
|
} else {
|
|
out += res.ch;
|
|
}
|
|
({
|
|
pos,
|
|
lineStart,
|
|
curLine
|
|
} = res);
|
|
chunkStart = pos;
|
|
} else if (ch === 8232 || ch === 8233) {
|
|
++pos;
|
|
++curLine;
|
|
lineStart = pos;
|
|
} else if (ch === 10 || ch === 13) {
|
|
if (type === "template") {
|
|
out += input.slice(chunkStart, pos) + "\n";
|
|
++pos;
|
|
if (ch === 13 && input.charCodeAt(pos) === 10) {
|
|
++pos;
|
|
}
|
|
++curLine;
|
|
chunkStart = lineStart = pos;
|
|
} else {
|
|
errors.unterminated(initialPos, initialLineStart, initialCurLine);
|
|
}
|
|
} else {
|
|
++pos;
|
|
}
|
|
}
|
|
return {
|
|
pos,
|
|
str: out,
|
|
firstInvalidLoc,
|
|
lineStart,
|
|
curLine,
|
|
containsInvalid: !!firstInvalidLoc
|
|
};
|
|
}
|
|
function isStringEnd(type, ch, input, pos) {
|
|
if (type === "template") {
|
|
return ch === 96 || ch === 36 && input.charCodeAt(pos + 1) === 123;
|
|
}
|
|
return ch === (type === "double" ? 34 : 39);
|
|
}
|
|
function readEscapedChar(input, pos, lineStart, curLine, inTemplate, errors) {
|
|
const throwOnInvalid = !inTemplate;
|
|
pos++;
|
|
const res = ch => ({
|
|
pos,
|
|
ch,
|
|
lineStart,
|
|
curLine
|
|
});
|
|
const ch = input.charCodeAt(pos++);
|
|
switch (ch) {
|
|
case 110:
|
|
return res("\n");
|
|
case 114:
|
|
return res("\r");
|
|
case 120:
|
|
{
|
|
let code;
|
|
({
|
|
code,
|
|
pos
|
|
} = readHexChar(input, pos, lineStart, curLine, 2, false, throwOnInvalid, errors));
|
|
return res(code === null ? null : String.fromCharCode(code));
|
|
}
|
|
case 117:
|
|
{
|
|
let code;
|
|
({
|
|
code,
|
|
pos
|
|
} = readCodePoint(input, pos, lineStart, curLine, throwOnInvalid, errors));
|
|
return res(code === null ? null : String.fromCodePoint(code));
|
|
}
|
|
case 116:
|
|
return res("\t");
|
|
case 98:
|
|
return res("\b");
|
|
case 118:
|
|
return res("\u000b");
|
|
case 102:
|
|
return res("\f");
|
|
case 13:
|
|
if (input.charCodeAt(pos) === 10) {
|
|
++pos;
|
|
}
|
|
case 10:
|
|
lineStart = pos;
|
|
++curLine;
|
|
case 8232:
|
|
case 8233:
|
|
return res("");
|
|
case 56:
|
|
case 57:
|
|
if (inTemplate) {
|
|
return res(null);
|
|
} else {
|
|
errors.strictNumericEscape(pos - 1, lineStart, curLine);
|
|
}
|
|
default:
|
|
if (ch >= 48 && ch <= 55) {
|
|
const startPos = pos - 1;
|
|
const match = /^[0-7]+/.exec(input.slice(startPos, pos + 2));
|
|
let octalStr = match[0];
|
|
let octal = parseInt(octalStr, 8);
|
|
if (octal > 255) {
|
|
octalStr = octalStr.slice(0, -1);
|
|
octal = parseInt(octalStr, 8);
|
|
}
|
|
pos += octalStr.length - 1;
|
|
const next = input.charCodeAt(pos);
|
|
if (octalStr !== "0" || next === 56 || next === 57) {
|
|
if (inTemplate) {
|
|
return res(null);
|
|
} else {
|
|
errors.strictNumericEscape(startPos, lineStart, curLine);
|
|
}
|
|
}
|
|
return res(String.fromCharCode(octal));
|
|
}
|
|
return res(String.fromCharCode(ch));
|
|
}
|
|
}
|
|
function readHexChar(input, pos, lineStart, curLine, len, forceLen, throwOnInvalid, errors) {
|
|
const initialPos = pos;
|
|
let n;
|
|
({
|
|
n,
|
|
pos
|
|
} = readInt(input, pos, lineStart, curLine, 16, len, forceLen, false, errors, !throwOnInvalid));
|
|
if (n === null) {
|
|
if (throwOnInvalid) {
|
|
errors.invalidEscapeSequence(initialPos, lineStart, curLine);
|
|
} else {
|
|
pos = initialPos - 1;
|
|
}
|
|
}
|
|
return {
|
|
code: n,
|
|
pos
|
|
};
|
|
}
|
|
function readInt(input, pos, lineStart, curLine, radix, len, forceLen, allowNumSeparator, errors, bailOnError) {
|
|
const start = pos;
|
|
const forbiddenSiblings = radix === 16 ? forbiddenNumericSeparatorSiblings.hex : forbiddenNumericSeparatorSiblings.decBinOct;
|
|
const isAllowedSibling = radix === 16 ? isAllowedNumericSeparatorSibling.hex : radix === 10 ? isAllowedNumericSeparatorSibling.dec : radix === 8 ? isAllowedNumericSeparatorSibling.oct : isAllowedNumericSeparatorSibling.bin;
|
|
let invalid = false;
|
|
let total = 0;
|
|
for (let i = 0, e = len == null ? Infinity : len; i < e; ++i) {
|
|
const code = input.charCodeAt(pos);
|
|
let val;
|
|
if (code === 95 && allowNumSeparator !== "bail") {
|
|
const prev = input.charCodeAt(pos - 1);
|
|
const next = input.charCodeAt(pos + 1);
|
|
if (!allowNumSeparator) {
|
|
if (bailOnError) return {
|
|
n: null,
|
|
pos
|
|
};
|
|
errors.numericSeparatorInEscapeSequence(pos, lineStart, curLine);
|
|
} else if (Number.isNaN(next) || !isAllowedSibling(next) || forbiddenSiblings.has(prev) || forbiddenSiblings.has(next)) {
|
|
if (bailOnError) return {
|
|
n: null,
|
|
pos
|
|
};
|
|
errors.unexpectedNumericSeparator(pos, lineStart, curLine);
|
|
}
|
|
++pos;
|
|
continue;
|
|
}
|
|
if (code >= 97) {
|
|
val = code - 97 + 10;
|
|
} else if (code >= 65) {
|
|
val = code - 65 + 10;
|
|
} else if (_isDigit(code)) {
|
|
val = code - 48;
|
|
} else {
|
|
val = Infinity;
|
|
}
|
|
if (val >= radix) {
|
|
if (val <= 9 && bailOnError) {
|
|
return {
|
|
n: null,
|
|
pos
|
|
};
|
|
} else if (val <= 9 && errors.invalidDigit(pos, lineStart, curLine, radix)) {
|
|
val = 0;
|
|
} else if (forceLen) {
|
|
val = 0;
|
|
invalid = true;
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
++pos;
|
|
total = total * radix + val;
|
|
}
|
|
if (pos === start || len != null && pos - start !== len || invalid) {
|
|
return {
|
|
n: null,
|
|
pos
|
|
};
|
|
}
|
|
return {
|
|
n: total,
|
|
pos
|
|
};
|
|
}
|
|
function readCodePoint(input, pos, lineStart, curLine, throwOnInvalid, errors) {
|
|
const ch = input.charCodeAt(pos);
|
|
let code;
|
|
if (ch === 123) {
|
|
++pos;
|
|
({
|
|
code,
|
|
pos
|
|
} = readHexChar(input, pos, lineStart, curLine, input.indexOf("}", pos) - pos, true, throwOnInvalid, errors));
|
|
++pos;
|
|
if (code !== null && code > 0x10ffff) {
|
|
if (throwOnInvalid) {
|
|
errors.invalidCodePoint(pos, lineStart, curLine);
|
|
} else {
|
|
return {
|
|
code: null,
|
|
pos
|
|
};
|
|
}
|
|
}
|
|
} else {
|
|
({
|
|
code,
|
|
pos
|
|
} = readHexChar(input, pos, lineStart, curLine, 4, false, throwOnInvalid, errors));
|
|
}
|
|
return {
|
|
code,
|
|
pos
|
|
};
|
|
}
|
|
function buildPosition(pos, lineStart, curLine) {
|
|
return new Position(curLine, pos - lineStart, pos);
|
|
}
|
|
const VALID_REGEX_FLAGS = new Set([103, 109, 115, 105, 121, 117, 100, 118]);
|
|
class Token {
|
|
constructor(state) {
|
|
const startIndex = state.startIndex || 0;
|
|
this.type = state.type;
|
|
this.value = state.value;
|
|
this.start = startIndex + state.start;
|
|
this.end = startIndex + state.end;
|
|
this.loc = new SourceLocation(state.startLoc, state.endLoc);
|
|
}
|
|
}
|
|
class Tokenizer extends CommentsParser {
|
|
constructor(options, input) {
|
|
super();
|
|
this.isLookahead = void 0;
|
|
this.tokens = [];
|
|
this.errorHandlers_readInt = {
|
|
invalidDigit: (pos, lineStart, curLine, radix) => {
|
|
if (!(this.optionFlags & 2048)) return false;
|
|
this.raise(Errors.InvalidDigit, buildPosition(pos, lineStart, curLine), {
|
|
radix
|
|
});
|
|
return true;
|
|
},
|
|
numericSeparatorInEscapeSequence: this.errorBuilder(Errors.NumericSeparatorInEscapeSequence),
|
|
unexpectedNumericSeparator: this.errorBuilder(Errors.UnexpectedNumericSeparator)
|
|
};
|
|
this.errorHandlers_readCodePoint = Object.assign({}, this.errorHandlers_readInt, {
|
|
invalidEscapeSequence: this.errorBuilder(Errors.InvalidEscapeSequence),
|
|
invalidCodePoint: this.errorBuilder(Errors.InvalidCodePoint)
|
|
});
|
|
this.errorHandlers_readStringContents_string = Object.assign({}, this.errorHandlers_readCodePoint, {
|
|
strictNumericEscape: (pos, lineStart, curLine) => {
|
|
this.recordStrictModeErrors(Errors.StrictNumericEscape, buildPosition(pos, lineStart, curLine));
|
|
},
|
|
unterminated: (pos, lineStart, curLine) => {
|
|
throw this.raise(Errors.UnterminatedString, buildPosition(pos - 1, lineStart, curLine));
|
|
}
|
|
});
|
|
this.errorHandlers_readStringContents_template = Object.assign({}, this.errorHandlers_readCodePoint, {
|
|
strictNumericEscape: this.errorBuilder(Errors.StrictNumericEscape),
|
|
unterminated: (pos, lineStart, curLine) => {
|
|
throw this.raise(Errors.UnterminatedTemplate, buildPosition(pos, lineStart, curLine));
|
|
}
|
|
});
|
|
this.state = new State();
|
|
this.state.init(options);
|
|
this.input = input;
|
|
this.length = input.length;
|
|
this.comments = [];
|
|
this.isLookahead = false;
|
|
}
|
|
pushToken(token) {
|
|
this.tokens.length = this.state.tokensLength;
|
|
this.tokens.push(token);
|
|
++this.state.tokensLength;
|
|
}
|
|
next() {
|
|
this.checkKeywordEscapes();
|
|
if (this.optionFlags & 256) {
|
|
this.pushToken(new Token(this.state));
|
|
}
|
|
this.state.lastTokEndLoc = this.state.endLoc;
|
|
this.state.lastTokStartLoc = this.state.startLoc;
|
|
this.nextToken();
|
|
}
|
|
eat(type) {
|
|
if (this.match(type)) {
|
|
this.next();
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
match(type) {
|
|
return this.state.type === type;
|
|
}
|
|
createLookaheadState(state) {
|
|
return {
|
|
pos: state.pos,
|
|
value: null,
|
|
type: state.type,
|
|
start: state.start,
|
|
end: state.end,
|
|
context: [this.curContext()],
|
|
inType: state.inType,
|
|
startLoc: state.startLoc,
|
|
lastTokEndLoc: state.lastTokEndLoc,
|
|
curLine: state.curLine,
|
|
lineStart: state.lineStart,
|
|
curPosition: state.curPosition
|
|
};
|
|
}
|
|
lookahead() {
|
|
const old = this.state;
|
|
this.state = this.createLookaheadState(old);
|
|
this.isLookahead = true;
|
|
this.nextToken();
|
|
this.isLookahead = false;
|
|
const curr = this.state;
|
|
this.state = old;
|
|
return curr;
|
|
}
|
|
nextTokenStart() {
|
|
return this.nextTokenStartSince(this.state.pos);
|
|
}
|
|
nextTokenStartSince(pos) {
|
|
skipWhiteSpace.lastIndex = pos;
|
|
return skipWhiteSpace.test(this.input) ? skipWhiteSpace.lastIndex : pos;
|
|
}
|
|
lookaheadCharCode() {
|
|
return this.lookaheadCharCodeSince(this.state.pos);
|
|
}
|
|
lookaheadCharCodeSince(pos) {
|
|
return this.input.charCodeAt(this.nextTokenStartSince(pos));
|
|
}
|
|
nextTokenInLineStart() {
|
|
return this.nextTokenInLineStartSince(this.state.pos);
|
|
}
|
|
nextTokenInLineStartSince(pos) {
|
|
skipWhiteSpaceInLine.lastIndex = pos;
|
|
return skipWhiteSpaceInLine.test(this.input) ? skipWhiteSpaceInLine.lastIndex : pos;
|
|
}
|
|
lookaheadInLineCharCode() {
|
|
return this.input.charCodeAt(this.nextTokenInLineStart());
|
|
}
|
|
codePointAtPos(pos) {
|
|
let cp = this.input.charCodeAt(pos);
|
|
if ((cp & 0xfc00) === 0xd800 && ++pos < this.input.length) {
|
|
const trail = this.input.charCodeAt(pos);
|
|
if ((trail & 0xfc00) === 0xdc00) {
|
|
cp = 0x10000 + ((cp & 0x3ff) << 10) + (trail & 0x3ff);
|
|
}
|
|
}
|
|
return cp;
|
|
}
|
|
setStrict(strict) {
|
|
this.state.strict = strict;
|
|
if (strict) {
|
|
this.state.strictErrors.forEach(([toParseError, at]) => this.raise(toParseError, at));
|
|
this.state.strictErrors.clear();
|
|
}
|
|
}
|
|
curContext() {
|
|
return this.state.context[this.state.context.length - 1];
|
|
}
|
|
nextToken() {
|
|
this.skipSpace();
|
|
this.state.start = this.state.pos;
|
|
if (!this.isLookahead) this.state.startLoc = this.state.curPosition();
|
|
if (this.state.pos >= this.length) {
|
|
this.finishToken(140);
|
|
return;
|
|
}
|
|
this.getTokenFromCode(this.codePointAtPos(this.state.pos));
|
|
}
|
|
skipBlockComment(commentEnd) {
|
|
let startLoc;
|
|
if (!this.isLookahead) startLoc = this.state.curPosition();
|
|
const start = this.state.pos;
|
|
const end = this.input.indexOf(commentEnd, start + 2);
|
|
if (end === -1) {
|
|
throw this.raise(Errors.UnterminatedComment, this.state.curPosition());
|
|
}
|
|
this.state.pos = end + commentEnd.length;
|
|
lineBreakG.lastIndex = start + 2;
|
|
while (lineBreakG.test(this.input) && lineBreakG.lastIndex <= end) {
|
|
++this.state.curLine;
|
|
this.state.lineStart = lineBreakG.lastIndex;
|
|
}
|
|
if (this.isLookahead) return;
|
|
const comment = {
|
|
type: "CommentBlock",
|
|
value: this.input.slice(start + 2, end),
|
|
start: this.sourceToOffsetPos(start),
|
|
end: this.sourceToOffsetPos(end + commentEnd.length),
|
|
loc: new SourceLocation(startLoc, this.state.curPosition())
|
|
};
|
|
if (this.optionFlags & 256) this.pushToken(comment);
|
|
return comment;
|
|
}
|
|
skipLineComment(startSkip) {
|
|
const start = this.state.pos;
|
|
let startLoc;
|
|
if (!this.isLookahead) startLoc = this.state.curPosition();
|
|
let ch = this.input.charCodeAt(this.state.pos += startSkip);
|
|
if (this.state.pos < this.length) {
|
|
while (!isNewLine(ch) && ++this.state.pos < this.length) {
|
|
ch = this.input.charCodeAt(this.state.pos);
|
|
}
|
|
}
|
|
if (this.isLookahead) return;
|
|
const end = this.state.pos;
|
|
const value = this.input.slice(start + startSkip, end);
|
|
const comment = {
|
|
type: "CommentLine",
|
|
value,
|
|
start: this.sourceToOffsetPos(start),
|
|
end: this.sourceToOffsetPos(end),
|
|
loc: new SourceLocation(startLoc, this.state.curPosition())
|
|
};
|
|
if (this.optionFlags & 256) this.pushToken(comment);
|
|
return comment;
|
|
}
|
|
skipSpace() {
|
|
const spaceStart = this.state.pos;
|
|
const comments = this.optionFlags & 4096 ? [] : null;
|
|
loop: while (this.state.pos < this.length) {
|
|
const ch = this.input.charCodeAt(this.state.pos);
|
|
switch (ch) {
|
|
case 32:
|
|
case 160:
|
|
case 9:
|
|
++this.state.pos;
|
|
break;
|
|
case 13:
|
|
if (this.input.charCodeAt(this.state.pos + 1) === 10) {
|
|
++this.state.pos;
|
|
}
|
|
case 10:
|
|
case 8232:
|
|
case 8233:
|
|
++this.state.pos;
|
|
++this.state.curLine;
|
|
this.state.lineStart = this.state.pos;
|
|
break;
|
|
case 47:
|
|
switch (this.input.charCodeAt(this.state.pos + 1)) {
|
|
case 42:
|
|
{
|
|
const comment = this.skipBlockComment("*/");
|
|
if (comment !== undefined) {
|
|
this.addComment(comment);
|
|
comments == null || comments.push(comment);
|
|
}
|
|
break;
|
|
}
|
|
case 47:
|
|
{
|
|
const comment = this.skipLineComment(2);
|
|
if (comment !== undefined) {
|
|
this.addComment(comment);
|
|
comments == null || comments.push(comment);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
break loop;
|
|
}
|
|
break;
|
|
default:
|
|
if (isWhitespace(ch)) {
|
|
++this.state.pos;
|
|
} else if (ch === 45 && !this.inModule && this.optionFlags & 8192) {
|
|
const pos = this.state.pos;
|
|
if (this.input.charCodeAt(pos + 1) === 45 && this.input.charCodeAt(pos + 2) === 62 && (spaceStart === 0 || this.state.lineStart > spaceStart)) {
|
|
const comment = this.skipLineComment(3);
|
|
if (comment !== undefined) {
|
|
this.addComment(comment);
|
|
comments == null || comments.push(comment);
|
|
}
|
|
} else {
|
|
break loop;
|
|
}
|
|
} else if (ch === 60 && !this.inModule && this.optionFlags & 8192) {
|
|
const pos = this.state.pos;
|
|
if (this.input.charCodeAt(pos + 1) === 33 && this.input.charCodeAt(pos + 2) === 45 && this.input.charCodeAt(pos + 3) === 45) {
|
|
const comment = this.skipLineComment(4);
|
|
if (comment !== undefined) {
|
|
this.addComment(comment);
|
|
comments == null || comments.push(comment);
|
|
}
|
|
} else {
|
|
break loop;
|
|
}
|
|
} else {
|
|
break loop;
|
|
}
|
|
}
|
|
}
|
|
if ((comments == null ? void 0 : comments.length) > 0) {
|
|
const end = this.state.pos;
|
|
const commentWhitespace = {
|
|
start: this.sourceToOffsetPos(spaceStart),
|
|
end: this.sourceToOffsetPos(end),
|
|
comments: comments,
|
|
leadingNode: null,
|
|
trailingNode: null,
|
|
containingNode: null
|
|
};
|
|
this.state.commentStack.push(commentWhitespace);
|
|
}
|
|
}
|
|
finishToken(type, val) {
|
|
this.state.end = this.state.pos;
|
|
this.state.endLoc = this.state.curPosition();
|
|
const prevType = this.state.type;
|
|
this.state.type = type;
|
|
this.state.value = val;
|
|
if (!this.isLookahead) {
|
|
this.updateContext(prevType);
|
|
}
|
|
}
|
|
replaceToken(type) {
|
|
this.state.type = type;
|
|
this.updateContext();
|
|
}
|
|
readToken_numberSign() {
|
|
if (this.state.pos === 0 && this.readToken_interpreter()) {
|
|
return;
|
|
}
|
|
const nextPos = this.state.pos + 1;
|
|
const next = this.codePointAtPos(nextPos);
|
|
if (next >= 48 && next <= 57) {
|
|
throw this.raise(Errors.UnexpectedDigitAfterHash, this.state.curPosition());
|
|
}
|
|
if (next === 123 || next === 91 && this.hasPlugin("recordAndTuple")) {
|
|
this.expectPlugin("recordAndTuple");
|
|
if (this.getPluginOption("recordAndTuple", "syntaxType") === "bar") {
|
|
throw this.raise(next === 123 ? Errors.RecordExpressionHashIncorrectStartSyntaxType : Errors.TupleExpressionHashIncorrectStartSyntaxType, this.state.curPosition());
|
|
}
|
|
this.state.pos += 2;
|
|
if (next === 123) {
|
|
this.finishToken(7);
|
|
} else {
|
|
this.finishToken(1);
|
|
}
|
|
} else if (isIdentifierStart(next)) {
|
|
++this.state.pos;
|
|
this.finishToken(139, this.readWord1(next));
|
|
} else if (next === 92) {
|
|
++this.state.pos;
|
|
this.finishToken(139, this.readWord1());
|
|
} else {
|
|
this.finishOp(27, 1);
|
|
}
|
|
}
|
|
readToken_dot() {
|
|
const next = this.input.charCodeAt(this.state.pos + 1);
|
|
if (next >= 48 && next <= 57) {
|
|
this.readNumber(true);
|
|
return;
|
|
}
|
|
if (next === 46 && this.input.charCodeAt(this.state.pos + 2) === 46) {
|
|
this.state.pos += 3;
|
|
this.finishToken(21);
|
|
} else {
|
|
++this.state.pos;
|
|
this.finishToken(16);
|
|
}
|
|
}
|
|
readToken_slash() {
|
|
const next = this.input.charCodeAt(this.state.pos + 1);
|
|
if (next === 61) {
|
|
this.finishOp(31, 2);
|
|
} else {
|
|
this.finishOp(56, 1);
|
|
}
|
|
}
|
|
readToken_interpreter() {
|
|
if (this.state.pos !== 0 || this.length < 2) return false;
|
|
let ch = this.input.charCodeAt(this.state.pos + 1);
|
|
if (ch !== 33) return false;
|
|
const start = this.state.pos;
|
|
this.state.pos += 1;
|
|
while (!isNewLine(ch) && ++this.state.pos < this.length) {
|
|
ch = this.input.charCodeAt(this.state.pos);
|
|
}
|
|
const value = this.input.slice(start + 2, this.state.pos);
|
|
this.finishToken(28, value);
|
|
return true;
|
|
}
|
|
readToken_mult_modulo(code) {
|
|
let type = code === 42 ? 55 : 54;
|
|
let width = 1;
|
|
let next = this.input.charCodeAt(this.state.pos + 1);
|
|
if (code === 42 && next === 42) {
|
|
width++;
|
|
next = this.input.charCodeAt(this.state.pos + 2);
|
|
type = 57;
|
|
}
|
|
if (next === 61 && !this.state.inType) {
|
|
width++;
|
|
type = code === 37 ? 33 : 30;
|
|
}
|
|
this.finishOp(type, width);
|
|
}
|
|
readToken_pipe_amp(code) {
|
|
const next = this.input.charCodeAt(this.state.pos + 1);
|
|
if (next === code) {
|
|
if (this.input.charCodeAt(this.state.pos + 2) === 61) {
|
|
this.finishOp(30, 3);
|
|
} else {
|
|
this.finishOp(code === 124 ? 41 : 42, 2);
|
|
}
|
|
return;
|
|
}
|
|
if (code === 124) {
|
|
if (next === 62) {
|
|
this.finishOp(39, 2);
|
|
return;
|
|
}
|
|
if (this.hasPlugin("recordAndTuple") && next === 125) {
|
|
if (this.getPluginOption("recordAndTuple", "syntaxType") !== "bar") {
|
|
throw this.raise(Errors.RecordExpressionBarIncorrectEndSyntaxType, this.state.curPosition());
|
|
}
|
|
this.state.pos += 2;
|
|
this.finishToken(9);
|
|
return;
|
|
}
|
|
if (this.hasPlugin("recordAndTuple") && next === 93) {
|
|
if (this.getPluginOption("recordAndTuple", "syntaxType") !== "bar") {
|
|
throw this.raise(Errors.TupleExpressionBarIncorrectEndSyntaxType, this.state.curPosition());
|
|
}
|
|
this.state.pos += 2;
|
|
this.finishToken(4);
|
|
return;
|
|
}
|
|
}
|
|
if (next === 61) {
|
|
this.finishOp(30, 2);
|
|
return;
|
|
}
|
|
this.finishOp(code === 124 ? 43 : 45, 1);
|
|
}
|
|
readToken_caret() {
|
|
const next = this.input.charCodeAt(this.state.pos + 1);
|
|
if (next === 61 && !this.state.inType) {
|
|
this.finishOp(32, 2);
|
|
} else if (next === 94 && this.hasPlugin(["pipelineOperator", {
|
|
proposal: "hack",
|
|
topicToken: "^^"
|
|
}])) {
|
|
this.finishOp(37, 2);
|
|
const lookaheadCh = this.input.codePointAt(this.state.pos);
|
|
if (lookaheadCh === 94) {
|
|
this.unexpected();
|
|
}
|
|
} else {
|
|
this.finishOp(44, 1);
|
|
}
|
|
}
|
|
readToken_atSign() {
|
|
const next = this.input.charCodeAt(this.state.pos + 1);
|
|
if (next === 64 && this.hasPlugin(["pipelineOperator", {
|
|
proposal: "hack",
|
|
topicToken: "@@"
|
|
}])) {
|
|
this.finishOp(38, 2);
|
|
} else {
|
|
this.finishOp(26, 1);
|
|
}
|
|
}
|
|
readToken_plus_min(code) {
|
|
const next = this.input.charCodeAt(this.state.pos + 1);
|
|
if (next === code) {
|
|
this.finishOp(34, 2);
|
|
return;
|
|
}
|
|
if (next === 61) {
|
|
this.finishOp(30, 2);
|
|
} else {
|
|
this.finishOp(53, 1);
|
|
}
|
|
}
|
|
readToken_lt() {
|
|
const {
|
|
pos
|
|
} = this.state;
|
|
const next = this.input.charCodeAt(pos + 1);
|
|
if (next === 60) {
|
|
if (this.input.charCodeAt(pos + 2) === 61) {
|
|
this.finishOp(30, 3);
|
|
return;
|
|
}
|
|
this.finishOp(51, 2);
|
|
return;
|
|
}
|
|
if (next === 61) {
|
|
this.finishOp(49, 2);
|
|
return;
|
|
}
|
|
this.finishOp(47, 1);
|
|
}
|
|
readToken_gt() {
|
|
const {
|
|
pos
|
|
} = this.state;
|
|
const next = this.input.charCodeAt(pos + 1);
|
|
if (next === 62) {
|
|
const size = this.input.charCodeAt(pos + 2) === 62 ? 3 : 2;
|
|
if (this.input.charCodeAt(pos + size) === 61) {
|
|
this.finishOp(30, size + 1);
|
|
return;
|
|
}
|
|
this.finishOp(52, size);
|
|
return;
|
|
}
|
|
if (next === 61) {
|
|
this.finishOp(49, 2);
|
|
return;
|
|
}
|
|
this.finishOp(48, 1);
|
|
}
|
|
readToken_eq_excl(code) {
|
|
const next = this.input.charCodeAt(this.state.pos + 1);
|
|
if (next === 61) {
|
|
this.finishOp(46, this.input.charCodeAt(this.state.pos + 2) === 61 ? 3 : 2);
|
|
return;
|
|
}
|
|
if (code === 61 && next === 62) {
|
|
this.state.pos += 2;
|
|
this.finishToken(19);
|
|
return;
|
|
}
|
|
this.finishOp(code === 61 ? 29 : 35, 1);
|
|
}
|
|
readToken_question() {
|
|
const next = this.input.charCodeAt(this.state.pos + 1);
|
|
const next2 = this.input.charCodeAt(this.state.pos + 2);
|
|
if (next === 63) {
|
|
if (next2 === 61) {
|
|
this.finishOp(30, 3);
|
|
} else {
|
|
this.finishOp(40, 2);
|
|
}
|
|
} else if (next === 46 && !(next2 >= 48 && next2 <= 57)) {
|
|
this.state.pos += 2;
|
|
this.finishToken(18);
|
|
} else {
|
|
++this.state.pos;
|
|
this.finishToken(17);
|
|
}
|
|
}
|
|
getTokenFromCode(code) {
|
|
switch (code) {
|
|
case 46:
|
|
this.readToken_dot();
|
|
return;
|
|
case 40:
|
|
++this.state.pos;
|
|
this.finishToken(10);
|
|
return;
|
|
case 41:
|
|
++this.state.pos;
|
|
this.finishToken(11);
|
|
return;
|
|
case 59:
|
|
++this.state.pos;
|
|
this.finishToken(13);
|
|
return;
|
|
case 44:
|
|
++this.state.pos;
|
|
this.finishToken(12);
|
|
return;
|
|
case 91:
|
|
if (this.hasPlugin("recordAndTuple") && this.input.charCodeAt(this.state.pos + 1) === 124) {
|
|
if (this.getPluginOption("recordAndTuple", "syntaxType") !== "bar") {
|
|
throw this.raise(Errors.TupleExpressionBarIncorrectStartSyntaxType, this.state.curPosition());
|
|
}
|
|
this.state.pos += 2;
|
|
this.finishToken(2);
|
|
} else {
|
|
++this.state.pos;
|
|
this.finishToken(0);
|
|
}
|
|
return;
|
|
case 93:
|
|
++this.state.pos;
|
|
this.finishToken(3);
|
|
return;
|
|
case 123:
|
|
if (this.hasPlugin("recordAndTuple") && this.input.charCodeAt(this.state.pos + 1) === 124) {
|
|
if (this.getPluginOption("recordAndTuple", "syntaxType") !== "bar") {
|
|
throw this.raise(Errors.RecordExpressionBarIncorrectStartSyntaxType, this.state.curPosition());
|
|
}
|
|
this.state.pos += 2;
|
|
this.finishToken(6);
|
|
} else {
|
|
++this.state.pos;
|
|
this.finishToken(5);
|
|
}
|
|
return;
|
|
case 125:
|
|
++this.state.pos;
|
|
this.finishToken(8);
|
|
return;
|
|
case 58:
|
|
if (this.hasPlugin("functionBind") && this.input.charCodeAt(this.state.pos + 1) === 58) {
|
|
this.finishOp(15, 2);
|
|
} else {
|
|
++this.state.pos;
|
|
this.finishToken(14);
|
|
}
|
|
return;
|
|
case 63:
|
|
this.readToken_question();
|
|
return;
|
|
case 96:
|
|
this.readTemplateToken();
|
|
return;
|
|
case 48:
|
|
{
|
|
const next = this.input.charCodeAt(this.state.pos + 1);
|
|
if (next === 120 || next === 88) {
|
|
this.readRadixNumber(16);
|
|
return;
|
|
}
|
|
if (next === 111 || next === 79) {
|
|
this.readRadixNumber(8);
|
|
return;
|
|
}
|
|
if (next === 98 || next === 66) {
|
|
this.readRadixNumber(2);
|
|
return;
|
|
}
|
|
}
|
|
case 49:
|
|
case 50:
|
|
case 51:
|
|
case 52:
|
|
case 53:
|
|
case 54:
|
|
case 55:
|
|
case 56:
|
|
case 57:
|
|
this.readNumber(false);
|
|
return;
|
|
case 34:
|
|
case 39:
|
|
this.readString(code);
|
|
return;
|
|
case 47:
|
|
this.readToken_slash();
|
|
return;
|
|
case 37:
|
|
case 42:
|
|
this.readToken_mult_modulo(code);
|
|
return;
|
|
case 124:
|
|
case 38:
|
|
this.readToken_pipe_amp(code);
|
|
return;
|
|
case 94:
|
|
this.readToken_caret();
|
|
return;
|
|
case 43:
|
|
case 45:
|
|
this.readToken_plus_min(code);
|
|
return;
|
|
case 60:
|
|
this.readToken_lt();
|
|
return;
|
|
case 62:
|
|
this.readToken_gt();
|
|
return;
|
|
case 61:
|
|
case 33:
|
|
this.readToken_eq_excl(code);
|
|
return;
|
|
case 126:
|
|
this.finishOp(36, 1);
|
|
return;
|
|
case 64:
|
|
this.readToken_atSign();
|
|
return;
|
|
case 35:
|
|
this.readToken_numberSign();
|
|
return;
|
|
case 92:
|
|
this.readWord();
|
|
return;
|
|
default:
|
|
if (isIdentifierStart(code)) {
|
|
this.readWord(code);
|
|
return;
|
|
}
|
|
}
|
|
throw this.raise(Errors.InvalidOrUnexpectedToken, this.state.curPosition(), {
|
|
unexpected: String.fromCodePoint(code)
|
|
});
|
|
}
|
|
finishOp(type, size) {
|
|
const str = this.input.slice(this.state.pos, this.state.pos + size);
|
|
this.state.pos += size;
|
|
this.finishToken(type, str);
|
|
}
|
|
readRegexp() {
|
|
const startLoc = this.state.startLoc;
|
|
const start = this.state.start + 1;
|
|
let escaped, inClass;
|
|
let {
|
|
pos
|
|
} = this.state;
|
|
for (;; ++pos) {
|
|
if (pos >= this.length) {
|
|
throw this.raise(Errors.UnterminatedRegExp, createPositionWithColumnOffset(startLoc, 1));
|
|
}
|
|
const ch = this.input.charCodeAt(pos);
|
|
if (isNewLine(ch)) {
|
|
throw this.raise(Errors.UnterminatedRegExp, createPositionWithColumnOffset(startLoc, 1));
|
|
}
|
|
if (escaped) {
|
|
escaped = false;
|
|
} else {
|
|
if (ch === 91) {
|
|
inClass = true;
|
|
} else if (ch === 93 && inClass) {
|
|
inClass = false;
|
|
} else if (ch === 47 && !inClass) {
|
|
break;
|
|
}
|
|
escaped = ch === 92;
|
|
}
|
|
}
|
|
const content = this.input.slice(start, pos);
|
|
++pos;
|
|
let mods = "";
|
|
const nextPos = () => createPositionWithColumnOffset(startLoc, pos + 2 - start);
|
|
while (pos < this.length) {
|
|
const cp = this.codePointAtPos(pos);
|
|
const char = String.fromCharCode(cp);
|
|
if (VALID_REGEX_FLAGS.has(cp)) {
|
|
if (cp === 118) {
|
|
if (mods.includes("u")) {
|
|
this.raise(Errors.IncompatibleRegExpUVFlags, nextPos());
|
|
}
|
|
} else if (cp === 117) {
|
|
if (mods.includes("v")) {
|
|
this.raise(Errors.IncompatibleRegExpUVFlags, nextPos());
|
|
}
|
|
}
|
|
if (mods.includes(char)) {
|
|
this.raise(Errors.DuplicateRegExpFlags, nextPos());
|
|
}
|
|
} else if (isIdentifierChar(cp) || cp === 92) {
|
|
this.raise(Errors.MalformedRegExpFlags, nextPos());
|
|
} else {
|
|
break;
|
|
}
|
|
++pos;
|
|
mods += char;
|
|
}
|
|
this.state.pos = pos;
|
|
this.finishToken(138, {
|
|
pattern: content,
|
|
flags: mods
|
|
});
|
|
}
|
|
readInt(radix, len, forceLen = false, allowNumSeparator = true) {
|
|
const {
|
|
n,
|
|
pos
|
|
} = readInt(this.input, this.state.pos, this.state.lineStart, this.state.curLine, radix, len, forceLen, allowNumSeparator, this.errorHandlers_readInt, false);
|
|
this.state.pos = pos;
|
|
return n;
|
|
}
|
|
readRadixNumber(radix) {
|
|
const start = this.state.pos;
|
|
const startLoc = this.state.curPosition();
|
|
let isBigInt = false;
|
|
this.state.pos += 2;
|
|
const val = this.readInt(radix);
|
|
if (val == null) {
|
|
this.raise(Errors.InvalidDigit, createPositionWithColumnOffset(startLoc, 2), {
|
|
radix
|
|
});
|
|
}
|
|
const next = this.input.charCodeAt(this.state.pos);
|
|
if (next === 110) {
|
|
++this.state.pos;
|
|
isBigInt = true;
|
|
} else if (next === 109) {
|
|
throw this.raise(Errors.InvalidDecimal, startLoc);
|
|
}
|
|
if (isIdentifierStart(this.codePointAtPos(this.state.pos))) {
|
|
throw this.raise(Errors.NumberIdentifier, this.state.curPosition());
|
|
}
|
|
if (isBigInt) {
|
|
const str = this.input.slice(start, this.state.pos).replace(/[_n]/g, "");
|
|
this.finishToken(136, str);
|
|
return;
|
|
}
|
|
this.finishToken(135, val);
|
|
}
|
|
readNumber(startsWithDot) {
|
|
const start = this.state.pos;
|
|
const startLoc = this.state.curPosition();
|
|
let isFloat = false;
|
|
let isBigInt = false;
|
|
let hasExponent = false;
|
|
let isOctal = false;
|
|
if (!startsWithDot && this.readInt(10) === null) {
|
|
this.raise(Errors.InvalidNumber, this.state.curPosition());
|
|
}
|
|
const hasLeadingZero = this.state.pos - start >= 2 && this.input.charCodeAt(start) === 48;
|
|
if (hasLeadingZero) {
|
|
const integer = this.input.slice(start, this.state.pos);
|
|
this.recordStrictModeErrors(Errors.StrictOctalLiteral, startLoc);
|
|
if (!this.state.strict) {
|
|
const underscorePos = integer.indexOf("_");
|
|
if (underscorePos > 0) {
|
|
this.raise(Errors.ZeroDigitNumericSeparator, createPositionWithColumnOffset(startLoc, underscorePos));
|
|
}
|
|
}
|
|
isOctal = hasLeadingZero && !/[89]/.test(integer);
|
|
}
|
|
let next = this.input.charCodeAt(this.state.pos);
|
|
if (next === 46 && !isOctal) {
|
|
++this.state.pos;
|
|
this.readInt(10);
|
|
isFloat = true;
|
|
next = this.input.charCodeAt(this.state.pos);
|
|
}
|
|
if ((next === 69 || next === 101) && !isOctal) {
|
|
next = this.input.charCodeAt(++this.state.pos);
|
|
if (next === 43 || next === 45) {
|
|
++this.state.pos;
|
|
}
|
|
if (this.readInt(10) === null) {
|
|
this.raise(Errors.InvalidOrMissingExponent, startLoc);
|
|
}
|
|
isFloat = true;
|
|
hasExponent = true;
|
|
next = this.input.charCodeAt(this.state.pos);
|
|
}
|
|
if (next === 110) {
|
|
if (isFloat || hasLeadingZero) {
|
|
this.raise(Errors.InvalidBigIntLiteral, startLoc);
|
|
}
|
|
++this.state.pos;
|
|
isBigInt = true;
|
|
}
|
|
if (next === 109) {
|
|
this.expectPlugin("decimal", this.state.curPosition());
|
|
if (hasExponent || hasLeadingZero) {
|
|
this.raise(Errors.InvalidDecimal, startLoc);
|
|
}
|
|
++this.state.pos;
|
|
var isDecimal = true;
|
|
}
|
|
if (isIdentifierStart(this.codePointAtPos(this.state.pos))) {
|
|
throw this.raise(Errors.NumberIdentifier, this.state.curPosition());
|
|
}
|
|
const str = this.input.slice(start, this.state.pos).replace(/[_mn]/g, "");
|
|
if (isBigInt) {
|
|
this.finishToken(136, str);
|
|
return;
|
|
}
|
|
if (isDecimal) {
|
|
this.finishToken(137, str);
|
|
return;
|
|
}
|
|
const val = isOctal ? parseInt(str, 8) : parseFloat(str);
|
|
this.finishToken(135, val);
|
|
}
|
|
readCodePoint(throwOnInvalid) {
|
|
const {
|
|
code,
|
|
pos
|
|
} = readCodePoint(this.input, this.state.pos, this.state.lineStart, this.state.curLine, throwOnInvalid, this.errorHandlers_readCodePoint);
|
|
this.state.pos = pos;
|
|
return code;
|
|
}
|
|
readString(quote) {
|
|
const {
|
|
str,
|
|
pos,
|
|
curLine,
|
|
lineStart
|
|
} = readStringContents(quote === 34 ? "double" : "single", this.input, this.state.pos + 1, this.state.lineStart, this.state.curLine, this.errorHandlers_readStringContents_string);
|
|
this.state.pos = pos + 1;
|
|
this.state.lineStart = lineStart;
|
|
this.state.curLine = curLine;
|
|
this.finishToken(134, str);
|
|
}
|
|
readTemplateContinuation() {
|
|
if (!this.match(8)) {
|
|
this.unexpected(null, 8);
|
|
}
|
|
this.state.pos--;
|
|
this.readTemplateToken();
|
|
}
|
|
readTemplateToken() {
|
|
const opening = this.input[this.state.pos];
|
|
const {
|
|
str,
|
|
firstInvalidLoc,
|
|
pos,
|
|
curLine,
|
|
lineStart
|
|
} = readStringContents("template", this.input, this.state.pos + 1, this.state.lineStart, this.state.curLine, this.errorHandlers_readStringContents_template);
|
|
this.state.pos = pos + 1;
|
|
this.state.lineStart = lineStart;
|
|
this.state.curLine = curLine;
|
|
if (firstInvalidLoc) {
|
|
this.state.firstInvalidTemplateEscapePos = new Position(firstInvalidLoc.curLine, firstInvalidLoc.pos - firstInvalidLoc.lineStart, this.sourceToOffsetPos(firstInvalidLoc.pos));
|
|
}
|
|
if (this.input.codePointAt(pos) === 96) {
|
|
this.finishToken(24, firstInvalidLoc ? null : opening + str + "`");
|
|
} else {
|
|
this.state.pos++;
|
|
this.finishToken(25, firstInvalidLoc ? null : opening + str + "${");
|
|
}
|
|
}
|
|
recordStrictModeErrors(toParseError, at) {
|
|
const index = at.index;
|
|
if (this.state.strict && !this.state.strictErrors.has(index)) {
|
|
this.raise(toParseError, at);
|
|
} else {
|
|
this.state.strictErrors.set(index, [toParseError, at]);
|
|
}
|
|
}
|
|
readWord1(firstCode) {
|
|
this.state.containsEsc = false;
|
|
let word = "";
|
|
const start = this.state.pos;
|
|
let chunkStart = this.state.pos;
|
|
if (firstCode !== undefined) {
|
|
this.state.pos += firstCode <= 0xffff ? 1 : 2;
|
|
}
|
|
while (this.state.pos < this.length) {
|
|
const ch = this.codePointAtPos(this.state.pos);
|
|
if (isIdentifierChar(ch)) {
|
|
this.state.pos += ch <= 0xffff ? 1 : 2;
|
|
} else if (ch === 92) {
|
|
this.state.containsEsc = true;
|
|
word += this.input.slice(chunkStart, this.state.pos);
|
|
const escStart = this.state.curPosition();
|
|
const identifierCheck = this.state.pos === start ? isIdentifierStart : isIdentifierChar;
|
|
if (this.input.charCodeAt(++this.state.pos) !== 117) {
|
|
this.raise(Errors.MissingUnicodeEscape, this.state.curPosition());
|
|
chunkStart = this.state.pos - 1;
|
|
continue;
|
|
}
|
|
++this.state.pos;
|
|
const esc = this.readCodePoint(true);
|
|
if (esc !== null) {
|
|
if (!identifierCheck(esc)) {
|
|
this.raise(Errors.EscapedCharNotAnIdentifier, escStart);
|
|
}
|
|
word += String.fromCodePoint(esc);
|
|
}
|
|
chunkStart = this.state.pos;
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
return word + this.input.slice(chunkStart, this.state.pos);
|
|
}
|
|
readWord(firstCode) {
|
|
const word = this.readWord1(firstCode);
|
|
const type = keywords$1.get(word);
|
|
if (type !== undefined) {
|
|
this.finishToken(type, tokenLabelName(type));
|
|
} else {
|
|
this.finishToken(132, word);
|
|
}
|
|
}
|
|
checkKeywordEscapes() {
|
|
const {
|
|
type
|
|
} = this.state;
|
|
if (tokenIsKeyword(type) && this.state.containsEsc) {
|
|
this.raise(Errors.InvalidEscapedReservedWord, this.state.startLoc, {
|
|
reservedWord: tokenLabelName(type)
|
|
});
|
|
}
|
|
}
|
|
raise(toParseError, at, details = {}) {
|
|
const loc = at instanceof Position ? at : at.loc.start;
|
|
const error = toParseError(loc, details);
|
|
if (!(this.optionFlags & 2048)) throw error;
|
|
if (!this.isLookahead) this.state.errors.push(error);
|
|
return error;
|
|
}
|
|
raiseOverwrite(toParseError, at, details = {}) {
|
|
const loc = at instanceof Position ? at : at.loc.start;
|
|
const pos = loc.index;
|
|
const errors = this.state.errors;
|
|
for (let i = errors.length - 1; i >= 0; i--) {
|
|
const error = errors[i];
|
|
if (error.loc.index === pos) {
|
|
return errors[i] = toParseError(loc, details);
|
|
}
|
|
if (error.loc.index < pos) break;
|
|
}
|
|
return this.raise(toParseError, at, details);
|
|
}
|
|
updateContext(prevType) {}
|
|
unexpected(loc, type) {
|
|
throw this.raise(Errors.UnexpectedToken, loc != null ? loc : this.state.startLoc, {
|
|
expected: type ? tokenLabelName(type) : null
|
|
});
|
|
}
|
|
expectPlugin(pluginName, loc) {
|
|
if (this.hasPlugin(pluginName)) {
|
|
return true;
|
|
}
|
|
throw this.raise(Errors.MissingPlugin, loc != null ? loc : this.state.startLoc, {
|
|
missingPlugin: [pluginName]
|
|
});
|
|
}
|
|
expectOnePlugin(pluginNames) {
|
|
if (!pluginNames.some(name => this.hasPlugin(name))) {
|
|
throw this.raise(Errors.MissingOneOfPlugins, this.state.startLoc, {
|
|
missingPlugin: pluginNames
|
|
});
|
|
}
|
|
}
|
|
errorBuilder(error) {
|
|
return (pos, lineStart, curLine) => {
|
|
this.raise(error, buildPosition(pos, lineStart, curLine));
|
|
};
|
|
}
|
|
}
|
|
class ClassScope {
|
|
constructor() {
|
|
this.privateNames = new Set();
|
|
this.loneAccessors = new Map();
|
|
this.undefinedPrivateNames = new Map();
|
|
}
|
|
}
|
|
class ClassScopeHandler {
|
|
constructor(parser) {
|
|
this.parser = void 0;
|
|
this.stack = [];
|
|
this.undefinedPrivateNames = new Map();
|
|
this.parser = parser;
|
|
}
|
|
current() {
|
|
return this.stack[this.stack.length - 1];
|
|
}
|
|
enter() {
|
|
this.stack.push(new ClassScope());
|
|
}
|
|
exit() {
|
|
const oldClassScope = this.stack.pop();
|
|
const current = this.current();
|
|
for (const [name, loc] of Array.from(oldClassScope.undefinedPrivateNames)) {
|
|
if (current) {
|
|
if (!current.undefinedPrivateNames.has(name)) {
|
|
current.undefinedPrivateNames.set(name, loc);
|
|
}
|
|
} else {
|
|
this.parser.raise(Errors.InvalidPrivateFieldResolution, loc, {
|
|
identifierName: name
|
|
});
|
|
}
|
|
}
|
|
}
|
|
declarePrivateName(name, elementType, loc) {
|
|
const {
|
|
privateNames,
|
|
loneAccessors,
|
|
undefinedPrivateNames
|
|
} = this.current();
|
|
let redefined = privateNames.has(name);
|
|
if (elementType & 3) {
|
|
const accessor = redefined && loneAccessors.get(name);
|
|
if (accessor) {
|
|
const oldStatic = accessor & 4;
|
|
const newStatic = elementType & 4;
|
|
const oldKind = accessor & 3;
|
|
const newKind = elementType & 3;
|
|
redefined = oldKind === newKind || oldStatic !== newStatic;
|
|
if (!redefined) loneAccessors.delete(name);
|
|
} else if (!redefined) {
|
|
loneAccessors.set(name, elementType);
|
|
}
|
|
}
|
|
if (redefined) {
|
|
this.parser.raise(Errors.PrivateNameRedeclaration, loc, {
|
|
identifierName: name
|
|
});
|
|
}
|
|
privateNames.add(name);
|
|
undefinedPrivateNames.delete(name);
|
|
}
|
|
usePrivateName(name, loc) {
|
|
let classScope;
|
|
for (classScope of this.stack) {
|
|
if (classScope.privateNames.has(name)) return;
|
|
}
|
|
if (classScope) {
|
|
classScope.undefinedPrivateNames.set(name, loc);
|
|
} else {
|
|
this.parser.raise(Errors.InvalidPrivateFieldResolution, loc, {
|
|
identifierName: name
|
|
});
|
|
}
|
|
}
|
|
}
|
|
class ExpressionScope {
|
|
constructor(type = 0) {
|
|
this.type = type;
|
|
}
|
|
canBeArrowParameterDeclaration() {
|
|
return this.type === 2 || this.type === 1;
|
|
}
|
|
isCertainlyParameterDeclaration() {
|
|
return this.type === 3;
|
|
}
|
|
}
|
|
class ArrowHeadParsingScope extends ExpressionScope {
|
|
constructor(type) {
|
|
super(type);
|
|
this.declarationErrors = new Map();
|
|
}
|
|
recordDeclarationError(ParsingErrorClass, at) {
|
|
const index = at.index;
|
|
this.declarationErrors.set(index, [ParsingErrorClass, at]);
|
|
}
|
|
clearDeclarationError(index) {
|
|
this.declarationErrors.delete(index);
|
|
}
|
|
iterateErrors(iterator) {
|
|
this.declarationErrors.forEach(iterator);
|
|
}
|
|
}
|
|
class ExpressionScopeHandler {
|
|
constructor(parser) {
|
|
this.parser = void 0;
|
|
this.stack = [new ExpressionScope()];
|
|
this.parser = parser;
|
|
}
|
|
enter(scope) {
|
|
this.stack.push(scope);
|
|
}
|
|
exit() {
|
|
this.stack.pop();
|
|
}
|
|
recordParameterInitializerError(toParseError, node) {
|
|
const origin = node.loc.start;
|
|
const {
|
|
stack
|
|
} = this;
|
|
let i = stack.length - 1;
|
|
let scope = stack[i];
|
|
while (!scope.isCertainlyParameterDeclaration()) {
|
|
if (scope.canBeArrowParameterDeclaration()) {
|
|
scope.recordDeclarationError(toParseError, origin);
|
|
} else {
|
|
return;
|
|
}
|
|
scope = stack[--i];
|
|
}
|
|
this.parser.raise(toParseError, origin);
|
|
}
|
|
recordArrowParameterBindingError(error, node) {
|
|
const {
|
|
stack
|
|
} = this;
|
|
const scope = stack[stack.length - 1];
|
|
const origin = node.loc.start;
|
|
if (scope.isCertainlyParameterDeclaration()) {
|
|
this.parser.raise(error, origin);
|
|
} else if (scope.canBeArrowParameterDeclaration()) {
|
|
scope.recordDeclarationError(error, origin);
|
|
} else {
|
|
return;
|
|
}
|
|
}
|
|
recordAsyncArrowParametersError(at) {
|
|
const {
|
|
stack
|
|
} = this;
|
|
let i = stack.length - 1;
|
|
let scope = stack[i];
|
|
while (scope.canBeArrowParameterDeclaration()) {
|
|
if (scope.type === 2) {
|
|
scope.recordDeclarationError(Errors.AwaitBindingIdentifier, at);
|
|
}
|
|
scope = stack[--i];
|
|
}
|
|
}
|
|
validateAsPattern() {
|
|
const {
|
|
stack
|
|
} = this;
|
|
const currentScope = stack[stack.length - 1];
|
|
if (!currentScope.canBeArrowParameterDeclaration()) return;
|
|
currentScope.iterateErrors(([toParseError, loc]) => {
|
|
this.parser.raise(toParseError, loc);
|
|
let i = stack.length - 2;
|
|
let scope = stack[i];
|
|
while (scope.canBeArrowParameterDeclaration()) {
|
|
scope.clearDeclarationError(loc.index);
|
|
scope = stack[--i];
|
|
}
|
|
});
|
|
}
|
|
}
|
|
function newParameterDeclarationScope() {
|
|
return new ExpressionScope(3);
|
|
}
|
|
function newArrowHeadScope() {
|
|
return new ArrowHeadParsingScope(1);
|
|
}
|
|
function newAsyncArrowScope() {
|
|
return new ArrowHeadParsingScope(2);
|
|
}
|
|
function newExpressionScope() {
|
|
return new ExpressionScope();
|
|
}
|
|
class UtilParser extends Tokenizer {
|
|
addExtra(node, key, value, enumerable = true) {
|
|
if (!node) return;
|
|
let {
|
|
extra
|
|
} = node;
|
|
if (extra == null) {
|
|
extra = {};
|
|
node.extra = extra;
|
|
}
|
|
if (enumerable) {
|
|
extra[key] = value;
|
|
} else {
|
|
Object.defineProperty(extra, key, {
|
|
enumerable,
|
|
value
|
|
});
|
|
}
|
|
}
|
|
isContextual(token) {
|
|
return this.state.type === token && !this.state.containsEsc;
|
|
}
|
|
isUnparsedContextual(nameStart, name) {
|
|
if (this.input.startsWith(name, nameStart)) {
|
|
const nextCh = this.input.charCodeAt(nameStart + name.length);
|
|
return !(isIdentifierChar(nextCh) || (nextCh & 0xfc00) === 0xd800);
|
|
}
|
|
return false;
|
|
}
|
|
isLookaheadContextual(name) {
|
|
const next = this.nextTokenStart();
|
|
return this.isUnparsedContextual(next, name);
|
|
}
|
|
eatContextual(token) {
|
|
if (this.isContextual(token)) {
|
|
this.next();
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
expectContextual(token, toParseError) {
|
|
if (!this.eatContextual(token)) {
|
|
if (toParseError != null) {
|
|
throw this.raise(toParseError, this.state.startLoc);
|
|
}
|
|
this.unexpected(null, token);
|
|
}
|
|
}
|
|
canInsertSemicolon() {
|
|
return this.match(140) || this.match(8) || this.hasPrecedingLineBreak();
|
|
}
|
|
hasPrecedingLineBreak() {
|
|
return hasNewLine(this.input, this.offsetToSourcePos(this.state.lastTokEndLoc.index), this.state.start);
|
|
}
|
|
hasFollowingLineBreak() {
|
|
return hasNewLine(this.input, this.state.end, this.nextTokenStart());
|
|
}
|
|
isLineTerminator() {
|
|
return this.eat(13) || this.canInsertSemicolon();
|
|
}
|
|
semicolon(allowAsi = true) {
|
|
if (allowAsi ? this.isLineTerminator() : this.eat(13)) return;
|
|
this.raise(Errors.MissingSemicolon, this.state.lastTokEndLoc);
|
|
}
|
|
expect(type, loc) {
|
|
if (!this.eat(type)) {
|
|
this.unexpected(loc, type);
|
|
}
|
|
}
|
|
tryParse(fn, oldState = this.state.clone()) {
|
|
const abortSignal = {
|
|
node: null
|
|
};
|
|
try {
|
|
const node = fn((node = null) => {
|
|
abortSignal.node = node;
|
|
throw abortSignal;
|
|
});
|
|
if (this.state.errors.length > oldState.errors.length) {
|
|
const failState = this.state;
|
|
this.state = oldState;
|
|
this.state.tokensLength = failState.tokensLength;
|
|
return {
|
|
node,
|
|
error: failState.errors[oldState.errors.length],
|
|
thrown: false,
|
|
aborted: false,
|
|
failState
|
|
};
|
|
}
|
|
return {
|
|
node: node,
|
|
error: null,
|
|
thrown: false,
|
|
aborted: false,
|
|
failState: null
|
|
};
|
|
} catch (error) {
|
|
const failState = this.state;
|
|
this.state = oldState;
|
|
if (error instanceof SyntaxError) {
|
|
return {
|
|
node: null,
|
|
error,
|
|
thrown: true,
|
|
aborted: false,
|
|
failState
|
|
};
|
|
}
|
|
if (error === abortSignal) {
|
|
return {
|
|
node: abortSignal.node,
|
|
error: null,
|
|
thrown: false,
|
|
aborted: true,
|
|
failState
|
|
};
|
|
}
|
|
throw error;
|
|
}
|
|
}
|
|
checkExpressionErrors(refExpressionErrors, andThrow) {
|
|
if (!refExpressionErrors) return false;
|
|
const {
|
|
shorthandAssignLoc,
|
|
doubleProtoLoc,
|
|
privateKeyLoc,
|
|
optionalParametersLoc,
|
|
voidPatternLoc
|
|
} = refExpressionErrors;
|
|
const hasErrors = !!shorthandAssignLoc || !!doubleProtoLoc || !!optionalParametersLoc || !!privateKeyLoc || !!voidPatternLoc;
|
|
if (!andThrow) {
|
|
return hasErrors;
|
|
}
|
|
if (shorthandAssignLoc != null) {
|
|
this.raise(Errors.InvalidCoverInitializedName, shorthandAssignLoc);
|
|
}
|
|
if (doubleProtoLoc != null) {
|
|
this.raise(Errors.DuplicateProto, doubleProtoLoc);
|
|
}
|
|
if (privateKeyLoc != null) {
|
|
this.raise(Errors.UnexpectedPrivateField, privateKeyLoc);
|
|
}
|
|
if (optionalParametersLoc != null) {
|
|
this.unexpected(optionalParametersLoc);
|
|
}
|
|
if (voidPatternLoc != null) {
|
|
this.raise(Errors.InvalidCoverDiscardElement, voidPatternLoc);
|
|
}
|
|
}
|
|
isLiteralPropertyName() {
|
|
return tokenIsLiteralPropertyName(this.state.type);
|
|
}
|
|
isPrivateName(node) {
|
|
return node.type === "PrivateName";
|
|
}
|
|
getPrivateNameSV(node) {
|
|
return node.id.name;
|
|
}
|
|
hasPropertyAsPrivateName(node) {
|
|
return (node.type === "MemberExpression" || node.type === "OptionalMemberExpression") && this.isPrivateName(node.property);
|
|
}
|
|
isObjectProperty(node) {
|
|
return node.type === "ObjectProperty";
|
|
}
|
|
isObjectMethod(node) {
|
|
return node.type === "ObjectMethod";
|
|
}
|
|
initializeScopes(inModule = this.options.sourceType === "module") {
|
|
const oldLabels = this.state.labels;
|
|
this.state.labels = [];
|
|
const oldExportedIdentifiers = this.exportedIdentifiers;
|
|
this.exportedIdentifiers = new Set();
|
|
const oldInModule = this.inModule;
|
|
this.inModule = inModule;
|
|
const oldScope = this.scope;
|
|
const ScopeHandler = this.getScopeHandler();
|
|
this.scope = new ScopeHandler(this, inModule);
|
|
const oldProdParam = this.prodParam;
|
|
this.prodParam = new ProductionParameterHandler();
|
|
const oldClassScope = this.classScope;
|
|
this.classScope = new ClassScopeHandler(this);
|
|
const oldExpressionScope = this.expressionScope;
|
|
this.expressionScope = new ExpressionScopeHandler(this);
|
|
return () => {
|
|
this.state.labels = oldLabels;
|
|
this.exportedIdentifiers = oldExportedIdentifiers;
|
|
this.inModule = oldInModule;
|
|
this.scope = oldScope;
|
|
this.prodParam = oldProdParam;
|
|
this.classScope = oldClassScope;
|
|
this.expressionScope = oldExpressionScope;
|
|
};
|
|
}
|
|
enterInitialScopes() {
|
|
let paramFlags = 0;
|
|
if (this.inModule || this.optionFlags & 1) {
|
|
paramFlags |= 2;
|
|
}
|
|
if (this.optionFlags & 32) {
|
|
paramFlags |= 1;
|
|
}
|
|
const isCommonJS = !this.inModule && this.options.sourceType === "commonjs";
|
|
if (isCommonJS || this.optionFlags & 2) {
|
|
paramFlags |= 4;
|
|
}
|
|
this.prodParam.enter(paramFlags);
|
|
let scopeFlags = isCommonJS ? 514 : 1;
|
|
if (this.optionFlags & 4) {
|
|
scopeFlags |= 512;
|
|
}
|
|
this.scope.enter(scopeFlags);
|
|
}
|
|
checkDestructuringPrivate(refExpressionErrors) {
|
|
const {
|
|
privateKeyLoc
|
|
} = refExpressionErrors;
|
|
if (privateKeyLoc !== null) {
|
|
this.expectPlugin("destructuringPrivate", privateKeyLoc);
|
|
}
|
|
}
|
|
}
|
|
class ExpressionErrors {
|
|
constructor() {
|
|
this.shorthandAssignLoc = null;
|
|
this.doubleProtoLoc = null;
|
|
this.privateKeyLoc = null;
|
|
this.optionalParametersLoc = null;
|
|
this.voidPatternLoc = null;
|
|
}
|
|
}
|
|
class Node {
|
|
constructor(parser, pos, loc) {
|
|
this.type = "";
|
|
this.start = pos;
|
|
this.end = 0;
|
|
this.loc = new SourceLocation(loc);
|
|
if ((parser == null ? void 0 : parser.optionFlags) & 128) this.range = [pos, 0];
|
|
if (parser != null && parser.filename) this.loc.filename = parser.filename;
|
|
}
|
|
}
|
|
const NodePrototype = Node.prototype;
|
|
{
|
|
NodePrototype.__clone = function () {
|
|
const newNode = new Node(undefined, this.start, this.loc.start);
|
|
const keys = Object.keys(this);
|
|
for (let i = 0, length = keys.length; i < length; i++) {
|
|
const key = keys[i];
|
|
if (key !== "leadingComments" && key !== "trailingComments" && key !== "innerComments") {
|
|
newNode[key] = this[key];
|
|
}
|
|
}
|
|
return newNode;
|
|
};
|
|
}
|
|
class NodeUtils extends UtilParser {
|
|
startNode() {
|
|
const loc = this.state.startLoc;
|
|
return new Node(this, loc.index, loc);
|
|
}
|
|
startNodeAt(loc) {
|
|
return new Node(this, loc.index, loc);
|
|
}
|
|
startNodeAtNode(type) {
|
|
return this.startNodeAt(type.loc.start);
|
|
}
|
|
finishNode(node, type) {
|
|
return this.finishNodeAt(node, type, this.state.lastTokEndLoc);
|
|
}
|
|
finishNodeAt(node, type, endLoc) {
|
|
node.type = type;
|
|
node.end = endLoc.index;
|
|
node.loc.end = endLoc;
|
|
if (this.optionFlags & 128) node.range[1] = endLoc.index;
|
|
if (this.optionFlags & 4096) {
|
|
this.processComment(node);
|
|
}
|
|
return node;
|
|
}
|
|
resetStartLocation(node, startLoc) {
|
|
node.start = startLoc.index;
|
|
node.loc.start = startLoc;
|
|
if (this.optionFlags & 128) node.range[0] = startLoc.index;
|
|
}
|
|
resetEndLocation(node, endLoc = this.state.lastTokEndLoc) {
|
|
node.end = endLoc.index;
|
|
node.loc.end = endLoc;
|
|
if (this.optionFlags & 128) node.range[1] = endLoc.index;
|
|
}
|
|
resetStartLocationFromNode(node, locationNode) {
|
|
this.resetStartLocation(node, locationNode.loc.start);
|
|
}
|
|
castNodeTo(node, type) {
|
|
node.type = type;
|
|
return node;
|
|
}
|
|
cloneIdentifier(node) {
|
|
const {
|
|
type,
|
|
start,
|
|
end,
|
|
loc,
|
|
range,
|
|
name
|
|
} = node;
|
|
const cloned = Object.create(NodePrototype);
|
|
cloned.type = type;
|
|
cloned.start = start;
|
|
cloned.end = end;
|
|
cloned.loc = loc;
|
|
cloned.range = range;
|
|
cloned.name = name;
|
|
if (node.extra) cloned.extra = node.extra;
|
|
return cloned;
|
|
}
|
|
cloneStringLiteral(node) {
|
|
const {
|
|
type,
|
|
start,
|
|
end,
|
|
loc,
|
|
range,
|
|
extra
|
|
} = node;
|
|
const cloned = Object.create(NodePrototype);
|
|
cloned.type = type;
|
|
cloned.start = start;
|
|
cloned.end = end;
|
|
cloned.loc = loc;
|
|
cloned.range = range;
|
|
cloned.extra = extra;
|
|
cloned.value = node.value;
|
|
return cloned;
|
|
}
|
|
}
|
|
const unwrapParenthesizedExpression = node => {
|
|
return node.type === "ParenthesizedExpression" ? unwrapParenthesizedExpression(node.expression) : node;
|
|
};
|
|
class LValParser extends NodeUtils {
|
|
toAssignable(node, isLHS = false) {
|
|
var _node$extra, _node$extra3;
|
|
let parenthesized = undefined;
|
|
if (node.type === "ParenthesizedExpression" || (_node$extra = node.extra) != null && _node$extra.parenthesized) {
|
|
parenthesized = unwrapParenthesizedExpression(node);
|
|
if (isLHS) {
|
|
if (parenthesized.type === "Identifier") {
|
|
this.expressionScope.recordArrowParameterBindingError(Errors.InvalidParenthesizedAssignment, node);
|
|
} else if (parenthesized.type !== "CallExpression" && parenthesized.type !== "MemberExpression" && !this.isOptionalMemberExpression(parenthesized)) {
|
|
this.raise(Errors.InvalidParenthesizedAssignment, node);
|
|
}
|
|
} else {
|
|
this.raise(Errors.InvalidParenthesizedAssignment, node);
|
|
}
|
|
}
|
|
switch (node.type) {
|
|
case "Identifier":
|
|
case "ObjectPattern":
|
|
case "ArrayPattern":
|
|
case "AssignmentPattern":
|
|
case "RestElement":
|
|
case "VoidPattern":
|
|
break;
|
|
case "ObjectExpression":
|
|
this.castNodeTo(node, "ObjectPattern");
|
|
for (let i = 0, length = node.properties.length, last = length - 1; i < length; i++) {
|
|
var _node$extra2;
|
|
const prop = node.properties[i];
|
|
const isLast = i === last;
|
|
this.toAssignableObjectExpressionProp(prop, isLast, isLHS);
|
|
if (isLast && prop.type === "RestElement" && (_node$extra2 = node.extra) != null && _node$extra2.trailingCommaLoc) {
|
|
this.raise(Errors.RestTrailingComma, node.extra.trailingCommaLoc);
|
|
}
|
|
}
|
|
break;
|
|
case "ObjectProperty":
|
|
{
|
|
const {
|
|
key,
|
|
value
|
|
} = node;
|
|
if (this.isPrivateName(key)) {
|
|
this.classScope.usePrivateName(this.getPrivateNameSV(key), key.loc.start);
|
|
}
|
|
this.toAssignable(value, isLHS);
|
|
break;
|
|
}
|
|
case "SpreadElement":
|
|
{
|
|
throw new Error("Internal @babel/parser error (this is a bug, please report it)." + " SpreadElement should be converted by .toAssignable's caller.");
|
|
}
|
|
case "ArrayExpression":
|
|
this.castNodeTo(node, "ArrayPattern");
|
|
this.toAssignableList(node.elements, (_node$extra3 = node.extra) == null ? void 0 : _node$extra3.trailingCommaLoc, isLHS);
|
|
break;
|
|
case "AssignmentExpression":
|
|
if (node.operator !== "=") {
|
|
this.raise(Errors.MissingEqInAssignment, node.left.loc.end);
|
|
}
|
|
this.castNodeTo(node, "AssignmentPattern");
|
|
delete node.operator;
|
|
if (node.left.type === "VoidPattern") {
|
|
this.raise(Errors.VoidPatternInitializer, node.left);
|
|
}
|
|
this.toAssignable(node.left, isLHS);
|
|
break;
|
|
case "ParenthesizedExpression":
|
|
this.toAssignable(parenthesized, isLHS);
|
|
break;
|
|
}
|
|
}
|
|
toAssignableObjectExpressionProp(prop, isLast, isLHS) {
|
|
if (prop.type === "ObjectMethod") {
|
|
this.raise(prop.kind === "get" || prop.kind === "set" ? Errors.PatternHasAccessor : Errors.PatternHasMethod, prop.key);
|
|
} else if (prop.type === "SpreadElement") {
|
|
this.castNodeTo(prop, "RestElement");
|
|
const arg = prop.argument;
|
|
this.checkToRestConversion(arg, false);
|
|
this.toAssignable(arg, isLHS);
|
|
if (!isLast) {
|
|
this.raise(Errors.RestTrailingComma, prop);
|
|
}
|
|
} else {
|
|
this.toAssignable(prop, isLHS);
|
|
}
|
|
}
|
|
toAssignableList(exprList, trailingCommaLoc, isLHS) {
|
|
const end = exprList.length - 1;
|
|
for (let i = 0; i <= end; i++) {
|
|
const elt = exprList[i];
|
|
if (!elt) continue;
|
|
this.toAssignableListItem(exprList, i, isLHS);
|
|
if (elt.type === "RestElement") {
|
|
if (i < end) {
|
|
this.raise(Errors.RestTrailingComma, elt);
|
|
} else if (trailingCommaLoc) {
|
|
this.raise(Errors.RestTrailingComma, trailingCommaLoc);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
toAssignableListItem(exprList, index, isLHS) {
|
|
const node = exprList[index];
|
|
if (node.type === "SpreadElement") {
|
|
this.castNodeTo(node, "RestElement");
|
|
const arg = node.argument;
|
|
this.checkToRestConversion(arg, true);
|
|
this.toAssignable(arg, isLHS);
|
|
} else {
|
|
this.toAssignable(node, isLHS);
|
|
}
|
|
}
|
|
isAssignable(node, isBinding) {
|
|
switch (node.type) {
|
|
case "Identifier":
|
|
case "ObjectPattern":
|
|
case "ArrayPattern":
|
|
case "AssignmentPattern":
|
|
case "RestElement":
|
|
case "VoidPattern":
|
|
return true;
|
|
case "ObjectExpression":
|
|
{
|
|
const last = node.properties.length - 1;
|
|
return node.properties.every((prop, i) => {
|
|
return prop.type !== "ObjectMethod" && (i === last || prop.type !== "SpreadElement") && this.isAssignable(prop);
|
|
});
|
|
}
|
|
case "ObjectProperty":
|
|
return this.isAssignable(node.value);
|
|
case "SpreadElement":
|
|
return this.isAssignable(node.argument);
|
|
case "ArrayExpression":
|
|
return node.elements.every(element => element === null || this.isAssignable(element));
|
|
case "AssignmentExpression":
|
|
return node.operator === "=";
|
|
case "ParenthesizedExpression":
|
|
return this.isAssignable(node.expression);
|
|
case "MemberExpression":
|
|
case "OptionalMemberExpression":
|
|
return !isBinding;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
toReferencedList(exprList, isParenthesizedExpr) {
|
|
return exprList;
|
|
}
|
|
toReferencedListDeep(exprList, isParenthesizedExpr) {
|
|
this.toReferencedList(exprList, isParenthesizedExpr);
|
|
for (const expr of exprList) {
|
|
if ((expr == null ? void 0 : expr.type) === "ArrayExpression") {
|
|
this.toReferencedListDeep(expr.elements);
|
|
}
|
|
}
|
|
}
|
|
parseSpread(refExpressionErrors) {
|
|
const node = this.startNode();
|
|
this.next();
|
|
node.argument = this.parseMaybeAssignAllowIn(refExpressionErrors, undefined);
|
|
return this.finishNode(node, "SpreadElement");
|
|
}
|
|
parseRestBinding() {
|
|
const node = this.startNode();
|
|
this.next();
|
|
const argument = this.parseBindingAtom();
|
|
if (argument.type === "VoidPattern") {
|
|
this.raise(Errors.UnexpectedVoidPattern, argument);
|
|
}
|
|
node.argument = argument;
|
|
return this.finishNode(node, "RestElement");
|
|
}
|
|
parseBindingAtom() {
|
|
switch (this.state.type) {
|
|
case 0:
|
|
{
|
|
const node = this.startNode();
|
|
this.next();
|
|
node.elements = this.parseBindingList(3, 93, 1);
|
|
return this.finishNode(node, "ArrayPattern");
|
|
}
|
|
case 5:
|
|
return this.parseObjectLike(8, true);
|
|
case 88:
|
|
return this.parseVoidPattern(null);
|
|
}
|
|
return this.parseIdentifier();
|
|
}
|
|
parseBindingList(close, closeCharCode, flags) {
|
|
const allowEmpty = flags & 1;
|
|
const elts = [];
|
|
let first = true;
|
|
while (!this.eat(close)) {
|
|
if (first) {
|
|
first = false;
|
|
} else {
|
|
this.expect(12);
|
|
}
|
|
if (allowEmpty && this.match(12)) {
|
|
elts.push(null);
|
|
} else if (this.eat(close)) {
|
|
break;
|
|
} else if (this.match(21)) {
|
|
let rest = this.parseRestBinding();
|
|
if (this.hasPlugin("flow") || flags & 2) {
|
|
rest = this.parseFunctionParamType(rest);
|
|
}
|
|
elts.push(rest);
|
|
if (!this.checkCommaAfterRest(closeCharCode)) {
|
|
this.expect(close);
|
|
break;
|
|
}
|
|
} else {
|
|
const decorators = [];
|
|
if (flags & 2) {
|
|
if (this.match(26) && this.hasPlugin("decorators")) {
|
|
this.raise(Errors.UnsupportedParameterDecorator, this.state.startLoc);
|
|
}
|
|
while (this.match(26)) {
|
|
decorators.push(this.parseDecorator());
|
|
}
|
|
}
|
|
elts.push(this.parseBindingElement(flags, decorators));
|
|
}
|
|
}
|
|
return elts;
|
|
}
|
|
parseBindingRestProperty(prop) {
|
|
this.next();
|
|
if (this.hasPlugin("discardBinding") && this.match(88)) {
|
|
prop.argument = this.parseVoidPattern(null);
|
|
this.raise(Errors.UnexpectedVoidPattern, prop.argument);
|
|
} else {
|
|
prop.argument = this.parseIdentifier();
|
|
}
|
|
this.checkCommaAfterRest(125);
|
|
return this.finishNode(prop, "RestElement");
|
|
}
|
|
parseBindingProperty() {
|
|
const {
|
|
type,
|
|
startLoc
|
|
} = this.state;
|
|
if (type === 21) {
|
|
return this.parseBindingRestProperty(this.startNode());
|
|
}
|
|
const prop = this.startNode();
|
|
if (type === 139) {
|
|
this.expectPlugin("destructuringPrivate", startLoc);
|
|
this.classScope.usePrivateName(this.state.value, startLoc);
|
|
prop.key = this.parsePrivateName();
|
|
} else {
|
|
this.parsePropertyName(prop);
|
|
}
|
|
prop.method = false;
|
|
return this.parseObjPropValue(prop, startLoc, false, false, true, false);
|
|
}
|
|
parseBindingElement(flags, decorators) {
|
|
const left = this.parseMaybeDefault();
|
|
if (this.hasPlugin("flow") || flags & 2) {
|
|
this.parseFunctionParamType(left);
|
|
}
|
|
if (decorators.length) {
|
|
left.decorators = decorators;
|
|
this.resetStartLocationFromNode(left, decorators[0]);
|
|
}
|
|
const elt = this.parseMaybeDefault(left.loc.start, left);
|
|
return elt;
|
|
}
|
|
parseFunctionParamType(param) {
|
|
return param;
|
|
}
|
|
parseMaybeDefault(startLoc, left) {
|
|
startLoc != null ? startLoc : startLoc = this.state.startLoc;
|
|
left = left != null ? left : this.parseBindingAtom();
|
|
if (!this.eat(29)) return left;
|
|
const node = this.startNodeAt(startLoc);
|
|
if (left.type === "VoidPattern") {
|
|
this.raise(Errors.VoidPatternInitializer, left);
|
|
}
|
|
node.left = left;
|
|
node.right = this.parseMaybeAssignAllowIn();
|
|
return this.finishNode(node, "AssignmentPattern");
|
|
}
|
|
isValidLVal(type, disallowCallExpression, isUnparenthesizedInAssign, binding) {
|
|
switch (type) {
|
|
case "AssignmentPattern":
|
|
return "left";
|
|
case "RestElement":
|
|
return "argument";
|
|
case "ObjectProperty":
|
|
return "value";
|
|
case "ParenthesizedExpression":
|
|
return "expression";
|
|
case "ArrayPattern":
|
|
return "elements";
|
|
case "ObjectPattern":
|
|
return "properties";
|
|
case "VoidPattern":
|
|
return true;
|
|
case "CallExpression":
|
|
if (!disallowCallExpression && !this.state.strict && this.optionFlags & 8192) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
isOptionalMemberExpression(expression) {
|
|
return expression.type === "OptionalMemberExpression";
|
|
}
|
|
checkLVal(expression, ancestor, binding = 64, checkClashes = false, strictModeChanged = false, hasParenthesizedAncestor = false, disallowCallExpression = false) {
|
|
var _expression$extra;
|
|
const type = expression.type;
|
|
if (this.isObjectMethod(expression)) return;
|
|
const isOptionalMemberExpression = this.isOptionalMemberExpression(expression);
|
|
if (isOptionalMemberExpression || type === "MemberExpression") {
|
|
if (isOptionalMemberExpression) {
|
|
this.expectPlugin("optionalChainingAssign", expression.loc.start);
|
|
if (ancestor.type !== "AssignmentExpression") {
|
|
this.raise(Errors.InvalidLhsOptionalChaining, expression, {
|
|
ancestor
|
|
});
|
|
}
|
|
}
|
|
if (binding !== 64) {
|
|
this.raise(Errors.InvalidPropertyBindingPattern, expression);
|
|
}
|
|
return;
|
|
}
|
|
if (type === "Identifier") {
|
|
this.checkIdentifier(expression, binding, strictModeChanged);
|
|
const {
|
|
name
|
|
} = expression;
|
|
if (checkClashes) {
|
|
if (checkClashes.has(name)) {
|
|
this.raise(Errors.ParamDupe, expression);
|
|
} else {
|
|
checkClashes.add(name);
|
|
}
|
|
}
|
|
return;
|
|
} else if (type === "VoidPattern" && ancestor.type === "CatchClause") {
|
|
this.raise(Errors.VoidPatternCatchClauseParam, expression);
|
|
}
|
|
const unwrappedExpression = unwrapParenthesizedExpression(expression);
|
|
disallowCallExpression || (disallowCallExpression = unwrappedExpression.type === "CallExpression" && (unwrappedExpression.callee.type === "Import" || unwrappedExpression.callee.type === "Super"));
|
|
const validity = this.isValidLVal(type, disallowCallExpression, !(hasParenthesizedAncestor || (_expression$extra = expression.extra) != null && _expression$extra.parenthesized) && ancestor.type === "AssignmentExpression", binding);
|
|
if (validity === true) return;
|
|
if (validity === false) {
|
|
const ParseErrorClass = binding === 64 ? Errors.InvalidLhs : Errors.InvalidLhsBinding;
|
|
this.raise(ParseErrorClass, expression, {
|
|
ancestor
|
|
});
|
|
return;
|
|
}
|
|
let key, isParenthesizedExpression;
|
|
if (typeof validity === "string") {
|
|
key = validity;
|
|
isParenthesizedExpression = type === "ParenthesizedExpression";
|
|
} else {
|
|
[key, isParenthesizedExpression] = validity;
|
|
}
|
|
const nextAncestor = type === "ArrayPattern" || type === "ObjectPattern" ? {
|
|
type
|
|
} : ancestor;
|
|
const val = expression[key];
|
|
if (Array.isArray(val)) {
|
|
for (const child of val) {
|
|
if (child) {
|
|
this.checkLVal(child, nextAncestor, binding, checkClashes, strictModeChanged, isParenthesizedExpression, true);
|
|
}
|
|
}
|
|
} else if (val) {
|
|
this.checkLVal(val, nextAncestor, binding, checkClashes, strictModeChanged, isParenthesizedExpression, disallowCallExpression);
|
|
}
|
|
}
|
|
checkIdentifier(at, bindingType, strictModeChanged = false) {
|
|
if (this.state.strict && (strictModeChanged ? isStrictBindReservedWord(at.name, this.inModule) : isStrictBindOnlyReservedWord(at.name))) {
|
|
if (bindingType === 64) {
|
|
this.raise(Errors.StrictEvalArguments, at, {
|
|
referenceName: at.name
|
|
});
|
|
} else {
|
|
this.raise(Errors.StrictEvalArgumentsBinding, at, {
|
|
bindingName: at.name
|
|
});
|
|
}
|
|
}
|
|
if (bindingType & 8192 && at.name === "let") {
|
|
this.raise(Errors.LetInLexicalBinding, at);
|
|
}
|
|
if (!(bindingType & 64)) {
|
|
this.declareNameFromIdentifier(at, bindingType);
|
|
}
|
|
}
|
|
declareNameFromIdentifier(identifier, binding) {
|
|
this.scope.declareName(identifier.name, binding, identifier.loc.start);
|
|
}
|
|
checkToRestConversion(node, allowPattern) {
|
|
switch (node.type) {
|
|
case "ParenthesizedExpression":
|
|
this.checkToRestConversion(node.expression, allowPattern);
|
|
break;
|
|
case "Identifier":
|
|
case "MemberExpression":
|
|
break;
|
|
case "ArrayExpression":
|
|
case "ObjectExpression":
|
|
if (allowPattern) break;
|
|
default:
|
|
this.raise(Errors.InvalidRestAssignmentPattern, node);
|
|
}
|
|
}
|
|
checkCommaAfterRest(close) {
|
|
if (!this.match(12)) {
|
|
return false;
|
|
}
|
|
this.raise(this.lookaheadCharCode() === close ? Errors.RestTrailingComma : Errors.ElementAfterRest, this.state.startLoc);
|
|
return true;
|
|
}
|
|
}
|
|
const keywordAndTSRelationalOperator = /in(?:stanceof)?|as|satisfies/y;
|
|
function nonNull(x) {
|
|
if (x == null) {
|
|
throw new Error(`Unexpected ${x} value.`);
|
|
}
|
|
return x;
|
|
}
|
|
function assert(x) {
|
|
if (!x) {
|
|
throw new Error("Assert fail");
|
|
}
|
|
}
|
|
const TSErrors = ParseErrorEnum`typescript`({
|
|
AbstractMethodHasImplementation: ({
|
|
methodName
|
|
}) => `Method '${methodName}' cannot have an implementation because it is marked abstract.`,
|
|
AbstractPropertyHasInitializer: ({
|
|
propertyName
|
|
}) => `Property '${propertyName}' cannot have an initializer because it is marked abstract.`,
|
|
AccessorCannotBeOptional: "An 'accessor' property cannot be declared optional.",
|
|
AccessorCannotDeclareThisParameter: "'get' and 'set' accessors cannot declare 'this' parameters.",
|
|
AccessorCannotHaveTypeParameters: "An accessor cannot have type parameters.",
|
|
ClassMethodHasDeclare: "Class methods cannot have the 'declare' modifier.",
|
|
ClassMethodHasReadonly: "Class methods cannot have the 'readonly' modifier.",
|
|
ConstInitializerMustBeStringOrNumericLiteralOrLiteralEnumReference: "A 'const' initializer in an ambient context must be a string or numeric literal or literal enum reference.",
|
|
ConstructorHasTypeParameters: "Type parameters cannot appear on a constructor declaration.",
|
|
DeclareAccessor: ({
|
|
kind
|
|
}) => `'declare' is not allowed in ${kind}ters.`,
|
|
DeclareClassFieldHasInitializer: "Initializers are not allowed in ambient contexts.",
|
|
DeclareFunctionHasImplementation: "An implementation cannot be declared in ambient contexts.",
|
|
DuplicateAccessibilityModifier: ({
|
|
modifier
|
|
}) => `Accessibility modifier already seen: '${modifier}'.`,
|
|
DuplicateModifier: ({
|
|
modifier
|
|
}) => `Duplicate modifier: '${modifier}'.`,
|
|
EmptyHeritageClauseType: ({
|
|
token
|
|
}) => `'${token}' list cannot be empty.`,
|
|
EmptyTypeArguments: "Type argument list cannot be empty.",
|
|
EmptyTypeParameters: "Type parameter list cannot be empty.",
|
|
ExpectedAmbientAfterExportDeclare: "'export declare' must be followed by an ambient declaration.",
|
|
ImportAliasHasImportType: "An import alias can not use 'import type'.",
|
|
ImportReflectionHasImportType: "An `import module` declaration can not use `type` modifier",
|
|
IncompatibleModifiers: ({
|
|
modifiers
|
|
}) => `'${modifiers[0]}' modifier cannot be used with '${modifiers[1]}' modifier.`,
|
|
IndexSignatureHasAbstract: "Index signatures cannot have the 'abstract' modifier.",
|
|
IndexSignatureHasAccessibility: ({
|
|
modifier
|
|
}) => `Index signatures cannot have an accessibility modifier ('${modifier}').`,
|
|
IndexSignatureHasDeclare: "Index signatures cannot have the 'declare' modifier.",
|
|
IndexSignatureHasOverride: "'override' modifier cannot appear on an index signature.",
|
|
IndexSignatureHasStatic: "Index signatures cannot have the 'static' modifier.",
|
|
InitializerNotAllowedInAmbientContext: "Initializers are not allowed in ambient contexts.",
|
|
InvalidHeritageClauseType: ({
|
|
token
|
|
}) => `'${token}' list can only include identifiers or qualified-names with optional type arguments.`,
|
|
InvalidModifierOnAwaitUsingDeclaration: modifier => `'${modifier}' modifier cannot appear on an await using declaration.`,
|
|
InvalidModifierOnTypeMember: ({
|
|
modifier
|
|
}) => `'${modifier}' modifier cannot appear on a type member.`,
|
|
InvalidModifierOnTypeParameter: ({
|
|
modifier
|
|
}) => `'${modifier}' modifier cannot appear on a type parameter.`,
|
|
InvalidModifierOnTypeParameterPositions: ({
|
|
modifier
|
|
}) => `'${modifier}' modifier can only appear on a type parameter of a class, interface or type alias.`,
|
|
InvalidModifierOnUsingDeclaration: modifier => `'${modifier}' modifier cannot appear on a using declaration.`,
|
|
InvalidModifiersOrder: ({
|
|
orderedModifiers
|
|
}) => `'${orderedModifiers[0]}' modifier must precede '${orderedModifiers[1]}' modifier.`,
|
|
InvalidPropertyAccessAfterInstantiationExpression: "Invalid property access after an instantiation expression. " + "You can either wrap the instantiation expression in parentheses, or delete the type arguments.",
|
|
InvalidTupleMemberLabel: "Tuple members must be labeled with a simple identifier.",
|
|
MissingInterfaceName: "'interface' declarations must be followed by an identifier.",
|
|
NonAbstractClassHasAbstractMethod: "Abstract methods can only appear within an abstract class.",
|
|
NonClassMethodPropertyHasAbstractModifier: "'abstract' modifier can only appear on a class, method, or property declaration.",
|
|
OptionalTypeBeforeRequired: "A required element cannot follow an optional element.",
|
|
OverrideNotInSubClass: "This member cannot have an 'override' modifier because its containing class does not extend another class.",
|
|
PatternIsOptional: "A binding pattern parameter cannot be optional in an implementation signature.",
|
|
PrivateElementHasAbstract: "Private elements cannot have the 'abstract' modifier.",
|
|
PrivateElementHasAccessibility: ({
|
|
modifier
|
|
}) => `Private elements cannot have an accessibility modifier ('${modifier}').`,
|
|
ReadonlyForMethodSignature: "'readonly' modifier can only appear on a property declaration or index signature.",
|
|
ReservedArrowTypeParam: "This syntax is reserved in files with the .mts or .cts extension. Add a trailing comma, as in `<T,>() => ...`.",
|
|
ReservedTypeAssertion: "This syntax is reserved in files with the .mts or .cts extension. Use an `as` expression instead.",
|
|
SetAccessorCannotHaveOptionalParameter: "A 'set' accessor cannot have an optional parameter.",
|
|
SetAccessorCannotHaveRestParameter: "A 'set' accessor cannot have rest parameter.",
|
|
SetAccessorCannotHaveReturnType: "A 'set' accessor cannot have a return type annotation.",
|
|
SingleTypeParameterWithoutTrailingComma: ({
|
|
typeParameterName
|
|
}) => `Single type parameter ${typeParameterName} should have a trailing comma. Example usage: <${typeParameterName},>.`,
|
|
StaticBlockCannotHaveModifier: "Static class blocks cannot have any modifier.",
|
|
TupleOptionalAfterType: "A labeled tuple optional element must be declared using a question mark after the name and before the colon (`name?: type`), rather than after the type (`name: type?`).",
|
|
TypeAnnotationAfterAssign: "Type annotations must come before default assignments, e.g. instead of `age = 25: number` use `age: number = 25`.",
|
|
TypeImportCannotSpecifyDefaultAndNamed: "A type-only import can specify a default import or named bindings, but not both.",
|
|
TypeModifierIsUsedInTypeExports: "The 'type' modifier cannot be used on a named export when 'export type' is used on its export statement.",
|
|
TypeModifierIsUsedInTypeImports: "The 'type' modifier cannot be used on a named import when 'import type' is used on its import statement.",
|
|
UnexpectedParameterModifier: "A parameter property is only allowed in a constructor implementation.",
|
|
UnexpectedReadonly: "'readonly' type modifier is only permitted on array and tuple literal types.",
|
|
UnexpectedTypeAnnotation: "Did not expect a type annotation here.",
|
|
UnexpectedTypeCastInParameter: "Unexpected type cast in parameter position.",
|
|
UnsupportedImportTypeArgument: "Argument in a type import must be a string literal.",
|
|
UnsupportedParameterPropertyKind: "A parameter property may not be declared using a binding pattern.",
|
|
UnsupportedSignatureParameterKind: ({
|
|
type
|
|
}) => `Name in a signature must be an Identifier, ObjectPattern or ArrayPattern, instead got ${type}.`,
|
|
UsingDeclarationInAmbientContext: kind => `'${kind}' declarations are not allowed in ambient contexts.`
|
|
});
|
|
function keywordTypeFromName(value) {
|
|
switch (value) {
|
|
case "any":
|
|
return "TSAnyKeyword";
|
|
case "boolean":
|
|
return "TSBooleanKeyword";
|
|
case "bigint":
|
|
return "TSBigIntKeyword";
|
|
case "never":
|
|
return "TSNeverKeyword";
|
|
case "number":
|
|
return "TSNumberKeyword";
|
|
case "object":
|
|
return "TSObjectKeyword";
|
|
case "string":
|
|
return "TSStringKeyword";
|
|
case "symbol":
|
|
return "TSSymbolKeyword";
|
|
case "undefined":
|
|
return "TSUndefinedKeyword";
|
|
case "unknown":
|
|
return "TSUnknownKeyword";
|
|
default:
|
|
return undefined;
|
|
}
|
|
}
|
|
function tsIsAccessModifier(modifier) {
|
|
return modifier === "private" || modifier === "public" || modifier === "protected";
|
|
}
|
|
function tsIsVarianceAnnotations(modifier) {
|
|
return modifier === "in" || modifier === "out";
|
|
}
|
|
var typescript = superClass => class TypeScriptParserMixin extends superClass {
|
|
constructor(...args) {
|
|
super(...args);
|
|
this.tsParseInOutModifiers = this.tsParseModifiers.bind(this, {
|
|
allowedModifiers: ["in", "out"],
|
|
disallowedModifiers: ["const", "public", "private", "protected", "readonly", "declare", "abstract", "override"],
|
|
errorTemplate: TSErrors.InvalidModifierOnTypeParameter
|
|
});
|
|
this.tsParseConstModifier = this.tsParseModifiers.bind(this, {
|
|
allowedModifiers: ["const"],
|
|
disallowedModifiers: ["in", "out"],
|
|
errorTemplate: TSErrors.InvalidModifierOnTypeParameterPositions
|
|
});
|
|
this.tsParseInOutConstModifiers = this.tsParseModifiers.bind(this, {
|
|
allowedModifiers: ["in", "out", "const"],
|
|
disallowedModifiers: ["public", "private", "protected", "readonly", "declare", "abstract", "override"],
|
|
errorTemplate: TSErrors.InvalidModifierOnTypeParameter
|
|
});
|
|
}
|
|
getScopeHandler() {
|
|
return TypeScriptScopeHandler;
|
|
}
|
|
tsIsIdentifier() {
|
|
return tokenIsIdentifier(this.state.type);
|
|
}
|
|
tsTokenCanFollowModifier() {
|
|
return this.match(0) || this.match(5) || this.match(55) || this.match(21) || this.match(139) || this.isLiteralPropertyName();
|
|
}
|
|
tsNextTokenOnSameLineAndCanFollowModifier() {
|
|
this.next();
|
|
if (this.hasPrecedingLineBreak()) {
|
|
return false;
|
|
}
|
|
return this.tsTokenCanFollowModifier();
|
|
}
|
|
tsNextTokenCanFollowModifier() {
|
|
if (this.match(106)) {
|
|
this.next();
|
|
return this.tsTokenCanFollowModifier();
|
|
}
|
|
return this.tsNextTokenOnSameLineAndCanFollowModifier();
|
|
}
|
|
tsParseModifier(allowedModifiers, stopOnStartOfClassStaticBlock, hasSeenStaticModifier) {
|
|
if (!tokenIsIdentifier(this.state.type) && this.state.type !== 58 && this.state.type !== 75) {
|
|
return undefined;
|
|
}
|
|
const modifier = this.state.value;
|
|
if (allowedModifiers.includes(modifier)) {
|
|
if (hasSeenStaticModifier && this.match(106)) {
|
|
return undefined;
|
|
}
|
|
if (stopOnStartOfClassStaticBlock && this.tsIsStartOfStaticBlocks()) {
|
|
return undefined;
|
|
}
|
|
if (this.tsTryParse(this.tsNextTokenCanFollowModifier.bind(this))) {
|
|
return modifier;
|
|
}
|
|
}
|
|
return undefined;
|
|
}
|
|
tsParseModifiers({
|
|
allowedModifiers,
|
|
disallowedModifiers,
|
|
stopOnStartOfClassStaticBlock,
|
|
errorTemplate = TSErrors.InvalidModifierOnTypeMember
|
|
}, modified) {
|
|
const enforceOrder = (loc, modifier, before, after) => {
|
|
if (modifier === before && modified[after]) {
|
|
this.raise(TSErrors.InvalidModifiersOrder, loc, {
|
|
orderedModifiers: [before, after]
|
|
});
|
|
}
|
|
};
|
|
const incompatible = (loc, modifier, mod1, mod2) => {
|
|
if (modified[mod1] && modifier === mod2 || modified[mod2] && modifier === mod1) {
|
|
this.raise(TSErrors.IncompatibleModifiers, loc, {
|
|
modifiers: [mod1, mod2]
|
|
});
|
|
}
|
|
};
|
|
for (;;) {
|
|
const {
|
|
startLoc
|
|
} = this.state;
|
|
const modifier = this.tsParseModifier(allowedModifiers.concat(disallowedModifiers != null ? disallowedModifiers : []), stopOnStartOfClassStaticBlock, modified.static);
|
|
if (!modifier) break;
|
|
if (tsIsAccessModifier(modifier)) {
|
|
if (modified.accessibility) {
|
|
this.raise(TSErrors.DuplicateAccessibilityModifier, startLoc, {
|
|
modifier
|
|
});
|
|
} else {
|
|
enforceOrder(startLoc, modifier, modifier, "override");
|
|
enforceOrder(startLoc, modifier, modifier, "static");
|
|
enforceOrder(startLoc, modifier, modifier, "readonly");
|
|
modified.accessibility = modifier;
|
|
}
|
|
} else if (tsIsVarianceAnnotations(modifier)) {
|
|
if (modified[modifier]) {
|
|
this.raise(TSErrors.DuplicateModifier, startLoc, {
|
|
modifier
|
|
});
|
|
}
|
|
modified[modifier] = true;
|
|
enforceOrder(startLoc, modifier, "in", "out");
|
|
} else {
|
|
if (hasOwnProperty.call(modified, modifier)) {
|
|
this.raise(TSErrors.DuplicateModifier, startLoc, {
|
|
modifier
|
|
});
|
|
} else {
|
|
enforceOrder(startLoc, modifier, "static", "readonly");
|
|
enforceOrder(startLoc, modifier, "static", "override");
|
|
enforceOrder(startLoc, modifier, "override", "readonly");
|
|
enforceOrder(startLoc, modifier, "abstract", "override");
|
|
incompatible(startLoc, modifier, "declare", "override");
|
|
incompatible(startLoc, modifier, "static", "abstract");
|
|
}
|
|
modified[modifier] = true;
|
|
}
|
|
if (disallowedModifiers != null && disallowedModifiers.includes(modifier)) {
|
|
this.raise(errorTemplate, startLoc, {
|
|
modifier
|
|
});
|
|
}
|
|
}
|
|
}
|
|
tsIsListTerminator(kind) {
|
|
switch (kind) {
|
|
case "EnumMembers":
|
|
case "TypeMembers":
|
|
return this.match(8);
|
|
case "HeritageClauseElement":
|
|
return this.match(5);
|
|
case "TupleElementTypes":
|
|
return this.match(3);
|
|
case "TypeParametersOrArguments":
|
|
return this.match(48);
|
|
}
|
|
}
|
|
tsParseList(kind, parseElement) {
|
|
const result = [];
|
|
while (!this.tsIsListTerminator(kind)) {
|
|
result.push(parseElement());
|
|
}
|
|
return result;
|
|
}
|
|
tsParseDelimitedList(kind, parseElement, refTrailingCommaPos) {
|
|
return nonNull(this.tsParseDelimitedListWorker(kind, parseElement, true, refTrailingCommaPos));
|
|
}
|
|
tsParseDelimitedListWorker(kind, parseElement, expectSuccess, refTrailingCommaPos) {
|
|
const result = [];
|
|
let trailingCommaPos = -1;
|
|
for (;;) {
|
|
if (this.tsIsListTerminator(kind)) {
|
|
break;
|
|
}
|
|
trailingCommaPos = -1;
|
|
const element = parseElement();
|
|
if (element == null) {
|
|
return undefined;
|
|
}
|
|
result.push(element);
|
|
if (this.eat(12)) {
|
|
trailingCommaPos = this.state.lastTokStartLoc.index;
|
|
continue;
|
|
}
|
|
if (this.tsIsListTerminator(kind)) {
|
|
break;
|
|
}
|
|
if (expectSuccess) {
|
|
this.expect(12);
|
|
}
|
|
return undefined;
|
|
}
|
|
if (refTrailingCommaPos) {
|
|
refTrailingCommaPos.value = trailingCommaPos;
|
|
}
|
|
return result;
|
|
}
|
|
tsParseBracketedList(kind, parseElement, bracket, skipFirstToken, refTrailingCommaPos) {
|
|
if (!skipFirstToken) {
|
|
if (bracket) {
|
|
this.expect(0);
|
|
} else {
|
|
this.expect(47);
|
|
}
|
|
}
|
|
const result = this.tsParseDelimitedList(kind, parseElement, refTrailingCommaPos);
|
|
if (bracket) {
|
|
this.expect(3);
|
|
} else {
|
|
this.expect(48);
|
|
}
|
|
return result;
|
|
}
|
|
tsParseImportType() {
|
|
const node = this.startNode();
|
|
this.expect(83);
|
|
this.expect(10);
|
|
if (!this.match(134)) {
|
|
this.raise(TSErrors.UnsupportedImportTypeArgument, this.state.startLoc);
|
|
{
|
|
node.argument = super.parseExprAtom();
|
|
}
|
|
} else {
|
|
{
|
|
node.argument = this.parseStringLiteral(this.state.value);
|
|
}
|
|
}
|
|
if (this.eat(12)) {
|
|
node.options = this.tsParseImportTypeOptions();
|
|
} else {
|
|
node.options = null;
|
|
}
|
|
this.expect(11);
|
|
if (this.eat(16)) {
|
|
node.qualifier = this.tsParseEntityName(1 | 2);
|
|
}
|
|
if (this.match(47)) {
|
|
{
|
|
node.typeParameters = this.tsParseTypeArguments();
|
|
}
|
|
}
|
|
return this.finishNode(node, "TSImportType");
|
|
}
|
|
tsParseImportTypeOptions() {
|
|
const node = this.startNode();
|
|
this.expect(5);
|
|
const withProperty = this.startNode();
|
|
if (this.isContextual(76)) {
|
|
withProperty.method = false;
|
|
withProperty.key = this.parseIdentifier(true);
|
|
withProperty.computed = false;
|
|
withProperty.shorthand = false;
|
|
} else {
|
|
this.unexpected(null, 76);
|
|
}
|
|
this.expect(14);
|
|
withProperty.value = this.tsParseImportTypeWithPropertyValue();
|
|
node.properties = [this.finishObjectProperty(withProperty)];
|
|
this.eat(12);
|
|
this.expect(8);
|
|
return this.finishNode(node, "ObjectExpression");
|
|
}
|
|
tsParseImportTypeWithPropertyValue() {
|
|
const node = this.startNode();
|
|
const properties = [];
|
|
this.expect(5);
|
|
while (!this.match(8)) {
|
|
const type = this.state.type;
|
|
if (tokenIsIdentifier(type) || type === 134) {
|
|
properties.push(super.parsePropertyDefinition(null));
|
|
} else {
|
|
this.unexpected();
|
|
}
|
|
this.eat(12);
|
|
}
|
|
node.properties = properties;
|
|
this.next();
|
|
return this.finishNode(node, "ObjectExpression");
|
|
}
|
|
tsParseEntityName(flags) {
|
|
let entity;
|
|
if (flags & 1 && this.match(78)) {
|
|
if (flags & 2) {
|
|
entity = this.parseIdentifier(true);
|
|
} else {
|
|
const node = this.startNode();
|
|
this.next();
|
|
entity = this.finishNode(node, "ThisExpression");
|
|
}
|
|
} else {
|
|
entity = this.parseIdentifier(!!(flags & 1));
|
|
}
|
|
while (this.eat(16)) {
|
|
const node = this.startNodeAtNode(entity);
|
|
node.left = entity;
|
|
node.right = this.parseIdentifier(!!(flags & 1));
|
|
entity = this.finishNode(node, "TSQualifiedName");
|
|
}
|
|
return entity;
|
|
}
|
|
tsParseTypeReference() {
|
|
const node = this.startNode();
|
|
node.typeName = this.tsParseEntityName(1);
|
|
if (!this.hasPrecedingLineBreak() && this.match(47)) {
|
|
{
|
|
node.typeParameters = this.tsParseTypeArguments();
|
|
}
|
|
}
|
|
return this.finishNode(node, "TSTypeReference");
|
|
}
|
|
tsParseThisTypePredicate(lhs) {
|
|
this.next();
|
|
const node = this.startNodeAtNode(lhs);
|
|
node.parameterName = lhs;
|
|
node.typeAnnotation = this.tsParseTypeAnnotation(false);
|
|
node.asserts = false;
|
|
return this.finishNode(node, "TSTypePredicate");
|
|
}
|
|
tsParseThisTypeNode() {
|
|
const node = this.startNode();
|
|
this.next();
|
|
return this.finishNode(node, "TSThisType");
|
|
}
|
|
tsParseTypeQuery() {
|
|
const node = this.startNode();
|
|
this.expect(87);
|
|
if (this.match(83)) {
|
|
node.exprName = this.tsParseImportType();
|
|
} else {
|
|
{
|
|
node.exprName = this.tsParseEntityName(1 | 2);
|
|
}
|
|
}
|
|
if (!this.hasPrecedingLineBreak() && this.match(47)) {
|
|
{
|
|
node.typeParameters = this.tsParseTypeArguments();
|
|
}
|
|
}
|
|
return this.finishNode(node, "TSTypeQuery");
|
|
}
|
|
tsParseTypeParameter(parseModifiers) {
|
|
const node = this.startNode();
|
|
parseModifiers(node);
|
|
node.name = this.tsParseTypeParameterName();
|
|
node.constraint = this.tsEatThenParseType(81);
|
|
node.default = this.tsEatThenParseType(29);
|
|
return this.finishNode(node, "TSTypeParameter");
|
|
}
|
|
tsTryParseTypeParameters(parseModifiers) {
|
|
if (this.match(47)) {
|
|
return this.tsParseTypeParameters(parseModifiers);
|
|
}
|
|
}
|
|
tsParseTypeParameters(parseModifiers) {
|
|
const node = this.startNode();
|
|
if (this.match(47) || this.match(143)) {
|
|
this.next();
|
|
} else {
|
|
this.unexpected();
|
|
}
|
|
const refTrailingCommaPos = {
|
|
value: -1
|
|
};
|
|
node.params = this.tsParseBracketedList("TypeParametersOrArguments", this.tsParseTypeParameter.bind(this, parseModifiers), false, true, refTrailingCommaPos);
|
|
if (node.params.length === 0) {
|
|
this.raise(TSErrors.EmptyTypeParameters, node);
|
|
}
|
|
if (refTrailingCommaPos.value !== -1) {
|
|
this.addExtra(node, "trailingComma", refTrailingCommaPos.value);
|
|
}
|
|
return this.finishNode(node, "TSTypeParameterDeclaration");
|
|
}
|
|
tsFillSignature(returnToken, signature) {
|
|
const returnTokenRequired = returnToken === 19;
|
|
const paramsKey = "parameters";
|
|
const returnTypeKey = "typeAnnotation";
|
|
signature.typeParameters = this.tsTryParseTypeParameters(this.tsParseConstModifier);
|
|
this.expect(10);
|
|
signature[paramsKey] = this.tsParseBindingListForSignature();
|
|
if (returnTokenRequired) {
|
|
signature[returnTypeKey] = this.tsParseTypeOrTypePredicateAnnotation(returnToken);
|
|
} else if (this.match(returnToken)) {
|
|
signature[returnTypeKey] = this.tsParseTypeOrTypePredicateAnnotation(returnToken);
|
|
}
|
|
}
|
|
tsParseBindingListForSignature() {
|
|
const list = super.parseBindingList(11, 41, 2);
|
|
for (const pattern of list) {
|
|
const {
|
|
type
|
|
} = pattern;
|
|
if (type === "AssignmentPattern" || type === "TSParameterProperty") {
|
|
this.raise(TSErrors.UnsupportedSignatureParameterKind, pattern, {
|
|
type
|
|
});
|
|
}
|
|
}
|
|
return list;
|
|
}
|
|
tsParseTypeMemberSemicolon() {
|
|
if (!this.eat(12) && !this.isLineTerminator()) {
|
|
this.expect(13);
|
|
}
|
|
}
|
|
tsParseSignatureMember(kind, node) {
|
|
this.tsFillSignature(14, node);
|
|
this.tsParseTypeMemberSemicolon();
|
|
return this.finishNode(node, kind);
|
|
}
|
|
tsIsUnambiguouslyIndexSignature() {
|
|
this.next();
|
|
if (tokenIsIdentifier(this.state.type)) {
|
|
this.next();
|
|
return this.match(14);
|
|
}
|
|
return false;
|
|
}
|
|
tsTryParseIndexSignature(node) {
|
|
if (!(this.match(0) && this.tsLookAhead(this.tsIsUnambiguouslyIndexSignature.bind(this)))) {
|
|
return;
|
|
}
|
|
this.expect(0);
|
|
const id = this.parseIdentifier();
|
|
id.typeAnnotation = this.tsParseTypeAnnotation();
|
|
this.resetEndLocation(id);
|
|
this.expect(3);
|
|
node.parameters = [id];
|
|
const type = this.tsTryParseTypeAnnotation();
|
|
if (type) node.typeAnnotation = type;
|
|
this.tsParseTypeMemberSemicolon();
|
|
return this.finishNode(node, "TSIndexSignature");
|
|
}
|
|
tsParsePropertyOrMethodSignature(node, readonly) {
|
|
if (this.eat(17)) node.optional = true;
|
|
if (this.match(10) || this.match(47)) {
|
|
if (readonly) {
|
|
this.raise(TSErrors.ReadonlyForMethodSignature, node);
|
|
}
|
|
const method = node;
|
|
if (method.kind && this.match(47)) {
|
|
this.raise(TSErrors.AccessorCannotHaveTypeParameters, this.state.curPosition());
|
|
}
|
|
this.tsFillSignature(14, method);
|
|
this.tsParseTypeMemberSemicolon();
|
|
const paramsKey = "parameters";
|
|
const returnTypeKey = "typeAnnotation";
|
|
if (method.kind === "get") {
|
|
if (method[paramsKey].length > 0) {
|
|
this.raise(Errors.BadGetterArity, this.state.curPosition());
|
|
if (this.isThisParam(method[paramsKey][0])) {
|
|
this.raise(TSErrors.AccessorCannotDeclareThisParameter, this.state.curPosition());
|
|
}
|
|
}
|
|
} else if (method.kind === "set") {
|
|
if (method[paramsKey].length !== 1) {
|
|
this.raise(Errors.BadSetterArity, this.state.curPosition());
|
|
} else {
|
|
const firstParameter = method[paramsKey][0];
|
|
if (this.isThisParam(firstParameter)) {
|
|
this.raise(TSErrors.AccessorCannotDeclareThisParameter, this.state.curPosition());
|
|
}
|
|
if (firstParameter.type === "Identifier" && firstParameter.optional) {
|
|
this.raise(TSErrors.SetAccessorCannotHaveOptionalParameter, this.state.curPosition());
|
|
}
|
|
if (firstParameter.type === "RestElement") {
|
|
this.raise(TSErrors.SetAccessorCannotHaveRestParameter, this.state.curPosition());
|
|
}
|
|
}
|
|
if (method[returnTypeKey]) {
|
|
this.raise(TSErrors.SetAccessorCannotHaveReturnType, method[returnTypeKey]);
|
|
}
|
|
} else {
|
|
method.kind = "method";
|
|
}
|
|
return this.finishNode(method, "TSMethodSignature");
|
|
} else {
|
|
const property = node;
|
|
if (readonly) property.readonly = true;
|
|
const type = this.tsTryParseTypeAnnotation();
|
|
if (type) property.typeAnnotation = type;
|
|
this.tsParseTypeMemberSemicolon();
|
|
return this.finishNode(property, "TSPropertySignature");
|
|
}
|
|
}
|
|
tsParseTypeMember() {
|
|
const node = this.startNode();
|
|
if (this.match(10) || this.match(47)) {
|
|
return this.tsParseSignatureMember("TSCallSignatureDeclaration", node);
|
|
}
|
|
if (this.match(77)) {
|
|
const id = this.startNode();
|
|
this.next();
|
|
if (this.match(10) || this.match(47)) {
|
|
return this.tsParseSignatureMember("TSConstructSignatureDeclaration", node);
|
|
} else {
|
|
node.key = this.createIdentifier(id, "new");
|
|
return this.tsParsePropertyOrMethodSignature(node, false);
|
|
}
|
|
}
|
|
this.tsParseModifiers({
|
|
allowedModifiers: ["readonly"],
|
|
disallowedModifiers: ["declare", "abstract", "private", "protected", "public", "static", "override"]
|
|
}, node);
|
|
const idx = this.tsTryParseIndexSignature(node);
|
|
if (idx) {
|
|
return idx;
|
|
}
|
|
super.parsePropertyName(node);
|
|
if (!node.computed && node.key.type === "Identifier" && (node.key.name === "get" || node.key.name === "set") && this.tsTokenCanFollowModifier()) {
|
|
node.kind = node.key.name;
|
|
super.parsePropertyName(node);
|
|
if (!this.match(10) && !this.match(47)) {
|
|
this.unexpected(null, 10);
|
|
}
|
|
}
|
|
return this.tsParsePropertyOrMethodSignature(node, !!node.readonly);
|
|
}
|
|
tsParseTypeLiteral() {
|
|
const node = this.startNode();
|
|
node.members = this.tsParseObjectTypeMembers();
|
|
return this.finishNode(node, "TSTypeLiteral");
|
|
}
|
|
tsParseObjectTypeMembers() {
|
|
this.expect(5);
|
|
const members = this.tsParseList("TypeMembers", this.tsParseTypeMember.bind(this));
|
|
this.expect(8);
|
|
return members;
|
|
}
|
|
tsIsStartOfMappedType() {
|
|
this.next();
|
|
if (this.eat(53)) {
|
|
return this.isContextual(122);
|
|
}
|
|
if (this.isContextual(122)) {
|
|
this.next();
|
|
}
|
|
if (!this.match(0)) {
|
|
return false;
|
|
}
|
|
this.next();
|
|
if (!this.tsIsIdentifier()) {
|
|
return false;
|
|
}
|
|
this.next();
|
|
return this.match(58);
|
|
}
|
|
tsParseMappedType() {
|
|
const node = this.startNode();
|
|
this.expect(5);
|
|
if (this.match(53)) {
|
|
node.readonly = this.state.value;
|
|
this.next();
|
|
this.expectContextual(122);
|
|
} else if (this.eatContextual(122)) {
|
|
node.readonly = true;
|
|
}
|
|
this.expect(0);
|
|
{
|
|
const typeParameter = this.startNode();
|
|
typeParameter.name = this.tsParseTypeParameterName();
|
|
typeParameter.constraint = this.tsExpectThenParseType(58);
|
|
node.typeParameter = this.finishNode(typeParameter, "TSTypeParameter");
|
|
}
|
|
node.nameType = this.eatContextual(93) ? this.tsParseType() : null;
|
|
this.expect(3);
|
|
if (this.match(53)) {
|
|
node.optional = this.state.value;
|
|
this.next();
|
|
this.expect(17);
|
|
} else if (this.eat(17)) {
|
|
node.optional = true;
|
|
}
|
|
node.typeAnnotation = this.tsTryParseType();
|
|
this.semicolon();
|
|
this.expect(8);
|
|
return this.finishNode(node, "TSMappedType");
|
|
}
|
|
tsParseTupleType() {
|
|
const node = this.startNode();
|
|
node.elementTypes = this.tsParseBracketedList("TupleElementTypes", this.tsParseTupleElementType.bind(this), true, false);
|
|
let seenOptionalElement = false;
|
|
node.elementTypes.forEach(elementNode => {
|
|
const {
|
|
type
|
|
} = elementNode;
|
|
if (seenOptionalElement && type !== "TSRestType" && type !== "TSOptionalType" && !(type === "TSNamedTupleMember" && elementNode.optional)) {
|
|
this.raise(TSErrors.OptionalTypeBeforeRequired, elementNode);
|
|
}
|
|
seenOptionalElement || (seenOptionalElement = type === "TSNamedTupleMember" && elementNode.optional || type === "TSOptionalType");
|
|
});
|
|
return this.finishNode(node, "TSTupleType");
|
|
}
|
|
tsParseTupleElementType() {
|
|
const restStartLoc = this.state.startLoc;
|
|
const rest = this.eat(21);
|
|
const {
|
|
startLoc
|
|
} = this.state;
|
|
let labeled;
|
|
let label;
|
|
let optional;
|
|
let type;
|
|
const isWord = tokenIsKeywordOrIdentifier(this.state.type);
|
|
const chAfterWord = isWord ? this.lookaheadCharCode() : null;
|
|
if (chAfterWord === 58) {
|
|
labeled = true;
|
|
optional = false;
|
|
label = this.parseIdentifier(true);
|
|
this.expect(14);
|
|
type = this.tsParseType();
|
|
} else if (chAfterWord === 63) {
|
|
optional = true;
|
|
const wordName = this.state.value;
|
|
const typeOrLabel = this.tsParseNonArrayType();
|
|
if (this.lookaheadCharCode() === 58) {
|
|
labeled = true;
|
|
label = this.createIdentifier(this.startNodeAt(startLoc), wordName);
|
|
this.expect(17);
|
|
this.expect(14);
|
|
type = this.tsParseType();
|
|
} else {
|
|
labeled = false;
|
|
type = typeOrLabel;
|
|
this.expect(17);
|
|
}
|
|
} else {
|
|
type = this.tsParseType();
|
|
optional = this.eat(17);
|
|
labeled = this.eat(14);
|
|
}
|
|
if (labeled) {
|
|
let labeledNode;
|
|
if (label) {
|
|
labeledNode = this.startNodeAt(startLoc);
|
|
labeledNode.optional = optional;
|
|
labeledNode.label = label;
|
|
labeledNode.elementType = type;
|
|
if (this.eat(17)) {
|
|
labeledNode.optional = true;
|
|
this.raise(TSErrors.TupleOptionalAfterType, this.state.lastTokStartLoc);
|
|
}
|
|
} else {
|
|
labeledNode = this.startNodeAt(startLoc);
|
|
labeledNode.optional = optional;
|
|
this.raise(TSErrors.InvalidTupleMemberLabel, type);
|
|
labeledNode.label = type;
|
|
labeledNode.elementType = this.tsParseType();
|
|
}
|
|
type = this.finishNode(labeledNode, "TSNamedTupleMember");
|
|
} else if (optional) {
|
|
const optionalTypeNode = this.startNodeAt(startLoc);
|
|
optionalTypeNode.typeAnnotation = type;
|
|
type = this.finishNode(optionalTypeNode, "TSOptionalType");
|
|
}
|
|
if (rest) {
|
|
const restNode = this.startNodeAt(restStartLoc);
|
|
restNode.typeAnnotation = type;
|
|
type = this.finishNode(restNode, "TSRestType");
|
|
}
|
|
return type;
|
|
}
|
|
tsParseParenthesizedType() {
|
|
const node = this.startNode();
|
|
this.expect(10);
|
|
node.typeAnnotation = this.tsParseType();
|
|
this.expect(11);
|
|
return this.finishNode(node, "TSParenthesizedType");
|
|
}
|
|
tsParseFunctionOrConstructorType(type, abstract) {
|
|
const node = this.startNode();
|
|
if (type === "TSConstructorType") {
|
|
node.abstract = !!abstract;
|
|
if (abstract) this.next();
|
|
this.next();
|
|
}
|
|
this.tsInAllowConditionalTypesContext(() => this.tsFillSignature(19, node));
|
|
return this.finishNode(node, type);
|
|
}
|
|
tsParseLiteralTypeNode() {
|
|
const node = this.startNode();
|
|
switch (this.state.type) {
|
|
case 135:
|
|
case 136:
|
|
case 134:
|
|
case 85:
|
|
case 86:
|
|
node.literal = super.parseExprAtom();
|
|
break;
|
|
default:
|
|
this.unexpected();
|
|
}
|
|
return this.finishNode(node, "TSLiteralType");
|
|
}
|
|
tsParseTemplateLiteralType() {
|
|
{
|
|
const node = this.startNode();
|
|
node.literal = super.parseTemplate(false);
|
|
return this.finishNode(node, "TSLiteralType");
|
|
}
|
|
}
|
|
parseTemplateSubstitution() {
|
|
if (this.state.inType) return this.tsParseType();
|
|
return super.parseTemplateSubstitution();
|
|
}
|
|
tsParseThisTypeOrThisTypePredicate() {
|
|
const thisKeyword = this.tsParseThisTypeNode();
|
|
if (this.isContextual(116) && !this.hasPrecedingLineBreak()) {
|
|
return this.tsParseThisTypePredicate(thisKeyword);
|
|
} else {
|
|
return thisKeyword;
|
|
}
|
|
}
|
|
tsParseNonArrayType() {
|
|
switch (this.state.type) {
|
|
case 134:
|
|
case 135:
|
|
case 136:
|
|
case 85:
|
|
case 86:
|
|
return this.tsParseLiteralTypeNode();
|
|
case 53:
|
|
if (this.state.value === "-") {
|
|
const node = this.startNode();
|
|
const nextToken = this.lookahead();
|
|
if (nextToken.type !== 135 && nextToken.type !== 136) {
|
|
this.unexpected();
|
|
}
|
|
node.literal = this.parseMaybeUnary();
|
|
return this.finishNode(node, "TSLiteralType");
|
|
}
|
|
break;
|
|
case 78:
|
|
return this.tsParseThisTypeOrThisTypePredicate();
|
|
case 87:
|
|
return this.tsParseTypeQuery();
|
|
case 83:
|
|
return this.tsParseImportType();
|
|
case 5:
|
|
return this.tsLookAhead(this.tsIsStartOfMappedType.bind(this)) ? this.tsParseMappedType() : this.tsParseTypeLiteral();
|
|
case 0:
|
|
return this.tsParseTupleType();
|
|
case 10:
|
|
return this.tsParseParenthesizedType();
|
|
case 25:
|
|
case 24:
|
|
return this.tsParseTemplateLiteralType();
|
|
default:
|
|
{
|
|
const {
|
|
type
|
|
} = this.state;
|
|
if (tokenIsIdentifier(type) || type === 88 || type === 84) {
|
|
const nodeType = type === 88 ? "TSVoidKeyword" : type === 84 ? "TSNullKeyword" : keywordTypeFromName(this.state.value);
|
|
if (nodeType !== undefined && this.lookaheadCharCode() !== 46) {
|
|
const node = this.startNode();
|
|
this.next();
|
|
return this.finishNode(node, nodeType);
|
|
}
|
|
return this.tsParseTypeReference();
|
|
}
|
|
}
|
|
}
|
|
throw this.unexpected();
|
|
}
|
|
tsParseArrayTypeOrHigher() {
|
|
const {
|
|
startLoc
|
|
} = this.state;
|
|
let type = this.tsParseNonArrayType();
|
|
while (!this.hasPrecedingLineBreak() && this.eat(0)) {
|
|
if (this.match(3)) {
|
|
const node = this.startNodeAt(startLoc);
|
|
node.elementType = type;
|
|
this.expect(3);
|
|
type = this.finishNode(node, "TSArrayType");
|
|
} else {
|
|
const node = this.startNodeAt(startLoc);
|
|
node.objectType = type;
|
|
node.indexType = this.tsParseType();
|
|
this.expect(3);
|
|
type = this.finishNode(node, "TSIndexedAccessType");
|
|
}
|
|
}
|
|
return type;
|
|
}
|
|
tsParseTypeOperator() {
|
|
const node = this.startNode();
|
|
const operator = this.state.value;
|
|
this.next();
|
|
node.operator = operator;
|
|
node.typeAnnotation = this.tsParseTypeOperatorOrHigher();
|
|
if (operator === "readonly") {
|
|
this.tsCheckTypeAnnotationForReadOnly(node);
|
|
}
|
|
return this.finishNode(node, "TSTypeOperator");
|
|
}
|
|
tsCheckTypeAnnotationForReadOnly(node) {
|
|
switch (node.typeAnnotation.type) {
|
|
case "TSTupleType":
|
|
case "TSArrayType":
|
|
return;
|
|
default:
|
|
this.raise(TSErrors.UnexpectedReadonly, node);
|
|
}
|
|
}
|
|
tsParseInferType() {
|
|
const node = this.startNode();
|
|
this.expectContextual(115);
|
|
const typeParameter = this.startNode();
|
|
typeParameter.name = this.tsParseTypeParameterName();
|
|
typeParameter.constraint = this.tsTryParse(() => this.tsParseConstraintForInferType());
|
|
node.typeParameter = this.finishNode(typeParameter, "TSTypeParameter");
|
|
return this.finishNode(node, "TSInferType");
|
|
}
|
|
tsParseConstraintForInferType() {
|
|
if (this.eat(81)) {
|
|
const constraint = this.tsInDisallowConditionalTypesContext(() => this.tsParseType());
|
|
if (this.state.inDisallowConditionalTypesContext || !this.match(17)) {
|
|
return constraint;
|
|
}
|
|
}
|
|
}
|
|
tsParseTypeOperatorOrHigher() {
|
|
const isTypeOperator = tokenIsTSTypeOperator(this.state.type) && !this.state.containsEsc;
|
|
return isTypeOperator ? this.tsParseTypeOperator() : this.isContextual(115) ? this.tsParseInferType() : this.tsInAllowConditionalTypesContext(() => this.tsParseArrayTypeOrHigher());
|
|
}
|
|
tsParseUnionOrIntersectionType(kind, parseConstituentType, operator) {
|
|
const node = this.startNode();
|
|
const hasLeadingOperator = this.eat(operator);
|
|
const types = [];
|
|
do {
|
|
types.push(parseConstituentType());
|
|
} while (this.eat(operator));
|
|
if (types.length === 1 && !hasLeadingOperator) {
|
|
return types[0];
|
|
}
|
|
node.types = types;
|
|
return this.finishNode(node, kind);
|
|
}
|
|
tsParseIntersectionTypeOrHigher() {
|
|
return this.tsParseUnionOrIntersectionType("TSIntersectionType", this.tsParseTypeOperatorOrHigher.bind(this), 45);
|
|
}
|
|
tsParseUnionTypeOrHigher() {
|
|
return this.tsParseUnionOrIntersectionType("TSUnionType", this.tsParseIntersectionTypeOrHigher.bind(this), 43);
|
|
}
|
|
tsIsStartOfFunctionType() {
|
|
if (this.match(47)) {
|
|
return true;
|
|
}
|
|
return this.match(10) && this.tsLookAhead(this.tsIsUnambiguouslyStartOfFunctionType.bind(this));
|
|
}
|
|
tsSkipParameterStart() {
|
|
if (tokenIsIdentifier(this.state.type) || this.match(78)) {
|
|
this.next();
|
|
return true;
|
|
}
|
|
if (this.match(5)) {
|
|
const {
|
|
errors
|
|
} = this.state;
|
|
const previousErrorCount = errors.length;
|
|
try {
|
|
this.parseObjectLike(8, true);
|
|
return errors.length === previousErrorCount;
|
|
} catch (_unused) {
|
|
return false;
|
|
}
|
|
}
|
|
if (this.match(0)) {
|
|
this.next();
|
|
const {
|
|
errors
|
|
} = this.state;
|
|
const previousErrorCount = errors.length;
|
|
try {
|
|
super.parseBindingList(3, 93, 1);
|
|
return errors.length === previousErrorCount;
|
|
} catch (_unused2) {
|
|
return false;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
tsIsUnambiguouslyStartOfFunctionType() {
|
|
this.next();
|
|
if (this.match(11) || this.match(21)) {
|
|
return true;
|
|
}
|
|
if (this.tsSkipParameterStart()) {
|
|
if (this.match(14) || this.match(12) || this.match(17) || this.match(29)) {
|
|
return true;
|
|
}
|
|
if (this.match(11)) {
|
|
this.next();
|
|
if (this.match(19)) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
tsParseTypeOrTypePredicateAnnotation(returnToken) {
|
|
return this.tsInType(() => {
|
|
const t = this.startNode();
|
|
this.expect(returnToken);
|
|
const node = this.startNode();
|
|
const asserts = !!this.tsTryParse(this.tsParseTypePredicateAsserts.bind(this));
|
|
if (asserts && this.match(78)) {
|
|
let thisTypePredicate = this.tsParseThisTypeOrThisTypePredicate();
|
|
if (thisTypePredicate.type === "TSThisType") {
|
|
node.parameterName = thisTypePredicate;
|
|
node.asserts = true;
|
|
node.typeAnnotation = null;
|
|
thisTypePredicate = this.finishNode(node, "TSTypePredicate");
|
|
} else {
|
|
this.resetStartLocationFromNode(thisTypePredicate, node);
|
|
thisTypePredicate.asserts = true;
|
|
}
|
|
t.typeAnnotation = thisTypePredicate;
|
|
return this.finishNode(t, "TSTypeAnnotation");
|
|
}
|
|
const typePredicateVariable = this.tsIsIdentifier() && this.tsTryParse(this.tsParseTypePredicatePrefix.bind(this));
|
|
if (!typePredicateVariable) {
|
|
if (!asserts) {
|
|
return this.tsParseTypeAnnotation(false, t);
|
|
}
|
|
node.parameterName = this.parseIdentifier();
|
|
node.asserts = asserts;
|
|
node.typeAnnotation = null;
|
|
t.typeAnnotation = this.finishNode(node, "TSTypePredicate");
|
|
return this.finishNode(t, "TSTypeAnnotation");
|
|
}
|
|
const type = this.tsParseTypeAnnotation(false);
|
|
node.parameterName = typePredicateVariable;
|
|
node.typeAnnotation = type;
|
|
node.asserts = asserts;
|
|
t.typeAnnotation = this.finishNode(node, "TSTypePredicate");
|
|
return this.finishNode(t, "TSTypeAnnotation");
|
|
});
|
|
}
|
|
tsTryParseTypeOrTypePredicateAnnotation() {
|
|
if (this.match(14)) {
|
|
return this.tsParseTypeOrTypePredicateAnnotation(14);
|
|
}
|
|
}
|
|
tsTryParseTypeAnnotation() {
|
|
if (this.match(14)) {
|
|
return this.tsParseTypeAnnotation();
|
|
}
|
|
}
|
|
tsTryParseType() {
|
|
return this.tsEatThenParseType(14);
|
|
}
|
|
tsParseTypePredicatePrefix() {
|
|
const id = this.parseIdentifier();
|
|
if (this.isContextual(116) && !this.hasPrecedingLineBreak()) {
|
|
this.next();
|
|
return id;
|
|
}
|
|
}
|
|
tsParseTypePredicateAsserts() {
|
|
if (this.state.type !== 109) {
|
|
return false;
|
|
}
|
|
const containsEsc = this.state.containsEsc;
|
|
this.next();
|
|
if (!tokenIsIdentifier(this.state.type) && !this.match(78)) {
|
|
return false;
|
|
}
|
|
if (containsEsc) {
|
|
this.raise(Errors.InvalidEscapedReservedWord, this.state.lastTokStartLoc, {
|
|
reservedWord: "asserts"
|
|
});
|
|
}
|
|
return true;
|
|
}
|
|
tsParseTypeAnnotation(eatColon = true, t = this.startNode()) {
|
|
this.tsInType(() => {
|
|
if (eatColon) this.expect(14);
|
|
t.typeAnnotation = this.tsParseType();
|
|
});
|
|
return this.finishNode(t, "TSTypeAnnotation");
|
|
}
|
|
tsParseType() {
|
|
assert(this.state.inType);
|
|
const type = this.tsParseNonConditionalType();
|
|
if (this.state.inDisallowConditionalTypesContext || this.hasPrecedingLineBreak() || !this.eat(81)) {
|
|
return type;
|
|
}
|
|
const node = this.startNodeAtNode(type);
|
|
node.checkType = type;
|
|
node.extendsType = this.tsInDisallowConditionalTypesContext(() => this.tsParseNonConditionalType());
|
|
this.expect(17);
|
|
node.trueType = this.tsInAllowConditionalTypesContext(() => this.tsParseType());
|
|
this.expect(14);
|
|
node.falseType = this.tsInAllowConditionalTypesContext(() => this.tsParseType());
|
|
return this.finishNode(node, "TSConditionalType");
|
|
}
|
|
isAbstractConstructorSignature() {
|
|
return this.isContextual(124) && this.isLookaheadContextual("new");
|
|
}
|
|
tsParseNonConditionalType() {
|
|
if (this.tsIsStartOfFunctionType()) {
|
|
return this.tsParseFunctionOrConstructorType("TSFunctionType");
|
|
}
|
|
if (this.match(77)) {
|
|
return this.tsParseFunctionOrConstructorType("TSConstructorType");
|
|
} else if (this.isAbstractConstructorSignature()) {
|
|
return this.tsParseFunctionOrConstructorType("TSConstructorType", true);
|
|
}
|
|
return this.tsParseUnionTypeOrHigher();
|
|
}
|
|
tsParseTypeAssertion() {
|
|
if (this.getPluginOption("typescript", "disallowAmbiguousJSXLike")) {
|
|
this.raise(TSErrors.ReservedTypeAssertion, this.state.startLoc);
|
|
}
|
|
const node = this.startNode();
|
|
node.typeAnnotation = this.tsInType(() => {
|
|
this.next();
|
|
return this.match(75) ? this.tsParseTypeReference() : this.tsParseType();
|
|
});
|
|
this.expect(48);
|
|
node.expression = this.parseMaybeUnary();
|
|
return this.finishNode(node, "TSTypeAssertion");
|
|
}
|
|
tsParseHeritageClause(token) {
|
|
const originalStartLoc = this.state.startLoc;
|
|
const delimitedList = this.tsParseDelimitedList("HeritageClauseElement", () => {
|
|
{
|
|
const node = this.startNode();
|
|
node.expression = this.tsParseEntityName(1 | 2);
|
|
if (this.match(47)) {
|
|
node.typeParameters = this.tsParseTypeArguments();
|
|
}
|
|
return this.finishNode(node, "TSExpressionWithTypeArguments");
|
|
}
|
|
});
|
|
if (!delimitedList.length) {
|
|
this.raise(TSErrors.EmptyHeritageClauseType, originalStartLoc, {
|
|
token
|
|
});
|
|
}
|
|
return delimitedList;
|
|
}
|
|
tsParseInterfaceDeclaration(node, properties = {}) {
|
|
if (this.hasFollowingLineBreak()) return null;
|
|
this.expectContextual(129);
|
|
if (properties.declare) node.declare = true;
|
|
if (tokenIsIdentifier(this.state.type)) {
|
|
node.id = this.parseIdentifier();
|
|
this.checkIdentifier(node.id, 130);
|
|
} else {
|
|
node.id = null;
|
|
this.raise(TSErrors.MissingInterfaceName, this.state.startLoc);
|
|
}
|
|
node.typeParameters = this.tsTryParseTypeParameters(this.tsParseInOutConstModifiers);
|
|
if (this.eat(81)) {
|
|
node.extends = this.tsParseHeritageClause("extends");
|
|
}
|
|
const body = this.startNode();
|
|
body.body = this.tsInType(this.tsParseObjectTypeMembers.bind(this));
|
|
node.body = this.finishNode(body, "TSInterfaceBody");
|
|
return this.finishNode(node, "TSInterfaceDeclaration");
|
|
}
|
|
tsParseTypeAliasDeclaration(node) {
|
|
node.id = this.parseIdentifier();
|
|
this.checkIdentifier(node.id, 2);
|
|
node.typeAnnotation = this.tsInType(() => {
|
|
node.typeParameters = this.tsTryParseTypeParameters(this.tsParseInOutModifiers);
|
|
this.expect(29);
|
|
if (this.isContextual(114) && this.lookaheadCharCode() !== 46) {
|
|
const node = this.startNode();
|
|
this.next();
|
|
return this.finishNode(node, "TSIntrinsicKeyword");
|
|
}
|
|
return this.tsParseType();
|
|
});
|
|
this.semicolon();
|
|
return this.finishNode(node, "TSTypeAliasDeclaration");
|
|
}
|
|
tsInTopLevelContext(cb) {
|
|
if (this.curContext() !== types.brace) {
|
|
const oldContext = this.state.context;
|
|
this.state.context = [oldContext[0]];
|
|
try {
|
|
return cb();
|
|
} finally {
|
|
this.state.context = oldContext;
|
|
}
|
|
} else {
|
|
return cb();
|
|
}
|
|
}
|
|
tsInType(cb) {
|
|
const oldInType = this.state.inType;
|
|
this.state.inType = true;
|
|
try {
|
|
return cb();
|
|
} finally {
|
|
this.state.inType = oldInType;
|
|
}
|
|
}
|
|
tsInDisallowConditionalTypesContext(cb) {
|
|
const oldInDisallowConditionalTypesContext = this.state.inDisallowConditionalTypesContext;
|
|
this.state.inDisallowConditionalTypesContext = true;
|
|
try {
|
|
return cb();
|
|
} finally {
|
|
this.state.inDisallowConditionalTypesContext = oldInDisallowConditionalTypesContext;
|
|
}
|
|
}
|
|
tsInAllowConditionalTypesContext(cb) {
|
|
const oldInDisallowConditionalTypesContext = this.state.inDisallowConditionalTypesContext;
|
|
this.state.inDisallowConditionalTypesContext = false;
|
|
try {
|
|
return cb();
|
|
} finally {
|
|
this.state.inDisallowConditionalTypesContext = oldInDisallowConditionalTypesContext;
|
|
}
|
|
}
|
|
tsEatThenParseType(token) {
|
|
if (this.match(token)) {
|
|
return this.tsNextThenParseType();
|
|
}
|
|
}
|
|
tsExpectThenParseType(token) {
|
|
return this.tsInType(() => {
|
|
this.expect(token);
|
|
return this.tsParseType();
|
|
});
|
|
}
|
|
tsNextThenParseType() {
|
|
return this.tsInType(() => {
|
|
this.next();
|
|
return this.tsParseType();
|
|
});
|
|
}
|
|
tsParseEnumMember() {
|
|
const node = this.startNode();
|
|
node.id = this.match(134) ? super.parseStringLiteral(this.state.value) : this.parseIdentifier(true);
|
|
if (this.eat(29)) {
|
|
node.initializer = super.parseMaybeAssignAllowIn();
|
|
}
|
|
return this.finishNode(node, "TSEnumMember");
|
|
}
|
|
tsParseEnumDeclaration(node, properties = {}) {
|
|
if (properties.const) node.const = true;
|
|
if (properties.declare) node.declare = true;
|
|
this.expectContextual(126);
|
|
node.id = this.parseIdentifier();
|
|
this.checkIdentifier(node.id, node.const ? 8971 : 8459);
|
|
{
|
|
this.expect(5);
|
|
node.members = this.tsParseDelimitedList("EnumMembers", this.tsParseEnumMember.bind(this));
|
|
this.expect(8);
|
|
}
|
|
return this.finishNode(node, "TSEnumDeclaration");
|
|
}
|
|
tsParseEnumBody() {
|
|
const node = this.startNode();
|
|
this.expect(5);
|
|
node.members = this.tsParseDelimitedList("EnumMembers", this.tsParseEnumMember.bind(this));
|
|
this.expect(8);
|
|
return this.finishNode(node, "TSEnumBody");
|
|
}
|
|
tsParseModuleBlock() {
|
|
const node = this.startNode();
|
|
this.scope.enter(0);
|
|
this.expect(5);
|
|
super.parseBlockOrModuleBlockBody(node.body = [], undefined, true, 8);
|
|
this.scope.exit();
|
|
return this.finishNode(node, "TSModuleBlock");
|
|
}
|
|
tsParseModuleOrNamespaceDeclaration(node, nested = false) {
|
|
node.id = this.parseIdentifier();
|
|
if (!nested) {
|
|
this.checkIdentifier(node.id, 1024);
|
|
}
|
|
if (this.eat(16)) {
|
|
const inner = this.startNode();
|
|
this.tsParseModuleOrNamespaceDeclaration(inner, true);
|
|
node.body = inner;
|
|
} else {
|
|
this.scope.enter(1024);
|
|
this.prodParam.enter(0);
|
|
node.body = this.tsParseModuleBlock();
|
|
this.prodParam.exit();
|
|
this.scope.exit();
|
|
}
|
|
return this.finishNode(node, "TSModuleDeclaration");
|
|
}
|
|
tsParseAmbientExternalModuleDeclaration(node) {
|
|
if (this.isContextual(112)) {
|
|
node.kind = "global";
|
|
{
|
|
node.global = true;
|
|
}
|
|
node.id = this.parseIdentifier();
|
|
} else if (this.match(134)) {
|
|
node.kind = "module";
|
|
node.id = super.parseStringLiteral(this.state.value);
|
|
} else {
|
|
this.unexpected();
|
|
}
|
|
if (this.match(5)) {
|
|
this.scope.enter(1024);
|
|
this.prodParam.enter(0);
|
|
node.body = this.tsParseModuleBlock();
|
|
this.prodParam.exit();
|
|
this.scope.exit();
|
|
} else {
|
|
this.semicolon();
|
|
}
|
|
return this.finishNode(node, "TSModuleDeclaration");
|
|
}
|
|
tsParseImportEqualsDeclaration(node, maybeDefaultIdentifier, isExport) {
|
|
{
|
|
node.isExport = isExport || false;
|
|
}
|
|
node.id = maybeDefaultIdentifier || this.parseIdentifier();
|
|
this.checkIdentifier(node.id, 4096);
|
|
this.expect(29);
|
|
const moduleReference = this.tsParseModuleReference();
|
|
if (node.importKind === "type" && moduleReference.type !== "TSExternalModuleReference") {
|
|
this.raise(TSErrors.ImportAliasHasImportType, moduleReference);
|
|
}
|
|
node.moduleReference = moduleReference;
|
|
this.semicolon();
|
|
return this.finishNode(node, "TSImportEqualsDeclaration");
|
|
}
|
|
tsIsExternalModuleReference() {
|
|
return this.isContextual(119) && this.lookaheadCharCode() === 40;
|
|
}
|
|
tsParseModuleReference() {
|
|
return this.tsIsExternalModuleReference() ? this.tsParseExternalModuleReference() : this.tsParseEntityName(0);
|
|
}
|
|
tsParseExternalModuleReference() {
|
|
const node = this.startNode();
|
|
this.expectContextual(119);
|
|
this.expect(10);
|
|
if (!this.match(134)) {
|
|
this.unexpected();
|
|
}
|
|
node.expression = super.parseExprAtom();
|
|
this.expect(11);
|
|
this.sawUnambiguousESM = true;
|
|
return this.finishNode(node, "TSExternalModuleReference");
|
|
}
|
|
tsLookAhead(f) {
|
|
const state = this.state.clone();
|
|
const res = f();
|
|
this.state = state;
|
|
return res;
|
|
}
|
|
tsTryParseAndCatch(f) {
|
|
const result = this.tryParse(abort => f() || abort());
|
|
if (result.aborted || !result.node) return;
|
|
if (result.error) this.state = result.failState;
|
|
return result.node;
|
|
}
|
|
tsTryParse(f) {
|
|
const state = this.state.clone();
|
|
const result = f();
|
|
if (result !== undefined && result !== false) {
|
|
return result;
|
|
}
|
|
this.state = state;
|
|
}
|
|
tsTryParseDeclare(node) {
|
|
if (this.isLineTerminator()) {
|
|
return;
|
|
}
|
|
const startType = this.state.type;
|
|
return this.tsInAmbientContext(() => {
|
|
switch (startType) {
|
|
case 68:
|
|
node.declare = true;
|
|
return super.parseFunctionStatement(node, false, false);
|
|
case 80:
|
|
node.declare = true;
|
|
return this.parseClass(node, true, false);
|
|
case 126:
|
|
return this.tsParseEnumDeclaration(node, {
|
|
declare: true
|
|
});
|
|
case 112:
|
|
return this.tsParseAmbientExternalModuleDeclaration(node);
|
|
case 100:
|
|
if (this.state.containsEsc) {
|
|
return;
|
|
}
|
|
case 75:
|
|
case 74:
|
|
if (!this.match(75) || !this.isLookaheadContextual("enum")) {
|
|
node.declare = true;
|
|
return this.parseVarStatement(node, this.state.value, true);
|
|
}
|
|
this.expect(75);
|
|
return this.tsParseEnumDeclaration(node, {
|
|
const: true,
|
|
declare: true
|
|
});
|
|
case 107:
|
|
if (this.isUsing()) {
|
|
this.raise(TSErrors.InvalidModifierOnUsingDeclaration, this.state.startLoc, "declare");
|
|
node.declare = true;
|
|
return this.parseVarStatement(node, "using", true);
|
|
}
|
|
break;
|
|
case 96:
|
|
if (this.isAwaitUsing()) {
|
|
this.raise(TSErrors.InvalidModifierOnAwaitUsingDeclaration, this.state.startLoc, "declare");
|
|
node.declare = true;
|
|
this.next();
|
|
return this.parseVarStatement(node, "await using", true);
|
|
}
|
|
break;
|
|
case 129:
|
|
{
|
|
const result = this.tsParseInterfaceDeclaration(node, {
|
|
declare: true
|
|
});
|
|
if (result) return result;
|
|
}
|
|
default:
|
|
if (tokenIsIdentifier(startType)) {
|
|
return this.tsParseDeclaration(node, this.state.type, true, null);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
tsTryParseExportDeclaration() {
|
|
return this.tsParseDeclaration(this.startNode(), this.state.type, true, null);
|
|
}
|
|
tsParseDeclaration(node, type, next, decorators) {
|
|
switch (type) {
|
|
case 124:
|
|
if (this.tsCheckLineTerminator(next) && (this.match(80) || tokenIsIdentifier(this.state.type))) {
|
|
return this.tsParseAbstractDeclaration(node, decorators);
|
|
}
|
|
break;
|
|
case 127:
|
|
if (this.tsCheckLineTerminator(next)) {
|
|
if (this.match(134)) {
|
|
return this.tsParseAmbientExternalModuleDeclaration(node);
|
|
} else if (tokenIsIdentifier(this.state.type)) {
|
|
node.kind = "module";
|
|
return this.tsParseModuleOrNamespaceDeclaration(node);
|
|
}
|
|
}
|
|
break;
|
|
case 128:
|
|
if (this.tsCheckLineTerminator(next) && tokenIsIdentifier(this.state.type)) {
|
|
node.kind = "namespace";
|
|
return this.tsParseModuleOrNamespaceDeclaration(node);
|
|
}
|
|
break;
|
|
case 130:
|
|
if (this.tsCheckLineTerminator(next) && tokenIsIdentifier(this.state.type)) {
|
|
return this.tsParseTypeAliasDeclaration(node);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
tsCheckLineTerminator(next) {
|
|
if (next) {
|
|
if (this.hasFollowingLineBreak()) return false;
|
|
this.next();
|
|
return true;
|
|
}
|
|
return !this.isLineTerminator();
|
|
}
|
|
tsTryParseGenericAsyncArrowFunction(startLoc) {
|
|
if (!this.match(47)) return;
|
|
const oldMaybeInArrowParameters = this.state.maybeInArrowParameters;
|
|
this.state.maybeInArrowParameters = true;
|
|
const res = this.tsTryParseAndCatch(() => {
|
|
const node = this.startNodeAt(startLoc);
|
|
node.typeParameters = this.tsParseTypeParameters(this.tsParseConstModifier);
|
|
super.parseFunctionParams(node);
|
|
node.returnType = this.tsTryParseTypeOrTypePredicateAnnotation();
|
|
this.expect(19);
|
|
return node;
|
|
});
|
|
this.state.maybeInArrowParameters = oldMaybeInArrowParameters;
|
|
if (!res) return;
|
|
return super.parseArrowExpression(res, null, true);
|
|
}
|
|
tsParseTypeArgumentsInExpression() {
|
|
if (this.reScan_lt() !== 47) return;
|
|
return this.tsParseTypeArguments();
|
|
}
|
|
tsParseTypeArguments() {
|
|
const node = this.startNode();
|
|
node.params = this.tsInType(() => this.tsInTopLevelContext(() => {
|
|
this.expect(47);
|
|
return this.tsParseDelimitedList("TypeParametersOrArguments", this.tsParseType.bind(this));
|
|
}));
|
|
if (node.params.length === 0) {
|
|
this.raise(TSErrors.EmptyTypeArguments, node);
|
|
} else if (!this.state.inType && this.curContext() === types.brace) {
|
|
this.reScan_lt_gt();
|
|
}
|
|
this.expect(48);
|
|
return this.finishNode(node, "TSTypeParameterInstantiation");
|
|
}
|
|
tsIsDeclarationStart() {
|
|
return tokenIsTSDeclarationStart(this.state.type);
|
|
}
|
|
isExportDefaultSpecifier() {
|
|
if (this.tsIsDeclarationStart()) return false;
|
|
return super.isExportDefaultSpecifier();
|
|
}
|
|
parseBindingElement(flags, decorators) {
|
|
const startLoc = decorators.length ? decorators[0].loc.start : this.state.startLoc;
|
|
const modified = {};
|
|
this.tsParseModifiers({
|
|
allowedModifiers: ["public", "private", "protected", "override", "readonly"]
|
|
}, modified);
|
|
const accessibility = modified.accessibility;
|
|
const override = modified.override;
|
|
const readonly = modified.readonly;
|
|
if (!(flags & 4) && (accessibility || readonly || override)) {
|
|
this.raise(TSErrors.UnexpectedParameterModifier, startLoc);
|
|
}
|
|
const left = this.parseMaybeDefault();
|
|
if (flags & 2) {
|
|
this.parseFunctionParamType(left);
|
|
}
|
|
const elt = this.parseMaybeDefault(left.loc.start, left);
|
|
if (accessibility || readonly || override) {
|
|
const pp = this.startNodeAt(startLoc);
|
|
if (decorators.length) {
|
|
pp.decorators = decorators;
|
|
}
|
|
if (accessibility) pp.accessibility = accessibility;
|
|
if (readonly) pp.readonly = readonly;
|
|
if (override) pp.override = override;
|
|
if (elt.type !== "Identifier" && elt.type !== "AssignmentPattern") {
|
|
this.raise(TSErrors.UnsupportedParameterPropertyKind, pp);
|
|
}
|
|
pp.parameter = elt;
|
|
return this.finishNode(pp, "TSParameterProperty");
|
|
}
|
|
if (decorators.length) {
|
|
left.decorators = decorators;
|
|
}
|
|
return elt;
|
|
}
|
|
isSimpleParameter(node) {
|
|
return node.type === "TSParameterProperty" && super.isSimpleParameter(node.parameter) || super.isSimpleParameter(node);
|
|
}
|
|
tsDisallowOptionalPattern(node) {
|
|
for (const param of node.params) {
|
|
if (param.type !== "Identifier" && param.optional && !this.state.isAmbientContext) {
|
|
this.raise(TSErrors.PatternIsOptional, param);
|
|
}
|
|
}
|
|
}
|
|
setArrowFunctionParameters(node, params, trailingCommaLoc) {
|
|
super.setArrowFunctionParameters(node, params, trailingCommaLoc);
|
|
this.tsDisallowOptionalPattern(node);
|
|
}
|
|
parseFunctionBodyAndFinish(node, type, isMethod = false) {
|
|
if (this.match(14)) {
|
|
node.returnType = this.tsParseTypeOrTypePredicateAnnotation(14);
|
|
}
|
|
const bodilessType = type === "FunctionDeclaration" ? "TSDeclareFunction" : type === "ClassMethod" || type === "ClassPrivateMethod" ? "TSDeclareMethod" : undefined;
|
|
if (bodilessType && !this.match(5) && this.isLineTerminator()) {
|
|
return this.finishNode(node, bodilessType);
|
|
}
|
|
if (bodilessType === "TSDeclareFunction" && this.state.isAmbientContext) {
|
|
this.raise(TSErrors.DeclareFunctionHasImplementation, node);
|
|
if (node.declare) {
|
|
return super.parseFunctionBodyAndFinish(node, bodilessType, isMethod);
|
|
}
|
|
}
|
|
this.tsDisallowOptionalPattern(node);
|
|
return super.parseFunctionBodyAndFinish(node, type, isMethod);
|
|
}
|
|
registerFunctionStatementId(node) {
|
|
if (!node.body && node.id) {
|
|
this.checkIdentifier(node.id, 1024);
|
|
} else {
|
|
super.registerFunctionStatementId(node);
|
|
}
|
|
}
|
|
tsCheckForInvalidTypeCasts(items) {
|
|
items.forEach(node => {
|
|
if ((node == null ? void 0 : node.type) === "TSTypeCastExpression") {
|
|
this.raise(TSErrors.UnexpectedTypeAnnotation, node.typeAnnotation);
|
|
}
|
|
});
|
|
}
|
|
toReferencedList(exprList, isInParens) {
|
|
this.tsCheckForInvalidTypeCasts(exprList);
|
|
return exprList;
|
|
}
|
|
parseArrayLike(close, isTuple, refExpressionErrors) {
|
|
const node = super.parseArrayLike(close, isTuple, refExpressionErrors);
|
|
if (node.type === "ArrayExpression") {
|
|
this.tsCheckForInvalidTypeCasts(node.elements);
|
|
}
|
|
return node;
|
|
}
|
|
parseSubscript(base, startLoc, noCalls, state) {
|
|
if (!this.hasPrecedingLineBreak() && this.match(35)) {
|
|
this.state.canStartJSXElement = false;
|
|
this.next();
|
|
const nonNullExpression = this.startNodeAt(startLoc);
|
|
nonNullExpression.expression = base;
|
|
return this.finishNode(nonNullExpression, "TSNonNullExpression");
|
|
}
|
|
let isOptionalCall = false;
|
|
if (this.match(18) && this.lookaheadCharCode() === 60) {
|
|
if (noCalls) {
|
|
state.stop = true;
|
|
return base;
|
|
}
|
|
state.optionalChainMember = isOptionalCall = true;
|
|
this.next();
|
|
}
|
|
if (this.match(47) || this.match(51)) {
|
|
let missingParenErrorLoc;
|
|
const result = this.tsTryParseAndCatch(() => {
|
|
if (!noCalls && this.atPossibleAsyncArrow(base)) {
|
|
const asyncArrowFn = this.tsTryParseGenericAsyncArrowFunction(startLoc);
|
|
if (asyncArrowFn) {
|
|
state.stop = true;
|
|
return asyncArrowFn;
|
|
}
|
|
}
|
|
const typeArguments = this.tsParseTypeArgumentsInExpression();
|
|
if (!typeArguments) return;
|
|
if (isOptionalCall && !this.match(10)) {
|
|
missingParenErrorLoc = this.state.curPosition();
|
|
return;
|
|
}
|
|
if (tokenIsTemplate(this.state.type)) {
|
|
const result = super.parseTaggedTemplateExpression(base, startLoc, state);
|
|
{
|
|
result.typeParameters = typeArguments;
|
|
}
|
|
return result;
|
|
}
|
|
if (!noCalls && this.eat(10)) {
|
|
const node = this.startNodeAt(startLoc);
|
|
node.callee = base;
|
|
node.arguments = this.parseCallExpressionArguments();
|
|
this.tsCheckForInvalidTypeCasts(node.arguments);
|
|
{
|
|
node.typeParameters = typeArguments;
|
|
}
|
|
if (state.optionalChainMember) {
|
|
node.optional = isOptionalCall;
|
|
}
|
|
return this.finishCallExpression(node, state.optionalChainMember);
|
|
}
|
|
const tokenType = this.state.type;
|
|
if (tokenType === 48 || tokenType === 52 || tokenType !== 10 && tokenCanStartExpression(tokenType) && !this.hasPrecedingLineBreak()) {
|
|
return;
|
|
}
|
|
const node = this.startNodeAt(startLoc);
|
|
node.expression = base;
|
|
{
|
|
node.typeParameters = typeArguments;
|
|
}
|
|
return this.finishNode(node, "TSInstantiationExpression");
|
|
});
|
|
if (missingParenErrorLoc) {
|
|
this.unexpected(missingParenErrorLoc, 10);
|
|
}
|
|
if (result) {
|
|
if (result.type === "TSInstantiationExpression") {
|
|
if (this.match(16) || this.match(18) && this.lookaheadCharCode() !== 40) {
|
|
this.raise(TSErrors.InvalidPropertyAccessAfterInstantiationExpression, this.state.startLoc);
|
|
}
|
|
if (!this.match(16) && !this.match(18)) {
|
|
result.expression = super.stopParseSubscript(base, state);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
}
|
|
return super.parseSubscript(base, startLoc, noCalls, state);
|
|
}
|
|
parseNewCallee(node) {
|
|
var _callee$extra;
|
|
super.parseNewCallee(node);
|
|
const {
|
|
callee
|
|
} = node;
|
|
if (callee.type === "TSInstantiationExpression" && !((_callee$extra = callee.extra) != null && _callee$extra.parenthesized)) {
|
|
{
|
|
node.typeParameters = callee.typeParameters;
|
|
}
|
|
node.callee = callee.expression;
|
|
}
|
|
}
|
|
parseExprOp(left, leftStartLoc, minPrec) {
|
|
let isSatisfies;
|
|
if (tokenOperatorPrecedence(58) > minPrec && !this.hasPrecedingLineBreak() && (this.isContextual(93) || (isSatisfies = this.isContextual(120)))) {
|
|
const node = this.startNodeAt(leftStartLoc);
|
|
node.expression = left;
|
|
node.typeAnnotation = this.tsInType(() => {
|
|
this.next();
|
|
if (this.match(75)) {
|
|
if (isSatisfies) {
|
|
this.raise(Errors.UnexpectedKeyword, this.state.startLoc, {
|
|
keyword: "const"
|
|
});
|
|
}
|
|
return this.tsParseTypeReference();
|
|
}
|
|
return this.tsParseType();
|
|
});
|
|
this.finishNode(node, isSatisfies ? "TSSatisfiesExpression" : "TSAsExpression");
|
|
this.reScan_lt_gt();
|
|
return this.parseExprOp(node, leftStartLoc, minPrec);
|
|
}
|
|
return super.parseExprOp(left, leftStartLoc, minPrec);
|
|
}
|
|
checkReservedWord(word, startLoc, checkKeywords, isBinding) {
|
|
if (!this.state.isAmbientContext) {
|
|
super.checkReservedWord(word, startLoc, checkKeywords, isBinding);
|
|
}
|
|
}
|
|
checkImportReflection(node) {
|
|
super.checkImportReflection(node);
|
|
if (node.module && node.importKind !== "value") {
|
|
this.raise(TSErrors.ImportReflectionHasImportType, node.specifiers[0].loc.start);
|
|
}
|
|
}
|
|
checkDuplicateExports() {}
|
|
isPotentialImportPhase(isExport) {
|
|
if (super.isPotentialImportPhase(isExport)) return true;
|
|
if (this.isContextual(130)) {
|
|
const ch = this.lookaheadCharCode();
|
|
return isExport ? ch === 123 || ch === 42 : ch !== 61;
|
|
}
|
|
return !isExport && this.isContextual(87);
|
|
}
|
|
applyImportPhase(node, isExport, phase, loc) {
|
|
super.applyImportPhase(node, isExport, phase, loc);
|
|
if (isExport) {
|
|
node.exportKind = phase === "type" ? "type" : "value";
|
|
} else {
|
|
node.importKind = phase === "type" || phase === "typeof" ? phase : "value";
|
|
}
|
|
}
|
|
parseImport(node) {
|
|
if (this.match(134)) {
|
|
node.importKind = "value";
|
|
return super.parseImport(node);
|
|
}
|
|
let importNode;
|
|
if (tokenIsIdentifier(this.state.type) && this.lookaheadCharCode() === 61) {
|
|
node.importKind = "value";
|
|
return this.tsParseImportEqualsDeclaration(node);
|
|
} else if (this.isContextual(130)) {
|
|
const maybeDefaultIdentifier = this.parseMaybeImportPhase(node, false);
|
|
if (this.lookaheadCharCode() === 61) {
|
|
return this.tsParseImportEqualsDeclaration(node, maybeDefaultIdentifier);
|
|
} else {
|
|
importNode = super.parseImportSpecifiersAndAfter(node, maybeDefaultIdentifier);
|
|
}
|
|
} else {
|
|
importNode = super.parseImport(node);
|
|
}
|
|
if (importNode.importKind === "type" && importNode.specifiers.length > 1 && importNode.specifiers[0].type === "ImportDefaultSpecifier") {
|
|
this.raise(TSErrors.TypeImportCannotSpecifyDefaultAndNamed, importNode);
|
|
}
|
|
return importNode;
|
|
}
|
|
parseExport(node, decorators) {
|
|
if (this.match(83)) {
|
|
const nodeImportEquals = node;
|
|
this.next();
|
|
let maybeDefaultIdentifier = null;
|
|
if (this.isContextual(130) && this.isPotentialImportPhase(false)) {
|
|
maybeDefaultIdentifier = this.parseMaybeImportPhase(nodeImportEquals, false);
|
|
} else {
|
|
nodeImportEquals.importKind = "value";
|
|
}
|
|
const declaration = this.tsParseImportEqualsDeclaration(nodeImportEquals, maybeDefaultIdentifier, true);
|
|
{
|
|
return declaration;
|
|
}
|
|
} else if (this.eat(29)) {
|
|
const assign = node;
|
|
assign.expression = super.parseExpression();
|
|
this.semicolon();
|
|
this.sawUnambiguousESM = true;
|
|
return this.finishNode(assign, "TSExportAssignment");
|
|
} else if (this.eatContextual(93)) {
|
|
const decl = node;
|
|
this.expectContextual(128);
|
|
decl.id = this.parseIdentifier();
|
|
this.semicolon();
|
|
return this.finishNode(decl, "TSNamespaceExportDeclaration");
|
|
} else {
|
|
return super.parseExport(node, decorators);
|
|
}
|
|
}
|
|
isAbstractClass() {
|
|
return this.isContextual(124) && this.isLookaheadContextual("class");
|
|
}
|
|
parseExportDefaultExpression() {
|
|
if (this.isAbstractClass()) {
|
|
const cls = this.startNode();
|
|
this.next();
|
|
cls.abstract = true;
|
|
return this.parseClass(cls, true, true);
|
|
}
|
|
if (this.match(129)) {
|
|
const result = this.tsParseInterfaceDeclaration(this.startNode());
|
|
if (result) return result;
|
|
}
|
|
return super.parseExportDefaultExpression();
|
|
}
|
|
parseVarStatement(node, kind, allowMissingInitializer = false) {
|
|
const {
|
|
isAmbientContext
|
|
} = this.state;
|
|
const declaration = super.parseVarStatement(node, kind, allowMissingInitializer || isAmbientContext);
|
|
if (!isAmbientContext) return declaration;
|
|
if (!node.declare && (kind === "using" || kind === "await using")) {
|
|
this.raiseOverwrite(TSErrors.UsingDeclarationInAmbientContext, node, kind);
|
|
return declaration;
|
|
}
|
|
for (const {
|
|
id,
|
|
init
|
|
} of declaration.declarations) {
|
|
if (!init) continue;
|
|
if (kind === "var" || kind === "let" || !!id.typeAnnotation) {
|
|
this.raise(TSErrors.InitializerNotAllowedInAmbientContext, init);
|
|
} else if (!isValidAmbientConstInitializer(init, this.hasPlugin("estree"))) {
|
|
this.raise(TSErrors.ConstInitializerMustBeStringOrNumericLiteralOrLiteralEnumReference, init);
|
|
}
|
|
}
|
|
return declaration;
|
|
}
|
|
parseStatementContent(flags, decorators) {
|
|
if (!this.state.containsEsc) {
|
|
switch (this.state.type) {
|
|
case 75:
|
|
{
|
|
if (this.isLookaheadContextual("enum")) {
|
|
const node = this.startNode();
|
|
this.expect(75);
|
|
return this.tsParseEnumDeclaration(node, {
|
|
const: true
|
|
});
|
|
}
|
|
break;
|
|
}
|
|
case 124:
|
|
case 125:
|
|
{
|
|
if (this.nextTokenIsIdentifierAndNotTSRelationalOperatorOnSameLine()) {
|
|
const token = this.state.type;
|
|
const node = this.startNode();
|
|
this.next();
|
|
const declaration = token === 125 ? this.tsTryParseDeclare(node) : this.tsParseAbstractDeclaration(node, decorators);
|
|
if (declaration) {
|
|
if (token === 125) {
|
|
declaration.declare = true;
|
|
}
|
|
return declaration;
|
|
} else {
|
|
node.expression = this.createIdentifier(this.startNodeAt(node.loc.start), token === 125 ? "declare" : "abstract");
|
|
this.semicolon(false);
|
|
return this.finishNode(node, "ExpressionStatement");
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 126:
|
|
return this.tsParseEnumDeclaration(this.startNode());
|
|
case 112:
|
|
{
|
|
const nextCh = this.lookaheadCharCode();
|
|
if (nextCh === 123) {
|
|
const node = this.startNode();
|
|
return this.tsParseAmbientExternalModuleDeclaration(node);
|
|
}
|
|
break;
|
|
}
|
|
case 129:
|
|
{
|
|
const result = this.tsParseInterfaceDeclaration(this.startNode());
|
|
if (result) return result;
|
|
break;
|
|
}
|
|
case 127:
|
|
{
|
|
if (this.nextTokenIsIdentifierOrStringLiteralOnSameLine()) {
|
|
const node = this.startNode();
|
|
this.next();
|
|
return this.tsParseDeclaration(node, 127, false, decorators);
|
|
}
|
|
break;
|
|
}
|
|
case 128:
|
|
{
|
|
if (this.nextTokenIsIdentifierOnSameLine()) {
|
|
const node = this.startNode();
|
|
this.next();
|
|
return this.tsParseDeclaration(node, 128, false, decorators);
|
|
}
|
|
break;
|
|
}
|
|
case 130:
|
|
{
|
|
if (this.nextTokenIsIdentifierOnSameLine()) {
|
|
const node = this.startNode();
|
|
this.next();
|
|
return this.tsParseTypeAliasDeclaration(node);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return super.parseStatementContent(flags, decorators);
|
|
}
|
|
parseAccessModifier() {
|
|
return this.tsParseModifier(["public", "protected", "private"]);
|
|
}
|
|
tsHasSomeModifiers(member, modifiers) {
|
|
return modifiers.some(modifier => {
|
|
if (tsIsAccessModifier(modifier)) {
|
|
return member.accessibility === modifier;
|
|
}
|
|
return !!member[modifier];
|
|
});
|
|
}
|
|
tsIsStartOfStaticBlocks() {
|
|
return this.isContextual(106) && this.lookaheadCharCode() === 123;
|
|
}
|
|
parseClassMember(classBody, member, state) {
|
|
const modifiers = ["declare", "private", "public", "protected", "override", "abstract", "readonly", "static"];
|
|
this.tsParseModifiers({
|
|
allowedModifiers: modifiers,
|
|
disallowedModifiers: ["in", "out"],
|
|
stopOnStartOfClassStaticBlock: true,
|
|
errorTemplate: TSErrors.InvalidModifierOnTypeParameterPositions
|
|
}, member);
|
|
const callParseClassMemberWithIsStatic = () => {
|
|
if (this.tsIsStartOfStaticBlocks()) {
|
|
this.next();
|
|
this.next();
|
|
if (this.tsHasSomeModifiers(member, modifiers)) {
|
|
this.raise(TSErrors.StaticBlockCannotHaveModifier, this.state.curPosition());
|
|
}
|
|
super.parseClassStaticBlock(classBody, member);
|
|
} else {
|
|
this.parseClassMemberWithIsStatic(classBody, member, state, !!member.static);
|
|
}
|
|
};
|
|
if (member.declare) {
|
|
this.tsInAmbientContext(callParseClassMemberWithIsStatic);
|
|
} else {
|
|
callParseClassMemberWithIsStatic();
|
|
}
|
|
}
|
|
parseClassMemberWithIsStatic(classBody, member, state, isStatic) {
|
|
const idx = this.tsTryParseIndexSignature(member);
|
|
if (idx) {
|
|
classBody.body.push(idx);
|
|
if (member.abstract) {
|
|
this.raise(TSErrors.IndexSignatureHasAbstract, member);
|
|
}
|
|
if (member.accessibility) {
|
|
this.raise(TSErrors.IndexSignatureHasAccessibility, member, {
|
|
modifier: member.accessibility
|
|
});
|
|
}
|
|
if (member.declare) {
|
|
this.raise(TSErrors.IndexSignatureHasDeclare, member);
|
|
}
|
|
if (member.override) {
|
|
this.raise(TSErrors.IndexSignatureHasOverride, member);
|
|
}
|
|
return;
|
|
}
|
|
if (!this.state.inAbstractClass && member.abstract) {
|
|
this.raise(TSErrors.NonAbstractClassHasAbstractMethod, member);
|
|
}
|
|
if (member.override) {
|
|
if (!state.hadSuperClass) {
|
|
this.raise(TSErrors.OverrideNotInSubClass, member);
|
|
}
|
|
}
|
|
super.parseClassMemberWithIsStatic(classBody, member, state, isStatic);
|
|
}
|
|
parsePostMemberNameModifiers(methodOrProp) {
|
|
const optional = this.eat(17);
|
|
if (optional) methodOrProp.optional = true;
|
|
if (methodOrProp.readonly && this.match(10)) {
|
|
this.raise(TSErrors.ClassMethodHasReadonly, methodOrProp);
|
|
}
|
|
if (methodOrProp.declare && this.match(10)) {
|
|
this.raise(TSErrors.ClassMethodHasDeclare, methodOrProp);
|
|
}
|
|
}
|
|
shouldParseExportDeclaration() {
|
|
if (this.tsIsDeclarationStart()) return true;
|
|
return super.shouldParseExportDeclaration();
|
|
}
|
|
parseConditional(expr, startLoc, refExpressionErrors) {
|
|
if (!this.match(17)) return expr;
|
|
if (this.state.maybeInArrowParameters) {
|
|
const nextCh = this.lookaheadCharCode();
|
|
if (nextCh === 44 || nextCh === 61 || nextCh === 58 || nextCh === 41) {
|
|
this.setOptionalParametersError(refExpressionErrors);
|
|
return expr;
|
|
}
|
|
}
|
|
return super.parseConditional(expr, startLoc, refExpressionErrors);
|
|
}
|
|
parseParenItem(node, startLoc) {
|
|
const newNode = super.parseParenItem(node, startLoc);
|
|
if (this.eat(17)) {
|
|
newNode.optional = true;
|
|
this.resetEndLocation(node);
|
|
}
|
|
if (this.match(14)) {
|
|
const typeCastNode = this.startNodeAt(startLoc);
|
|
typeCastNode.expression = node;
|
|
typeCastNode.typeAnnotation = this.tsParseTypeAnnotation();
|
|
return this.finishNode(typeCastNode, "TSTypeCastExpression");
|
|
}
|
|
return node;
|
|
}
|
|
parseExportDeclaration(node) {
|
|
if (!this.state.isAmbientContext && this.isContextual(125)) {
|
|
return this.tsInAmbientContext(() => this.parseExportDeclaration(node));
|
|
}
|
|
const startLoc = this.state.startLoc;
|
|
const isDeclare = this.eatContextual(125);
|
|
if (isDeclare && (this.isContextual(125) || !this.shouldParseExportDeclaration())) {
|
|
throw this.raise(TSErrors.ExpectedAmbientAfterExportDeclare, this.state.startLoc);
|
|
}
|
|
const isIdentifier = tokenIsIdentifier(this.state.type);
|
|
const declaration = isIdentifier && this.tsTryParseExportDeclaration() || super.parseExportDeclaration(node);
|
|
if (!declaration) return null;
|
|
if (declaration.type === "TSInterfaceDeclaration" || declaration.type === "TSTypeAliasDeclaration" || isDeclare) {
|
|
node.exportKind = "type";
|
|
}
|
|
if (isDeclare && declaration.type !== "TSImportEqualsDeclaration") {
|
|
this.resetStartLocation(declaration, startLoc);
|
|
declaration.declare = true;
|
|
}
|
|
return declaration;
|
|
}
|
|
parseClassId(node, isStatement, optionalId, bindingType) {
|
|
if ((!isStatement || optionalId) && this.isContextual(113)) {
|
|
return;
|
|
}
|
|
super.parseClassId(node, isStatement, optionalId, node.declare ? 1024 : 8331);
|
|
const typeParameters = this.tsTryParseTypeParameters(this.tsParseInOutConstModifiers);
|
|
if (typeParameters) node.typeParameters = typeParameters;
|
|
}
|
|
parseClassPropertyAnnotation(node) {
|
|
if (!node.optional) {
|
|
if (this.eat(35)) {
|
|
node.definite = true;
|
|
} else if (this.eat(17)) {
|
|
node.optional = true;
|
|
}
|
|
}
|
|
const type = this.tsTryParseTypeAnnotation();
|
|
if (type) node.typeAnnotation = type;
|
|
}
|
|
parseClassProperty(node) {
|
|
this.parseClassPropertyAnnotation(node);
|
|
if (this.state.isAmbientContext && !(node.readonly && !node.typeAnnotation) && this.match(29)) {
|
|
this.raise(TSErrors.DeclareClassFieldHasInitializer, this.state.startLoc);
|
|
}
|
|
if (node.abstract && this.match(29)) {
|
|
const {
|
|
key
|
|
} = node;
|
|
this.raise(TSErrors.AbstractPropertyHasInitializer, this.state.startLoc, {
|
|
propertyName: key.type === "Identifier" && !node.computed ? key.name : `[${this.input.slice(this.offsetToSourcePos(key.start), this.offsetToSourcePos(key.end))}]`
|
|
});
|
|
}
|
|
return super.parseClassProperty(node);
|
|
}
|
|
parseClassPrivateProperty(node) {
|
|
if (node.abstract) {
|
|
this.raise(TSErrors.PrivateElementHasAbstract, node);
|
|
}
|
|
if (node.accessibility) {
|
|
this.raise(TSErrors.PrivateElementHasAccessibility, node, {
|
|
modifier: node.accessibility
|
|
});
|
|
}
|
|
this.parseClassPropertyAnnotation(node);
|
|
return super.parseClassPrivateProperty(node);
|
|
}
|
|
parseClassAccessorProperty(node) {
|
|
this.parseClassPropertyAnnotation(node);
|
|
if (node.optional) {
|
|
this.raise(TSErrors.AccessorCannotBeOptional, node);
|
|
}
|
|
return super.parseClassAccessorProperty(node);
|
|
}
|
|
pushClassMethod(classBody, method, isGenerator, isAsync, isConstructor, allowsDirectSuper) {
|
|
const typeParameters = this.tsTryParseTypeParameters(this.tsParseConstModifier);
|
|
if (typeParameters && isConstructor) {
|
|
this.raise(TSErrors.ConstructorHasTypeParameters, typeParameters);
|
|
}
|
|
const {
|
|
declare = false,
|
|
kind
|
|
} = method;
|
|
if (declare && (kind === "get" || kind === "set")) {
|
|
this.raise(TSErrors.DeclareAccessor, method, {
|
|
kind
|
|
});
|
|
}
|
|
if (typeParameters) method.typeParameters = typeParameters;
|
|
super.pushClassMethod(classBody, method, isGenerator, isAsync, isConstructor, allowsDirectSuper);
|
|
}
|
|
pushClassPrivateMethod(classBody, method, isGenerator, isAsync) {
|
|
const typeParameters = this.tsTryParseTypeParameters(this.tsParseConstModifier);
|
|
if (typeParameters) method.typeParameters = typeParameters;
|
|
super.pushClassPrivateMethod(classBody, method, isGenerator, isAsync);
|
|
}
|
|
declareClassPrivateMethodInScope(node, kind) {
|
|
if (node.type === "TSDeclareMethod") return;
|
|
if (node.type === "MethodDefinition" && node.value.body == null) {
|
|
return;
|
|
}
|
|
super.declareClassPrivateMethodInScope(node, kind);
|
|
}
|
|
parseClassSuper(node) {
|
|
super.parseClassSuper(node);
|
|
if (node.superClass && (this.match(47) || this.match(51))) {
|
|
{
|
|
node.superTypeParameters = this.tsParseTypeArgumentsInExpression();
|
|
}
|
|
}
|
|
if (this.eatContextual(113)) {
|
|
node.implements = this.tsParseHeritageClause("implements");
|
|
}
|
|
}
|
|
parseObjPropValue(prop, startLoc, isGenerator, isAsync, isPattern, isAccessor, refExpressionErrors) {
|
|
const typeParameters = this.tsTryParseTypeParameters(this.tsParseConstModifier);
|
|
if (typeParameters) prop.typeParameters = typeParameters;
|
|
return super.parseObjPropValue(prop, startLoc, isGenerator, isAsync, isPattern, isAccessor, refExpressionErrors);
|
|
}
|
|
parseFunctionParams(node, isConstructor) {
|
|
const typeParameters = this.tsTryParseTypeParameters(this.tsParseConstModifier);
|
|
if (typeParameters) node.typeParameters = typeParameters;
|
|
super.parseFunctionParams(node, isConstructor);
|
|
}
|
|
parseVarId(decl, kind) {
|
|
super.parseVarId(decl, kind);
|
|
if (decl.id.type === "Identifier" && !this.hasPrecedingLineBreak() && this.eat(35)) {
|
|
decl.definite = true;
|
|
}
|
|
const type = this.tsTryParseTypeAnnotation();
|
|
if (type) {
|
|
decl.id.typeAnnotation = type;
|
|
this.resetEndLocation(decl.id);
|
|
}
|
|
}
|
|
parseAsyncArrowFromCallExpression(node, call) {
|
|
if (this.match(14)) {
|
|
node.returnType = this.tsParseTypeAnnotation();
|
|
}
|
|
return super.parseAsyncArrowFromCallExpression(node, call);
|
|
}
|
|
parseMaybeAssign(refExpressionErrors, afterLeftParse) {
|
|
var _jsx, _jsx2, _typeCast, _jsx3, _typeCast2;
|
|
let state;
|
|
let jsx;
|
|
let typeCast;
|
|
if (this.hasPlugin("jsx") && (this.match(143) || this.match(47))) {
|
|
state = this.state.clone();
|
|
jsx = this.tryParse(() => super.parseMaybeAssign(refExpressionErrors, afterLeftParse), state);
|
|
if (!jsx.error) return jsx.node;
|
|
const {
|
|
context
|
|
} = this.state;
|
|
const currentContext = context[context.length - 1];
|
|
if (currentContext === types.j_oTag || currentContext === types.j_expr) {
|
|
context.pop();
|
|
}
|
|
}
|
|
if (!((_jsx = jsx) != null && _jsx.error) && !this.match(47)) {
|
|
return super.parseMaybeAssign(refExpressionErrors, afterLeftParse);
|
|
}
|
|
if (!state || state === this.state) state = this.state.clone();
|
|
let typeParameters;
|
|
const arrow = this.tryParse(abort => {
|
|
var _expr$extra, _typeParameters;
|
|
typeParameters = this.tsParseTypeParameters(this.tsParseConstModifier);
|
|
const expr = super.parseMaybeAssign(refExpressionErrors, afterLeftParse);
|
|
if (expr.type !== "ArrowFunctionExpression" || (_expr$extra = expr.extra) != null && _expr$extra.parenthesized) {
|
|
abort();
|
|
}
|
|
if (((_typeParameters = typeParameters) == null ? void 0 : _typeParameters.params.length) !== 0) {
|
|
this.resetStartLocationFromNode(expr, typeParameters);
|
|
}
|
|
expr.typeParameters = typeParameters;
|
|
return expr;
|
|
}, state);
|
|
if (!arrow.error && !arrow.aborted) {
|
|
if (typeParameters) this.reportReservedArrowTypeParam(typeParameters);
|
|
return arrow.node;
|
|
}
|
|
if (!jsx) {
|
|
assert(!this.hasPlugin("jsx"));
|
|
typeCast = this.tryParse(() => super.parseMaybeAssign(refExpressionErrors, afterLeftParse), state);
|
|
if (!typeCast.error) return typeCast.node;
|
|
}
|
|
if ((_jsx2 = jsx) != null && _jsx2.node) {
|
|
this.state = jsx.failState;
|
|
return jsx.node;
|
|
}
|
|
if (arrow.node) {
|
|
this.state = arrow.failState;
|
|
if (typeParameters) this.reportReservedArrowTypeParam(typeParameters);
|
|
return arrow.node;
|
|
}
|
|
if ((_typeCast = typeCast) != null && _typeCast.node) {
|
|
this.state = typeCast.failState;
|
|
return typeCast.node;
|
|
}
|
|
throw ((_jsx3 = jsx) == null ? void 0 : _jsx3.error) || arrow.error || ((_typeCast2 = typeCast) == null ? void 0 : _typeCast2.error);
|
|
}
|
|
reportReservedArrowTypeParam(node) {
|
|
var _node$extra2;
|
|
if (node.params.length === 1 && !node.params[0].constraint && !((_node$extra2 = node.extra) != null && _node$extra2.trailingComma) && this.getPluginOption("typescript", "disallowAmbiguousJSXLike")) {
|
|
this.raise(TSErrors.ReservedArrowTypeParam, node);
|
|
}
|
|
}
|
|
parseMaybeUnary(refExpressionErrors, sawUnary) {
|
|
if (!this.hasPlugin("jsx") && this.match(47)) {
|
|
return this.tsParseTypeAssertion();
|
|
}
|
|
return super.parseMaybeUnary(refExpressionErrors, sawUnary);
|
|
}
|
|
parseArrow(node) {
|
|
if (this.match(14)) {
|
|
const result = this.tryParse(abort => {
|
|
const returnType = this.tsParseTypeOrTypePredicateAnnotation(14);
|
|
if (this.canInsertSemicolon() || !this.match(19)) abort();
|
|
return returnType;
|
|
});
|
|
if (result.aborted) return;
|
|
if (!result.thrown) {
|
|
if (result.error) this.state = result.failState;
|
|
node.returnType = result.node;
|
|
}
|
|
}
|
|
return super.parseArrow(node);
|
|
}
|
|
parseFunctionParamType(param) {
|
|
if (this.eat(17)) {
|
|
param.optional = true;
|
|
}
|
|
const type = this.tsTryParseTypeAnnotation();
|
|
if (type) param.typeAnnotation = type;
|
|
this.resetEndLocation(param);
|
|
return param;
|
|
}
|
|
isAssignable(node, isBinding) {
|
|
switch (node.type) {
|
|
case "TSTypeCastExpression":
|
|
return this.isAssignable(node.expression, isBinding);
|
|
case "TSParameterProperty":
|
|
return true;
|
|
default:
|
|
return super.isAssignable(node, isBinding);
|
|
}
|
|
}
|
|
toAssignable(node, isLHS = false) {
|
|
switch (node.type) {
|
|
case "ParenthesizedExpression":
|
|
this.toAssignableParenthesizedExpression(node, isLHS);
|
|
break;
|
|
case "TSAsExpression":
|
|
case "TSSatisfiesExpression":
|
|
case "TSNonNullExpression":
|
|
case "TSTypeAssertion":
|
|
if (isLHS) {
|
|
this.expressionScope.recordArrowParameterBindingError(TSErrors.UnexpectedTypeCastInParameter, node);
|
|
} else {
|
|
this.raise(TSErrors.UnexpectedTypeCastInParameter, node);
|
|
}
|
|
this.toAssignable(node.expression, isLHS);
|
|
break;
|
|
case "AssignmentExpression":
|
|
if (!isLHS && node.left.type === "TSTypeCastExpression") {
|
|
node.left = this.typeCastToParameter(node.left);
|
|
}
|
|
default:
|
|
super.toAssignable(node, isLHS);
|
|
}
|
|
}
|
|
toAssignableParenthesizedExpression(node, isLHS) {
|
|
switch (node.expression.type) {
|
|
case "TSAsExpression":
|
|
case "TSSatisfiesExpression":
|
|
case "TSNonNullExpression":
|
|
case "TSTypeAssertion":
|
|
case "ParenthesizedExpression":
|
|
this.toAssignable(node.expression, isLHS);
|
|
break;
|
|
default:
|
|
super.toAssignable(node, isLHS);
|
|
}
|
|
}
|
|
checkToRestConversion(node, allowPattern) {
|
|
switch (node.type) {
|
|
case "TSAsExpression":
|
|
case "TSSatisfiesExpression":
|
|
case "TSTypeAssertion":
|
|
case "TSNonNullExpression":
|
|
this.checkToRestConversion(node.expression, false);
|
|
break;
|
|
default:
|
|
super.checkToRestConversion(node, allowPattern);
|
|
}
|
|
}
|
|
isValidLVal(type, disallowCallExpression, isUnparenthesizedInAssign, binding) {
|
|
switch (type) {
|
|
case "TSTypeCastExpression":
|
|
return true;
|
|
case "TSParameterProperty":
|
|
return "parameter";
|
|
case "TSNonNullExpression":
|
|
return "expression";
|
|
case "TSAsExpression":
|
|
case "TSSatisfiesExpression":
|
|
case "TSTypeAssertion":
|
|
return (binding !== 64 || !isUnparenthesizedInAssign) && ["expression", true];
|
|
default:
|
|
return super.isValidLVal(type, disallowCallExpression, isUnparenthesizedInAssign, binding);
|
|
}
|
|
}
|
|
parseBindingAtom() {
|
|
if (this.state.type === 78) {
|
|
return this.parseIdentifier(true);
|
|
}
|
|
return super.parseBindingAtom();
|
|
}
|
|
parseMaybeDecoratorArguments(expr, startLoc) {
|
|
if (this.match(47) || this.match(51)) {
|
|
const typeArguments = this.tsParseTypeArgumentsInExpression();
|
|
if (this.match(10)) {
|
|
const call = super.parseMaybeDecoratorArguments(expr, startLoc);
|
|
{
|
|
call.typeParameters = typeArguments;
|
|
}
|
|
return call;
|
|
}
|
|
this.unexpected(null, 10);
|
|
}
|
|
return super.parseMaybeDecoratorArguments(expr, startLoc);
|
|
}
|
|
checkCommaAfterRest(close) {
|
|
if (this.state.isAmbientContext && this.match(12) && this.lookaheadCharCode() === close) {
|
|
this.next();
|
|
return false;
|
|
}
|
|
return super.checkCommaAfterRest(close);
|
|
}
|
|
isClassMethod() {
|
|
return this.match(47) || super.isClassMethod();
|
|
}
|
|
isClassProperty() {
|
|
return this.match(35) || this.match(14) || super.isClassProperty();
|
|
}
|
|
parseMaybeDefault(startLoc, left) {
|
|
const node = super.parseMaybeDefault(startLoc, left);
|
|
if (node.type === "AssignmentPattern" && node.typeAnnotation && node.right.start < node.typeAnnotation.start) {
|
|
this.raise(TSErrors.TypeAnnotationAfterAssign, node.typeAnnotation);
|
|
}
|
|
return node;
|
|
}
|
|
getTokenFromCode(code) {
|
|
if (this.state.inType) {
|
|
if (code === 62) {
|
|
this.finishOp(48, 1);
|
|
return;
|
|
}
|
|
if (code === 60) {
|
|
this.finishOp(47, 1);
|
|
return;
|
|
}
|
|
}
|
|
super.getTokenFromCode(code);
|
|
}
|
|
reScan_lt_gt() {
|
|
const {
|
|
type
|
|
} = this.state;
|
|
if (type === 47) {
|
|
this.state.pos -= 1;
|
|
this.readToken_lt();
|
|
} else if (type === 48) {
|
|
this.state.pos -= 1;
|
|
this.readToken_gt();
|
|
}
|
|
}
|
|
reScan_lt() {
|
|
const {
|
|
type
|
|
} = this.state;
|
|
if (type === 51) {
|
|
this.state.pos -= 2;
|
|
this.finishOp(47, 1);
|
|
return 47;
|
|
}
|
|
return type;
|
|
}
|
|
toAssignableListItem(exprList, index, isLHS) {
|
|
const node = exprList[index];
|
|
if (node.type === "TSTypeCastExpression") {
|
|
exprList[index] = this.typeCastToParameter(node);
|
|
}
|
|
super.toAssignableListItem(exprList, index, isLHS);
|
|
}
|
|
typeCastToParameter(node) {
|
|
node.expression.typeAnnotation = node.typeAnnotation;
|
|
this.resetEndLocation(node.expression, node.typeAnnotation.loc.end);
|
|
return node.expression;
|
|
}
|
|
shouldParseArrow(params) {
|
|
if (this.match(14)) {
|
|
return params.every(expr => this.isAssignable(expr, true));
|
|
}
|
|
return super.shouldParseArrow(params);
|
|
}
|
|
shouldParseAsyncArrow() {
|
|
return this.match(14) || super.shouldParseAsyncArrow();
|
|
}
|
|
canHaveLeadingDecorator() {
|
|
return super.canHaveLeadingDecorator() || this.isAbstractClass();
|
|
}
|
|
jsxParseOpeningElementAfterName(node) {
|
|
if (this.match(47) || this.match(51)) {
|
|
const typeArguments = this.tsTryParseAndCatch(() => this.tsParseTypeArgumentsInExpression());
|
|
if (typeArguments) {
|
|
{
|
|
node.typeParameters = typeArguments;
|
|
}
|
|
}
|
|
}
|
|
return super.jsxParseOpeningElementAfterName(node);
|
|
}
|
|
getGetterSetterExpectedParamCount(method) {
|
|
const baseCount = super.getGetterSetterExpectedParamCount(method);
|
|
const params = this.getObjectOrClassMethodParams(method);
|
|
const firstParam = params[0];
|
|
const hasContextParam = firstParam && this.isThisParam(firstParam);
|
|
return hasContextParam ? baseCount + 1 : baseCount;
|
|
}
|
|
parseCatchClauseParam() {
|
|
const param = super.parseCatchClauseParam();
|
|
const type = this.tsTryParseTypeAnnotation();
|
|
if (type) {
|
|
param.typeAnnotation = type;
|
|
this.resetEndLocation(param);
|
|
}
|
|
return param;
|
|
}
|
|
tsInAmbientContext(cb) {
|
|
const {
|
|
isAmbientContext: oldIsAmbientContext,
|
|
strict: oldStrict
|
|
} = this.state;
|
|
this.state.isAmbientContext = true;
|
|
this.state.strict = false;
|
|
try {
|
|
return cb();
|
|
} finally {
|
|
this.state.isAmbientContext = oldIsAmbientContext;
|
|
this.state.strict = oldStrict;
|
|
}
|
|
}
|
|
parseClass(node, isStatement, optionalId) {
|
|
const oldInAbstractClass = this.state.inAbstractClass;
|
|
this.state.inAbstractClass = !!node.abstract;
|
|
try {
|
|
return super.parseClass(node, isStatement, optionalId);
|
|
} finally {
|
|
this.state.inAbstractClass = oldInAbstractClass;
|
|
}
|
|
}
|
|
tsParseAbstractDeclaration(node, decorators) {
|
|
if (this.match(80)) {
|
|
node.abstract = true;
|
|
return this.maybeTakeDecorators(decorators, this.parseClass(node, true, false));
|
|
} else if (this.isContextual(129)) {
|
|
if (!this.hasFollowingLineBreak()) {
|
|
node.abstract = true;
|
|
this.raise(TSErrors.NonClassMethodPropertyHasAbstractModifier, node);
|
|
return this.tsParseInterfaceDeclaration(node);
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
throw this.unexpected(null, 80);
|
|
}
|
|
parseMethod(node, isGenerator, isAsync, isConstructor, allowDirectSuper, type, inClassScope) {
|
|
const method = super.parseMethod(node, isGenerator, isAsync, isConstructor, allowDirectSuper, type, inClassScope);
|
|
if (method.abstract || method.type === "TSAbstractMethodDefinition") {
|
|
const hasEstreePlugin = this.hasPlugin("estree");
|
|
const methodFn = hasEstreePlugin ? method.value : method;
|
|
if (methodFn.body) {
|
|
const {
|
|
key
|
|
} = method;
|
|
this.raise(TSErrors.AbstractMethodHasImplementation, method, {
|
|
methodName: key.type === "Identifier" && !method.computed ? key.name : `[${this.input.slice(this.offsetToSourcePos(key.start), this.offsetToSourcePos(key.end))}]`
|
|
});
|
|
}
|
|
}
|
|
return method;
|
|
}
|
|
tsParseTypeParameterName() {
|
|
const typeName = this.parseIdentifier();
|
|
return typeName.name;
|
|
}
|
|
shouldParseAsAmbientContext() {
|
|
return !!this.getPluginOption("typescript", "dts");
|
|
}
|
|
parse() {
|
|
if (this.shouldParseAsAmbientContext()) {
|
|
this.state.isAmbientContext = true;
|
|
}
|
|
return super.parse();
|
|
}
|
|
getExpression() {
|
|
if (this.shouldParseAsAmbientContext()) {
|
|
this.state.isAmbientContext = true;
|
|
}
|
|
return super.getExpression();
|
|
}
|
|
parseExportSpecifier(node, isString, isInTypeExport, isMaybeTypeOnly) {
|
|
if (!isString && isMaybeTypeOnly) {
|
|
this.parseTypeOnlyImportExportSpecifier(node, false, isInTypeExport);
|
|
return this.finishNode(node, "ExportSpecifier");
|
|
}
|
|
node.exportKind = "value";
|
|
return super.parseExportSpecifier(node, isString, isInTypeExport, isMaybeTypeOnly);
|
|
}
|
|
parseImportSpecifier(specifier, importedIsString, isInTypeOnlyImport, isMaybeTypeOnly, bindingType) {
|
|
if (!importedIsString && isMaybeTypeOnly) {
|
|
this.parseTypeOnlyImportExportSpecifier(specifier, true, isInTypeOnlyImport);
|
|
return this.finishNode(specifier, "ImportSpecifier");
|
|
}
|
|
specifier.importKind = "value";
|
|
return super.parseImportSpecifier(specifier, importedIsString, isInTypeOnlyImport, isMaybeTypeOnly, isInTypeOnlyImport ? 4098 : 4096);
|
|
}
|
|
parseTypeOnlyImportExportSpecifier(node, isImport, isInTypeOnlyImportExport) {
|
|
const leftOfAsKey = isImport ? "imported" : "local";
|
|
const rightOfAsKey = isImport ? "local" : "exported";
|
|
let leftOfAs = node[leftOfAsKey];
|
|
let rightOfAs;
|
|
let hasTypeSpecifier = false;
|
|
let canParseAsKeyword = true;
|
|
const loc = leftOfAs.loc.start;
|
|
if (this.isContextual(93)) {
|
|
const firstAs = this.parseIdentifier();
|
|
if (this.isContextual(93)) {
|
|
const secondAs = this.parseIdentifier();
|
|
if (tokenIsKeywordOrIdentifier(this.state.type)) {
|
|
hasTypeSpecifier = true;
|
|
leftOfAs = firstAs;
|
|
rightOfAs = isImport ? this.parseIdentifier() : this.parseModuleExportName();
|
|
canParseAsKeyword = false;
|
|
} else {
|
|
rightOfAs = secondAs;
|
|
canParseAsKeyword = false;
|
|
}
|
|
} else if (tokenIsKeywordOrIdentifier(this.state.type)) {
|
|
canParseAsKeyword = false;
|
|
rightOfAs = isImport ? this.parseIdentifier() : this.parseModuleExportName();
|
|
} else {
|
|
hasTypeSpecifier = true;
|
|
leftOfAs = firstAs;
|
|
}
|
|
} else if (tokenIsKeywordOrIdentifier(this.state.type)) {
|
|
hasTypeSpecifier = true;
|
|
if (isImport) {
|
|
leftOfAs = this.parseIdentifier(true);
|
|
if (!this.isContextual(93)) {
|
|
this.checkReservedWord(leftOfAs.name, leftOfAs.loc.start, true, true);
|
|
}
|
|
} else {
|
|
leftOfAs = this.parseModuleExportName();
|
|
}
|
|
}
|
|
if (hasTypeSpecifier && isInTypeOnlyImportExport) {
|
|
this.raise(isImport ? TSErrors.TypeModifierIsUsedInTypeImports : TSErrors.TypeModifierIsUsedInTypeExports, loc);
|
|
}
|
|
node[leftOfAsKey] = leftOfAs;
|
|
node[rightOfAsKey] = rightOfAs;
|
|
const kindKey = isImport ? "importKind" : "exportKind";
|
|
node[kindKey] = hasTypeSpecifier ? "type" : "value";
|
|
if (canParseAsKeyword && this.eatContextual(93)) {
|
|
node[rightOfAsKey] = isImport ? this.parseIdentifier() : this.parseModuleExportName();
|
|
}
|
|
if (!node[rightOfAsKey]) {
|
|
node[rightOfAsKey] = this.cloneIdentifier(node[leftOfAsKey]);
|
|
}
|
|
if (isImport) {
|
|
this.checkIdentifier(node[rightOfAsKey], hasTypeSpecifier ? 4098 : 4096);
|
|
}
|
|
}
|
|
fillOptionalPropertiesForTSESLint(node) {
|
|
var _node$directive, _node$decorators, _node$optional, _node$typeAnnotation, _node$accessibility, _node$decorators2, _node$override, _node$readonly, _node$static, _node$declare, _node$returnType, _node$typeParameters, _node$optional2, _node$optional3, _node$accessibility2, _node$readonly2, _node$static2, _node$declare2, _node$definite, _node$readonly3, _node$typeAnnotation2, _node$accessibility3, _node$decorators3, _node$override2, _node$optional4, _node$id, _node$abstract, _node$declare3, _node$decorators4, _node$implements, _node$superTypeArgume, _node$typeParameters2, _node$declare4, _node$definite2, _node$const, _node$declare5, _node$computed, _node$qualifier, _node$options, _node$declare6, _node$extends, _node$optional5, _node$readonly4, _node$declare7, _node$global, _node$const2, _node$in, _node$out;
|
|
switch (node.type) {
|
|
case "ExpressionStatement":
|
|
(_node$directive = node.directive) != null ? _node$directive : node.directive = undefined;
|
|
return;
|
|
case "RestElement":
|
|
node.value = undefined;
|
|
case "Identifier":
|
|
case "ArrayPattern":
|
|
case "AssignmentPattern":
|
|
case "ObjectPattern":
|
|
(_node$decorators = node.decorators) != null ? _node$decorators : node.decorators = [];
|
|
(_node$optional = node.optional) != null ? _node$optional : node.optional = false;
|
|
(_node$typeAnnotation = node.typeAnnotation) != null ? _node$typeAnnotation : node.typeAnnotation = undefined;
|
|
return;
|
|
case "TSParameterProperty":
|
|
(_node$accessibility = node.accessibility) != null ? _node$accessibility : node.accessibility = undefined;
|
|
(_node$decorators2 = node.decorators) != null ? _node$decorators2 : node.decorators = [];
|
|
(_node$override = node.override) != null ? _node$override : node.override = false;
|
|
(_node$readonly = node.readonly) != null ? _node$readonly : node.readonly = false;
|
|
(_node$static = node.static) != null ? _node$static : node.static = false;
|
|
return;
|
|
case "TSEmptyBodyFunctionExpression":
|
|
node.body = null;
|
|
case "TSDeclareFunction":
|
|
case "FunctionDeclaration":
|
|
case "FunctionExpression":
|
|
case "ClassMethod":
|
|
case "ClassPrivateMethod":
|
|
(_node$declare = node.declare) != null ? _node$declare : node.declare = false;
|
|
(_node$returnType = node.returnType) != null ? _node$returnType : node.returnType = undefined;
|
|
(_node$typeParameters = node.typeParameters) != null ? _node$typeParameters : node.typeParameters = undefined;
|
|
return;
|
|
case "Property":
|
|
(_node$optional2 = node.optional) != null ? _node$optional2 : node.optional = false;
|
|
return;
|
|
case "TSMethodSignature":
|
|
case "TSPropertySignature":
|
|
(_node$optional3 = node.optional) != null ? _node$optional3 : node.optional = false;
|
|
case "TSIndexSignature":
|
|
(_node$accessibility2 = node.accessibility) != null ? _node$accessibility2 : node.accessibility = undefined;
|
|
(_node$readonly2 = node.readonly) != null ? _node$readonly2 : node.readonly = false;
|
|
(_node$static2 = node.static) != null ? _node$static2 : node.static = false;
|
|
return;
|
|
case "TSAbstractPropertyDefinition":
|
|
case "PropertyDefinition":
|
|
case "TSAbstractAccessorProperty":
|
|
case "AccessorProperty":
|
|
(_node$declare2 = node.declare) != null ? _node$declare2 : node.declare = false;
|
|
(_node$definite = node.definite) != null ? _node$definite : node.definite = false;
|
|
(_node$readonly3 = node.readonly) != null ? _node$readonly3 : node.readonly = false;
|
|
(_node$typeAnnotation2 = node.typeAnnotation) != null ? _node$typeAnnotation2 : node.typeAnnotation = undefined;
|
|
case "TSAbstractMethodDefinition":
|
|
case "MethodDefinition":
|
|
(_node$accessibility3 = node.accessibility) != null ? _node$accessibility3 : node.accessibility = undefined;
|
|
(_node$decorators3 = node.decorators) != null ? _node$decorators3 : node.decorators = [];
|
|
(_node$override2 = node.override) != null ? _node$override2 : node.override = false;
|
|
(_node$optional4 = node.optional) != null ? _node$optional4 : node.optional = false;
|
|
return;
|
|
case "ClassExpression":
|
|
(_node$id = node.id) != null ? _node$id : node.id = null;
|
|
case "ClassDeclaration":
|
|
(_node$abstract = node.abstract) != null ? _node$abstract : node.abstract = false;
|
|
(_node$declare3 = node.declare) != null ? _node$declare3 : node.declare = false;
|
|
(_node$decorators4 = node.decorators) != null ? _node$decorators4 : node.decorators = [];
|
|
(_node$implements = node.implements) != null ? _node$implements : node.implements = [];
|
|
(_node$superTypeArgume = node.superTypeArguments) != null ? _node$superTypeArgume : node.superTypeArguments = undefined;
|
|
(_node$typeParameters2 = node.typeParameters) != null ? _node$typeParameters2 : node.typeParameters = undefined;
|
|
return;
|
|
case "TSTypeAliasDeclaration":
|
|
case "VariableDeclaration":
|
|
(_node$declare4 = node.declare) != null ? _node$declare4 : node.declare = false;
|
|
return;
|
|
case "VariableDeclarator":
|
|
(_node$definite2 = node.definite) != null ? _node$definite2 : node.definite = false;
|
|
return;
|
|
case "TSEnumDeclaration":
|
|
(_node$const = node.const) != null ? _node$const : node.const = false;
|
|
(_node$declare5 = node.declare) != null ? _node$declare5 : node.declare = false;
|
|
return;
|
|
case "TSEnumMember":
|
|
(_node$computed = node.computed) != null ? _node$computed : node.computed = false;
|
|
return;
|
|
case "TSImportType":
|
|
(_node$qualifier = node.qualifier) != null ? _node$qualifier : node.qualifier = null;
|
|
(_node$options = node.options) != null ? _node$options : node.options = null;
|
|
return;
|
|
case "TSInterfaceDeclaration":
|
|
(_node$declare6 = node.declare) != null ? _node$declare6 : node.declare = false;
|
|
(_node$extends = node.extends) != null ? _node$extends : node.extends = [];
|
|
return;
|
|
case "TSMappedType":
|
|
(_node$optional5 = node.optional) != null ? _node$optional5 : node.optional = false;
|
|
(_node$readonly4 = node.readonly) != null ? _node$readonly4 : node.readonly = undefined;
|
|
return;
|
|
case "TSModuleDeclaration":
|
|
(_node$declare7 = node.declare) != null ? _node$declare7 : node.declare = false;
|
|
(_node$global = node.global) != null ? _node$global : node.global = node.kind === "global";
|
|
return;
|
|
case "TSTypeParameter":
|
|
(_node$const2 = node.const) != null ? _node$const2 : node.const = false;
|
|
(_node$in = node.in) != null ? _node$in : node.in = false;
|
|
(_node$out = node.out) != null ? _node$out : node.out = false;
|
|
return;
|
|
}
|
|
}
|
|
chStartsBindingIdentifierAndNotRelationalOperator(ch, pos) {
|
|
if (isIdentifierStart(ch)) {
|
|
keywordAndTSRelationalOperator.lastIndex = pos;
|
|
if (keywordAndTSRelationalOperator.test(this.input)) {
|
|
const endCh = this.codePointAtPos(keywordAndTSRelationalOperator.lastIndex);
|
|
if (!isIdentifierChar(endCh) && endCh !== 92) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
} else if (ch === 92) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
nextTokenIsIdentifierAndNotTSRelationalOperatorOnSameLine() {
|
|
const next = this.nextTokenInLineStart();
|
|
const nextCh = this.codePointAtPos(next);
|
|
return this.chStartsBindingIdentifierAndNotRelationalOperator(nextCh, next);
|
|
}
|
|
nextTokenIsIdentifierOrStringLiteralOnSameLine() {
|
|
const next = this.nextTokenInLineStart();
|
|
const nextCh = this.codePointAtPos(next);
|
|
return this.chStartsBindingIdentifier(nextCh, next) || nextCh === 34 || nextCh === 39;
|
|
}
|
|
};
|
|
function isPossiblyLiteralEnum(expression) {
|
|
if (expression.type !== "MemberExpression") return false;
|
|
const {
|
|
computed,
|
|
property
|
|
} = expression;
|
|
if (computed && property.type !== "StringLiteral" && (property.type !== "TemplateLiteral" || property.expressions.length > 0)) {
|
|
return false;
|
|
}
|
|
return isUncomputedMemberExpressionChain(expression.object);
|
|
}
|
|
function isValidAmbientConstInitializer(expression, estree) {
|
|
var _expression$extra;
|
|
const {
|
|
type
|
|
} = expression;
|
|
if ((_expression$extra = expression.extra) != null && _expression$extra.parenthesized) {
|
|
return false;
|
|
}
|
|
if (estree) {
|
|
if (type === "Literal") {
|
|
const {
|
|
value
|
|
} = expression;
|
|
if (typeof value === "string" || typeof value === "boolean") {
|
|
return true;
|
|
}
|
|
}
|
|
} else {
|
|
if (type === "StringLiteral" || type === "BooleanLiteral") {
|
|
return true;
|
|
}
|
|
}
|
|
if (isNumber(expression, estree) || isNegativeNumber(expression, estree)) {
|
|
return true;
|
|
}
|
|
if (type === "TemplateLiteral" && expression.expressions.length === 0) {
|
|
return true;
|
|
}
|
|
if (isPossiblyLiteralEnum(expression)) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
function isNumber(expression, estree) {
|
|
if (estree) {
|
|
return expression.type === "Literal" && (typeof expression.value === "number" || "bigint" in expression);
|
|
}
|
|
return expression.type === "NumericLiteral" || expression.type === "BigIntLiteral";
|
|
}
|
|
function isNegativeNumber(expression, estree) {
|
|
if (expression.type === "UnaryExpression") {
|
|
const {
|
|
operator,
|
|
argument
|
|
} = expression;
|
|
if (operator === "-" && isNumber(argument, estree)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
function isUncomputedMemberExpressionChain(expression) {
|
|
if (expression.type === "Identifier") return true;
|
|
if (expression.type !== "MemberExpression" || expression.computed) {
|
|
return false;
|
|
}
|
|
return isUncomputedMemberExpressionChain(expression.object);
|
|
}
|
|
const PlaceholderErrors = ParseErrorEnum`placeholders`({
|
|
ClassNameIsRequired: "A class name is required.",
|
|
UnexpectedSpace: "Unexpected space in placeholder."
|
|
});
|
|
var placeholders = superClass => class PlaceholdersParserMixin extends superClass {
|
|
parsePlaceholder(expectedNode) {
|
|
if (this.match(133)) {
|
|
const node = this.startNode();
|
|
this.next();
|
|
this.assertNoSpace();
|
|
node.name = super.parseIdentifier(true);
|
|
this.assertNoSpace();
|
|
this.expect(133);
|
|
return this.finishPlaceholder(node, expectedNode);
|
|
}
|
|
}
|
|
finishPlaceholder(node, expectedNode) {
|
|
let placeholder = node;
|
|
if (!placeholder.expectedNode || !placeholder.type) {
|
|
placeholder = this.finishNode(placeholder, "Placeholder");
|
|
}
|
|
placeholder.expectedNode = expectedNode;
|
|
return placeholder;
|
|
}
|
|
getTokenFromCode(code) {
|
|
if (code === 37 && this.input.charCodeAt(this.state.pos + 1) === 37) {
|
|
this.finishOp(133, 2);
|
|
} else {
|
|
super.getTokenFromCode(code);
|
|
}
|
|
}
|
|
parseExprAtom(refExpressionErrors) {
|
|
return this.parsePlaceholder("Expression") || super.parseExprAtom(refExpressionErrors);
|
|
}
|
|
parseIdentifier(liberal) {
|
|
return this.parsePlaceholder("Identifier") || super.parseIdentifier(liberal);
|
|
}
|
|
checkReservedWord(word, startLoc, checkKeywords, isBinding) {
|
|
if (word !== undefined) {
|
|
super.checkReservedWord(word, startLoc, checkKeywords, isBinding);
|
|
}
|
|
}
|
|
cloneIdentifier(node) {
|
|
const cloned = super.cloneIdentifier(node);
|
|
if (cloned.type === "Placeholder") {
|
|
cloned.expectedNode = node.expectedNode;
|
|
}
|
|
return cloned;
|
|
}
|
|
cloneStringLiteral(node) {
|
|
if (node.type === "Placeholder") {
|
|
return this.cloneIdentifier(node);
|
|
}
|
|
return super.cloneStringLiteral(node);
|
|
}
|
|
parseBindingAtom() {
|
|
return this.parsePlaceholder("Pattern") || super.parseBindingAtom();
|
|
}
|
|
isValidLVal(type, disallowCallExpression, isParenthesized, binding) {
|
|
return type === "Placeholder" || super.isValidLVal(type, disallowCallExpression, isParenthesized, binding);
|
|
}
|
|
toAssignable(node, isLHS) {
|
|
if (node && node.type === "Placeholder" && node.expectedNode === "Expression") {
|
|
node.expectedNode = "Pattern";
|
|
} else {
|
|
super.toAssignable(node, isLHS);
|
|
}
|
|
}
|
|
chStartsBindingIdentifier(ch, pos) {
|
|
if (super.chStartsBindingIdentifier(ch, pos)) {
|
|
return true;
|
|
}
|
|
const next = this.nextTokenStart();
|
|
if (this.input.charCodeAt(next) === 37 && this.input.charCodeAt(next + 1) === 37) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
verifyBreakContinue(node, isBreak) {
|
|
if (node.label && node.label.type === "Placeholder") return;
|
|
super.verifyBreakContinue(node, isBreak);
|
|
}
|
|
parseExpressionStatement(node, expr) {
|
|
var _expr$extra;
|
|
if (expr.type !== "Placeholder" || (_expr$extra = expr.extra) != null && _expr$extra.parenthesized) {
|
|
return super.parseExpressionStatement(node, expr);
|
|
}
|
|
if (this.match(14)) {
|
|
const stmt = node;
|
|
stmt.label = this.finishPlaceholder(expr, "Identifier");
|
|
this.next();
|
|
stmt.body = super.parseStatementOrSloppyAnnexBFunctionDeclaration();
|
|
return this.finishNode(stmt, "LabeledStatement");
|
|
}
|
|
this.semicolon();
|
|
const stmtPlaceholder = node;
|
|
stmtPlaceholder.name = expr.name;
|
|
return this.finishPlaceholder(stmtPlaceholder, "Statement");
|
|
}
|
|
parseBlock(allowDirectives, createNewLexicalScope, afterBlockParse) {
|
|
return this.parsePlaceholder("BlockStatement") || super.parseBlock(allowDirectives, createNewLexicalScope, afterBlockParse);
|
|
}
|
|
parseFunctionId(requireId) {
|
|
return this.parsePlaceholder("Identifier") || super.parseFunctionId(requireId);
|
|
}
|
|
parseClass(node, isStatement, optionalId) {
|
|
const type = isStatement ? "ClassDeclaration" : "ClassExpression";
|
|
this.next();
|
|
const oldStrict = this.state.strict;
|
|
const placeholder = this.parsePlaceholder("Identifier");
|
|
if (placeholder) {
|
|
if (this.match(81) || this.match(133) || this.match(5)) {
|
|
node.id = placeholder;
|
|
} else if (optionalId || !isStatement) {
|
|
node.id = null;
|
|
node.body = this.finishPlaceholder(placeholder, "ClassBody");
|
|
return this.finishNode(node, type);
|
|
} else {
|
|
throw this.raise(PlaceholderErrors.ClassNameIsRequired, this.state.startLoc);
|
|
}
|
|
} else {
|
|
this.parseClassId(node, isStatement, optionalId);
|
|
}
|
|
super.parseClassSuper(node);
|
|
node.body = this.parsePlaceholder("ClassBody") || super.parseClassBody(!!node.superClass, oldStrict);
|
|
return this.finishNode(node, type);
|
|
}
|
|
parseExport(node, decorators) {
|
|
const placeholder = this.parsePlaceholder("Identifier");
|
|
if (!placeholder) return super.parseExport(node, decorators);
|
|
const node2 = node;
|
|
if (!this.isContextual(98) && !this.match(12)) {
|
|
node2.specifiers = [];
|
|
node2.source = null;
|
|
node2.declaration = this.finishPlaceholder(placeholder, "Declaration");
|
|
return this.finishNode(node2, "ExportNamedDeclaration");
|
|
}
|
|
this.expectPlugin("exportDefaultFrom");
|
|
const specifier = this.startNode();
|
|
specifier.exported = placeholder;
|
|
node2.specifiers = [this.finishNode(specifier, "ExportDefaultSpecifier")];
|
|
return super.parseExport(node2, decorators);
|
|
}
|
|
isExportDefaultSpecifier() {
|
|
if (this.match(65)) {
|
|
const next = this.nextTokenStart();
|
|
if (this.isUnparsedContextual(next, "from")) {
|
|
if (this.input.startsWith(tokenLabelName(133), this.nextTokenStartSince(next + 4))) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return super.isExportDefaultSpecifier();
|
|
}
|
|
maybeParseExportDefaultSpecifier(node, maybeDefaultIdentifier) {
|
|
var _specifiers;
|
|
if ((_specifiers = node.specifiers) != null && _specifiers.length) {
|
|
return true;
|
|
}
|
|
return super.maybeParseExportDefaultSpecifier(node, maybeDefaultIdentifier);
|
|
}
|
|
checkExport(node) {
|
|
const {
|
|
specifiers
|
|
} = node;
|
|
if (specifiers != null && specifiers.length) {
|
|
node.specifiers = specifiers.filter(node => node.exported.type === "Placeholder");
|
|
}
|
|
super.checkExport(node);
|
|
node.specifiers = specifiers;
|
|
}
|
|
parseImport(node) {
|
|
const placeholder = this.parsePlaceholder("Identifier");
|
|
if (!placeholder) return super.parseImport(node);
|
|
node.specifiers = [];
|
|
if (!this.isContextual(98) && !this.match(12)) {
|
|
node.source = this.finishPlaceholder(placeholder, "StringLiteral");
|
|
this.semicolon();
|
|
return this.finishNode(node, "ImportDeclaration");
|
|
}
|
|
const specifier = this.startNodeAtNode(placeholder);
|
|
specifier.local = placeholder;
|
|
node.specifiers.push(this.finishNode(specifier, "ImportDefaultSpecifier"));
|
|
if (this.eat(12)) {
|
|
const hasStarImport = this.maybeParseStarImportSpecifier(node);
|
|
if (!hasStarImport) this.parseNamedImportSpecifiers(node);
|
|
}
|
|
this.expectContextual(98);
|
|
node.source = this.parseImportSource();
|
|
this.semicolon();
|
|
return this.finishNode(node, "ImportDeclaration");
|
|
}
|
|
parseImportSource() {
|
|
return this.parsePlaceholder("StringLiteral") || super.parseImportSource();
|
|
}
|
|
assertNoSpace() {
|
|
if (this.state.start > this.offsetToSourcePos(this.state.lastTokEndLoc.index)) {
|
|
this.raise(PlaceholderErrors.UnexpectedSpace, this.state.lastTokEndLoc);
|
|
}
|
|
}
|
|
};
|
|
var v8intrinsic = superClass => class V8IntrinsicMixin extends superClass {
|
|
parseV8Intrinsic() {
|
|
if (this.match(54)) {
|
|
const v8IntrinsicStartLoc = this.state.startLoc;
|
|
const node = this.startNode();
|
|
this.next();
|
|
if (tokenIsIdentifier(this.state.type)) {
|
|
const name = this.parseIdentifierName();
|
|
const identifier = this.createIdentifier(node, name);
|
|
this.castNodeTo(identifier, "V8IntrinsicIdentifier");
|
|
if (this.match(10)) {
|
|
return identifier;
|
|
}
|
|
}
|
|
this.unexpected(v8IntrinsicStartLoc);
|
|
}
|
|
}
|
|
parseExprAtom(refExpressionErrors) {
|
|
return this.parseV8Intrinsic() || super.parseExprAtom(refExpressionErrors);
|
|
}
|
|
};
|
|
const PIPELINE_PROPOSALS = ["minimal", "fsharp", "hack", "smart"];
|
|
const TOPIC_TOKENS = ["^^", "@@", "^", "%", "#"];
|
|
function validatePlugins(pluginsMap) {
|
|
if (pluginsMap.has("decorators")) {
|
|
if (pluginsMap.has("decorators-legacy")) {
|
|
throw new Error("Cannot use the decorators and decorators-legacy plugin together");
|
|
}
|
|
const decoratorsBeforeExport = pluginsMap.get("decorators").decoratorsBeforeExport;
|
|
if (decoratorsBeforeExport != null && typeof decoratorsBeforeExport !== "boolean") {
|
|
throw new Error("'decoratorsBeforeExport' must be a boolean, if specified.");
|
|
}
|
|
const allowCallParenthesized = pluginsMap.get("decorators").allowCallParenthesized;
|
|
if (allowCallParenthesized != null && typeof allowCallParenthesized !== "boolean") {
|
|
throw new Error("'allowCallParenthesized' must be a boolean.");
|
|
}
|
|
}
|
|
if (pluginsMap.has("flow") && pluginsMap.has("typescript")) {
|
|
throw new Error("Cannot combine flow and typescript plugins.");
|
|
}
|
|
if (pluginsMap.has("placeholders") && pluginsMap.has("v8intrinsic")) {
|
|
throw new Error("Cannot combine placeholders and v8intrinsic plugins.");
|
|
}
|
|
if (pluginsMap.has("pipelineOperator")) {
|
|
var _pluginsMap$get2;
|
|
const proposal = pluginsMap.get("pipelineOperator").proposal;
|
|
if (!PIPELINE_PROPOSALS.includes(proposal)) {
|
|
const proposalList = PIPELINE_PROPOSALS.map(p => `"${p}"`).join(", ");
|
|
throw new Error(`"pipelineOperator" requires "proposal" option whose value must be one of: ${proposalList}.`);
|
|
}
|
|
if (proposal === "hack") {
|
|
if (pluginsMap.has("placeholders")) {
|
|
throw new Error("Cannot combine placeholders plugin and Hack-style pipes.");
|
|
}
|
|
if (pluginsMap.has("v8intrinsic")) {
|
|
throw new Error("Cannot combine v8intrinsic plugin and Hack-style pipes.");
|
|
}
|
|
const topicToken = pluginsMap.get("pipelineOperator").topicToken;
|
|
if (!TOPIC_TOKENS.includes(topicToken)) {
|
|
const tokenList = TOPIC_TOKENS.map(t => `"${t}"`).join(", ");
|
|
throw new Error(`"pipelineOperator" in "proposal": "hack" mode also requires a "topicToken" option whose value must be one of: ${tokenList}.`);
|
|
}
|
|
{
|
|
var _pluginsMap$get;
|
|
if (topicToken === "#" && ((_pluginsMap$get = pluginsMap.get("recordAndTuple")) == null ? void 0 : _pluginsMap$get.syntaxType) === "hash") {
|
|
throw new Error(`Plugin conflict between \`["pipelineOperator", { proposal: "hack", topicToken: "#" }]\` and \`${JSON.stringify(["recordAndTuple", pluginsMap.get("recordAndTuple")])}\`.`);
|
|
}
|
|
}
|
|
} else if (proposal === "smart" && ((_pluginsMap$get2 = pluginsMap.get("recordAndTuple")) == null ? void 0 : _pluginsMap$get2.syntaxType) === "hash") {
|
|
throw new Error(`Plugin conflict between \`["pipelineOperator", { proposal: "smart" }]\` and \`${JSON.stringify(["recordAndTuple", pluginsMap.get("recordAndTuple")])}\`.`);
|
|
}
|
|
}
|
|
if (pluginsMap.has("moduleAttributes")) {
|
|
{
|
|
if (pluginsMap.has("deprecatedImportAssert") || pluginsMap.has("importAssertions")) {
|
|
throw new Error("Cannot combine importAssertions, deprecatedImportAssert and moduleAttributes plugins.");
|
|
}
|
|
const moduleAttributesVersionPluginOption = pluginsMap.get("moduleAttributes").version;
|
|
if (moduleAttributesVersionPluginOption !== "may-2020") {
|
|
throw new Error("The 'moduleAttributes' plugin requires a 'version' option," + " representing the last proposal update. Currently, the" + " only supported value is 'may-2020'.");
|
|
}
|
|
}
|
|
}
|
|
if (pluginsMap.has("importAssertions")) {
|
|
if (pluginsMap.has("deprecatedImportAssert")) {
|
|
throw new Error("Cannot combine importAssertions and deprecatedImportAssert plugins.");
|
|
}
|
|
}
|
|
if (!pluginsMap.has("deprecatedImportAssert") && pluginsMap.has("importAttributes") && pluginsMap.get("importAttributes").deprecatedAssertSyntax) {
|
|
{
|
|
pluginsMap.set("deprecatedImportAssert", {});
|
|
}
|
|
}
|
|
if (pluginsMap.has("recordAndTuple")) {
|
|
{
|
|
const syntaxType = pluginsMap.get("recordAndTuple").syntaxType;
|
|
if (syntaxType != null) {
|
|
const RECORD_AND_TUPLE_SYNTAX_TYPES = ["hash", "bar"];
|
|
if (!RECORD_AND_TUPLE_SYNTAX_TYPES.includes(syntaxType)) {
|
|
throw new Error("The 'syntaxType' option of the 'recordAndTuple' plugin must be one of: " + RECORD_AND_TUPLE_SYNTAX_TYPES.map(p => `'${p}'`).join(", "));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (pluginsMap.has("asyncDoExpressions") && !pluginsMap.has("doExpressions")) {
|
|
const error = new Error("'asyncDoExpressions' requires 'doExpressions', please add 'doExpressions' to parser plugins.");
|
|
error.missingPlugins = "doExpressions";
|
|
throw error;
|
|
}
|
|
if (pluginsMap.has("optionalChainingAssign") && pluginsMap.get("optionalChainingAssign").version !== "2023-07") {
|
|
throw new Error("The 'optionalChainingAssign' plugin requires a 'version' option," + " representing the last proposal update. Currently, the" + " only supported value is '2023-07'.");
|
|
}
|
|
if (pluginsMap.has("discardBinding") && pluginsMap.get("discardBinding").syntaxType !== "void") {
|
|
throw new Error("The 'discardBinding' plugin requires a 'syntaxType' option. Currently the only supported value is 'void'.");
|
|
}
|
|
}
|
|
const mixinPlugins = {
|
|
estree,
|
|
jsx,
|
|
flow,
|
|
typescript,
|
|
v8intrinsic,
|
|
placeholders
|
|
};
|
|
const mixinPluginNames = Object.keys(mixinPlugins);
|
|
class ExpressionParser extends LValParser {
|
|
checkProto(prop, isRecord, sawProto, refExpressionErrors) {
|
|
if (prop.type === "SpreadElement" || this.isObjectMethod(prop) || prop.computed || prop.shorthand) {
|
|
return sawProto;
|
|
}
|
|
const key = prop.key;
|
|
const name = key.type === "Identifier" ? key.name : key.value;
|
|
if (name === "__proto__") {
|
|
if (isRecord) {
|
|
this.raise(Errors.RecordNoProto, key);
|
|
return true;
|
|
}
|
|
if (sawProto) {
|
|
if (refExpressionErrors) {
|
|
if (refExpressionErrors.doubleProtoLoc === null) {
|
|
refExpressionErrors.doubleProtoLoc = key.loc.start;
|
|
}
|
|
} else {
|
|
this.raise(Errors.DuplicateProto, key);
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
return sawProto;
|
|
}
|
|
shouldExitDescending(expr, potentialArrowAt) {
|
|
return expr.type === "ArrowFunctionExpression" && this.offsetToSourcePos(expr.start) === potentialArrowAt;
|
|
}
|
|
getExpression() {
|
|
this.enterInitialScopes();
|
|
this.nextToken();
|
|
if (this.match(140)) {
|
|
throw this.raise(Errors.ParseExpressionEmptyInput, this.state.startLoc);
|
|
}
|
|
const expr = this.parseExpression();
|
|
if (!this.match(140)) {
|
|
throw this.raise(Errors.ParseExpressionExpectsEOF, this.state.startLoc, {
|
|
unexpected: this.input.codePointAt(this.state.start)
|
|
});
|
|
}
|
|
this.finalizeRemainingComments();
|
|
expr.comments = this.comments;
|
|
expr.errors = this.state.errors;
|
|
if (this.optionFlags & 256) {
|
|
expr.tokens = this.tokens;
|
|
}
|
|
return expr;
|
|
}
|
|
parseExpression(disallowIn, refExpressionErrors) {
|
|
if (disallowIn) {
|
|
return this.disallowInAnd(() => this.parseExpressionBase(refExpressionErrors));
|
|
}
|
|
return this.allowInAnd(() => this.parseExpressionBase(refExpressionErrors));
|
|
}
|
|
parseExpressionBase(refExpressionErrors) {
|
|
const startLoc = this.state.startLoc;
|
|
const expr = this.parseMaybeAssign(refExpressionErrors);
|
|
if (this.match(12)) {
|
|
const node = this.startNodeAt(startLoc);
|
|
node.expressions = [expr];
|
|
while (this.eat(12)) {
|
|
node.expressions.push(this.parseMaybeAssign(refExpressionErrors));
|
|
}
|
|
this.toReferencedList(node.expressions);
|
|
return this.finishNode(node, "SequenceExpression");
|
|
}
|
|
return expr;
|
|
}
|
|
parseMaybeAssignDisallowIn(refExpressionErrors, afterLeftParse) {
|
|
return this.disallowInAnd(() => this.parseMaybeAssign(refExpressionErrors, afterLeftParse));
|
|
}
|
|
parseMaybeAssignAllowIn(refExpressionErrors, afterLeftParse) {
|
|
return this.allowInAnd(() => this.parseMaybeAssign(refExpressionErrors, afterLeftParse));
|
|
}
|
|
setOptionalParametersError(refExpressionErrors) {
|
|
refExpressionErrors.optionalParametersLoc = this.state.startLoc;
|
|
}
|
|
parseMaybeAssign(refExpressionErrors, afterLeftParse) {
|
|
const startLoc = this.state.startLoc;
|
|
const isYield = this.isContextual(108);
|
|
if (isYield) {
|
|
if (this.prodParam.hasYield) {
|
|
this.next();
|
|
let left = this.parseYield(startLoc);
|
|
if (afterLeftParse) {
|
|
left = afterLeftParse.call(this, left, startLoc);
|
|
}
|
|
return left;
|
|
}
|
|
}
|
|
let ownExpressionErrors;
|
|
if (refExpressionErrors) {
|
|
ownExpressionErrors = false;
|
|
} else {
|
|
refExpressionErrors = new ExpressionErrors();
|
|
ownExpressionErrors = true;
|
|
}
|
|
const {
|
|
type
|
|
} = this.state;
|
|
if (type === 10 || tokenIsIdentifier(type)) {
|
|
this.state.potentialArrowAt = this.state.start;
|
|
}
|
|
let left = this.parseMaybeConditional(refExpressionErrors);
|
|
if (afterLeftParse) {
|
|
left = afterLeftParse.call(this, left, startLoc);
|
|
}
|
|
if (tokenIsAssignment(this.state.type)) {
|
|
const node = this.startNodeAt(startLoc);
|
|
const operator = this.state.value;
|
|
node.operator = operator;
|
|
if (this.match(29)) {
|
|
this.toAssignable(left, true);
|
|
node.left = left;
|
|
const startIndex = startLoc.index;
|
|
if (refExpressionErrors.doubleProtoLoc != null && refExpressionErrors.doubleProtoLoc.index >= startIndex) {
|
|
refExpressionErrors.doubleProtoLoc = null;
|
|
}
|
|
if (refExpressionErrors.shorthandAssignLoc != null && refExpressionErrors.shorthandAssignLoc.index >= startIndex) {
|
|
refExpressionErrors.shorthandAssignLoc = null;
|
|
}
|
|
if (refExpressionErrors.privateKeyLoc != null && refExpressionErrors.privateKeyLoc.index >= startIndex) {
|
|
this.checkDestructuringPrivate(refExpressionErrors);
|
|
refExpressionErrors.privateKeyLoc = null;
|
|
}
|
|
if (refExpressionErrors.voidPatternLoc != null && refExpressionErrors.voidPatternLoc.index >= startIndex) {
|
|
refExpressionErrors.voidPatternLoc = null;
|
|
}
|
|
} else {
|
|
node.left = left;
|
|
}
|
|
this.next();
|
|
node.right = this.parseMaybeAssign();
|
|
this.checkLVal(left, this.finishNode(node, "AssignmentExpression"), undefined, undefined, undefined, undefined, operator === "||=" || operator === "&&=" || operator === "??=");
|
|
return node;
|
|
} else if (ownExpressionErrors) {
|
|
this.checkExpressionErrors(refExpressionErrors, true);
|
|
}
|
|
if (isYield) {
|
|
const {
|
|
type
|
|
} = this.state;
|
|
const startsExpr = this.hasPlugin("v8intrinsic") ? tokenCanStartExpression(type) : tokenCanStartExpression(type) && !this.match(54);
|
|
if (startsExpr && !this.isAmbiguousPrefixOrIdentifier()) {
|
|
this.raiseOverwrite(Errors.YieldNotInGeneratorFunction, startLoc);
|
|
return this.parseYield(startLoc);
|
|
}
|
|
}
|
|
return left;
|
|
}
|
|
parseMaybeConditional(refExpressionErrors) {
|
|
const startLoc = this.state.startLoc;
|
|
const potentialArrowAt = this.state.potentialArrowAt;
|
|
const expr = this.parseExprOps(refExpressionErrors);
|
|
if (this.shouldExitDescending(expr, potentialArrowAt)) {
|
|
return expr;
|
|
}
|
|
return this.parseConditional(expr, startLoc, refExpressionErrors);
|
|
}
|
|
parseConditional(expr, startLoc, refExpressionErrors) {
|
|
if (this.eat(17)) {
|
|
const node = this.startNodeAt(startLoc);
|
|
node.test = expr;
|
|
node.consequent = this.parseMaybeAssignAllowIn();
|
|
this.expect(14);
|
|
node.alternate = this.parseMaybeAssign();
|
|
return this.finishNode(node, "ConditionalExpression");
|
|
}
|
|
return expr;
|
|
}
|
|
parseMaybeUnaryOrPrivate(refExpressionErrors) {
|
|
return this.match(139) ? this.parsePrivateName() : this.parseMaybeUnary(refExpressionErrors);
|
|
}
|
|
parseExprOps(refExpressionErrors) {
|
|
const startLoc = this.state.startLoc;
|
|
const potentialArrowAt = this.state.potentialArrowAt;
|
|
const expr = this.parseMaybeUnaryOrPrivate(refExpressionErrors);
|
|
if (this.shouldExitDescending(expr, potentialArrowAt)) {
|
|
return expr;
|
|
}
|
|
return this.parseExprOp(expr, startLoc, -1);
|
|
}
|
|
parseExprOp(left, leftStartLoc, minPrec) {
|
|
if (this.isPrivateName(left)) {
|
|
const value = this.getPrivateNameSV(left);
|
|
if (minPrec >= tokenOperatorPrecedence(58) || !this.prodParam.hasIn || !this.match(58)) {
|
|
this.raise(Errors.PrivateInExpectedIn, left, {
|
|
identifierName: value
|
|
});
|
|
}
|
|
this.classScope.usePrivateName(value, left.loc.start);
|
|
}
|
|
const op = this.state.type;
|
|
if (tokenIsOperator(op) && (this.prodParam.hasIn || !this.match(58))) {
|
|
let prec = tokenOperatorPrecedence(op);
|
|
if (prec > minPrec) {
|
|
if (op === 39) {
|
|
this.expectPlugin("pipelineOperator");
|
|
if (this.state.inFSharpPipelineDirectBody) {
|
|
return left;
|
|
}
|
|
this.checkPipelineAtInfixOperator(left, leftStartLoc);
|
|
}
|
|
const node = this.startNodeAt(leftStartLoc);
|
|
node.left = left;
|
|
node.operator = this.state.value;
|
|
const logical = op === 41 || op === 42;
|
|
const coalesce = op === 40;
|
|
if (coalesce) {
|
|
prec = tokenOperatorPrecedence(42);
|
|
}
|
|
this.next();
|
|
if (op === 39 && this.hasPlugin(["pipelineOperator", {
|
|
proposal: "minimal"
|
|
}])) {
|
|
if (this.state.type === 96 && this.prodParam.hasAwait) {
|
|
throw this.raise(Errors.UnexpectedAwaitAfterPipelineBody, this.state.startLoc);
|
|
}
|
|
}
|
|
node.right = this.parseExprOpRightExpr(op, prec);
|
|
const finishedNode = this.finishNode(node, logical || coalesce ? "LogicalExpression" : "BinaryExpression");
|
|
const nextOp = this.state.type;
|
|
if (coalesce && (nextOp === 41 || nextOp === 42) || logical && nextOp === 40) {
|
|
throw this.raise(Errors.MixingCoalesceWithLogical, this.state.startLoc);
|
|
}
|
|
return this.parseExprOp(finishedNode, leftStartLoc, minPrec);
|
|
}
|
|
}
|
|
return left;
|
|
}
|
|
parseExprOpRightExpr(op, prec) {
|
|
const startLoc = this.state.startLoc;
|
|
switch (op) {
|
|
case 39:
|
|
switch (this.getPluginOption("pipelineOperator", "proposal")) {
|
|
case "hack":
|
|
return this.withTopicBindingContext(() => {
|
|
return this.parseHackPipeBody();
|
|
});
|
|
case "fsharp":
|
|
return this.withSoloAwaitPermittingContext(() => {
|
|
return this.parseFSharpPipelineBody(prec);
|
|
});
|
|
}
|
|
if (this.getPluginOption("pipelineOperator", "proposal") === "smart") {
|
|
return this.withTopicBindingContext(() => {
|
|
if (this.prodParam.hasYield && this.isContextual(108)) {
|
|
throw this.raise(Errors.PipeBodyIsTighter, this.state.startLoc);
|
|
}
|
|
return this.parseSmartPipelineBodyInStyle(this.parseExprOpBaseRightExpr(op, prec), startLoc);
|
|
});
|
|
}
|
|
default:
|
|
return this.parseExprOpBaseRightExpr(op, prec);
|
|
}
|
|
}
|
|
parseExprOpBaseRightExpr(op, prec) {
|
|
const startLoc = this.state.startLoc;
|
|
return this.parseExprOp(this.parseMaybeUnaryOrPrivate(), startLoc, tokenIsRightAssociative(op) ? prec - 1 : prec);
|
|
}
|
|
parseHackPipeBody() {
|
|
var _body$extra;
|
|
const {
|
|
startLoc
|
|
} = this.state;
|
|
const body = this.parseMaybeAssign();
|
|
const requiredParentheses = UnparenthesizedPipeBodyDescriptions.has(body.type);
|
|
if (requiredParentheses && !((_body$extra = body.extra) != null && _body$extra.parenthesized)) {
|
|
this.raise(Errors.PipeUnparenthesizedBody, startLoc, {
|
|
type: body.type
|
|
});
|
|
}
|
|
if (!this.topicReferenceWasUsedInCurrentContext()) {
|
|
this.raise(Errors.PipeTopicUnused, startLoc);
|
|
}
|
|
return body;
|
|
}
|
|
checkExponentialAfterUnary(node) {
|
|
if (this.match(57)) {
|
|
this.raise(Errors.UnexpectedTokenUnaryExponentiation, node.argument);
|
|
}
|
|
}
|
|
parseMaybeUnary(refExpressionErrors, sawUnary) {
|
|
const startLoc = this.state.startLoc;
|
|
const isAwait = this.isContextual(96);
|
|
if (isAwait && this.recordAwaitIfAllowed()) {
|
|
this.next();
|
|
const expr = this.parseAwait(startLoc);
|
|
if (!sawUnary) this.checkExponentialAfterUnary(expr);
|
|
return expr;
|
|
}
|
|
const update = this.match(34);
|
|
const node = this.startNode();
|
|
if (tokenIsPrefix(this.state.type)) {
|
|
node.operator = this.state.value;
|
|
node.prefix = true;
|
|
if (this.match(72)) {
|
|
this.expectPlugin("throwExpressions");
|
|
}
|
|
const isDelete = this.match(89);
|
|
this.next();
|
|
node.argument = this.parseMaybeUnary(null, true);
|
|
this.checkExpressionErrors(refExpressionErrors, true);
|
|
if (this.state.strict && isDelete) {
|
|
const arg = node.argument;
|
|
if (arg.type === "Identifier") {
|
|
this.raise(Errors.StrictDelete, node);
|
|
} else if (this.hasPropertyAsPrivateName(arg)) {
|
|
this.raise(Errors.DeletePrivateField, node);
|
|
}
|
|
}
|
|
if (!update) {
|
|
if (!sawUnary) {
|
|
this.checkExponentialAfterUnary(node);
|
|
}
|
|
return this.finishNode(node, "UnaryExpression");
|
|
}
|
|
}
|
|
const expr = this.parseUpdate(node, update, refExpressionErrors);
|
|
if (isAwait) {
|
|
const {
|
|
type
|
|
} = this.state;
|
|
const startsExpr = this.hasPlugin("v8intrinsic") ? tokenCanStartExpression(type) : tokenCanStartExpression(type) && !this.match(54);
|
|
if (startsExpr && !this.isAmbiguousPrefixOrIdentifier()) {
|
|
this.raiseOverwrite(Errors.AwaitNotInAsyncContext, startLoc);
|
|
return this.parseAwait(startLoc);
|
|
}
|
|
}
|
|
return expr;
|
|
}
|
|
parseUpdate(node, update, refExpressionErrors) {
|
|
if (update) {
|
|
const updateExpressionNode = node;
|
|
this.checkLVal(updateExpressionNode.argument, this.finishNode(updateExpressionNode, "UpdateExpression"));
|
|
return node;
|
|
}
|
|
const startLoc = this.state.startLoc;
|
|
let expr = this.parseExprSubscripts(refExpressionErrors);
|
|
if (this.checkExpressionErrors(refExpressionErrors, false)) return expr;
|
|
while (tokenIsPostfix(this.state.type) && !this.canInsertSemicolon()) {
|
|
const node = this.startNodeAt(startLoc);
|
|
node.operator = this.state.value;
|
|
node.prefix = false;
|
|
node.argument = expr;
|
|
this.next();
|
|
this.checkLVal(expr, expr = this.finishNode(node, "UpdateExpression"));
|
|
}
|
|
return expr;
|
|
}
|
|
parseExprSubscripts(refExpressionErrors) {
|
|
const startLoc = this.state.startLoc;
|
|
const potentialArrowAt = this.state.potentialArrowAt;
|
|
const expr = this.parseExprAtom(refExpressionErrors);
|
|
if (this.shouldExitDescending(expr, potentialArrowAt)) {
|
|
return expr;
|
|
}
|
|
return this.parseSubscripts(expr, startLoc);
|
|
}
|
|
parseSubscripts(base, startLoc, noCalls) {
|
|
const state = {
|
|
optionalChainMember: false,
|
|
maybeAsyncArrow: this.atPossibleAsyncArrow(base),
|
|
stop: false
|
|
};
|
|
do {
|
|
base = this.parseSubscript(base, startLoc, noCalls, state);
|
|
state.maybeAsyncArrow = false;
|
|
} while (!state.stop);
|
|
return base;
|
|
}
|
|
parseSubscript(base, startLoc, noCalls, state) {
|
|
const {
|
|
type
|
|
} = this.state;
|
|
if (!noCalls && type === 15) {
|
|
return this.parseBind(base, startLoc, noCalls, state);
|
|
} else if (tokenIsTemplate(type)) {
|
|
return this.parseTaggedTemplateExpression(base, startLoc, state);
|
|
}
|
|
let optional = false;
|
|
if (type === 18) {
|
|
if (noCalls) {
|
|
this.raise(Errors.OptionalChainingNoNew, this.state.startLoc);
|
|
if (this.lookaheadCharCode() === 40) {
|
|
return this.stopParseSubscript(base, state);
|
|
}
|
|
}
|
|
state.optionalChainMember = optional = true;
|
|
this.next();
|
|
}
|
|
if (!noCalls && this.match(10)) {
|
|
return this.parseCoverCallAndAsyncArrowHead(base, startLoc, state, optional);
|
|
} else {
|
|
const computed = this.eat(0);
|
|
if (computed || optional || this.eat(16)) {
|
|
return this.parseMember(base, startLoc, state, computed, optional);
|
|
} else {
|
|
return this.stopParseSubscript(base, state);
|
|
}
|
|
}
|
|
}
|
|
stopParseSubscript(base, state) {
|
|
state.stop = true;
|
|
return base;
|
|
}
|
|
parseMember(base, startLoc, state, computed, optional) {
|
|
const node = this.startNodeAt(startLoc);
|
|
node.object = base;
|
|
node.computed = computed;
|
|
if (computed) {
|
|
node.property = this.parseExpression();
|
|
this.expect(3);
|
|
} else if (this.match(139)) {
|
|
if (base.type === "Super") {
|
|
this.raise(Errors.SuperPrivateField, startLoc);
|
|
}
|
|
this.classScope.usePrivateName(this.state.value, this.state.startLoc);
|
|
node.property = this.parsePrivateName();
|
|
} else {
|
|
node.property = this.parseIdentifier(true);
|
|
}
|
|
if (state.optionalChainMember) {
|
|
node.optional = optional;
|
|
return this.finishNode(node, "OptionalMemberExpression");
|
|
} else {
|
|
return this.finishNode(node, "MemberExpression");
|
|
}
|
|
}
|
|
parseBind(base, startLoc, noCalls, state) {
|
|
const node = this.startNodeAt(startLoc);
|
|
node.object = base;
|
|
this.next();
|
|
node.callee = this.parseNoCallExpr();
|
|
state.stop = true;
|
|
return this.parseSubscripts(this.finishNode(node, "BindExpression"), startLoc, noCalls);
|
|
}
|
|
parseCoverCallAndAsyncArrowHead(base, startLoc, state, optional) {
|
|
const oldMaybeInArrowParameters = this.state.maybeInArrowParameters;
|
|
let refExpressionErrors = null;
|
|
this.state.maybeInArrowParameters = true;
|
|
this.next();
|
|
const node = this.startNodeAt(startLoc);
|
|
node.callee = base;
|
|
const {
|
|
maybeAsyncArrow,
|
|
optionalChainMember
|
|
} = state;
|
|
if (maybeAsyncArrow) {
|
|
this.expressionScope.enter(newAsyncArrowScope());
|
|
refExpressionErrors = new ExpressionErrors();
|
|
}
|
|
if (optionalChainMember) {
|
|
node.optional = optional;
|
|
}
|
|
if (optional) {
|
|
node.arguments = this.parseCallExpressionArguments();
|
|
} else {
|
|
node.arguments = this.parseCallExpressionArguments(base.type !== "Super", node, refExpressionErrors);
|
|
}
|
|
let finishedNode = this.finishCallExpression(node, optionalChainMember);
|
|
if (maybeAsyncArrow && this.shouldParseAsyncArrow() && !optional) {
|
|
state.stop = true;
|
|
this.checkDestructuringPrivate(refExpressionErrors);
|
|
this.expressionScope.validateAsPattern();
|
|
this.expressionScope.exit();
|
|
finishedNode = this.parseAsyncArrowFromCallExpression(this.startNodeAt(startLoc), finishedNode);
|
|
} else {
|
|
if (maybeAsyncArrow) {
|
|
this.checkExpressionErrors(refExpressionErrors, true);
|
|
this.expressionScope.exit();
|
|
}
|
|
this.toReferencedArguments(finishedNode);
|
|
}
|
|
this.state.maybeInArrowParameters = oldMaybeInArrowParameters;
|
|
return finishedNode;
|
|
}
|
|
toReferencedArguments(node, isParenthesizedExpr) {
|
|
this.toReferencedListDeep(node.arguments, isParenthesizedExpr);
|
|
}
|
|
parseTaggedTemplateExpression(base, startLoc, state) {
|
|
const node = this.startNodeAt(startLoc);
|
|
node.tag = base;
|
|
node.quasi = this.parseTemplate(true);
|
|
if (state.optionalChainMember) {
|
|
this.raise(Errors.OptionalChainingNoTemplate, startLoc);
|
|
}
|
|
return this.finishNode(node, "TaggedTemplateExpression");
|
|
}
|
|
atPossibleAsyncArrow(base) {
|
|
return base.type === "Identifier" && base.name === "async" && this.state.lastTokEndLoc.index === base.end && !this.canInsertSemicolon() && base.end - base.start === 5 && this.offsetToSourcePos(base.start) === this.state.potentialArrowAt;
|
|
}
|
|
finishCallExpression(node, optional) {
|
|
if (node.callee.type === "Import") {
|
|
if (node.arguments.length === 0 || node.arguments.length > 2) {
|
|
this.raise(Errors.ImportCallArity, node);
|
|
} else {
|
|
for (const arg of node.arguments) {
|
|
if (arg.type === "SpreadElement") {
|
|
this.raise(Errors.ImportCallSpreadArgument, arg);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return this.finishNode(node, optional ? "OptionalCallExpression" : "CallExpression");
|
|
}
|
|
parseCallExpressionArguments(allowPlaceholder, nodeForExtra, refExpressionErrors) {
|
|
const elts = [];
|
|
let first = true;
|
|
const oldInFSharpPipelineDirectBody = this.state.inFSharpPipelineDirectBody;
|
|
this.state.inFSharpPipelineDirectBody = false;
|
|
while (!this.eat(11)) {
|
|
if (first) {
|
|
first = false;
|
|
} else {
|
|
this.expect(12);
|
|
if (this.match(11)) {
|
|
if (nodeForExtra) {
|
|
this.addTrailingCommaExtraToNode(nodeForExtra);
|
|
}
|
|
this.next();
|
|
break;
|
|
}
|
|
}
|
|
elts.push(this.parseExprListItem(11, false, refExpressionErrors, allowPlaceholder));
|
|
}
|
|
this.state.inFSharpPipelineDirectBody = oldInFSharpPipelineDirectBody;
|
|
return elts;
|
|
}
|
|
shouldParseAsyncArrow() {
|
|
return this.match(19) && !this.canInsertSemicolon();
|
|
}
|
|
parseAsyncArrowFromCallExpression(node, call) {
|
|
var _call$extra;
|
|
this.resetPreviousNodeTrailingComments(call);
|
|
this.expect(19);
|
|
this.parseArrowExpression(node, call.arguments, true, (_call$extra = call.extra) == null ? void 0 : _call$extra.trailingCommaLoc);
|
|
if (call.innerComments) {
|
|
setInnerComments(node, call.innerComments);
|
|
}
|
|
if (call.callee.trailingComments) {
|
|
setInnerComments(node, call.callee.trailingComments);
|
|
}
|
|
return node;
|
|
}
|
|
parseNoCallExpr() {
|
|
const startLoc = this.state.startLoc;
|
|
return this.parseSubscripts(this.parseExprAtom(), startLoc, true);
|
|
}
|
|
parseExprAtom(refExpressionErrors) {
|
|
let node;
|
|
let decorators = null;
|
|
const {
|
|
type
|
|
} = this.state;
|
|
switch (type) {
|
|
case 79:
|
|
return this.parseSuper();
|
|
case 83:
|
|
node = this.startNode();
|
|
this.next();
|
|
if (this.match(16)) {
|
|
return this.parseImportMetaPropertyOrPhaseCall(node);
|
|
}
|
|
if (this.match(10)) {
|
|
if (this.optionFlags & 512) {
|
|
return this.parseImportCall(node);
|
|
} else {
|
|
return this.finishNode(node, "Import");
|
|
}
|
|
} else {
|
|
this.raise(Errors.UnsupportedImport, this.state.lastTokStartLoc);
|
|
return this.finishNode(node, "Import");
|
|
}
|
|
case 78:
|
|
node = this.startNode();
|
|
this.next();
|
|
return this.finishNode(node, "ThisExpression");
|
|
case 90:
|
|
{
|
|
return this.parseDo(this.startNode(), false);
|
|
}
|
|
case 56:
|
|
case 31:
|
|
{
|
|
this.readRegexp();
|
|
return this.parseRegExpLiteral(this.state.value);
|
|
}
|
|
case 135:
|
|
return this.parseNumericLiteral(this.state.value);
|
|
case 136:
|
|
return this.parseBigIntLiteral(this.state.value);
|
|
case 134:
|
|
return this.parseStringLiteral(this.state.value);
|
|
case 84:
|
|
return this.parseNullLiteral();
|
|
case 85:
|
|
return this.parseBooleanLiteral(true);
|
|
case 86:
|
|
return this.parseBooleanLiteral(false);
|
|
case 10:
|
|
{
|
|
const canBeArrow = this.state.potentialArrowAt === this.state.start;
|
|
return this.parseParenAndDistinguishExpression(canBeArrow);
|
|
}
|
|
case 0:
|
|
{
|
|
return this.parseArrayLike(3, false, refExpressionErrors);
|
|
}
|
|
case 5:
|
|
{
|
|
return this.parseObjectLike(8, false, false, refExpressionErrors);
|
|
}
|
|
case 68:
|
|
return this.parseFunctionOrFunctionSent();
|
|
case 26:
|
|
decorators = this.parseDecorators();
|
|
case 80:
|
|
return this.parseClass(this.maybeTakeDecorators(decorators, this.startNode()), false);
|
|
case 77:
|
|
return this.parseNewOrNewTarget();
|
|
case 25:
|
|
case 24:
|
|
return this.parseTemplate(false);
|
|
case 15:
|
|
{
|
|
node = this.startNode();
|
|
this.next();
|
|
node.object = null;
|
|
const callee = node.callee = this.parseNoCallExpr();
|
|
if (callee.type === "MemberExpression") {
|
|
return this.finishNode(node, "BindExpression");
|
|
} else {
|
|
throw this.raise(Errors.UnsupportedBind, callee);
|
|
}
|
|
}
|
|
case 139:
|
|
{
|
|
this.raise(Errors.PrivateInExpectedIn, this.state.startLoc, {
|
|
identifierName: this.state.value
|
|
});
|
|
return this.parsePrivateName();
|
|
}
|
|
case 33:
|
|
{
|
|
return this.parseTopicReferenceThenEqualsSign(54, "%");
|
|
}
|
|
case 32:
|
|
{
|
|
return this.parseTopicReferenceThenEqualsSign(44, "^");
|
|
}
|
|
case 37:
|
|
case 38:
|
|
{
|
|
return this.parseTopicReference("hack");
|
|
}
|
|
case 44:
|
|
case 54:
|
|
case 27:
|
|
{
|
|
const pipeProposal = this.getPluginOption("pipelineOperator", "proposal");
|
|
if (pipeProposal) {
|
|
return this.parseTopicReference(pipeProposal);
|
|
}
|
|
throw this.unexpected();
|
|
}
|
|
case 47:
|
|
{
|
|
const lookaheadCh = this.input.codePointAt(this.nextTokenStart());
|
|
if (isIdentifierStart(lookaheadCh) || lookaheadCh === 62) {
|
|
throw this.expectOnePlugin(["jsx", "flow", "typescript"]);
|
|
}
|
|
throw this.unexpected();
|
|
}
|
|
default:
|
|
{
|
|
if (type === 137) {
|
|
return this.parseDecimalLiteral(this.state.value);
|
|
} else if (type === 2 || type === 1) {
|
|
return this.parseArrayLike(this.state.type === 2 ? 4 : 3, true);
|
|
} else if (type === 6 || type === 7) {
|
|
return this.parseObjectLike(this.state.type === 6 ? 9 : 8, false, true);
|
|
}
|
|
}
|
|
if (tokenIsIdentifier(type)) {
|
|
if (this.isContextual(127) && this.lookaheadInLineCharCode() === 123) {
|
|
return this.parseModuleExpression();
|
|
}
|
|
const canBeArrow = this.state.potentialArrowAt === this.state.start;
|
|
const containsEsc = this.state.containsEsc;
|
|
const id = this.parseIdentifier();
|
|
if (!containsEsc && id.name === "async" && !this.canInsertSemicolon()) {
|
|
const {
|
|
type
|
|
} = this.state;
|
|
if (type === 68) {
|
|
this.resetPreviousNodeTrailingComments(id);
|
|
this.next();
|
|
return this.parseAsyncFunctionExpression(this.startNodeAtNode(id));
|
|
} else if (tokenIsIdentifier(type)) {
|
|
if (this.lookaheadCharCode() === 61) {
|
|
return this.parseAsyncArrowUnaryFunction(this.startNodeAtNode(id));
|
|
} else {
|
|
return id;
|
|
}
|
|
} else if (type === 90) {
|
|
this.resetPreviousNodeTrailingComments(id);
|
|
return this.parseDo(this.startNodeAtNode(id), true);
|
|
}
|
|
}
|
|
if (canBeArrow && this.match(19) && !this.canInsertSemicolon()) {
|
|
this.next();
|
|
return this.parseArrowExpression(this.startNodeAtNode(id), [id], false);
|
|
}
|
|
return id;
|
|
} else {
|
|
throw this.unexpected();
|
|
}
|
|
}
|
|
}
|
|
parseTopicReferenceThenEqualsSign(topicTokenType, topicTokenValue) {
|
|
const pipeProposal = this.getPluginOption("pipelineOperator", "proposal");
|
|
if (pipeProposal) {
|
|
this.state.type = topicTokenType;
|
|
this.state.value = topicTokenValue;
|
|
this.state.pos--;
|
|
this.state.end--;
|
|
this.state.endLoc = createPositionWithColumnOffset(this.state.endLoc, -1);
|
|
return this.parseTopicReference(pipeProposal);
|
|
}
|
|
throw this.unexpected();
|
|
}
|
|
parseTopicReference(pipeProposal) {
|
|
const node = this.startNode();
|
|
const startLoc = this.state.startLoc;
|
|
const tokenType = this.state.type;
|
|
this.next();
|
|
return this.finishTopicReference(node, startLoc, pipeProposal, tokenType);
|
|
}
|
|
finishTopicReference(node, startLoc, pipeProposal, tokenType) {
|
|
if (this.testTopicReferenceConfiguration(pipeProposal, startLoc, tokenType)) {
|
|
if (pipeProposal === "hack") {
|
|
if (!this.topicReferenceIsAllowedInCurrentContext()) {
|
|
this.raise(Errors.PipeTopicUnbound, startLoc);
|
|
}
|
|
this.registerTopicReference();
|
|
return this.finishNode(node, "TopicReference");
|
|
} else {
|
|
if (!this.topicReferenceIsAllowedInCurrentContext()) {
|
|
this.raise(Errors.PrimaryTopicNotAllowed, startLoc);
|
|
}
|
|
this.registerTopicReference();
|
|
return this.finishNode(node, "PipelinePrimaryTopicReference");
|
|
}
|
|
} else {
|
|
throw this.raise(Errors.PipeTopicUnconfiguredToken, startLoc, {
|
|
token: tokenLabelName(tokenType)
|
|
});
|
|
}
|
|
}
|
|
testTopicReferenceConfiguration(pipeProposal, startLoc, tokenType) {
|
|
switch (pipeProposal) {
|
|
case "hack":
|
|
{
|
|
return this.hasPlugin(["pipelineOperator", {
|
|
topicToken: tokenLabelName(tokenType)
|
|
}]);
|
|
}
|
|
case "smart":
|
|
return tokenType === 27;
|
|
default:
|
|
throw this.raise(Errors.PipeTopicRequiresHackPipes, startLoc);
|
|
}
|
|
}
|
|
parseAsyncArrowUnaryFunction(node) {
|
|
this.prodParam.enter(functionFlags(true, this.prodParam.hasYield));
|
|
const params = [this.parseIdentifier()];
|
|
this.prodParam.exit();
|
|
if (this.hasPrecedingLineBreak()) {
|
|
this.raise(Errors.LineTerminatorBeforeArrow, this.state.curPosition());
|
|
}
|
|
this.expect(19);
|
|
return this.parseArrowExpression(node, params, true);
|
|
}
|
|
parseDo(node, isAsync) {
|
|
this.expectPlugin("doExpressions");
|
|
if (isAsync) {
|
|
this.expectPlugin("asyncDoExpressions");
|
|
}
|
|
node.async = isAsync;
|
|
this.next();
|
|
const oldLabels = this.state.labels;
|
|
this.state.labels = [];
|
|
if (isAsync) {
|
|
this.prodParam.enter(2);
|
|
node.body = this.parseBlock();
|
|
this.prodParam.exit();
|
|
} else {
|
|
node.body = this.parseBlock();
|
|
}
|
|
this.state.labels = oldLabels;
|
|
return this.finishNode(node, "DoExpression");
|
|
}
|
|
parseSuper() {
|
|
const node = this.startNode();
|
|
this.next();
|
|
if (this.match(10) && !this.scope.allowDirectSuper) {
|
|
{
|
|
if (!(this.optionFlags & 16)) {
|
|
this.raise(Errors.SuperNotAllowed, node);
|
|
}
|
|
}
|
|
} else if (!this.scope.allowSuper) {
|
|
{
|
|
if (!(this.optionFlags & 16)) {
|
|
this.raise(Errors.UnexpectedSuper, node);
|
|
}
|
|
}
|
|
}
|
|
if (!this.match(10) && !this.match(0) && !this.match(16)) {
|
|
this.raise(Errors.UnsupportedSuper, node);
|
|
}
|
|
return this.finishNode(node, "Super");
|
|
}
|
|
parsePrivateName() {
|
|
const node = this.startNode();
|
|
const id = this.startNodeAt(createPositionWithColumnOffset(this.state.startLoc, 1));
|
|
const name = this.state.value;
|
|
this.next();
|
|
node.id = this.createIdentifier(id, name);
|
|
return this.finishNode(node, "PrivateName");
|
|
}
|
|
parseFunctionOrFunctionSent() {
|
|
const node = this.startNode();
|
|
this.next();
|
|
if (this.prodParam.hasYield && this.match(16)) {
|
|
const meta = this.createIdentifier(this.startNodeAtNode(node), "function");
|
|
this.next();
|
|
if (this.match(103)) {
|
|
this.expectPlugin("functionSent");
|
|
} else if (!this.hasPlugin("functionSent")) {
|
|
this.unexpected();
|
|
}
|
|
return this.parseMetaProperty(node, meta, "sent");
|
|
}
|
|
return this.parseFunction(node);
|
|
}
|
|
parseMetaProperty(node, meta, propertyName) {
|
|
node.meta = meta;
|
|
const containsEsc = this.state.containsEsc;
|
|
node.property = this.parseIdentifier(true);
|
|
if (node.property.name !== propertyName || containsEsc) {
|
|
this.raise(Errors.UnsupportedMetaProperty, node.property, {
|
|
target: meta.name,
|
|
onlyValidPropertyName: propertyName
|
|
});
|
|
}
|
|
return this.finishNode(node, "MetaProperty");
|
|
}
|
|
parseImportMetaPropertyOrPhaseCall(node) {
|
|
this.next();
|
|
if (this.isContextual(105) || this.isContextual(97)) {
|
|
const isSource = this.isContextual(105);
|
|
this.expectPlugin(isSource ? "sourcePhaseImports" : "deferredImportEvaluation");
|
|
this.next();
|
|
node.phase = isSource ? "source" : "defer";
|
|
return this.parseImportCall(node);
|
|
} else {
|
|
const id = this.createIdentifierAt(this.startNodeAtNode(node), "import", this.state.lastTokStartLoc);
|
|
if (this.isContextual(101)) {
|
|
if (!this.inModule) {
|
|
this.raise(Errors.ImportMetaOutsideModule, id);
|
|
}
|
|
this.sawUnambiguousESM = true;
|
|
}
|
|
return this.parseMetaProperty(node, id, "meta");
|
|
}
|
|
}
|
|
parseLiteralAtNode(value, type, node) {
|
|
this.addExtra(node, "rawValue", value);
|
|
this.addExtra(node, "raw", this.input.slice(this.offsetToSourcePos(node.start), this.state.end));
|
|
node.value = value;
|
|
this.next();
|
|
return this.finishNode(node, type);
|
|
}
|
|
parseLiteral(value, type) {
|
|
const node = this.startNode();
|
|
return this.parseLiteralAtNode(value, type, node);
|
|
}
|
|
parseStringLiteral(value) {
|
|
return this.parseLiteral(value, "StringLiteral");
|
|
}
|
|
parseNumericLiteral(value) {
|
|
return this.parseLiteral(value, "NumericLiteral");
|
|
}
|
|
parseBigIntLiteral(value) {
|
|
{
|
|
return this.parseLiteral(value, "BigIntLiteral");
|
|
}
|
|
}
|
|
parseDecimalLiteral(value) {
|
|
return this.parseLiteral(value, "DecimalLiteral");
|
|
}
|
|
parseRegExpLiteral(value) {
|
|
const node = this.startNode();
|
|
this.addExtra(node, "raw", this.input.slice(this.offsetToSourcePos(node.start), this.state.end));
|
|
node.pattern = value.pattern;
|
|
node.flags = value.flags;
|
|
this.next();
|
|
return this.finishNode(node, "RegExpLiteral");
|
|
}
|
|
parseBooleanLiteral(value) {
|
|
const node = this.startNode();
|
|
node.value = value;
|
|
this.next();
|
|
return this.finishNode(node, "BooleanLiteral");
|
|
}
|
|
parseNullLiteral() {
|
|
const node = this.startNode();
|
|
this.next();
|
|
return this.finishNode(node, "NullLiteral");
|
|
}
|
|
parseParenAndDistinguishExpression(canBeArrow) {
|
|
const startLoc = this.state.startLoc;
|
|
let val;
|
|
this.next();
|
|
this.expressionScope.enter(newArrowHeadScope());
|
|
const oldMaybeInArrowParameters = this.state.maybeInArrowParameters;
|
|
const oldInFSharpPipelineDirectBody = this.state.inFSharpPipelineDirectBody;
|
|
this.state.maybeInArrowParameters = true;
|
|
this.state.inFSharpPipelineDirectBody = false;
|
|
const innerStartLoc = this.state.startLoc;
|
|
const exprList = [];
|
|
const refExpressionErrors = new ExpressionErrors();
|
|
let first = true;
|
|
let spreadStartLoc;
|
|
let optionalCommaStartLoc;
|
|
while (!this.match(11)) {
|
|
if (first) {
|
|
first = false;
|
|
} else {
|
|
this.expect(12, refExpressionErrors.optionalParametersLoc === null ? null : refExpressionErrors.optionalParametersLoc);
|
|
if (this.match(11)) {
|
|
optionalCommaStartLoc = this.state.startLoc;
|
|
break;
|
|
}
|
|
}
|
|
if (this.match(21)) {
|
|
const spreadNodeStartLoc = this.state.startLoc;
|
|
spreadStartLoc = this.state.startLoc;
|
|
exprList.push(this.parseParenItem(this.parseRestBinding(), spreadNodeStartLoc));
|
|
if (!this.checkCommaAfterRest(41)) {
|
|
break;
|
|
}
|
|
} else {
|
|
exprList.push(this.parseMaybeAssignAllowInOrVoidPattern(11, refExpressionErrors, this.parseParenItem));
|
|
}
|
|
}
|
|
const innerEndLoc = this.state.lastTokEndLoc;
|
|
this.expect(11);
|
|
this.state.maybeInArrowParameters = oldMaybeInArrowParameters;
|
|
this.state.inFSharpPipelineDirectBody = oldInFSharpPipelineDirectBody;
|
|
let arrowNode = this.startNodeAt(startLoc);
|
|
if (canBeArrow && this.shouldParseArrow(exprList) && (arrowNode = this.parseArrow(arrowNode))) {
|
|
this.checkDestructuringPrivate(refExpressionErrors);
|
|
this.expressionScope.validateAsPattern();
|
|
this.expressionScope.exit();
|
|
this.parseArrowExpression(arrowNode, exprList, false);
|
|
return arrowNode;
|
|
}
|
|
this.expressionScope.exit();
|
|
if (!exprList.length) {
|
|
this.unexpected(this.state.lastTokStartLoc);
|
|
}
|
|
if (optionalCommaStartLoc) this.unexpected(optionalCommaStartLoc);
|
|
if (spreadStartLoc) this.unexpected(spreadStartLoc);
|
|
this.checkExpressionErrors(refExpressionErrors, true);
|
|
this.toReferencedListDeep(exprList, true);
|
|
if (exprList.length > 1) {
|
|
val = this.startNodeAt(innerStartLoc);
|
|
val.expressions = exprList;
|
|
this.finishNode(val, "SequenceExpression");
|
|
this.resetEndLocation(val, innerEndLoc);
|
|
} else {
|
|
val = exprList[0];
|
|
}
|
|
return this.wrapParenthesis(startLoc, val);
|
|
}
|
|
wrapParenthesis(startLoc, expression) {
|
|
if (!(this.optionFlags & 1024)) {
|
|
this.addExtra(expression, "parenthesized", true);
|
|
this.addExtra(expression, "parenStart", startLoc.index);
|
|
this.takeSurroundingComments(expression, startLoc.index, this.state.lastTokEndLoc.index);
|
|
return expression;
|
|
}
|
|
const parenExpression = this.startNodeAt(startLoc);
|
|
parenExpression.expression = expression;
|
|
return this.finishNode(parenExpression, "ParenthesizedExpression");
|
|
}
|
|
shouldParseArrow(params) {
|
|
return !this.canInsertSemicolon();
|
|
}
|
|
parseArrow(node) {
|
|
if (this.eat(19)) {
|
|
return node;
|
|
}
|
|
}
|
|
parseParenItem(node, startLoc) {
|
|
return node;
|
|
}
|
|
parseNewOrNewTarget() {
|
|
const node = this.startNode();
|
|
this.next();
|
|
if (this.match(16)) {
|
|
const meta = this.createIdentifier(this.startNodeAtNode(node), "new");
|
|
this.next();
|
|
const metaProp = this.parseMetaProperty(node, meta, "target");
|
|
if (!this.scope.allowNewTarget) {
|
|
this.raise(Errors.UnexpectedNewTarget, metaProp);
|
|
}
|
|
return metaProp;
|
|
}
|
|
return this.parseNew(node);
|
|
}
|
|
parseNew(node) {
|
|
this.parseNewCallee(node);
|
|
if (this.eat(10)) {
|
|
const args = this.parseExprList(11);
|
|
this.toReferencedList(args);
|
|
node.arguments = args;
|
|
} else {
|
|
node.arguments = [];
|
|
}
|
|
return this.finishNode(node, "NewExpression");
|
|
}
|
|
parseNewCallee(node) {
|
|
const isImport = this.match(83);
|
|
const callee = this.parseNoCallExpr();
|
|
node.callee = callee;
|
|
if (isImport && (callee.type === "Import" || callee.type === "ImportExpression")) {
|
|
this.raise(Errors.ImportCallNotNewExpression, callee);
|
|
}
|
|
}
|
|
parseTemplateElement(isTagged) {
|
|
const {
|
|
start,
|
|
startLoc,
|
|
end,
|
|
value
|
|
} = this.state;
|
|
const elemStart = start + 1;
|
|
const elem = this.startNodeAt(createPositionWithColumnOffset(startLoc, 1));
|
|
if (value === null) {
|
|
if (!isTagged) {
|
|
this.raise(Errors.InvalidEscapeSequenceTemplate, createPositionWithColumnOffset(this.state.firstInvalidTemplateEscapePos, 1));
|
|
}
|
|
}
|
|
const isTail = this.match(24);
|
|
const endOffset = isTail ? -1 : -2;
|
|
const elemEnd = end + endOffset;
|
|
elem.value = {
|
|
raw: this.input.slice(elemStart, elemEnd).replace(/\r\n?/g, "\n"),
|
|
cooked: value === null ? null : value.slice(1, endOffset)
|
|
};
|
|
elem.tail = isTail;
|
|
this.next();
|
|
const finishedNode = this.finishNode(elem, "TemplateElement");
|
|
this.resetEndLocation(finishedNode, createPositionWithColumnOffset(this.state.lastTokEndLoc, endOffset));
|
|
return finishedNode;
|
|
}
|
|
parseTemplate(isTagged) {
|
|
const node = this.startNode();
|
|
let curElt = this.parseTemplateElement(isTagged);
|
|
const quasis = [curElt];
|
|
const substitutions = [];
|
|
while (!curElt.tail) {
|
|
substitutions.push(this.parseTemplateSubstitution());
|
|
this.readTemplateContinuation();
|
|
quasis.push(curElt = this.parseTemplateElement(isTagged));
|
|
}
|
|
node.expressions = substitutions;
|
|
node.quasis = quasis;
|
|
return this.finishNode(node, "TemplateLiteral");
|
|
}
|
|
parseTemplateSubstitution() {
|
|
return this.parseExpression();
|
|
}
|
|
parseObjectLike(close, isPattern, isRecord, refExpressionErrors) {
|
|
if (isRecord) {
|
|
this.expectPlugin("recordAndTuple");
|
|
}
|
|
const oldInFSharpPipelineDirectBody = this.state.inFSharpPipelineDirectBody;
|
|
this.state.inFSharpPipelineDirectBody = false;
|
|
let sawProto = false;
|
|
let first = true;
|
|
const node = this.startNode();
|
|
node.properties = [];
|
|
this.next();
|
|
while (!this.match(close)) {
|
|
if (first) {
|
|
first = false;
|
|
} else {
|
|
this.expect(12);
|
|
if (this.match(close)) {
|
|
this.addTrailingCommaExtraToNode(node);
|
|
break;
|
|
}
|
|
}
|
|
let prop;
|
|
if (isPattern) {
|
|
prop = this.parseBindingProperty();
|
|
} else {
|
|
prop = this.parsePropertyDefinition(refExpressionErrors);
|
|
sawProto = this.checkProto(prop, isRecord, sawProto, refExpressionErrors);
|
|
}
|
|
if (isRecord && !this.isObjectProperty(prop) && prop.type !== "SpreadElement") {
|
|
this.raise(Errors.InvalidRecordProperty, prop);
|
|
}
|
|
{
|
|
if (prop.shorthand) {
|
|
this.addExtra(prop, "shorthand", true);
|
|
}
|
|
}
|
|
node.properties.push(prop);
|
|
}
|
|
this.next();
|
|
this.state.inFSharpPipelineDirectBody = oldInFSharpPipelineDirectBody;
|
|
let type = "ObjectExpression";
|
|
if (isPattern) {
|
|
type = "ObjectPattern";
|
|
} else if (isRecord) {
|
|
type = "RecordExpression";
|
|
}
|
|
return this.finishNode(node, type);
|
|
}
|
|
addTrailingCommaExtraToNode(node) {
|
|
this.addExtra(node, "trailingComma", this.state.lastTokStartLoc.index);
|
|
this.addExtra(node, "trailingCommaLoc", this.state.lastTokStartLoc, false);
|
|
}
|
|
maybeAsyncOrAccessorProp(prop) {
|
|
return !prop.computed && prop.key.type === "Identifier" && (this.isLiteralPropertyName() || this.match(0) || this.match(55));
|
|
}
|
|
parsePropertyDefinition(refExpressionErrors) {
|
|
let decorators = [];
|
|
if (this.match(26)) {
|
|
if (this.hasPlugin("decorators")) {
|
|
this.raise(Errors.UnsupportedPropertyDecorator, this.state.startLoc);
|
|
}
|
|
while (this.match(26)) {
|
|
decorators.push(this.parseDecorator());
|
|
}
|
|
}
|
|
const prop = this.startNode();
|
|
let isAsync = false;
|
|
let isAccessor = false;
|
|
let startLoc;
|
|
if (this.match(21)) {
|
|
if (decorators.length) this.unexpected();
|
|
return this.parseSpread();
|
|
}
|
|
if (decorators.length) {
|
|
prop.decorators = decorators;
|
|
decorators = [];
|
|
}
|
|
prop.method = false;
|
|
if (refExpressionErrors) {
|
|
startLoc = this.state.startLoc;
|
|
}
|
|
let isGenerator = this.eat(55);
|
|
this.parsePropertyNamePrefixOperator(prop);
|
|
const containsEsc = this.state.containsEsc;
|
|
this.parsePropertyName(prop, refExpressionErrors);
|
|
if (!isGenerator && !containsEsc && this.maybeAsyncOrAccessorProp(prop)) {
|
|
const {
|
|
key
|
|
} = prop;
|
|
const keyName = key.name;
|
|
if (keyName === "async" && !this.hasPrecedingLineBreak()) {
|
|
isAsync = true;
|
|
this.resetPreviousNodeTrailingComments(key);
|
|
isGenerator = this.eat(55);
|
|
this.parsePropertyName(prop);
|
|
}
|
|
if (keyName === "get" || keyName === "set") {
|
|
isAccessor = true;
|
|
this.resetPreviousNodeTrailingComments(key);
|
|
prop.kind = keyName;
|
|
if (this.match(55)) {
|
|
isGenerator = true;
|
|
this.raise(Errors.AccessorIsGenerator, this.state.curPosition(), {
|
|
kind: keyName
|
|
});
|
|
this.next();
|
|
}
|
|
this.parsePropertyName(prop);
|
|
}
|
|
}
|
|
return this.parseObjPropValue(prop, startLoc, isGenerator, isAsync, false, isAccessor, refExpressionErrors);
|
|
}
|
|
getGetterSetterExpectedParamCount(method) {
|
|
return method.kind === "get" ? 0 : 1;
|
|
}
|
|
getObjectOrClassMethodParams(method) {
|
|
return method.params;
|
|
}
|
|
checkGetterSetterParams(method) {
|
|
var _params;
|
|
const paramCount = this.getGetterSetterExpectedParamCount(method);
|
|
const params = this.getObjectOrClassMethodParams(method);
|
|
if (params.length !== paramCount) {
|
|
this.raise(method.kind === "get" ? Errors.BadGetterArity : Errors.BadSetterArity, method);
|
|
}
|
|
if (method.kind === "set" && ((_params = params[params.length - 1]) == null ? void 0 : _params.type) === "RestElement") {
|
|
this.raise(Errors.BadSetterRestParameter, method);
|
|
}
|
|
}
|
|
parseObjectMethod(prop, isGenerator, isAsync, isPattern, isAccessor) {
|
|
if (isAccessor) {
|
|
const finishedProp = this.parseMethod(prop, isGenerator, false, false, false, "ObjectMethod");
|
|
this.checkGetterSetterParams(finishedProp);
|
|
return finishedProp;
|
|
}
|
|
if (isAsync || isGenerator || this.match(10)) {
|
|
if (isPattern) this.unexpected();
|
|
prop.kind = "method";
|
|
prop.method = true;
|
|
return this.parseMethod(prop, isGenerator, isAsync, false, false, "ObjectMethod");
|
|
}
|
|
}
|
|
parseObjectProperty(prop, startLoc, isPattern, refExpressionErrors) {
|
|
prop.shorthand = false;
|
|
if (this.eat(14)) {
|
|
prop.value = isPattern ? this.parseMaybeDefault(this.state.startLoc) : this.parseMaybeAssignAllowInOrVoidPattern(8, refExpressionErrors);
|
|
return this.finishObjectProperty(prop);
|
|
}
|
|
if (!prop.computed && prop.key.type === "Identifier") {
|
|
this.checkReservedWord(prop.key.name, prop.key.loc.start, true, false);
|
|
if (isPattern) {
|
|
prop.value = this.parseMaybeDefault(startLoc, this.cloneIdentifier(prop.key));
|
|
} else if (this.match(29)) {
|
|
const shorthandAssignLoc = this.state.startLoc;
|
|
if (refExpressionErrors != null) {
|
|
if (refExpressionErrors.shorthandAssignLoc === null) {
|
|
refExpressionErrors.shorthandAssignLoc = shorthandAssignLoc;
|
|
}
|
|
} else {
|
|
this.raise(Errors.InvalidCoverInitializedName, shorthandAssignLoc);
|
|
}
|
|
prop.value = this.parseMaybeDefault(startLoc, this.cloneIdentifier(prop.key));
|
|
} else {
|
|
prop.value = this.cloneIdentifier(prop.key);
|
|
}
|
|
prop.shorthand = true;
|
|
return this.finishObjectProperty(prop);
|
|
}
|
|
}
|
|
finishObjectProperty(node) {
|
|
return this.finishNode(node, "ObjectProperty");
|
|
}
|
|
parseObjPropValue(prop, startLoc, isGenerator, isAsync, isPattern, isAccessor, refExpressionErrors) {
|
|
const node = this.parseObjectMethod(prop, isGenerator, isAsync, isPattern, isAccessor) || this.parseObjectProperty(prop, startLoc, isPattern, refExpressionErrors);
|
|
if (!node) this.unexpected();
|
|
return node;
|
|
}
|
|
parsePropertyName(prop, refExpressionErrors) {
|
|
if (this.eat(0)) {
|
|
prop.computed = true;
|
|
prop.key = this.parseMaybeAssignAllowIn();
|
|
this.expect(3);
|
|
} else {
|
|
const {
|
|
type,
|
|
value
|
|
} = this.state;
|
|
let key;
|
|
if (tokenIsKeywordOrIdentifier(type)) {
|
|
key = this.parseIdentifier(true);
|
|
} else {
|
|
switch (type) {
|
|
case 135:
|
|
key = this.parseNumericLiteral(value);
|
|
break;
|
|
case 134:
|
|
key = this.parseStringLiteral(value);
|
|
break;
|
|
case 136:
|
|
key = this.parseBigIntLiteral(value);
|
|
break;
|
|
case 139:
|
|
{
|
|
const privateKeyLoc = this.state.startLoc;
|
|
if (refExpressionErrors != null) {
|
|
if (refExpressionErrors.privateKeyLoc === null) {
|
|
refExpressionErrors.privateKeyLoc = privateKeyLoc;
|
|
}
|
|
} else {
|
|
this.raise(Errors.UnexpectedPrivateField, privateKeyLoc);
|
|
}
|
|
key = this.parsePrivateName();
|
|
break;
|
|
}
|
|
default:
|
|
if (type === 137) {
|
|
key = this.parseDecimalLiteral(value);
|
|
break;
|
|
}
|
|
this.unexpected();
|
|
}
|
|
}
|
|
prop.key = key;
|
|
if (type !== 139) {
|
|
prop.computed = false;
|
|
}
|
|
}
|
|
}
|
|
initFunction(node, isAsync) {
|
|
node.id = null;
|
|
node.generator = false;
|
|
node.async = isAsync;
|
|
}
|
|
parseMethod(node, isGenerator, isAsync, isConstructor, allowDirectSuper, type, inClassScope = false) {
|
|
this.initFunction(node, isAsync);
|
|
node.generator = isGenerator;
|
|
this.scope.enter(514 | 16 | (inClassScope ? 576 : 0) | (allowDirectSuper ? 32 : 0));
|
|
this.prodParam.enter(functionFlags(isAsync, node.generator));
|
|
this.parseFunctionParams(node, isConstructor);
|
|
const finishedNode = this.parseFunctionBodyAndFinish(node, type, true);
|
|
this.prodParam.exit();
|
|
this.scope.exit();
|
|
return finishedNode;
|
|
}
|
|
parseArrayLike(close, isTuple, refExpressionErrors) {
|
|
if (isTuple) {
|
|
this.expectPlugin("recordAndTuple");
|
|
}
|
|
const oldInFSharpPipelineDirectBody = this.state.inFSharpPipelineDirectBody;
|
|
this.state.inFSharpPipelineDirectBody = false;
|
|
const node = this.startNode();
|
|
this.next();
|
|
node.elements = this.parseExprList(close, !isTuple, refExpressionErrors, node);
|
|
this.state.inFSharpPipelineDirectBody = oldInFSharpPipelineDirectBody;
|
|
return this.finishNode(node, isTuple ? "TupleExpression" : "ArrayExpression");
|
|
}
|
|
parseArrowExpression(node, params, isAsync, trailingCommaLoc) {
|
|
this.scope.enter(514 | 4);
|
|
let flags = functionFlags(isAsync, false);
|
|
if (!this.match(5) && this.prodParam.hasIn) {
|
|
flags |= 8;
|
|
}
|
|
this.prodParam.enter(flags);
|
|
this.initFunction(node, isAsync);
|
|
const oldMaybeInArrowParameters = this.state.maybeInArrowParameters;
|
|
if (params) {
|
|
this.state.maybeInArrowParameters = true;
|
|
this.setArrowFunctionParameters(node, params, trailingCommaLoc);
|
|
}
|
|
this.state.maybeInArrowParameters = false;
|
|
this.parseFunctionBody(node, true);
|
|
this.prodParam.exit();
|
|
this.scope.exit();
|
|
this.state.maybeInArrowParameters = oldMaybeInArrowParameters;
|
|
return this.finishNode(node, "ArrowFunctionExpression");
|
|
}
|
|
setArrowFunctionParameters(node, params, trailingCommaLoc) {
|
|
this.toAssignableList(params, trailingCommaLoc, false);
|
|
node.params = params;
|
|
}
|
|
parseFunctionBodyAndFinish(node, type, isMethod = false) {
|
|
this.parseFunctionBody(node, false, isMethod);
|
|
return this.finishNode(node, type);
|
|
}
|
|
parseFunctionBody(node, allowExpression, isMethod = false) {
|
|
const isExpression = allowExpression && !this.match(5);
|
|
this.expressionScope.enter(newExpressionScope());
|
|
if (isExpression) {
|
|
node.body = this.parseMaybeAssign();
|
|
this.checkParams(node, false, allowExpression, false);
|
|
} else {
|
|
const oldStrict = this.state.strict;
|
|
const oldLabels = this.state.labels;
|
|
this.state.labels = [];
|
|
this.prodParam.enter(this.prodParam.currentFlags() | 4);
|
|
node.body = this.parseBlock(true, false, hasStrictModeDirective => {
|
|
const nonSimple = !this.isSimpleParamList(node.params);
|
|
if (hasStrictModeDirective && nonSimple) {
|
|
this.raise(Errors.IllegalLanguageModeDirective, (node.kind === "method" || node.kind === "constructor") && !!node.key ? node.key.loc.end : node);
|
|
}
|
|
const strictModeChanged = !oldStrict && this.state.strict;
|
|
this.checkParams(node, !this.state.strict && !allowExpression && !isMethod && !nonSimple, allowExpression, strictModeChanged);
|
|
if (this.state.strict && node.id) {
|
|
this.checkIdentifier(node.id, 65, strictModeChanged);
|
|
}
|
|
});
|
|
this.prodParam.exit();
|
|
this.state.labels = oldLabels;
|
|
}
|
|
this.expressionScope.exit();
|
|
}
|
|
isSimpleParameter(node) {
|
|
return node.type === "Identifier";
|
|
}
|
|
isSimpleParamList(params) {
|
|
for (let i = 0, len = params.length; i < len; i++) {
|
|
if (!this.isSimpleParameter(params[i])) return false;
|
|
}
|
|
return true;
|
|
}
|
|
checkParams(node, allowDuplicates, isArrowFunction, strictModeChanged = true) {
|
|
const checkClashes = !allowDuplicates && new Set();
|
|
const formalParameters = {
|
|
type: "FormalParameters"
|
|
};
|
|
for (const param of node.params) {
|
|
this.checkLVal(param, formalParameters, 5, checkClashes, strictModeChanged);
|
|
}
|
|
}
|
|
parseExprList(close, allowEmpty, refExpressionErrors, nodeForExtra) {
|
|
const elts = [];
|
|
let first = true;
|
|
while (!this.eat(close)) {
|
|
if (first) {
|
|
first = false;
|
|
} else {
|
|
this.expect(12);
|
|
if (this.match(close)) {
|
|
if (nodeForExtra) {
|
|
this.addTrailingCommaExtraToNode(nodeForExtra);
|
|
}
|
|
this.next();
|
|
break;
|
|
}
|
|
}
|
|
elts.push(this.parseExprListItem(close, allowEmpty, refExpressionErrors));
|
|
}
|
|
return elts;
|
|
}
|
|
parseExprListItem(close, allowEmpty, refExpressionErrors, allowPlaceholder) {
|
|
let elt;
|
|
if (this.match(12)) {
|
|
if (!allowEmpty) {
|
|
this.raise(Errors.UnexpectedToken, this.state.curPosition(), {
|
|
unexpected: ","
|
|
});
|
|
}
|
|
elt = null;
|
|
} else if (this.match(21)) {
|
|
const spreadNodeStartLoc = this.state.startLoc;
|
|
elt = this.parseParenItem(this.parseSpread(refExpressionErrors), spreadNodeStartLoc);
|
|
} else if (this.match(17)) {
|
|
this.expectPlugin("partialApplication");
|
|
if (!allowPlaceholder) {
|
|
this.raise(Errors.UnexpectedArgumentPlaceholder, this.state.startLoc);
|
|
}
|
|
const node = this.startNode();
|
|
this.next();
|
|
elt = this.finishNode(node, "ArgumentPlaceholder");
|
|
} else {
|
|
elt = this.parseMaybeAssignAllowInOrVoidPattern(close, refExpressionErrors, this.parseParenItem);
|
|
}
|
|
return elt;
|
|
}
|
|
parseIdentifier(liberal) {
|
|
const node = this.startNode();
|
|
const name = this.parseIdentifierName(liberal);
|
|
return this.createIdentifier(node, name);
|
|
}
|
|
createIdentifier(node, name) {
|
|
node.name = name;
|
|
node.loc.identifierName = name;
|
|
return this.finishNode(node, "Identifier");
|
|
}
|
|
createIdentifierAt(node, name, endLoc) {
|
|
node.name = name;
|
|
node.loc.identifierName = name;
|
|
return this.finishNodeAt(node, "Identifier", endLoc);
|
|
}
|
|
parseIdentifierName(liberal) {
|
|
let name;
|
|
const {
|
|
startLoc,
|
|
type
|
|
} = this.state;
|
|
if (tokenIsKeywordOrIdentifier(type)) {
|
|
name = this.state.value;
|
|
} else {
|
|
this.unexpected();
|
|
}
|
|
const tokenIsKeyword = tokenKeywordOrIdentifierIsKeyword(type);
|
|
if (liberal) {
|
|
if (tokenIsKeyword) {
|
|
this.replaceToken(132);
|
|
}
|
|
} else {
|
|
this.checkReservedWord(name, startLoc, tokenIsKeyword, false);
|
|
}
|
|
this.next();
|
|
return name;
|
|
}
|
|
checkReservedWord(word, startLoc, checkKeywords, isBinding) {
|
|
if (word.length > 10) {
|
|
return;
|
|
}
|
|
if (!canBeReservedWord(word)) {
|
|
return;
|
|
}
|
|
if (checkKeywords && isKeyword(word)) {
|
|
this.raise(Errors.UnexpectedKeyword, startLoc, {
|
|
keyword: word
|
|
});
|
|
return;
|
|
}
|
|
const reservedTest = !this.state.strict ? isReservedWord : isBinding ? isStrictBindReservedWord : isStrictReservedWord;
|
|
if (reservedTest(word, this.inModule)) {
|
|
this.raise(Errors.UnexpectedReservedWord, startLoc, {
|
|
reservedWord: word
|
|
});
|
|
return;
|
|
} else if (word === "yield") {
|
|
if (this.prodParam.hasYield) {
|
|
this.raise(Errors.YieldBindingIdentifier, startLoc);
|
|
return;
|
|
}
|
|
} else if (word === "await") {
|
|
if (this.prodParam.hasAwait) {
|
|
this.raise(Errors.AwaitBindingIdentifier, startLoc);
|
|
return;
|
|
}
|
|
if (this.scope.inStaticBlock) {
|
|
this.raise(Errors.AwaitBindingIdentifierInStaticBlock, startLoc);
|
|
return;
|
|
}
|
|
this.expressionScope.recordAsyncArrowParametersError(startLoc);
|
|
} else if (word === "arguments") {
|
|
if (this.scope.inClassAndNotInNonArrowFunction) {
|
|
this.raise(Errors.ArgumentsInClass, startLoc);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
recordAwaitIfAllowed() {
|
|
const isAwaitAllowed = this.prodParam.hasAwait;
|
|
if (isAwaitAllowed && !this.scope.inFunction) {
|
|
this.state.hasTopLevelAwait = true;
|
|
}
|
|
return isAwaitAllowed;
|
|
}
|
|
parseAwait(startLoc) {
|
|
const node = this.startNodeAt(startLoc);
|
|
this.expressionScope.recordParameterInitializerError(Errors.AwaitExpressionFormalParameter, node);
|
|
if (this.eat(55)) {
|
|
this.raise(Errors.ObsoleteAwaitStar, node);
|
|
}
|
|
if (!this.scope.inFunction && !(this.optionFlags & 1)) {
|
|
if (this.isAmbiguousPrefixOrIdentifier()) {
|
|
this.ambiguousScriptDifferentAst = true;
|
|
} else {
|
|
this.sawUnambiguousESM = true;
|
|
}
|
|
}
|
|
if (!this.state.soloAwait) {
|
|
node.argument = this.parseMaybeUnary(null, true);
|
|
}
|
|
return this.finishNode(node, "AwaitExpression");
|
|
}
|
|
isAmbiguousPrefixOrIdentifier() {
|
|
if (this.hasPrecedingLineBreak()) return true;
|
|
const {
|
|
type
|
|
} = this.state;
|
|
return type === 53 || type === 10 || type === 0 || tokenIsTemplate(type) || type === 102 && !this.state.containsEsc || type === 138 || type === 56 || this.hasPlugin("v8intrinsic") && type === 54;
|
|
}
|
|
parseYield(startLoc) {
|
|
const node = this.startNodeAt(startLoc);
|
|
this.expressionScope.recordParameterInitializerError(Errors.YieldInParameter, node);
|
|
let delegating = false;
|
|
let argument = null;
|
|
if (!this.hasPrecedingLineBreak()) {
|
|
delegating = this.eat(55);
|
|
switch (this.state.type) {
|
|
case 13:
|
|
case 140:
|
|
case 8:
|
|
case 11:
|
|
case 3:
|
|
case 9:
|
|
case 14:
|
|
case 12:
|
|
if (!delegating) break;
|
|
default:
|
|
argument = this.parseMaybeAssign();
|
|
}
|
|
}
|
|
node.delegate = delegating;
|
|
node.argument = argument;
|
|
return this.finishNode(node, "YieldExpression");
|
|
}
|
|
parseImportCall(node) {
|
|
this.next();
|
|
node.source = this.parseMaybeAssignAllowIn();
|
|
node.options = null;
|
|
if (this.eat(12)) {
|
|
if (!this.match(11)) {
|
|
node.options = this.parseMaybeAssignAllowIn();
|
|
if (this.eat(12)) {
|
|
this.addTrailingCommaExtraToNode(node.options);
|
|
if (!this.match(11)) {
|
|
do {
|
|
this.parseMaybeAssignAllowIn();
|
|
} while (this.eat(12) && !this.match(11));
|
|
this.raise(Errors.ImportCallArity, node);
|
|
}
|
|
}
|
|
} else {
|
|
this.addTrailingCommaExtraToNode(node.source);
|
|
}
|
|
}
|
|
this.expect(11);
|
|
return this.finishNode(node, "ImportExpression");
|
|
}
|
|
checkPipelineAtInfixOperator(left, leftStartLoc) {
|
|
if (this.hasPlugin(["pipelineOperator", {
|
|
proposal: "smart"
|
|
}])) {
|
|
if (left.type === "SequenceExpression") {
|
|
this.raise(Errors.PipelineHeadSequenceExpression, leftStartLoc);
|
|
}
|
|
}
|
|
}
|
|
parseSmartPipelineBodyInStyle(childExpr, startLoc) {
|
|
if (this.isSimpleReference(childExpr)) {
|
|
const bodyNode = this.startNodeAt(startLoc);
|
|
bodyNode.callee = childExpr;
|
|
return this.finishNode(bodyNode, "PipelineBareFunction");
|
|
} else {
|
|
const bodyNode = this.startNodeAt(startLoc);
|
|
this.checkSmartPipeTopicBodyEarlyErrors(startLoc);
|
|
bodyNode.expression = childExpr;
|
|
return this.finishNode(bodyNode, "PipelineTopicExpression");
|
|
}
|
|
}
|
|
isSimpleReference(expression) {
|
|
switch (expression.type) {
|
|
case "MemberExpression":
|
|
return !expression.computed && this.isSimpleReference(expression.object);
|
|
case "Identifier":
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
checkSmartPipeTopicBodyEarlyErrors(startLoc) {
|
|
if (this.match(19)) {
|
|
throw this.raise(Errors.PipelineBodyNoArrow, this.state.startLoc);
|
|
}
|
|
if (!this.topicReferenceWasUsedInCurrentContext()) {
|
|
this.raise(Errors.PipelineTopicUnused, startLoc);
|
|
}
|
|
}
|
|
withTopicBindingContext(callback) {
|
|
const outerContextTopicState = this.state.topicContext;
|
|
this.state.topicContext = {
|
|
maxNumOfResolvableTopics: 1,
|
|
maxTopicIndex: null
|
|
};
|
|
try {
|
|
return callback();
|
|
} finally {
|
|
this.state.topicContext = outerContextTopicState;
|
|
}
|
|
}
|
|
withSmartMixTopicForbiddingContext(callback) {
|
|
if (this.hasPlugin(["pipelineOperator", {
|
|
proposal: "smart"
|
|
}])) {
|
|
const outerContextTopicState = this.state.topicContext;
|
|
this.state.topicContext = {
|
|
maxNumOfResolvableTopics: 0,
|
|
maxTopicIndex: null
|
|
};
|
|
try {
|
|
return callback();
|
|
} finally {
|
|
this.state.topicContext = outerContextTopicState;
|
|
}
|
|
} else {
|
|
return callback();
|
|
}
|
|
}
|
|
withSoloAwaitPermittingContext(callback) {
|
|
const outerContextSoloAwaitState = this.state.soloAwait;
|
|
this.state.soloAwait = true;
|
|
try {
|
|
return callback();
|
|
} finally {
|
|
this.state.soloAwait = outerContextSoloAwaitState;
|
|
}
|
|
}
|
|
allowInAnd(callback) {
|
|
const flags = this.prodParam.currentFlags();
|
|
const prodParamToSet = 8 & ~flags;
|
|
if (prodParamToSet) {
|
|
this.prodParam.enter(flags | 8);
|
|
try {
|
|
return callback();
|
|
} finally {
|
|
this.prodParam.exit();
|
|
}
|
|
}
|
|
return callback();
|
|
}
|
|
disallowInAnd(callback) {
|
|
const flags = this.prodParam.currentFlags();
|
|
const prodParamToClear = 8 & flags;
|
|
if (prodParamToClear) {
|
|
this.prodParam.enter(flags & -9);
|
|
try {
|
|
return callback();
|
|
} finally {
|
|
this.prodParam.exit();
|
|
}
|
|
}
|
|
return callback();
|
|
}
|
|
registerTopicReference() {
|
|
this.state.topicContext.maxTopicIndex = 0;
|
|
}
|
|
topicReferenceIsAllowedInCurrentContext() {
|
|
return this.state.topicContext.maxNumOfResolvableTopics >= 1;
|
|
}
|
|
topicReferenceWasUsedInCurrentContext() {
|
|
return this.state.topicContext.maxTopicIndex != null && this.state.topicContext.maxTopicIndex >= 0;
|
|
}
|
|
parseFSharpPipelineBody(prec) {
|
|
const startLoc = this.state.startLoc;
|
|
this.state.potentialArrowAt = this.state.start;
|
|
const oldInFSharpPipelineDirectBody = this.state.inFSharpPipelineDirectBody;
|
|
this.state.inFSharpPipelineDirectBody = true;
|
|
const ret = this.parseExprOp(this.parseMaybeUnaryOrPrivate(), startLoc, prec);
|
|
this.state.inFSharpPipelineDirectBody = oldInFSharpPipelineDirectBody;
|
|
return ret;
|
|
}
|
|
parseModuleExpression() {
|
|
this.expectPlugin("moduleBlocks");
|
|
const node = this.startNode();
|
|
this.next();
|
|
if (!this.match(5)) {
|
|
this.unexpected(null, 5);
|
|
}
|
|
const program = this.startNodeAt(this.state.endLoc);
|
|
this.next();
|
|
const revertScopes = this.initializeScopes(true);
|
|
this.enterInitialScopes();
|
|
try {
|
|
node.body = this.parseProgram(program, 8, "module");
|
|
} finally {
|
|
revertScopes();
|
|
}
|
|
return this.finishNode(node, "ModuleExpression");
|
|
}
|
|
parseVoidPattern(refExpressionErrors) {
|
|
this.expectPlugin("discardBinding");
|
|
const node = this.startNode();
|
|
if (refExpressionErrors != null) {
|
|
refExpressionErrors.voidPatternLoc = this.state.startLoc;
|
|
}
|
|
this.next();
|
|
return this.finishNode(node, "VoidPattern");
|
|
}
|
|
parseMaybeAssignAllowInOrVoidPattern(close, refExpressionErrors, afterLeftParse) {
|
|
if (refExpressionErrors != null && this.match(88)) {
|
|
const nextCode = this.lookaheadCharCode();
|
|
if (nextCode === 44 || nextCode === (close === 3 ? 93 : close === 8 ? 125 : 41) || nextCode === 61) {
|
|
return this.parseMaybeDefault(this.state.startLoc, this.parseVoidPattern(refExpressionErrors));
|
|
}
|
|
}
|
|
return this.parseMaybeAssignAllowIn(refExpressionErrors, afterLeftParse);
|
|
}
|
|
parsePropertyNamePrefixOperator(prop) {}
|
|
}
|
|
const loopLabel = {
|
|
kind: 1
|
|
},
|
|
switchLabel = {
|
|
kind: 2
|
|
};
|
|
const loneSurrogate = /[\uD800-\uDFFF]/u;
|
|
const keywordRelationalOperator = /in(?:stanceof)?/y;
|
|
function babel7CompatTokens(tokens, input, startIndex) {
|
|
for (let i = 0; i < tokens.length; i++) {
|
|
const token = tokens[i];
|
|
const {
|
|
type
|
|
} = token;
|
|
if (typeof type === "number") {
|
|
{
|
|
if (type === 139) {
|
|
const {
|
|
loc,
|
|
start,
|
|
value,
|
|
end
|
|
} = token;
|
|
const hashEndPos = start + 1;
|
|
const hashEndLoc = createPositionWithColumnOffset(loc.start, 1);
|
|
tokens.splice(i, 1, new Token({
|
|
type: getExportedToken(27),
|
|
value: "#",
|
|
start: start,
|
|
end: hashEndPos,
|
|
startLoc: loc.start,
|
|
endLoc: hashEndLoc
|
|
}), new Token({
|
|
type: getExportedToken(132),
|
|
value: value,
|
|
start: hashEndPos,
|
|
end: end,
|
|
startLoc: hashEndLoc,
|
|
endLoc: loc.end
|
|
}));
|
|
i++;
|
|
continue;
|
|
}
|
|
if (tokenIsTemplate(type)) {
|
|
const {
|
|
loc,
|
|
start,
|
|
value,
|
|
end
|
|
} = token;
|
|
const backquoteEnd = start + 1;
|
|
const backquoteEndLoc = createPositionWithColumnOffset(loc.start, 1);
|
|
let startToken;
|
|
if (input.charCodeAt(start - startIndex) === 96) {
|
|
startToken = new Token({
|
|
type: getExportedToken(22),
|
|
value: "`",
|
|
start: start,
|
|
end: backquoteEnd,
|
|
startLoc: loc.start,
|
|
endLoc: backquoteEndLoc
|
|
});
|
|
} else {
|
|
startToken = new Token({
|
|
type: getExportedToken(8),
|
|
value: "}",
|
|
start: start,
|
|
end: backquoteEnd,
|
|
startLoc: loc.start,
|
|
endLoc: backquoteEndLoc
|
|
});
|
|
}
|
|
let templateValue, templateElementEnd, templateElementEndLoc, endToken;
|
|
if (type === 24) {
|
|
templateElementEnd = end - 1;
|
|
templateElementEndLoc = createPositionWithColumnOffset(loc.end, -1);
|
|
templateValue = value === null ? null : value.slice(1, -1);
|
|
endToken = new Token({
|
|
type: getExportedToken(22),
|
|
value: "`",
|
|
start: templateElementEnd,
|
|
end: end,
|
|
startLoc: templateElementEndLoc,
|
|
endLoc: loc.end
|
|
});
|
|
} else {
|
|
templateElementEnd = end - 2;
|
|
templateElementEndLoc = createPositionWithColumnOffset(loc.end, -2);
|
|
templateValue = value === null ? null : value.slice(1, -2);
|
|
endToken = new Token({
|
|
type: getExportedToken(23),
|
|
value: "${",
|
|
start: templateElementEnd,
|
|
end: end,
|
|
startLoc: templateElementEndLoc,
|
|
endLoc: loc.end
|
|
});
|
|
}
|
|
tokens.splice(i, 1, startToken, new Token({
|
|
type: getExportedToken(20),
|
|
value: templateValue,
|
|
start: backquoteEnd,
|
|
end: templateElementEnd,
|
|
startLoc: backquoteEndLoc,
|
|
endLoc: templateElementEndLoc
|
|
}), endToken);
|
|
i += 2;
|
|
continue;
|
|
}
|
|
}
|
|
token.type = getExportedToken(type);
|
|
}
|
|
}
|
|
return tokens;
|
|
}
|
|
class StatementParser extends ExpressionParser {
|
|
parseTopLevel(file, program) {
|
|
file.program = this.parseProgram(program, 140, this.options.sourceType === "module" ? "module" : "script");
|
|
file.comments = this.comments;
|
|
if (this.optionFlags & 256) {
|
|
file.tokens = babel7CompatTokens(this.tokens, this.input, this.startIndex);
|
|
}
|
|
return this.finishNode(file, "File");
|
|
}
|
|
parseProgram(program, end, sourceType) {
|
|
program.sourceType = sourceType;
|
|
program.interpreter = this.parseInterpreterDirective();
|
|
this.parseBlockBody(program, true, true, end);
|
|
if (this.inModule) {
|
|
if (!(this.optionFlags & 64) && this.scope.undefinedExports.size > 0) {
|
|
for (const [localName, at] of Array.from(this.scope.undefinedExports)) {
|
|
this.raise(Errors.ModuleExportUndefined, at, {
|
|
localName
|
|
});
|
|
}
|
|
}
|
|
this.addExtra(program, "topLevelAwait", this.state.hasTopLevelAwait);
|
|
}
|
|
let finishedProgram;
|
|
if (end === 140) {
|
|
finishedProgram = this.finishNode(program, "Program");
|
|
} else {
|
|
finishedProgram = this.finishNodeAt(program, "Program", createPositionWithColumnOffset(this.state.startLoc, -1));
|
|
}
|
|
return finishedProgram;
|
|
}
|
|
stmtToDirective(stmt) {
|
|
const directive = this.castNodeTo(stmt, "Directive");
|
|
const directiveLiteral = this.castNodeTo(stmt.expression, "DirectiveLiteral");
|
|
const expressionValue = directiveLiteral.value;
|
|
const raw = this.input.slice(this.offsetToSourcePos(directiveLiteral.start), this.offsetToSourcePos(directiveLiteral.end));
|
|
const val = directiveLiteral.value = raw.slice(1, -1);
|
|
this.addExtra(directiveLiteral, "raw", raw);
|
|
this.addExtra(directiveLiteral, "rawValue", val);
|
|
this.addExtra(directiveLiteral, "expressionValue", expressionValue);
|
|
directive.value = directiveLiteral;
|
|
delete stmt.expression;
|
|
return directive;
|
|
}
|
|
parseInterpreterDirective() {
|
|
if (!this.match(28)) {
|
|
return null;
|
|
}
|
|
const node = this.startNode();
|
|
node.value = this.state.value;
|
|
this.next();
|
|
return this.finishNode(node, "InterpreterDirective");
|
|
}
|
|
isLet() {
|
|
if (!this.isContextual(100)) {
|
|
return false;
|
|
}
|
|
return this.hasFollowingBindingAtom();
|
|
}
|
|
isUsing() {
|
|
if (!this.isContextual(107)) {
|
|
return false;
|
|
}
|
|
return this.nextTokenIsIdentifierOnSameLine();
|
|
}
|
|
isForUsing() {
|
|
if (!this.isContextual(107)) {
|
|
return false;
|
|
}
|
|
const next = this.nextTokenInLineStart();
|
|
const nextCh = this.codePointAtPos(next);
|
|
if (this.isUnparsedContextual(next, "of")) {
|
|
const nextCharAfterOf = this.lookaheadCharCodeSince(next + 2);
|
|
if (nextCharAfterOf !== 61 && nextCharAfterOf !== 58 && nextCharAfterOf !== 59) {
|
|
return false;
|
|
}
|
|
}
|
|
if (this.chStartsBindingIdentifier(nextCh, next) || this.isUnparsedContextual(next, "void")) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
nextTokenIsIdentifierOnSameLine() {
|
|
const next = this.nextTokenInLineStart();
|
|
const nextCh = this.codePointAtPos(next);
|
|
return this.chStartsBindingIdentifier(nextCh, next);
|
|
}
|
|
isAwaitUsing() {
|
|
if (!this.isContextual(96)) {
|
|
return false;
|
|
}
|
|
let next = this.nextTokenInLineStart();
|
|
if (this.isUnparsedContextual(next, "using")) {
|
|
next = this.nextTokenInLineStartSince(next + 5);
|
|
const nextCh = this.codePointAtPos(next);
|
|
if (this.chStartsBindingIdentifier(nextCh, next)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
chStartsBindingIdentifier(ch, pos) {
|
|
if (isIdentifierStart(ch)) {
|
|
keywordRelationalOperator.lastIndex = pos;
|
|
if (keywordRelationalOperator.test(this.input)) {
|
|
const endCh = this.codePointAtPos(keywordRelationalOperator.lastIndex);
|
|
if (!isIdentifierChar(endCh) && endCh !== 92) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
} else if (ch === 92) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
chStartsBindingPattern(ch) {
|
|
return ch === 91 || ch === 123;
|
|
}
|
|
hasFollowingBindingAtom() {
|
|
const next = this.nextTokenStart();
|
|
const nextCh = this.codePointAtPos(next);
|
|
return this.chStartsBindingPattern(nextCh) || this.chStartsBindingIdentifier(nextCh, next);
|
|
}
|
|
hasInLineFollowingBindingIdentifierOrBrace() {
|
|
const next = this.nextTokenInLineStart();
|
|
const nextCh = this.codePointAtPos(next);
|
|
return nextCh === 123 || this.chStartsBindingIdentifier(nextCh, next);
|
|
}
|
|
allowsUsing() {
|
|
return (this.scope.inModule || !this.scope.inTopLevel) && !this.scope.inBareCaseStatement;
|
|
}
|
|
parseModuleItem() {
|
|
return this.parseStatementLike(1 | 2 | 4 | 8);
|
|
}
|
|
parseStatementListItem() {
|
|
return this.parseStatementLike(2 | 4 | (!this.options.annexB || this.state.strict ? 0 : 8));
|
|
}
|
|
parseStatementOrSloppyAnnexBFunctionDeclaration(allowLabeledFunction = false) {
|
|
let flags = 0;
|
|
if (this.options.annexB && !this.state.strict) {
|
|
flags |= 4;
|
|
if (allowLabeledFunction) {
|
|
flags |= 8;
|
|
}
|
|
}
|
|
return this.parseStatementLike(flags);
|
|
}
|
|
parseStatement() {
|
|
return this.parseStatementLike(0);
|
|
}
|
|
parseStatementLike(flags) {
|
|
let decorators = null;
|
|
if (this.match(26)) {
|
|
decorators = this.parseDecorators(true);
|
|
}
|
|
return this.parseStatementContent(flags, decorators);
|
|
}
|
|
parseStatementContent(flags, decorators) {
|
|
const startType = this.state.type;
|
|
const node = this.startNode();
|
|
const allowDeclaration = !!(flags & 2);
|
|
const allowFunctionDeclaration = !!(flags & 4);
|
|
const topLevel = flags & 1;
|
|
switch (startType) {
|
|
case 60:
|
|
return this.parseBreakContinueStatement(node, true);
|
|
case 63:
|
|
return this.parseBreakContinueStatement(node, false);
|
|
case 64:
|
|
return this.parseDebuggerStatement(node);
|
|
case 90:
|
|
return this.parseDoWhileStatement(node);
|
|
case 91:
|
|
return this.parseForStatement(node);
|
|
case 68:
|
|
if (this.lookaheadCharCode() === 46) break;
|
|
if (!allowFunctionDeclaration) {
|
|
this.raise(this.state.strict ? Errors.StrictFunction : this.options.annexB ? Errors.SloppyFunctionAnnexB : Errors.SloppyFunction, this.state.startLoc);
|
|
}
|
|
return this.parseFunctionStatement(node, false, !allowDeclaration && allowFunctionDeclaration);
|
|
case 80:
|
|
if (!allowDeclaration) this.unexpected();
|
|
return this.parseClass(this.maybeTakeDecorators(decorators, node), true);
|
|
case 69:
|
|
return this.parseIfStatement(node);
|
|
case 70:
|
|
return this.parseReturnStatement(node);
|
|
case 71:
|
|
return this.parseSwitchStatement(node);
|
|
case 72:
|
|
return this.parseThrowStatement(node);
|
|
case 73:
|
|
return this.parseTryStatement(node);
|
|
case 96:
|
|
if (this.isAwaitUsing()) {
|
|
if (!this.allowsUsing()) {
|
|
this.raise(Errors.UnexpectedUsingDeclaration, node);
|
|
} else if (!allowDeclaration) {
|
|
this.raise(Errors.UnexpectedLexicalDeclaration, node);
|
|
} else if (!this.recordAwaitIfAllowed()) {
|
|
this.raise(Errors.AwaitUsingNotInAsyncContext, node);
|
|
}
|
|
this.next();
|
|
return this.parseVarStatement(node, "await using");
|
|
}
|
|
break;
|
|
case 107:
|
|
if (this.state.containsEsc || !this.hasInLineFollowingBindingIdentifierOrBrace()) {
|
|
break;
|
|
}
|
|
if (!this.allowsUsing()) {
|
|
this.raise(Errors.UnexpectedUsingDeclaration, this.state.startLoc);
|
|
} else if (!allowDeclaration) {
|
|
this.raise(Errors.UnexpectedLexicalDeclaration, this.state.startLoc);
|
|
}
|
|
return this.parseVarStatement(node, "using");
|
|
case 100:
|
|
{
|
|
if (this.state.containsEsc) {
|
|
break;
|
|
}
|
|
const next = this.nextTokenStart();
|
|
const nextCh = this.codePointAtPos(next);
|
|
if (nextCh !== 91) {
|
|
if (!allowDeclaration && this.hasFollowingLineBreak()) break;
|
|
if (!this.chStartsBindingIdentifier(nextCh, next) && nextCh !== 123) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
case 75:
|
|
{
|
|
if (!allowDeclaration) {
|
|
this.raise(Errors.UnexpectedLexicalDeclaration, this.state.startLoc);
|
|
}
|
|
}
|
|
case 74:
|
|
{
|
|
const kind = this.state.value;
|
|
return this.parseVarStatement(node, kind);
|
|
}
|
|
case 92:
|
|
return this.parseWhileStatement(node);
|
|
case 76:
|
|
return this.parseWithStatement(node);
|
|
case 5:
|
|
return this.parseBlock();
|
|
case 13:
|
|
return this.parseEmptyStatement(node);
|
|
case 83:
|
|
{
|
|
const nextTokenCharCode = this.lookaheadCharCode();
|
|
if (nextTokenCharCode === 40 || nextTokenCharCode === 46) {
|
|
break;
|
|
}
|
|
}
|
|
case 82:
|
|
{
|
|
if (!(this.optionFlags & 8) && !topLevel) {
|
|
this.raise(Errors.UnexpectedImportExport, this.state.startLoc);
|
|
}
|
|
this.next();
|
|
let result;
|
|
if (startType === 83) {
|
|
result = this.parseImport(node);
|
|
} else {
|
|
result = this.parseExport(node, decorators);
|
|
}
|
|
this.assertModuleNodeAllowed(result);
|
|
return result;
|
|
}
|
|
default:
|
|
{
|
|
if (this.isAsyncFunction()) {
|
|
if (!allowDeclaration) {
|
|
this.raise(Errors.AsyncFunctionInSingleStatementContext, this.state.startLoc);
|
|
}
|
|
this.next();
|
|
return this.parseFunctionStatement(node, true, !allowDeclaration && allowFunctionDeclaration);
|
|
}
|
|
}
|
|
}
|
|
const maybeName = this.state.value;
|
|
const expr = this.parseExpression();
|
|
if (tokenIsIdentifier(startType) && expr.type === "Identifier" && this.eat(14)) {
|
|
return this.parseLabeledStatement(node, maybeName, expr, flags);
|
|
} else {
|
|
return this.parseExpressionStatement(node, expr, decorators);
|
|
}
|
|
}
|
|
assertModuleNodeAllowed(node) {
|
|
if (!(this.optionFlags & 8) && !this.inModule) {
|
|
this.raise(Errors.ImportOutsideModule, node);
|
|
}
|
|
}
|
|
decoratorsEnabledBeforeExport() {
|
|
if (this.hasPlugin("decorators-legacy")) return true;
|
|
return this.hasPlugin("decorators") && this.getPluginOption("decorators", "decoratorsBeforeExport") !== false;
|
|
}
|
|
maybeTakeDecorators(maybeDecorators, classNode, exportNode) {
|
|
if (maybeDecorators) {
|
|
var _classNode$decorators;
|
|
if ((_classNode$decorators = classNode.decorators) != null && _classNode$decorators.length) {
|
|
if (typeof this.getPluginOption("decorators", "decoratorsBeforeExport") !== "boolean") {
|
|
this.raise(Errors.DecoratorsBeforeAfterExport, classNode.decorators[0]);
|
|
}
|
|
classNode.decorators.unshift(...maybeDecorators);
|
|
} else {
|
|
classNode.decorators = maybeDecorators;
|
|
}
|
|
this.resetStartLocationFromNode(classNode, maybeDecorators[0]);
|
|
if (exportNode) this.resetStartLocationFromNode(exportNode, classNode);
|
|
}
|
|
return classNode;
|
|
}
|
|
canHaveLeadingDecorator() {
|
|
return this.match(80);
|
|
}
|
|
parseDecorators(allowExport) {
|
|
const decorators = [];
|
|
do {
|
|
decorators.push(this.parseDecorator());
|
|
} while (this.match(26));
|
|
if (this.match(82)) {
|
|
if (!allowExport) {
|
|
this.unexpected();
|
|
}
|
|
if (!this.decoratorsEnabledBeforeExport()) {
|
|
this.raise(Errors.DecoratorExportClass, this.state.startLoc);
|
|
}
|
|
} else if (!this.canHaveLeadingDecorator()) {
|
|
throw this.raise(Errors.UnexpectedLeadingDecorator, this.state.startLoc);
|
|
}
|
|
return decorators;
|
|
}
|
|
parseDecorator() {
|
|
this.expectOnePlugin(["decorators", "decorators-legacy"]);
|
|
const node = this.startNode();
|
|
this.next();
|
|
if (this.hasPlugin("decorators")) {
|
|
const startLoc = this.state.startLoc;
|
|
let expr;
|
|
if (this.match(10)) {
|
|
const startLoc = this.state.startLoc;
|
|
this.next();
|
|
expr = this.parseExpression();
|
|
this.expect(11);
|
|
expr = this.wrapParenthesis(startLoc, expr);
|
|
const paramsStartLoc = this.state.startLoc;
|
|
node.expression = this.parseMaybeDecoratorArguments(expr, startLoc);
|
|
if (this.getPluginOption("decorators", "allowCallParenthesized") === false && node.expression !== expr) {
|
|
this.raise(Errors.DecoratorArgumentsOutsideParentheses, paramsStartLoc);
|
|
}
|
|
} else {
|
|
expr = this.parseIdentifier(false);
|
|
while (this.eat(16)) {
|
|
const node = this.startNodeAt(startLoc);
|
|
node.object = expr;
|
|
if (this.match(139)) {
|
|
this.classScope.usePrivateName(this.state.value, this.state.startLoc);
|
|
node.property = this.parsePrivateName();
|
|
} else {
|
|
node.property = this.parseIdentifier(true);
|
|
}
|
|
node.computed = false;
|
|
expr = this.finishNode(node, "MemberExpression");
|
|
}
|
|
node.expression = this.parseMaybeDecoratorArguments(expr, startLoc);
|
|
}
|
|
} else {
|
|
node.expression = this.parseExprSubscripts();
|
|
}
|
|
return this.finishNode(node, "Decorator");
|
|
}
|
|
parseMaybeDecoratorArguments(expr, startLoc) {
|
|
if (this.eat(10)) {
|
|
const node = this.startNodeAt(startLoc);
|
|
node.callee = expr;
|
|
node.arguments = this.parseCallExpressionArguments();
|
|
this.toReferencedList(node.arguments);
|
|
return this.finishNode(node, "CallExpression");
|
|
}
|
|
return expr;
|
|
}
|
|
parseBreakContinueStatement(node, isBreak) {
|
|
this.next();
|
|
if (this.isLineTerminator()) {
|
|
node.label = null;
|
|
} else {
|
|
node.label = this.parseIdentifier();
|
|
this.semicolon();
|
|
}
|
|
this.verifyBreakContinue(node, isBreak);
|
|
return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement");
|
|
}
|
|
verifyBreakContinue(node, isBreak) {
|
|
let i;
|
|
for (i = 0; i < this.state.labels.length; ++i) {
|
|
const lab = this.state.labels[i];
|
|
if (node.label == null || lab.name === node.label.name) {
|
|
if (lab.kind != null && (isBreak || lab.kind === 1)) {
|
|
break;
|
|
}
|
|
if (node.label && isBreak) break;
|
|
}
|
|
}
|
|
if (i === this.state.labels.length) {
|
|
const type = isBreak ? "BreakStatement" : "ContinueStatement";
|
|
this.raise(Errors.IllegalBreakContinue, node, {
|
|
type
|
|
});
|
|
}
|
|
}
|
|
parseDebuggerStatement(node) {
|
|
this.next();
|
|
this.semicolon();
|
|
return this.finishNode(node, "DebuggerStatement");
|
|
}
|
|
parseHeaderExpression() {
|
|
this.expect(10);
|
|
const val = this.parseExpression();
|
|
this.expect(11);
|
|
return val;
|
|
}
|
|
parseDoWhileStatement(node) {
|
|
this.next();
|
|
this.state.labels.push(loopLabel);
|
|
node.body = this.withSmartMixTopicForbiddingContext(() => this.parseStatement());
|
|
this.state.labels.pop();
|
|
this.expect(92);
|
|
node.test = this.parseHeaderExpression();
|
|
this.eat(13);
|
|
return this.finishNode(node, "DoWhileStatement");
|
|
}
|
|
parseForStatement(node) {
|
|
this.next();
|
|
this.state.labels.push(loopLabel);
|
|
let awaitAt = null;
|
|
if (this.isContextual(96) && this.recordAwaitIfAllowed()) {
|
|
awaitAt = this.state.startLoc;
|
|
this.next();
|
|
}
|
|
this.scope.enter(0);
|
|
this.expect(10);
|
|
if (this.match(13)) {
|
|
if (awaitAt !== null) {
|
|
this.unexpected(awaitAt);
|
|
}
|
|
return this.parseFor(node, null);
|
|
}
|
|
const startsWithLet = this.isContextual(100);
|
|
{
|
|
const startsWithAwaitUsing = this.isAwaitUsing();
|
|
const starsWithUsingDeclaration = startsWithAwaitUsing || this.isForUsing();
|
|
const isLetOrUsing = startsWithLet && this.hasFollowingBindingAtom() || starsWithUsingDeclaration;
|
|
if (this.match(74) || this.match(75) || isLetOrUsing) {
|
|
const initNode = this.startNode();
|
|
let kind;
|
|
if (startsWithAwaitUsing) {
|
|
kind = "await using";
|
|
if (!this.recordAwaitIfAllowed()) {
|
|
this.raise(Errors.AwaitUsingNotInAsyncContext, this.state.startLoc);
|
|
}
|
|
this.next();
|
|
} else {
|
|
kind = this.state.value;
|
|
}
|
|
this.next();
|
|
this.parseVar(initNode, true, kind);
|
|
const init = this.finishNode(initNode, "VariableDeclaration");
|
|
const isForIn = this.match(58);
|
|
if (isForIn && starsWithUsingDeclaration) {
|
|
this.raise(Errors.ForInUsing, init);
|
|
}
|
|
if ((isForIn || this.isContextual(102)) && init.declarations.length === 1) {
|
|
return this.parseForIn(node, init, awaitAt);
|
|
}
|
|
if (awaitAt !== null) {
|
|
this.unexpected(awaitAt);
|
|
}
|
|
return this.parseFor(node, init);
|
|
}
|
|
}
|
|
const startsWithAsync = this.isContextual(95);
|
|
const refExpressionErrors = new ExpressionErrors();
|
|
const init = this.parseExpression(true, refExpressionErrors);
|
|
const isForOf = this.isContextual(102);
|
|
if (isForOf) {
|
|
if (startsWithLet) {
|
|
this.raise(Errors.ForOfLet, init);
|
|
}
|
|
if (awaitAt === null && startsWithAsync && init.type === "Identifier") {
|
|
this.raise(Errors.ForOfAsync, init);
|
|
}
|
|
}
|
|
if (isForOf || this.match(58)) {
|
|
this.checkDestructuringPrivate(refExpressionErrors);
|
|
this.toAssignable(init, true);
|
|
const type = isForOf ? "ForOfStatement" : "ForInStatement";
|
|
this.checkLVal(init, {
|
|
type
|
|
});
|
|
return this.parseForIn(node, init, awaitAt);
|
|
} else {
|
|
this.checkExpressionErrors(refExpressionErrors, true);
|
|
}
|
|
if (awaitAt !== null) {
|
|
this.unexpected(awaitAt);
|
|
}
|
|
return this.parseFor(node, init);
|
|
}
|
|
parseFunctionStatement(node, isAsync, isHangingDeclaration) {
|
|
this.next();
|
|
return this.parseFunction(node, 1 | (isHangingDeclaration ? 2 : 0) | (isAsync ? 8 : 0));
|
|
}
|
|
parseIfStatement(node) {
|
|
this.next();
|
|
node.test = this.parseHeaderExpression();
|
|
node.consequent = this.parseStatementOrSloppyAnnexBFunctionDeclaration();
|
|
node.alternate = this.eat(66) ? this.parseStatementOrSloppyAnnexBFunctionDeclaration() : null;
|
|
return this.finishNode(node, "IfStatement");
|
|
}
|
|
parseReturnStatement(node) {
|
|
if (!this.prodParam.hasReturn) {
|
|
this.raise(Errors.IllegalReturn, this.state.startLoc);
|
|
}
|
|
this.next();
|
|
if (this.isLineTerminator()) {
|
|
node.argument = null;
|
|
} else {
|
|
node.argument = this.parseExpression();
|
|
this.semicolon();
|
|
}
|
|
return this.finishNode(node, "ReturnStatement");
|
|
}
|
|
parseSwitchStatement(node) {
|
|
this.next();
|
|
node.discriminant = this.parseHeaderExpression();
|
|
const cases = node.cases = [];
|
|
this.expect(5);
|
|
this.state.labels.push(switchLabel);
|
|
this.scope.enter(256);
|
|
let cur;
|
|
for (let sawDefault; !this.match(8);) {
|
|
if (this.match(61) || this.match(65)) {
|
|
const isCase = this.match(61);
|
|
if (cur) this.finishNode(cur, "SwitchCase");
|
|
cases.push(cur = this.startNode());
|
|
cur.consequent = [];
|
|
this.next();
|
|
if (isCase) {
|
|
cur.test = this.parseExpression();
|
|
} else {
|
|
if (sawDefault) {
|
|
this.raise(Errors.MultipleDefaultsInSwitch, this.state.lastTokStartLoc);
|
|
}
|
|
sawDefault = true;
|
|
cur.test = null;
|
|
}
|
|
this.expect(14);
|
|
} else {
|
|
if (cur) {
|
|
cur.consequent.push(this.parseStatementListItem());
|
|
} else {
|
|
this.unexpected();
|
|
}
|
|
}
|
|
}
|
|
this.scope.exit();
|
|
if (cur) this.finishNode(cur, "SwitchCase");
|
|
this.next();
|
|
this.state.labels.pop();
|
|
return this.finishNode(node, "SwitchStatement");
|
|
}
|
|
parseThrowStatement(node) {
|
|
this.next();
|
|
if (this.hasPrecedingLineBreak()) {
|
|
this.raise(Errors.NewlineAfterThrow, this.state.lastTokEndLoc);
|
|
}
|
|
node.argument = this.parseExpression();
|
|
this.semicolon();
|
|
return this.finishNode(node, "ThrowStatement");
|
|
}
|
|
parseCatchClauseParam() {
|
|
const param = this.parseBindingAtom();
|
|
this.scope.enter(this.options.annexB && param.type === "Identifier" ? 8 : 0);
|
|
this.checkLVal(param, {
|
|
type: "CatchClause"
|
|
}, 9);
|
|
return param;
|
|
}
|
|
parseTryStatement(node) {
|
|
this.next();
|
|
node.block = this.parseBlock();
|
|
node.handler = null;
|
|
if (this.match(62)) {
|
|
const clause = this.startNode();
|
|
this.next();
|
|
if (this.match(10)) {
|
|
this.expect(10);
|
|
clause.param = this.parseCatchClauseParam();
|
|
this.expect(11);
|
|
} else {
|
|
clause.param = null;
|
|
this.scope.enter(0);
|
|
}
|
|
clause.body = this.withSmartMixTopicForbiddingContext(() => this.parseBlock(false, false));
|
|
this.scope.exit();
|
|
node.handler = this.finishNode(clause, "CatchClause");
|
|
}
|
|
node.finalizer = this.eat(67) ? this.parseBlock() : null;
|
|
if (!node.handler && !node.finalizer) {
|
|
this.raise(Errors.NoCatchOrFinally, node);
|
|
}
|
|
return this.finishNode(node, "TryStatement");
|
|
}
|
|
parseVarStatement(node, kind, allowMissingInitializer = false) {
|
|
this.next();
|
|
this.parseVar(node, false, kind, allowMissingInitializer);
|
|
this.semicolon();
|
|
return this.finishNode(node, "VariableDeclaration");
|
|
}
|
|
parseWhileStatement(node) {
|
|
this.next();
|
|
node.test = this.parseHeaderExpression();
|
|
this.state.labels.push(loopLabel);
|
|
node.body = this.withSmartMixTopicForbiddingContext(() => this.parseStatement());
|
|
this.state.labels.pop();
|
|
return this.finishNode(node, "WhileStatement");
|
|
}
|
|
parseWithStatement(node) {
|
|
if (this.state.strict) {
|
|
this.raise(Errors.StrictWith, this.state.startLoc);
|
|
}
|
|
this.next();
|
|
node.object = this.parseHeaderExpression();
|
|
node.body = this.withSmartMixTopicForbiddingContext(() => this.parseStatement());
|
|
return this.finishNode(node, "WithStatement");
|
|
}
|
|
parseEmptyStatement(node) {
|
|
this.next();
|
|
return this.finishNode(node, "EmptyStatement");
|
|
}
|
|
parseLabeledStatement(node, maybeName, expr, flags) {
|
|
for (const label of this.state.labels) {
|
|
if (label.name === maybeName) {
|
|
this.raise(Errors.LabelRedeclaration, expr, {
|
|
labelName: maybeName
|
|
});
|
|
}
|
|
}
|
|
const kind = tokenIsLoop(this.state.type) ? 1 : this.match(71) ? 2 : null;
|
|
for (let i = this.state.labels.length - 1; i >= 0; i--) {
|
|
const label = this.state.labels[i];
|
|
if (label.statementStart === node.start) {
|
|
label.statementStart = this.sourceToOffsetPos(this.state.start);
|
|
label.kind = kind;
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
this.state.labels.push({
|
|
name: maybeName,
|
|
kind: kind,
|
|
statementStart: this.sourceToOffsetPos(this.state.start)
|
|
});
|
|
node.body = flags & 8 ? this.parseStatementOrSloppyAnnexBFunctionDeclaration(true) : this.parseStatement();
|
|
this.state.labels.pop();
|
|
node.label = expr;
|
|
return this.finishNode(node, "LabeledStatement");
|
|
}
|
|
parseExpressionStatement(node, expr, decorators) {
|
|
node.expression = expr;
|
|
this.semicolon();
|
|
return this.finishNode(node, "ExpressionStatement");
|
|
}
|
|
parseBlock(allowDirectives = false, createNewLexicalScope = true, afterBlockParse) {
|
|
const node = this.startNode();
|
|
if (allowDirectives) {
|
|
this.state.strictErrors.clear();
|
|
}
|
|
this.expect(5);
|
|
if (createNewLexicalScope) {
|
|
this.scope.enter(0);
|
|
}
|
|
this.parseBlockBody(node, allowDirectives, false, 8, afterBlockParse);
|
|
if (createNewLexicalScope) {
|
|
this.scope.exit();
|
|
}
|
|
return this.finishNode(node, "BlockStatement");
|
|
}
|
|
isValidDirective(stmt) {
|
|
return stmt.type === "ExpressionStatement" && stmt.expression.type === "StringLiteral" && !stmt.expression.extra.parenthesized;
|
|
}
|
|
parseBlockBody(node, allowDirectives, topLevel, end, afterBlockParse) {
|
|
const body = node.body = [];
|
|
const directives = node.directives = [];
|
|
this.parseBlockOrModuleBlockBody(body, allowDirectives ? directives : undefined, topLevel, end, afterBlockParse);
|
|
}
|
|
parseBlockOrModuleBlockBody(body, directives, topLevel, end, afterBlockParse) {
|
|
const oldStrict = this.state.strict;
|
|
let hasStrictModeDirective = false;
|
|
let parsedNonDirective = false;
|
|
while (!this.match(end)) {
|
|
const stmt = topLevel ? this.parseModuleItem() : this.parseStatementListItem();
|
|
if (directives && !parsedNonDirective) {
|
|
if (this.isValidDirective(stmt)) {
|
|
const directive = this.stmtToDirective(stmt);
|
|
directives.push(directive);
|
|
if (!hasStrictModeDirective && directive.value.value === "use strict") {
|
|
hasStrictModeDirective = true;
|
|
this.setStrict(true);
|
|
}
|
|
continue;
|
|
}
|
|
parsedNonDirective = true;
|
|
this.state.strictErrors.clear();
|
|
}
|
|
body.push(stmt);
|
|
}
|
|
afterBlockParse == null || afterBlockParse.call(this, hasStrictModeDirective);
|
|
if (!oldStrict) {
|
|
this.setStrict(false);
|
|
}
|
|
this.next();
|
|
}
|
|
parseFor(node, init) {
|
|
node.init = init;
|
|
this.semicolon(false);
|
|
node.test = this.match(13) ? null : this.parseExpression();
|
|
this.semicolon(false);
|
|
node.update = this.match(11) ? null : this.parseExpression();
|
|
this.expect(11);
|
|
node.body = this.withSmartMixTopicForbiddingContext(() => this.parseStatement());
|
|
this.scope.exit();
|
|
this.state.labels.pop();
|
|
return this.finishNode(node, "ForStatement");
|
|
}
|
|
parseForIn(node, init, awaitAt) {
|
|
const isForIn = this.match(58);
|
|
this.next();
|
|
if (isForIn) {
|
|
if (awaitAt !== null) this.unexpected(awaitAt);
|
|
} else {
|
|
node.await = awaitAt !== null;
|
|
}
|
|
if (init.type === "VariableDeclaration" && init.declarations[0].init != null && (!isForIn || !this.options.annexB || this.state.strict || init.kind !== "var" || init.declarations[0].id.type !== "Identifier")) {
|
|
this.raise(Errors.ForInOfLoopInitializer, init, {
|
|
type: isForIn ? "ForInStatement" : "ForOfStatement"
|
|
});
|
|
}
|
|
if (init.type === "AssignmentPattern") {
|
|
this.raise(Errors.InvalidLhs, init, {
|
|
ancestor: {
|
|
type: "ForStatement"
|
|
}
|
|
});
|
|
}
|
|
node.left = init;
|
|
node.right = isForIn ? this.parseExpression() : this.parseMaybeAssignAllowIn();
|
|
this.expect(11);
|
|
node.body = this.withSmartMixTopicForbiddingContext(() => this.parseStatement());
|
|
this.scope.exit();
|
|
this.state.labels.pop();
|
|
return this.finishNode(node, isForIn ? "ForInStatement" : "ForOfStatement");
|
|
}
|
|
parseVar(node, isFor, kind, allowMissingInitializer = false) {
|
|
const declarations = node.declarations = [];
|
|
node.kind = kind;
|
|
for (;;) {
|
|
const decl = this.startNode();
|
|
this.parseVarId(decl, kind);
|
|
decl.init = !this.eat(29) ? null : isFor ? this.parseMaybeAssignDisallowIn() : this.parseMaybeAssignAllowIn();
|
|
if (decl.init === null && !allowMissingInitializer) {
|
|
if (decl.id.type !== "Identifier" && !(isFor && (this.match(58) || this.isContextual(102)))) {
|
|
this.raise(Errors.DeclarationMissingInitializer, this.state.lastTokEndLoc, {
|
|
kind: "destructuring"
|
|
});
|
|
} else if ((kind === "const" || kind === "using" || kind === "await using") && !(this.match(58) || this.isContextual(102))) {
|
|
this.raise(Errors.DeclarationMissingInitializer, this.state.lastTokEndLoc, {
|
|
kind
|
|
});
|
|
}
|
|
}
|
|
declarations.push(this.finishNode(decl, "VariableDeclarator"));
|
|
if (!this.eat(12)) break;
|
|
}
|
|
return node;
|
|
}
|
|
parseVarId(decl, kind) {
|
|
const id = this.parseBindingAtom();
|
|
if (kind === "using" || kind === "await using") {
|
|
if (id.type === "ArrayPattern" || id.type === "ObjectPattern") {
|
|
this.raise(Errors.UsingDeclarationHasBindingPattern, id.loc.start);
|
|
}
|
|
} else {
|
|
if (id.type === "VoidPattern") {
|
|
this.raise(Errors.UnexpectedVoidPattern, id.loc.start);
|
|
}
|
|
}
|
|
this.checkLVal(id, {
|
|
type: "VariableDeclarator"
|
|
}, kind === "var" ? 5 : 8201);
|
|
decl.id = id;
|
|
}
|
|
parseAsyncFunctionExpression(node) {
|
|
return this.parseFunction(node, 8);
|
|
}
|
|
parseFunction(node, flags = 0) {
|
|
const hangingDeclaration = flags & 2;
|
|
const isDeclaration = !!(flags & 1);
|
|
const requireId = isDeclaration && !(flags & 4);
|
|
const isAsync = !!(flags & 8);
|
|
this.initFunction(node, isAsync);
|
|
if (this.match(55)) {
|
|
if (hangingDeclaration) {
|
|
this.raise(Errors.GeneratorInSingleStatementContext, this.state.startLoc);
|
|
}
|
|
this.next();
|
|
node.generator = true;
|
|
}
|
|
if (isDeclaration) {
|
|
node.id = this.parseFunctionId(requireId);
|
|
}
|
|
const oldMaybeInArrowParameters = this.state.maybeInArrowParameters;
|
|
this.state.maybeInArrowParameters = false;
|
|
this.scope.enter(514);
|
|
this.prodParam.enter(functionFlags(isAsync, node.generator));
|
|
if (!isDeclaration) {
|
|
node.id = this.parseFunctionId();
|
|
}
|
|
this.parseFunctionParams(node, false);
|
|
this.withSmartMixTopicForbiddingContext(() => {
|
|
this.parseFunctionBodyAndFinish(node, isDeclaration ? "FunctionDeclaration" : "FunctionExpression");
|
|
});
|
|
this.prodParam.exit();
|
|
this.scope.exit();
|
|
if (isDeclaration && !hangingDeclaration) {
|
|
this.registerFunctionStatementId(node);
|
|
}
|
|
this.state.maybeInArrowParameters = oldMaybeInArrowParameters;
|
|
return node;
|
|
}
|
|
parseFunctionId(requireId) {
|
|
return requireId || tokenIsIdentifier(this.state.type) ? this.parseIdentifier() : null;
|
|
}
|
|
parseFunctionParams(node, isConstructor) {
|
|
this.expect(10);
|
|
this.expressionScope.enter(newParameterDeclarationScope());
|
|
node.params = this.parseBindingList(11, 41, 2 | (isConstructor ? 4 : 0));
|
|
this.expressionScope.exit();
|
|
}
|
|
registerFunctionStatementId(node) {
|
|
if (!node.id) return;
|
|
this.scope.declareName(node.id.name, !this.options.annexB || this.state.strict || node.generator || node.async ? this.scope.treatFunctionsAsVar ? 5 : 8201 : 17, node.id.loc.start);
|
|
}
|
|
parseClass(node, isStatement, optionalId) {
|
|
this.next();
|
|
const oldStrict = this.state.strict;
|
|
this.state.strict = true;
|
|
this.parseClassId(node, isStatement, optionalId);
|
|
this.parseClassSuper(node);
|
|
node.body = this.parseClassBody(!!node.superClass, oldStrict);
|
|
return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression");
|
|
}
|
|
isClassProperty() {
|
|
return this.match(29) || this.match(13) || this.match(8);
|
|
}
|
|
isClassMethod() {
|
|
return this.match(10);
|
|
}
|
|
nameIsConstructor(key) {
|
|
return key.type === "Identifier" && key.name === "constructor" || key.type === "StringLiteral" && key.value === "constructor";
|
|
}
|
|
isNonstaticConstructor(method) {
|
|
return !method.computed && !method.static && this.nameIsConstructor(method.key);
|
|
}
|
|
parseClassBody(hadSuperClass, oldStrict) {
|
|
this.classScope.enter();
|
|
const state = {
|
|
hadConstructor: false,
|
|
hadSuperClass
|
|
};
|
|
let decorators = [];
|
|
const classBody = this.startNode();
|
|
classBody.body = [];
|
|
this.expect(5);
|
|
this.withSmartMixTopicForbiddingContext(() => {
|
|
while (!this.match(8)) {
|
|
if (this.eat(13)) {
|
|
if (decorators.length > 0) {
|
|
throw this.raise(Errors.DecoratorSemicolon, this.state.lastTokEndLoc);
|
|
}
|
|
continue;
|
|
}
|
|
if (this.match(26)) {
|
|
decorators.push(this.parseDecorator());
|
|
continue;
|
|
}
|
|
const member = this.startNode();
|
|
if (decorators.length) {
|
|
member.decorators = decorators;
|
|
this.resetStartLocationFromNode(member, decorators[0]);
|
|
decorators = [];
|
|
}
|
|
this.parseClassMember(classBody, member, state);
|
|
if (member.kind === "constructor" && member.decorators && member.decorators.length > 0) {
|
|
this.raise(Errors.DecoratorConstructor, member);
|
|
}
|
|
}
|
|
});
|
|
this.state.strict = oldStrict;
|
|
this.next();
|
|
if (decorators.length) {
|
|
throw this.raise(Errors.TrailingDecorator, this.state.startLoc);
|
|
}
|
|
this.classScope.exit();
|
|
return this.finishNode(classBody, "ClassBody");
|
|
}
|
|
parseClassMemberFromModifier(classBody, member) {
|
|
const key = this.parseIdentifier(true);
|
|
if (this.isClassMethod()) {
|
|
const method = member;
|
|
method.kind = "method";
|
|
method.computed = false;
|
|
method.key = key;
|
|
method.static = false;
|
|
this.pushClassMethod(classBody, method, false, false, false, false);
|
|
return true;
|
|
} else if (this.isClassProperty()) {
|
|
const prop = member;
|
|
prop.computed = false;
|
|
prop.key = key;
|
|
prop.static = false;
|
|
classBody.body.push(this.parseClassProperty(prop));
|
|
return true;
|
|
}
|
|
this.resetPreviousNodeTrailingComments(key);
|
|
return false;
|
|
}
|
|
parseClassMember(classBody, member, state) {
|
|
const isStatic = this.isContextual(106);
|
|
if (isStatic) {
|
|
if (this.parseClassMemberFromModifier(classBody, member)) {
|
|
return;
|
|
}
|
|
if (this.eat(5)) {
|
|
this.parseClassStaticBlock(classBody, member);
|
|
return;
|
|
}
|
|
}
|
|
this.parseClassMemberWithIsStatic(classBody, member, state, isStatic);
|
|
}
|
|
parseClassMemberWithIsStatic(classBody, member, state, isStatic) {
|
|
const publicMethod = member;
|
|
const privateMethod = member;
|
|
const publicProp = member;
|
|
const privateProp = member;
|
|
const accessorProp = member;
|
|
const method = publicMethod;
|
|
const publicMember = publicMethod;
|
|
member.static = isStatic;
|
|
this.parsePropertyNamePrefixOperator(member);
|
|
if (this.eat(55)) {
|
|
method.kind = "method";
|
|
const isPrivateName = this.match(139);
|
|
this.parseClassElementName(method);
|
|
this.parsePostMemberNameModifiers(method);
|
|
if (isPrivateName) {
|
|
this.pushClassPrivateMethod(classBody, privateMethod, true, false);
|
|
return;
|
|
}
|
|
if (this.isNonstaticConstructor(publicMethod)) {
|
|
this.raise(Errors.ConstructorIsGenerator, publicMethod.key);
|
|
}
|
|
this.pushClassMethod(classBody, publicMethod, true, false, false, false);
|
|
return;
|
|
}
|
|
const isContextual = !this.state.containsEsc && tokenIsIdentifier(this.state.type);
|
|
const key = this.parseClassElementName(member);
|
|
const maybeContextualKw = isContextual ? key.name : null;
|
|
const isPrivate = this.isPrivateName(key);
|
|
const maybeQuestionTokenStartLoc = this.state.startLoc;
|
|
this.parsePostMemberNameModifiers(publicMember);
|
|
if (this.isClassMethod()) {
|
|
method.kind = "method";
|
|
if (isPrivate) {
|
|
this.pushClassPrivateMethod(classBody, privateMethod, false, false);
|
|
return;
|
|
}
|
|
const isConstructor = this.isNonstaticConstructor(publicMethod);
|
|
let allowsDirectSuper = false;
|
|
if (isConstructor) {
|
|
publicMethod.kind = "constructor";
|
|
if (state.hadConstructor && !this.hasPlugin("typescript")) {
|
|
this.raise(Errors.DuplicateConstructor, key);
|
|
}
|
|
if (isConstructor && this.hasPlugin("typescript") && member.override) {
|
|
this.raise(Errors.OverrideOnConstructor, key);
|
|
}
|
|
state.hadConstructor = true;
|
|
allowsDirectSuper = state.hadSuperClass;
|
|
}
|
|
this.pushClassMethod(classBody, publicMethod, false, false, isConstructor, allowsDirectSuper);
|
|
} else if (this.isClassProperty()) {
|
|
if (isPrivate) {
|
|
this.pushClassPrivateProperty(classBody, privateProp);
|
|
} else {
|
|
this.pushClassProperty(classBody, publicProp);
|
|
}
|
|
} else if (maybeContextualKw === "async" && !this.isLineTerminator()) {
|
|
this.resetPreviousNodeTrailingComments(key);
|
|
const isGenerator = this.eat(55);
|
|
if (publicMember.optional) {
|
|
this.unexpected(maybeQuestionTokenStartLoc);
|
|
}
|
|
method.kind = "method";
|
|
const isPrivate = this.match(139);
|
|
this.parseClassElementName(method);
|
|
this.parsePostMemberNameModifiers(publicMember);
|
|
if (isPrivate) {
|
|
this.pushClassPrivateMethod(classBody, privateMethod, isGenerator, true);
|
|
} else {
|
|
if (this.isNonstaticConstructor(publicMethod)) {
|
|
this.raise(Errors.ConstructorIsAsync, publicMethod.key);
|
|
}
|
|
this.pushClassMethod(classBody, publicMethod, isGenerator, true, false, false);
|
|
}
|
|
} else if ((maybeContextualKw === "get" || maybeContextualKw === "set") && !(this.match(55) && this.isLineTerminator())) {
|
|
this.resetPreviousNodeTrailingComments(key);
|
|
method.kind = maybeContextualKw;
|
|
const isPrivate = this.match(139);
|
|
this.parseClassElementName(publicMethod);
|
|
if (isPrivate) {
|
|
this.pushClassPrivateMethod(classBody, privateMethod, false, false);
|
|
} else {
|
|
if (this.isNonstaticConstructor(publicMethod)) {
|
|
this.raise(Errors.ConstructorIsAccessor, publicMethod.key);
|
|
}
|
|
this.pushClassMethod(classBody, publicMethod, false, false, false, false);
|
|
}
|
|
this.checkGetterSetterParams(publicMethod);
|
|
} else if (maybeContextualKw === "accessor" && !this.isLineTerminator()) {
|
|
this.expectPlugin("decoratorAutoAccessors");
|
|
this.resetPreviousNodeTrailingComments(key);
|
|
const isPrivate = this.match(139);
|
|
this.parseClassElementName(publicProp);
|
|
this.pushClassAccessorProperty(classBody, accessorProp, isPrivate);
|
|
} else if (this.isLineTerminator()) {
|
|
if (isPrivate) {
|
|
this.pushClassPrivateProperty(classBody, privateProp);
|
|
} else {
|
|
this.pushClassProperty(classBody, publicProp);
|
|
}
|
|
} else {
|
|
this.unexpected();
|
|
}
|
|
}
|
|
parseClassElementName(member) {
|
|
const {
|
|
type,
|
|
value
|
|
} = this.state;
|
|
if ((type === 132 || type === 134) && member.static && value === "prototype") {
|
|
this.raise(Errors.StaticPrototype, this.state.startLoc);
|
|
}
|
|
if (type === 139) {
|
|
if (value === "constructor") {
|
|
this.raise(Errors.ConstructorClassPrivateField, this.state.startLoc);
|
|
}
|
|
const key = this.parsePrivateName();
|
|
member.key = key;
|
|
return key;
|
|
}
|
|
this.parsePropertyName(member);
|
|
return member.key;
|
|
}
|
|
parseClassStaticBlock(classBody, member) {
|
|
var _member$decorators;
|
|
this.scope.enter(576 | 128 | 16);
|
|
const oldLabels = this.state.labels;
|
|
this.state.labels = [];
|
|
this.prodParam.enter(0);
|
|
const body = member.body = [];
|
|
this.parseBlockOrModuleBlockBody(body, undefined, false, 8);
|
|
this.prodParam.exit();
|
|
this.scope.exit();
|
|
this.state.labels = oldLabels;
|
|
classBody.body.push(this.finishNode(member, "StaticBlock"));
|
|
if ((_member$decorators = member.decorators) != null && _member$decorators.length) {
|
|
this.raise(Errors.DecoratorStaticBlock, member);
|
|
}
|
|
}
|
|
pushClassProperty(classBody, prop) {
|
|
if (!prop.computed && this.nameIsConstructor(prop.key)) {
|
|
this.raise(Errors.ConstructorClassField, prop.key);
|
|
}
|
|
classBody.body.push(this.parseClassProperty(prop));
|
|
}
|
|
pushClassPrivateProperty(classBody, prop) {
|
|
const node = this.parseClassPrivateProperty(prop);
|
|
classBody.body.push(node);
|
|
this.classScope.declarePrivateName(this.getPrivateNameSV(node.key), 0, node.key.loc.start);
|
|
}
|
|
pushClassAccessorProperty(classBody, prop, isPrivate) {
|
|
if (!isPrivate && !prop.computed && this.nameIsConstructor(prop.key)) {
|
|
this.raise(Errors.ConstructorClassField, prop.key);
|
|
}
|
|
const node = this.parseClassAccessorProperty(prop);
|
|
classBody.body.push(node);
|
|
if (isPrivate) {
|
|
this.classScope.declarePrivateName(this.getPrivateNameSV(node.key), 0, node.key.loc.start);
|
|
}
|
|
}
|
|
pushClassMethod(classBody, method, isGenerator, isAsync, isConstructor, allowsDirectSuper) {
|
|
classBody.body.push(this.parseMethod(method, isGenerator, isAsync, isConstructor, allowsDirectSuper, "ClassMethod", true));
|
|
}
|
|
pushClassPrivateMethod(classBody, method, isGenerator, isAsync) {
|
|
const node = this.parseMethod(method, isGenerator, isAsync, false, false, "ClassPrivateMethod", true);
|
|
classBody.body.push(node);
|
|
const kind = node.kind === "get" ? node.static ? 6 : 2 : node.kind === "set" ? node.static ? 5 : 1 : 0;
|
|
this.declareClassPrivateMethodInScope(node, kind);
|
|
}
|
|
declareClassPrivateMethodInScope(node, kind) {
|
|
this.classScope.declarePrivateName(this.getPrivateNameSV(node.key), kind, node.key.loc.start);
|
|
}
|
|
parsePostMemberNameModifiers(methodOrProp) {}
|
|
parseClassPrivateProperty(node) {
|
|
this.parseInitializer(node);
|
|
this.semicolon();
|
|
return this.finishNode(node, "ClassPrivateProperty");
|
|
}
|
|
parseClassProperty(node) {
|
|
this.parseInitializer(node);
|
|
this.semicolon();
|
|
return this.finishNode(node, "ClassProperty");
|
|
}
|
|
parseClassAccessorProperty(node) {
|
|
this.parseInitializer(node);
|
|
this.semicolon();
|
|
return this.finishNode(node, "ClassAccessorProperty");
|
|
}
|
|
parseInitializer(node) {
|
|
this.scope.enter(576 | 16);
|
|
this.expressionScope.enter(newExpressionScope());
|
|
this.prodParam.enter(0);
|
|
node.value = this.eat(29) ? this.parseMaybeAssignAllowIn() : null;
|
|
this.expressionScope.exit();
|
|
this.prodParam.exit();
|
|
this.scope.exit();
|
|
}
|
|
parseClassId(node, isStatement, optionalId, bindingType = 8331) {
|
|
if (tokenIsIdentifier(this.state.type)) {
|
|
node.id = this.parseIdentifier();
|
|
if (isStatement) {
|
|
this.declareNameFromIdentifier(node.id, bindingType);
|
|
}
|
|
} else {
|
|
if (optionalId || !isStatement) {
|
|
node.id = null;
|
|
} else {
|
|
throw this.raise(Errors.MissingClassName, this.state.startLoc);
|
|
}
|
|
}
|
|
}
|
|
parseClassSuper(node) {
|
|
node.superClass = this.eat(81) ? this.parseExprSubscripts() : null;
|
|
}
|
|
parseExport(node, decorators) {
|
|
const maybeDefaultIdentifier = this.parseMaybeImportPhase(node, true);
|
|
const hasDefault = this.maybeParseExportDefaultSpecifier(node, maybeDefaultIdentifier);
|
|
const parseAfterDefault = !hasDefault || this.eat(12);
|
|
const hasStar = parseAfterDefault && this.eatExportStar(node);
|
|
const hasNamespace = hasStar && this.maybeParseExportNamespaceSpecifier(node);
|
|
const parseAfterNamespace = parseAfterDefault && (!hasNamespace || this.eat(12));
|
|
const isFromRequired = hasDefault || hasStar;
|
|
if (hasStar && !hasNamespace) {
|
|
if (hasDefault) this.unexpected();
|
|
if (decorators) {
|
|
throw this.raise(Errors.UnsupportedDecoratorExport, node);
|
|
}
|
|
this.parseExportFrom(node, true);
|
|
this.sawUnambiguousESM = true;
|
|
return this.finishNode(node, "ExportAllDeclaration");
|
|
}
|
|
const hasSpecifiers = this.maybeParseExportNamedSpecifiers(node);
|
|
if (hasDefault && parseAfterDefault && !hasStar && !hasSpecifiers) {
|
|
this.unexpected(null, 5);
|
|
}
|
|
if (hasNamespace && parseAfterNamespace) {
|
|
this.unexpected(null, 98);
|
|
}
|
|
let hasDeclaration;
|
|
if (isFromRequired || hasSpecifiers) {
|
|
hasDeclaration = false;
|
|
if (decorators) {
|
|
throw this.raise(Errors.UnsupportedDecoratorExport, node);
|
|
}
|
|
this.parseExportFrom(node, isFromRequired);
|
|
} else {
|
|
hasDeclaration = this.maybeParseExportDeclaration(node);
|
|
}
|
|
if (isFromRequired || hasSpecifiers || hasDeclaration) {
|
|
var _node2$declaration;
|
|
const node2 = node;
|
|
this.checkExport(node2, true, false, !!node2.source);
|
|
if (((_node2$declaration = node2.declaration) == null ? void 0 : _node2$declaration.type) === "ClassDeclaration") {
|
|
this.maybeTakeDecorators(decorators, node2.declaration, node2);
|
|
} else if (decorators) {
|
|
throw this.raise(Errors.UnsupportedDecoratorExport, node);
|
|
}
|
|
this.sawUnambiguousESM = true;
|
|
return this.finishNode(node2, "ExportNamedDeclaration");
|
|
}
|
|
if (this.eat(65)) {
|
|
const node2 = node;
|
|
const decl = this.parseExportDefaultExpression();
|
|
node2.declaration = decl;
|
|
if (decl.type === "ClassDeclaration") {
|
|
this.maybeTakeDecorators(decorators, decl, node2);
|
|
} else if (decorators) {
|
|
throw this.raise(Errors.UnsupportedDecoratorExport, node);
|
|
}
|
|
this.checkExport(node2, true, true);
|
|
this.sawUnambiguousESM = true;
|
|
return this.finishNode(node2, "ExportDefaultDeclaration");
|
|
}
|
|
throw this.unexpected(null, 5);
|
|
}
|
|
eatExportStar(node) {
|
|
return this.eat(55);
|
|
}
|
|
maybeParseExportDefaultSpecifier(node, maybeDefaultIdentifier) {
|
|
if (maybeDefaultIdentifier || this.isExportDefaultSpecifier()) {
|
|
this.expectPlugin("exportDefaultFrom", maybeDefaultIdentifier == null ? void 0 : maybeDefaultIdentifier.loc.start);
|
|
const id = maybeDefaultIdentifier || this.parseIdentifier(true);
|
|
const specifier = this.startNodeAtNode(id);
|
|
specifier.exported = id;
|
|
node.specifiers = [this.finishNode(specifier, "ExportDefaultSpecifier")];
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
maybeParseExportNamespaceSpecifier(node) {
|
|
if (this.isContextual(93)) {
|
|
var _ref, _ref$specifiers;
|
|
(_ref$specifiers = (_ref = node).specifiers) != null ? _ref$specifiers : _ref.specifiers = [];
|
|
const specifier = this.startNodeAt(this.state.lastTokStartLoc);
|
|
this.next();
|
|
specifier.exported = this.parseModuleExportName();
|
|
node.specifiers.push(this.finishNode(specifier, "ExportNamespaceSpecifier"));
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
maybeParseExportNamedSpecifiers(node) {
|
|
if (this.match(5)) {
|
|
const node2 = node;
|
|
if (!node2.specifiers) node2.specifiers = [];
|
|
const isTypeExport = node2.exportKind === "type";
|
|
node2.specifiers.push(...this.parseExportSpecifiers(isTypeExport));
|
|
node2.source = null;
|
|
if (this.hasPlugin("importAssertions")) {
|
|
node2.assertions = [];
|
|
} else {
|
|
node2.attributes = [];
|
|
}
|
|
node2.declaration = null;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
maybeParseExportDeclaration(node) {
|
|
if (this.shouldParseExportDeclaration()) {
|
|
node.specifiers = [];
|
|
node.source = null;
|
|
if (this.hasPlugin("importAssertions")) {
|
|
node.assertions = [];
|
|
} else {
|
|
node.attributes = [];
|
|
}
|
|
node.declaration = this.parseExportDeclaration(node);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
isAsyncFunction() {
|
|
if (!this.isContextual(95)) return false;
|
|
const next = this.nextTokenInLineStart();
|
|
return this.isUnparsedContextual(next, "function");
|
|
}
|
|
parseExportDefaultExpression() {
|
|
const expr = this.startNode();
|
|
if (this.match(68)) {
|
|
this.next();
|
|
return this.parseFunction(expr, 1 | 4);
|
|
} else if (this.isAsyncFunction()) {
|
|
this.next();
|
|
this.next();
|
|
return this.parseFunction(expr, 1 | 4 | 8);
|
|
}
|
|
if (this.match(80)) {
|
|
return this.parseClass(expr, true, true);
|
|
}
|
|
if (this.match(26)) {
|
|
if (this.hasPlugin("decorators") && this.getPluginOption("decorators", "decoratorsBeforeExport") === true) {
|
|
this.raise(Errors.DecoratorBeforeExport, this.state.startLoc);
|
|
}
|
|
return this.parseClass(this.maybeTakeDecorators(this.parseDecorators(false), this.startNode()), true, true);
|
|
}
|
|
if (this.match(75) || this.match(74) || this.isLet() || this.isUsing() || this.isAwaitUsing()) {
|
|
throw this.raise(Errors.UnsupportedDefaultExport, this.state.startLoc);
|
|
}
|
|
const res = this.parseMaybeAssignAllowIn();
|
|
this.semicolon();
|
|
return res;
|
|
}
|
|
parseExportDeclaration(node) {
|
|
if (this.match(80)) {
|
|
const node = this.parseClass(this.startNode(), true, false);
|
|
return node;
|
|
}
|
|
return this.parseStatementListItem();
|
|
}
|
|
isExportDefaultSpecifier() {
|
|
const {
|
|
type
|
|
} = this.state;
|
|
if (tokenIsIdentifier(type)) {
|
|
if (type === 95 && !this.state.containsEsc || type === 100) {
|
|
return false;
|
|
}
|
|
if ((type === 130 || type === 129) && !this.state.containsEsc) {
|
|
const next = this.nextTokenStart();
|
|
const nextChar = this.input.charCodeAt(next);
|
|
if (nextChar === 123 || this.chStartsBindingIdentifier(nextChar, next) && !this.input.startsWith("from", next)) {
|
|
this.expectOnePlugin(["flow", "typescript"]);
|
|
return false;
|
|
}
|
|
}
|
|
} else if (!this.match(65)) {
|
|
return false;
|
|
}
|
|
const next = this.nextTokenStart();
|
|
const hasFrom = this.isUnparsedContextual(next, "from");
|
|
if (this.input.charCodeAt(next) === 44 || tokenIsIdentifier(this.state.type) && hasFrom) {
|
|
return true;
|
|
}
|
|
if (this.match(65) && hasFrom) {
|
|
const nextAfterFrom = this.input.charCodeAt(this.nextTokenStartSince(next + 4));
|
|
return nextAfterFrom === 34 || nextAfterFrom === 39;
|
|
}
|
|
return false;
|
|
}
|
|
parseExportFrom(node, expect) {
|
|
if (this.eatContextual(98)) {
|
|
node.source = this.parseImportSource();
|
|
this.checkExport(node);
|
|
this.maybeParseImportAttributes(node);
|
|
this.checkJSONModuleImport(node);
|
|
} else if (expect) {
|
|
this.unexpected();
|
|
}
|
|
this.semicolon();
|
|
}
|
|
shouldParseExportDeclaration() {
|
|
const {
|
|
type
|
|
} = this.state;
|
|
if (type === 26) {
|
|
this.expectOnePlugin(["decorators", "decorators-legacy"]);
|
|
if (this.hasPlugin("decorators")) {
|
|
if (this.getPluginOption("decorators", "decoratorsBeforeExport") === true) {
|
|
this.raise(Errors.DecoratorBeforeExport, this.state.startLoc);
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
if (this.isUsing()) {
|
|
this.raise(Errors.UsingDeclarationExport, this.state.startLoc);
|
|
return true;
|
|
}
|
|
if (this.isAwaitUsing()) {
|
|
this.raise(Errors.UsingDeclarationExport, this.state.startLoc);
|
|
return true;
|
|
}
|
|
return type === 74 || type === 75 || type === 68 || type === 80 || this.isLet() || this.isAsyncFunction();
|
|
}
|
|
checkExport(node, checkNames, isDefault, isFrom) {
|
|
if (checkNames) {
|
|
var _node$specifiers;
|
|
if (isDefault) {
|
|
this.checkDuplicateExports(node, "default");
|
|
if (this.hasPlugin("exportDefaultFrom")) {
|
|
var _declaration$extra;
|
|
const declaration = node.declaration;
|
|
if (declaration.type === "Identifier" && declaration.name === "from" && declaration.end - declaration.start === 4 && !((_declaration$extra = declaration.extra) != null && _declaration$extra.parenthesized)) {
|
|
this.raise(Errors.ExportDefaultFromAsIdentifier, declaration);
|
|
}
|
|
}
|
|
} else if ((_node$specifiers = node.specifiers) != null && _node$specifiers.length) {
|
|
for (const specifier of node.specifiers) {
|
|
const {
|
|
exported
|
|
} = specifier;
|
|
const exportName = exported.type === "Identifier" ? exported.name : exported.value;
|
|
this.checkDuplicateExports(specifier, exportName);
|
|
if (!isFrom && specifier.local) {
|
|
const {
|
|
local
|
|
} = specifier;
|
|
if (local.type !== "Identifier") {
|
|
this.raise(Errors.ExportBindingIsString, specifier, {
|
|
localName: local.value,
|
|
exportName
|
|
});
|
|
} else {
|
|
this.checkReservedWord(local.name, local.loc.start, true, false);
|
|
this.scope.checkLocalExport(local);
|
|
}
|
|
}
|
|
}
|
|
} else if (node.declaration) {
|
|
const decl = node.declaration;
|
|
if (decl.type === "FunctionDeclaration" || decl.type === "ClassDeclaration") {
|
|
const {
|
|
id
|
|
} = decl;
|
|
if (!id) throw new Error("Assertion failure");
|
|
this.checkDuplicateExports(node, id.name);
|
|
} else if (decl.type === "VariableDeclaration") {
|
|
for (const declaration of decl.declarations) {
|
|
this.checkDeclaration(declaration.id);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
checkDeclaration(node) {
|
|
if (node.type === "Identifier") {
|
|
this.checkDuplicateExports(node, node.name);
|
|
} else if (node.type === "ObjectPattern") {
|
|
for (const prop of node.properties) {
|
|
this.checkDeclaration(prop);
|
|
}
|
|
} else if (node.type === "ArrayPattern") {
|
|
for (const elem of node.elements) {
|
|
if (elem) {
|
|
this.checkDeclaration(elem);
|
|
}
|
|
}
|
|
} else if (node.type === "ObjectProperty") {
|
|
this.checkDeclaration(node.value);
|
|
} else if (node.type === "RestElement") {
|
|
this.checkDeclaration(node.argument);
|
|
} else if (node.type === "AssignmentPattern") {
|
|
this.checkDeclaration(node.left);
|
|
}
|
|
}
|
|
checkDuplicateExports(node, exportName) {
|
|
if (this.exportedIdentifiers.has(exportName)) {
|
|
if (exportName === "default") {
|
|
this.raise(Errors.DuplicateDefaultExport, node);
|
|
} else {
|
|
this.raise(Errors.DuplicateExport, node, {
|
|
exportName
|
|
});
|
|
}
|
|
}
|
|
this.exportedIdentifiers.add(exportName);
|
|
}
|
|
parseExportSpecifiers(isInTypeExport) {
|
|
const nodes = [];
|
|
let first = true;
|
|
this.expect(5);
|
|
while (!this.eat(8)) {
|
|
if (first) {
|
|
first = false;
|
|
} else {
|
|
this.expect(12);
|
|
if (this.eat(8)) break;
|
|
}
|
|
const isMaybeTypeOnly = this.isContextual(130);
|
|
const isString = this.match(134);
|
|
const node = this.startNode();
|
|
node.local = this.parseModuleExportName();
|
|
nodes.push(this.parseExportSpecifier(node, isString, isInTypeExport, isMaybeTypeOnly));
|
|
}
|
|
return nodes;
|
|
}
|
|
parseExportSpecifier(node, isString, isInTypeExport, isMaybeTypeOnly) {
|
|
if (this.eatContextual(93)) {
|
|
node.exported = this.parseModuleExportName();
|
|
} else if (isString) {
|
|
node.exported = this.cloneStringLiteral(node.local);
|
|
} else if (!node.exported) {
|
|
node.exported = this.cloneIdentifier(node.local);
|
|
}
|
|
return this.finishNode(node, "ExportSpecifier");
|
|
}
|
|
parseModuleExportName() {
|
|
if (this.match(134)) {
|
|
const result = this.parseStringLiteral(this.state.value);
|
|
const surrogate = loneSurrogate.exec(result.value);
|
|
if (surrogate) {
|
|
this.raise(Errors.ModuleExportNameHasLoneSurrogate, result, {
|
|
surrogateCharCode: surrogate[0].charCodeAt(0)
|
|
});
|
|
}
|
|
return result;
|
|
}
|
|
return this.parseIdentifier(true);
|
|
}
|
|
isJSONModuleImport(node) {
|
|
if (node.assertions != null) {
|
|
return node.assertions.some(({
|
|
key,
|
|
value
|
|
}) => {
|
|
return value.value === "json" && (key.type === "Identifier" ? key.name === "type" : key.value === "type");
|
|
});
|
|
}
|
|
return false;
|
|
}
|
|
checkImportReflection(node) {
|
|
const {
|
|
specifiers
|
|
} = node;
|
|
const singleBindingType = specifiers.length === 1 ? specifiers[0].type : null;
|
|
if (node.phase === "source") {
|
|
if (singleBindingType !== "ImportDefaultSpecifier") {
|
|
this.raise(Errors.SourcePhaseImportRequiresDefault, specifiers[0].loc.start);
|
|
}
|
|
} else if (node.phase === "defer") {
|
|
if (singleBindingType !== "ImportNamespaceSpecifier") {
|
|
this.raise(Errors.DeferImportRequiresNamespace, specifiers[0].loc.start);
|
|
}
|
|
} else if (node.module) {
|
|
var _node$assertions;
|
|
if (singleBindingType !== "ImportDefaultSpecifier") {
|
|
this.raise(Errors.ImportReflectionNotBinding, specifiers[0].loc.start);
|
|
}
|
|
if (((_node$assertions = node.assertions) == null ? void 0 : _node$assertions.length) > 0) {
|
|
this.raise(Errors.ImportReflectionHasAssertion, specifiers[0].loc.start);
|
|
}
|
|
}
|
|
}
|
|
checkJSONModuleImport(node) {
|
|
if (this.isJSONModuleImport(node) && node.type !== "ExportAllDeclaration") {
|
|
const {
|
|
specifiers
|
|
} = node;
|
|
if (specifiers != null) {
|
|
const nonDefaultNamedSpecifier = specifiers.find(specifier => {
|
|
let imported;
|
|
if (specifier.type === "ExportSpecifier") {
|
|
imported = specifier.local;
|
|
} else if (specifier.type === "ImportSpecifier") {
|
|
imported = specifier.imported;
|
|
}
|
|
if (imported !== undefined) {
|
|
return imported.type === "Identifier" ? imported.name !== "default" : imported.value !== "default";
|
|
}
|
|
});
|
|
if (nonDefaultNamedSpecifier !== undefined) {
|
|
this.raise(Errors.ImportJSONBindingNotDefault, nonDefaultNamedSpecifier.loc.start);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
isPotentialImportPhase(isExport) {
|
|
if (isExport) return false;
|
|
return this.isContextual(105) || this.isContextual(97) || this.isContextual(127);
|
|
}
|
|
applyImportPhase(node, isExport, phase, loc) {
|
|
if (isExport) {
|
|
return;
|
|
}
|
|
if (phase === "module") {
|
|
this.expectPlugin("importReflection", loc);
|
|
node.module = true;
|
|
} else if (this.hasPlugin("importReflection")) {
|
|
node.module = false;
|
|
}
|
|
if (phase === "source") {
|
|
this.expectPlugin("sourcePhaseImports", loc);
|
|
node.phase = "source";
|
|
} else if (phase === "defer") {
|
|
this.expectPlugin("deferredImportEvaluation", loc);
|
|
node.phase = "defer";
|
|
} else if (this.hasPlugin("sourcePhaseImports")) {
|
|
node.phase = null;
|
|
}
|
|
}
|
|
parseMaybeImportPhase(node, isExport) {
|
|
if (!this.isPotentialImportPhase(isExport)) {
|
|
this.applyImportPhase(node, isExport, null);
|
|
return null;
|
|
}
|
|
const phaseIdentifier = this.startNode();
|
|
const phaseIdentifierName = this.parseIdentifierName(true);
|
|
const {
|
|
type
|
|
} = this.state;
|
|
const isImportPhase = tokenIsKeywordOrIdentifier(type) ? type !== 98 || this.lookaheadCharCode() === 102 : type !== 12;
|
|
if (isImportPhase) {
|
|
this.applyImportPhase(node, isExport, phaseIdentifierName, phaseIdentifier.loc.start);
|
|
return null;
|
|
} else {
|
|
this.applyImportPhase(node, isExport, null);
|
|
return this.createIdentifier(phaseIdentifier, phaseIdentifierName);
|
|
}
|
|
}
|
|
isPrecedingIdImportPhase(phase) {
|
|
const {
|
|
type
|
|
} = this.state;
|
|
return tokenIsIdentifier(type) ? type !== 98 || this.lookaheadCharCode() === 102 : type !== 12;
|
|
}
|
|
parseImport(node) {
|
|
if (this.match(134)) {
|
|
return this.parseImportSourceAndAttributes(node);
|
|
}
|
|
return this.parseImportSpecifiersAndAfter(node, this.parseMaybeImportPhase(node, false));
|
|
}
|
|
parseImportSpecifiersAndAfter(node, maybeDefaultIdentifier) {
|
|
node.specifiers = [];
|
|
const hasDefault = this.maybeParseDefaultImportSpecifier(node, maybeDefaultIdentifier);
|
|
const parseNext = !hasDefault || this.eat(12);
|
|
const hasStar = parseNext && this.maybeParseStarImportSpecifier(node);
|
|
if (parseNext && !hasStar) this.parseNamedImportSpecifiers(node);
|
|
this.expectContextual(98);
|
|
return this.parseImportSourceAndAttributes(node);
|
|
}
|
|
parseImportSourceAndAttributes(node) {
|
|
var _node$specifiers2;
|
|
(_node$specifiers2 = node.specifiers) != null ? _node$specifiers2 : node.specifiers = [];
|
|
node.source = this.parseImportSource();
|
|
this.maybeParseImportAttributes(node);
|
|
this.checkImportReflection(node);
|
|
this.checkJSONModuleImport(node);
|
|
this.semicolon();
|
|
this.sawUnambiguousESM = true;
|
|
return this.finishNode(node, "ImportDeclaration");
|
|
}
|
|
parseImportSource() {
|
|
if (!this.match(134)) this.unexpected();
|
|
return this.parseExprAtom();
|
|
}
|
|
parseImportSpecifierLocal(node, specifier, type) {
|
|
specifier.local = this.parseIdentifier();
|
|
node.specifiers.push(this.finishImportSpecifier(specifier, type));
|
|
}
|
|
finishImportSpecifier(specifier, type, bindingType = 8201) {
|
|
this.checkLVal(specifier.local, {
|
|
type
|
|
}, bindingType);
|
|
return this.finishNode(specifier, type);
|
|
}
|
|
parseImportAttributes() {
|
|
this.expect(5);
|
|
const attrs = [];
|
|
const attrNames = new Set();
|
|
do {
|
|
if (this.match(8)) {
|
|
break;
|
|
}
|
|
const node = this.startNode();
|
|
const keyName = this.state.value;
|
|
if (attrNames.has(keyName)) {
|
|
this.raise(Errors.ModuleAttributesWithDuplicateKeys, this.state.startLoc, {
|
|
key: keyName
|
|
});
|
|
}
|
|
attrNames.add(keyName);
|
|
if (this.match(134)) {
|
|
node.key = this.parseStringLiteral(keyName);
|
|
} else {
|
|
node.key = this.parseIdentifier(true);
|
|
}
|
|
this.expect(14);
|
|
if (!this.match(134)) {
|
|
throw this.raise(Errors.ModuleAttributeInvalidValue, this.state.startLoc);
|
|
}
|
|
node.value = this.parseStringLiteral(this.state.value);
|
|
attrs.push(this.finishNode(node, "ImportAttribute"));
|
|
} while (this.eat(12));
|
|
this.expect(8);
|
|
return attrs;
|
|
}
|
|
parseModuleAttributes() {
|
|
const attrs = [];
|
|
const attributes = new Set();
|
|
do {
|
|
const node = this.startNode();
|
|
node.key = this.parseIdentifier(true);
|
|
if (node.key.name !== "type") {
|
|
this.raise(Errors.ModuleAttributeDifferentFromType, node.key);
|
|
}
|
|
if (attributes.has(node.key.name)) {
|
|
this.raise(Errors.ModuleAttributesWithDuplicateKeys, node.key, {
|
|
key: node.key.name
|
|
});
|
|
}
|
|
attributes.add(node.key.name);
|
|
this.expect(14);
|
|
if (!this.match(134)) {
|
|
throw this.raise(Errors.ModuleAttributeInvalidValue, this.state.startLoc);
|
|
}
|
|
node.value = this.parseStringLiteral(this.state.value);
|
|
attrs.push(this.finishNode(node, "ImportAttribute"));
|
|
} while (this.eat(12));
|
|
return attrs;
|
|
}
|
|
maybeParseImportAttributes(node) {
|
|
let attributes;
|
|
{
|
|
var useWith = false;
|
|
}
|
|
if (this.match(76)) {
|
|
if (this.hasPrecedingLineBreak() && this.lookaheadCharCode() === 40) {
|
|
return;
|
|
}
|
|
this.next();
|
|
if (this.hasPlugin("moduleAttributes")) {
|
|
attributes = this.parseModuleAttributes();
|
|
this.addExtra(node, "deprecatedWithLegacySyntax", true);
|
|
} else {
|
|
attributes = this.parseImportAttributes();
|
|
}
|
|
{
|
|
useWith = true;
|
|
}
|
|
} else if (this.isContextual(94) && !this.hasPrecedingLineBreak()) {
|
|
if (!this.hasPlugin("deprecatedImportAssert") && !this.hasPlugin("importAssertions")) {
|
|
this.raise(Errors.ImportAttributesUseAssert, this.state.startLoc);
|
|
}
|
|
if (!this.hasPlugin("importAssertions")) {
|
|
this.addExtra(node, "deprecatedAssertSyntax", true);
|
|
}
|
|
this.next();
|
|
attributes = this.parseImportAttributes();
|
|
} else {
|
|
attributes = [];
|
|
}
|
|
if (!useWith && this.hasPlugin("importAssertions")) {
|
|
node.assertions = attributes;
|
|
} else {
|
|
node.attributes = attributes;
|
|
}
|
|
}
|
|
maybeParseDefaultImportSpecifier(node, maybeDefaultIdentifier) {
|
|
if (maybeDefaultIdentifier) {
|
|
const specifier = this.startNodeAtNode(maybeDefaultIdentifier);
|
|
specifier.local = maybeDefaultIdentifier;
|
|
node.specifiers.push(this.finishImportSpecifier(specifier, "ImportDefaultSpecifier"));
|
|
return true;
|
|
} else if (tokenIsKeywordOrIdentifier(this.state.type)) {
|
|
this.parseImportSpecifierLocal(node, this.startNode(), "ImportDefaultSpecifier");
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
maybeParseStarImportSpecifier(node) {
|
|
if (this.match(55)) {
|
|
const specifier = this.startNode();
|
|
this.next();
|
|
this.expectContextual(93);
|
|
this.parseImportSpecifierLocal(node, specifier, "ImportNamespaceSpecifier");
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
parseNamedImportSpecifiers(node) {
|
|
let first = true;
|
|
this.expect(5);
|
|
while (!this.eat(8)) {
|
|
if (first) {
|
|
first = false;
|
|
} else {
|
|
if (this.eat(14)) {
|
|
throw this.raise(Errors.DestructureNamedImport, this.state.startLoc);
|
|
}
|
|
this.expect(12);
|
|
if (this.eat(8)) break;
|
|
}
|
|
const specifier = this.startNode();
|
|
const importedIsString = this.match(134);
|
|
const isMaybeTypeOnly = this.isContextual(130);
|
|
specifier.imported = this.parseModuleExportName();
|
|
const importSpecifier = this.parseImportSpecifier(specifier, importedIsString, node.importKind === "type" || node.importKind === "typeof", isMaybeTypeOnly, undefined);
|
|
node.specifiers.push(importSpecifier);
|
|
}
|
|
}
|
|
parseImportSpecifier(specifier, importedIsString, isInTypeOnlyImport, isMaybeTypeOnly, bindingType) {
|
|
if (this.eatContextual(93)) {
|
|
specifier.local = this.parseIdentifier();
|
|
} else {
|
|
const {
|
|
imported
|
|
} = specifier;
|
|
if (importedIsString) {
|
|
throw this.raise(Errors.ImportBindingIsString, specifier, {
|
|
importName: imported.value
|
|
});
|
|
}
|
|
this.checkReservedWord(imported.name, specifier.loc.start, true, true);
|
|
if (!specifier.local) {
|
|
specifier.local = this.cloneIdentifier(imported);
|
|
}
|
|
}
|
|
return this.finishImportSpecifier(specifier, "ImportSpecifier", bindingType);
|
|
}
|
|
isThisParam(param) {
|
|
return param.type === "Identifier" && param.name === "this";
|
|
}
|
|
}
|
|
class Parser extends StatementParser {
|
|
constructor(options, input, pluginsMap) {
|
|
const normalizedOptions = getOptions(options);
|
|
super(normalizedOptions, input);
|
|
this.options = normalizedOptions;
|
|
this.initializeScopes();
|
|
this.plugins = pluginsMap;
|
|
this.filename = normalizedOptions.sourceFilename;
|
|
this.startIndex = normalizedOptions.startIndex;
|
|
let optionFlags = 0;
|
|
if (normalizedOptions.allowAwaitOutsideFunction) {
|
|
optionFlags |= 1;
|
|
}
|
|
if (normalizedOptions.allowReturnOutsideFunction) {
|
|
optionFlags |= 2;
|
|
}
|
|
if (normalizedOptions.allowImportExportEverywhere) {
|
|
optionFlags |= 8;
|
|
}
|
|
if (normalizedOptions.allowSuperOutsideMethod) {
|
|
optionFlags |= 16;
|
|
}
|
|
if (normalizedOptions.allowUndeclaredExports) {
|
|
optionFlags |= 64;
|
|
}
|
|
if (normalizedOptions.allowNewTargetOutsideFunction) {
|
|
optionFlags |= 4;
|
|
}
|
|
if (normalizedOptions.allowYieldOutsideFunction) {
|
|
optionFlags |= 32;
|
|
}
|
|
if (normalizedOptions.ranges) {
|
|
optionFlags |= 128;
|
|
}
|
|
if (normalizedOptions.tokens) {
|
|
optionFlags |= 256;
|
|
}
|
|
if (normalizedOptions.createImportExpressions) {
|
|
optionFlags |= 512;
|
|
}
|
|
if (normalizedOptions.createParenthesizedExpressions) {
|
|
optionFlags |= 1024;
|
|
}
|
|
if (normalizedOptions.errorRecovery) {
|
|
optionFlags |= 2048;
|
|
}
|
|
if (normalizedOptions.attachComment) {
|
|
optionFlags |= 4096;
|
|
}
|
|
if (normalizedOptions.annexB) {
|
|
optionFlags |= 8192;
|
|
}
|
|
this.optionFlags = optionFlags;
|
|
}
|
|
getScopeHandler() {
|
|
return ScopeHandler;
|
|
}
|
|
parse() {
|
|
this.enterInitialScopes();
|
|
const file = this.startNode();
|
|
const program = this.startNode();
|
|
this.nextToken();
|
|
file.errors = null;
|
|
const result = this.parseTopLevel(file, program);
|
|
result.errors = this.state.errors;
|
|
result.comments.length = this.state.commentsLen;
|
|
return result;
|
|
}
|
|
}
|
|
function parse(input, options) {
|
|
var _options;
|
|
if (((_options = options) == null ? void 0 : _options.sourceType) === "unambiguous") {
|
|
options = Object.assign({}, options);
|
|
try {
|
|
options.sourceType = "module";
|
|
const parser = getParser(options, input);
|
|
const ast = parser.parse();
|
|
if (parser.sawUnambiguousESM) {
|
|
return ast;
|
|
}
|
|
if (parser.ambiguousScriptDifferentAst) {
|
|
try {
|
|
options.sourceType = "script";
|
|
return getParser(options, input).parse();
|
|
} catch (_unused) {}
|
|
} else {
|
|
ast.program.sourceType = "script";
|
|
}
|
|
return ast;
|
|
} catch (moduleError) {
|
|
try {
|
|
options.sourceType = "script";
|
|
return getParser(options, input).parse();
|
|
} catch (_unused2) {}
|
|
throw moduleError;
|
|
}
|
|
} else {
|
|
return getParser(options, input).parse();
|
|
}
|
|
}
|
|
function parseExpression(input, options) {
|
|
const parser = getParser(options, input);
|
|
if (parser.options.strictMode) {
|
|
parser.state.strict = true;
|
|
}
|
|
return parser.getExpression();
|
|
}
|
|
function generateExportedTokenTypes(internalTokenTypes) {
|
|
const tokenTypes = {};
|
|
for (const typeName of Object.keys(internalTokenTypes)) {
|
|
tokenTypes[typeName] = getExportedToken(internalTokenTypes[typeName]);
|
|
}
|
|
return tokenTypes;
|
|
}
|
|
const tokTypes = generateExportedTokenTypes(tt);
|
|
function getParser(options, input) {
|
|
let cls = Parser;
|
|
const pluginsMap = new Map();
|
|
if (options != null && options.plugins) {
|
|
for (const plugin of options.plugins) {
|
|
let name, opts;
|
|
if (typeof plugin === "string") {
|
|
name = plugin;
|
|
} else {
|
|
[name, opts] = plugin;
|
|
}
|
|
if (!pluginsMap.has(name)) {
|
|
pluginsMap.set(name, opts || {});
|
|
}
|
|
}
|
|
validatePlugins(pluginsMap);
|
|
cls = getParserClass(pluginsMap);
|
|
}
|
|
return new cls(options, input, pluginsMap);
|
|
}
|
|
const parserClassCache = new Map();
|
|
function getParserClass(pluginsMap) {
|
|
const pluginList = [];
|
|
for (const name of mixinPluginNames) {
|
|
if (pluginsMap.has(name)) {
|
|
pluginList.push(name);
|
|
}
|
|
}
|
|
const key = pluginList.join("|");
|
|
let cls = parserClassCache.get(key);
|
|
if (!cls) {
|
|
cls = Parser;
|
|
for (const plugin of pluginList) {
|
|
cls = mixinPlugins[plugin](cls);
|
|
}
|
|
parserClassCache.set(key, cls);
|
|
}
|
|
return cls;
|
|
}
|
|
lib.parse = parse;
|
|
lib.parseExpression = parseExpression;
|
|
lib.tokTypes = tokTypes;
|
|
|
|
return lib;
|
|
}
|
|
|
|
var hasRequiredBabel;
|
|
|
|
function requireBabel () {
|
|
if (hasRequiredBabel) return babel;
|
|
hasRequiredBabel = 1;
|
|
(function (exports$1) {
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
exports$1.parse = exports$1.parser = void 0;
|
|
var tslib_1 = require$$0;
|
|
var _babel_options_1 = tslib_1.__importDefault(require_babel_options());
|
|
// Prefer the new @babel/parser package, but fall back to babylon if
|
|
// that's what's available.
|
|
exports$1.parser = (function () {
|
|
try {
|
|
return requireLib();
|
|
}
|
|
catch (_a) {
|
|
try {
|
|
return require("babylon");
|
|
}
|
|
catch (_b) {
|
|
throw new Error("Install @babel/parser to use the `typescript`, `flow`, or `babel` parsers");
|
|
}
|
|
}
|
|
})();
|
|
// This module is suitable for passing as options.parser when calling
|
|
// recast.parse to process JavaScript code with Babel:
|
|
//
|
|
// const ast = recast.parse(source, {
|
|
// parser: require("recast/parsers/babel")
|
|
// });
|
|
//
|
|
function parse(source, options) {
|
|
var babelOptions = (0, _babel_options_1.default)(options);
|
|
babelOptions.plugins.push("jsx", "flow", "decoratorAutoAccessors");
|
|
return exports$1.parser.parse(source, babelOptions);
|
|
}
|
|
exports$1.parse = parse;
|
|
} (babel));
|
|
return babel;
|
|
}
|
|
|
|
var hasRequiredBabelTs;
|
|
|
|
function requireBabelTs () {
|
|
if (hasRequiredBabelTs) return babelTs$1;
|
|
hasRequiredBabelTs = 1;
|
|
(function (exports$1) {
|
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
exports$1.parse = exports$1.parser = void 0;
|
|
var tslib_1 = require$$0;
|
|
var babel_1 = requireBabel();
|
|
Object.defineProperty(exports$1, "parser", { enumerable: true, get: function () { return babel_1.parser; } });
|
|
var _babel_options_1 = tslib_1.__importDefault(require_babel_options());
|
|
function parse(source, options) {
|
|
var babelOptions = (0, _babel_options_1.default)(options);
|
|
babelOptions.plugins.push("jsx", "typescript");
|
|
return babel_1.parser.parse(source, babelOptions);
|
|
}
|
|
exports$1.parse = parse;
|
|
} (babelTs$1));
|
|
return babelTs$1;
|
|
}
|
|
|
|
var babelTsExports = requireBabelTs();
|
|
var babelTs = /*@__PURE__*/getDefaultExportFromCjs(babelTsExports);
|
|
|
|
var parser = /*#__PURE__*/_mergeNamespaces({
|
|
__proto__: null,
|
|
default: babelTs
|
|
}, [babelTsExports]);
|
|
|
|
function getCwd() {
|
|
// Support overriding the CWD for testing
|
|
if (process.env.SPARK_DIR) {
|
|
return process.env.SPARK_DIR;
|
|
}
|
|
else {
|
|
return '/workspaces/spark-template';
|
|
}
|
|
}
|
|
const collectImports = (importName, ast) => {
|
|
const imports = [];
|
|
mainExports.visit(ast, {
|
|
visitImportDeclaration: function (path) {
|
|
const node = path.value;
|
|
if (node.source.value === importName) {
|
|
for (const specifier of node.specifiers) {
|
|
if (specifier.type === 'ImportSpecifier') {
|
|
imports.push(specifier.imported.name);
|
|
}
|
|
}
|
|
}
|
|
return this.traverse(path);
|
|
},
|
|
});
|
|
return imports;
|
|
};
|
|
function tagFile(source, filePath) {
|
|
const tsAst = mainExports.parse(source, {
|
|
parser,
|
|
});
|
|
const repoDir = getCwd();
|
|
const publicFilePath = filePath.replace(repoDir + '/', '');
|
|
const iconImports = collectImports('@phosphor-icons/react', tsAst);
|
|
mainExports.visit(tsAst, {
|
|
visitJSXElement: function (path) {
|
|
/**
|
|
* set component-specific attributes for JSX elements inside components folder
|
|
*/
|
|
if (filePath.includes('components')) {
|
|
path.value.openingElement.attributes.push(
|
|
// {
|
|
// type: 'JSXAttribute',
|
|
// name: {
|
|
// type: 'JSXIdentifier',
|
|
// name: 'data-component',
|
|
// },
|
|
// value: {
|
|
// type: 'StringLiteral',
|
|
// value: publicFilePath.split('/').slice(-1)[0].replace('.tsx', ''),
|
|
// },
|
|
// },
|
|
{
|
|
type: 'JSXAttribute',
|
|
name: {
|
|
type: 'JSXIdentifier',
|
|
name: 'data-component-loc',
|
|
},
|
|
value: {
|
|
type: 'StringLiteral',
|
|
value: `${publicFilePath}:${path.value.loc.start.line}:${path.value.loc.start.column}`,
|
|
},
|
|
}, {
|
|
type: 'JSXAttribute',
|
|
name: {
|
|
type: 'JSXIdentifier',
|
|
name: 'data-component-loc-end',
|
|
},
|
|
value: {
|
|
type: 'StringLiteral',
|
|
value: `${publicFilePath}:${path.value.loc.end.line}:${path.value.loc.end.column}`,
|
|
},
|
|
});
|
|
}
|
|
else {
|
|
/**
|
|
* set data-loc attribute for all JSX elements
|
|
*/
|
|
path.value.openingElement.attributes.push({
|
|
type: 'JSXAttribute',
|
|
name: {
|
|
type: 'JSXIdentifier',
|
|
name: 'data-loc',
|
|
},
|
|
value: {
|
|
type: 'StringLiteral',
|
|
value: `${publicFilePath}:${path.value.loc.start.line}:${path.value.loc.start.column}`,
|
|
},
|
|
}, {
|
|
type: 'JSXAttribute',
|
|
name: {
|
|
type: 'JSXIdentifier',
|
|
name: 'data-loc-end',
|
|
},
|
|
value: {
|
|
type: 'StringLiteral',
|
|
value: `${publicFilePath}:${path.value.loc.end.line}:${path.value.loc.end.column}`,
|
|
},
|
|
});
|
|
}
|
|
/**
|
|
* set data-dynamic attribute for JSX elements with children
|
|
* e.g <div>{[1, 2, 3].map((item) => <div>{item}</div>)}</div>
|
|
*/
|
|
if (path.value.children.find((child) => child.type === 'JSXExpressionContainer')) {
|
|
path.value.openingElement.attributes.push({
|
|
type: 'JSXAttribute',
|
|
name: {
|
|
type: 'JSXIdentifier',
|
|
name: 'data-dynamic',
|
|
},
|
|
value: {
|
|
type: 'StringLiteral',
|
|
value: 'true',
|
|
},
|
|
});
|
|
}
|
|
if (iconImports.includes(path.value.openingElement.name.name)) {
|
|
path.value.openingElement.attributes.push({
|
|
type: 'JSXAttribute',
|
|
name: { type: 'JSXIdentifier', name: 'data-icon' },
|
|
value: {
|
|
type: 'StringLiteral',
|
|
value: path.value.openingElement.name.name,
|
|
},
|
|
});
|
|
}
|
|
this.traverse(path);
|
|
},
|
|
});
|
|
const result = mainExports.print(tsAst);
|
|
return { code: result.code, map: result.map };
|
|
}
|
|
const tagSourcePlugin = () => ({
|
|
name: 'tag-source',
|
|
apply: 'serve',
|
|
enforce: 'pre',
|
|
transform(code, id) {
|
|
if (!['.tsx', '.jsx'].some((ext) => id.endsWith(ext)))
|
|
return;
|
|
const result = tagFile(code, id);
|
|
return { code: result.code, map: result.map };
|
|
},
|
|
});
|
|
const designerHost = () => ({
|
|
name: 'designer-host',
|
|
apply: 'serve',
|
|
transform(code, id) {
|
|
if (id.endsWith('main.tsx')) {
|
|
return `
|
|
import "@github/spark/designer-styles.css";
|
|
import "@github/spark/designerHost";
|
|
${code}
|
|
`;
|
|
}
|
|
},
|
|
});
|
|
|
|
export { getCwd as default, designerHost, tagFile, tagSourcePlugin };
|
|
//# sourceMappingURL=designerPlugin.js.map
|