refactor(Php): 优化函数调用优化器中的参数类型常量

- 将简写的参数类型常量重命名为更具描述性的名称
- 为数组类型添加新的参数类型支持
- 更新所有相关的常量引用以使用新命名
- 实现标准容器数组表达式的转换功能
- 修复字符串键名处理中的缺少方法调用问题
pull/1/head
韩天峰 3 months ago
parent 4e94de6620
commit 8450e69e1c
  1. 76
      src/Php/Optimizer/FuncCallOptimizer.php

@ -18,13 +18,14 @@ use PhpParser\Node;
*/
trait FuncCallOptimizer
{
private const string A_V = 'v';
private const string A_S = 's';
private const string A_I = 'i';
private const string A_F = 'f';
private const string A_B = 'b';
private const string A_R = 'R';
private const string A_OPT = '?';
private const string ARG_TYPE_VAR = 'v';
private const string ARG_TYPE_STR = 's';
private const string ARG_TYPE_INT = 'i';
private const string ARG_TYPE_FLOAT = 'f';
private const string ARG_TYPE_BOOL = 'b';
private const string ARG_TYPE_REF = 'R';
private const string ARG_TYPE_ARRAY = 'A';
private const string ARG_OPTIONAL = '?';
private const int FOLD_STRING_LEN = 1;
private const int FOLD_STRING_CASE = 2;
@ -149,10 +150,10 @@ trait FuncCallOptimizer
]],
// Type conversions
'strval' => ['conversion' => self::A_S],
'intval' => ['conversion' => self::A_I],
'floatval' => ['conversion' => self::A_F],
'boolval' => ['conversion' => self::A_B],
'strval' => ['conversion' => self::ARG_TYPE_STR],
'intval' => ['conversion' => self::ARG_TYPE_INT],
'floatval' => ['conversion' => self::ARG_TYPE_FLOAT],
'boolval' => ['conversion' => self::ARG_TYPE_BOOL],
// SSA compile-time type checks
'is_int' => ['constFold' => self::FOLD_SSA_TYPE, 'constFoldExtra' => self::TYPE_INT],
@ -272,7 +273,7 @@ trait FuncCallOptimizer
}
$char = $this->phpParamToArgChar($param);
if ($param->isOptional()) {
$char = self::A_OPT . $char;
$char = self::ARG_OPTIONAL . $char;
}
$types[] = $char;
}
@ -283,19 +284,20 @@ trait FuncCallOptimizer
private function phpParamToArgChar(\ReflectionParameter $param): string
{
if ($param->isPassedByReference()) {
return self::A_R;
return self::ARG_TYPE_REF;
}
$type = $param->getType();
if ($type instanceof \ReflectionNamedType) {
return match ($type->getName()) {
'string' => self::A_S,
'int' => self::A_I,
'float' => self::A_F,
'bool' => self::A_B,
default => self::A_V,
'string' => self::ARG_TYPE_STR,
'int' => self::ARG_TYPE_INT,
'float' => self::ARG_TYPE_FLOAT,
'bool' => self::ARG_TYPE_BOOL,
'array' => self::ARG_TYPE_ARRAY,
default => self::ARG_TYPE_VAR,
};
}
return self::A_V;
return self::ARG_TYPE_VAR;
}
// =========================================================================
@ -329,19 +331,29 @@ trait FuncCallOptimizer
private function resolveArg(Node\Expr\FuncCall $expr, int $index, string $type): string
{
$base = ($type[0] ?? '') === self::A_OPT ? substr($type, 1) : $type;
$base = ($type[0] ?? '') === self::ARG_OPTIONAL ? substr($type, 1) : $type;
$raw = ($base === self::A_R) ? $this->getRefArg($expr, $index) : $this->getArg($expr, $index);
$raw = ($base === self::ARG_TYPE_REF) ? $this->getRefArg($expr, $index) : $this->getArg($expr, $index);
return match ($base) {
self::A_S => $this->convertStringExpr($raw),
self::A_I => $this->convertIntExpr($raw),
self::A_F => $this->convertFloatExpr($raw),
self::A_B => $this->convertBoolExpr($raw),
self::ARG_TYPE_STR => $this->convertStringExpr($raw),
self::ARG_TYPE_INT => $this->convertIntExpr($raw),
self::ARG_TYPE_FLOAT => $this->convertFloatExpr($raw),
self::ARG_TYPE_BOOL => $this->convertBoolExpr($raw),
self::ARG_TYPE_ARRAY => $this->convertStdContainerArrayExpr($expr, $index, $raw),
default => $raw,
};
}
private function convertStdContainerArrayExpr(Node\Expr\FuncCall $expr, int $index, string $raw): string
{
$arg = $expr->args[$index]->value;
if ($this->isVarExpr($arg) and $this->isStdContainer($arg->name)) {
return $this->convertArrayExpr($raw . '_ref');
}
return $this->convertArrayExpr($raw);
}
private function buildArgList(Node\Expr\FuncCall $expr, string $argTypeStr, array $defaults = []): array
{
if ($argTypeStr === '') {
@ -353,7 +365,7 @@ trait FuncCallOptimizer
$args = [];
foreach ($types as $i => $type) {
$optional = ($type[0] ?? '') === self::A_OPT;
$optional = ($type[0] ?? '') === self::ARG_OPTIONAL;
if ($optional && $argCount <= $i) {
if (isset($defaults[$i])) {
$args[] = $defaults[$i];
@ -376,7 +388,7 @@ trait FuncCallOptimizer
foreach ($expr->args as $arg) {
$args[] = $this->parseExpr($arg->value);
}
return $target . '({' . implode(', ', $args) . '})';
return $target . '(' . implode(', ', $args) . ')';
}
private function dispatchConversion(Node\Expr\FuncCall $expr, string $convType): string
@ -385,7 +397,7 @@ trait FuncCallOptimizer
$type = $this->detectTypeOfExpr($arg);
$parsed = $this->parseExpr($arg);
if ($convType === self::A_S) {
if ($convType === self::ARG_TYPE_STR) {
return match ($type) {
self::TYPE_BIGINT => 'php::BigInt::toString(' . $parsed . ')',
self::TYPE_BIGFLOAT => 'php::BigFloat::toString(' . $parsed . ')',
@ -395,9 +407,9 @@ trait FuncCallOptimizer
}
return match ($convType) {
self::A_I => $this->convertIntExpr($parsed),
self::A_F => $this->convertFloatExpr($parsed),
self::A_B => $this->convertBoolExpr($parsed),
self::ARG_TYPE_INT => $this->convertIntExpr($parsed),
self::ARG_TYPE_FLOAT => $this->convertFloatExpr($parsed),
self::ARG_TYPE_BOOL => $this->convertBoolExpr($parsed),
default => $parsed,
};
}
@ -745,7 +757,7 @@ trait FuncCallOptimizer
$key = $this->getLiteralString($var);
$cVar = $this->escapeVarName($var);
$list[] = '{' . $key . ', php::Var(' . $cVar . ')}';
$list[] = '{' . $key . '.str(), php::Var(' . $cVar . ')}';
}
return 'php::Array{' . implode(', ', $list) . '}';

Loading…
Cancel
Save