123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388 |
- 'use strict';
- /* eslint-disable jsdoc/valid-types -- doesn't allow `readonly`.
- TODO: remove eslint-disable when https://github.com/jsdoc-type-pratt-parser/jsdoc-type-pratt-parser/issues/164 is fixed
- */
- /**
- * @typedef {{ readonly [type: string]: ReadonlyArray<string> }} VisitorKeys
- */
- /* eslint-enable jsdoc/valid-types -- doesn't allow `readonly string[]`. TODO: check why */
- /**
- * @type {VisitorKeys}
- */
- const KEYS = {
- ArrayExpression: [
- "elements"
- ],
- ArrayPattern: [
- "elements"
- ],
- ArrowFunctionExpression: [
- "params",
- "body"
- ],
- AssignmentExpression: [
- "left",
- "right"
- ],
- AssignmentPattern: [
- "left",
- "right"
- ],
- AwaitExpression: [
- "argument"
- ],
- BinaryExpression: [
- "left",
- "right"
- ],
- BlockStatement: [
- "body"
- ],
- BreakStatement: [
- "label"
- ],
- CallExpression: [
- "callee",
- "arguments"
- ],
- CatchClause: [
- "param",
- "body"
- ],
- ChainExpression: [
- "expression"
- ],
- ClassBody: [
- "body"
- ],
- ClassDeclaration: [
- "id",
- "superClass",
- "body"
- ],
- ClassExpression: [
- "id",
- "superClass",
- "body"
- ],
- ConditionalExpression: [
- "test",
- "consequent",
- "alternate"
- ],
- ContinueStatement: [
- "label"
- ],
- DebuggerStatement: [],
- DoWhileStatement: [
- "body",
- "test"
- ],
- EmptyStatement: [],
- ExperimentalRestProperty: [
- "argument"
- ],
- ExperimentalSpreadProperty: [
- "argument"
- ],
- ExportAllDeclaration: [
- "exported",
- "source"
- ],
- ExportDefaultDeclaration: [
- "declaration"
- ],
- ExportNamedDeclaration: [
- "declaration",
- "specifiers",
- "source"
- ],
- ExportSpecifier: [
- "exported",
- "local"
- ],
- ExpressionStatement: [
- "expression"
- ],
- ForInStatement: [
- "left",
- "right",
- "body"
- ],
- ForOfStatement: [
- "left",
- "right",
- "body"
- ],
- ForStatement: [
- "init",
- "test",
- "update",
- "body"
- ],
- FunctionDeclaration: [
- "id",
- "params",
- "body"
- ],
- FunctionExpression: [
- "id",
- "params",
- "body"
- ],
- Identifier: [],
- IfStatement: [
- "test",
- "consequent",
- "alternate"
- ],
- ImportDeclaration: [
- "specifiers",
- "source"
- ],
- ImportDefaultSpecifier: [
- "local"
- ],
- ImportExpression: [
- "source"
- ],
- ImportNamespaceSpecifier: [
- "local"
- ],
- ImportSpecifier: [
- "imported",
- "local"
- ],
- JSXAttribute: [
- "name",
- "value"
- ],
- JSXClosingElement: [
- "name"
- ],
- JSXClosingFragment: [],
- JSXElement: [
- "openingElement",
- "children",
- "closingElement"
- ],
- JSXEmptyExpression: [],
- JSXExpressionContainer: [
- "expression"
- ],
- JSXFragment: [
- "openingFragment",
- "children",
- "closingFragment"
- ],
- JSXIdentifier: [],
- JSXMemberExpression: [
- "object",
- "property"
- ],
- JSXNamespacedName: [
- "namespace",
- "name"
- ],
- JSXOpeningElement: [
- "name",
- "attributes"
- ],
- JSXOpeningFragment: [],
- JSXSpreadAttribute: [
- "argument"
- ],
- JSXSpreadChild: [
- "expression"
- ],
- JSXText: [],
- LabeledStatement: [
- "label",
- "body"
- ],
- Literal: [],
- LogicalExpression: [
- "left",
- "right"
- ],
- MemberExpression: [
- "object",
- "property"
- ],
- MetaProperty: [
- "meta",
- "property"
- ],
- MethodDefinition: [
- "key",
- "value"
- ],
- NewExpression: [
- "callee",
- "arguments"
- ],
- ObjectExpression: [
- "properties"
- ],
- ObjectPattern: [
- "properties"
- ],
- PrivateIdentifier: [],
- Program: [
- "body"
- ],
- Property: [
- "key",
- "value"
- ],
- PropertyDefinition: [
- "key",
- "value"
- ],
- RestElement: [
- "argument"
- ],
- ReturnStatement: [
- "argument"
- ],
- SequenceExpression: [
- "expressions"
- ],
- SpreadElement: [
- "argument"
- ],
- StaticBlock: [
- "body"
- ],
- Super: [],
- SwitchCase: [
- "test",
- "consequent"
- ],
- SwitchStatement: [
- "discriminant",
- "cases"
- ],
- TaggedTemplateExpression: [
- "tag",
- "quasi"
- ],
- TemplateElement: [],
- TemplateLiteral: [
- "quasis",
- "expressions"
- ],
- ThisExpression: [],
- ThrowStatement: [
- "argument"
- ],
- TryStatement: [
- "block",
- "handler",
- "finalizer"
- ],
- UnaryExpression: [
- "argument"
- ],
- UpdateExpression: [
- "argument"
- ],
- VariableDeclaration: [
- "declarations"
- ],
- VariableDeclarator: [
- "id",
- "init"
- ],
- WhileStatement: [
- "test",
- "body"
- ],
- WithStatement: [
- "object",
- "body"
- ],
- YieldExpression: [
- "argument"
- ]
- };
- // Types.
- const NODE_TYPES = Object.keys(KEYS);
- // Freeze the keys.
- for (const type of NODE_TYPES) {
- Object.freeze(KEYS[type]);
- }
- Object.freeze(KEYS);
- /**
- * @author Toru Nagashima <https://github.com/mysticatea>
- * See LICENSE file in root directory for full license.
- */
- /**
- * @typedef {import('./visitor-keys.js').VisitorKeys} VisitorKeys
- */
- // List to ignore keys.
- const KEY_BLACKLIST = new Set([
- "parent",
- "leadingComments",
- "trailingComments"
- ]);
- /**
- * Check whether a given key should be used or not.
- * @param {string} key The key to check.
- * @returns {boolean} `true` if the key should be used.
- */
- function filterKey(key) {
- return !KEY_BLACKLIST.has(key) && key[0] !== "_";
- }
- /* eslint-disable jsdoc/valid-types -- doesn't allow `readonly`.
- TODO: remove eslint-disable when https://github.com/jsdoc-type-pratt-parser/jsdoc-type-pratt-parser/issues/164 is fixed
- */
- /**
- * Get visitor keys of a given node.
- * @param {Object} node The AST node to get keys.
- * @returns {readonly string[]} Visitor keys of the node.
- */
- function getKeys(node) {
- return Object.keys(node).filter(filterKey);
- }
- /* eslint-enable jsdoc/valid-types -- doesn't allow `readonly` */
- /**
- * Make the union set with `KEYS` and given keys.
- * @param {VisitorKeys} additionalKeys The additional keys.
- * @returns {VisitorKeys} The union set.
- */
- function unionWith(additionalKeys) {
- const retv = /** @type {{ [type: string]: ReadonlyArray<string> }} */
- (Object.assign({}, KEYS));
- for (const type of Object.keys(additionalKeys)) {
- if (Object.hasOwn(retv, type)) {
- const keys = new Set(additionalKeys[type]);
- for (const key of retv[type]) {
- keys.add(key);
- }
- retv[type] = Object.freeze(Array.from(keys));
- } else {
- retv[type] = Object.freeze(Array.from(additionalKeys[type]));
- }
- }
- return Object.freeze(retv);
- }
- exports.KEYS = KEYS;
- exports.getKeys = getKeys;
- exports.unionWith = unionWith;
|