// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. class Visitor { constructor() { this.diagnostics = []; } collectDiagnostics(programAst) { this.visitProgram(programAst); return this.diagnostics; } addDiagnostic(d) { this.diagnostics.push(d); } // must be overridden static ruleCode() { throw new Error("Rule code not provided!"); } visitProgram(n) { switch (n.type) { case "Module": return this.visitModule(n); case "Script": return this.visitScript(n); } } visitModule(m) { m.body = this.visitModuleItems(m.body); return m; } visitScript(m) { m.body = this.visitStatements(m.body); return m; } visitModuleItems(items) { return items.map(this.visitModuleItem.bind(this)); } visitModuleItem(n) { switch (n.type) { case "ExportDeclaration": case "ExportDefaultDeclaration": case "ExportNamedDeclaration": case "ExportDefaultExpression": case "ImportDeclaration": case "ExportAllDeclaration": case "TsImportEqualsDeclaration": case "TsExportAssignment": case "TsNamespaceExportDeclaration": return this.visitModuleDeclaration(n); default: return this.visitStatement(n); } } visitModuleDeclaration(n) { switch (n.type) { case "ExportDeclaration": return this.visitExportDeclaration(n); case "ExportDefaultDeclaration": return this.visitExportDefaultDeclaration(n); case "ExportNamedDeclaration": return this.visitExportNamedDeclration(n); case "ExportDefaultExpression": return this.visitExportDefaultExpression(n); case "ImportDeclaration": return this.visitImportDeclaration(n); case "ExportAllDeclaration": return this.visitExportAllDeclration(n); case "TsImportEqualsDeclaration": return this.visitTsImportEqualsDeclaration(n); case "TsExportAssignment": return this.visitTsExportAssignment(n); case "TsNamespaceExportDeclaration": return this.visitTsNamespaceExportDeclaration(n); } } visitTsNamespaceExportDeclaration(n) { n.id = this.visitBindingIdentifier(n.id); return n; } visitTsExportAssignment(n) { n.expression = this.visitExpression(n.expression); return n; } visitTsImportEqualsDeclaration(n) { n.id = this.visitBindingIdentifier(n.id); n.moduleRef = this.visitTsModuleReference(n.moduleRef); return n; } visitTsModuleReference(n) { switch (n.type) { case "Identifier": return this.visitIdentifierReference(n); case "TsExternalModuleReference": return this.visitTsExternalModuleReference(n); case "TsQualifiedName": return this.visitTsQualifiedName(n); } } visitTsExternalModuleReference(n) { n.expression = this.visitExpression(n.expression); return n; } visitExportAllDeclration(n) { n.source = this.visitStringLiteral(n.source); return n; } visitExportDefaultExpression(n) { n.expression = this.visitExpression(n.expression); return n; } visitExportNamedDeclration(n) { n.specifiers = this.visitExportSpecifiers(n.specifiers); n.source = this.visitOptionalStringLiteral(n.source); return n; } visitExportSpecifiers(nodes) { return nodes.map(this.visitExportSpecifier.bind(this)); } visitExportSpecifier(n) { switch (n.type) { case "ExportDefaultSpecifier": return this.visitExportDefaultSpecifier(n); case "ExportNamespaceSpecifer": return this.visitExportNamespaceSpecifier(n); case "ExportSpecifier": return this.visitNamedExportSpecifier(n); } } visitNamedExportSpecifier(n) { if (n.exported) { n.exported = this.visitBindingIdentifier(n.exported); } n.orig = this.visitIdentifierReference(n.orig); return n; } visitExportNamespaceSpecifier(n) { n.name = this.visitBindingIdentifier(n.name); return n; } visitExportDefaultSpecifier(n) { n.exported = this.visitBindingIdentifier(n.exported); return n; } visitOptionalStringLiteral(n) { if (n) { return this.visitStringLiteral(n); } } visitExportDefaultDeclaration(n) { n.decl = this.visitDefaultDeclaration(n.decl); return n; } visitDefaultDeclaration(n) { switch (n.type) { case "ClassExpression": return this.visitClassExpression(n); case "FunctionExpression": return this.visitFunctionExpression(n); case "TsInterfaceDeclaration": return this.visitTsInterfaceDeclaration(n); } } visitFunctionExpression(n) { n = this.visitFunction(n); if (n.identifier) { n.identifier = this.visitBindingIdentifier(n.identifier); } return n; } visitClassExpression(n) { n = this.visitClass(n); if (n.identifier) { n.identifier = this.visitBindingIdentifier(n.identifier); } return n; } visitExportDeclaration(n) { n.declaration = this.visitDeclaration(n.declaration); return n; } visitArrayExpression(e) { if (e.elements) { e.elements = e.elements.map(this.visitArrayElement.bind(this)); } return e; } visitArrayElement(e) { if (e && e.type === "SpreadElement") { return this.visitSpreadElement(e); } return this.visitOptionalExpression(e); } visitSpreadElement(e) { e.arguments = this.visitExpression(e.arguments); return e; } visitOptionalExpression(e) { if (e) { return this.visitExpression(e); } } visitArrowFunctionExpression(e) { e.body = this.visitArrowBody(e.body); e.params = this.visitPatterns(e.params); e.returnType = this.visitTsTypeAnnotation(e.returnType); e.typeParameters = this.visitTsTypeParameterDeclaration(e.typeParameters); return e; } visitArrowBody(body) { switch (body.type) { case "BlockStatement": return this.visitBlockStatement(body); default: return this.visitExpression(body); } } visitBlockStatement(block) { block.stmts = this.visitStatements(block.stmts); return block; } visitStatements(stmts) { return stmts.map(this.visitStatement.bind(this)); } visitStatement(stmt) { switch (stmt.type) { case "ClassDeclaration": case "FunctionDeclaration": case "TsEnumDeclaration": case "TsInterfaceDeclaration": case "TsModuleDeclaration": case "TsTypeAliasDeclaration": case "VariableDeclaration": return this.visitDeclaration(stmt); case "BreakStatement": return this.visitBreakStatement(stmt); case "BlockStatement": return this.visitBlockStatement(stmt); case "ContinueStatement": return this.visitContinueStatement(stmt); case "DebuggerStatement": return this.visitDebuggerStatement(stmt); case "DoWhileStatement": return this.visitDoWhileStatement(stmt); case "EmptyStatement": return this.visitEmptyStatement(stmt); case "ForInStatement": return this.visitForInStatement(stmt); case "ForOfStatement": return this.visitForOfStatement(stmt); case "ForStatement": return this.visitForStatement(stmt); case "IfStatement": return this.visitIfStatement(stmt); case "LabeledStatement": return this.visitLabeledStatement(stmt); case "ReturnStatement": return this.visitReturnStatement(stmt); case "SwitchStatement": return this.visitSwitchStatement(stmt); case "ThrowStatement": return this.visitThrowStatement(stmt); case "TryStatement": return this.visitTryStatement(stmt); case "WhileStatement": return this.visitWhileStatement(stmt); case "WithStatement": return this.visitWithStatement(stmt); case "ExpressionStatement": return this.visitExpressionStatement(stmt); default: throw new Error(`Unknown statement type: ` + stmt.type); } } visitSwitchStatement(stmt) { stmt.discriminant = this.visitExpression(stmt.discriminant); stmt.cases = this.visitSwitchCases(stmt.cases); return stmt; } visitSwitchCases(cases) { return cases.map(this.visitSwitchCase.bind(this)); } visitSwitchCase(c) { c.test = this.visitOptionalExpression(c.test); c.consequent = this.visitStatements(c.consequent); return c; } visitIfStatement(stmt) { stmt.test = this.visitExpression(stmt.test); stmt.consequent = this.visitStatement(stmt.consequent); stmt.alternate = this.visitOptionalStatement(stmt.alternate); return stmt; } visitOptionalStatement(stmt) { if (stmt) { return this.visitStatement(stmt); } } visitBreakStatement(stmt) { if (stmt.label) { stmt.label = this.visitLabelIdentifier(stmt.label); } return stmt; } visitWhileStatement(stmt) { stmt.test = this.visitExpression(stmt.test); stmt.body = this.visitStatement(stmt.body); return stmt; } visitTryStatement(stmt) { stmt.block = this.visitBlockStatement(stmt.block); stmt.handler = this.visitCatchClause(stmt.handler); if (stmt.finalizer) { stmt.finalizer = this.visitBlockStatement(stmt.finalizer); } return stmt; } visitCatchClause(handler) { if (handler) { if (handler.param) { handler.param = this.visitPattern(handler.param); } handler.body = this.visitBlockStatement(handler.body); } return handler; } visitThrowStatement(stmt) { stmt.argument = this.visitExpression(stmt.argument); return stmt; } visitReturnStatement(stmt) { if (stmt.argument) { stmt.argument = this.visitExpression(stmt.argument); } return stmt; } visitLabeledStatement(stmt) { stmt.label = this.visitLabelIdentifier(stmt.label); stmt.body = this.visitStatement(stmt.body); return stmt; } visitForStatement(stmt) { if (stmt.init) { if (stmt.init.type === "VariableDeclaration") { stmt.init = this.visitVariableDeclaration(stmt.init); } else { stmt.init = this.visitOptionalExpression(stmt.init); } } stmt.test = this.visitOptionalExpression(stmt.test); stmt.update = this.visitOptionalExpression(stmt.update); stmt.body = this.visitStatement(stmt.body); return stmt; } visitForOfStatement(stmt) { if (stmt.left.type === "VariableDeclaration") { stmt.left = this.visitVariableDeclaration(stmt.left); } else { stmt.left = this.visitPattern(stmt.left); } stmt.right = this.visitExpression(stmt.right); stmt.body = this.visitStatement(stmt.body); return stmt; } visitForInStatement(stmt) { if (stmt.left.type === "VariableDeclaration") { stmt.left = this.visitVariableDeclaration(stmt.left); } else { stmt.left = this.visitPattern(stmt.left); } stmt.right = this.visitExpression(stmt.right); stmt.body = this.visitStatement(stmt.body); return stmt; } visitEmptyStatement(stmt) { return stmt; } visitDoWhileStatement(stmt) { stmt.body = this.visitStatement(stmt.body); stmt.test = this.visitExpression(stmt.test); return stmt; } visitDebuggerStatement(stmt) { return stmt; } visitWithStatement(stmt) { stmt.object = this.visitExpression(stmt.object); stmt.body = this.visitStatement(stmt.body); return stmt; } visitDeclaration(decl) { switch (decl.type) { case "ClassDeclaration": return this.visitClassDeclartion(decl); case "FunctionDeclaration": return this.visitFunctionDeclaration(decl); case "TsEnumDeclaration": return this.visitTsEnumDeclaration(decl); case "TsInterfaceDeclaration": return this.visitTsInterfaceDeclaration(decl); case "TsModuleDeclaration": return this.visitTsModuleDeclaration(decl); case "TsTypeAliasDeclaration": return this.visitTsTypeAliasDeclaration(decl); case "VariableDeclaration": return this.visitVariableDeclaration(decl); } } visitVariableDeclaration(n) { n.declarations = this.visitVariableDeclarators(n.declarations); return n; } visitVariableDeclarators(nodes) { return nodes.map(this.visitVariableDeclarator.bind(this)); } visitVariableDeclarator(n) { n.id = this.visitPattern(n.id); n.init = this.visitOptionalExpression(n.init); return n; } visitTsTypeAliasDeclaration(n) { n.id = this.visitBindingIdentifier(n.id); n.typeAnnotation = this.visitTsType(n.typeAnnotation); n.typeParams = this.visitTsTypeParameterDeclaration(n.typeParams); return n; } visitTsModuleDeclaration(n) { n.id = this.visitTsModuleName(n.id); if (n.body) { n.body = this.visitTsNamespaceBody(n.body); } return n; } visitTsModuleName(n) { switch (n.type) { case "Identifier": return this.visitBindingIdentifier(n); case "StringLiteral": return this.visitStringLiteral(n); } } visitTsNamespaceBody(n) { if (n) { switch (n.type) { case "TsModuleBlock": return this.visitTsModuleBlock(n); case "TsNamespaceDeclaration": return this.visitTsNamespaceDeclaration(n); } } } visitTsNamespaceDeclaration(n) { const body = this.visitTsNamespaceBody(n.body); if (body) { n.body = body; } n.id = this.visitBindingIdentifier(n.id); return n; } visitTsModuleBlock(n) { n.body = this.visitModuleItems(n.body); return n; } visitTsInterfaceDeclaration(n) { n.id = this.visitBindingIdentifier(n.id); n.typeParams = this.visitTsTypeParameterDeclaration(n.typeParams); n.extends = this.visitTsExpressionsWithTypeArguments(n.extends); n.body = this.visitTsInterfaceBody(n.body); return n; } visitTsInterfaceBody(n) { n.body = this.visitTsTypeElements(n.body); return n; } visitTsTypeElements(nodes) { return nodes.map(this.visitTsTypeElement.bind(this)); } visitTsTypeElement(n) { n.params = this.visitTsFnParameters(n.params); n.typeAnnotation = this.visitTsTypeAnnotation(n.typeAnnotation); return n; } visitTsEnumDeclaration(n) { n.id = this.visitIdentifier(n.id); n.member = this.visitTsEnumMembers(n.member); return n; } visitTsEnumMembers(nodes) { return nodes.map(this.visitTsEnumMember.bind(this)); } visitTsEnumMember(n) { n.id = this.visitTsEnumMemberId(n.id); n.init = this.visitOptionalExpression(n.init); return n; } visitTsEnumMemberId(n) { switch (n.type) { case "Identifier": return this.visitBindingIdentifier(n); case "StringLiteral": return this.visitStringLiteral(n); } } visitFunctionDeclaration(decl) { decl.ident = this.visitIdentifier(decl.ident); decl = this.visitFunction(decl); return decl; } visitClassDeclartion(decl) { decl = this.visitClass(decl); decl.identifier = this.visitIdentifier(decl.identifier); return decl; } visitClassBody(members) { return members.map(this.visitClassMember.bind(this)); } visitClassMember(member) { switch (member.type) { case "ClassMethod": return this.visitClassMethod(member); case "ClassProperty": return this.visitClassProperty(member); case "Constructor": return this.visitConstructor(member); case "PrivateMethod": return this.visitPrivateMethod(member); case "PrivateProperty": return this.visitPrivateProperty(member); case "TsIndexSignature": return this.visitTsIndexSignature(member); } } visitTsIndexSignature(n) { n.params = this.visitTsFnParameters(n.params); n.typeAnnotation = this.visitTsTypeAnnotation(n.typeAnnotation); return n; } visitTsFnParameters(params) { return params.map(this.visitTsFnParameter.bind(this)); } visitTsFnParameter(n) { n.typeAnnotation = this.visitTsTypeAnnotation(n.typeAnnotation); return n; } visitPrivateProperty(n) { n.decorators = this.visitDecorators(n.decorators); n.key = this.visitPrivateName(n.key); n.typeAnnotation = this.visitTsTypeAnnotation(n.typeAnnotation); n.value = this.visitOptionalExpression(n.value); return n; } visitPrivateMethod(n) { n.accessibility = this.visitAccessibility(n.accessibility); n.function = this.visitFunction(n.function); n.key = this.visitPrivateName(n.key); return n; } visitPrivateName(n) { return n; } visitConstructor(n) { n.accessibility = this.visitAccessibility(n.accessibility); n.key = this.visitPropertyName(n.key); n.params = this.visitConstructorParameters(n.params); if (n.body) { n.body = this.visitBlockStatement(n.body); } return n; } visitConstructorParameters(nodes) { return nodes.map(this.visitConstructorParameter.bind(this)); } visitConstructorParameter(n) { switch (n.type) { case "TsParameterProperty": return this.visitTsParameterProperty(n); default: return this.visitParameter(n); } } visitTsParameterProperty(n) { n.accessibility = this.visitAccessibility(n.accessibility); n.decorators = this.visitDecorators(n.decorators); n.param = this.visitTsParameterPropertyParameter(n.param); return n; } visitTsParameterPropertyParameter(n) { n.typeAnnotation = this.visitTsTypeAnnotation(n.typeAnnotation); return n; } visitPropertyName(key) { switch (key.type) { case "Identifier": return this.visitBindingIdentifier(key); case "StringLiteral": return this.visitStringLiteral(key); case "NumericLiteral": return this.visitNumericLiteral(key); default: return this.visitComputedPropertyKey(key); } } visitAccessibility(n) { return n; } visitClassProperty(n) { n.accessibility = this.visitAccessibility(n.accessibility); n.decorators = this.visitDecorators(n.decorators); n.key = this.visitExpression(n.key); n.typeAnnotation = this.visitTsTypeAnnotation(n.typeAnnotation); n.value = this.visitOptionalExpression(n.value); return n; } visitClassMethod(n) { n.accessibility = this.visitAccessibility(n.accessibility); n.function = this.visitFunction(n.function); n.key = this.visitPropertyName(n.key); return n; } visitPropertName(n) { switch (n.type) { case "Identifier": return this.visitIdentifier(n); case "NumericLiteral": return this.visitNumericLiteral(n); case "StringLiteral": return this.visitStringLiteral(n); case "Computed": return this.visitComputedPropertyKey(n); } } visitComputedPropertyKey(n) { n.expression = this.visitExpression(n.expression); return n; } visitClass(n) { n.decorators = this.visitDecorators(n.decorators); n.superClass = this.visitOptionalExpression(n.superClass); n.superTypeParams = this.visitTsTypeParameterInstantiation( n.superTypeParams, ); if (n.implements) { n.implements = this.visitTsExpressionsWithTypeArguments(n.implements); } n.body = this.visitClassBody(n.body); return n; } visitFunction(n) { n.decorators = this.visitDecorators(n.decorators); n.params = this.visitParameters(n.params); if (n.body) { n.body = this.visitBlockStatement(n.body); } n.returnType = this.visitTsTypeAnnotation(n.returnType); n.typeParameters = this.visitTsTypeParameterDeclaration(n.typeParameters); return n; } visitTsExpressionsWithTypeArguments(nodes) { return nodes.map(this.visitTsExpressionWithTypeArguments.bind(this)); } visitTsExpressionWithTypeArguments(n) { n.expression = this.visitTsEntityName(n.expression); n.typeArguments = this.visitTsTypeParameterInstantiation(n.typeArguments); return n; } visitTsTypeParameterInstantiation(n) { if (n) { n.params = this.visitTsTypes(n.params); } return n; } visitTsTypes(nodes) { return nodes.map(this.visitTsType.bind(this)); } visitTsEntityName(n) { switch (n.type) { case "Identifier": return this.visitBindingIdentifier(n); case "TsQualifiedName": return this.visitTsQualifiedName(n); } } visitTsQualifiedName(n) { n.left = this.visitTsEntityName(n.left); n.right = this.visitIdentifier(n.right); return n; } visitDecorators(nodes) { if (nodes) { return nodes.map(this.visitDecorator.bind(this)); } } visitDecorator(n) { n.expression = this.visitExpression(n.expression); return n; } visitExpressionStatement(stmt) { stmt.expression = this.visitExpression(stmt.expression); return stmt; } visitContinueStatement(stmt) { if (stmt.label) { stmt.label = this.visitLabelIdentifier(stmt.label); } return stmt; } visitExpression(n) { switch (n.type) { case "ArrayExpression": return this.visitArrayExpression(n); case "ArrowFunctionExpression": return this.visitArrowFunctionExpression(n); case "AssignmentExpression": return this.visitAssignmentExpression(n); case "AwaitExpression": return this.visitAwaitExpression(n); case "BinaryExpression": return this.visitBinaryExpression(n); case "BooleanLiteral": return this.visitBooleanLiteral(n); case "CallExpression": return this.visitCallExpression(n); case "ClassExpression": return this.visitClassExpression(n); case "ConditionalExpression": return this.visitConditionalExpression(n); case "FunctionExpression": return this.visitFunctionExpression(n); case "Identifier": return this.visitIdentifierReference(n); case "JSXElement": return this.visitJSXElement(n); case "JSXEmptyExpression": return this.visitJSXEmptyExpression(n); case "JSXFragment": return this.visitJSXFragment(n); case "JSXMemberExpression": return this.visitJSXMemberExpression(n); case "JSXNamespacedName": return this.visitJSXNamespacedName(n); case "JSXText": return this.visitJSXText(n); case "MemberExpression": return this.visitMemberExpression(n); case "MetaProperty": return this.visitMetaProperty(n); case "NewExpression": return this.visitNewExpression(n); case "NullLiteral": return this.visitNullLiteral(n); case "NumericLiteral": return this.visitNumericLiteral(n); case "ObjectExpression": return this.visitObjectExpression(n); case "ParenthesisExpression": return this.visitParenthesisExpression(n); case "PrivateName": return this.visitPrivateName(n); case "RegExpLiteral": return this.visitRegExpLiteral(n); case "SequenceExpression": return this.visitSequenceExpression(n); case "StringLiteral": return this.visitStringLiteral(n); case "TaggedTemplateExpression": return this.visitTaggedTemplateExpression(n); case "TemplateLiteral": return this.visitTemplateLiteral(n); case "ThisExpression": return this.visitThisExpression(n); case "TsAsExpression": return this.visitTsAsExpression(n); case "TsNonNullExpression": return this.visitTsNonNullExpression(n); case "TsTypeAssertion": return this.visitTsTypeAssertion(n); case "TsTypeCastExpression": return this.visitTsTypeCastExpression(n); case "UnaryExpression": return this.visitUnaryExpression(n); case "UpdateExpression": return this.visitUpdateExpression(n); case "YieldExpression": return this.visitYieldExpression(n); case "OptionalChainingExpression": return this.visitOptionalChainingExpression(n); case "Invalid": return n; } } visitOptionalChainingExpression(n) { n.expr = this.visitExpression(n.expr); return n; } visitAssignmentExpression(n) { n.left = this.visitPatternOrExpressison(n.left); n.right = this.visitExpression(n.right); return n; } visitPatternOrExpressison(n) { switch (n.type) { case "ObjectPattern": case "ArrayPattern": case "Identifier": case "AssignmentPattern": case "RestElement": return this.visitPattern(n); default: return this.visitExpression(n); } } visitYieldExpression(n) { n.argument = this.visitOptionalExpression(n.argument); return n; } visitUpdateExpression(n) { n.argument = this.visitExpression(n.argument); return n; } visitUnaryExpression(n) { n.argument = this.visitExpression(n.argument); return n; } visitTsTypeCastExpression(n) { n.expression = this.visitExpression(n.expression); n.typeAnnotation = this.visitTsTypeAnnotation(n.typeAnnotation); return n; } visitTsTypeAssertion(n) { n.expression = this.visitExpression(n.expression); n.typeAnnotation = this.visitTsType(n.typeAnnotation); return n; } visitTsNonNullExpression(n) { n.expression = this.visitExpression(n.expression); return n; } visitTsAsExpression(n) { n.expression = this.visitExpression(n.expression); n.typeAnnotation = this.visitTsType(n.typeAnnotation); return n; } visitThisExpression(n) { return n; } visitTemplateLiteral(n) { n.expressions = n.expressions.map(this.visitExpression.bind(this)); return n; } visitParameters(n) { return n.map(this.visitParameter.bind(this)); } visitParameter(n) { n.pat = this.visitPattern(n.pat); return n; } visitTaggedTemplateExpression(n) { n.tag = this.visitExpression(n.tag); n.expressions = n.expressions.map(this.visitExpression.bind(this)); return n; } visitSequenceExpression(n) { n.expressions = n.expressions.map(this.visitExpression.bind(this)); return n; } visitRegExpLiteral(n) { return n; } visitParenthesisExpression(n) { n.expression = this.visitExpression(n.expression); return n; } visitObjectExpression(n) { if (n.properties) { n.properties = this.visitObjectProperties(n.properties); } return n; } visitObjectProperties(nodes) { return nodes.map(this.visitObjectProperty.bind(this)); } visitObjectProperty(n) { switch (n.type) { case "SpreadElement": return this.visitSpreadElement(n); default: return this.visitProperty(n); } } visitProperty(n) { switch (n.type) { case "Identifier": return this.visitIdentifier(n); case "AssignmentProperty": return this.visitAssignmentProperty(n); case "GetterProperty": return this.visitGetterProperty(n); case "KeyValueProperty": return this.visitKeyValueProperty(n); case "MethodProperty": return this.visitMethodProperty(n); case "SetterProperty": return this.visitSetterProperty(n); } } visitSetterProperty(n) { n.key = this.visitPropertyName(n.key); n.param = this.visitPattern(n.param); if (n.body) { n.body = this.visitBlockStatement(n.body); } return n; } visitMethodProperty(n) { n.key = this.visitPropertyName(n.key); if (n.body) { n.body = this.visitBlockStatement(n.body); } n.decorators = this.visitDecorators(n.decorators); n.params = this.visitParameters(n.params); n.returnType = this.visitTsTypeAnnotation(n.returnType); n.typeParameters = this.visitTsTypeParameterDeclaration(n.typeParameters); return n; } visitKeyValueProperty(n) { n.key = this.visitPropertyName(n.key); n.value = this.visitExpression(n.value); return n; } visitGetterProperty(n) { n.key = this.visitPropertyName(n.key); if (n.body) { n.body = this.visitBlockStatement(n.body); } n.typeAnnotation = this.visitTsTypeAnnotation(n.typeAnnotation); return n; } visitAssignmentProperty(n) { n.key = this.visitIdentifier(n.key); n.value = this.visitExpression(n.value); return n; } visitNullLiteral(n) { return n; } visitNewExpression(n) { n.callee = this.visitExpression(n.callee); if (n.arguments) { n.arguments = this.visitArguments(n.arguments); } n.typeArguments = this.visitTsTypeArguments(n.typeArguments); return n; } visitTsTypeArguments(n) { if (n) { n.params = this.visitTsTypes(n.params); } return n; } visitArguments(nodes) { return nodes.map(this.visitArgument.bind(this)); } visitArgument(n) { n.expression = this.visitExpression(n.expression); return n; } visitMetaProperty(n) { n.meta = this.visitIdentifierReference(n.meta); n.property = this.visitIdentifier(n.property); return n; } visitMemberExpression(n) { n.object = this.visitExpressionOrSuper(n.object); n.property = this.visitExpression(n.property); return n; } visitExpressionOrSuper(n) { if (n.type === "Super") { return n; } return this.visitExpression(n); } visitJSXText(n) { return n; } visitJSXNamespacedName(n) { n.namespace = this.visitIdentifierReference(n.namespace); n.name = this.visitIdentifierReference(n.name); return n; } visitJSXMemberExpression(n) { n.object = this.visitJSXObject(n.object); n.property = this.visitIdentifierReference(n.property); return n; } visitJSXObject(n) { switch (n.type) { case "Identifier": return this.visitIdentifierReference(n); case "JSXMemberExpression": return this.visitJSXMemberExpression(n); } } visitJSXFragment(n) { n.opening = this.visitJSXOpeningFragment(n.opening); if (n.children) { n.children = this.visitJSXElementChildren(n.children); } n.closing = this.visitJSXClosingFragment(n.closing); return n; } visitJSXClosingFragment(n) { return n; } visitJSXElementChildren(nodes) { return nodes.map(this.visitJSXElementChild.bind(this)); } visitJSXElementChild(n) { switch (n.type) { case "JSXElement": return this.visitJSXElement(n); case "JSXExpressionContainer": return this.visitJSXExpressionContainer(n); case "JSXFragment": return this.visitJSXFragment(n); case "JSXSpreadChild": return this.visitJSXSpreadChild(n); case "JSXText": return this.visitJSXText(n); } } visitJSXExpressionContainer(n) { n.expression = this.visitExpression(n.expression); return n; } visitJSXSpreadChild(n) { n.expression = this.visitExpression(n.expression); return n; } visitJSXOpeningFragment(n) { return n; } visitJSXEmptyExpression(n) { return n; } visitJSXElement(n) { n.opening = this.visitJSXOpeningElement(n.opening); n.children = this.visitJSXElementChildren(n.children); n.closing = this.visitJSXClosingElement(n.closing); return n; } visitJSXClosingElement(n) { if (n) { n.name = this.visitJSXElementName(n.name); } return n; } visitJSXElementName(n) { switch (n.type) { case "Identifier": return this.visitIdentifierReference(n); case "JSXMemberExpression": return this.visitJSXMemberExpression(n); case "JSXNamespacedName": return this.visitJSXNamespacedName(n); } } visitJSXOpeningElement(n) { n.name = this.visitJSXElementName(n.name); n.typeArguments = this.visitTsTypeParameterInstantiation(n.typeArguments); n.attrs = this.visitJSXAttributes(n.attrs); return n; } visitJSXAttributes(attrs) { if (attrs) return attrs.map(this.visitJSXAttributeOrSpread.bind(this)); } visitJSXAttributeOrSpread(n) { switch (n.type) { case "JSXAttribute": return this.visitJSXAttribute(n); case "SpreadElement": return this.visitSpreadElement(n); } } visitJSXAttribute(n) { n.name = this.visitJSXAttributeName(n.name); n.value = this.visitJSXAttributeValue(n.value); return n; } visitJSXAttributeValue(n) { if (!n) return n; switch (n.type) { case "BooleanLiteral": return this.visitBooleanLiteral(n); case "NullLiteral": return this.visitNullLiteral(n); case "NumericLiteral": return this.visitNumericLiteral(n); case "JSXText": return this.visitJSXText(n); case "StringLiteral": return this.visitStringLiteral(n); case "JSXElement": return this.visitJSXElement(n); case "JSXExpressionContainer": return this.visitJSXExpressionContainer(n); case "JSXFragment": return this.visitJSXFragment(n); } return n; } visitJSXAttributeName(n) { switch (n.type) { case "Identifier": return this.visitIdentifierReference(n); case "JSXNamespacedName": return this.visitJSXNamespacedName(n); } } visitConditionalExpression(n) { n.test = this.visitExpression(n.test); n.consequent = this.visitExpression(n.consequent); n.alternate = this.visitExpression(n.alternate); return n; } visitCallExpression(n) { n.callee = this.visitExpressionOrSuper(n.callee); n.typeArguments = this.visitTsTypeParameterInstantiation(n.typeArguments); if (n.arguments) { n.arguments = this.visitArguments(n.arguments); } return n; } visitBooleanLiteral(n) { return n; } visitBinaryExpression(n) { n.left = this.visitExpression(n.left); n.right = this.visitExpression(n.right); return n; } visitAwaitExpression(n) { n.argument = this.visitExpression(n.argument); return n; } visitTsTypeParameterDeclaration(n) { if (n) { n.parameters = this.visitTsTypeParameters(n.parameters); } return n; } visitTsTypeParameters(nodes) { return nodes.map(this.visitTsTypeParameter.bind(this)); } visitTsTypeParameter(n) { if (n.constraint) { n.constraint = this.visitTsType(n.constraint); } if (n.default) { n.default = this.visitTsType(n.default); } n.name = this.visitIdentifierReference(n.name); return n; } visitTsTypeAnnotation(a) { if (a) { a.typeAnnotation = this.visitTsType(a.typeAnnotation); } return a; } visitTsType(n) { throw new Error("Method visitTsType not implemented."); } visitPatterns(nodes) { return nodes.map(this.visitPattern.bind(this)); } visitImportDeclaration(n) { n.source = this.visitStringLiteral(n.source); n.specifiers = this.visitImportSpecifiers(n.specifiers || []); return n; } visitImportSpecifiers(nodes) { return nodes.map(this.visitImportSpecifier.bind(this)); } visitImportSpecifier(node) { switch (node.type) { case "ImportDefaultSpecifier": return this.visitImportDefaultSpecifier(node); case "ImportNamespaceSpecifier": return this.visitImportNamespaceSpecifier(node); case "ImportSpecifier": return this.visitNamedImportSpecifier(node); } } visitNamedImportSpecifier(node) { node.local = this.visitBindingIdentifier(node.local); if (node.imported) { node.imported = this.visitIdentifierReference(node.imported); } return node; } visitImportNamespaceSpecifier(node) { node.local = this.visitBindingIdentifier(node.local); return node; } visitImportDefaultSpecifier(node) { node.local = this.visitBindingIdentifier(node.local); return node; } visitBindingIdentifier(i) { return this.visitIdentifier(i); } visitIdentifierReference(i) { return this.visitIdentifier(i); } visitLabelIdentifier(label) { return this.visitIdentifier(label); } visitIdentifier(n) { return n; } visitStringLiteral(n) { return n; } visitNumericLiteral(n) { return n; } visitPattern(n) { switch (n.type) { case "Identifier": return this.visitBindingIdentifier(n); case "ArrayPattern": return this.visitArrayPattern(n); case "ObjectPattern": return this.visitObjectPattern(n); case "AssignmentPattern": return this.visitAssignmentPattern(n); case "RestElement": return this.visitRestElement(n); default: return this.visitExpression(n); } } visitRestElement(n) { n.argument = this.visitPattern(n.argument); n.typeAnnotation = this.visitTsTypeAnnotation(n.typeAnnotation); return n; } visitAssignmentPattern(n) { n.left = this.visitPattern(n.left); n.right = this.visitExpression(n.right); n.typeAnnotation = this.visitTsTypeAnnotation(n.typeAnnotation); return n; } visitObjectPattern(n) { n.props = this.visitObjectPatternProperties(n.props); n.typeAnnotation = this.visitTsTypeAnnotation(n.typeAnnotation); return n; } visitObjectPatternProperties(nodes) { return nodes.map(this.visitObjectPatternProperty.bind(this)); } visitObjectPatternProperty(n) { switch (n.type) { case "AssignmentPatternProperty": return this.visitAssignmentPatternProperty(n); case "KeyValuePatternProperty": return this.visitKeyValuePatternProperty(n); case "RestElement": return this.visitRestElement(n); } } visitKeyValuePatternProperty(n) { n.key = this.visitPropertyName(n.key); n.value = this.visitPattern(n.value); return n; } visitAssignmentPatternProperty(n) { n.key = this.visitBindingIdentifier(n.key); n.value = this.visitOptionalExpression(n.value); return n; } visitArrayPattern(n) { n.typeAnnotation = this.visitTsTypeAnnotation(n.typeAnnotation); n.elements = this.visitArrayPatternElements(n.elements); return n; } visitArrayPatternElements(nodes) { return nodes.map(this.visitArrayPatternElement.bind(this)); } visitArrayPatternElement(n) { if (n) { n = this.visitPattern(n); } return n; } }