| 1 |  |  | <?php | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3 |  |  | declare(strict_types=1); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 5 |  |  | namespace GraphQL\Language; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 6 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 7 |  |  | use ArrayObject; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 8 |  |  | use Exception; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 9 |  |  | use GraphQL\Language\AST\Node; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 10 |  |  | use GraphQL\Language\AST\NodeKind; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 11 |  |  | use GraphQL\Language\AST\NodeList; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 12 |  |  | use GraphQL\Utils\TypeInfo; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 13 |  |  | use SplFixedArray; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 14 |  |  | use stdClass; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 15 |  |  | use function array_pop; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 16 |  |  | use function array_splice; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 17 |  |  | use function call_user_func; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 18 |  |  | use function call_user_func_array; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 19 |  |  | use function count; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 20 |  |  | use function func_get_args; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 21 |  |  | use function is_array; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 22 |  |  | use function is_callable; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 23 |  |  | use function json_encode; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 24 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 25 |  |  | /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 26 |  |  |  * Utility for efficient AST traversal and modification. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 27 |  |  |  * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 28 |  |  |  * `visit()` will walk through an AST using a depth first traversal, calling | 
            
                                                                                                            
                            
            
                                    
            
            
                | 29 |  |  |  * the visitor's enter function at each node in the traversal, and calling the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 30 |  |  |  * leave function after visiting that node and all of it's child nodes. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 31 |  |  |  * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 32 |  |  |  * By returning different values from the enter and leave functions, the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 33 |  |  |  * behavior of the visitor can be altered, including skipping over a sub-tree of | 
            
                                                                                                            
                            
            
                                    
            
            
                | 34 |  |  |  * the AST (by returning false), editing the AST by returning a value or null | 
            
                                                                                                            
                            
            
                                    
            
            
                | 35 |  |  |  * to remove the value, or to stop the whole traversal by returning BREAK. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 36 |  |  |  * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 37 |  |  |  * When using `visit()` to edit an AST, the original AST will not be modified, and | 
            
                                                                                                            
                            
            
                                    
            
            
                | 38 |  |  |  * a new version of the AST with the changes applied will be returned from the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 39 |  |  |  * visit function. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 40 |  |  |  * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 41 |  |  |  *     $editedAST = Visitor::visit($ast, [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 42 |  |  |  *       'enter' => function ($node, $key, $parent, $path, $ancestors) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 43 |  |  |  *         // return | 
            
                                                                                                            
                            
            
                                    
            
            
                | 44 |  |  |  *         //   null: no action | 
            
                                                                                                            
                            
            
                                    
            
            
                | 45 |  |  |  *         //   Visitor::skipNode(): skip visiting this node | 
            
                                                                                                            
                            
            
                                    
            
            
                | 46 |  |  |  *         //   Visitor::stop(): stop visiting altogether | 
            
                                                                                                            
                            
            
                                    
            
            
                | 47 |  |  |  *         //   Visitor::removeNode(): delete this node | 
            
                                                                                                            
                            
            
                                    
            
            
                | 48 |  |  |  *         //   any value: replace this node with the returned value | 
            
                                                                                                            
                            
            
                                    
            
            
                | 49 |  |  |  *       }, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 50 |  |  |  *       'leave' => function ($node, $key, $parent, $path, $ancestors) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 51 |  |  |  *         // return | 
            
                                                                                                            
                            
            
                                    
            
            
                | 52 |  |  |  *         //   null: no action | 
            
                                                                                                            
                            
            
                                    
            
            
                | 53 |  |  |  *         //   Visitor::stop(): stop visiting altogether | 
            
                                                                                                            
                            
            
                                    
            
            
                | 54 |  |  |  *         //   Visitor::removeNode(): delete this node | 
            
                                                                                                            
                            
            
                                    
            
            
                | 55 |  |  |  *         //   any value: replace this node with the returned value | 
            
                                                                                                            
                            
            
                                    
            
            
                | 56 |  |  |  *       } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 57 |  |  |  *     ]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 58 |  |  |  * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 59 |  |  |  * Alternatively to providing enter() and leave() functions, a visitor can | 
            
                                                                                                            
                            
            
                                    
            
            
                | 60 |  |  |  * instead provide functions named the same as the [kinds of AST nodes](reference.md#graphqllanguageastnodekind), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 61 |  |  |  * or enter/leave visitors at a named key, leading to four permutations of | 
            
                                                                                                            
                            
            
                                    
            
            
                | 62 |  |  |  * visitor API: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 63 |  |  |  * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 64 |  |  |  * 1) Named visitors triggered when entering a node a specific kind. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 65 |  |  |  * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 66 |  |  |  *     Visitor::visit($ast, [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 67 |  |  |  *       'Kind' => function ($node) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 68 |  |  |  *         // enter the "Kind" node | 
            
                                                                                                            
                            
            
                                    
            
            
                | 69 |  |  |  *       } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 70 |  |  |  *     ]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 71 |  |  |  * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 72 |  |  |  * 2) Named visitors that trigger upon entering and leaving a node of | 
            
                                                                                                            
                            
            
                                    
            
            
                | 73 |  |  |  *    a specific kind. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 74 |  |  |  * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 75 |  |  |  *     Visitor::visit($ast, [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 76 |  |  |  *       'Kind' => [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 77 |  |  |  *         'enter' => function ($node) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 78 |  |  |  *           // enter the "Kind" node | 
            
                                                                                                            
                            
            
                                    
            
            
                | 79 |  |  |  *         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 80 |  |  |  *         'leave' => function ($node) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 81 |  |  |  *           // leave the "Kind" node | 
            
                                                                                                            
                            
            
                                    
            
            
                | 82 |  |  |  *         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 83 |  |  |  *       ] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 84 |  |  |  *     ]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 85 |  |  |  * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 86 |  |  |  * 3) Generic visitors that trigger upon entering and leaving any node. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 87 |  |  |  * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 88 |  |  |  *     Visitor::visit($ast, [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 89 |  |  |  *       'enter' => function ($node) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 90 |  |  |  *         // enter any node | 
            
                                                                                                            
                            
            
                                    
            
            
                | 91 |  |  |  *       }, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 92 |  |  |  *       'leave' => function ($node) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 93 |  |  |  *         // leave any node | 
            
                                                                                                            
                            
            
                                    
            
            
                | 94 |  |  |  *       } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 95 |  |  |  *     ]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 96 |  |  |  * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 97 |  |  |  * 4) Parallel visitors for entering and leaving nodes of a specific kind. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 98 |  |  |  * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 99 |  |  |  *     Visitor::visit($ast, [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 100 |  |  |  *       'enter' => [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 101 |  |  |  *         'Kind' => function($node) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 102 |  |  |  *           // enter the "Kind" node | 
            
                                                                                                            
                            
            
                                    
            
            
                | 103 |  |  |  *         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 104 |  |  |  *       }, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 105 |  |  |  *       'leave' => [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 106 |  |  |  *         'Kind' => function ($node) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 107 |  |  |  *           // leave the "Kind" node | 
            
                                                                                                            
                            
            
                                    
            
            
                | 108 |  |  |  *         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 109 |  |  |  *       ] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 110 |  |  |  *     ]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 111 |  |  |  */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 112 |  |  | class Visitor | 
            
                                                                                                            
                            
            
                                    
            
            
                | 113 |  |  | { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 114 |  |  |     /** @var string[][] */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 115 |  |  |     public static $visitorKeys = [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 116 |  |  |         NodeKind::NAME                 => [], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 117 |  |  |         NodeKind::DOCUMENT             => ['definitions'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 118 |  |  |         NodeKind::OPERATION_DEFINITION => ['name', 'variableDefinitions', 'directives', 'selectionSet'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 119 |  |  |         NodeKind::VARIABLE_DEFINITION  => ['variable', 'type', 'defaultValue', 'directives'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 120 |  |  |         NodeKind::VARIABLE             => ['name'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 121 |  |  |         NodeKind::SELECTION_SET        => ['selections'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 122 |  |  |         NodeKind::FIELD                => ['alias', 'name', 'arguments', 'directives', 'selectionSet'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 123 |  |  |         NodeKind::ARGUMENT             => ['name', 'value'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 124 |  |  |         NodeKind::FRAGMENT_SPREAD      => ['name', 'directives'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 125 |  |  |         NodeKind::INLINE_FRAGMENT      => ['typeCondition', 'directives', 'selectionSet'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 126 |  |  |         NodeKind::FRAGMENT_DEFINITION  => [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 127 |  |  |             'name', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 128 |  |  |             // Note: fragment variable definitions are experimental and may be changed | 
            
                                                                                                            
                            
            
                                    
            
            
                | 129 |  |  |             // or removed in the future. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 130 |  |  |             'variableDefinitions', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 131 |  |  |             'typeCondition', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 132 |  |  |             'directives', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 133 |  |  |             'selectionSet', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 134 |  |  |         ], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 135 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 136 |  |  |         NodeKind::INT           => [], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 137 |  |  |         NodeKind::FLOAT         => [], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 138 |  |  |         NodeKind::STRING        => [], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 139 |  |  |         NodeKind::BOOLEAN       => [], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 140 |  |  |         NodeKind::NULL          => [], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 141 |  |  |         NodeKind::ENUM          => [], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 142 |  |  |         NodeKind::LST           => ['values'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 143 |  |  |         NodeKind::OBJECT        => ['fields'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 144 |  |  |         NodeKind::OBJECT_FIELD  => ['name', 'value'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 145 |  |  |         NodeKind::DIRECTIVE     => ['name', 'arguments'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 146 |  |  |         NodeKind::NAMED_TYPE    => ['name'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 147 |  |  |         NodeKind::LIST_TYPE     => ['type'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 148 |  |  |         NodeKind::NON_NULL_TYPE => ['type'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 149 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 150 |  |  |         NodeKind::SCHEMA_DEFINITION            => ['directives', 'operationTypes'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 151 |  |  |         NodeKind::OPERATION_TYPE_DEFINITION    => ['type'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 152 |  |  |         NodeKind::SCALAR_TYPE_DEFINITION       => ['description', 'name', 'directives'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 153 |  |  |         NodeKind::OBJECT_TYPE_DEFINITION       => ['description', 'name', 'interfaces', 'directives', 'fields'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 154 |  |  |         NodeKind::FIELD_DEFINITION             => ['description', 'name', 'arguments', 'type', 'directives'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 155 |  |  |         NodeKind::INPUT_VALUE_DEFINITION       => ['description', 'name', 'type', 'defaultValue', 'directives'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 156 |  |  |         NodeKind::INTERFACE_TYPE_DEFINITION    => ['description', 'name', 'directives', 'fields'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 157 |  |  |         NodeKind::UNION_TYPE_DEFINITION        => ['description', 'name', 'directives', 'types'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 158 |  |  |         NodeKind::ENUM_TYPE_DEFINITION         => ['description', 'name', 'directives', 'values'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 159 |  |  |         NodeKind::ENUM_VALUE_DEFINITION        => ['description', 'name', 'directives'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 160 |  |  |         NodeKind::INPUT_OBJECT_TYPE_DEFINITION => ['description', 'name', 'directives', 'fields'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 161 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 162 |  |  |         NodeKind::SCALAR_TYPE_EXTENSION       => ['name', 'directives'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 163 |  |  |         NodeKind::OBJECT_TYPE_EXTENSION       => ['name', 'interfaces', 'directives', 'fields'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 164 |  |  |         NodeKind::INTERFACE_TYPE_EXTENSION    => ['name', 'directives', 'fields'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 165 |  |  |         NodeKind::UNION_TYPE_EXTENSION        => ['name', 'directives', 'types'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 166 |  |  |         NodeKind::ENUM_TYPE_EXTENSION         => ['name', 'directives', 'values'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 167 |  |  |         NodeKind::INPUT_OBJECT_TYPE_EXTENSION => ['name', 'directives', 'fields'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 168 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 169 |  |  |         NodeKind::DIRECTIVE_DEFINITION => ['description', 'name', 'arguments', 'locations'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 170 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 171 |  |  |         NodeKind::SCHEMA_EXTENSION => ['directives', 'operationTypes'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 172 |  |  |     ]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 173 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 174 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 175 |  |  |      * Visit the AST (see class description for details) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 176 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 177 |  |  |      * @param Node|ArrayObject|stdClass $root | 
            
                                                                                                            
                            
            
                                    
            
            
                | 178 |  |  |      * @param callable[]                $visitor | 
            
                                                                                                            
                            
            
                                    
            
            
                | 179 |  |  |      * @param mixed[]|null              $keyMap | 
            
                                                                                                            
                            
            
                                    
            
            
                | 180 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 181 |  |  |      * @return Node|mixed | 
            
                                                                                                            
                            
            
                                    
            
            
                | 182 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 183 |  |  |      * @throws Exception | 
            
                                                                                                            
                            
            
                                    
            
            
                | 184 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 185 |  |  |      * @api | 
            
                                                                                                            
                            
            
                                    
            
            
                | 186 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 187 | 775 |  |     public static function visit($root, $visitor, $keyMap = null) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 188 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 189 | 775 |  |         $visitorKeys = $keyMap ?: self::$visitorKeys; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 190 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 191 | 775 |  |         $stack     = null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 192 | 775 |  |         $inArray   = $root instanceof NodeList || is_array($root); | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 193 | 775 |  |         $keys      = [$root]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 194 | 775 |  |         $index     = -1; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 195 | 775 |  |         $edits     = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 196 | 775 |  |         $parent    = null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 197 | 775 |  |         $path      = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 198 | 775 |  |         $ancestors = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 199 | 775 |  |         $newRoot   = $root; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 200 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 201 | 775 |  |         $UNDEFINED = null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 202 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 203 |  |  |         do { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 204 | 775 |  |             $index++; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 205 | 775 |  |             $isLeaving = $index === count($keys); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 206 | 775 |  |             $key       = null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 207 | 775 |  |             $node      = null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 208 | 775 |  |             $isEdited  = $isLeaving && count($edits) !== 0; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 209 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 210 | 775 |  |             if ($isLeaving) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 211 | 773 |  |                 $key    = ! $ancestors ? $UNDEFINED : $path[count($path) - 1]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 212 | 773 |  |                 $node   = $parent; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 213 | 773 |  |                 $parent = array_pop($ancestors); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 214 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 215 | 773 |  |                 if ($isEdited) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 216 | 146 |  |                     if ($inArray) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 217 |  |  |                         // $node = $node; // arrays are value types in PHP | 
            
                                                                                                            
                            
            
                                    
            
            
                | 218 | 138 |  |                         if ($node instanceof NodeList) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 219 | 138 |  |                             $node = clone $node; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 220 |  |  |                         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 221 |  |  |                     } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 222 | 146 |  |                         $node = clone $node; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 223 |  |  |                     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 224 | 146 |  |                     $editOffset = 0; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 225 | 146 |  |                     for ($ii = 0; $ii < count($edits); $ii++) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 226 | 146 |  |                         $editKey   = $edits[$ii][0]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 227 | 146 |  |                         $editValue = $edits[$ii][1]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 228 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 229 | 146 |  |                         if ($inArray) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 230 | 138 |  |                             $editKey -= $editOffset; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 231 |  |  |                         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 232 | 146 |  |                         if ($inArray && $editValue === null) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 233 | 4 |  |                             if ($node instanceof NodeList) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 234 | 4 |  |                                 $node->splice($editKey, 1); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 235 |  |  |                             } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 236 |  |  |                                 array_splice($node, $editKey, 1); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 237 |  |  |                             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 238 | 4 |  |                             $editOffset++; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 239 |  |  |                         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 240 | 146 |  |                             if ($node instanceof NodeList || is_array($node)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 241 | 138 |  |                                 $node[$editKey] = $editValue; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 242 |  |  |                             } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 243 | 146 |  |                                 $node->{$editKey} = $editValue; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 244 |  |  |                             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 245 |  |  |                         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 246 |  |  |                     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 247 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 248 | 773 |  |                 $index   = $stack['index']; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 249 | 773 |  |                 $keys    = $stack['keys']; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 250 | 773 |  |                 $edits   = $stack['edits']; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 251 | 773 |  |                 $inArray = $stack['inArray']; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 252 | 773 |  |                 $stack   = $stack['prev']; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 253 |  |  |             } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 254 | 775 |  |                 $key  = $parent !== null | 
            
                                                                                                            
                            
            
                                    
            
            
                | 255 | 768 |  |                     ? ($inArray | 
            
                                                                                                            
                            
            
                                    
            
            
                | 256 | 763 |  |                         ? $index | 
            
                                                                                                            
                            
            
                                    
            
            
                | 257 | 768 |  |                         : $keys[$index] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 258 |  |  |                     ) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 259 | 775 |  |                     : $UNDEFINED; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 260 | 775 |  |                 $node = $parent !== null | 
            
                                                                                                            
                            
            
                                    
            
            
                | 261 | 768 |  |                     ? ($parent instanceof NodeList || is_array($parent) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 262 | 763 |  |                         ? $parent[$key] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 263 | 768 |  |                         : $parent->{$key} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 264 |  |  |                     ) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 265 | 775 |  |                     : $newRoot; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 266 | 775 |  |                 if ($node === null || $node === $UNDEFINED) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 267 | 764 |  |                     continue; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 268 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 269 | 775 |  |                 if ($parent !== null) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 270 | 768 |  |                     $path[] = $key; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 271 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 272 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 273 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 274 | 775 |  |             $result = null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 275 | 775 |  |             if (! $node instanceof NodeList && ! is_array($node)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 276 | 775 |  |                 if (! ($node instanceof Node)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 277 | 2 |  |                     throw new Exception('Invalid AST Node: ' . json_encode($node)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 278 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 279 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 280 | 773 |  |                 $visitFn = self::getVisitFn($visitor, $node->kind, $isLeaving); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 281 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 282 | 773 |  |                 if ($visitFn) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 283 | 773 |  |                     $result    = call_user_func($visitFn, $node, $key, $parent, $path, $ancestors); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 284 | 773 |  |                     $editValue = null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 285 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 286 | 773 |  |                     if ($result !== null) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 287 | 214 |  |                         if ($result instanceof VisitorOperation) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 288 | 7 |  |                             if ($result->doBreak) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 289 | 2 |  |                                 break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 290 |  |  |                             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 291 | 5 |  |                             if (! $isLeaving && $result->doContinue) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 292 | 1 |  |                                 array_pop($path); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 293 | 1 |  |                                 continue; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 294 |  |  |                             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 295 | 4 |  |                             if ($result->removeNode) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 296 | 4 |  |                                 $editValue = null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 297 |  |  |                             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 298 |  |  |                         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 299 | 207 |  |                             $editValue = $result; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 300 |  |  |                         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 301 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 302 | 211 |  |                         $edits[] = [$key, $editValue]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 303 | 211 |  |                         if (! $isLeaving) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 304 | 68 |  |                             if (! ($editValue instanceof Node)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 305 | 64 |  |                                 array_pop($path); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 306 | 64 |  |                                 continue; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 307 |  |  |                             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 308 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 309 | 4 |  |                             $node = $editValue; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 310 |  |  |                         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 311 |  |  |                     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 312 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 313 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 314 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 315 | 773 |  |             if ($result === null && $isEdited) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 316 | 138 |  |                 $edits[] = [$key, $node]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 317 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 318 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 319 | 773 |  |             if ($isLeaving) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 320 | 773 |  |                 array_pop($path); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 321 |  |  |             } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 322 |  |  |                 $stack   = [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 323 | 773 |  |                     'inArray' => $inArray, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 324 | 773 |  |                     'index'   => $index, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 325 | 773 |  |                     'keys'    => $keys, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 326 | 773 |  |                     'edits'   => $edits, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 327 | 773 |  |                     'prev'    => $stack, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 328 |  |  |                 ]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 329 | 773 |  |                 $inArray = $node instanceof NodeList || is_array($node); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 330 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 331 | 773 |  |                 $keys  = ($inArray ? $node : $visitorKeys[$node->kind]) ?: []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 332 | 773 |  |                 $index = -1; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 333 | 773 |  |                 $edits = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 334 | 773 |  |                 if ($parent !== null) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 335 | 768 |  |                     $ancestors[] = $parent; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 336 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 337 | 773 |  |                 $parent = $node; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 338 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 339 | 773 |  |         } while ($stack); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 340 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 341 | 773 |  |         if (count($edits) !== 0) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 342 | 211 |  |             $newRoot = $edits[0][1]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 343 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 344 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 345 | 773 |  |         return $newRoot; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 346 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 347 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 348 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 349 |  |  |      * Returns marker for visitor break | 
            
                                                                                                            
                            
            
                                    
            
            
                | 350 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 351 |  |  |      * @return VisitorOperation | 
            
                                                                                                            
                            
            
                                    
            
            
                | 352 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 353 |  |  |      * @api | 
            
                                                                                                            
                            
            
                                    
            
            
                | 354 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 355 | 6 |  |     public static function stop() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 356 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 357 | 6 |  |         $r          = new VisitorOperation(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 358 | 6 |  |         $r->doBreak = true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 359 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 360 | 6 |  |         return $r; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 361 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 362 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 363 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 364 |  |  |      * Returns marker for skipping current node | 
            
                                                                                                            
                            
            
                                    
            
            
                | 365 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 366 |  |  |      * @return VisitorOperation | 
            
                                                                                                            
                            
            
                                    
            
            
                | 367 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 368 |  |  |      * @api | 
            
                                                                                                            
                            
            
                                    
            
            
                | 369 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 370 | 193 |  |     public static function skipNode() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 371 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 372 | 193 |  |         $r             = new VisitorOperation(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 373 | 193 |  |         $r->doContinue = true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 374 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 375 | 193 |  |         return $r; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 376 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 377 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 378 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 379 |  |  |      * Returns marker for removing a node | 
            
                                                                                                            
                            
            
                                    
            
            
                | 380 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 381 |  |  |      * @return VisitorOperation | 
            
                                                                                                            
                            
            
                                    
            
            
                | 382 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 383 |  |  |      * @api | 
            
                                                                                                            
                            
            
                                    
            
            
                | 384 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 385 | 4 |  |     public static function removeNode() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 386 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 387 | 4 |  |         $r             = new VisitorOperation(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 388 | 4 |  |         $r->removeNode = true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 389 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 390 | 4 |  |         return $r; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 391 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 392 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 393 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 394 |  |  |      * @param callable[][] $visitors | 
            
                                                                                                            
                            
            
                                    
            
            
                | 395 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 396 |  |  |      * @return array<string, callable> | 
            
                                                                                                            
                            
            
                                    
            
            
                | 397 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 398 | 735 |  |     public static function visitInParallel($visitors) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 399 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 400 | 735 |  |         $visitorsCount = count($visitors); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 401 | 735 |  |         $skipping      = new SplFixedArray($visitorsCount); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 402 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 403 |  |  |         return [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 404 |  |  |             'enter' => static function (Node $node) use ($visitors, $skipping, $visitorsCount) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 405 | 735 |  |                 for ($i = 0; $i < $visitorsCount; $i++) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 406 | 735 |  |                     if (! empty($skipping[$i])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 407 | 195 |  |                         continue; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 408 |  |  |                     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 409 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 410 | 735 |  |                     $fn = self::getVisitFn( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 411 | 735 |  |                         $visitors[$i], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 412 | 735 |  |                         $node->kind, /* isLeaving */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 413 | 735 |  |                         false | 
            
                                                                                                            
                            
            
                                    
            
            
                | 414 |  |  |                     ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 415 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 416 | 735 |  |                     if (! $fn) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 417 | 715 |  |                         continue; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 418 |  |  |                     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 419 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 420 | 677 |  |                     $result = call_user_func_array($fn, func_get_args()); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 421 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 422 | 677 |  |                     if ($result instanceof VisitorOperation) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 423 | 194 |  |                         if ($result->doContinue) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 424 | 191 |  |                             $skipping[$i] = $node; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 425 | 3 |  |                         } elseif ($result->doBreak) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 426 | 2 |  |                             $skipping[$i] = $result; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 427 | 1 |  |                         } elseif ($result->removeNode) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 428 | 194 |  |                             return $result; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 429 |  |  |                         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 430 | 638 |  |                     } elseif ($result !== null) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 431 |  |  |                         return $result; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 432 |  |  |                     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 433 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 434 | 735 |  |             }, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 435 |  |  |             'leave' => static function (Node $node) use ($visitors, $skipping, $visitorsCount) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 436 | 735 |  |                 for ($i = 0; $i < $visitorsCount; $i++) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 437 | 735 |  |                     if (empty($skipping[$i])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 438 | 732 |  |                         $fn = self::getVisitFn( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 439 | 732 |  |                             $visitors[$i], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 440 | 732 |  |                             $node->kind, /* isLeaving */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 441 | 732 |  |                             true | 
            
                                                                                                            
                            
            
                                    
            
            
                | 442 |  |  |                         ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 443 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 444 | 732 |  |                         if ($fn) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 445 | 260 |  |                             $result = call_user_func_array($fn, func_get_args()); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 446 | 260 |  |                             if ($result instanceof VisitorOperation) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 447 | 13 |  |                                 if ($result->doBreak) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 448 | 2 |  |                                     $skipping[$i] = $result; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 449 | 11 |  |                                 } elseif ($result->removeNode) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 450 | 13 |  |                                     return $result; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 451 |  |  |                                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 452 | 260 |  |                             } elseif ($result !== null) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 453 | 732 |  |                                 return $result; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 454 |  |  |                             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 455 |  |  |                         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 456 | 195 |  |                     } elseif ($skipping[$i] === $node) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 457 | 191 |  |                         $skipping[$i] = null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 458 |  |  |                     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 459 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 460 | 735 |  |             }, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 461 |  |  |         ]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 462 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 463 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 464 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 465 |  |  |      * Creates a new visitor instance which maintains a provided TypeInfo instance | 
            
                                                                                                            
                            
            
                                    
            
            
                | 466 |  |  |      * along with visiting visitor. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 467 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 468 | 535 |  |     public static function visitWithTypeInfo(TypeInfo $typeInfo, $visitor) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 469 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 470 |  |  |         return [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 471 |  |  |             'enter' => static function (Node $node) use ($typeInfo, $visitor) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 472 | 535 |  |                 $typeInfo->enter($node); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 473 | 535 |  |                 $fn = self::getVisitFn($visitor, $node->kind, false); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 474 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 475 | 535 |  |                 if ($fn) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 476 | 535 |  |                     $result = call_user_func_array($fn, func_get_args()); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 477 | 535 |  |                     if ($result !== null) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 478 | 63 |  |                         $typeInfo->leave($node); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 479 | 63 |  |                         if ($result instanceof Node) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 480 | 1 |  |                             $typeInfo->enter($result); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 481 |  |  |                         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 482 |  |  |                     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 483 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 484 | 535 |  |                     return $result; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 485 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 486 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 487 | 170 |  |                 return null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 488 | 535 |  |             }, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 489 |  |  |             'leave' => static function (Node $node) use ($typeInfo, $visitor) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 490 | 535 |  |                 $fn     = self::getVisitFn($visitor, $node->kind, true); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 491 | 535 |  |                 $result = $fn ? call_user_func_array($fn, func_get_args()) : null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 492 | 535 |  |                 $typeInfo->leave($node); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 493 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 494 | 535 |  |                 return $result; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 495 | 535 |  |             }, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 496 |  |  |         ]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 497 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 498 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 499 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 500 |  |  |      * @param callable[]|null $visitor | 
            
                                                                                                            
                            
            
                                    
            
            
                | 501 |  |  |      * @param string          $kind | 
            
                                                                                                            
                            
            
                                    
            
            
                | 502 |  |  |      * @param bool            $isLeaving | 
            
                                                                                                            
                            
            
                                    
            
            
                | 503 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 504 |  |  |      * @return callable|null | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 505 |  |  |      */ | 
            
                                                                        
                            
            
                                    
            
            
                | 506 | 773 |  |     public static function getVisitFn($visitor, $kind, $isLeaving) | 
            
                                                                        
                            
            
                                    
            
            
                | 507 |  |  |     { | 
            
                                                                        
                            
            
                                    
            
            
                | 508 | 773 |  |         if ($visitor === null) { | 
            
                                                                        
                            
            
                                    
            
            
                | 509 | 1 |  |             return null; | 
            
                                                                        
                            
            
                                    
            
            
                | 510 |  |  |         } | 
            
                                                                        
                            
            
                                    
            
            
                | 511 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 512 | 773 |  |         $kindVisitor = $visitor[$kind] ?? null; | 
            
                                                                        
                            
            
                                    
            
            
                | 513 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 514 | 773 |  |         if (! $isLeaving && is_callable($kindVisitor)) { | 
            
                                                                        
                            
            
                                    
            
            
                | 515 |  |  |             // { Kind() {} } | 
            
                                                                        
                            
            
                                    
            
            
                | 516 | 521 |  |             return $kindVisitor; | 
            
                                                                        
                            
            
                                    
            
            
                | 517 |  |  |         } | 
            
                                                                        
                            
            
                                    
            
            
                | 518 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 519 | 773 |  |         if (is_array($kindVisitor)) { | 
            
                                                                        
                            
            
                                    
            
            
                | 520 | 332 |  |             if ($isLeaving) { | 
            
                                                                        
                            
            
                                    
            
            
                | 521 | 332 |  |                 $kindSpecificVisitor = $kindVisitor['leave'] ?? null; | 
            
                                                                        
                            
            
                                    
            
            
                | 522 |  |  |             } else { | 
            
                                                                        
                            
            
                                    
            
            
                | 523 | 332 |  |                 $kindSpecificVisitor = $kindVisitor['enter'] ?? null; | 
            
                                                                        
                            
            
                                    
            
            
                | 524 |  |  |             } | 
            
                                                                        
                            
            
                                    
            
            
                | 525 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 526 | 332 |  |             if ($kindSpecificVisitor && is_callable($kindSpecificVisitor)) { | 
            
                                                                        
                            
            
                                    
            
            
                | 527 |  |  |                 // { Kind: { enter() {}, leave() {} } } | 
            
                                                                        
                            
            
                                    
            
            
                | 528 | 332 |  |                 return $kindSpecificVisitor; | 
            
                                                                        
                            
            
                                    
            
            
                | 529 |  |  |             } | 
            
                                                                        
                            
            
                                    
            
            
                | 530 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 531 | 271 |  |             return null; | 
            
                                                                        
                            
            
                                    
            
            
                | 532 |  |  |         } | 
            
                                                                        
                            
            
                                    
            
            
                | 533 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 534 | 772 |  |         $visitor += ['leave' => null, 'enter' => null]; | 
            
                                                                        
                            
            
                                    
            
            
                | 535 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 536 | 772 |  |         $specificVisitor = $isLeaving ? $visitor['leave'] : $visitor['enter']; | 
            
                                                                        
                            
            
                                    
            
            
                | 537 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 538 | 772 |  |         if ($specificVisitor) { | 
            
                                                                        
                            
            
                                    
            
            
                | 539 | 770 |  |             if (is_callable($specificVisitor)) { | 
            
                                                                        
                            
            
                                    
            
            
                | 540 |  |  |                 // { enter() {}, leave() {} } | 
            
                                                                        
                            
            
                                    
            
            
                | 541 | 749 |  |                 return $specificVisitor; | 
            
                                                                        
                            
            
                                    
            
            
                | 542 |  |  |             } | 
            
                                                                        
                            
            
                                    
            
            
                | 543 | 142 |  |             $specificKindVisitor = $specificVisitor[$kind] ?? null; | 
            
                                                                        
                            
            
                                    
            
            
                | 544 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 545 | 142 |  |             if (is_callable($specificKindVisitor)) { | 
            
                                                                        
                            
            
                                    
            
            
                | 546 |  |  |                 // { enter: { Kind() {} }, leave: { Kind() {} } } | 
            
                                                                        
                            
            
                                    
            
            
                | 547 | 142 |  |                 return $specificKindVisitor; | 
            
                                                                        
                            
            
                                    
            
            
                | 548 |  |  |             } | 
            
                                                                        
                            
            
                                    
            
            
                | 549 |  |  |         } | 
            
                                                                        
                            
            
                                    
            
            
                | 550 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 551 | 750 |  |         return null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 552 |  |  |     } | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 553 |  |  | } | 
            
                                                        
            
                                    
            
            
                | 554 |  |  |  |