diff --git a/koala-wrapper/src/arkts-api/visitor.ts b/koala-wrapper/src/arkts-api/visitor.ts index 3a76bf8404a5ecb303cac0db7b933874c9f8d9c0..6b3936debae7aaa6297332d8f2ed3058bd6f309b 100644 --- a/koala-wrapper/src/arkts-api/visitor.ts +++ b/koala-wrapper/src/arkts-api/visitor.ts @@ -54,6 +54,28 @@ import { isTSTypeAliasDeclaration, isETSParameterExpression, isETSFunctionType, + BlockExpression, + ETSNewClassInstanceExpression, + ArrayExpression, + ConditionalExpression, + TSAsExpression, + BinaryExpression, + ClassDeclaration, + TSInterfaceDeclaration, + TSTypeAliasDeclaration, + ClassDefinition, + TSInterfaceBody, + BlockStatement, + ReturnStatement, + TryStatement, + ForUpdateStatement, + ForInStatement, + ForOfStatement, + ScriptFunction, + ClassProperty, + TemplateLiteral, + ImportDeclaration, + ETSFunctionType, } from '../generated'; import { isEtsScript, @@ -71,8 +93,23 @@ import { isAssignmentExpression, isEtsParameterExpression, } from './factory/nodeTests'; -import { classDefinitionFlags } from './utilities/public'; +import { classDefinitionFlags, nodeType } from './utilities/public'; import { Es2pandaAstNodeType } from '../Es2pandaEnums'; +import { + ArrowFunctionExpression, + AssignmentExpression, + CallExpression, + ETSParameterExpression, + EtsScript, + ExpressionStatement, + FunctionDeclaration, + IfStatement, + MethodDefinition, + StructDeclaration, + VariableDeclaration, + VariableDeclarator, +} from './types'; +import { MemberExpression } from './to-be-generated/MemberExpression'; type Visitor = (node: AstNode) => AstNode; @@ -98,20 +135,26 @@ function nodesVisitor( let updated: boolean = false; export function visitEachChild(node: AstNode, visitor: Visitor): AstNode { - updated = false; - let script: AstNode = node; - script = visitETSModule(script, visitor); - script = visitDeclaration(script, visitor); - script = visitDefinition(script, visitor); - script = visitDefinitionBody(script, visitor); - script = visitStatement(script, visitor); - script = visitForLoopStatement(script, visitor); - script = visitOuterExpression(script, visitor); - script = visitInnerExpression(script, visitor); - script = visitTrivialExpression(script, visitor); - script = visitLiteral(script, visitor); - // TODO - return visitWithoutUpdate(script, visitor); + const type = nodeType(node); + if (visitorByType.has(type)) { + return visitorByType.get(type)!(node, visitor); + } + return node; + + // updated = false; + // let script: AstNode = node; + // script = visitETSModule(script, visitor); + // script = visitDeclaration(script, visitor); + // script = visitDefinition(script, visitor); + // script = visitDefinitionBody(script, visitor); + // script = visitStatement(script, visitor); + // script = visitForLoopStatement(script, visitor); + // script = visitOuterExpression(script, visitor); + // script = visitInnerExpression(script, visitor); + // script = visitTrivialExpression(script, visitor); + // script = visitLiteral(script, visitor); + // // TODO + // return visitWithoutUpdate(script, visitor); } function visitOuterExpression(node: AstNode, visitor: Visitor): AstNode { @@ -474,3 +517,310 @@ function visitWithoutUpdate(node: T, visitor: Visitor): T { } return node; } + +class VisitorFactory { + static visitBlockExpression(node: BlockExpression, visitor: Visitor): BlockExpression { + return factory.updateBlockExpression(node, nodesVisitor(node.statements, visitor)); + } + static visitCallExpression(node: CallExpression, visitor: Visitor): CallExpression { + const call = factory.updateCallExpression( + node, + nodeVisitor(node.expression, visitor), + nodesVisitor(node.typeArguments, visitor), + nodesVisitor(node.arguments, visitor) + ); + if (!!node.trailingBlock) { + call.setTralingBlock(nodeVisitor(node.trailingBlock, visitor)); + } + return call; + } + static visitArrowFunctionExpression(node: ArrowFunctionExpression, visitor: Visitor): ArrowFunctionExpression { + return factory.updateArrowFunction(node, nodeVisitor(node.scriptFunction, visitor)); + } + static visitAssignmentExpression(node: AssignmentExpression, visitor: Visitor): AssignmentExpression { + return factory.updateAssignmentExpression( + node, + nodeVisitor(node.left as Expression, visitor), + node.operatorType, + nodeVisitor(node.right as Expression, visitor) + ); + } + static visitETSNewClassInstanceExpression( + node: ETSNewClassInstanceExpression, + visitor: Visitor + ): ETSNewClassInstanceExpression { + return factory.updateETSNewClassInstanceExpression( + node, + node.getTypeRef, + nodesVisitor(node.getArguments, visitor) + ); + } + static visitArrayExpression(node: ArrayExpression, visitor: Visitor): ArrayExpression { + return factory.updateArrayExpression(node, nodesVisitor(node.elements, visitor)); + } + static visitMemberExpression(node: MemberExpression, visitor: Visitor): MemberExpression { + return factory.updateMemberExpression( + node, + nodeVisitor(node.object, visitor), + nodeVisitor(node.property, visitor), + node.kind, + node.computed, + node.optional + ); + } + static visitConditionalExpression(node: ConditionalExpression, visitor: Visitor): ConditionalExpression { + return factory.updateConditionalExpression( + node, + nodeVisitor(node.test, visitor), + nodeVisitor(node.consequent, visitor), + nodeVisitor(node.alternate, visitor) + ); + } + static visitTSAsExpression(node: TSAsExpression, visitor: Visitor): TSAsExpression { + return factory.updateTSAsExpression( + node, + nodeVisitor(node.expr, visitor), + nodeVisitor(node.typeAnnotation, visitor), + node.isConst + ); + } + static visitObjectExpression(node: ObjectExpression, visitor: Visitor): ObjectExpression { + return factory.updateObjectExpression( + node, + Es2pandaAstNodeType.AST_NODE_TYPE_OBJECT_EXPRESSION, + nodesVisitor(node.properties as Property[], visitor), + false + ); + } + static visitProperty(node: Property, visitor: Visitor): Property { + return factory.updateProperty(node, node.key, nodeVisitor(node.value, visitor)); + } + static visitBinaryExpression(node: BinaryExpression, visitor: Visitor): BinaryExpression { + return factory.updateBinaryExpression( + node, + nodeVisitor(node.left, visitor), + nodeVisitor(node.right, visitor), + node.operatorType + ); + } + static visitFunctionDeclaration(node: FunctionDeclaration, visitor: Visitor): FunctionDeclaration { + return factory.updateFunctionDeclaration( + node, + nodeVisitor(node.scriptFunction, visitor), + node.isAnon, + node.annotations + ); + } + static visitClassDeclaration(node: ClassDeclaration, visitor: Visitor): ClassDeclaration { + return factory.updateClassDeclaration(node, nodeVisitor(node.definition, visitor)); + } + static visitStructDeclaration(node: StructDeclaration, visitor: Visitor): StructDeclaration { + return factory.updateStructDeclaration(node, nodeVisitor(node.definition, visitor)); + } + static visitTSInterfaceDeclaration(node: TSInterfaceDeclaration, visitor: Visitor): TSInterfaceDeclaration { + return factory.updateInterfaceDeclaration( + node, + nodesVisitor(node.extends, visitor), + nodeVisitor(node.id, visitor), + nodeVisitor(node.typeParams, visitor), + nodeVisitor(node.body, visitor), + node.isStatic, + // TODO: how do I get it? + true + ); + } + static visitVariableDeclaration(node: VariableDeclaration, visitor: Visitor): VariableDeclaration { + return factory.updateVariableDeclaration( + node, + 0, + node.declarationKind, + nodesVisitor(node.declarators, visitor) + ); + } + static visitTSTypeAliasDeclaration(node: TSTypeAliasDeclaration, visitor: Visitor): TSTypeAliasDeclaration { + return factory.updateTSTypeAliasDeclaration( + node, + node.id, + nodeVisitor(node.typeParams, visitor), + nodeVisitor(node.typeAnnotation, visitor) + ); + } + static visitClassDefinition(node: ClassDefinition, visitor: Visitor): ClassDefinition { + return factory.updateClassDefinition( + node, + node.ident, + node.typeParams, + node.superTypeParams, + node.implements, + undefined, + node.super, + nodesVisitor(node.body, visitor), + node.modifiers, + classDefinitionFlags(node) + ); + } + static visitMethodDefinition(node: MethodDefinition, visitor: Visitor): MethodDefinition { + return factory.updateMethodDefinition( + node, + node.kind, + node.name, + nodeVisitor(node.scriptFunction, visitor), + node.modifiers, + false + ); + } + static visitTSInterfaceBody(node: TSInterfaceBody, visitor: Visitor): TSInterfaceBody { + return factory.updateInterfaceBody(node, nodesVisitor(node.body, visitor)); + } + static visitVariableDeclarator(node: VariableDeclarator, visitor: Visitor): VariableDeclarator { + return factory.updateVariableDeclarator( + node, + global.generatedEs2panda._VariableDeclaratorFlag(global.context, node.peer), + nodeVisitor(node.name, visitor), + nodeVisitor(node.initializer, visitor) + ); + } + static visitBlockStatement(node: BlockStatement, visitor: Visitor): BlockStatement { + return factory.updateBlock(node, nodesVisitor(node.statements, visitor)); + } + static visitExpressionStatement(node: ExpressionStatement, visitor: Visitor): ExpressionStatement { + return factory.updateExpressionStatement(node, nodeVisitor(node.expression, visitor)); + } + static visitIfStatement(node: IfStatement, visitor: Visitor): IfStatement { + return factory.updateIfStatement( + node, + nodeVisitor(node.test, visitor), + nodeVisitor(node.consequent, visitor), + nodeVisitor(node.alternate, visitor) + ); + } + static visitReturnStatement(node: ReturnStatement, visitor: Visitor): ReturnStatement { + return factory.updateReturnStatement(node, nodeVisitor(node.argument, visitor)); + } + static visitTryStatement(node: TryStatement, visitor: Visitor): TryStatement { + return factory.updateTryStatement( + node, + nodeVisitor(node.block, visitor), + nodesVisitor(node.catchClauses, visitor), + nodeVisitor(node.finallyBlock, visitor), + [], + [] + ); + } + static visitForUpdateStatement(node: ForUpdateStatement, visitor: Visitor): ForUpdateStatement { + return factory.updateForUpdateStatement( + node, + nodeVisitor(node.init, visitor), + nodeVisitor(node.test, visitor), + nodeVisitor(node.update, visitor), + nodeVisitor(node.body, visitor) + ); + } + static visitForInStatement(node: ForInStatement, visitor: Visitor): ForInStatement { + return factory.updateForInStatement( + node, + nodeVisitor(node.left, visitor), + nodeVisitor(node.right, visitor), + nodeVisitor(node.body, visitor) + ); + } + static visitForOfStatement(node: ForOfStatement, visitor: Visitor): ForOfStatement { + return factory.updateForOfStatement( + node, + nodeVisitor(node.left, visitor), + nodeVisitor(node.right, visitor), + nodeVisitor(node.body, visitor), + node.isAwait + ); + } + static visitETSModule(node: EtsScript, visitor: Visitor): EtsScript { + return factory.updateEtsScript(node, nodesVisitor(node.statements, visitor)); + } + static visitScriptFunction(node: ScriptFunction, visitor: Visitor): ScriptFunction { + return factory.updateScriptFunction( + node, + nodeVisitor(node.body, visitor), + factory.createFunctionSignature( + nodeVisitor(node.typeParams, visitor), + nodesVisitor(node.params, visitor), + nodeVisitor(node.returnTypeAnnotation, visitor), + node.hasReceiver + ), + node.flags, + node.modifiers + ); + } + static visitClassProperty(node: ClassProperty, visitor: Visitor): ClassProperty { + return factory.updateClassProperty( + node, + node.key, + nodeVisitor(node.value, visitor), + node.typeAnnotation, + node.modifiers, + node.isComputed + ); + } + static visitTemplateLiteral(node: TemplateLiteral, visitor: Visitor): TemplateLiteral { + return factory.updateTemplateLiteral( + node, + nodesVisitor(node.quasis, visitor), + nodesVisitor(node.expressions, visitor), + node.multilineString + ); + } + static visitImportDeclaration(node: ImportDeclaration, visitor: Visitor): ImportDeclaration { + nodesVisitor(node.specifiers, visitor); + return node; + } + static visitETSFunctionType(node: ETSFunctionType, visitor: Visitor): ETSFunctionType { + nodesVisitor(node.params, visitor); + return node; + } + static visitETSParameterExpression(node: ETSParameterExpression, visitor: Visitor): ETSParameterExpression { + nodeVisitor(node.type, visitor); + return node; + } +} + +const visitorByType = new Map AstNode>([ + [Es2pandaAstNodeType.AST_NODE_TYPE_BLOCK_EXPRESSION, VisitorFactory.visitBlockExpression], + [Es2pandaAstNodeType.AST_NODE_TYPE_CALL_EXPRESSION, VisitorFactory.visitCallExpression], + [Es2pandaAstNodeType.AST_NODE_TYPE_ARROW_FUNCTION_EXPRESSION, VisitorFactory.visitArrowFunctionExpression], + [Es2pandaAstNodeType.AST_NODE_TYPE_ASSIGNMENT_EXPRESSION, VisitorFactory.visitAssignmentExpression], + [ + Es2pandaAstNodeType.AST_NODE_TYPE_ETS_NEW_CLASS_INSTANCE_EXPRESSION, + VisitorFactory.visitETSNewClassInstanceExpression, + ], + [Es2pandaAstNodeType.AST_NODE_TYPE_ARRAY_EXPRESSION, VisitorFactory.visitArrayExpression], + [Es2pandaAstNodeType.AST_NODE_TYPE_MEMBER_EXPRESSION, VisitorFactory.visitMemberExpression], + [Es2pandaAstNodeType.AST_NODE_TYPE_CONDITIONAL_EXPRESSION, VisitorFactory.visitConditionalExpression], + [Es2pandaAstNodeType.AST_NODE_TYPE_TS_AS_EXPRESSION, VisitorFactory.visitTSAsExpression], + [Es2pandaAstNodeType.AST_NODE_TYPE_OBJECT_EXPRESSION, VisitorFactory.visitObjectExpression], + [Es2pandaAstNodeType.AST_NODE_TYPE_PROPERTY, VisitorFactory.visitProperty], + [Es2pandaAstNodeType.AST_NODE_TYPE_BINARY_EXPRESSION, VisitorFactory.visitBinaryExpression], + [Es2pandaAstNodeType.AST_NODE_TYPE_FUNCTION_DECLARATION, VisitorFactory.visitFunctionDeclaration], + [Es2pandaAstNodeType.AST_NODE_TYPE_CLASS_DECLARATION, VisitorFactory.visitClassDeclaration], + [Es2pandaAstNodeType.AST_NODE_TYPE_STRUCT_DECLARATION, VisitorFactory.visitStructDeclaration], + [Es2pandaAstNodeType.AST_NODE_TYPE_TS_INTERFACE_DECLARATION, VisitorFactory.visitTSInterfaceDeclaration], + [Es2pandaAstNodeType.AST_NODE_TYPE_VARIABLE_DECLARATION, VisitorFactory.visitVariableDeclaration], + [Es2pandaAstNodeType.AST_NODE_TYPE_TS_TYPE_ALIAS_DECLARATION, VisitorFactory.visitTSTypeAliasDeclaration], + [Es2pandaAstNodeType.AST_NODE_TYPE_CLASS_DEFINITION, VisitorFactory.visitClassDefinition], + [Es2pandaAstNodeType.AST_NODE_TYPE_METHOD_DEFINITION, VisitorFactory.visitMethodDefinition], + [Es2pandaAstNodeType.AST_NODE_TYPE_TS_INTERFACE_BODY, VisitorFactory.visitTSInterfaceBody], + [Es2pandaAstNodeType.AST_NODE_TYPE_VARIABLE_DECLARATOR, VisitorFactory.visitVariableDeclarator], + [Es2pandaAstNodeType.AST_NODE_TYPE_BLOCK_STATEMENT, VisitorFactory.visitBlockStatement], + [Es2pandaAstNodeType.AST_NODE_TYPE_EXPRESSION_STATEMENT, VisitorFactory.visitExpressionStatement], + [Es2pandaAstNodeType.AST_NODE_TYPE_IF_STATEMENT, VisitorFactory.visitIfStatement], + [Es2pandaAstNodeType.AST_NODE_TYPE_RETURN_STATEMENT, VisitorFactory.visitReturnStatement], + [Es2pandaAstNodeType.AST_NODE_TYPE_TRY_STATEMENT, VisitorFactory.visitTryStatement], + [Es2pandaAstNodeType.AST_NODE_TYPE_FOR_UPDATE_STATEMENT, VisitorFactory.visitForUpdateStatement], + [Es2pandaAstNodeType.AST_NODE_TYPE_FOR_IN_STATEMENT, VisitorFactory.visitForInStatement], + [Es2pandaAstNodeType.AST_NODE_TYPE_FOR_OF_STATEMENT, VisitorFactory.visitForOfStatement], + [Es2pandaAstNodeType.AST_NODE_TYPE_ETS_MODULE, VisitorFactory.visitETSModule], + [Es2pandaAstNodeType.AST_NODE_TYPE_SCRIPT_FUNCTION, VisitorFactory.visitScriptFunction], + [Es2pandaAstNodeType.AST_NODE_TYPE_CLASS_PROPERTY, VisitorFactory.visitClassProperty], + [Es2pandaAstNodeType.AST_NODE_TYPE_TEMPLATE_LITERAL, VisitorFactory.visitTemplateLiteral], + [Es2pandaAstNodeType.AST_NODE_TYPE_IMPORT_DECLARATION, VisitorFactory.visitImportDeclaration], + [Es2pandaAstNodeType.AST_NODE_TYPE_ETS_FUNCTION_TYPE, VisitorFactory.visitETSFunctionType], + [Es2pandaAstNodeType.AST_NODE_TYPE_ETS_PARAMETER_EXPRESSION, VisitorFactory.visitETSParameterExpression], +]);