feat(compiler): 实现函数作用域管理和类型声明优化

- 添加函数作用域层级管理功能,支持嵌套作用域跟踪
- 实现抽象类和接口类型的实例化检查,防止非法创建实例
- 优化参数类型声明处理,增加对象参数的作用域管理
- 添加标准数组创建的位置限制检查,确保在顶层作用域创建
- 扩展继承关系检查逻辑,支持内部接口的类型验证
- 增加完整的单元测试覆盖类型命中和声明功能
pull/1/head
韩天峰 4 months ago
parent 1e22f19e63
commit 30ad4dbb0e
  1. 16
      src/Php/CompilerBase.php
  2. 19
      src/Php/Context/FunctionContext.php
  3. 8
      src/Php/Context/ScopeContext.php
  4. 21
      tests/aot/type_decl/010.phpt
  5. 22
      tests/aot/type_hits/006.phpt

@ -1039,6 +1039,12 @@ class CompilerBase extends \PhpAot\Core\Translator
}
foreach ($this->functionDef->argInfoList as $argInfo) {
$this->addArgument($argInfo->name, $argInfo->type);
if ($argInfo->class
and !$this->isAbstractClass($argInfo->class)
and !$this->hasInterface($argInfo->class)
and !$this->isInternalClass($argInfo->class)) {
$this->addObject($argInfo->name, $argInfo->class);
}
}
$stmts = '';
@ -1248,6 +1254,7 @@ class CompilerBase extends \PhpAot\Core\Translator
protected function parseStmts(array $stmts): string
{
$this->context->enterScope();
$lines = [];
$inLoopTop = $this->context->inLoop;
$last = array_key_last($stmts);
@ -1351,6 +1358,7 @@ class CompilerBase extends \PhpAot\Core\Translator
foreach ($lines as $line) {
$code .= $this->getIndent() . $line . PHP_EOL;
}
$this->context->leaveScope();
return $code;
}
@ -1523,6 +1531,9 @@ class CompilerBase extends \PhpAot\Core\Translator
if ($this->hasVar($var)) {
$this->fatalError($left, "Cannot re-assign `\${$var}` to std::array");
}
if ($this->context->scopeLevel > 1) {
$this->fatalError($left, 'Must create std::array in the top-level scope of the function');
}
$this->addLocalVar($var, self::TYPE_STD_ARRAY);
return $this->parseStdArray($var, $right);
} else {
@ -1881,6 +1892,9 @@ class CompilerBase extends \PhpAot\Core\Translator
protected function addObject(string $name, string $class): void
{
if ($this->hasInterface($class) or $this->isAbstractClass($class)) {
$this->error("Cannot create an instance of abstract/interface `$class`");
}
$this->context->objects[$name] = $class;
}
@ -3784,7 +3798,7 @@ class CompilerBase extends \PhpAot\Core\Translator
protected function isInheritedFrom(string $class, string $expected): bool
{
$internal = ($this->isInternalClass($expected) or $this->isInternalInterface($expected));
$isInterface = $this->hasInterface($expected);
$isInterface = ($this->hasInterface($expected) or $this->isInternalInterface($expected));
// 类不存在,说明这是一个动态类,跳过静态检查,需要运行时检查
if (!$this->hasClass($class)) {
return true;

@ -39,6 +39,11 @@ class FunctionContext
public array $beforeStmtLines = [];
public array $afterStmtLines = [];
public array $objectProps;
public int $scopeLevel = 0;
/**
* @var array<int, ScopeContext>
*/
public array $scopeLayouts = [];
public function __construct()
{
@ -49,8 +54,22 @@ class FunctionContext
$this->objectProps = [];
$this->ceWrappers = [];
$this->tmpVarIndex = 0;
$this->scopeLayouts = [];
$this->scopeLevel = 0;
$this->inLoop = false;
$this->inClosure = false;
$this->inAssignExpr = false;
}
public function enterScope(): void
{
$this->scopeLayouts[$this->scopeLevel] = new ScopeContext();
$this->scopeLevel++;
}
public function leaveScope(): void
{
unset($this->scopeLayouts[$this->scopeLevel]);
$this->scopeLevel--;
}
}

@ -0,0 +1,8 @@
<?php
namespace PhpAot\Php\Context;
class ScopeContext
{
}

@ -0,0 +1,21 @@
--TEST--
Type Declarations
--FILE--
<?php
class Foo1123 {
public function bar() {
var_dump(__METHOD__);
}
}
function foo(Foo1123 $v1) {
$v1->bar();
}
function main() {
$o = new Foo1123;
foo($o);
}
?>
--EXPECTF--
string(12) "Foo1123::bar"

@ -0,0 +1,22 @@
--TEST--
type hits
--FILE--
<?php
function foo(Stringable $data) {
var_dump(strval($data));
}
class A implements Stringable {
public function __toString() : string {
return "Hello World";
}
}
function main()
{
$obj = new A();
foo($obj);
}
?>
--EXPECT--
string(11) "Hello World"
Loading…
Cancel
Save