fix(compiler): 修复接口中self返回类型解析错误

pull/22/head
Yurun 1 month ago
parent 559a8860a0
commit f9516c43c9
  1. 5
      src/CompilerBase.php
  2. 42
      tests/compiler/class/interface-method-self-return.phpt
  3. 36
      tests/compiler/namespace/interface-self-return-namespaced.phpt

@ -1017,7 +1017,10 @@ class CompilerBase implements PropertyAccessContext
protected function getFullClassName(): string
{
return ltrim($this->namespace . '\\' . $this->class, '\\');
// 在接口上下文中,$this->class 为空但 $this->interface 已设置,
// `self` 类型声明应解析为接口自身的完整名称。
$classLike = $this->class !== '' ? $this->class : $this->interface;
return ltrim($this->namespace . '\\' . $classLike, '\\');
}
protected function getFullMethodName(string $fullClassName, string $method): string

@ -0,0 +1,42 @@
--TEST--
interface method with `self` return type implemented by class (fluent interface), and namespace block containing comments
--FILE--
<?php
namespace {
interface TestInterface
{
public function get(): self;
}
class TestClass implements TestInterface
{
public int $value = 0;
public function get(): self
{
return $this;
}
public function setValue(int $value): self
{
$this->value = $value;
return $this;
}
}
function main()
{
$test = new TestClass;
// get() returns self, so the result still satisfies the interface
var_dump($test->get() instanceof TestInterface);
var_dump($test === $test->get());
// fluent chaining of self-returning methods
var_dump($test->get()->setValue(42)->value);
}
}
?>
--EXPECT--
bool(true)
bool(true)
int(42)

@ -0,0 +1,36 @@
--TEST--
interface method `self` return type resolves to the interface's fully-qualified name inside a named namespace
--FILE--
<?php
namespace App {
interface Chainable
{
public function chain(): self;
}
// comment inside a named namespace block (Stmt_Nop)
class Widget implements Chainable
{
public array $log = [];
public function chain(): self
{
$this->log[] = 'chain';
return $this;
}
}
}
namespace {
function main()
{
$w = new \App\Widget();
var_dump($w->chain()->chain() instanceof \App\Chainable);
var_dump(count($w->log));
}
}
?>
--EXPECT--
bool(true)
int(2)
Loading…
Cancel
Save