From 92f5c977b42d1322f3cebb260024179e1285b9d0 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Sun, 2 Aug 2026 08:42:56 +0900 Subject: fix(symfony-console): dispatch parse_token to CompletionInput in bind PHP's Input::bind() -> ArgvInput::parse() calls $this->parseToken(), which late-binds to CompletionInput::parseToken; that override swallows per-token RuntimeExceptions so an incomplete command line still parses. Delegating CompletionInput::bind to ArgvInput::bind pinned the call to ArgvInput's parseToken, aborting the whole parse on the first invalid token and leaving CompletionInput::parse_token dead. parseToken is protected and not on any trait, so ArgvInput::base_bind threads the concrete implementation in as a callback instead of a trait object. Co-Authored-By: Claude Fable 5 --- .../src/symfony/console/completion/completion_input.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'crates/shirabe-external-packages/src/symfony/console/completion/completion_input.rs') diff --git a/crates/shirabe-external-packages/src/symfony/console/completion/completion_input.rs b/crates/shirabe-external-packages/src/symfony/console/completion/completion_input.rs index d076f8a3..a16575de 100644 --- a/crates/shirabe-external-packages/src/symfony/console/completion/completion_input.rs +++ b/crates/shirabe-external-packages/src/symfony/console/completion/completion_input.rs @@ -57,7 +57,10 @@ impl CompletionInput { } pub fn bind(&mut self, definition: &InputDefinition) -> anyhow::Result<()> { - self.inner.bind(definition)?; + self.inner + .base_bind(definition, |argv, token, parse_options| { + Ok(CompletionInput::parse_token(argv, token, parse_options)) + })?; let relevant_token = self.get_relevant_token(); if "-" == &relevant_token[0..1] { @@ -203,8 +206,11 @@ impl CompletionInput { self.inner.get_first_argument() } - pub(crate) fn parse_token(&mut self, token: &str, parse_options: bool) -> bool { - match self.inner.parse_token(token, parse_options) { + /// PHP `CompletionInput::parseToken` (called back from `ArgvInput::base_bind`). Takes the + /// embedded ArgvInput instead of `&mut self` because the parse loop already holds the + /// exclusive borrow of it. + fn parse_token(inner: &mut ArgvInput, token: &str, parse_options: bool) -> bool { + match inner.parse_token(token, parse_options) { Ok(value) => return value, Err(_e) => { // suppress errors, completed input is almost never valid -- cgit v1.3.1