diff --git a/src/CompilerBase.php b/src/CompilerBase.php index 074a1517..fab95bf8 100644 --- a/src/CompilerBase.php +++ b/src/CompilerBase.php @@ -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 diff --git a/tests/compiler/class/interface-method-self-return.phpt b/tests/compiler/class/interface-method-self-return.phpt new file mode 100644 index 00000000..90e44eab --- /dev/null +++ b/tests/compiler/class/interface-method-self-return.phpt @@ -0,0 +1,42 @@ +--TEST-- +interface method with `self` return type implemented by class (fluent interface), and namespace block containing comments +--FILE-- +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) diff --git a/tests/compiler/namespace/interface-self-return-namespaced.phpt b/tests/compiler/namespace/interface-self-return-namespaced.phpt new file mode 100644 index 00000000..cfda0bad --- /dev/null +++ b/tests/compiler/namespace/interface-self-return-namespaced.phpt @@ -0,0 +1,36 @@ +--TEST-- +interface method `self` return type resolves to the interface's fully-qualified name inside a named namespace +--FILE-- +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)