refactor(php): 将函数声明和调用跟踪重构为符号级别

- 将 $functionDeclInFile 和 $functionCallInFile 重命名为 $symbolDeclInFile 和 $symbolCallInFile
- 更新 CompilerBase 类中的变量引用以使用新的符号命名
- 修改 FileSorter 构造函数参数和属性以匹配新的符号命名
- 调整 Preprocessor 中的符号收集逻辑以支持类继承关系
- 在 Translator 中添加字符串字面量外部声明支持
- 扩展符号跟踪功能以涵盖类声明和父类引用
pull/1/head
韩天峰 5 months ago
parent 28f2b5ac8a
commit 78c7daa646
  1. 8
      src/Php/CompilerBase.php
  2. 20
      src/Php/FileSorter.php
  3. 23
      src/Php/Preprocessor.php
  4. 3
      src/Php/Translator.php

@ -143,8 +143,8 @@ class CompilerBase extends \PhpAot\Core\Translator
protected array $nativeFunctions = []; protected array $nativeFunctions = [];
protected array $internalFunctions = []; protected array $internalFunctions = [];
protected array $nativeConstants = []; protected array $nativeConstants = [];
protected array $functionDeclInFile = []; protected array $symbolDeclInFile = [];
protected array $functionCallInFile = []; protected array $symbolCallInFile = [];
protected array $redoAfterDeclare = []; protected array $redoAfterDeclare = [];
protected array $constData = []; protected array $constData = [];
protected int $optimizeLevel = 0; protected int $optimizeLevel = 0;
@ -1600,8 +1600,8 @@ class CompilerBase extends \PhpAot\Core\Translator
{ {
// 在预处理阶段检测到函数声明,但是未定义,说明在当前文件,但是顺序错误 // 在预处理阶段检测到函数声明,但是未定义,说明在当前文件,但是顺序错误
// 跳过,稍后再处理 // 跳过,稍后再处理
if (isset($this->functionDeclInFile[$name]) if (isset($this->symbolDeclInFile[$name])
and $this->functionDeclInFile[$name] === $this->file and $this->symbolDeclInFile[$name] === $this->file
and !$this->hasNativeFunction($name)) { and !$this->hasNativeFunction($name)) {
$this->redoAfterDeclare[$name] = true; $this->redoAfterDeclare[$name] = true;
throw new Skip(); throw new Skip();

@ -10,13 +10,13 @@ namespace PhpAot\Php;
class FileSorter class FileSorter
{ {
private array $functionDeclInFile; private array $symbolDeclInFile;
private array $functionCallInFile; private array $symbolCallInFile;
public function __construct(array $functionDeclInFile, array $functionCallInFile) public function __construct(array $symbolDeclInFile, array $symbolCallInFile)
{ {
$this->functionDeclInFile = $functionDeclInFile; $this->symbolDeclInFile = $symbolDeclInFile;
$this->functionCallInFile = $functionCallInFile; $this->symbolCallInFile = $symbolCallInFile;
} }
public function sort(): array public function sort(): array
@ -65,12 +65,12 @@ class FileSorter
{ {
$dependencies = []; $dependencies = [];
foreach ($this->functionCallInFile as $call) { foreach ($this->symbolCallInFile as $call) {
$callerFile = $call['file']; $callerFile = $call['file'];
$functionName = $call['name']; $functionName = $call['name'];
if (isset($this->functionDeclInFile[$functionName])) { if (isset($this->symbolDeclInFile[$functionName])) {
$declFile = $this->functionDeclInFile[$functionName]; $declFile = $this->symbolDeclInFile[$functionName];
if ($callerFile !== $declFile) { if ($callerFile !== $declFile) {
if (!isset($dependencies[$callerFile])) { if (!isset($dependencies[$callerFile])) {
@ -89,9 +89,9 @@ class FileSorter
private function getAllFiles(): array private function getAllFiles(): array
{ {
$files = array_values($this->functionDeclInFile); $files = array_values($this->symbolDeclInFile);
foreach ($this->functionCallInFile as $call) { foreach ($this->symbolCallInFile as $call) {
$files[] = $call['file']; $files[] = $call['file'];
} }

@ -20,12 +20,12 @@ class Preprocessor extends CompilerBase
public function sortFiles(array &$list): void public function sortFiles(array &$list): void
{ {
foreach ($this->functionCallInFile as $k => $call) { foreach ($this->symbolCallInFile as $k => $call) {
if (!isset($this->functionDeclInFile[$call['name']])) { if (!isset($this->symbolDeclInFile[$call['name']])) {
unset($this->functionCallInFile[$k]); unset($this->symbolCallInFile[$k]);
} }
} }
$sorter = new FileSorter($this->functionDeclInFile, $this->functionCallInFile); $sorter = new FileSorter($this->symbolDeclInFile, $this->symbolCallInFile);
$sortedFiles = $sorter->sort(); $sortedFiles = $sorter->sort();
foreach ($list as $file) { foreach ($list as $file) {
@ -120,8 +120,8 @@ class Preprocessor extends CompilerBase
foreach ($functionCalls as $call) { foreach ($functionCalls as $call) {
if ($call->name instanceof Node\Name) { if ($call->name instanceof Node\Name) {
$name = $call->name->toString(); $name = $call->name->toString();
$this->functionCallInFile[] = [ $this->symbolCallInFile[] = [
'name' => $name, 'name' => $name,
'file' => $this->file, 'file' => $this->file,
'line' => $call->getLine(), 'line' => $call->getLine(),
@ -164,7 +164,7 @@ class Preprocessor extends CompilerBase
if ($this->stubFile) { if ($this->stubFile) {
$this->nativeFunctions[$name] = $this->parseFunctionDecl($v); $this->nativeFunctions[$name] = $this->parseFunctionDecl($v);
} else { } else {
$this->functionDeclInFile[$name] = $this->file; $this->symbolDeclInFile[$name] = $this->file;
} }
} }
@ -180,11 +180,18 @@ class Preprocessor extends CompilerBase
protected function prepareClass(Node\Stmt\Class_|Node\Stmt\Trait_|Node\Stmt\Enum_ $class): string protected function prepareClass(Node\Stmt\Class_|Node\Stmt\Trait_|Node\Stmt\Enum_ $class): string
{ {
$this->class = $this->parseIdentifier($class->name); $this->class = $this->parseIdentifier($class->name);
$fullClassName = $this->getNamespacedClassName($this->class);
if (!empty($class->extends)) { if (!empty($class->extends)) {
$this->parentClass = $this->getParentClass($class->extends); $this->parentClass = $this->getParentClass($class->extends);
$fullClassName = $this->getNamespacedClassName($this->class); $this->symbolCallInFile[] = [
'name' => $this->parentClass,
'file' => $this->file,
'line' => $class->getLine(),
];
$this->classExtends[$fullClassName] = $this->parentClass; $this->classExtends[$fullClassName] = $this->parentClass;
} }
$this->symbolDeclInFile[$fullClassName] = $this->file;
$code = ''; $code = '';
foreach ($class->stmts as $v) { foreach ($class->stmts as $v) {
$type = $v->getType(); $type = $v->getType();

@ -419,6 +419,9 @@ class Translator extends Preprocessor
{ {
$code = '#include <phpx.h>' . PHP_EOL; $code = '#include <phpx.h>' . PHP_EOL;
$literalStringsCount = count($this->literalStrings);
$code .= 'extern ' . self::TYPE_STR . ' ' . self::LITERAL_STRINGS . '[' . $literalStringsCount . '];' . PHP_EOL;
foreach ($this->nativeFunctions as $name => $func) { foreach ($this->nativeFunctions as $name => $func) {
$code .= 'extern ' . $func->returnType . ' ' . self::PREFIX . $name . '('; $code .= 'extern ' . $func->returnType . ' ' . self::PREFIX . $name . '(';
$list = []; $list = [];

Loading…
Cancel
Save