@@ -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. native_parser_node . new ( ) ;
10991130 let rule_name = self
11001131 . grammar
@@ -1137,10 +1168,19 @@ impl NativeAstArena {
11371168 . ok_or_else ( || php_error ( "Native AST node index is out of range" ) )
11381169 }
11391170
1140- fn child_to_zval ( & self , native_ast_zval : & Zval , child : NativeAstChild ) -> PhpResult < Zval > {
1171+ fn child_to_zval_with_classes (
1172+ & self ,
1173+ native_ast_zval : & Zval ,
1174+ child : NativeAstChild ,
1175+ classes : & PhpClasses ,
1176+ ) -> PhpResult < Zval > {
11411177 match child {
1142- NativeAstChild :: Node ( index) => self . create_php_node ( native_ast_zval, index) ,
1143- NativeAstChild :: Token ( index) => self . token_source . create_php_token ( index) ,
1178+ NativeAstChild :: Node ( index) => {
1179+ self . create_php_node_with_classes ( native_ast_zval, index, classes)
1180+ }
1181+ NativeAstChild :: Token ( index) => self
1182+ . token_source
1183+ . create_php_token_with_classes ( index, classes) ,
11441184 }
11451185 }
11461186
@@ -1172,8 +1212,9 @@ impl NativeAstArena {
11721212 }
11731213
11741214 fn descendant_stack ( & self , index : usize ) -> PhpResult < Vec < NativeAstChild > > {
1175- let mut stack = self . node ( index) ?. children . clone ( ) ;
1176- stack. reverse ( ) ;
1215+ let node = self . node ( index) ?;
1216+ let mut stack = Vec :: with_capacity ( node. descendant_count ) ;
1217+ stack. extend ( node. children . iter ( ) . rev ( ) . copied ( ) ) ;
11771218 Ok ( stack)
11781219 }
11791220}
@@ -1238,6 +1279,7 @@ pub fn wp_sqlite_mysql_native_ast_get_first_child(
12381279 node_index : i64 ,
12391280) -> PhpResult < Zval > {
12401281 let ast = native_ast ( native_ast_zval) ?;
1282+ let classes = php_classes ( ) ?;
12411283 let Some ( child) = ast
12421284 . arena
12431285 . node ( native_ast_node_index ( node_index) ?) ?
@@ -1247,7 +1289,8 @@ pub fn wp_sqlite_mysql_native_ast_get_first_child(
12471289 else {
12481290 return Ok ( Zval :: null ( ) ) ;
12491291 } ;
1250- ast. arena . child_to_zval ( native_ast_zval, child)
1292+ ast. arena
1293+ . child_to_zval_with_classes ( native_ast_zval, child, & classes)
12511294}
12521295
12531296#[ php_function]
@@ -1257,9 +1300,12 @@ pub fn wp_sqlite_mysql_native_ast_get_first_child_node(
12571300 rule_name : Option < String > ,
12581301) -> PhpResult < Zval > {
12591302 let ast = native_ast ( native_ast_zval) ?;
1303+ let classes = php_classes ( ) ?;
12601304 for child in & ast. arena . node ( native_ast_node_index ( node_index) ?) ?. children {
12611305 if ast. arena . child_node_matches ( * child, rule_name. as_deref ( ) ) {
1262- return ast. arena . child_to_zval ( native_ast_zval, * child) ;
1306+ return ast
1307+ . arena
1308+ . child_to_zval_with_classes ( native_ast_zval, * child, & classes) ;
12631309 }
12641310 }
12651311 Ok ( Zval :: null ( ) )
@@ -1272,9 +1318,12 @@ pub fn wp_sqlite_mysql_native_ast_get_first_child_token(
12721318 token_id : Option < i64 > ,
12731319) -> PhpResult < Zval > {
12741320 let ast = native_ast ( native_ast_zval) ?;
1321+ let classes = php_classes ( ) ?;
12751322 for child in & ast. arena . node ( native_ast_node_index ( node_index) ?) ?. children {
12761323 if ast. arena . child_token_matches ( * child, token_id) {
1277- return ast. arena . child_to_zval ( native_ast_zval, * child) ;
1324+ return ast
1325+ . arena
1326+ . child_to_zval_with_classes ( native_ast_zval, * child, & classes) ;
12781327 }
12791328 }
12801329 Ok ( Zval :: null ( ) )
@@ -1287,12 +1336,15 @@ pub fn wp_sqlite_mysql_native_ast_get_first_descendant_node(
12871336 rule_name : Option < String > ,
12881337) -> PhpResult < Zval > {
12891338 let ast = native_ast ( native_ast_zval) ?;
1339+ let classes = php_classes ( ) ?;
12901340 let mut stack = ast
12911341 . arena
12921342 . descendant_stack ( native_ast_node_index ( node_index) ?) ?;
12931343 while let Some ( child) = stack. pop ( ) {
12941344 if ast. arena . child_node_matches ( child, rule_name. as_deref ( ) ) {
1295- return ast. arena . child_to_zval ( native_ast_zval, child) ;
1345+ return ast
1346+ . arena
1347+ . child_to_zval_with_classes ( native_ast_zval, child, & classes) ;
12961348 }
12971349 if let NativeAstChild :: Node ( index) = child {
12981350 for child in ast. arena . node ( index) ?. children . iter ( ) . rev ( ) {
@@ -1310,12 +1362,15 @@ pub fn wp_sqlite_mysql_native_ast_get_first_descendant_token(
13101362 token_id : Option < i64 > ,
13111363) -> PhpResult < Zval > {
13121364 let ast = native_ast ( native_ast_zval) ?;
1365+ let classes = php_classes ( ) ?;
13131366 let mut stack = ast
13141367 . arena
13151368 . descendant_stack ( native_ast_node_index ( node_index) ?) ?;
13161369 while let Some ( child) = stack. pop ( ) {
13171370 if ast. arena . child_token_matches ( child, token_id) {
1318- return ast. arena . child_to_zval ( native_ast_zval, child) ;
1371+ return ast
1372+ . arena
1373+ . child_to_zval_with_classes ( native_ast_zval, child, & classes) ;
13191374 }
13201375 if let NativeAstChild :: Node ( index) = child {
13211376 for child in ast. arena . node ( index) ?. children . iter ( ) . rev ( ) {
@@ -1332,12 +1387,16 @@ pub fn wp_sqlite_mysql_native_ast_get_children(
13321387 node_index : i64 ,
13331388) -> PhpResult < Vec < Zval > > {
13341389 let ast = native_ast ( native_ast_zval) ?;
1390+ let classes = php_classes ( ) ?;
13351391 ast. arena
13361392 . node ( native_ast_node_index ( node_index) ?) ?
13371393 . children
13381394 . iter ( )
13391395 . copied ( )
1340- . map ( |child| ast. arena . child_to_zval ( native_ast_zval, child) )
1396+ . map ( |child| {
1397+ ast. arena
1398+ . child_to_zval_with_classes ( native_ast_zval, child, & classes)
1399+ } )
13411400 . collect ( )
13421401}
13431402
@@ -1348,13 +1407,17 @@ pub fn wp_sqlite_mysql_native_ast_get_child_nodes(
13481407 rule_name : Option < String > ,
13491408) -> PhpResult < Vec < Zval > > {
13501409 let ast = native_ast ( native_ast_zval) ?;
1410+ let classes = php_classes ( ) ?;
13511411 ast. arena
13521412 . node ( native_ast_node_index ( node_index) ?) ?
13531413 . children
13541414 . iter ( )
13551415 . copied ( )
13561416 . filter ( |child| ast. arena . child_node_matches ( * child, rule_name. as_deref ( ) ) )
1357- . map ( |child| ast. arena . child_to_zval ( native_ast_zval, child) )
1417+ . map ( |child| {
1418+ ast. arena
1419+ . child_to_zval_with_classes ( native_ast_zval, child, & classes)
1420+ } )
13581421 . collect ( )
13591422}
13601423
@@ -1365,13 +1428,17 @@ pub fn wp_sqlite_mysql_native_ast_get_child_tokens(
13651428 token_id : Option < i64 > ,
13661429) -> PhpResult < Vec < Zval > > {
13671430 let ast = native_ast ( native_ast_zval) ?;
1431+ let classes = php_classes ( ) ?;
13681432 ast. arena
13691433 . node ( native_ast_node_index ( node_index) ?) ?
13701434 . children
13711435 . iter ( )
13721436 . copied ( )
13731437 . filter ( |child| ast. arena . child_token_matches ( * child, token_id) )
1374- . map ( |child| ast. arena . child_to_zval ( native_ast_zval, child) )
1438+ . map ( |child| {
1439+ ast. arena
1440+ . child_to_zval_with_classes ( native_ast_zval, child, & classes)
1441+ } )
13751442 . collect ( )
13761443}
13771444
@@ -1381,12 +1448,17 @@ pub fn wp_sqlite_mysql_native_ast_get_descendants(
13811448 node_index : i64 ,
13821449) -> PhpResult < Vec < Zval > > {
13831450 let ast = native_ast ( native_ast_zval) ?;
1384- let mut descendants = Vec :: new ( ) ;
1451+ let classes = php_classes ( ) ?;
1452+ let root = ast. arena . node ( native_ast_node_index ( node_index) ?) ?;
1453+ let mut descendants = Vec :: with_capacity ( root. descendant_count ) ;
13851454 let mut stack = ast
13861455 . arena
13871456 . descendant_stack ( native_ast_node_index ( node_index) ?) ?;
13881457 while let Some ( child) = stack. pop ( ) {
1389- descendants. push ( ast. arena . child_to_zval ( native_ast_zval, child) ?) ;
1458+ descendants. push (
1459+ ast. arena
1460+ . child_to_zval_with_classes ( native_ast_zval, child, & classes) ?,
1461+ ) ;
13901462 if let NativeAstChild :: Node ( index) = child {
13911463 for child in ast. arena . node ( index) ?. children . iter ( ) . rev ( ) {
13921464 stack. push ( * child) ;
@@ -1403,13 +1475,18 @@ pub fn wp_sqlite_mysql_native_ast_get_descendant_nodes(
14031475 rule_name : Option < String > ,
14041476) -> PhpResult < Vec < Zval > > {
14051477 let ast = native_ast ( native_ast_zval) ?;
1478+ let classes = php_classes ( ) ?;
14061479 let mut descendants = Vec :: new ( ) ;
14071480 let mut stack = ast
14081481 . arena
14091482 . descendant_stack ( native_ast_node_index ( node_index) ?) ?;
14101483 while let Some ( child) = stack. pop ( ) {
14111484 if ast. arena . child_node_matches ( child, rule_name. as_deref ( ) ) {
1412- descendants. push ( ast. arena . child_to_zval ( native_ast_zval, child) ?) ;
1485+ descendants. push ( ast. arena . child_to_zval_with_classes (
1486+ native_ast_zval,
1487+ child,
1488+ & classes,
1489+ ) ?) ;
14131490 }
14141491 if let NativeAstChild :: Node ( index) = child {
14151492 for child in ast. arena . node ( index) ?. children . iter ( ) . rev ( ) {
@@ -1427,13 +1504,18 @@ pub fn wp_sqlite_mysql_native_ast_get_descendant_tokens(
14271504 token_id : Option < i64 > ,
14281505) -> PhpResult < Vec < Zval > > {
14291506 let ast = native_ast ( native_ast_zval) ?;
1507+ let classes = php_classes ( ) ?;
14301508 let mut descendants = Vec :: new ( ) ;
14311509 let mut stack = ast
14321510 . arena
14331511 . descendant_stack ( native_ast_node_index ( node_index) ?) ?;
14341512 while let Some ( child) = stack. pop ( ) {
14351513 if ast. arena . child_token_matches ( child, token_id) {
1436- descendants. push ( ast. arena . child_to_zval ( native_ast_zval, child) ?) ;
1514+ descendants. push ( ast. arena . child_to_zval_with_classes (
1515+ native_ast_zval,
1516+ child,
1517+ & classes,
1518+ ) ?) ;
14371519 }
14381520 if let NativeAstChild :: Node ( index) = child {
14391521 for child in ast. arena . node ( index) ?. children . iter ( ) . rev ( ) {
0 commit comments