UNPKG

eslint-codemod-utils

Version:

A collection of AST helper functions for more complex ESLint rule fixes.

161 lines (158 loc) 8.54 kB
import { jsxAttribute, jsxClosingElement, jsxClosingFragment, jsxElement, jsxEmptyExpression, jsxExpressionContainer, jsxFragment, jsxIdentifier, jsxMemberExpression, jsxOpeningElement, jsxOpeningFragment, jsxSpreadAttribute, jsxSpreadChild, jsxText, } from './jsx-nodes'; import { arrayExpression, arrayPattern, arrowFunctionExpression, assignmentExpression, awaitExpression, binaryExpression, blockStatement, breakStatement, callExpression, catchClause, chainExpression, classBody, classDeclaration, classExpression, conditionalExpression, continueStatement, debuggerStatement, decorator, doWhileStatement, emptyStatement, exportAllDeclaration, exportDefaultDeclaration, exportNamedDeclaration, exportSpecifier, expressionStatement, forInStatement, forOfStatement, forStatement, functionDeclaration, functionExpression, identifier, ifStatement, importDeclaration, importDefaultSpecifier, importExpression, importNamespaceSpecifier, importSpecifier, literal, logicalExpression, memberExpression, methodDefinition, newExpression, objectExpression, objectPattern, privateIdentifier, program, property, propertyDefinition, restElement, returnStatement, sequenceExpression, spreadElement, staticBlock, superCallExpression, switchCase, switchStatement, taggedTemplateExpression, templateElement, templateLiteral, thisExpression, throwStatement, tryStatement, unaryExpression, updateExpression, variableDeclaration, variableDeclarator, whileStatement, withStatement, yieldExpression, } from './nodes'; import { tsAbstractKeyword, tsAnyKeyword, tsArrayType, tsAsExpression, tsAsyncKeyword, tsBooleanKeyword, tsConditionalType, tsEmptyBodyFunctionExpression, tsIntersectionType, tsLiteralType, tsNeverKeyword, tsNonNullExpression, tsNullKeyword, tsQualifiedName, tsReadonlyKeyword, tsSatisfiesExpression, tsStringKeyword, tsTypeAliasDeclaration, tsTypeOperator, tsTypeParameter, tsTypeParameterDeclaration, tsTypeParameterInstantiation, tsTypeQuery, tsTypeReference, tsUndefinedKeyword, tsUnionType, tsUnknownKeyword, tsVoidKeyword, } from './ts-nodes'; import { identity } from './utils/identity'; export const 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. export const typeToHelperLookup = new Proxy({ // TODO implement AssignmentPattern: identity, AssignmentExpression: assignmentExpression, AwaitExpression: awaitExpression, ArrayExpression: arrayExpression, ArrayPattern: arrayPattern, BlockStatement: blockStatement, BinaryExpression: binaryExpression, ConditionalExpression: conditionalExpression, ChainExpression: chainExpression, Decorator: decorator, JSXFragment: jsxFragment, JSXSpreadChild: jsxSpreadChild, JSXExpressionContainer: jsxExpressionContainer, JSXClosingElement: jsxClosingElement, JSXOpeningElement: jsxOpeningElement, JSXOpeningFragment: jsxOpeningFragment, JSXClosingFragment: jsxClosingFragment, JSXElement: jsxElement, JSXText: jsxText, JSXSpreadAttribute: jsxSpreadAttribute, JSXAttribute: jsxAttribute, JSXMemberExpression: jsxMemberExpression, JSXNamespacedName: identity, JSXIdentifier: jsxIdentifier, JSXEmptyExpression: jsxEmptyExpression, ArrowFunctionExpression: arrowFunctionExpression, FunctionExpression: functionExpression, Identifier: identifier, IfStatement: ifStatement, // TODO implement LabeledStatement: 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: literal, LogicalExpression: logicalExpression, /** this isn't a concrete node type */ ForStatement: forStatement, ForInStatement: forInStatement, ForOfStatement: forOfStatement, ImportSpecifier: importSpecifier, ImportNamespaceSpecifier: importNamespaceSpecifier, ImportDefaultSpecifier: importDefaultSpecifier, ImportDeclaration: importDeclaration, ImportExpression: importExpression, ThisExpression: thisExpression, ThrowStatement: throwStatement, TemplateLiteral: templateLiteral, TemplateElement: templateElement, TaggedTemplateExpression: taggedTemplateExpression, ObjectExpression: objectExpression, ObjectPattern: objectPattern, RestElement: restElement, MemberExpression: memberExpression, // TODO: needs implementation MetaProperty: identity, MethodDefinition: methodDefinition, NewExpression: newExpression, SwitchStatement: switchStatement, EmptyStatement: emptyStatement, FunctionDeclaration: functionDeclaration, CallExpression: callExpression, CatchClause: catchClause, ContinueStatement: continueStatement, ClassDeclaration: classDeclaration, ClassExpression: classExpression, ClassBody: classBody, DebuggerStatement: debuggerStatement, DoWhileStatement: doWhileStatement, ExportNamedDeclaration: exportNamedDeclaration, ExportSpecifier: exportSpecifier, ExportAllDeclaration: exportAllDeclaration, ExportDefaultDeclaration: exportDefaultDeclaration, BreakStatement: breakStatement, PrivateIdentifier: privateIdentifier, Property: property, Program: program, PropertyDefinition: propertyDefinition, ReturnStatement: returnStatement, Super: superCallExpression, SequenceExpression: sequenceExpression, SpreadElement: spreadElement, StaticBlock: staticBlock, SwitchCase: switchCase, TryStatement: tryStatement, WhileStatement: whileStatement, WithStatement: withStatement, ExpressionStatement: expressionStatement, UnaryExpression: unaryExpression, UpdateExpression: updateExpression, VariableDeclaration: variableDeclaration, VariableDeclarator: variableDeclarator, YieldExpression: yieldExpression, // typescript TSArrayType: tsArrayType, TSAsExpression: tsAsExpression, TSEmptyBodyFunctionExpression: tsEmptyBodyFunctionExpression, TSStringKeyword: tsStringKeyword, TSTypeReference: tsTypeReference, TSAnyKeyword: tsAnyKeyword, TSVoidKeyword: tsVoidKeyword, TSUnknownKeyword: tsUnknownKeyword, TSBooleanKeyword: tsBooleanKeyword, TSReadonlyKeyword: tsReadonlyKeyword, TSNullKeyword: tsNullKeyword, TSQualifiedName: tsQualifiedName, TSTypeParameterInstantiation: tsTypeParameterInstantiation, TSLiteralType: tsLiteralType, TSNonNullExpression: tsNonNullExpression, TSIntersectionType: tsIntersectionType, TSUnionType: tsUnionType, TSTypeQuery: tsTypeQuery, TSTypeOperator: tsTypeOperator, TSTypeAliasDeclaration: tsTypeAliasDeclaration, TSTypeParameterDeclaration: tsTypeParameterDeclaration, TSTypeParameter: tsTypeParameter, TSAbstractKeyword: tsAbstractKeyword, TSSatisfiesExpression: tsSatisfiesExpression, TSUndefinedKeyword: tsUndefinedKeyword, TSConditionalType: tsConditionalType, TSNeverKeyword: tsNeverKeyword, TSAsyncKeyword: 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; }, });