From e8d6a57d157ab778108bcb044a3dfa5952d4a5ae Mon Sep 17 00:00:00 2001 From: nsfisis Date: Sun, 7 Jun 2026 18:47:59 +0900 Subject: feat(phase-c): resolve dynamic-dispatch phase-b TODOs Replace the PHP `call_user_func([$obj, $method], ...)` / `$obj->{'get'.$x}()` dynamic dispatches (category E) with static Rust dispatch. - json_config_source: inject the clean-update as a typed `FnOnce(&mut JsonManipulator) -> Result` closure instead of a method-name string, dropping the call_user_func_array round-trip through PhpMixed args. The auth-config method override moves into the add/remove_config_setting closures. - config_command: dispatch addConfigSetting/addProperty on the concrete JsonConfigSource via match. - locker: select getRequires/getDevRequires and getReplaces/getProvides via match on the existing handle getters (previously stubbed to empty Vec). - create_project_command: reuse the existing get_links_for_type helper. Co-Authored-By: Claude Opus 4.8 (1M context) --- crates/shirabe/src/package/locker.rs | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'crates/shirabe/src/package/locker.rs') diff --git a/crates/shirabe/src/package/locker.rs b/crates/shirabe/src/package/locker.rs index 51177db..91affe2 100644 --- a/crates/shirabe/src/package/locker.rs +++ b/crates/shirabe/src/package/locker.rs @@ -951,9 +951,12 @@ impl Locker { let installed_repo = InstalledRepository::new(vec![/* set.repo, root_repo */]); // PHP: call_user_func([$package, $set['method']]) - // TODO(phase-b): dynamic method dispatch by name - let links: Vec = vec![]; - for link in links { + let links = match set.method.as_str() { + "getRequires" => package.get_requires(), + "getDevRequires" => package.get_dev_requires(), + _ => unreachable!(), + }; + for link in links.values() { if PlatformRepository::is_platform_package(&link.get_target()) { continue; } @@ -984,10 +987,12 @@ impl Locker { ] .iter() { - // TODO(phase-b): dynamic method dispatch - let provider_links: Vec = vec![]; - let _ = method; - for provider_link in provider_links { + let provider_links = match *method { + "getReplaces" => provider.get_replaces(), + "getProvides" => provider.get_provides(), + _ => unreachable!(), + }; + for provider_link in provider_links.values() { if provider_link.get_target() == link.get_target() { description = sprintf( text, -- cgit v1.3.1