|
11 | 11 | * children are never materialized into PHP arrays unless something actually |
12 | 12 | * asks for them. |
13 | 13 | * |
14 | | - * Read methods eagerly call `materialize_native_children()` — once the |
15 | | - * children have been copied into PHP, `was_mutated()` returns true and the |
16 | | - * call falls through to the parent implementation. The `was_mutated` flag is |
17 | | - * NOT a runtime check for whether the native extension is loaded — if this |
18 | | - * class is in use, the extension is loaded by definition. It tracks whether |
19 | | - * THIS specific node has had its children pulled into the inherited |
20 | | - * `$children` array (which happens on first read or first mutation via |
21 | | - * `append_child()` / `merge_fragment()`). From that point on, the node is a |
22 | | - * plain PHP-backed `WP_Parser_Node`. |
| 14 | + * The hedge in those methods (`if ( $this->was_mutated() )`) is NOT a runtime |
| 15 | + * check for whether the native extension is loaded — if this class is in use, |
| 16 | + * the extension is loaded by definition. It checks whether THIS specific node |
| 17 | + * has been mutated from PHP. A node loses its native backing the first time |
| 18 | + * `append_child()` or `merge_fragment()` is called on it: those overrides |
| 19 | + * invoke `materialize_native_children()`, which copies the native children |
| 20 | + * into the inherited `$children` array and drops the native AST reference. |
| 21 | + * From that point on, the node is a plain PHP-backed `WP_Parser_Node` and the |
| 22 | + * read methods fall through to the parent implementation. |
23 | 23 | * |
24 | 24 | * Mutation from PHP is real and intentional — query rewriters in |
25 | 25 | * `WP_PDO_MySQL_On_SQLite` (e.g. building synthetic `count(*)` expressions) |
@@ -56,98 +56,130 @@ public function merge_fragment( $node ) { |
56 | 56 |
|
57 | 57 | /** @inheritDoc */ |
58 | 58 | public function has_child(): bool { |
59 | | - $this->materialize_native_children(); |
60 | | - return parent::has_child(); |
| 59 | + if ( $this->was_mutated() ) { |
| 60 | + return parent::has_child(); |
| 61 | + } |
| 62 | + return wp_sqlite_mysql_native_ast_has_child( $this->native_ast, $this->native_node_index ); |
61 | 63 | } |
62 | 64 |
|
63 | 65 | /** @inheritDoc */ |
64 | 66 | public function has_child_node( ?string $rule_name = null ): bool { |
65 | | - $this->materialize_native_children(); |
66 | | - return parent::has_child_node( $rule_name ); |
| 67 | + if ( $this->was_mutated() ) { |
| 68 | + return parent::has_child_node( $rule_name ); |
| 69 | + } |
| 70 | + return wp_sqlite_mysql_native_ast_has_child_node( $this->native_ast, $this->native_node_index, $rule_name ); |
67 | 71 | } |
68 | 72 |
|
69 | 73 | /** @inheritDoc */ |
70 | 74 | public function has_child_token( ?int $token_id = null ): bool { |
71 | | - $this->materialize_native_children(); |
72 | | - return parent::has_child_token( $token_id ); |
| 75 | + if ( $this->was_mutated() ) { |
| 76 | + return parent::has_child_token( $token_id ); |
| 77 | + } |
| 78 | + return wp_sqlite_mysql_native_ast_has_child_token( $this->native_ast, $this->native_node_index, $token_id ); |
73 | 79 | } |
74 | 80 |
|
75 | 81 | /** @inheritDoc */ |
76 | 82 | public function get_first_child() { |
77 | | - $this->materialize_native_children(); |
78 | | - return parent::get_first_child(); |
| 83 | + if ( $this->was_mutated() ) { |
| 84 | + return parent::get_first_child(); |
| 85 | + } |
| 86 | + return wp_sqlite_mysql_native_ast_get_first_child( $this->native_ast, $this->native_node_index ); |
79 | 87 | } |
80 | 88 |
|
81 | 89 | /** @inheritDoc */ |
82 | 90 | public function get_first_child_node( ?string $rule_name = null ): ?WP_Parser_Node { |
83 | | - $this->materialize_native_children(); |
84 | | - return parent::get_first_child_node( $rule_name ); |
| 91 | + if ( $this->was_mutated() ) { |
| 92 | + return parent::get_first_child_node( $rule_name ); |
| 93 | + } |
| 94 | + return wp_sqlite_mysql_native_ast_get_first_child_node( $this->native_ast, $this->native_node_index, $rule_name ); |
85 | 95 | } |
86 | 96 |
|
87 | 97 | /** @inheritDoc */ |
88 | 98 | public function get_first_child_token( ?int $token_id = null ): ?WP_Parser_Token { |
89 | | - $this->materialize_native_children(); |
90 | | - return parent::get_first_child_token( $token_id ); |
| 99 | + if ( $this->was_mutated() ) { |
| 100 | + return parent::get_first_child_token( $token_id ); |
| 101 | + } |
| 102 | + return wp_sqlite_mysql_native_ast_get_first_child_token( $this->native_ast, $this->native_node_index, $token_id ); |
91 | 103 | } |
92 | 104 |
|
93 | 105 | /** @inheritDoc */ |
94 | 106 | public function get_first_descendant_node( ?string $rule_name = null ): ?WP_Parser_Node { |
95 | | - $this->materialize_native_children(); |
96 | | - return parent::get_first_descendant_node( $rule_name ); |
| 107 | + if ( $this->was_mutated() ) { |
| 108 | + return parent::get_first_descendant_node( $rule_name ); |
| 109 | + } |
| 110 | + return wp_sqlite_mysql_native_ast_get_first_descendant_node( $this->native_ast, $this->native_node_index, $rule_name ); |
97 | 111 | } |
98 | 112 |
|
99 | 113 | /** @inheritDoc */ |
100 | 114 | public function get_first_descendant_token( ?int $token_id = null ): ?WP_Parser_Token { |
101 | | - $this->materialize_native_children(); |
102 | | - return parent::get_first_descendant_token( $token_id ); |
| 115 | + if ( $this->was_mutated() ) { |
| 116 | + return parent::get_first_descendant_token( $token_id ); |
| 117 | + } |
| 118 | + return wp_sqlite_mysql_native_ast_get_first_descendant_token( $this->native_ast, $this->native_node_index, $token_id ); |
103 | 119 | } |
104 | 120 |
|
105 | 121 | /** @inheritDoc */ |
106 | 122 | public function get_children(): array { |
107 | | - $this->materialize_native_children(); |
108 | | - return parent::get_children(); |
| 123 | + if ( $this->was_mutated() ) { |
| 124 | + return parent::get_children(); |
| 125 | + } |
| 126 | + return wp_sqlite_mysql_native_ast_get_children( $this->native_ast, $this->native_node_index ); |
109 | 127 | } |
110 | 128 |
|
111 | 129 | /** @inheritDoc */ |
112 | 130 | public function get_child_nodes( ?string $rule_name = null ): array { |
113 | | - $this->materialize_native_children(); |
114 | | - return parent::get_child_nodes( $rule_name ); |
| 131 | + if ( $this->was_mutated() ) { |
| 132 | + return parent::get_child_nodes( $rule_name ); |
| 133 | + } |
| 134 | + return wp_sqlite_mysql_native_ast_get_child_nodes( $this->native_ast, $this->native_node_index, $rule_name ); |
115 | 135 | } |
116 | 136 |
|
117 | 137 | /** @inheritDoc */ |
118 | 138 | public function get_child_tokens( ?int $token_id = null ): array { |
119 | | - $this->materialize_native_children(); |
120 | | - return parent::get_child_tokens( $token_id ); |
| 139 | + if ( $this->was_mutated() ) { |
| 140 | + return parent::get_child_tokens( $token_id ); |
| 141 | + } |
| 142 | + return wp_sqlite_mysql_native_ast_get_child_tokens( $this->native_ast, $this->native_node_index, $token_id ); |
121 | 143 | } |
122 | 144 |
|
123 | 145 | /** @inheritDoc */ |
124 | 146 | public function get_descendants(): array { |
125 | | - $this->materialize_native_children(); |
126 | | - return parent::get_descendants(); |
| 147 | + if ( $this->was_mutated() ) { |
| 148 | + return parent::get_descendants(); |
| 149 | + } |
| 150 | + return wp_sqlite_mysql_native_ast_get_descendants( $this->native_ast, $this->native_node_index ); |
127 | 151 | } |
128 | 152 |
|
129 | 153 | /** @inheritDoc */ |
130 | 154 | public function get_descendant_nodes( ?string $rule_name = null ): array { |
131 | | - $this->materialize_native_children(); |
132 | | - return parent::get_descendant_nodes( $rule_name ); |
| 155 | + if ( $this->was_mutated() ) { |
| 156 | + return parent::get_descendant_nodes( $rule_name ); |
| 157 | + } |
| 158 | + return wp_sqlite_mysql_native_ast_get_descendant_nodes( $this->native_ast, $this->native_node_index, $rule_name ); |
133 | 159 | } |
134 | 160 |
|
135 | 161 | /** @inheritDoc */ |
136 | 162 | public function get_descendant_tokens( ?int $token_id = null ): array { |
137 | | - $this->materialize_native_children(); |
138 | | - return parent::get_descendant_tokens( $token_id ); |
| 163 | + if ( $this->was_mutated() ) { |
| 164 | + return parent::get_descendant_tokens( $token_id ); |
| 165 | + } |
| 166 | + return wp_sqlite_mysql_native_ast_get_descendant_tokens( $this->native_ast, $this->native_node_index, $token_id ); |
139 | 167 | } |
140 | 168 |
|
141 | 169 | /** @inheritDoc */ |
142 | 170 | public function get_start(): int { |
143 | | - $this->materialize_native_children(); |
144 | | - return parent::get_start(); |
| 171 | + if ( $this->was_mutated() ) { |
| 172 | + return parent::get_start(); |
| 173 | + } |
| 174 | + return wp_sqlite_mysql_native_ast_get_start( $this->native_ast, $this->native_node_index ); |
145 | 175 | } |
146 | 176 |
|
147 | 177 | /** @inheritDoc */ |
148 | 178 | public function get_length(): int { |
149 | | - $this->materialize_native_children(); |
150 | | - return parent::get_length(); |
| 179 | + if ( $this->was_mutated() ) { |
| 180 | + return parent::get_length(); |
| 181 | + } |
| 182 | + return wp_sqlite_mysql_native_ast_get_length( $this->native_ast, $this->native_node_index ); |
151 | 183 | } |
152 | 184 |
|
153 | 185 | /** |
|
0 commit comments