Commit ac419aba authored by Cholgrrr's avatar Cholgrrr
Browse files

.gitignore, settings.json und 14061 weitere dateien aktualisiert...

parent ed14b8b4
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = createTemplateBuilder;
var _options = require("./options");
var _string = require("./string");
var _literal = require("./literal");
const NO_PLACEHOLDER = (0, _options.validate)({
placeholderPattern: false
});
function createTemplateBuilder(formatter, defaultOpts) {
const templateFnCache = new WeakMap();
const templateAstCache = new WeakMap();
const cachedOpts = defaultOpts || (0, _options.validate)(null);
return Object.assign((tpl, ...args) => {
if (typeof tpl === "string") {
if (args.length > 1) throw new Error("Unexpected extra params.");
return extendedTrace((0, _string.default)(formatter, tpl, (0, _options.merge)(cachedOpts, (0, _options.validate)(args[0]))));
} else if (Array.isArray(tpl)) {
let builder = templateFnCache.get(tpl);
if (!builder) {
builder = (0, _literal.default)(formatter, tpl, cachedOpts);
templateFnCache.set(tpl, builder);
}
return extendedTrace(builder(args));
} else if (typeof tpl === "object" && tpl) {
if (args.length > 0) throw new Error("Unexpected extra params.");
return createTemplateBuilder(formatter, (0, _options.merge)(cachedOpts, (0, _options.validate)(tpl)));
}
throw new Error(`Unexpected template param ${typeof tpl}`);
}, {
ast: (tpl, ...args) => {
if (typeof tpl === "string") {
if (args.length > 1) throw new Error("Unexpected extra params.");
return (0, _string.default)(formatter, tpl, (0, _options.merge)((0, _options.merge)(cachedOpts, (0, _options.validate)(args[0])), NO_PLACEHOLDER))();
} else if (Array.isArray(tpl)) {
let builder = templateAstCache.get(tpl);
if (!builder) {
builder = (0, _literal.default)(formatter, tpl, (0, _options.merge)(cachedOpts, NO_PLACEHOLDER));
templateAstCache.set(tpl, builder);
}
return builder(args)();
}
throw new Error(`Unexpected template param ${typeof tpl}`);
}
});
}
function extendedTrace(fn) {
let rootStack = "";
try {
throw new Error();
} catch (error) {
if (error.stack) {
rootStack = error.stack.split("\n").slice(3).join("\n");
}
}
return arg => {
try {
return fn(arg);
} catch (err) {
err.stack += `\n =============\n${rootStack}`;
throw err;
}
};
}
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.program = exports.expression = exports.statement = exports.statements = exports.smart = void 0;
var t = require("@babel/types");
function makeStatementFormatter(fn) {
return {
code: str => `/* @babel/template */;\n${str}`,
validate: () => {},
unwrap: ast => {
return fn(ast.program.body.slice(1));
}
};
}
const smart = makeStatementFormatter(body => {
if (body.length > 1) {
return body;
} else {
return body[0];
}
});
exports.smart = smart;
const statements = makeStatementFormatter(body => body);
exports.statements = statements;
const statement = makeStatementFormatter(body => {
if (body.length === 0) {
throw new Error("Found nothing to return.");
}
if (body.length > 1) {
throw new Error("Found multiple statements but wanted one");
}
return body[0];
});
exports.statement = statement;
const expression = {
code: str => `(\n${str}\n)`,
validate: ast => {
if (ast.program.body.length > 1) {
throw new Error("Found multiple statements but wanted one");
}
if (expression.unwrap(ast).start === 0) {
throw new Error("Parse result included parens.");
}
},
unwrap: ({
program
}) => {
const [stmt] = program.body;
t.assertExpressionStatement(stmt);
return stmt.expression;
}
};
exports.expression = expression;
const program = {
code: str => str,
validate: () => {},
unwrap: ast => ast.program
};
exports.program = program;
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.program = exports.expression = exports.statements = exports.statement = exports.smart = void 0;
var formatters = require("./formatters");
var _builder = require("./builder");
const smart = (0, _builder.default)(formatters.smart);
exports.smart = smart;
const statement = (0, _builder.default)(formatters.statement);
exports.statement = statement;
const statements = (0, _builder.default)(formatters.statements);
exports.statements = statements;
const expression = (0, _builder.default)(formatters.expression);
exports.expression = expression;
const program = (0, _builder.default)(formatters.program);
exports.program = program;
var _default = Object.assign(smart.bind(undefined), {
smart,
statement,
statements,
expression,
program,
ast: smart.ast
});
exports.default = _default;
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = literalTemplate;
var _options = require("./options");
var _parse = require("./parse");
var _populate = require("./populate");
function literalTemplate(formatter, tpl, opts) {
const {
metadata,
names
} = buildLiteralData(formatter, tpl, opts);
return arg => {
const defaultReplacements = {};
arg.forEach((replacement, i) => {
defaultReplacements[names[i]] = replacement;
});
return arg => {
const replacements = (0, _options.normalizeReplacements)(arg);
if (replacements) {
Object.keys(replacements).forEach(key => {
if (Object.prototype.hasOwnProperty.call(defaultReplacements, key)) {
throw new Error("Unexpected replacement overlap.");
}
});
}
return formatter.unwrap((0, _populate.default)(metadata, replacements ? Object.assign(replacements, defaultReplacements) : defaultReplacements));
};
};
}
function buildLiteralData(formatter, tpl, opts) {
let names;
let nameSet;
let metadata;
let prefix = "";
do {
prefix += "$";
const result = buildTemplateCode(tpl, prefix);
names = result.names;
nameSet = new Set(names);
metadata = (0, _parse.default)(formatter, formatter.code(result.code), {
parser: opts.parser,
placeholderWhitelist: new Set(result.names.concat(opts.placeholderWhitelist ? Array.from(opts.placeholderWhitelist) : [])),
placeholderPattern: opts.placeholderPattern,
preserveComments: opts.preserveComments,
syntacticPlaceholders: opts.syntacticPlaceholders
});
} while (metadata.placeholders.some(placeholder => placeholder.isDuplicate && nameSet.has(placeholder.name)));
return {
metadata,
names
};
}
function buildTemplateCode(tpl, prefix) {
const names = [];
let code = tpl[0];
for (let i = 1; i < tpl.length; i++) {
const value = `${prefix}${i - 1}`;
names.push(value);
code += value + tpl[i];
}
return {
names,
code
};
}
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.merge = merge;
exports.validate = validate;
exports.normalizeReplacements = normalizeReplacements;
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
function merge(a, b) {
const {
placeholderWhitelist = a.placeholderWhitelist,
placeholderPattern = a.placeholderPattern,
preserveComments = a.preserveComments,
syntacticPlaceholders = a.syntacticPlaceholders
} = b;
return {
parser: Object.assign({}, a.parser, b.parser),
placeholderWhitelist,
placeholderPattern,
preserveComments,
syntacticPlaceholders
};
}
function validate(opts) {
if (opts != null && typeof opts !== "object") {
throw new Error("Unknown template options.");
}
const _ref = opts || {},
{
placeholderWhitelist,
placeholderPattern,
preserveComments,
syntacticPlaceholders
} = _ref,
parser = _objectWithoutPropertiesLoose(_ref, ["placeholderWhitelist", "placeholderPattern", "preserveComments", "syntacticPlaceholders"]);
if (placeholderWhitelist != null && !(placeholderWhitelist instanceof Set)) {
throw new Error("'.placeholderWhitelist' must be a Set, null, or undefined");
}
if (placeholderPattern != null && !(placeholderPattern instanceof RegExp) && placeholderPattern !== false) {
throw new Error("'.placeholderPattern' must be a RegExp, false, null, or undefined");
}
if (preserveComments != null && typeof preserveComments !== "boolean") {
throw new Error("'.preserveComments' must be a boolean, null, or undefined");
}
if (syntacticPlaceholders != null && typeof syntacticPlaceholders !== "boolean") {
throw new Error("'.syntacticPlaceholders' must be a boolean, null, or undefined");
}
if (syntacticPlaceholders === true && (placeholderWhitelist != null || placeholderPattern != null)) {
throw new Error("'.placeholderWhitelist' and '.placeholderPattern' aren't compatible" + " with '.syntacticPlaceholders: true'");
}
return {
parser,
placeholderWhitelist: placeholderWhitelist || undefined,
placeholderPattern: placeholderPattern == null ? undefined : placeholderPattern,
preserveComments: preserveComments == null ? undefined : preserveComments,
syntacticPlaceholders: syntacticPlaceholders == null ? undefined : syntacticPlaceholders
};
}
function normalizeReplacements(replacements) {
if (Array.isArray(replacements)) {
return replacements.reduce((acc, replacement, i) => {
acc["$" + i] = replacement;
return acc;
}, {});
} else if (typeof replacements === "object" || replacements == null) {
return replacements || undefined;
}
throw new Error("Template replacements must be an array, object, null, or undefined");
}
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = parseAndBuildMetadata;
var t = require("@babel/types");
var _parser = require("@babel/parser");
var _codeFrame = require("@babel/code-frame");
const PATTERN = /^[_$A-Z0-9]+$/;
function parseAndBuildMetadata(formatter, code, opts) {
const {
placeholderWhitelist,
placeholderPattern,
preserveComments,
syntacticPlaceholders
} = opts;
const ast = parseWithCodeFrame(code, opts.parser, syntacticPlaceholders);
t.removePropertiesDeep(ast, {
preserveComments
});
formatter.validate(ast);
const syntactic = {
placeholders: [],
placeholderNames: new Set()
};
const legacy = {
placeholders: [],
placeholderNames: new Set()
};
const isLegacyRef = {
value: undefined
};
t.traverse(ast, placeholderVisitorHandler, {
syntactic,
legacy,
isLegacyRef,
placeholderWhitelist,
placeholderPattern,
syntacticPlaceholders
});
return Object.assign({
ast
}, isLegacyRef.value ? legacy : syntactic);
}
function placeholderVisitorHandler(node, ancestors, state) {
var _state$placeholderWhi;
let name;
if (t.isPlaceholder(node)) {
if (state.syntacticPlaceholders === false) {
throw new Error("%%foo%%-style placeholders can't be used when " + "'.syntacticPlaceholders' is false.");
} else {
name = node.name.name;
state.isLegacyRef.value = false;
}
} else if (state.isLegacyRef.value === false || state.syntacticPlaceholders) {
return;
} else if (t.isIdentifier(node) || t.isJSXIdentifier(node)) {
name = node.name;
state.isLegacyRef.value = true;
} else if (t.isStringLiteral(node)) {
name = node.value;
state.isLegacyRef.value = true;
} else {
return;
}
if (!state.isLegacyRef.value && (state.placeholderPattern != null || state.placeholderWhitelist != null)) {
throw new Error("'.placeholderWhitelist' and '.placeholderPattern' aren't compatible" + " with '.syntacticPlaceholders: true'");
}
if (state.isLegacyRef.value && (state.placeholderPattern === false || !(state.placeholderPattern || PATTERN).test(name)) && !((_state$placeholderWhi = state.placeholderWhitelist) != null && _state$placeholderWhi.has(name))) {
return;
}
ancestors = ancestors.slice();
const {
node: parent,
key
} = ancestors[ancestors.length - 1];
let type;
if (t.isStringLiteral(node) || t.isPlaceholder(node, {
expectedNode: "StringLiteral"
})) {
type = "string";
} else if (t.isNewExpression(parent) && key === "arguments" || t.isCallExpression(parent) && key === "arguments" || t.isFunction(parent) && key === "params") {
type = "param";
} else if (t.isExpressionStatement(parent) && !t.isPlaceholder(node)) {
type = "statement";
ancestors = ancestors.slice(0, -1);
} else if (t.isStatement(node) && t.isPlaceholder(node)) {
type = "statement";
} else {
type = "other";
}
const {
placeholders,
placeholderNames
} = state.isLegacyRef.value ? state.legacy : state.syntactic;
placeholders.push({
name,
type,
resolve: ast => resolveAncestors(ast, ancestors),
isDuplicate: placeholderNames.has(name)
});
placeholderNames.add(name);
}
function resolveAncestors(ast, ancestors) {
let parent = ast;
for (let i = 0; i < ancestors.length - 1; i++) {
const {
key,
index
} = ancestors[i];
if (index === undefined) {
parent = parent[key];
} else {
parent = parent[key][index];
}
}
const {
key,
index
} = ancestors[ancestors.length - 1];
return {
parent,
key,
index
};
}
function parseWithCodeFrame(code, parserOpts, syntacticPlaceholders) {
const plugins = (parserOpts.plugins || []).slice();
if (syntacticPlaceholders !== false) {
plugins.push("placeholders");
}
parserOpts = Object.assign({
allowReturnOutsideFunction: true,
allowSuperOutsideMethod: true,
sourceType: "module"
}, parserOpts, {
plugins
});
try {
return (0, _parser.parse)(code, parserOpts);
} catch (err) {
const loc = err.loc;
if (loc) {
err.message += "\n" + (0, _codeFrame.codeFrameColumns)(code, {
start: loc
});
err.code = "BABEL_TEMPLATE_PARSE_ERROR";
}
throw err;
}
}
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = populatePlaceholders;
var t = require("@babel/types");
function populatePlaceholders(metadata, replacements) {
const ast = t.cloneNode(metadata.ast);
if (replacements) {
metadata.placeholders.forEach(placeholder => {
if (!Object.prototype.hasOwnProperty.call(replacements, placeholder.name)) {
const placeholderName = placeholder.name;
throw new Error(`Error: No substitution given for "${placeholderName}". If this is not meant to be a
placeholder you may want to consider passing one of the following options to @babel/template:
- { placeholderPattern: false, placeholderWhitelist: new Set(['${placeholderName}'])}
- { placeholderPattern: /^${placeholderName}$/ }`);
}
});
Object.keys(replacements).forEach(key => {
if (!metadata.placeholderNames.has(key)) {
throw new Error(`Unknown substitution "${key}" given`);
}
});
}
metadata.placeholders.slice().reverse().forEach(placeholder => {
try {
applyReplacement(placeholder, ast, replacements && replacements[placeholder.name] || null);
} catch (e) {
e.message = `@babel/template placeholder "${placeholder.name}": ${e.message}`;
throw e;
}
});
return ast;
}
function applyReplacement(placeholder, ast, replacement) {
if (placeholder.isDuplicate) {
if (Array.isArray(replacement)) {
replacement = replacement.map(node => t.cloneNode(node));
} else if (typeof replacement === "object") {
replacement = t.cloneNode(replacement);
}
}
const {
parent,
key,
index
} = placeholder.resolve(ast);
if (placeholder.type === "string") {
if (typeof replacement === "string") {
replacement = t.stringLiteral(replacement);
}
if (!replacement || !t.isStringLiteral(replacement)) {
throw new Error("Expected string substitution");
}
} else if (placeholder.type === "statement") {
if (index === undefined) {
if (!replacement) {
replacement = t.emptyStatement();
} else if (Array.isArray(replacement)) {
replacement = t.blockStatement(replacement);
} else if (typeof replacement === "string") {
replacement = t.expressionStatement(t.identifier(replacement));
} else if (!t.isStatement(replacement)) {
replacement = t.expressionStatement(replacement);
}
} else {
if (replacement && !Array.isArray(replacement)) {
if (typeof replacement === "string") {
replacement = t.identifier(replacement);
}
if (!t.isStatement(replacement)) {
replacement = t.expressionStatement(replacement);
}
}
}
} else if (placeholder.type === "param") {
if (typeof replacement === "string") {
replacement = t.identifier(replacement);
}
if (index === undefined) throw new Error("Assertion failure.");
} else {
if (typeof replacement === "string") {
replacement = t.identifier(replacement);
}
if (Array.isArray(replacement)) {
throw new Error("Cannot replace single expression with an array.");
}
}
if (index === undefined) {
t.validate(parent, key, replacement);
parent[key] = replacement;
} else {
const items = parent[key].slice();
if (placeholder.type === "statement" || placeholder.type === "param") {
if (replacement == null) {
items.splice(index, 1);
} else if (Array.isArray(replacement)) {
items.splice(index, 1, ...replacement);
} else {
items[index] = replacement;
}
} else {
items[index] = replacement;
}
t.validate(parent, key, items);
parent[key] = items;
}
}
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = stringTemplate;
var _options = require("./options");
var _parse = require("./parse");
var _populate = require("./populate");
function stringTemplate(formatter, code, opts) {
code = formatter.code(code);
let metadata;
return arg => {
const replacements = (0, _options.normalizeReplacements)(arg);
if (!metadata) metadata = (0, _parse.default)(formatter, code, opts);
return formatter.unwrap((0, _populate.default)(metadata, replacements));
};
}
\ No newline at end of file
{
"name": "@babel/template",
"version": "7.14.5",
"description": "Generate an AST from a string template.",
"author": "The Babel Team (https://babel.dev/team)",
"homepage": "https://babel.dev/docs/en/next/babel-template",
"bugs": "https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A%20template%22+is%3Aopen",
"license": "MIT",
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "https://github.com/babel/babel.git",
"directory": "packages/babel-template"
},
"main": "./lib/index.js",
"dependencies": {
"@babel/code-frame": "^7.14.5",
"@babel/parser": "^7.14.5",
"@babel/types": "^7.14.5"
},
"engines": {
"node": ">=6.9.0"
}
}
\ No newline at end of file
MIT License
Copyright (c) 2014-present Sebastian McKenzie and other contributors
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# @babel/traverse
> The Babel Traverse module maintains the overall tree state, and is responsible for replacing, removing, and adding nodes
See our website [@babel/traverse](https://babeljs.io/docs/en/babel-traverse) for more information or the [issues](https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A%20traverse%22+is%3Aopen) associated with this package.
## Install
Using npm:
```sh
npm install --save-dev @babel/traverse
```
or using yarn:
```sh
yarn add @babel/traverse --dev
```
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.clear = clear;
exports.clearPath = clearPath;
exports.clearScope = clearScope;
exports.scope = exports.path = void 0;
let path = new WeakMap();
exports.path = path;
let scope = new WeakMap();
exports.scope = scope;
function clear() {
clearPath();
clearScope();
}
function clearPath() {
exports.path = path = new WeakMap();
}
function clearScope() {
exports.scope = scope = new WeakMap();
}
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _path = require("./path");
var t = require("@babel/types");
const testing = process.env.NODE_ENV === "test";
class TraversalContext {
constructor(scope, opts, state, parentPath) {
this.queue = null;
this.priorityQueue = null;
this.parentPath = parentPath;
this.scope = scope;
this.state = state;
this.opts = opts;
}
shouldVisit(node) {
const opts = this.opts;
if (opts.enter || opts.exit) return true;
if (opts[node.type]) return true;
const keys = t.VISITOR_KEYS[node.type];
if (!(keys != null && keys.length)) return false;
for (const key of keys) {
if (node[key]) return true;
}
return false;
}
create(node, obj, key, listKey) {
return _path.default.get({
parentPath: this.parentPath,
parent: node,
container: obj,
key: key,
listKey
});
}
maybeQueue(path, notPriority) {
if (this.trap) {
throw new Error("Infinite cycle detected");
}
if (this.queue) {
if (notPriority) {
this.queue.push(path);
} else {
this.priorityQueue.push(path);
}
}
}
visitMultiple(container, parent, listKey) {
if (container.length === 0) return false;
const queue = [];
for (let key = 0; key < container.length; key++) {
const node = container[key];
if (node && this.shouldVisit(node)) {
queue.push(this.create(parent, container, key, listKey));
}
}
return this.visitQueue(queue);
}
visitSingle(node, key) {
if (this.shouldVisit(node[key])) {
return this.visitQueue([this.create(node, node, key)]);
} else {
return false;
}
}
visitQueue(queue) {
this.queue = queue;
this.priorityQueue = [];
const visited = new WeakSet();
let stop = false;
for (const path of queue) {
path.resync();
if (path.contexts.length === 0 || path.contexts[path.contexts.length - 1] !== this) {
path.pushContext(this);
}
if (path.key === null) continue;
if (testing && queue.length >= 10000) {
this.trap = true;
}
const {
node
} = path;
if (visited.has(node)) continue;
if (node) visited.add(node);
if (path.visit()) {
stop = true;
break;
}
if (this.priorityQueue.length) {
stop = this.visitQueue(this.priorityQueue);
this.priorityQueue = [];
this.queue = queue;
if (stop) break;
}
}
for (const path of queue) {
path.popContext();
}
this.queue = null;
return stop;
}
visit(node, key) {
const nodes = node[key];
if (!nodes) return false;
if (Array.isArray(nodes)) {
return this.visitMultiple(nodes, node, key);
} else {
return this.visitSingle(node, key);
}
}
}
exports.default = TraversalContext;
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
class Hub {
getCode() {}
getScope() {}
addHelper() {
throw new Error("Helpers are not supported by the default hub.");
}
buildError(node, msg, Error = TypeError) {
return new Error(msg);
}
}
exports.default = Hub;
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "NodePath", {
enumerable: true,
get: function () {
return _path.default;
}
});
Object.defineProperty(exports, "Scope", {
enumerable: true,
get: function () {
return _scope.default;
}
});
Object.defineProperty(exports, "Hub", {
enumerable: true,
get: function () {
return _hub.default;
}
});
exports.visitors = exports.default = void 0;
var _context = require("./context");
var visitors = require("./visitors");
exports.visitors = visitors;
var t = require("@babel/types");
var cache = require("./cache");
var _path = require("./path");
var _scope = require("./scope");
var _hub = require("./hub");
function traverse(parent, opts = {}, scope, state, parentPath) {
if (!parent) return;
if (!opts.noScope && !scope) {
if (parent.type !== "Program" && parent.type !== "File") {
throw new Error("You must pass a scope and parentPath unless traversing a Program/File. " + `Instead of that you tried to traverse a ${parent.type} node without ` + "passing scope and parentPath.");
}
}
if (!t.VISITOR_KEYS[parent.type]) {
return;
}
visitors.explode(opts);
traverse.node(parent, opts, scope, state, parentPath);
}
var _default = traverse;
exports.default = _default;
traverse.visitors = visitors;
traverse.verify = visitors.verify;
traverse.explode = visitors.explode;
traverse.cheap = function (node, enter) {
return t.traverseFast(node, enter);
};
traverse.node = function (node, opts, scope, state, parentPath, skipKeys) {
const keys = t.VISITOR_KEYS[node.type];
if (!keys) return;
const context = new _context.default(scope, opts, state, parentPath);
for (const key of keys) {
if (skipKeys && skipKeys[key]) continue;
if (context.visit(node, key)) return;
}
};
traverse.clearNode = function (node, opts) {
t.removeProperties(node, opts);
cache.path.delete(node);
};
traverse.removeProperties = function (tree, opts) {
t.traverseFast(tree, traverse.clearNode, opts);
return tree;
};
function hasDenylistedType(path, state) {
if (path.node.type === state.type) {
state.has = true;
path.stop();
}
}
traverse.hasType = function (tree, type, denylistTypes) {
if (denylistTypes != null && denylistTypes.includes(tree.type)) return false;
if (tree.type === type) return true;
const state = {
has: false,
type: type
};
traverse(tree, {
noScope: true,
denylist: denylistTypes,
enter: hasDenylistedType
}, null, state);
return state.has;
};
traverse.cache = cache;
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.findParent = findParent;
exports.find = find;
exports.getFunctionParent = getFunctionParent;
exports.getStatementParent = getStatementParent;
exports.getEarliestCommonAncestorFrom = getEarliestCommonAncestorFrom;
exports.getDeepestCommonAncestorFrom = getDeepestCommonAncestorFrom;
exports.getAncestry = getAncestry;
exports.isAncestor = isAncestor;
exports.isDescendant = isDescendant;
exports.inType = inType;
var t = require("@babel/types");
var _index = require("./index");
function findParent(callback) {
let path = this;
while (path = path.parentPath) {
if (callback(path)) return path;
}
return null;
}
function find(callback) {
let path = this;
do {
if (callback(path)) return path;
} while (path = path.parentPath);
return null;
}
function getFunctionParent() {
return this.findParent(p => p.isFunction());
}
function getStatementParent() {
let path = this;
do {
if (!path.parentPath || Array.isArray(path.container) && path.isStatement()) {
break;
} else {
path = path.parentPath;
}
} while (path);
if (path && (path.isProgram() || path.isFile())) {
throw new Error("File/Program node, we can't possibly find a statement parent to this");
}
return path;
}
function getEarliestCommonAncestorFrom(paths) {
return this.getDeepestCommonAncestorFrom(paths, function (deepest, i, ancestries) {
let earliest;
const keys = t.VISITOR_KEYS[deepest.type];
for (const ancestry of ancestries) {
const path = ancestry[i + 1];
if (!earliest) {
earliest = path;
continue;
}
if (path.listKey && earliest.listKey === path.listKey) {
if (path.key < earliest.key) {
earliest = path;
continue;
}
}
const earliestKeyIndex = keys.indexOf(earliest.parentKey);
const currentKeyIndex = keys.indexOf(path.parentKey);
if (earliestKeyIndex > currentKeyIndex) {
earliest = path;
}
}
return earliest;
});
}
function getDeepestCommonAncestorFrom(paths, filter) {
if (!paths.length) {
return this;
}
if (paths.length === 1) {
return paths[0];
}
let minDepth = Infinity;
let lastCommonIndex, lastCommon;
const ancestries = paths.map(path => {
const ancestry = [];
do {
ancestry.unshift(path);
} while ((path = path.parentPath) && path !== this);
if (ancestry.length < minDepth) {
minDepth = ancestry.length;
}
return ancestry;
});
const first = ancestries[0];
depthLoop: for (let i = 0; i < minDepth; i++) {
const shouldMatch = first[i];
for (const ancestry of ancestries) {
if (ancestry[i] !== shouldMatch) {
break depthLoop;
}
}
lastCommonIndex = i;
lastCommon = shouldMatch;
}
if (lastCommon) {
if (filter) {
return filter(lastCommon, lastCommonIndex, ancestries);
} else {
return lastCommon;
}
} else {
throw new Error("Couldn't find intersection");
}
}
function getAncestry() {
let path = this;
const paths = [];
do {
paths.push(path);
} while (path = path.parentPath);
return paths;
}
function isAncestor(maybeDescendant) {
return maybeDescendant.isDescendant(this);
}
function isDescendant(maybeAncestor) {
return !!this.findParent(parent => parent === maybeAncestor);
}
function inType(...candidateTypes) {
let path = this;
while (path) {
for (const type of candidateTypes) {
if (path.node.type === type) return true;
}
path = path.parentPath;
}
return false;
}
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.shareCommentsWithSiblings = shareCommentsWithSiblings;
exports.addComment = addComment;
exports.addComments = addComments;
var t = require("@babel/types");
function shareCommentsWithSiblings() {
if (typeof this.key === "string") return;
const node = this.node;
if (!node) return;
const trailing = node.trailingComments;
const leading = node.leadingComments;
if (!trailing && !leading) return;
const prev = this.getSibling(this.key - 1);
const next = this.getSibling(this.key + 1);
const hasPrev = Boolean(prev.node);
const hasNext = Boolean(next.node);
if (hasPrev && !hasNext) {
prev.addComments("trailing", trailing);
} else if (hasNext && !hasPrev) {
next.addComments("leading", leading);
}
}
function addComment(type, content, line) {
t.addComment(this.node, type, content, line);
}
function addComments(type, comments) {
t.addComments(this.node, type, comments);
}
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.call = call;
exports._call = _call;
exports.isBlacklisted = exports.isDenylisted = isDenylisted;
exports.visit = visit;
exports.skip = skip;
exports.skipKey = skipKey;
exports.stop = stop;
exports.setScope = setScope;
exports.setContext = setContext;
exports.resync = resync;
exports._resyncParent = _resyncParent;
exports._resyncKey = _resyncKey;
exports._resyncList = _resyncList;
exports._resyncRemoved = _resyncRemoved;
exports.popContext = popContext;
exports.pushContext = pushContext;
exports.setup = setup;
exports.setKey = setKey;
exports.requeue = requeue;
exports._getQueueContexts = _getQueueContexts;
var _index = require("../index");
var _index2 = require("./index");
function call(key) {
const opts = this.opts;
this.debug(key);
if (this.node) {
if (this._call(opts[key])) return true;
}
if (this.node) {
return this._call(opts[this.node.type] && opts[this.node.type][key]);
}
return false;
}
function _call(fns) {
if (!fns) return false;
for (const fn of fns) {
if (!fn) continue;
const node = this.node;
if (!node) return true;
const ret = fn.call(this.state, this, this.state);
if (ret && typeof ret === "object" && typeof ret.then === "function") {
throw new Error(`You appear to be using a plugin with an async traversal visitor, ` + `which your current version of Babel does not support. ` + `If you're using a published plugin, you may need to upgrade ` + `your @babel/core version.`);
}
if (ret) {
throw new Error(`Unexpected return value from visitor method ${fn}`);
}
if (this.node !== node) return true;
if (this._traverseFlags > 0) return true;
}
return false;
}
function isDenylisted() {
var _this$opts$denylist;
const denylist = (_this$opts$denylist = this.opts.denylist) != null ? _this$opts$denylist : this.opts.blacklist;
return denylist && denylist.indexOf(this.node.type) > -1;
}
function visit() {
if (!this.node) {
return false;
}
if (this.isDenylisted()) {
return false;
}
if (this.opts.shouldSkip && this.opts.shouldSkip(this)) {
return false;
}
if (this.shouldSkip || this.call("enter") || this.shouldSkip) {
this.debug("Skip...");
return this.shouldStop;
}
this.debug("Recursing into...");
_index.default.node(this.node, this.opts, this.scope, this.state, this, this.skipKeys);
this.call("exit");
return this.shouldStop;
}
function skip() {
this.shouldSkip = true;
}
function skipKey(key) {
if (this.skipKeys == null) {
this.skipKeys = {};
}
this.skipKeys[key] = true;
}
function stop() {
this._traverseFlags |= _index2.SHOULD_SKIP | _index2.SHOULD_STOP;
}
function setScope() {
if (this.opts && this.opts.noScope) return;
let path = this.parentPath;
if (this.key === "key" && path.isMethod()) path = path.parentPath;
let target;
while (path && !target) {
if (path.opts && path.opts.noScope) return;
target = path.scope;
path = path.parentPath;
}
this.scope = this.getScope(target);
if (this.scope) this.scope.init();
}
function setContext(context) {
if (this.skipKeys != null) {
this.skipKeys = {};
}
this._traverseFlags = 0;
if (context) {
this.context = context;
this.state = context.state;
this.opts = context.opts;
}
this.setScope();
return this;
}
function resync() {
if (this.removed) return;
this._resyncParent();
this._resyncList();
this._resyncKey();
}
function _resyncParent() {
if (this.parentPath) {
this.parent = this.parentPath.node;
}
}
function _resyncKey() {
if (!this.container) return;
if (this.node === this.container[this.key]) return;
if (Array.isArray(this.container)) {
for (let i = 0; i < this.container.length; i++) {
if (this.container[i] === this.node) {
return this.setKey(i);
}
}
} else {
for (const key of Object.keys(this.container)) {
if (this.container[key] === this.node) {
return this.setKey(key);
}
}
}
this.key = null;
}
function _resyncList() {
if (!this.parent || !this.inList) return;
const newContainer = this.parent[this.listKey];
if (this.container === newContainer) return;
this.container = newContainer || null;
}
function _resyncRemoved() {
if (this.key == null || !this.container || this.container[this.key] !== this.node) {
this._markRemoved();
}
}
function popContext() {
this.contexts.pop();
if (this.contexts.length > 0) {
this.setContext(this.contexts[this.contexts.length - 1]);
} else {
this.setContext(undefined);
}
}
function pushContext(context) {
this.contexts.push(context);
this.setContext(context);
}
function setup(parentPath, container, listKey, key) {
this.listKey = listKey;
this.container = container;
this.parentPath = parentPath || this.parentPath;
this.setKey(key);
}
function setKey(key) {
var _this$node;
this.key = key;
this.node = this.container[this.key];
this.type = (_this$node = this.node) == null ? void 0 : _this$node.type;
}
function requeue(pathToQueue = this) {
if (pathToQueue.removed) return;
;
const contexts = this.contexts;
for (const context of contexts) {
context.maybeQueue(pathToQueue);
}
}
function _getQueueContexts() {
let path = this;
let contexts = this.contexts;
while (!contexts.length) {
path = path.parentPath;
if (!path) break;
contexts = path.contexts;
}
return contexts;
}
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.toComputedKey = toComputedKey;
exports.ensureBlock = ensureBlock;
exports.arrowFunctionToShadowed = arrowFunctionToShadowed;
exports.unwrapFunctionEnvironment = unwrapFunctionEnvironment;
exports.arrowFunctionToExpression = arrowFunctionToExpression;
var t = require("@babel/types");
var _helperFunctionName = require("@babel/helper-function-name");
function toComputedKey() {
let key;
if (this.isMemberExpression()) {
key = this.node.property;
} else if (this.isProperty() || this.isMethod()) {
key = this.node.key;
} else {
throw new ReferenceError("todo");
}
if (!this.node.computed) {
if (t.isIdentifier(key)) key = t.stringLiteral(key.name);
}
return key;
}
function ensureBlock() {
const body = this.get("body");
const bodyNode = body.node;
if (Array.isArray(body)) {
throw new Error("Can't convert array path to a block statement");
}
if (!bodyNode) {
throw new Error("Can't convert node without a body");
}
if (body.isBlockStatement()) {
return bodyNode;
}
const statements = [];
let stringPath = "body";
let key;
let listKey;
if (body.isStatement()) {
listKey = "body";
key = 0;
statements.push(body.node);
} else {
stringPath += ".body.0";
if (this.isFunction()) {
key = "argument";
statements.push(t.returnStatement(body.node));
} else {
key = "expression";
statements.push(t.expressionStatement(body.node));
}
}
this.node.body = t.blockStatement(statements);
const parentPath = this.get(stringPath);
body.setup(parentPath, listKey ? parentPath.node[listKey] : parentPath.node, listKey, key);
return this.node;
}
function arrowFunctionToShadowed() {
if (!this.isArrowFunctionExpression()) return;
this.arrowFunctionToExpression();
}
function unwrapFunctionEnvironment() {
if (!this.isArrowFunctionExpression() && !this.isFunctionExpression() && !this.isFunctionDeclaration()) {
throw this.buildCodeFrameError("Can only unwrap the environment of a function.");
}
hoistFunctionEnvironment(this);
}
function arrowFunctionToExpression({
allowInsertArrow = true,
specCompliant = false,
noNewArrows = !specCompliant
} = {}) {
if (!this.isArrowFunctionExpression()) {
throw this.buildCodeFrameError("Cannot convert non-arrow function to a function expression.");
}
const thisBinding = hoistFunctionEnvironment(this, noNewArrows, allowInsertArrow);
this.ensureBlock();
this.node.type = "FunctionExpression";
if (!noNewArrows) {
const checkBinding = thisBinding ? null : this.parentPath.scope.generateUidIdentifier("arrowCheckId");
if (checkBinding) {
this.parentPath.scope.push({
id: checkBinding,
init: t.objectExpression([])
});
}
this.get("body").unshiftContainer("body", t.expressionStatement(t.callExpression(this.hub.addHelper("newArrowCheck"), [t.thisExpression(), checkBinding ? t.identifier(checkBinding.name) : t.identifier(thisBinding)])));
this.replaceWith(t.callExpression(t.memberExpression((0, _helperFunctionName.default)(this, true) || this.node, t.identifier("bind")), [checkBinding ? t.identifier(checkBinding.name) : t.thisExpression()]));
}
}
function hoistFunctionEnvironment(fnPath, noNewArrows = true, allowInsertArrow = true) {
const thisEnvFn = fnPath.findParent(p => {
return p.isFunction() && !p.isArrowFunctionExpression() || p.isProgram() || p.isClassProperty({
static: false
});
});
const inConstructor = (thisEnvFn == null ? void 0 : thisEnvFn.node.kind) === "constructor";
if (thisEnvFn.isClassProperty()) {
throw fnPath.buildCodeFrameError("Unable to transform arrow inside class property");
}
const {
thisPaths,
argumentsPaths,
newTargetPaths,
superProps,
superCalls
} = getScopeInformation(fnPath);
if (inConstructor && superCalls.length > 0) {
if (!allowInsertArrow) {
throw superCalls[0].buildCodeFrameError("Unable to handle nested super() usage in arrow");
}
const allSuperCalls = [];
thisEnvFn.traverse({
Function(child) {
if (child.isArrowFunctionExpression()) return;
child.skip();
},
ClassProperty(child) {
child.skip();
},
CallExpression(child) {
if (!child.get("callee").isSuper()) return;
allSuperCalls.push(child);
}
});
const superBinding = getSuperBinding(thisEnvFn);
allSuperCalls.forEach(superCall => {
const callee = t.identifier(superBinding);
callee.loc = superCall.node.callee.loc;
superCall.get("callee").replaceWith(callee);
});
}
if (argumentsPaths.length > 0) {
const argumentsBinding = getBinding(thisEnvFn, "arguments", () => t.identifier("arguments"));
argumentsPaths.forEach(argumentsChild => {
const argsRef = t.identifier(argumentsBinding);
argsRef.loc = argumentsChild.node.loc;
argumentsChild.replaceWith(argsRef);
});
}
if (newTargetPaths.length > 0) {
const newTargetBinding = getBinding(thisEnvFn, "newtarget", () => t.metaProperty(t.identifier("new"), t.identifier("target")));
newTargetPaths.forEach(targetChild => {
const targetRef = t.identifier(newTargetBinding);
targetRef.loc = targetChild.node.loc;
targetChild.replaceWith(targetRef);
});
}
if (superProps.length > 0) {
if (!allowInsertArrow) {
throw superProps[0].buildCodeFrameError("Unable to handle nested super.prop usage");
}
const flatSuperProps = superProps.reduce((acc, superProp) => acc.concat(standardizeSuperProperty(superProp)), []);
flatSuperProps.forEach(superProp => {
const key = superProp.node.computed ? "" : superProp.get("property").node.name;
const isAssignment = superProp.parentPath.isAssignmentExpression({
left: superProp.node
});
const isCall = superProp.parentPath.isCallExpression({
callee: superProp.node
});
const superBinding = getSuperPropBinding(thisEnvFn, isAssignment, key);
const args = [];
if (superProp.node.computed) {
args.push(superProp.get("property").node);
}
if (isAssignment) {
const value = superProp.parentPath.node.right;
args.push(value);
}
const call = t.callExpression(t.identifier(superBinding), args);
if (isCall) {
superProp.parentPath.unshiftContainer("arguments", t.thisExpression());
superProp.replaceWith(t.memberExpression(call, t.identifier("call")));
thisPaths.push(superProp.parentPath.get("arguments.0"));
} else if (isAssignment) {
superProp.parentPath.replaceWith(call);
} else {
superProp.replaceWith(call);
}
});
}
let thisBinding;
if (thisPaths.length > 0 || !noNewArrows) {
thisBinding = getThisBinding(thisEnvFn, inConstructor);
if (noNewArrows || inConstructor && hasSuperClass(thisEnvFn)) {
thisPaths.forEach(thisChild => {
const thisRef = thisChild.isJSX() ? t.jsxIdentifier(thisBinding) : t.identifier(thisBinding);
thisRef.loc = thisChild.node.loc;
thisChild.replaceWith(thisRef);
});
if (!noNewArrows) thisBinding = null;
}
}
return thisBinding;
}
function standardizeSuperProperty(superProp) {
if (superProp.parentPath.isAssignmentExpression() && superProp.parentPath.node.operator !== "=") {
const assignmentPath = superProp.parentPath;
const op = assignmentPath.node.operator.slice(0, -1);
const value = assignmentPath.node.right;
assignmentPath.node.operator = "=";
if (superProp.node.computed) {
const tmp = superProp.scope.generateDeclaredUidIdentifier("tmp");
assignmentPath.get("left").replaceWith(t.memberExpression(superProp.node.object, t.assignmentExpression("=", tmp, superProp.node.property), true));
assignmentPath.get("right").replaceWith(t.binaryExpression(op, t.memberExpression(superProp.node.object, t.identifier(tmp.name), true), value));
} else {
assignmentPath.get("left").replaceWith(t.memberExpression(superProp.node.object, superProp.node.property));
assignmentPath.get("right").replaceWith(t.binaryExpression(op, t.memberExpression(superProp.node.object, t.identifier(superProp.node.property.name)), value));
}
return [assignmentPath.get("left"), assignmentPath.get("right").get("left")];
} else if (superProp.parentPath.isUpdateExpression()) {
const updateExpr = superProp.parentPath;
const tmp = superProp.scope.generateDeclaredUidIdentifier("tmp");
const computedKey = superProp.node.computed ? superProp.scope.generateDeclaredUidIdentifier("prop") : null;
const parts = [t.assignmentExpression("=", tmp, t.memberExpression(superProp.node.object, computedKey ? t.assignmentExpression("=", computedKey, superProp.node.property) : superProp.node.property, superProp.node.computed)), t.assignmentExpression("=", t.memberExpression(superProp.node.object, computedKey ? t.identifier(computedKey.name) : superProp.node.property, superProp.node.computed), t.binaryExpression("+", t.identifier(tmp.name), t.numericLiteral(1)))];
if (!superProp.parentPath.node.prefix) {
parts.push(t.identifier(tmp.name));
}
updateExpr.replaceWith(t.sequenceExpression(parts));
const left = updateExpr.get("expressions.0.right");
const right = updateExpr.get("expressions.1.left");
return [left, right];
}
return [superProp];
}
function hasSuperClass(thisEnvFn) {
return thisEnvFn.isClassMethod() && !!thisEnvFn.parentPath.parentPath.node.superClass;
}
function getThisBinding(thisEnvFn, inConstructor) {
return getBinding(thisEnvFn, "this", thisBinding => {
if (!inConstructor || !hasSuperClass(thisEnvFn)) return t.thisExpression();
const supers = new WeakSet();
thisEnvFn.traverse({
Function(child) {
if (child.isArrowFunctionExpression()) return;
child.skip();
},
ClassProperty(child) {
child.skip();
},
CallExpression(child) {
if (!child.get("callee").isSuper()) return;
if (supers.has(child.node)) return;
supers.add(child.node);
child.replaceWithMultiple([child.node, t.assignmentExpression("=", t.identifier(thisBinding), t.identifier("this"))]);
}
});
});
}
function getSuperBinding(thisEnvFn) {
return getBinding(thisEnvFn, "supercall", () => {
const argsBinding = thisEnvFn.scope.generateUidIdentifier("args");
return t.arrowFunctionExpression([t.restElement(argsBinding)], t.callExpression(t.super(), [t.spreadElement(t.identifier(argsBinding.name))]));
});
}
function getSuperPropBinding(thisEnvFn, isAssignment, propName) {
const op = isAssignment ? "set" : "get";
return getBinding(thisEnvFn, `superprop_${op}:${propName || ""}`, () => {
const argsList = [];
let fnBody;
if (propName) {
fnBody = t.memberExpression(t.super(), t.identifier(propName));
} else {
const method = thisEnvFn.scope.generateUidIdentifier("prop");
argsList.unshift(method);
fnBody = t.memberExpression(t.super(), t.identifier(method.name), true);
}
if (isAssignment) {
const valueIdent = thisEnvFn.scope.generateUidIdentifier("value");
argsList.push(valueIdent);
fnBody = t.assignmentExpression("=", fnBody, t.identifier(valueIdent.name));
}
return t.arrowFunctionExpression(argsList, fnBody);
});
}
function getBinding(thisEnvFn, key, init) {
const cacheKey = "binding:" + key;
let data = thisEnvFn.getData(cacheKey);
if (!data) {
const id = thisEnvFn.scope.generateUidIdentifier(key);
data = id.name;
thisEnvFn.setData(cacheKey, data);
thisEnvFn.scope.push({
id: id,
init: init(data)
});
}
return data;
}
function getScopeInformation(fnPath) {
const thisPaths = [];
const argumentsPaths = [];
const newTargetPaths = [];
const superProps = [];
const superCalls = [];
fnPath.traverse({
ClassProperty(child) {
child.skip();
},
Function(child) {
if (child.isArrowFunctionExpression()) return;
child.skip();
},
ThisExpression(child) {
thisPaths.push(child);
},
JSXIdentifier(child) {
if (child.node.name !== "this") return;
if (!child.parentPath.isJSXMemberExpression({
object: child.node
}) && !child.parentPath.isJSXOpeningElement({
name: child.node
})) {
return;
}
thisPaths.push(child);
},
CallExpression(child) {
if (child.get("callee").isSuper()) superCalls.push(child);
},
MemberExpression(child) {
if (child.get("object").isSuper()) superProps.push(child);
},
ReferencedIdentifier(child) {
if (child.node.name !== "arguments") return;
argumentsPaths.push(child);
},
MetaProperty(child) {
if (!child.get("meta").isIdentifier({
name: "new"
})) return;
if (!child.get("property").isIdentifier({
name: "target"
})) return;
newTargetPaths.push(child);
}
});
return {
thisPaths,
argumentsPaths,
newTargetPaths,
superProps,
superCalls
};
}
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.evaluateTruthy = evaluateTruthy;
exports.evaluate = evaluate;
const VALID_CALLEES = ["String", "Number", "Math"];
const INVALID_METHODS = ["random"];
function evaluateTruthy() {
const res = this.evaluate();
if (res.confident) return !!res.value;
}
function deopt(path, state) {
if (!state.confident) return;
state.deoptPath = path;
state.confident = false;
}
function evaluateCached(path, state) {
const {
node
} = path;
const {
seen
} = state;
if (seen.has(node)) {
const existing = seen.get(node);
if (existing.resolved) {
return existing.value;
} else {
deopt(path, state);
return;
}
} else {
const item = {
resolved: false
};
seen.set(node, item);
const val = _evaluate(path, state);
if (state.confident) {
item.resolved = true;
item.value = val;
}
return val;
}
}
function _evaluate(path, state) {
if (!state.confident) return;
if (path.isSequenceExpression()) {
const exprs = path.get("expressions");
return evaluateCached(exprs[exprs.length - 1], state);
}
if (path.isStringLiteral() || path.isNumericLiteral() || path.isBooleanLiteral()) {
return path.node.value;
}
if (path.isNullLiteral()) {
return null;
}
if (path.isTemplateLiteral()) {
return evaluateQuasis(path, path.node.quasis, state);
}
if (path.isTaggedTemplateExpression() && path.get("tag").isMemberExpression()) {
const object = path.get("tag.object");
const {
node: {
name
}
} = object;
const property = path.get("tag.property");
if (object.isIdentifier() && name === "String" && !path.scope.getBinding(name) && property.isIdentifier() && property.node.name === "raw") {
return evaluateQuasis(path, path.node.quasi.quasis, state, true);
}
}
if (path.isConditionalExpression()) {
const testResult = evaluateCached(path.get("test"), state);
if (!state.confident) return;
if (testResult) {
return evaluateCached(path.get("consequent"), state);
} else {
return evaluateCached(path.get("alternate"), state);
}
}
if (path.isExpressionWrapper()) {
return evaluateCached(path.get("expression"), state);
}
if (path.isMemberExpression() && !path.parentPath.isCallExpression({
callee: path.node
})) {
const property = path.get("property");
const object = path.get("object");
if (object.isLiteral() && property.isIdentifier()) {
const value = object.node.value;
const type = typeof value;
if (type === "number" || type === "string") {
return value[property.node.name];
}
}
}
if (path.isReferencedIdentifier()) {
const binding = path.scope.getBinding(path.node.name);
if (binding && binding.constantViolations.length > 0) {
return deopt(binding.path, state);
}
if (binding && path.node.start < binding.path.node.end) {
return deopt(binding.path, state);
}
if (binding != null && binding.hasValue) {
return binding.value;
} else {
if (path.node.name === "undefined") {
return binding ? deopt(binding.path, state) : undefined;
} else if (path.node.name === "Infinity") {
return binding ? deopt(binding.path, state) : Infinity;
} else if (path.node.name === "NaN") {
return binding ? deopt(binding.path, state) : NaN;
}
const resolved = path.resolve();
if (resolved === path) {
return deopt(path, state);
} else {
return evaluateCached(resolved, state);
}
}
}
if (path.isUnaryExpression({
prefix: true
})) {
if (path.node.operator === "void") {
return undefined;
}
const argument = path.get("argument");
if (path.node.operator === "typeof" && (argument.isFunction() || argument.isClass())) {
return "function";
}
const arg = evaluateCached(argument, state);
if (!state.confident) return;
switch (path.node.operator) {
case "!":
return !arg;
case "+":
return +arg;
case "-":
return -arg;
case "~":
return ~arg;
case "typeof":
return typeof arg;
}
}
if (path.isArrayExpression()) {
const arr = [];
const elems = path.get("elements");
for (const elem of elems) {
const elemValue = elem.evaluate();
if (elemValue.confident) {
arr.push(elemValue.value);
} else {
return deopt(elemValue.deopt, state);
}
}
return arr;
}
if (path.isObjectExpression()) {
const obj = {};
const props = path.get("properties");
for (const prop of props) {
if (prop.isObjectMethod() || prop.isSpreadElement()) {
return deopt(prop, state);
}
const keyPath = prop.get("key");
let key = keyPath;
if (prop.node.computed) {
key = key.evaluate();
if (!key.confident) {
return deopt(key.deopt, state);
}
key = key.value;
} else if (key.isIdentifier()) {
key = key.node.name;
} else {
key = key.node.value;
}
const valuePath = prop.get("value");
let value = valuePath.evaluate();
if (!value.confident) {
return deopt(value.deopt, state);
}
value = value.value;
obj[key] = value;
}
return obj;
}
if (path.isLogicalExpression()) {
const wasConfident = state.confident;
const left = evaluateCached(path.get("left"), state);
const leftConfident = state.confident;
state.confident = wasConfident;
const right = evaluateCached(path.get("right"), state);
const rightConfident = state.confident;
switch (path.node.operator) {
case "||":
state.confident = leftConfident && (!!left || rightConfident);
if (!state.confident) return;
return left || right;
case "&&":
state.confident = leftConfident && (!left || rightConfident);
if (!state.confident) return;
return left && right;
}
}
if (path.isBinaryExpression()) {
const left = evaluateCached(path.get("left"), state);
if (!state.confident) return;
const right = evaluateCached(path.get("right"), state);
if (!state.confident) return;
switch (path.node.operator) {
case "-":
return left - right;
case "+":
return left + right;
case "/":
return left / right;
case "*":
return left * right;
case "%":
return left % right;
case "**":
return Math.pow(left, right);
case "<":
return left < right;
case ">":
return left > right;
case "<=":
return left <= right;
case ">=":
return left >= right;
case "==":
return left == right;
case "!=":
return left != right;
case "===":
return left === right;
case "!==":
return left !== right;
case "|":
return left | right;
case "&":
return left & right;
case "^":
return left ^ right;
case "<<":
return left << right;
case ">>":
return left >> right;
case ">>>":
return left >>> right;
}
}
if (path.isCallExpression()) {
const callee = path.get("callee");
let context;
let func;
if (callee.isIdentifier() && !path.scope.getBinding(callee.node.name) && VALID_CALLEES.indexOf(callee.node.name) >= 0) {
func = global[callee.node.name];
}
if (callee.isMemberExpression()) {
const object = callee.get("object");
const property = callee.get("property");
if (object.isIdentifier() && property.isIdentifier() && VALID_CALLEES.indexOf(object.node.name) >= 0 && INVALID_METHODS.indexOf(property.node.name) < 0) {
context = global[object.node.name];
func = context[property.node.name];
}
if (object.isLiteral() && property.isIdentifier()) {
const type = typeof object.node.value;
if (type === "string" || type === "number") {
context = object.node.value;
func = context[property.node.name];
}
}
}
if (func) {
const args = path.get("arguments").map(arg => evaluateCached(arg, state));
if (!state.confident) return;
return func.apply(context, args);
}
}
deopt(path, state);
}
function evaluateQuasis(path, quasis, state, raw = false) {
let str = "";
let i = 0;
const exprs = path.get("expressions");
for (const elem of quasis) {
if (!state.confident) break;
str += raw ? elem.value.raw : elem.value.cooked;
const expr = exprs[i++];
if (expr) str += String(evaluateCached(expr, state));
}
if (!state.confident) return;
return str;
}
function evaluate() {
const state = {
confident: true,
deoptPath: null,
seen: new Map()
};
let value = evaluateCached(this, state);
if (!state.confident) value = undefined;
return {
confident: state.confident,
deopt: state.deoptPath,
value: value
};
}
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment