refactor(Php): 优化 MagicConst 和 Foreach 语句解析

- 修复 MagicConst 解析函数的类型声明
- 修复 Line 常量解析的返回值类型转换
- 修复 Foreach 语句解析函数的类型声明
- 更新 PhpParser 导入以支持 MagicConst 和 Foreach_ 节点类型
pull/1/head
韩天峰 8 months ago
parent 185c5a75dc
commit a085c33208
  1. 4
      examples/project/main.php
  2. 60
      src/Php/Translator.php

@ -3,5 +3,9 @@ function main()
{
fn1();
$rs = fn_test(199, 189);
$array = [1, 3, 5];
foreach ($array as $r) {
echo $r;
}
var_dump(gettype($rs));
}

@ -1,4 +1,5 @@
<?php
declare(strict_types=1);
namespace PhpAot\Php;
@ -10,6 +11,8 @@ use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Identifier;
use PhpParser\Error;
use PhpParser\Node\NullableType;
use PhpParser\Node\Scalar\MagicConst;
use PhpParser\Node\Stmt\Foreach_;
use PhpParser\NodeFinder;
use PhpParser\NodeTraverser;
use PhpParser\Parser;
@ -20,22 +23,22 @@ use stdClass;
class Translator extends \PhpAot\Core\Translator
{
const string TYPE_VAR = 'php::Var';
const string TYPE_BOOL = 'php::Bool';
const string TYPE_INT = 'php::Int';
const string TYPE_FLOAT = 'php::Float';
const string TYPE_OBJECT = 'php::Object';
const string TYPE_ARRAY = 'php::Array';
const string TYPE_STR = 'php::Str';
const string TYPE_REF = 'php::Var';
const string VALUE_NAN = 'std::numeric_limits<double>::quiet_NaN()';
const string VALUE_INF = 'std::numeric_limits<double>::infinity()';
const string LITERAL_STRINGS = '_literal_strings';
const string EXPR_VARIABLE = 'Expr_Variable';
const string EXPR_NEW = 'Expr_New';
const string EXPR_ARRAY_DIM_FETCH = 'Expr_ArrayDimFetch';
const string NAMESPACE_SEPARATOR = '__';
public const string TYPE_VAR = 'php::Var';
public const string TYPE_BOOL = 'php::Bool';
public const string TYPE_INT = 'php::Int';
public const string TYPE_FLOAT = 'php::Float';
public const string TYPE_OBJECT = 'php::Object';
public const string TYPE_ARRAY = 'php::Array';
public const string TYPE_STR = 'php::Str';
public const string TYPE_REF = 'php::Var';
public const string VALUE_NAN = 'std::numeric_limits<double>::quiet_NaN()';
public const string VALUE_INF = 'std::numeric_limits<double>::infinity()';
public const string LITERAL_STRINGS = '_literal_strings';
public const string EXPR_VARIABLE = 'Expr_Variable';
public const string EXPR_NEW = 'Expr_New';
public const string EXPR_ARRAY_DIM_FETCH = 'Expr_ArrayDimFetch';
public const string NAMESPACE_SEPARATOR = '__';
private string $phpxDir = '~/workspace/projects/phpx';
protected string $lang = 'PHP';
@ -137,7 +140,7 @@ class Translator extends \PhpAot\Core\Translator
private array $objectWrappers = [];
private bool $strictTypes = false;
const string PREFIX = 'php_';
public const string PREFIX = 'php_';
private string $rootPath;
private string $buildDir;
private int $debugLine = 0;
@ -155,7 +158,7 @@ class Translator extends \PhpAot\Core\Translator
$this->parser = (new ParserFactory())->createForNewestSupportedVersion();
// $this->prettyPrinter = new PrettyPrinter\Standard;
$this->setBuildDir($rootPath . '/build');
$climate = new CLImate;
$climate = new CLImate();
$this->climate = $climate;
$climate->arguments->add([
'optimize' => [
@ -203,7 +206,7 @@ class Translator extends \PhpAot\Core\Translator
$this->internalFunctions = array_flip(get_defined_functions()['internal']);
}
function showUsage(): void
public function showUsage(): void
{
$climate = $this->climate;
$climate->bold()->green('PHP AOT Compiler v1.0.0');
@ -234,7 +237,7 @@ class Translator extends \PhpAot\Core\Translator
$climate->br();
}
function preprocessArgvAdvanced(): void
public function preprocessArgvAdvanced(): void
{
global $argv;
$processed = [$argv[0]];
@ -289,7 +292,7 @@ class Translator extends \PhpAot\Core\Translator
$this->climate->info('convert: ' . $this->file);
$ast = $this->parser->parse($phpCode);
$traverser = new NodeTraverser;
$traverser = new NodeTraverser();
$traverser->addVisitor(new Visitor());
$stmts = $traverser->traverse($ast);
@ -451,7 +454,7 @@ class Translator extends \PhpAot\Core\Translator
if (isset($this->redoAfterDeclare[$name])) {
unset($this->redoAfterDeclare[$name]);
$this->climate->cyan('Received redo request, retrying...');
throw new RedoException;
throw new RedoException();
}
}
@ -510,6 +513,7 @@ class Translator extends \PhpAot\Core\Translator
$index = $this->literalStrings[$expr->value] ?? $this->addLiteralString($expr->value);
return self::LITERAL_STRINGS . '[' . $index . ']';
}
// no break
default:
abort($expr);
}
@ -1022,7 +1026,7 @@ class Translator extends \PhpAot\Core\Translator
$this->functionDef->returnType = $type;
// 返回值变更,需要重新解析
$this->climate->cyan('Return type changed, retrying...');
throw new RedoException;
throw new RedoException();
}
private function detectVarType($var): string
@ -1692,7 +1696,7 @@ class Translator extends \PhpAot\Core\Translator
return $code;
}
function isClosedCall($expr, $call): bool
public function isClosedCall($expr, $call): bool
{
if ($call === '') {
if (!str_starts_with($expr, '(')) {
@ -2118,7 +2122,7 @@ class Translator extends \PhpAot\Core\Translator
return $var . ' ^= ' . $this->parseIdentifier($node->expr);
}
private function parseMagicConst(mixed $expr): string
private function parseMagicConst(MagicConst $expr): string
{
switch ($expr->getType()) {
case 'Scalar_MagicConst_Dir':
@ -2126,7 +2130,7 @@ class Translator extends \PhpAot\Core\Translator
case 'Scalar_MagicConst_File':
return '"' . $this->escapeString($this->file) . '"';
case 'Scalar_MagicConst_Line':
return $expr->getStartLine();
return (string)$expr->getStartLine();
case 'Scalar_MagicConst_Function':
return '"' . $this->escapeString($this->functionDef->name) . '"';
default:
@ -2134,7 +2138,7 @@ class Translator extends \PhpAot\Core\Translator
}
}
private function parseForeach(Node $node): string
private function parseForeach(Foreach_ $node): string
{
if ($node->byRef) {
$this->fatalError($node, 'Cannot use & with foreach');
@ -2740,7 +2744,7 @@ class Translator extends \PhpAot\Core\Translator
$this->climate->info('prepare: ' . $this->file);
$ast = $this->parser->parse($phpCode);
$traverser = new NodeTraverser;
$traverser = new NodeTraverser();
$traverser->addVisitor(new Visitor());
$stmts = $traverser->traverse($ast);

Loading…
Cancel
Save