From 18a37a098157a98edbc8473e9c0d8dff3e8a88fa Mon Sep 17 00:00:00 2001 From: nsfisis Date: Fri, 7 Aug 2026 20:51:59 +0900 Subject: fix(plugin): make proxy stub property access an explicit error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A proxy stub declares none of the real class's instance properties, and the `__get`/`__set` forwarders were emitted only for classes that declare a public one. Every other property access therefore got PHP's own answer for an undeclared property — null on a read, a dynamic property on a write — so plugin code reading state the entity holds ran on with null and failed somewhere else entirely, or not at all. Emit the forwarders on every root stub, add `__isset`/`__unset` alongside them so `isset()` cannot answer false silently either, and serve all four from one dispatcher that answers the state the Rust-side entity exposes and rejects every other name. Co-Authored-By: Claude Opus 5 (1M context) --- .../php/stubs/Composer/Package/BasePackage.php | 31 ++++++++++++++-------- 1 file changed, 20 insertions(+), 11 deletions(-) (limited to 'crates/shirabe-php-rpc/php/stubs/Composer/Package/BasePackage.php') diff --git a/crates/shirabe-php-rpc/php/stubs/Composer/Package/BasePackage.php b/crates/shirabe-php-rpc/php/stubs/Composer/Package/BasePackage.php index 9fca286a..65eebd56 100644 --- a/crates/shirabe-php-rpc/php/stubs/Composer/Package/BasePackage.php +++ b/crates/shirabe-php-rpc/php/stubs/Composer/Package/BasePackage.php @@ -48,6 +48,26 @@ abstract class BasePackage implements PackageInterface, \ShirabeRustStub \ShirabeRustObjectRegistry::adopt($this->__rhandle, $this); } + public function __get($name) + { + return \ShirabeRpcRuntime::callRust($this->__rhandle, '__get', [$name]); + } + + public function __set($name, $value): void + { + \ShirabeRpcRuntime::callRust($this->__rhandle, '__set', [$name, $value]); + } + + public function __isset($name): bool + { + return \ShirabeRpcRuntime::callRust($this->__rhandle, '__isset', [$name]); + } + + public function __unset($name): void + { + \ShirabeRpcRuntime::callRust($this->__rhandle, '__unset', [$name]); + } + public function __construct(string $name) { [$this->__rhandle, $this->__epoch] = \ShirabeRpcRuntime::callRust(0, '__shirabeConstruct', [static::class, [$name]]); @@ -76,17 +96,6 @@ abstract class BasePackage implements PackageInterface, \ShirabeRustStub ]; public static $stabilities = self::STABILITIES; - /** The real class declares public properties; every access forwards to the entity. */ - public function __get($name) - { - return \ShirabeRpcRuntime::callRust($this->__rhandle, '__get', [$name]); - } - - public function __set($name, $value): void - { - \ShirabeRpcRuntime::callRust($this->__rhandle, '__set', [$name, $value]); - } - public static function packageNameToRegexp(string $allowPattern, string $wrap = '{^%s$}i'): string { $cleanedAllowPattern = str_replace('\\*', '.*', preg_quote($allowPattern)); -- cgit v1.3.1