@@ -93,10 +93,19 @@ fn update_object_property(
9393}
9494
9595fn create_mysql_token ( sql_zval : & Zval , token : TokenInfo , no_backslash : bool ) -> PhpResult < Zval > {
96+ let classes = php_classes ( ) ?;
97+ create_mysql_token_with_classes ( sql_zval, token, no_backslash, & classes)
98+ }
99+
100+ fn create_mysql_token_with_classes (
101+ sql_zval : & Zval ,
102+ token : TokenInfo ,
103+ no_backslash : bool ,
104+ classes : & PhpClasses ,
105+ ) -> PhpResult < Zval > {
96106 let id = token. id ;
97107 let start = i64:: try_from ( token. start ) . map_err ( php_error) ?;
98108 let length = i64:: try_from ( token. end . saturating_sub ( token. start ) ) . map_err ( php_error) ?;
99- let classes = php_classes ( ) ?;
100109 let mut object = classes. mysql_token . new ( ) ;
101110
102111 update_object_property ( & mut object, classes. parser_token , "id" , id) ?;
@@ -940,7 +949,7 @@ enum ParserTokenSource {
940949}
941950
942951impl ParserTokenSource {
943- fn create_php_token ( & self , index : usize ) -> PhpResult < Zval > {
952+ fn create_php_token_with_classes ( & self , index : usize , classes : & PhpClasses ) -> PhpResult < Zval > {
944953 match self {
945954 Self :: Php ( tokens) => tokens
946955 . get ( index)
@@ -955,7 +964,7 @@ impl ParserTokenSource {
955964 . get ( index)
956965 . copied ( )
957966 . ok_or_else ( || php_error ( "Parser token index is out of range" ) ) ?;
958- create_mysql_token ( sql_zval, token, * no_backslash)
967+ create_mysql_token_with_classes ( sql_zval, token, * no_backslash, classes )
959968 }
960969 }
961970 }
@@ -1020,6 +1029,7 @@ struct NativeAstNode {
10201029 children : Vec < NativeAstChild > ,
10211030 first_token : Option < usize > ,
10221031 last_token : Option < usize > ,
1032+ descendant_count : usize ,
10231033}
10241034
10251035struct NativeAstArena {
@@ -1049,10 +1059,12 @@ impl NativeAstArena {
10491059 let index = self . nodes . len ( ) ;
10501060 let mut first_token = None ;
10511061 let mut last_token = None ;
1062+ let mut descendant_count = 0 ;
10521063 for child in & children {
10531064 match child {
10541065 NativeAstChild :: Node ( child_index) => {
10551066 if let Some ( node) = self . nodes . get ( * child_index) {
1067+ descendant_count += 1 + node. descendant_count ;
10561068 if first_token. is_none ( ) {
10571069 first_token = node. first_token ;
10581070 }
@@ -1066,6 +1078,7 @@ impl NativeAstArena {
10661078 first_token = Some ( * token_index) ;
10671079 }
10681080 last_token = Some ( * token_index) ;
1081+ descendant_count += 1 ;
10691082 }
10701083 }
10711084 }
@@ -1075,26 +1088,44 @@ impl NativeAstArena {
10751088 children,
10761089 first_token,
10771090 last_token,
1091+ descendant_count,
10781092 } ) ;
10791093 index
10801094 }
10811095
10821096 fn create_php_ast ( & self , native_ast_zval : & Zval ) -> PhpResult < Zval > {
1097+ let classes = php_classes ( ) ?;
1098+ self . create_php_ast_with_classes ( native_ast_zval, & classes)
1099+ }
1100+
1101+ fn create_php_ast_with_classes (
1102+ & self ,
1103+ native_ast_zval : & Zval ,
1104+ classes : & PhpClasses ,
1105+ ) -> PhpResult < Zval > {
10831106 match self . root {
10841107 NativeAstRoot :: No => Ok ( Zval :: null ( ) ) ,
10851108 NativeAstRoot :: Empty => {
10861109 let mut zval = Zval :: new ( ) ;
10871110 zval. set_bool ( true ) ;
10881111 Ok ( zval)
10891112 }
1090- NativeAstRoot :: Node ( index) => self . create_php_node ( native_ast_zval, index) ,
1091- NativeAstRoot :: Token ( index) => self . token_source . create_php_token ( index) ,
1113+ NativeAstRoot :: Node ( index) => {
1114+ self . create_php_node_with_classes ( native_ast_zval, index, classes)
1115+ }
1116+ NativeAstRoot :: Token ( index) => self
1117+ . token_source
1118+ . create_php_token_with_classes ( index, classes) ,
10921119 }
10931120 }
10941121
1095- fn create_php_node ( & self , native_ast_zval : & Zval , index : usize ) -> PhpResult < Zval > {
1122+ fn create_php_node_with_classes (
1123+ & self ,
1124+ native_ast_zval : & Zval ,
1125+ index : usize ,
1126+ classes : & PhpClasses ,
1127+ ) -> PhpResult < Zval > {
10961128 let node = self . node ( index) ?;
1097- let classes = php_classes ( ) ?;
10981129 let mut object = classes. parser_node . new ( ) ;
10991130 let rule_name = self
11001131 . grammar
@@ -1127,10 +1158,19 @@ impl NativeAstArena {
11271158 . ok_or_else ( || php_error ( "Native AST node index is out of range" ) )
11281159 }
11291160
1130- fn child_to_zval ( & self , native_ast_zval : & Zval , child : NativeAstChild ) -> PhpResult < Zval > {
1161+ fn child_to_zval_with_classes (
1162+ & self ,
1163+ native_ast_zval : & Zval ,
1164+ child : NativeAstChild ,
1165+ classes : & PhpClasses ,
1166+ ) -> PhpResult < Zval > {
11311167 match child {
1132- NativeAstChild :: Node ( index) => self . create_php_node ( native_ast_zval, index) ,
1133- NativeAstChild :: Token ( index) => self . token_source . create_php_token ( index) ,
1168+ NativeAstChild :: Node ( index) => {
1169+ self . create_php_node_with_classes ( native_ast_zval, index, classes)
1170+ }
1171+ NativeAstChild :: Token ( index) => self
1172+ . token_source
1173+ . create_php_token_with_classes ( index, classes) ,
11341174 }
11351175 }
11361176
@@ -1162,8 +1202,9 @@ impl NativeAstArena {
11621202 }
11631203
11641204 fn descendant_stack ( & self , index : usize ) -> PhpResult < Vec < NativeAstChild > > {
1165- let mut stack = self . node ( index) ?. children . clone ( ) ;
1166- stack. reverse ( ) ;
1205+ let node = self . node ( index) ?;
1206+ let mut stack = Vec :: with_capacity ( node. descendant_count ) ;
1207+ stack. extend ( node. children . iter ( ) . rev ( ) . copied ( ) ) ;
11671208 Ok ( stack)
11681209 }
11691210}
@@ -1228,6 +1269,7 @@ pub fn wp_sqlite_mysql_native_ast_get_first_child(
12281269 node_index : i64 ,
12291270) -> PhpResult < Zval > {
12301271 let ast = native_ast ( native_ast_zval) ?;
1272+ let classes = php_classes ( ) ?;
12311273 let Some ( child) = ast
12321274 . arena
12331275 . node ( native_ast_node_index ( node_index) ?) ?
@@ -1237,7 +1279,8 @@ pub fn wp_sqlite_mysql_native_ast_get_first_child(
12371279 else {
12381280 return Ok ( Zval :: null ( ) ) ;
12391281 } ;
1240- ast. arena . child_to_zval ( native_ast_zval, child)
1282+ ast. arena
1283+ . child_to_zval_with_classes ( native_ast_zval, child, & classes)
12411284}
12421285
12431286#[ php_function]
@@ -1247,9 +1290,12 @@ pub fn wp_sqlite_mysql_native_ast_get_first_child_node(
12471290 rule_name : Option < String > ,
12481291) -> PhpResult < Zval > {
12491292 let ast = native_ast ( native_ast_zval) ?;
1293+ let classes = php_classes ( ) ?;
12501294 for child in & ast. arena . node ( native_ast_node_index ( node_index) ?) ?. children {
12511295 if ast. arena . child_node_matches ( * child, rule_name. as_deref ( ) ) {
1252- return ast. arena . child_to_zval ( native_ast_zval, * child) ;
1296+ return ast
1297+ . arena
1298+ . child_to_zval_with_classes ( native_ast_zval, * child, & classes) ;
12531299 }
12541300 }
12551301 Ok ( Zval :: null ( ) )
@@ -1262,9 +1308,12 @@ pub fn wp_sqlite_mysql_native_ast_get_first_child_token(
12621308 token_id : Option < i64 > ,
12631309) -> PhpResult < Zval > {
12641310 let ast = native_ast ( native_ast_zval) ?;
1311+ let classes = php_classes ( ) ?;
12651312 for child in & ast. arena . node ( native_ast_node_index ( node_index) ?) ?. children {
12661313 if ast. arena . child_token_matches ( * child, token_id) {
1267- return ast. arena . child_to_zval ( native_ast_zval, * child) ;
1314+ return ast
1315+ . arena
1316+ . child_to_zval_with_classes ( native_ast_zval, * child, & classes) ;
12681317 }
12691318 }
12701319 Ok ( Zval :: null ( ) )
@@ -1277,12 +1326,15 @@ pub fn wp_sqlite_mysql_native_ast_get_first_descendant_node(
12771326 rule_name : Option < String > ,
12781327) -> PhpResult < Zval > {
12791328 let ast = native_ast ( native_ast_zval) ?;
1329+ let classes = php_classes ( ) ?;
12801330 let mut stack = ast
12811331 . arena
12821332 . descendant_stack ( native_ast_node_index ( node_index) ?) ?;
12831333 while let Some ( child) = stack. pop ( ) {
12841334 if ast. arena . child_node_matches ( child, rule_name. as_deref ( ) ) {
1285- return ast. arena . child_to_zval ( native_ast_zval, child) ;
1335+ return ast
1336+ . arena
1337+ . child_to_zval_with_classes ( native_ast_zval, child, & classes) ;
12861338 }
12871339 if let NativeAstChild :: Node ( index) = child {
12881340 for child in ast. arena . node ( index) ?. children . iter ( ) . rev ( ) {
@@ -1300,12 +1352,15 @@ pub fn wp_sqlite_mysql_native_ast_get_first_descendant_token(
13001352 token_id : Option < i64 > ,
13011353) -> PhpResult < Zval > {
13021354 let ast = native_ast ( native_ast_zval) ?;
1355+ let classes = php_classes ( ) ?;
13031356 let mut stack = ast
13041357 . arena
13051358 . descendant_stack ( native_ast_node_index ( node_index) ?) ?;
13061359 while let Some ( child) = stack. pop ( ) {
13071360 if ast. arena . child_token_matches ( child, token_id) {
1308- return ast. arena . child_to_zval ( native_ast_zval, child) ;
1361+ return ast
1362+ . arena
1363+ . child_to_zval_with_classes ( native_ast_zval, child, & classes) ;
13091364 }
13101365 if let NativeAstChild :: Node ( index) = child {
13111366 for child in ast. arena . node ( index) ?. children . iter ( ) . rev ( ) {
@@ -1322,12 +1377,16 @@ pub fn wp_sqlite_mysql_native_ast_get_children(
13221377 node_index : i64 ,
13231378) -> PhpResult < Vec < Zval > > {
13241379 let ast = native_ast ( native_ast_zval) ?;
1380+ let classes = php_classes ( ) ?;
13251381 ast. arena
13261382 . node ( native_ast_node_index ( node_index) ?) ?
13271383 . children
13281384 . iter ( )
13291385 . copied ( )
1330- . map ( |child| ast. arena . child_to_zval ( native_ast_zval, child) )
1386+ . map ( |child| {
1387+ ast. arena
1388+ . child_to_zval_with_classes ( native_ast_zval, child, & classes)
1389+ } )
13311390 . collect ( )
13321391}
13331392
@@ -1338,13 +1397,17 @@ pub fn wp_sqlite_mysql_native_ast_get_child_nodes(
13381397 rule_name : Option < String > ,
13391398) -> PhpResult < Vec < Zval > > {
13401399 let ast = native_ast ( native_ast_zval) ?;
1400+ let classes = php_classes ( ) ?;
13411401 ast. arena
13421402 . node ( native_ast_node_index ( node_index) ?) ?
13431403 . children
13441404 . iter ( )
13451405 . copied ( )
13461406 . filter ( |child| ast. arena . child_node_matches ( * child, rule_name. as_deref ( ) ) )
1347- . map ( |child| ast. arena . child_to_zval ( native_ast_zval, child) )
1407+ . map ( |child| {
1408+ ast. arena
1409+ . child_to_zval_with_classes ( native_ast_zval, child, & classes)
1410+ } )
13481411 . collect ( )
13491412}
13501413
@@ -1355,13 +1418,17 @@ pub fn wp_sqlite_mysql_native_ast_get_child_tokens(
13551418 token_id : Option < i64 > ,
13561419) -> PhpResult < Vec < Zval > > {
13571420 let ast = native_ast ( native_ast_zval) ?;
1421+ let classes = php_classes ( ) ?;
13581422 ast. arena
13591423 . node ( native_ast_node_index ( node_index) ?) ?
13601424 . children
13611425 . iter ( )
13621426 . copied ( )
13631427 . filter ( |child| ast. arena . child_token_matches ( * child, token_id) )
1364- . map ( |child| ast. arena . child_to_zval ( native_ast_zval, child) )
1428+ . map ( |child| {
1429+ ast. arena
1430+ . child_to_zval_with_classes ( native_ast_zval, child, & classes)
1431+ } )
13651432 . collect ( )
13661433}
13671434
@@ -1371,12 +1438,17 @@ pub fn wp_sqlite_mysql_native_ast_get_descendants(
13711438 node_index : i64 ,
13721439) -> PhpResult < Vec < Zval > > {
13731440 let ast = native_ast ( native_ast_zval) ?;
1374- let mut descendants = Vec :: new ( ) ;
1441+ let classes = php_classes ( ) ?;
1442+ let root = ast. arena . node ( native_ast_node_index ( node_index) ?) ?;
1443+ let mut descendants = Vec :: with_capacity ( root. descendant_count ) ;
13751444 let mut stack = ast
13761445 . arena
13771446 . descendant_stack ( native_ast_node_index ( node_index) ?) ?;
13781447 while let Some ( child) = stack. pop ( ) {
1379- descendants. push ( ast. arena . child_to_zval ( native_ast_zval, child) ?) ;
1448+ descendants. push (
1449+ ast. arena
1450+ . child_to_zval_with_classes ( native_ast_zval, child, & classes) ?,
1451+ ) ;
13801452 if let NativeAstChild :: Node ( index) = child {
13811453 for child in ast. arena . node ( index) ?. children . iter ( ) . rev ( ) {
13821454 stack. push ( * child) ;
@@ -1393,13 +1465,18 @@ pub fn wp_sqlite_mysql_native_ast_get_descendant_nodes(
13931465 rule_name : Option < String > ,
13941466) -> PhpResult < Vec < Zval > > {
13951467 let ast = native_ast ( native_ast_zval) ?;
1468+ let classes = php_classes ( ) ?;
13961469 let mut descendants = Vec :: new ( ) ;
13971470 let mut stack = ast
13981471 . arena
13991472 . descendant_stack ( native_ast_node_index ( node_index) ?) ?;
14001473 while let Some ( child) = stack. pop ( ) {
14011474 if ast. arena . child_node_matches ( child, rule_name. as_deref ( ) ) {
1402- descendants. push ( ast. arena . child_to_zval ( native_ast_zval, child) ?) ;
1475+ descendants. push ( ast. arena . child_to_zval_with_classes (
1476+ native_ast_zval,
1477+ child,
1478+ & classes,
1479+ ) ?) ;
14031480 }
14041481 if let NativeAstChild :: Node ( index) = child {
14051482 for child in ast. arena . node ( index) ?. children . iter ( ) . rev ( ) {
@@ -1417,13 +1494,18 @@ pub fn wp_sqlite_mysql_native_ast_get_descendant_tokens(
14171494 token_id : Option < i64 > ,
14181495) -> PhpResult < Vec < Zval > > {
14191496 let ast = native_ast ( native_ast_zval) ?;
1497+ let classes = php_classes ( ) ?;
14201498 let mut descendants = Vec :: new ( ) ;
14211499 let mut stack = ast
14221500 . arena
14231501 . descendant_stack ( native_ast_node_index ( node_index) ?) ?;
14241502 while let Some ( child) = stack. pop ( ) {
14251503 if ast. arena . child_token_matches ( child, token_id) {
1426- descendants. push ( ast. arena . child_to_zval ( native_ast_zval, child) ?) ;
1504+ descendants. push ( ast. arena . child_to_zval_with_classes (
1505+ native_ast_zval,
1506+ child,
1507+ & classes,
1508+ ) ?) ;
14271509 }
14281510 if let NativeAstChild :: Node ( index) = child {
14291511 for child in ast. arena . node ( index) ?. children . iter ( ) . rev ( ) {
0 commit comments