eslint-codemod-utils
Version:
A collection of AST helper functions for more complex ESLint rule fixes.
164 lines (161 loc) • 7.82 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.typeToHelperLookup = exports.DEFAULT_WHITESPACE = void 0;
const jsx_nodes_1 = require("./jsx-nodes");
const nodes_1 = require("./nodes");
const ts_nodes_1 = require("./ts-nodes");
const identity_1 = require("./utils/identity");
exports.DEFAULT_WHITESPACE = '\n ';
// Explicit annotation: the inferred object type for the proxy target is so
// deep (every helper's destructured `Loose<…>` signature is distinct) that
// `tsc --declaration` cannot serialize it into the emitted `.d.ts`. Pinning
// the exported type to the compact `Partial<NodeMap>` shape keeps the public
// declaration portable without weakening the runtime dispatch contract.
exports.typeToHelperLookup = new Proxy({
// TODO implement
AssignmentPattern: identity_1.identity,
AssignmentExpression: nodes_1.assignmentExpression,
AwaitExpression: nodes_1.awaitExpression,
ArrayExpression: nodes_1.arrayExpression,
ArrayPattern: nodes_1.arrayPattern,
BlockStatement: nodes_1.blockStatement,
BinaryExpression: nodes_1.binaryExpression,
ConditionalExpression: nodes_1.conditionalExpression,
ChainExpression: nodes_1.chainExpression,
Decorator: nodes_1.decorator,
JSXFragment: jsx_nodes_1.jsxFragment,
JSXSpreadChild: jsx_nodes_1.jsxSpreadChild,
JSXExpressionContainer: jsx_nodes_1.jsxExpressionContainer,
JSXClosingElement: jsx_nodes_1.jsxClosingElement,
JSXOpeningElement: jsx_nodes_1.jsxOpeningElement,
JSXOpeningFragment: jsx_nodes_1.jsxOpeningFragment,
JSXClosingFragment: jsx_nodes_1.jsxClosingFragment,
JSXElement: jsx_nodes_1.jsxElement,
JSXText: jsx_nodes_1.jsxText,
JSXSpreadAttribute: jsx_nodes_1.jsxSpreadAttribute,
JSXAttribute: jsx_nodes_1.jsxAttribute,
JSXMemberExpression: jsx_nodes_1.jsxMemberExpression,
JSXNamespacedName: identity_1.identity,
JSXIdentifier: jsx_nodes_1.jsxIdentifier,
JSXEmptyExpression: jsx_nodes_1.jsxEmptyExpression,
ArrowFunctionExpression: nodes_1.arrowFunctionExpression,
FunctionExpression: nodes_1.functionExpression,
Identifier: nodes_1.identifier,
IfStatement: nodes_1.ifStatement,
// TODO implement
LabeledStatement: identity_1.identity,
// `literal` is overloaded to accept raw primitives or `WithoutType<Literal>`.
// The dispatch map only ever calls the object-shaped overload, but the
// overload signatures make `satisfies NodeMap` unable to pick a single
// arity. Cast via `unknown` so the map entry satisfies the contract
// without widening the public `literal(…)` signature.
Literal: nodes_1.literal,
LogicalExpression: nodes_1.logicalExpression,
/** this isn't a concrete node type */
ForStatement: nodes_1.forStatement,
ForInStatement: nodes_1.forInStatement,
ForOfStatement: nodes_1.forOfStatement,
ImportSpecifier: nodes_1.importSpecifier,
ImportNamespaceSpecifier: nodes_1.importNamespaceSpecifier,
ImportDefaultSpecifier: nodes_1.importDefaultSpecifier,
ImportDeclaration: nodes_1.importDeclaration,
ImportExpression: nodes_1.importExpression,
ThisExpression: nodes_1.thisExpression,
ThrowStatement: nodes_1.throwStatement,
TemplateLiteral: nodes_1.templateLiteral,
TemplateElement: nodes_1.templateElement,
TaggedTemplateExpression: nodes_1.taggedTemplateExpression,
ObjectExpression: nodes_1.objectExpression,
ObjectPattern: nodes_1.objectPattern,
RestElement: nodes_1.restElement,
MemberExpression: nodes_1.memberExpression,
// TODO: needs implementation
MetaProperty: identity_1.identity,
MethodDefinition: nodes_1.methodDefinition,
NewExpression: nodes_1.newExpression,
SwitchStatement: nodes_1.switchStatement,
EmptyStatement: nodes_1.emptyStatement,
FunctionDeclaration: nodes_1.functionDeclaration,
CallExpression: nodes_1.callExpression,
CatchClause: nodes_1.catchClause,
ContinueStatement: nodes_1.continueStatement,
ClassDeclaration: nodes_1.classDeclaration,
ClassExpression: nodes_1.classExpression,
ClassBody: nodes_1.classBody,
DebuggerStatement: nodes_1.debuggerStatement,
DoWhileStatement: nodes_1.doWhileStatement,
ExportNamedDeclaration: nodes_1.exportNamedDeclaration,
ExportSpecifier: nodes_1.exportSpecifier,
ExportAllDeclaration: nodes_1.exportAllDeclaration,
ExportDefaultDeclaration: nodes_1.exportDefaultDeclaration,
BreakStatement: nodes_1.breakStatement,
PrivateIdentifier: nodes_1.privateIdentifier,
Property: nodes_1.property,
Program: nodes_1.program,
PropertyDefinition: nodes_1.propertyDefinition,
ReturnStatement: nodes_1.returnStatement,
Super: nodes_1.superCallExpression,
SequenceExpression: nodes_1.sequenceExpression,
SpreadElement: nodes_1.spreadElement,
StaticBlock: nodes_1.staticBlock,
SwitchCase: nodes_1.switchCase,
TryStatement: nodes_1.tryStatement,
WhileStatement: nodes_1.whileStatement,
WithStatement: nodes_1.withStatement,
ExpressionStatement: nodes_1.expressionStatement,
UnaryExpression: nodes_1.unaryExpression,
UpdateExpression: nodes_1.updateExpression,
VariableDeclaration: nodes_1.variableDeclaration,
VariableDeclarator: nodes_1.variableDeclarator,
YieldExpression: nodes_1.yieldExpression,
// typescript
TSArrayType: ts_nodes_1.tsArrayType,
TSAsExpression: ts_nodes_1.tsAsExpression,
TSEmptyBodyFunctionExpression: ts_nodes_1.tsEmptyBodyFunctionExpression,
TSStringKeyword: ts_nodes_1.tsStringKeyword,
TSTypeReference: ts_nodes_1.tsTypeReference,
TSAnyKeyword: ts_nodes_1.tsAnyKeyword,
TSVoidKeyword: ts_nodes_1.tsVoidKeyword,
TSUnknownKeyword: ts_nodes_1.tsUnknownKeyword,
TSBooleanKeyword: ts_nodes_1.tsBooleanKeyword,
TSReadonlyKeyword: ts_nodes_1.tsReadonlyKeyword,
TSNullKeyword: ts_nodes_1.tsNullKeyword,
TSQualifiedName: ts_nodes_1.tsQualifiedName,
TSTypeParameterInstantiation: ts_nodes_1.tsTypeParameterInstantiation,
TSLiteralType: ts_nodes_1.tsLiteralType,
TSNonNullExpression: ts_nodes_1.tsNonNullExpression,
TSIntersectionType: ts_nodes_1.tsIntersectionType,
TSUnionType: ts_nodes_1.tsUnionType,
TSTypeQuery: ts_nodes_1.tsTypeQuery,
TSTypeOperator: ts_nodes_1.tsTypeOperator,
TSTypeAliasDeclaration: ts_nodes_1.tsTypeAliasDeclaration,
TSTypeParameterDeclaration: ts_nodes_1.tsTypeParameterDeclaration,
TSTypeParameter: ts_nodes_1.tsTypeParameter,
TSAbstractKeyword: ts_nodes_1.tsAbstractKeyword,
TSSatisfiesExpression: ts_nodes_1.tsSatisfiesExpression,
TSUndefinedKeyword: ts_nodes_1.tsUndefinedKeyword,
TSConditionalType: ts_nodes_1.tsConditionalType,
TSNeverKeyword: ts_nodes_1.tsNeverKeyword,
TSAsyncKeyword: ts_nodes_1.tsAsyncKeyword,
// `NodeMap` covers every TSESTree node, but this dispatch table is
// incrementally implemented (see the Proxy below — unknown types throw
// an `UnknownNodeError` at runtime). Partial-satisfy so unimplemented
// variants are tolerated at the type level.
}, {
// dynamic getter will fail and provide debug information
get(target, name, receiver) {
if (Reflect.has(target, name)) {
return Reflect.get(target, name, receiver);
}
const nodeName = name.toString();
const error = new Error(`\
type '${nodeName}' missing in typeMap.
This is probably because the type '${nodeName}' is a Typescript or Flow specific node type. These nodes currently have only partial support.
To resolve this you can:
* Use a more constrained parser like esprima in your eslint config
* Lodge a bug at https://github.com/DarkPurple141/eslint-codemod-utils/issues
`);
error.name = 'UnknownNodeError';
throw error;
},
});