123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- "use strict";
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
- if (k2 === undefined) k2 = k;
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
- }) : (function(o, m, k, k2) {
- if (k2 === undefined) k2 = k;
- o[k2] = m[k];
- }));
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
- Object.defineProperty(o, "default", { enumerable: true, value: v });
- }) : function(o, v) {
- o["default"] = v;
- });
- var __importStar = (this && this.__importStar) || function (mod) {
- if (mod && mod.__esModule) return mod;
- var result = {};
- if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
- __setModuleDefault(result, mod);
- return result;
- };
- var __importDefault = (this && this.__importDefault) || function (mod) {
- return (mod && mod.__esModule) ? mod : { "default": mod };
- };
- Object.defineProperty(exports, "__esModule", { value: true });
- const assert_never_1 = __importDefault(require("assert-never"));
- const babel_walk_1 = require("babel-walk");
- const t = __importStar(require("@babel/types"));
- const reference_1 = __importDefault(require("./reference"));
- const isScope = (node) => t.isFunctionParent(node) || t.isProgram(node);
- const isBlockScope = (node) => t.isBlockStatement(node) || isScope(node);
- const declaresArguments = (node) => t.isFunction(node) && !t.isArrowFunctionExpression(node);
- const declaresThis = declaresArguments;
- const LOCALS_SYMBOL = Symbol('locals');
- const getLocals = (node) => node[LOCALS_SYMBOL];
- const declareLocals = (node) => (node[LOCALS_SYMBOL] = node[LOCALS_SYMBOL] || new Set());
- const setLocal = (node, name) => declareLocals(node).add(name);
- // First pass
- function declareFunction(node) {
- for (const param of node.params) {
- declarePattern(param, node);
- }
- const id = node.id;
- if (id) {
- setLocal(node, id.name);
- }
- }
- function declarePattern(node, parent) {
- switch (node.type) {
- case 'Identifier':
- setLocal(parent, node.name);
- break;
- case 'ObjectPattern':
- for (const prop of node.properties) {
- switch (prop.type) {
- case 'RestElement':
- declarePattern(prop.argument, parent);
- break;
- case 'ObjectProperty':
- declarePattern(prop.value, parent);
- break;
- default:
- assert_never_1.default(prop);
- break;
- }
- }
- break;
- case 'ArrayPattern':
- for (const element of node.elements) {
- if (element)
- declarePattern(element, parent);
- }
- break;
- case 'RestElement':
- declarePattern(node.argument, parent);
- break;
- case 'AssignmentPattern':
- declarePattern(node.left, parent);
- break;
- // istanbul ignore next
- default:
- throw new Error('Unrecognized pattern type: ' + node.type);
- }
- }
- function declareModuleSpecifier(node, _state, parents) {
- for (let i = parents.length - 2; i >= 0; i--) {
- if (isScope(parents[i])) {
- setLocal(parents[i], node.local.name);
- return;
- }
- }
- }
- const firstPass = babel_walk_1.ancestor({
- VariableDeclaration(node, _state, parents) {
- for (let i = parents.length - 2; i >= 0; i--) {
- if (node.kind === 'var'
- ? t.isFunctionParent(parents[i])
- : isBlockScope(parents[i])) {
- for (const declaration of node.declarations) {
- declarePattern(declaration.id, parents[i]);
- }
- return;
- }
- }
- },
- FunctionDeclaration(node, _state, parents) {
- if (node.id) {
- for (let i = parents.length - 2; i >= 0; i--) {
- if (isScope(parents[i])) {
- setLocal(parents[i], node.id.name);
- return;
- }
- }
- }
- },
- Function: declareFunction,
- ClassDeclaration(node, _state, parents) {
- for (let i = parents.length - 2; i >= 0; i--) {
- if (isScope(parents[i])) {
- setLocal(parents[i], node.id.name);
- return;
- }
- }
- },
- TryStatement(node) {
- if (node.handler === null)
- return;
- if (node.handler.param === null)
- return;
- declarePattern(node.handler.param, node.handler);
- },
- ImportDefaultSpecifier: declareModuleSpecifier,
- ImportSpecifier: declareModuleSpecifier,
- ImportNamespaceSpecifier: declareModuleSpecifier,
- });
- // Second pass
- const secondPass = babel_walk_1.ancestor({
- Identifier(node, state, parents) {
- var _a;
- const name = node.name;
- if (name === 'undefined')
- return;
- const lastParent = parents[parents.length - 2];
- if (lastParent) {
- if (!reference_1.default(node, lastParent))
- return;
- for (const parent of parents) {
- if (name === 'arguments' && declaresArguments(parent)) {
- return;
- }
- if ((_a = getLocals(parent)) === null || _a === void 0 ? void 0 : _a.has(name)) {
- return;
- }
- }
- }
- state.globals.push(node);
- },
- ThisExpression(node, state, parents) {
- for (const parent of parents) {
- if (declaresThis(parent)) {
- return;
- }
- }
- state.globals.push(node);
- },
- });
- function findGlobals(ast) {
- const globals = [];
- // istanbul ignore if
- if (!t.isNode(ast)) {
- throw new TypeError('Source must be a Babylon AST');
- }
- firstPass(ast, undefined);
- secondPass(ast, { globals });
- const groupedGlobals = new Map();
- for (const node of globals) {
- const name = node.type === 'ThisExpression' ? 'this' : node.name;
- const existing = groupedGlobals.get(name);
- if (existing) {
- existing.push(node);
- }
- else {
- groupedGlobals.set(name, [node]);
- }
- }
- return [...groupedGlobals]
- .map(([name, nodes]) => ({ name, nodes }))
- .sort((a, b) => (a.name < b.name ? -1 : 1));
- }
- exports.default = findGlobals;
- //# sourceMappingURL=globals.js.map
|