diff options
Diffstat (limited to 'crates/shirabe-php-rpc/php')
4 files changed, 207 insertions, 138 deletions
diff --git a/crates/shirabe-php-rpc/php/guards/Composer/Util/ProcessExecutor.php b/crates/shirabe-php-rpc/php/guards/Composer/Util/ProcessExecutor.php deleted file mode 100644 index 405905e8..00000000 --- a/crates/shirabe-php-rpc/php/guards/Composer/Util/ProcessExecutor.php +++ /dev/null @@ -1,114 +0,0 @@ -<?php - -// Generated by scripts/plugin-stub-generator; do not edit by hand. -// Guard for Composer\Util\ProcessExecutor. -// The Rust side owns this class and the worker has no proxy for it, so this -// declaration shadows the real one: the constants and the hierarchy stay, while -// constructing it or calling anything on it raises an explicit error. - -namespace Composer\Util; - -use Composer\IO\IOInterface; -use React\Promise\PromiseInterface; - -class ProcessExecutor -{ - private const STATUS_QUEUED = 1; - private const STATUS_STARTED = 2; - private const STATUS_COMPLETED = 3; - private const STATUS_FAILED = 4; - private const STATUS_ABORTED = 5; - private const BUILTIN_CMD_COMMANDS = [ - 'assoc', 'break', 'call', 'cd', 'chdir', 'cls', 'color', 'copy', 'date', - 'del', 'dir', 'echo', 'endlocal', 'erase', 'exit', 'for', 'ftype', 'goto', - 'help', 'if', 'label', 'md', 'mkdir', 'mklink', 'move', 'path', 'pause', - 'popd', 'prompt', 'pushd', 'rd', 'rem', 'ren', 'rename', 'rmdir', 'set', - 'setlocal', 'shift', 'start', 'time', 'title', 'type', 'ver', 'vol', - ]; - private const GIT_CMDS_NEED_GIT_DIR = [ - ['show'], - ['log'], - ['branch'], - ['remote', 'set-url'], - ]; - - public function __construct(?IOInterface $io = null) - { - \ShirabeUnsupportedClass::fail(self::class, '__construct'); - } - - public function execute($command, &$output = null, ?string $cwd = null): int - { - \ShirabeUnsupportedClass::fail(self::class, 'execute'); - } - - public function executeTty($command, ?string $cwd = null): int - { - \ShirabeUnsupportedClass::fail(self::class, 'executeTty'); - } - - public function executeAsync($command, ?string $cwd = null): PromiseInterface - { - \ShirabeUnsupportedClass::fail(self::class, 'executeAsync'); - } - - protected function outputHandler(string $type, string $buffer): void - { - \ShirabeUnsupportedClass::fail(self::class, 'outputHandler'); - } - - public function setMaxJobs(int $maxJobs): void - { - \ShirabeUnsupportedClass::fail(self::class, 'setMaxJobs'); - } - - public function resetMaxJobs(): void - { - \ShirabeUnsupportedClass::fail(self::class, 'resetMaxJobs'); - } - - public function wait($index = null): void - { - \ShirabeUnsupportedClass::fail(self::class, 'wait'); - } - - public function enableAsync(): void - { - \ShirabeUnsupportedClass::fail(self::class, 'enableAsync'); - } - - public function countActiveJobs($index = null): int - { - \ShirabeUnsupportedClass::fail(self::class, 'countActiveJobs'); - } - - public function splitLines(?string $output): array - { - \ShirabeUnsupportedClass::fail(self::class, 'splitLines'); - } - - public function getErrorOutput(): string - { - \ShirabeUnsupportedClass::fail(self::class, 'getErrorOutput'); - } - - public static function getTimeout(): int - { - \ShirabeUnsupportedClass::fail(self::class, 'getTimeout'); - } - - public static function setTimeout(int $timeout): void - { - \ShirabeUnsupportedClass::fail(self::class, 'setTimeout'); - } - - public static function escape($argument): string - { - \ShirabeUnsupportedClass::fail(self::class, 'escape'); - } - - public function requiresGitDirEnv($command): bool - { - \ShirabeUnsupportedClass::fail(self::class, 'requiresGitDirEnv'); - } -} diff --git a/crates/shirabe-php-rpc/php/stubs/Composer/Util/Filesystem.php b/crates/shirabe-php-rpc/php/stubs/Composer/Util/Filesystem.php index e1532889..c66bcf56 100644 --- a/crates/shirabe-php-rpc/php/stubs/Composer/Util/Filesystem.php +++ b/crates/shirabe-php-rpc/php/stubs/Composer/Util/Filesystem.php @@ -83,26 +83,6 @@ class Filesystem implements \ShirabeRustStub return $path; } - public static function isLocalPath(string $path) - { - // on windows, \\foo indicates network paths so we exclude those from local paths, however it is unsafe - // on linux as file:////foo (which would be a network path \\foo on windows) will resolve to /foo which could be a local path - if (Platform::isWindows()) { - return Preg::isMatch('{^(file://(?!//)|/(?!/)|/?[a-z]:[\\\\/]|\.\.[\\\\/]|[a-z0-9_.-]+[\\\\/])}i', $path); - } - - return Preg::isMatch('{^(file://|/|/?[a-z]:[\\\\/]|\.\.[\\\\/]|[a-z0-9_.-]+[\\\\/])}i', $path); - } - - public static function getPlatformPath(string $path) - { - if (Platform::isWindows()) { - $path = Preg::replace('{^(?:file:///([a-z]):?/)}i', 'file://$1:/', $path); - } - - return Preg::replace('{^file://}i', '', $path); - } - public static function isReadable(string $path) { if (is_readable($path)) { @@ -121,6 +101,18 @@ class Filesystem implements \ShirabeRustStub return false; } + // Forwarded rather than materialized: it references Composer\Util\Platform, which a guard shadows in the worker. + public static function isLocalPath(string $path) + { + return \ShirabeRpcRuntime::callRust(0, '__shirabeCallStatic', [self::class, 'isLocalPath', [$path]]); + } + + // Forwarded rather than materialized: it references Composer\Util\Platform, which a guard shadows in the worker. + public static function getPlatformPath(string $path) + { + return \ShirabeRpcRuntime::callRust(0, '__shirabeCallStatic', [self::class, 'getPlatformPath', [$path]]); + } + public function remove(string $file) { return \ShirabeRpcRuntime::callRust($this->__rhandle, 'remove', [$file]); diff --git a/crates/shirabe-php-rpc/php/stubs/Composer/Util/ProcessExecutor.php b/crates/shirabe-php-rpc/php/stubs/Composer/Util/ProcessExecutor.php new file mode 100644 index 00000000..dfa1f0d2 --- /dev/null +++ b/crates/shirabe-php-rpc/php/stubs/Composer/Util/ProcessExecutor.php @@ -0,0 +1,176 @@ +<?php + +// Generated by scripts/plugin-stub-generator; do not edit by hand. +// Proxy stub for Composer\Util\ProcessExecutor: the public surface forwards to the Rust-side entity over RPC. + +namespace Composer\Util; + +use Composer\IO\IOInterface; +use React\Promise\PromiseInterface; + +class ProcessExecutor implements \ShirabeRustStub +{ + /** @var int */ + protected $__rhandle; + /** @var int */ + protected $__epoch; + + /** + * Binds a stub the registry built for an existing entity. Proxy instantiation bypasses + * the constructor, which belongs to plugin code building a new entity instead. + */ + public function __shirabeBind(int $rhandle, int $epoch): void + { + $this->__rhandle = $rhandle; + $this->__epoch = $epoch; + } + + public function __destruct() + { + \ShirabeRustObjectRegistry::release($this->__rhandle); + } + + public function __shirabeRustHandleDescriptor(): array + { + return [ + '__rhandle' => $this->__rhandle, + '__class' => static::class, + '__epoch' => $this->__epoch, + ]; + } + + public function __clone() + { + // PHP has already shallow-copied this stub, so both copies would point at one + // entity and release it twice. The Rust side clones the entity instead, applying + // whatever __clone semantics the real class defines, and this copy rebinds to the + // fresh handle. Entities without clone semantics answer with an explicit error. + [$this->__rhandle, $this->__epoch] = \ShirabeRpcRuntime::callRust($this->__rhandle, '__shirabeClone', []); + \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(?IOInterface $io = null) + { + [$this->__rhandle, $this->__epoch] = \ShirabeRpcRuntime::callRust(0, '__shirabeConstruct', [static::class, [$io]]); + \ShirabeRustObjectRegistry::adopt($this->__rhandle, $this); + } + + private const STATUS_QUEUED = 1; + private const STATUS_STARTED = 2; + private const STATUS_COMPLETED = 3; + private const STATUS_FAILED = 4; + private const STATUS_ABORTED = 5; + private const BUILTIN_CMD_COMMANDS = [ + 'assoc', 'break', 'call', 'cd', 'chdir', 'cls', 'color', 'copy', 'date', + 'del', 'dir', 'echo', 'endlocal', 'erase', 'exit', 'for', 'ftype', 'goto', + 'help', 'if', 'label', 'md', 'mkdir', 'mklink', 'move', 'path', 'pause', + 'popd', 'prompt', 'pushd', 'rd', 'rem', 'ren', 'rename', 'rmdir', 'set', + 'setlocal', 'shift', 'start', 'time', 'title', 'type', 'ver', 'vol', + ]; + private const GIT_CMDS_NEED_GIT_DIR = [ + ['show'], + ['log'], + ['branch'], + ['remote', 'set-url'], + ]; + + // Forwarded rather than materialized: it reads the static property $timeout, whose value the Rust side owns. + public static function getTimeout(): int + { + return \ShirabeRpcRuntime::callRust(0, '__shirabeCallStatic', [self::class, 'getTimeout', []]); + } + + // Forwarded rather than materialized: it reads the static property $timeout, whose value the Rust side owns. + public static function setTimeout(int $timeout): void + { + \ShirabeRpcRuntime::callRust(0, '__shirabeCallStatic', [self::class, 'setTimeout', [$timeout]]); + } + + // Forwarded rather than materialized: it references Composer\Util\Platform, which a guard shadows in the worker. + public static function escape($argument): string + { + return \ShirabeRpcRuntime::callRust(0, '__shirabeCallStatic', [self::class, 'escape', [$argument]]); + } + + public function execute($command, &$output = null, ?string $cwd = null): int + { + $__args = [$command, $output, $cwd]; + array_splice($__args, func_num_args()); + $__out = []; + $__result = \ShirabeRpcRuntime::callRust($this->__rhandle, 'execute', $__args, [1], $__out); + if (array_key_exists(1, $__out)) { + $output = $__out[1]; + } + return $__result; + } + + public function executeTty($command, ?string $cwd = null): int + { + return \ShirabeRpcRuntime::callRust($this->__rhandle, 'executeTty', [$command, $cwd]); + } + + public function executeAsync($command, ?string $cwd = null): PromiseInterface + { + return \ShirabeRpcRuntime::callRust($this->__rhandle, 'executeAsync', [$command, $cwd]); + } + + public function setMaxJobs(int $maxJobs): void + { + \ShirabeRpcRuntime::callRust($this->__rhandle, 'setMaxJobs', [$maxJobs]); + } + + public function resetMaxJobs(): void + { + \ShirabeRpcRuntime::callRust($this->__rhandle, 'resetMaxJobs', []); + } + + public function wait($index = null): void + { + \ShirabeRpcRuntime::callRust($this->__rhandle, 'wait', [$index]); + } + + public function enableAsync(): void + { + \ShirabeRpcRuntime::callRust($this->__rhandle, 'enableAsync', []); + } + + public function countActiveJobs($index = null): int + { + return \ShirabeRpcRuntime::callRust($this->__rhandle, 'countActiveJobs', [$index]); + } + + public function splitLines(?string $output): array + { + return \ShirabeRpcRuntime::callRust($this->__rhandle, 'splitLines', [$output]); + } + + public function getErrorOutput(): string + { + return \ShirabeRpcRuntime::callRust($this->__rhandle, 'getErrorOutput', []); + } + + public function requiresGitDirEnv($command): bool + { + return \ShirabeRpcRuntime::callRust($this->__rhandle, 'requiresGitDirEnv', [$command]); + } +} diff --git a/crates/shirabe-php-rpc/php/worker.php b/crates/shirabe-php-rpc/php/worker.php index 6ed5df40..bc10c2de 100644 --- a/crates/shirabe-php-rpc/php/worker.php +++ b/crates/shirabe-php-rpc/php/worker.php @@ -295,15 +295,29 @@ final class ShirabeRpcRuntime return array_map([self::class, 'fromWire'], $value); } - /** Sends a CallRustMethod request and drives the cooperative loop until its Return. */ - public static function callRust(int $rhandle, string $method, array $args) - { + /** + * Sends a CallRustMethod request and drives the cooperative loop until its Return. + * + * `$outParamPositions` names the by-ref parameters of the called method; the Rust side + * answers with the value each of them holds afterwards, and the caller (a generated stub) + * assigns those back to its own by-ref parameters. + * + * @param list<int> $outParamPositions + * @param array<int, mixed>|null $outParams + */ + public static function callRust( + int $rhandle, + string $method, + array $args, + array $outParamPositions = [], + ?array &$outParams = null + ) { $corrId = self::$nextCorrId; self::$nextCorrId += 2; self::writeFrame( SHIRABE_TAG_CALL_RUST_METHOD, $corrId, - serialize([$rhandle, $method, self::toWire($args), []]) + serialize([$rhandle, $method, self::toWire($args), $outParamPositions]) ); while (true) { $frame = self::readFrame(); @@ -320,6 +334,7 @@ final class ShirabeRpcRuntime self::fail('protocol violation: unparseable response payload'); } if ($tag === SHIRABE_TAG_RETURN) { + $outParams = self::fromWire($fields[1] ?? []); return self::fromWire($fields[0]); } [$class, $message, $code] = $fields; |
