import { fail } from '../common/debug' ; import { ArgumentNode , ArrowCallableNode , AssertNode , AssignmentExpressionNode , AssignmentNode , AugmentedAssignmentNode , AwaitNode , BinaryOperationNode , BreakNode , CallNode , CaseNode , ClassNode , ConstantNode , ContinueNode , DecoratorNode , DelNode , DictionaryExpandEntryNode , DictionaryKeyEntryNode , DictionaryNode , EllipsisNode , ErrorNode , ExceptNode , FormatStringNode , ForNode , FunctionAnnotationNode , FunctionNode , GlobalNode , IfNode , ImportAsNode , ImportFromAsNode , ImportFromNode , ImportNode , IndexNode , LambdaNode , ListComprehensionForNode , ListComprehensionIfNode , ListComprehensionNode , ListNode , MatchNode , MemberAccessNode , ModuleNameNode , ModuleNode , NameNode , NonlocalNode , NumberNode , ParameterNode , ParseNode , ParseNodeArray , ParseNodeType , PassNode , PatternAsNode , PatternCaptureNode , PatternClassArgumentNode , PatternClassNode , PatternLiteralNode , PatternMappingExpandEntryNode , PatternMappingKeyEntryNode , PatternMappingNode , PatternSequenceNode , PatternValueNode , RaiseNode , ReturnNode , SetNode , SliceNode , StatementListNode , StringListNode , StringNode , SuiteNode , TernaryNode , TryNode , TupleNode , TypeAnnotationNode , UnaryOperationNode , UnpackNode , WhileNode , WithItemNode , WithNode , YieldFromNode , YieldNode , } from '../parser/parseNodes' ; export class ParseTreeWalker { walk ( node ) { const childrenToWalk = this . visitNode ( node ) ; if ( childrenToWalk . length > 0 ) { this . walkMultiple ( childrenToWalk ) ; } } walkMultiple ( nodes ) { nodes . forEach ( ( node ) => { if ( node ) { this . walk ( node ) ; } } ) ; } visitNode ( node ) { switch ( node . nodeType ) { case ParseNodeType . Error : if ( this . visitError ( node ) ) { return [ node . child , ... ( node . decorators ?? [ ] ) ] ; } break ; case ParseNodeType . Argument : if ( this . visitArgument ( node ) ) { return [ node . name , node . valueExpression ] ; } break ; case ParseNodeType . Assert : if ( this . visitAssert ( node ) ) { return [ node . testExpression , node . exceptionExpression ] ; } break ; case ParseNodeType . Assignment : if ( this . visitAssignment ( node ) ) { return [ node . leftExpression , node . rightExpression , node . typeAnnotationComment ] ; } break ; case ParseNodeType . AssignmentExpression : if ( this . visitAssignmentExpression ( node ) ) { return [ node . name , node . rightExpression ] ; } break ; case ParseNodeType . AugmentedAssignment : if ( this . visitAugmentedAssignment ( node ) ) { return [ node . leftExpression , node . rightExpression ] ; } break ; case ParseNodeType . Await : if ( this . visitAwait ( node ) ) { return [ node . expression ] ; } break ; case ParseNodeType . BinaryOperation : if ( this . visitBinaryOperation ( node ) ) { return [ node . leftExpression , node . rightExpression ] ; } break ; case ParseNodeType . Break : if ( this . visitBreak ( node ) ) { return [ ] ; } break ; case ParseNodeType . Call : if ( this . visitCall ( node ) ) { return [ node . leftExpression , ... node . arguments ] ; } break ; case ParseNodeType . Class : if ( this . visitClass ( node ) ) { return [ ... node . decorators , node . name , ... node . arguments , node . suite ] ; } break ; case ParseNodeType . Constant : if ( this . visitConstant ( node ) ) { return [ ] ; } break ; case ParseNodeType . Continue : if ( this . visitContinue ( node ) ) { return [ ] ; } break ; case ParseNodeType . Decorator : if ( this . visitDecorator ( node ) ) { return [ node . expression ] ; } break ; case ParseNodeType . Del : if ( this . visitDel ( node ) ) { return node . expressions ; } break ; case ParseNodeType . Dictionary : if ( this . visitDictionary ( node ) ) { return node . entries ; } break ; case ParseNodeType . DictionaryExpandEntry : if ( this . visitDictionaryExpandEntry ( node ) ) { return [ node . expandExpression ] ; } break ; case ParseNodeType . DictionaryKeyEntry : if ( this . visitDictionaryKeyEntry ( node ) ) { return [ node . keyExpression , node . valueExpression ] ; } break ; case ParseNodeType . Ellipsis : if ( this . visitEllipsis ( node ) ) { return [ ] ; } break ; case ParseNodeType . If : if ( this . visitIf ( node ) ) { return [ node . testExpression , node . ifSuite , node . elseSuite ] ; } break ; case ParseNodeType . Import : if ( this . visitImport ( node ) ) { return node . list ; } break ; case ParseNodeType . ImportAs : if ( this . visitImportAs ( node ) ) { return [ node . module , node . alias ] ; } break ; case ParseNodeType . ImportFrom : if ( this . visitImportFrom ( node ) ) { return [ node . module , ... node . imports ] ; } break ; case ParseNodeType . ImportFromAs : if ( this . visitImportFromAs ( node ) ) { return [ node . name , node . alias ] ; } break ; case ParseNodeType . Index : if ( this . visitIndex ( node ) ) { return [ node . baseExpression , ... node . items ] ; } break ; case ParseNodeType . Except : if ( this . visitExcept ( node ) ) { return [ node . typeExpression , node . name , node . exceptSuite ] ; } break ; case ParseNodeType . For : if ( this . visitFor ( node ) ) { return [ node . targetExpression , node . iterableExpression , node . forSuite , node . elseSuite ] ; } break ; case ParseNodeType . FormatString : if ( this . visitFormatString ( node ) ) { return node . expressions ; } break ; case ParseNodeType . Function : if ( this . visitFunction ( node ) ) { return [ ... node . decorators , node . name , ... node . parameters , node . returnTypeAnnotation , node . functionAnnotationComment , node . suite , ] ; } break ; case ParseNodeType . Global : if ( this . visitGlobal ( node ) ) { return node . nameList ; } break ; case ParseNodeType . Lambda : if ( this . visitLambda ( node ) ) { return [ ... node . parameters , node . expression ] ; } break ; case ParseNodeType . List : if ( this . visitList ( node ) ) { return node . entries ; } break ; case ParseNodeType . ListComprehension : if ( this . visitListComprehension ( node ) ) { return [ node . expression , ... node . comprehensions ] ; } break ; case ParseNodeType . ListComprehensionFor : if ( this . visitListComprehensionFor ( node ) ) { return [ node . targetExpression , node . iterableExpression ] ; } break ; case ParseNodeType . ListComprehensionIf : if ( this . visitListComprehensionIf ( node ) ) { return [ node . testExpression ] ; } break ; case ParseNodeType . MemberAccess : if ( this . visitMemberAccess ( node ) ) { return [ node . leftExpression , node . memberName ] ; } break ; case ParseNodeType . Module : if ( this . visitModule ( node ) ) { return [ ... node . statements ] ; } break ; case ParseNodeType . ModuleName : if ( this . visitModuleName ( node ) ) { return node . nameParts ; } break ; case ParseNodeType . Name : if ( this . visitName ( node ) ) { return [ ] ; } break ; case ParseNodeType . Nonlocal : if ( this . visitNonlocal ( node ) ) { return node . nameList ; } break ; case ParseNodeType . Number : if ( this . visitNumber ( node ) ) { return [ ] ; } break ; case ParseNodeType . Parameter : if ( this . visitParameter ( node ) ) { return [ node . name , node . typeAnnotation , node . typeAnnotationComment , node . defaultValue ] ; } break ; case ParseNodeType . Pass : if ( this . visitPass ( node ) ) { return [ ] ; } break ; case ParseNodeType . Raise : if ( this . visitRaise ( node ) ) { return [ node . typeExpression , node . valueExpression , node . tracebackExpression ] ; } break ; case ParseNodeType . Return : if ( this . visitReturn ( node ) ) { return [ node . returnExpression ] ; } break ; case ParseNodeType . Set : if ( this . visitSet ( node ) ) { return node . entries ; } break ; case ParseNodeType . Slice : if ( this . visitSlice ( node ) ) { return [ node . startValue , node . endValue , node . stepValue ] ; } break ; case ParseNodeType . StatementList : if ( this . visitStatementList ( node ) ) { return node . statements ; } break ; case ParseNodeType . StringList : if ( this . visitStringList ( node ) ) { return [ node . typeAnnotation , ... node . strings ] ; } break ; case ParseNodeType . String : if ( this . visitString ( node ) ) { return [ ] ; } break ; case ParseNodeType . Suite : if ( this . visitSuite ( node ) ) { return [ ... node . statements ] ; } break ; case ParseNodeType . Ternary : if ( this . visitTernary ( node ) ) { return [ node . ifExpression , node . testExpression , node . elseExpression ] ; } break ; case ParseNodeType . Tuple : if ( this . visitTuple ( node ) ) { return node . expressions ; } break ; case ParseNodeType . Try : if ( this . visitTry ( node ) ) { return [ node . trySuite , ... node . exceptClauses , node . elseSuite , node . finallySuite ] ; } break ; case ParseNodeType . TypeAnnotation : if ( this . visitTypeAnnotation ( node ) ) { return [ node . valueExpression , node . typeAnnotation ] ; } break ; case ParseNodeType . UnaryOperation : if ( this . visitUnaryOperation ( node ) ) { return [ node . expression ] ; } break ; case ParseNodeType . Unpack : if ( this . visitUnpack ( node ) ) { return [ node . expression ] ; } break ; case ParseNodeType . While : if ( this . visitWhile ( node ) ) { return [ node . testExpression , node . whileSuite , node . elseSuite ] ; } break ; case ParseNodeType . With : if ( this . visitWith ( node ) ) { return [ ... node . withItems , node . suite ] ; } break ; case ParseNodeType . WithItem : if ( this . visitWithItem ( node ) ) { return [ node . expression , node . target ] ; } break ; case ParseNodeType . Yield : if ( this . visitYield ( node ) ) { return [ node . expression ] ; } break ; case ParseNodeType . YieldFrom : if ( this . visitYieldFrom ( node ) ) { return [ node . expression ] ; } break ; case ParseNodeType . FunctionAnnotation : if ( this . visitFunctionAnnotation ( node ) ) { return [ ... node . paramTypeAnnotations , node . returnTypeAnnotation ] ; } break ; case ParseNodeType . Match : if ( this . visitMatch ( node ) ) { return [ node . subjectExpression , ... node . cases ] ; } break ; case ParseNodeType . Case : if ( this . visitCase ( node ) ) { return [ node . pattern , node . guardExpression , node . suite ] ; } break ; case ParseNodeType . PatternSequence : if ( this . visitPatternSequence ( node ) ) { return [ ... node . entries ] ; } break ; case ParseNodeType . PatternAs : if ( this . visitPatternAs ( node ) ) { return [ ... node . orPatterns , node . target ] ; } break ; case ParseNodeType . PatternLiteral : if ( this . visitPatternLiteral ( node ) ) { return [ node . expression ] ; } break ; case ParseNodeType . PatternClass : if ( this . visitPatternClass ( node ) ) { return [ node . className , ... node . arguments ] ; } break ; case ParseNodeType . PatternCapture : if ( this . visitPatternCapture ( node ) ) { return [ node . target ] ; } break ; case ParseNodeType . PatternMapping : if ( this . visitPatternMapping ( node ) ) { return [ ... node . entries ] ; } break ; case ParseNodeType . PatternMappingKeyEntry : if ( this . visitPatternMappingKeyEntry ( node ) ) { return [ node . keyPattern , node . valuePattern ] ; } break ; case ParseNodeType . PatternMappingExpandEntry : if ( this . visitPatternMappingExpandEntry ( node ) ) { return [ node . target ] ; } break ; case ParseNodeType . PatternValue : if ( this . visitPatternValue ( node ) ) { return [ node . expression ] ; } break ; case ParseNodeType . PatternClassArgument : if ( this . visitPatternClassArgument ( node ) ) { return [ node . name , node . pattern ] ; } break ; case ParseNodeType . ArrowCallable : if ( this . visitArrowCallable ( node ) ) { return [ ... node . parameters . map ( ( param ) => param . typeAnnotation ) , node . returnTypeAnnotation ] ; } break ; default : fail ( 'Unexpected node type' ) ; break ; } return [ ] ; } visitArgument ( node ) { return true ; } visitArrowCallable ( node ) { return true ; } visitAssert ( node ) { return true ; } visitAssignment ( node ) { return true ; } visitAssignmentExpression ( node ) { return true ; } visitAugmentedAssignment ( node ) { return true ; } visitAwait ( node ) { return true ; } visitBinaryOperation ( node ) { return true ; } visitBreak ( node ) { return true ; } visitCall ( node ) { return true ; } visitCase ( node ) { return true ; } visitClass ( node ) { return true ; } visitTernary ( node ) { return true ; } visitContinue ( node ) { return true ; } visitConstant ( node ) { return true ; } visitDecorator ( node ) { return true ; } visitDel ( node ) { return true ; } visitDictionary ( node ) { return true ; } visitDictionaryKeyEntry ( node ) { return true ; } visitDictionaryExpandEntry ( node ) { return true ; } visitError ( node ) { return true ; } visitEllipsis ( node ) { return true ; } visitIf ( node ) { return true ; } visitImport ( node ) { return true ; } visitImportAs ( node ) { return true ; } visitImportFrom ( node ) { return true ; } visitImportFromAs ( node ) { return true ; } visitIndex ( node ) { return true ; } visitExcept ( node ) { return true ; } visitFor ( node ) { return true ; } visitFormatString ( node ) { return true ; } visitFunction ( node ) { return true ; } visitFunctionAnnotation ( node ) { return true ; } visitGlobal ( node ) { return true ; } visitLambda ( node ) { return true ; } visitList ( node ) { return true ; } visitListComprehension ( node ) { return true ; } visitListComprehensionFor ( node ) { return true ; } visitListComprehensionIf ( node ) { return true ; } visitMatch ( node ) { return true ; } visitMemberAccess ( node ) { return true ; } visitModule ( node ) { return true ; } visitModuleName ( node ) { return true ; } visitName ( node ) { return true ; } visitNonlocal ( node ) { return true ; } visitNumber ( node ) { return true ; } visitParameter ( node ) { return true ; } visitPass ( node ) { return true ; } visitPatternCapture ( node ) { return true ; } visitPatternClass ( node ) { return true ; } visitPatternClassArgument ( node ) { return true ; } visitPatternAs ( node ) { return true ; } visitPatternLiteral ( node ) { return true ; } visitPatternMappingExpandEntry ( node ) { return true ; } visitPatternSequence ( node ) { return true ; } visitPatternValue ( node ) { return true ; } visitPatternMappingKeyEntry ( node ) { return true ; } visitPatternMapping ( node ) { return true ; } visitRaise ( node ) { return true ; } visitReturn ( node ) { return true ; } visitSet ( node ) { return true ; } visitSlice ( node ) { return true ; } visitStatementList ( node ) { return true ; } visitString ( node ) { return true ; } visitStringList ( node ) { return true ; } visitSuite ( node ) { return true ; } visitTuple ( node ) { return true ; } visitTry ( node ) { return true ; } visitTypeAnnotation ( node ) { return true ; } visitUnaryOperation ( node ) { return true ; } visitUnpack ( node ) { return true ; } visitWhile ( node ) { return true ; } visitWith ( node ) { return true ; } visitWithItem ( node ) { return true ; } visitYield ( node ) { return true ; } visitYieldFrom ( node ) { return true ; } }