Skip to content

Commit 9ebad6a

Browse files
committed
Convert code from using a switch to using a hash map of closures
Switch statements are slow until php 7.2.
1 parent 0aef8de commit 9ebad6a

File tree

1 file changed

+22
-14
lines changed

1 file changed

+22
-14
lines changed

src/ASTConverter/ASTConverter.php

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -110,17 +110,24 @@ private static final function _phpparser_node_to_ast_node($n) {
110110
}
111111

112112
/**
113+
* This returns an array of values mapping class names to the closures which converts them to a scalar or \ast\Node or \ast\Node\Decl
114+
*
115+
* Why not a switch? Switches are slow until php 7.2, and there are dozens of class names to handle.
116+
*
117+
* - In php <= 7.1, the interpreter would loop through all possible cases, and compare against the value one by one.
118+
* - There are a lot of local variables to look at.
119+
*
113120
* @return Closure[]
114121
*/
115122
private static function _init_handle_map() : array {
116-
return [
123+
$closures = [
117124
'PhpParser\Node\Arg' => function(PhpParser\Node\Arg $n, int $startLine) {
118125
return self::_phpparser_node_to_ast_node($n->value);
119126
},
120127
'PhpParser\Node\Expr\Array_' => function(PhpParser\Node\Expr\Array_ $n, int $startLine) {
121128
return self::_phpparser_array_to_ast_array($n, $startLine);
122129
},
123-
'PhpParser\Node\Expr\Assign' => function(PhpParser\Node\Expr\AssignOp\BitwiseAnd $n, int $startLine) : \ast\Node {
130+
'PhpParser\Node\Expr\Assign' => function(PhpParser\Node\Expr\Assign $n, int $startLine) : ?\ast\Node {
124131
return self::_ast_node_assign(
125132
self::_phpparser_node_to_ast_node($n->var),
126133
self::_phpparser_node_to_ast_node($n->expr),
@@ -131,7 +138,7 @@ private static function _init_handle_map() : array {
131138
return self::_ast_node_assignop(\ast\flags\BINARY_BITWISE_AND, $n, $startLine);
132139
},
133140
'PhpParser\Node\Expr\AssignOp\BitwiseXor' => function(PhpParser\Node\Expr\AssignOp\BitwiseXor $n, int $startLine) : \ast\Node {
134-
return self::_ast_node_assignop(\ast\flags\BINARY_BITWISE_OR, $n, $startLine);
141+
return self::_ast_node_assignop(\ast\flags\BINARY_BITWISE_XOR, $n, $startLine);
135142
},
136143
'PhpParser\Node\Expr\AssignOp\BitwiseOr' => function(PhpParser\Node\Expr\AssignOp\BitwiseOr $n, int $startLine) : \ast\Node {
137144
return self::_ast_node_assignop(\ast\flags\BINARY_BITWISE_OR, $n, $startLine);
@@ -230,7 +237,7 @@ private static function _init_handle_map() : array {
230237
);
231238
// FIXME: add a test of ClassConstFetch to php-ast
232239
},
233-
'PhpParser\Node\Expr\ClassConstFetch' => function(PhpParser\Node\Expr\ClassConstFetch $n, int $startLine) : \ast\Node {
240+
'PhpParser\Node\Expr\ClassConstFetch' => function(PhpParser\Node\Expr\ClassConstFetch $n, int $startLine) : ?\ast\Node {
234241
return self::_phpparser_classconstfetch_to_ast_classconstfetch($n, $startLine);
235242
},
236243
'PhpParser\Node\Expr\ConstFetch' => function(PhpParser\Node\Expr\ConstFetch $n, int $startLine) : \ast\Node {
@@ -286,7 +293,7 @@ private static function _init_handle_map() : array {
286293
'args' => self::_phpparser_arg_list_to_ast_arg_list($n->args, $startLine),
287294
], $startLine);
288295
},
289-
'PhpParser\Node\Expr\PropertyFetch' => function(PhpParser\Node\Expr\PropertyFetch $n, int $startLine) : \ast\Node {
296+
'PhpParser\Node\Expr\PropertyFetch' => function(PhpParser\Node\Expr\PropertyFetch $n, int $startLine) : ?\ast\Node {
290297
return self::_phpparser_propertyfetch_to_ast_prop($n, $startLine);
291298
},
292299
'PhpParser\Node\Expr\StaticCall' => function(PhpParser\Node\Expr\StaticCall $n, int $startLine) : \ast\Node {
@@ -303,7 +310,7 @@ private static function _init_handle_map() : array {
303310
'PhpParser\Node\Expr\UnaryPlus' => function(PhpParser\Node\Expr\UnaryPlus $n, int $startLine) : \ast\Node {
304311
return self::_ast_node_unary_op(\ast\flags\UNARY_PLUS, self::_phpparser_node_to_ast_node($n->expr), $startLine);
305312
},
306-
'PhpParser\Node\Expr\Variable' => function(PhpParser\Node\Expr\Variable $n, int $startLine) : \ast\Node {
313+
'PhpParser\Node\Expr\Variable' => function(PhpParser\Node\Expr\Variable $n, int $startLine) : ?\ast\Node {
307314
return self::_ast_node_variable($n->name, $startLine);
308315
},
309316
/**
@@ -503,6 +510,11 @@ private static function _init_handle_map() : array {
503510
);
504511
},
505512
];
513+
514+
foreach ($closures as $key => $value) {
515+
assert(class_exists($key), "Class $key should exist");
516+
}
517+
return $closures;
506518
}
507519

508520
private static function _ast_node_try(
@@ -1155,8 +1167,7 @@ private static function _extract_phpdoc_comment($comments) : ?string {
11551167
// return var_export($comments, true);
11561168
}
11571169

1158-
private static function _phpparser_list_to_ast_list(PhpParser\Node $n, int $startLine) : \ast\Node {
1159-
assert($n instanceof PhpParser\Node\Expr\List_);
1170+
private static function _phpparser_list_to_ast_list(PhpParser\Node\Expr\List_ $n, int $startLine) : \ast\Node {
11601171
$astItems = [];
11611172
foreach ($n->items as $item) {
11621173
if ($item === null) {
@@ -1171,8 +1182,7 @@ private static function _phpparser_list_to_ast_list(PhpParser\Node $n, int $star
11711182
return astnode(\ast\AST_ARRAY, \ast\flags\ARRAY_SYNTAX_LIST, $astItems, $startLine);
11721183
}
11731184

1174-
private static function _phpparser_array_to_ast_array(PhpParser\Node $n, int $startLine) : \ast\Node {
1175-
assert($n instanceof PhpParser\Node\Expr\Array_);
1185+
private static function _phpparser_array_to_ast_array(PhpParser\Node\Expr\Array_ $n, int $startLine) : \ast\Node {
11761186
$astItems = [];
11771187
foreach ($n->items as $item) {
11781188
if ($item === null) {
@@ -1187,8 +1197,7 @@ private static function _phpparser_array_to_ast_array(PhpParser\Node $n, int $st
11871197
return astnode(\ast\AST_ARRAY, \ast\flags\ARRAY_SYNTAX_SHORT, $astItems, $startLine);
11881198
}
11891199

1190-
private static function _phpparser_propertyfetch_to_ast_prop(PhpParser\Node $n, int $startLine) : ?\ast\Node {
1191-
assert($n instanceof PhpParser\Node\Expr\PropertyFetch);
1200+
private static function _phpparser_propertyfetch_to_ast_prop(PhpParser\Node\Expr\PropertyFetch $n, int $startLine) : ?\ast\Node {
11921201
$name = $n->name;
11931202
if (is_object($name)) {
11941203
$name = self::_phpparser_node_to_ast_node($name);
@@ -1206,8 +1215,7 @@ private static function _phpparser_propertyfetch_to_ast_prop(PhpParser\Node $n,
12061215
], $startLine);
12071216
}
12081217

1209-
private static function _phpparser_classconstfetch_to_ast_classconstfetch(PhpParser\Node $n, int $startLine) : ?\ast\Node {
1210-
assert($n instanceof PhpParser\Node\Expr\ClassConstFetch);
1218+
private static function _phpparser_classconstfetch_to_ast_classconstfetch(PhpParser\Node\Expr\ClassConstFetch $n, int $startLine) : ?\ast\Node {
12111219
$name = $n->name;
12121220
if (is_object($name)) {
12131221
$name = self::_phpparser_node_to_ast_node($name);

0 commit comments

Comments
 (0)