aboutsummaryrefslogtreecommitdiffhomepage
path: root/docs/dev/plugin-stub-generation.md
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-08-06 02:40:00 +0900
committernsfisis <nsfisis@gmail.com>2026-08-06 02:40:00 +0900
commit90764c477f24e4d67d3e0cae943c33fd2b8ae220 (patch)
tree8274fb1e266d6a14653c2a440cc6831ffda1c6bf /docs/dev/plugin-stub-generation.md
parent0e89281dd7f057d3829508b8e6c5d85c3f111c45 (diff)
downloadphp-shirabe-90764c477f24e4d67d3e0cae943c33fd2b8ae220.tar.gz
php-shirabe-90764c477f24e4d67d3e0cae943c33fd2b8ae220.tar.zst
php-shirabe-90764c477f24e4d67d3e0cae943c33fd2b8ae220.zip
feat(plugin): widen the RPC surface to LibraryInstaller-based plugins
An installer that extends LibraryInstaller reaches for the Composer object graph in ways the proxy did not answer: the download manager and the config, the writable repository methods, a React promise as its own return value, and `new Package(...)` from its supports() path. * `Composer::getConfig`/`getDownloadManager` are dispatched, and both classes become generated proxy stubs. Their reads and mutators answer from the Rust entity; the surfaces needing stubs of their own (ConfigSourceInterface, DownloaderInterface) stay explicit errors. * The download manager's futures are driven to completion and handed back as already-settled React promises, since PHP declares a non-nullable PromiseInterface there. A promise a plugin returns is drained the same way: settled yields its value, rejected re-raises, pending is an explicit error. * Proxy stubs now carry the real class's constructor and ask the Rust side to allocate the entity; reviving a stub for an existing entity binds the handle without running it. Classes Rust cannot build name themselves in the error. * The package proxy covers `Package`'s own setters, `CompletePackage`'s metadata, `RootPackage`'s root-only state, and `BasePackage::$id`. Link values and release dates still have no wire image, so the methods carrying them remain explicit errors.
Diffstat (limited to 'docs/dev/plugin-stub-generation.md')
-rw-r--r--docs/dev/plugin-stub-generation.md16
1 files changed, 11 insertions, 5 deletions
diff --git a/docs/dev/plugin-stub-generation.md b/docs/dev/plugin-stub-generation.md
index 33025df7..27835921 100644
--- a/docs/dev/plugin-stub-generation.md
+++ b/docs/dev/plugin-stub-generation.md
@@ -46,12 +46,18 @@ the generator's vendor directory or the classifier report is unavailable.
## What the generator emits
* **Root stubs** (targets whose parent class is not itself a target) carry the
- proxy boilerplate: `__rhandle`/`__epoch` properties, a constructor that
- accepts `(rhandle, epoch)` from proxy instantiation and throws a diagnosable
- `RuntimeException` when plugin code tries to `new` the class directly, a
+ proxy boilerplate: `__rhandle`/`__epoch` properties, the `__shirabeBind`
+ binder the registry calls when reviving a stub for an existing entity, a
destructor releasing the Rust handle, and the wire descriptor helper. The
real `extends`/`implements` hierarchy is preserved and `\ShirabeRustStub` is
appended to the interface list.
+* **Constructors** reproduce the real class's parameter list and forward to the
+ Rust side (`__shirabeConstruct` on handle 0), which allocates the entity and
+ answers with its handle; a class Rust cannot build answers with an explicit
+ error naming it. One is emitted for every root stub and for every subclass
+ that declares a public constructor of its own, so `new SomeProxiedClass(...)`
+ in plugin code never yields an unbound stub. Proxy revival does not run them
+ (see `__shirabeBind` above).
* **Instance methods** forward via `\ShirabeRpcRuntime::callRust`. For a root
stub the emitted surface is the interface closure (each interface before the
ones it extends, methods in declaration order; a concrete redeclaration in
@@ -89,8 +95,8 @@ Generation fails — instead of emitting something quietly wrong — on:
* a target missing from the classifier report, classified other than
`rust-proxy`/`contract`, or a report carrying violations,
-* by-ref or variadic parameters, static interface methods, magic methods
- other than `__toString`/`__clone`,
+* by-ref or variadic parameters (in constructors too), static interface
+ methods, magic methods other than `__toString`/`__clone`,
* an omitted override diverging from the inherited stub signature,
* a subclass target listed before its base class, or extending a class that is
neither a target nor provided by `php/runtime/`,