From da0d38a8e16ebefd59ef5291b5788e6238cc78ba Mon Sep 17 00:00:00 2001 From: nsfisis Date: Sat, 8 Aug 2026 03:04:27 +0900 Subject: refactor(semver): replace Constraint's OP_*/STR_OP_* with CmpOp PHP's version_compare takes its operator as a string, so the shim's port did too, and Constraint carried two families of operator constants plus translation tables to convert between the string form and its own int codes. Five copies of those tables had accumulated across Constraint, CompilingMatcher and the plugin value bridge. version_compare now takes a CmpOp, which makes an invalid operator unrepresentable and removes the tables' reason to exist. Constraint stores a CmpOp and keeps only the string parsing its constructor needs; getOperator, compile and CompilingMatcher::match speak CmpOp as well. PHP's OP_* numbering stays observable: a plugin reads the raw integer off the Constraint object over RPC, so get_operator_constant and its new inverse hold that 0..5 mapping. Co-Authored-By: Claude Opus 5 (1M context) --- .../src/dependency_resolver/default_policy.rs | 3 ++- crates/shirabe/src/dependency_resolver/pool.rs | 8 ++------ .../shirabe/src/dependency_resolver/pool_builder.rs | 5 ++--- .../src/dependency_resolver/pool_optimizer.rs | 20 ++++++-------------- crates/shirabe/src/dependency_resolver/problem.rs | 20 ++++++++++---------- 5 files changed, 22 insertions(+), 34 deletions(-) (limited to 'crates/shirabe/src/dependency_resolver') diff --git a/crates/shirabe/src/dependency_resolver/default_policy.rs b/crates/shirabe/src/dependency_resolver/default_policy.rs index d81c8621..8c1a7697 100644 --- a/crates/shirabe/src/dependency_resolver/default_policy.rs +++ b/crates/shirabe/src/dependency_resolver/default_policy.rs @@ -6,6 +6,7 @@ use crate::package::BasePackageHandle; use crate::package::STABILITIES; use crate::util::Platform; use indexmap::IndexMap; +use shirabe_php_shim::CmpOp; use shirabe_php_shim::PhpMixed; use shirabe_semver::CompilingMatcher; use shirabe_semver::constraint::SimpleConstraint; @@ -205,7 +206,7 @@ impl PolicyInterface for DefaultPolicy { CompilingMatcher::r#match( &SimpleConstraint::new(operator.to_string(), b.get_version(), None).into(), - SimpleConstraint::OP_EQ, + CmpOp::Eq, a.get_version(), ) } diff --git a/crates/shirabe/src/dependency_resolver/pool.rs b/crates/shirabe/src/dependency_resolver/pool.rs index 80534b0a..a0dfd362 100644 --- a/crates/shirabe/src/dependency_resolver/pool.rs +++ b/crates/shirabe/src/dependency_resolver/pool.rs @@ -4,7 +4,7 @@ use crate::advisory::AnySecurityAdvisory; use crate::package::BasePackageHandle; use crate::package::version::VersionParser; use indexmap::IndexMap; -use shirabe_php_shim::{STR_PAD_LEFT, str_pad}; +use shirabe_php_shim::{CmpOp, STR_PAD_LEFT, str_pad}; use shirabe_semver::CompilingMatcher; use shirabe_semver::constraint::AnyConstraint; use shirabe_semver::constraint::SimpleConstraint; @@ -305,11 +305,7 @@ impl Pool { if candidate_name == name { return constraint.is_none() - || CompilingMatcher::r#match( - constraint.unwrap(), - SimpleConstraint::OP_EQ, - candidate_version, - ); + || CompilingMatcher::r#match(constraint.unwrap(), CmpOp::Eq, candidate_version); } let provides = candidate.get_provides(); diff --git a/crates/shirabe/src/dependency_resolver/pool_builder.rs b/crates/shirabe/src/dependency_resolver/pool_builder.rs index 137a36ba..35699a90 100644 --- a/crates/shirabe/src/dependency_resolver/pool_builder.rs +++ b/crates/shirabe/src/dependency_resolver/pool_builder.rs @@ -21,7 +21,7 @@ use crate::repository::RootPackageRepository; use indexmap::IndexMap; use shirabe_external_packages::composer::pcre::Preg; use shirabe_php_shim::{ - LogicException, PhpMixed, array_flip_strings, array_map, in_array_strict, microtime, + CmpOp, LogicException, PhpMixed, array_flip_strings, array_map, in_array_strict, microtime, number_format, round, strpos, }; use shirabe_semver::CompilingMatcher; @@ -29,7 +29,6 @@ use shirabe_semver::Intervals; use shirabe_semver::constraint::AnyConstraint; use shirabe_semver::constraint::MatchAllConstraint; use shirabe_semver::constraint::MultiConstraint; -use shirabe_semver::constraint::SimpleConstraint; #[derive(Debug)] pub struct PoolBuilder { @@ -289,7 +288,7 @@ impl PoolBuilder { for (_idx, package_or_alias) in &package_and_aliases { if CompilingMatcher::r#match( &constraint, - SimpleConstraint::OP_EQ, + CmpOp::Eq, package_or_alias.get_version(), ) { found = true; diff --git a/crates/shirabe/src/dependency_resolver/pool_optimizer.rs b/crates/shirabe/src/dependency_resolver/pool_optimizer.rs index 972d2f21..5aca700e 100644 --- a/crates/shirabe/src/dependency_resolver/pool_optimizer.rs +++ b/crates/shirabe/src/dependency_resolver/pool_optimizer.rs @@ -6,7 +6,7 @@ use crate::dependency_resolver::Request; use crate::package::BasePackageHandle; use crate::package::version::VersionParser; use indexmap::IndexMap; -use shirabe_php_shim::{implode, ksort}; +use shirabe_php_shim::{CmpOp, implode, ksort}; use shirabe_semver::CompilingMatcher; use shirabe_semver::Intervals; use shirabe_semver::constraint::AnyConstraint; @@ -156,11 +156,7 @@ impl PoolOptimizer { let constraint = irremovable_package_constraints .get(&package.get_name()) .unwrap(); - if CompilingMatcher::r#match( - constraint, - SimpleConstraint::OP_EQ, - package.get_version().to_string(), - ) { + if CompilingMatcher::r#match(constraint, CmpOp::Eq, package.get_version().to_string()) { self.mark_package_irremovable(package.clone()); } } @@ -252,7 +248,7 @@ impl PoolOptimizer { if CompilingMatcher::r#match( require_constraint, - SimpleConstraint::OP_EQ, + CmpOp::Eq, package.get_version().to_string(), ) { group_hash_parts.push(format!( @@ -265,7 +261,7 @@ impl PoolOptimizer { for (_, link) in package.get_replaces() { if CompilingMatcher::r#match( link.get_constraint(), - SimpleConstraint::OP_EQ, + CmpOp::Eq, package.get_version().to_string(), ) { // Use the same hash part as the regular require hash because that's what the replacement does @@ -283,7 +279,7 @@ impl PoolOptimizer { for (_, conflict_constraint) in conflict_constraints { if CompilingMatcher::r#match( conflict_constraint, - SimpleConstraint::OP_EQ, + CmpOp::Eq, package.get_version().to_string(), ) { group_hash_parts.push(format!( @@ -605,11 +601,7 @@ impl PoolOptimizer { .and_then(|m| m.get(&id)) .map(|p| p.get_version()); if let Some(version_str) = version_str - && !CompilingMatcher::r#match( - link_constraint, - SimpleConstraint::OP_EQ, - version_str, - ) + && !CompilingMatcher::r#match(link_constraint, CmpOp::Eq, version_str) { self.mark_package_for_removal(id); if let Some(map) = package_index.get_mut(require) { diff --git a/crates/shirabe/src/dependency_resolver/problem.rs b/crates/shirabe/src/dependency_resolver/problem.rs index 8ee4b816..f9e525bf 100644 --- a/crates/shirabe/src/dependency_resolver/problem.rs +++ b/crates/shirabe/src/dependency_resolver/problem.rs @@ -13,8 +13,8 @@ use indexmap::IndexMap; use shirabe_external_packages::composer::pcre::{CaptureKey, Preg}; use shirabe_external_packages::symfony::console::formatter::OutputFormatter; use shirabe_php_shim::{ - LogicException, PhpMixed, defined, extension_loaded, implode, loosely_compare, php_regex, - phpversion, spl_object_hash, sprintf, str_replace, str_starts_with, stripos, strpos, + CmpOp, LogicException, PhpMixed, defined, extension_loaded, implode, loosely_compare, + php_regex, phpversion, spl_object_hash, sprintf, str_replace, str_starts_with, stripos, strpos, strtolower, substr, substr_count, version_compare, }; use shirabe_semver::constraint::AnyConstraint; @@ -284,9 +284,9 @@ impl Problem { // uksort($versions, 'version_compare') let mut keys: Vec = versions.keys().cloned().collect(); keys.sort_by(|a, b| { - if version_compare(a, b, "<") { + if version_compare(a, b, CmpOp::Lt) { std::cmp::Ordering::Less - } else if version_compare(a, b, ">") { + } else if version_compare(a, b, CmpOp::Gt) { std::cmp::Ordering::Greater } else { std::cmp::Ordering::Equal @@ -564,7 +564,7 @@ impl Problem { if let Some(c) = constraint && c.is_constraint() - && c.get_operator() == SimpleConstraint::STR_OP_EQ + && c.get_operator() == Some(CmpOp::Eq) && Preg::is_match3(php_regex!(r"{^dev-.*#.*}"), &c.get_pretty_string(), None) { let new_constraint = Preg::replace( @@ -578,12 +578,12 @@ impl Problem { MultiConstraint::new( vec![ AnyConstraint::Simple(SimpleConstraint::new( - SimpleConstraint::STR_OP_EQ.to_string(), + "==".to_string(), new_constraint.clone(), None, )), AnyConstraint::Simple(SimpleConstraint::new( - SimpleConstraint::STR_OP_EQ.to_string(), + "==".to_string(), str_replace("#", "+", &new_constraint), None, )), @@ -1102,9 +1102,9 @@ impl Problem { // uksort($package['versions'], 'version_compare') let mut keys: Vec = package.versions.keys().cloned().collect(); keys.sort_by(|a, b| { - if version_compare(a, b, "<") { + if version_compare(a, b, CmpOp::Lt) { std::cmp::Ordering::Less - } else if version_compare(a, b, ">") { + } else if version_compare(a, b, CmpOp::Gt) { std::cmp::Ordering::Greater } else { std::cmp::Ordering::Equal @@ -1386,7 +1386,7 @@ impl Problem { pub(crate) fn constraint_to_text(constraint: Option<&AnyConstraint>) -> String { if let Some(c) = constraint && c.is_constraint() - && c.get_operator() == SimpleConstraint::STR_OP_EQ + && c.get_operator() == Some(CmpOp::Eq) && !str_starts_with(c.get_version(), "dev-") { if !Preg::is_match3( -- cgit v1.3.1-4-g156e