Skip to content

Commit 780e349

Browse files
committed
Apply was_mutated() rename to native node fast paths
Forward-port the renamed helper and inverted hedge to the tip after the fast-path restore commit reintroduced the old form during rebase.
1 parent cf00421 commit 780e349

1 file changed

Lines changed: 69 additions & 68 deletions

File tree

packages/mysql-on-sqlite/src/mysql/native/class-wp-mysql-native-parser-node.php

Lines changed: 69 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,15 @@
1111
* children are never materialized into PHP arrays unless something actually
1212
* asks for them.
1313
*
14-
* The hedge in those methods (`if ( $this->has_unmaterialized_native_ast() )`)
15-
* is NOT a runtime check for whether the native extension is loaded — if this
16-
* class is in use, the extension is loaded by definition. It checks whether
17-
* THIS specific node still has an authoritative native AST behind it. A node
18-
* loses its native backing the first time it is mutated from PHP via
19-
* `append_child()` or `merge_fragment()`: those overrides call
20-
* `materialize_native_children()`, which copies the native children into the
21-
* inherited `$children` array and then drops the native AST reference. From
22-
* that point on, the node is a plain PHP-backed `WP_Parser_Node` and the read
23-
* methods fall through to the parent implementation.
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.
2423
*
2524
* Mutation from PHP is real and intentional — query rewriters in
2625
* `WP_PDO_MySQL_On_SQLite` (e.g. building synthetic `count(*)` expressions)
@@ -31,6 +30,7 @@
3130
class WP_MySQL_Native_Parser_Node extends WP_Parser_Node {
3231
private $native_ast = null;
3332
private $native_node_index = null;
33+
private $was_mutated = false;
3434

3535
public function __construct( $rule_id, $rule_name, $native_ast = null, $native_node_index = null ) {
3636
parent::__construct( $rule_id, $rule_name );
@@ -67,145 +67,145 @@ public function merge_fragment( $node ) {
6767

6868
/** @inheritDoc */
6969
public function has_child(): bool {
70-
if ( $this->has_unmaterialized_native_ast() ) {
71-
return wp_sqlite_mysql_native_ast_has_child( $this->native_ast, $this->native_node_index );
70+
if ( $this->was_mutated() ) {
71+
return parent::has_child();
7272
}
73-
return parent::has_child();
73+
return wp_sqlite_mysql_native_ast_has_child( $this->native_ast, $this->native_node_index );
7474
}
7575

7676
/** @inheritDoc */
7777
public function has_child_node( ?string $rule_name = null ): bool {
78-
if ( $this->has_unmaterialized_native_ast() ) {
79-
return wp_sqlite_mysql_native_ast_has_child_node( $this->native_ast, $this->native_node_index, $rule_name );
78+
if ( $this->was_mutated() ) {
79+
return parent::has_child_node( $rule_name );
8080
}
81-
return parent::has_child_node( $rule_name );
81+
return wp_sqlite_mysql_native_ast_has_child_node( $this->native_ast, $this->native_node_index, $rule_name );
8282
}
8383

8484
/** @inheritDoc */
8585
public function has_child_token( ?int $token_id = null ): bool {
86-
if ( $this->has_unmaterialized_native_ast() ) {
87-
return wp_sqlite_mysql_native_ast_has_child_token( $this->native_ast, $this->native_node_index, $token_id );
86+
if ( $this->was_mutated() ) {
87+
return parent::has_child_token( $token_id );
8888
}
89-
return parent::has_child_token( $token_id );
89+
return wp_sqlite_mysql_native_ast_has_child_token( $this->native_ast, $this->native_node_index, $token_id );
9090
}
9191

9292
/** @inheritDoc */
9393
public function get_first_child() {
94-
if ( $this->has_unmaterialized_native_ast() ) {
95-
return wp_sqlite_mysql_native_ast_get_first_child( $this->native_ast, $this->native_node_index );
94+
if ( $this->was_mutated() ) {
95+
return parent::get_first_child();
9696
}
97-
return parent::get_first_child();
97+
return wp_sqlite_mysql_native_ast_get_first_child( $this->native_ast, $this->native_node_index );
9898
}
9999

100100
/** @inheritDoc */
101101
public function get_first_child_node( ?string $rule_name = null ): ?WP_Parser_Node {
102-
if ( $this->has_unmaterialized_native_ast() ) {
103-
return wp_sqlite_mysql_native_ast_get_first_child_node( $this->native_ast, $this->native_node_index, $rule_name );
102+
if ( $this->was_mutated() ) {
103+
return parent::get_first_child_node( $rule_name );
104104
}
105-
return parent::get_first_child_node( $rule_name );
105+
return wp_sqlite_mysql_native_ast_get_first_child_node( $this->native_ast, $this->native_node_index, $rule_name );
106106
}
107107

108108
/** @inheritDoc */
109109
public function get_first_child_token( ?int $token_id = null ): ?WP_Parser_Token {
110-
if ( $this->has_unmaterialized_native_ast() ) {
111-
return wp_sqlite_mysql_native_ast_get_first_child_token( $this->native_ast, $this->native_node_index, $token_id );
110+
if ( $this->was_mutated() ) {
111+
return parent::get_first_child_token( $token_id );
112112
}
113-
return parent::get_first_child_token( $token_id );
113+
return wp_sqlite_mysql_native_ast_get_first_child_token( $this->native_ast, $this->native_node_index, $token_id );
114114
}
115115

116116
/** @inheritDoc */
117117
public function get_first_descendant_node( ?string $rule_name = null ): ?WP_Parser_Node {
118-
if ( $this->has_unmaterialized_native_ast() ) {
119-
return wp_sqlite_mysql_native_ast_get_first_descendant_node( $this->native_ast, $this->native_node_index, $rule_name );
118+
if ( $this->was_mutated() ) {
119+
return parent::get_first_descendant_node( $rule_name );
120120
}
121-
return parent::get_first_descendant_node( $rule_name );
121+
return wp_sqlite_mysql_native_ast_get_first_descendant_node( $this->native_ast, $this->native_node_index, $rule_name );
122122
}
123123

124124
/** @inheritDoc */
125125
public function get_first_descendant_token( ?int $token_id = null ): ?WP_Parser_Token {
126-
if ( $this->has_unmaterialized_native_ast() ) {
127-
return wp_sqlite_mysql_native_ast_get_first_descendant_token( $this->native_ast, $this->native_node_index, $token_id );
126+
if ( $this->was_mutated() ) {
127+
return parent::get_first_descendant_token( $token_id );
128128
}
129-
return parent::get_first_descendant_token( $token_id );
129+
return wp_sqlite_mysql_native_ast_get_first_descendant_token( $this->native_ast, $this->native_node_index, $token_id );
130130
}
131131

132132
/** @inheritDoc */
133133
public function get_children(): array {
134-
if ( $this->has_unmaterialized_native_ast() ) {
135-
return wp_sqlite_mysql_native_ast_get_children( $this->native_ast, $this->native_node_index );
134+
if ( $this->was_mutated() ) {
135+
return parent::get_children();
136136
}
137-
return parent::get_children();
137+
return wp_sqlite_mysql_native_ast_get_children( $this->native_ast, $this->native_node_index );
138138
}
139139

140140
/** @inheritDoc */
141141
public function get_child_nodes( ?string $rule_name = null ): array {
142-
if ( $this->has_unmaterialized_native_ast() ) {
143-
return wp_sqlite_mysql_native_ast_get_child_nodes( $this->native_ast, $this->native_node_index, $rule_name );
142+
if ( $this->was_mutated() ) {
143+
return parent::get_child_nodes( $rule_name );
144144
}
145-
return parent::get_child_nodes( $rule_name );
145+
return wp_sqlite_mysql_native_ast_get_child_nodes( $this->native_ast, $this->native_node_index, $rule_name );
146146
}
147147

148148
/** @inheritDoc */
149149
public function get_child_tokens( ?int $token_id = null ): array {
150-
if ( $this->has_unmaterialized_native_ast() ) {
151-
return wp_sqlite_mysql_native_ast_get_child_tokens( $this->native_ast, $this->native_node_index, $token_id );
150+
if ( $this->was_mutated() ) {
151+
return parent::get_child_tokens( $token_id );
152152
}
153-
return parent::get_child_tokens( $token_id );
153+
return wp_sqlite_mysql_native_ast_get_child_tokens( $this->native_ast, $this->native_node_index, $token_id );
154154
}
155155

156156
/** @inheritDoc */
157157
public function get_descendants(): array {
158-
if ( $this->has_unmaterialized_native_ast() ) {
159-
return wp_sqlite_mysql_native_ast_get_descendants( $this->native_ast, $this->native_node_index );
158+
if ( $this->was_mutated() ) {
159+
return parent::get_descendants();
160160
}
161-
return parent::get_descendants();
161+
return wp_sqlite_mysql_native_ast_get_descendants( $this->native_ast, $this->native_node_index );
162162
}
163163

164164
/** @inheritDoc */
165165
public function get_descendant_nodes( ?string $rule_name = null ): array {
166-
if ( $this->has_unmaterialized_native_ast() ) {
167-
return wp_sqlite_mysql_native_ast_get_descendant_nodes( $this->native_ast, $this->native_node_index, $rule_name );
166+
if ( $this->was_mutated() ) {
167+
return parent::get_descendant_nodes( $rule_name );
168168
}
169-
return parent::get_descendant_nodes( $rule_name );
169+
return wp_sqlite_mysql_native_ast_get_descendant_nodes( $this->native_ast, $this->native_node_index, $rule_name );
170170
}
171171

172172
/** @inheritDoc */
173173
public function get_descendant_tokens( ?int $token_id = null ): array {
174-
if ( $this->has_unmaterialized_native_ast() ) {
175-
return wp_sqlite_mysql_native_ast_get_descendant_tokens( $this->native_ast, $this->native_node_index, $token_id );
174+
if ( $this->was_mutated() ) {
175+
return parent::get_descendant_tokens( $token_id );
176176
}
177-
return parent::get_descendant_tokens( $token_id );
177+
return wp_sqlite_mysql_native_ast_get_descendant_tokens( $this->native_ast, $this->native_node_index, $token_id );
178178
}
179179

180180
/** @inheritDoc */
181181
public function get_start(): int {
182-
if ( $this->has_unmaterialized_native_ast() ) {
183-
return wp_sqlite_mysql_native_ast_get_start( $this->native_ast, $this->native_node_index );
182+
if ( $this->was_mutated() ) {
183+
return parent::get_start();
184184
}
185-
return parent::get_start();
185+
return wp_sqlite_mysql_native_ast_get_start( $this->native_ast, $this->native_node_index );
186186
}
187187

188188
/** @inheritDoc */
189189
public function get_length(): int {
190-
if ( $this->has_unmaterialized_native_ast() ) {
191-
return wp_sqlite_mysql_native_ast_get_length( $this->native_ast, $this->native_node_index );
190+
if ( $this->was_mutated() ) {
191+
return parent::get_length();
192192
}
193-
return parent::get_length();
193+
return wp_sqlite_mysql_native_ast_get_length( $this->native_ast, $this->native_node_index );
194194
}
195195

196196
/**
197-
* Indicates whether this node still has an unmaterialized native AST.
197+
* Indicates whether this node has been mutated from PHP.
198198
*
199-
* Returns true for freshly-parsed nodes whose children live in the
200-
* Rust-owned AST buffer; returns false once the node has been mutated and
201-
* its children copied into the inherited `$children` array (see
202-
* self::materialize_native_children()).
199+
* Returns false for freshly-parsed nodes whose children still live in the
200+
* Rust-owned AST buffer; returns true once `append_child()` or
201+
* `merge_fragment()` has copied the children into the inherited
202+
* `$children` array and dropped the native AST reference.
203203
*
204204
* This is a per-instance state check, not a check for whether the native
205205
* extension is loaded.
206206
*/
207-
private function has_unmaterialized_native_ast(): bool {
208-
return null !== $this->native_ast;
207+
private function was_mutated(): bool {
208+
return $this->was_mutated;
209209
}
210210

211211
/**
@@ -214,16 +214,17 @@ private function has_unmaterialized_native_ast(): bool {
214214
*
215215
* Called before any mutation (append_child, merge_fragment) so the node's
216216
* authoritative state lives in PHP from that point on. After this runs,
217-
* has_unmaterialized_native_ast() returns false and read methods fall
218-
* through to the parent WP_Parser_Node implementation.
217+
* was_mutated() returns true and read methods fall through to the parent
218+
* WP_Parser_Node implementation.
219219
*/
220220
private function materialize_native_children(): void {
221-
if ( ! $this->has_unmaterialized_native_ast() ) {
221+
if ( $this->was_mutated ) {
222222
return;
223223
}
224224

225225
$this->children = wp_sqlite_mysql_native_ast_get_children( $this->native_ast, $this->native_node_index );
226226
$this->native_ast = null;
227227
$this->native_node_index = null;
228+
$this->was_mutated = true;
228229
}
229230
}

0 commit comments

Comments
 (0)