aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe/src/plugin
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-05-25 00:58:20 +0900
committernsfisis <nsfisis@gmail.com>2026-05-25 00:58:36 +0900
commit1921f173ea219cb4b25847294d2d3fa465550fbb (patch)
tree0d30486a2cb9a0c106e5d5827be3f655c60cd871 /crates/shirabe/src/plugin
parentdbdecaf5a1c54a876b7ee0153d58dd39b1080f97 (diff)
downloadphp-shirabe-1921f173ea219cb4b25847294d2d3fa465550fbb.tar.gz
php-shirabe-1921f173ea219cb4b25847294d2d3fa465550fbb.tar.zst
php-shirabe-1921f173ea219cb4b25847294d2d3fa465550fbb.zip
refactor(package): introduce Rc<RefCell<_>> handles for packages
PHP packages have reference semantics, so introduce shared-ownership handles over an AnyPackage enum (PackageInterfaceHandle and friends) and replace Box<dyn PackageInterface> throughout. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe/src/plugin')
-rw-r--r--crates/shirabe/src/plugin/plugin_manager.rs81
-rw-r--r--crates/shirabe/src/plugin/pre_pool_create_event.rs18
2 files changed, 56 insertions, 43 deletions
diff --git a/crates/shirabe/src/plugin/plugin_manager.rs b/crates/shirabe/src/plugin/plugin_manager.rs
index 77ac577..ddde387 100644
--- a/crates/shirabe/src/plugin/plugin_manager.rs
+++ b/crates/shirabe/src/plugin/plugin_manager.rs
@@ -25,6 +25,7 @@ use crate::package::CompletePackage;
use crate::package::Link;
use crate::package::Locker;
use crate::package::PackageInterface;
+use crate::package::PackageInterfaceHandle;
use crate::package::RootPackageInterface;
use crate::package::base_package::{self, BasePackage};
use crate::package::version::VersionParser;
@@ -143,10 +144,20 @@ impl PluginManager {
.borrow()
.get_local_repository()
.clone_box();
- // The root package borrow is also tied to `self.composer`; clone the package box
- // for the same reason as above.
- let root_package = self.composer_full().borrow().get_package().clone_box();
- self.load_repository(&*repo, false, Some(&*root_package))?;
+ // The root package borrow is also tied to `self.composer`; clone the package handle
+ // (shared Rc) for the same reason as above.
+ let root_package = self.composer_full().borrow().get_package().clone();
+ self.load_repository(
+ &*repo,
+ false,
+ Some(
+ root_package
+ .as_rc()
+ .borrow()
+ .as_root_package_interface()
+ .unwrap(),
+ ),
+ )?;
}
if self.global_composer.is_some() && !self.are_plugins_disabled("global") {
@@ -532,23 +543,18 @@ impl PluginManager {
}
let sorted_packages = PackageSorter::sort_packages(
- packages.iter().map(|p| p.clone_package_box()).collect(),
+ packages.iter().map(|p| p.clone().into()).collect(),
weights,
);
- let required_packages: Vec<Box<dyn PackageInterface>> = if !is_global_repo {
+ let required_packages: Vec<crate::package::BasePackageHandle> = if !is_global_repo {
// PHP: $requiredPackages = RepositoryUtils::filterRequiredPackages($packages, $rootPackage, true);
- // RepositoryUtils::filter_required_packages takes &[Box<dyn BasePackage>] plus a bucket.
- // We need to convert &[Box<dyn BasePackage>] from packages.
- let bucket: Vec<Box<dyn crate::package::BasePackage>> = vec![];
+ let bucket: Vec<crate::package::BasePackageHandle> = vec![];
RepositoryUtils::filter_required_packages(
packages.as_slice(),
- root_package.unwrap(),
+ root_package.unwrap() as &dyn PackageInterface,
true,
bucket,
)
- .iter()
- .map(|p| p.clone_package_box())
- .collect()
} else {
vec![]
};
@@ -565,26 +571,33 @@ impl PluginManager {
}
// PHP: !in_array($package, $requiredPackages, true) — identity-based comparison.
- // Compare data pointers since `sorted_packages` and `required_packages` are both
- // `Box<dyn PackageInterface>`.
- let package_addr =
- package.as_ref() as *const dyn PackageInterface as *const () as usize;
- let in_required = required_packages.iter().any(|rp| {
- (rp.as_ref() as *const dyn PackageInterface as *const () as usize) == package_addr
- });
+ // Both `sorted_packages` and `required_packages` are package handles, so compare
+ // by shared-Rc pointer identity.
+ let package_addr = package.ptr_id();
+ let in_required = required_packages
+ .iter()
+ .any(|rp| rp.ptr_id() == package_addr);
if !is_global_repo
&& !in_required
- && !self.is_plugin_allowed(package.get_name(), false, true, false)?
+ && !self.is_plugin_allowed(&package.get_name(), false, true, false)?
{
self.io.write_error(&format!("<warning>The \"{}\" plugin was not loaded as it is not listed in allow-plugins and is not required by the root package anymore.</warning>", package.get_name()));
continue;
}
if "composer-plugin" == package.get_type() {
- self.register_package(&**package, false, is_global_repo)?;
+ self.register_package(
+ package.as_rc().borrow().as_package_interface(),
+ false,
+ is_global_repo,
+ )?;
// Backward compatibility
} else if "composer-installer" == package.get_type() {
- self.register_package(&**package, false, is_global_repo)?;
+ self.register_package(
+ package.as_rc().borrow().as_package_interface(),
+ false,
+ is_global_repo,
+ )?;
}
let _ = cp;
}
@@ -596,7 +609,7 @@ impl PluginManager {
let packages = repo.get_packages();
// PHP: $sortedPackages = array_reverse(PackageSorter::sortPackages($packages));
let mut sorted_packages = PackageSorter::sort_packages(
- packages.iter().map(|p| p.clone_package_box()).collect(),
+ packages.iter().map(|p| p.clone().into()).collect(),
IndexMap::new(),
);
sorted_packages.reverse();
@@ -606,10 +619,10 @@ impl PluginManager {
continue;
}
if "composer-plugin" == package.get_type() {
- self.deactivate_package(&**package);
+ self.deactivate_package(package.as_rc().borrow().as_package_interface());
// Backward compatibility
} else if "composer-installer" == package.get_type() {
- self.deactivate_package(&**package);
+ self.deactivate_package(package.as_rc().borrow().as_package_interface());
}
}
}
@@ -617,21 +630,21 @@ impl PluginManager {
fn collect_dependencies(
&self,
installed_repo: &InstalledRepository,
- mut collected: IndexMap<String, Box<dyn PackageInterface>>,
+ mut collected: IndexMap<String, PackageInterfaceHandle>,
package: &dyn PackageInterface,
- ) -> IndexMap<String, Box<dyn PackageInterface>> {
+ ) -> IndexMap<String, PackageInterfaceHandle> {
// TODO(plugin): used by registerPackage to assemble plugin dependency autoload map
for (_k, require_link) in &package.get_requires() {
for required_package in installed_repo
.find_packages_with_replacers_and_providers(require_link.get_target(), None)
{
- if !collected.contains_key(required_package.get_name()) {
- collected.insert(
- required_package.get_name().to_string(),
- required_package.clone_package_box(),
+ if !collected.contains_key(&required_package.get_name()) {
+ collected.insert(required_package.get_name(), required_package.clone().into());
+ collected = self.collect_dependencies(
+ installed_repo,
+ collected,
+ required_package.as_rc().borrow().as_package_interface(),
);
- collected =
- self.collect_dependencies(installed_repo, collected, &*required_package);
}
}
}
diff --git a/crates/shirabe/src/plugin/pre_pool_create_event.rs b/crates/shirabe/src/plugin/pre_pool_create_event.rs
index f4426f7..2bbaa6c 100644
--- a/crates/shirabe/src/plugin/pre_pool_create_event.rs
+++ b/crates/shirabe/src/plugin/pre_pool_create_event.rs
@@ -4,7 +4,7 @@ use indexmap::IndexMap;
use crate::dependency_resolver::Request;
use crate::event_dispatcher::Event;
-use crate::package::BasePackage;
+use crate::package::BasePackageHandle;
use crate::repository::RepositoryInterface;
#[derive(Debug)]
@@ -16,8 +16,8 @@ pub struct PrePoolCreateEvent {
stability_flags: IndexMap<String, i64>,
root_aliases: IndexMap<String, IndexMap<String, IndexMap<String, String>>>,
root_references: IndexMap<String, String>,
- packages: Vec<Box<dyn BasePackage>>,
- unacceptable_fixed_packages: Vec<Box<dyn BasePackage>>,
+ packages: Vec<BasePackageHandle>,
+ unacceptable_fixed_packages: Vec<BasePackageHandle>,
}
impl PrePoolCreateEvent {
@@ -34,8 +34,8 @@ impl PrePoolCreateEvent {
stability_flags: IndexMap<String, i64>,
root_aliases: IndexMap<String, IndexMap<String, IndexMap<String, String>>>,
root_references: IndexMap<String, String>,
- packages: Vec<Box<dyn BasePackage>>,
- unacceptable_fixed_packages: Vec<Box<dyn BasePackage>>,
+ packages: Vec<BasePackageHandle>,
+ unacceptable_fixed_packages: Vec<BasePackageHandle>,
) -> Self {
Self {
inner: Event::new(name, vec![], IndexMap::new()),
@@ -76,19 +76,19 @@ impl PrePoolCreateEvent {
&self.root_references
}
- pub fn get_packages(&self) -> &Vec<Box<dyn BasePackage>> {
+ pub fn get_packages(&self) -> &Vec<BasePackageHandle> {
&self.packages
}
- pub fn get_unacceptable_fixed_packages(&self) -> &Vec<Box<dyn BasePackage>> {
+ pub fn get_unacceptable_fixed_packages(&self) -> &Vec<BasePackageHandle> {
&self.unacceptable_fixed_packages
}
- pub fn set_packages(&mut self, packages: Vec<Box<dyn BasePackage>>) {
+ pub fn set_packages(&mut self, packages: Vec<BasePackageHandle>) {
self.packages = packages;
}
- pub fn set_unacceptable_fixed_packages(&mut self, packages: Vec<Box<dyn BasePackage>>) {
+ pub fn set_unacceptable_fixed_packages(&mut self, packages: Vec<BasePackageHandle>) {
self.unacceptable_fixed_packages = packages;
}
}