diff --git a/scarb/src/compiler/compilation_unit.rs b/scarb/src/compiler/compilation_unit.rs index b279c7f2f..a410821cd 100644 --- a/scarb/src/compiler/compilation_unit.rs +++ b/scarb/src/compiler/compilation_unit.rs @@ -11,10 +11,16 @@ use crate::flock::Filesystem; use crate::internal::stable_hash::StableHasher; /// An object that has enough information so that Scarb knows how to build it. +pub enum CompilationUnit { + Cairo(CairoCompilationUnit), + ProcMacro(ProcMacroCompilationUnit), +} + +/// An object that has enough information so that Scarb knows how to build Cairo code with it. #[derive(Clone, Debug)] #[non_exhaustive] -pub struct CompilationUnit { - /// The Scarb [`Package`] to be build. +pub struct CairoCompilationUnit { + /// The Scarb [`Package`] to be built. pub main_package_id: PackageId, /// Collection of all [`Package`]s needed to provide as _crate roots_ to @@ -43,11 +49,29 @@ pub struct CompilationUnit { pub cfg_set: CfgSet, } +/// An object that has enough information so that Scarb knows how to build procedural macro with it. +#[derive(Clone, Debug)] +#[non_exhaustive] +pub struct ProcMacroCompilationUnit { + /// The Scarb [`Package`] to be built. + pub main_package_id: PackageId, + + /// Collection of all [`Package`]s needed in order to build `package`. + /// + /// ## Invariants + /// + /// For performance purposes, the component describing the main package is always **first**. + pub components: Vec, + + /// Rust compiler configuration parameters to use in this unit. + pub compiler_config: serde_json::Value, +} + /// Information about a single package that is part of a [`CompilationUnit`]. #[derive(Clone, Debug)] #[non_exhaustive] pub struct CompilationUnitComponent { - /// The Scarb [`Package`] to be build. + /// The Scarb [`Package`] to be built. pub package: Package, /// Information about the specific target to build, out of the possible targets in `package`. pub target: Target, @@ -64,38 +88,27 @@ pub struct CompilationUnitCairoPlugin { pub builtin: bool, } -impl CompilationUnit { - pub fn main_component(&self) -> &CompilationUnitComponent { - // NOTE: This uses the order invariant of `component` field. - let component = &self.components[0]; - assert_eq!(component.package.id, self.main_package_id); - component - } +pub trait CompilationUnitAttributes { + fn main_package_id(&self) -> PackageId; + fn components(&self) -> &[CompilationUnitComponent]; + fn digest(&self) -> String; - pub fn core_package_component(&self) -> Option<&CompilationUnitComponent> { + fn main_component(&self) -> &CompilationUnitComponent { // NOTE: This uses the order invariant of `component` field. - if self.components.len() < 2 { - None - } else { - let component = &self.components[1]; - assert!(component.package.id.is_core()); - Some(component) - } + let component = &self.components()[0]; + assert_eq!(component.package.id, self.main_package_id()); + component } - pub fn target(&self) -> &Target { + fn target(&self) -> &Target { &self.main_component().target } - pub fn target_dir(&self, ws: &Workspace<'_>) -> Filesystem { - ws.target_dir().child(self.profile.as_str()) + fn id(&self) -> String { + format!("{}-{}", self.main_package_id().name, self.digest()) } - pub fn is_cairo_plugin(&self) -> bool { - self.target().is_cairo_plugin() - } - - pub fn is_sole_for_package(&self) -> bool { + fn is_sole_for_package(&self) -> bool { self.main_component() .package .manifest @@ -106,15 +119,11 @@ impl CompilationUnit { >= 2 } - pub fn has_custom_name(&self) -> bool { - self.main_component().target.kind.as_str() != self.main_package_id.name.as_str() - } - - pub fn id(&self) -> String { - format!("{}-{}", self.main_package_id.name, self.digest()) + fn has_custom_name(&self) -> bool { + self.main_component().target.kind.as_str() != self.main_package_id().name.as_str() } - pub fn name(&self) -> String { + fn name(&self) -> String { let mut string = String::new(); let main_component = self.main_component(); @@ -128,12 +137,42 @@ impl CompilationUnit { write!(&mut string, " ").unwrap(); } - write!(&mut string, "{}", self.main_package_id).unwrap(); + write!(&mut string, "{}", self.main_package_id()).unwrap(); string } +} - pub fn digest(&self) -> String { +impl CompilationUnitAttributes for CompilationUnit { + fn main_package_id(&self) -> PackageId { + match self { + Self::Cairo(unit) => unit.main_package_id(), + Self::ProcMacro(unit) => unit.main_package_id(), + } + } + fn components(&self) -> &[CompilationUnitComponent] { + match self { + Self::Cairo(unit) => unit.components(), + Self::ProcMacro(unit) => unit.components(), + } + } + fn digest(&self) -> String { + match self { + Self::Cairo(unit) => unit.digest(), + Self::ProcMacro(unit) => unit.digest(), + } + } +} + +impl CompilationUnitAttributes for CairoCompilationUnit { + fn main_package_id(&self) -> PackageId { + self.main_package_id + } + fn components(&self) -> &[CompilationUnitComponent] { + &self.components + } + + fn digest(&self) -> String { let mut hasher = StableHasher::new(); self.main_package_id.hash(&mut hasher); for component in &self.components { @@ -145,6 +184,45 @@ impl CompilationUnit { } } +impl CompilationUnitAttributes for ProcMacroCompilationUnit { + fn main_package_id(&self) -> PackageId { + self.main_package_id + } + fn components(&self) -> &[CompilationUnitComponent] { + &self.components + } + + fn digest(&self) -> String { + let mut hasher = StableHasher::new(); + self.main_package_id.hash(&mut hasher); + for component in &self.components { + component.hash(&mut hasher); + } + hasher.finish_as_short_hash() + } +} + +impl CairoCompilationUnit { + pub fn core_package_component(&self) -> Option<&CompilationUnitComponent> { + // NOTE: This uses the order invariant of `component` field. + if self.components.len() < 2 { + None + } else { + let component = &self.components[1]; + assert!(component.package.id.is_core()); + Some(component) + } + } + + pub fn target_dir(&self, ws: &Workspace<'_>) -> Filesystem { + ws.target_dir().child(self.profile.as_str()) + } + + pub fn is_cairo_plugin(&self) -> bool { + self.target().is_cairo_plugin() + } +} + impl CompilationUnitComponent { pub fn cairo_package_name(&self) -> SmolStr { self.package.id.name.to_smol_str() diff --git a/scarb/src/compiler/compilers/lib.rs b/scarb/src/compiler/compilers/lib.rs index a5f9eaa32..3266f179e 100644 --- a/scarb/src/compiler/compilers/lib.rs +++ b/scarb/src/compiler/compilers/lib.rs @@ -7,7 +7,7 @@ use tracing::trace_span; use crate::compiler::helpers::{ build_compiler_config, collect_main_crate_ids, write_json, write_string, }; -use crate::compiler::{CompilationUnit, Compiler}; +use crate::compiler::{CairoCompilationUnit, CompilationUnitAttributes, Compiler}; use crate::core::{TargetKind, Workspace}; pub struct LibCompiler; @@ -37,7 +37,7 @@ impl Compiler for LibCompiler { fn compile( &self, - unit: CompilationUnit, + unit: CairoCompilationUnit, db: &mut RootDatabase, ws: &Workspace<'_>, ) -> Result<()> { diff --git a/scarb/src/compiler/compilers/starknet_contract.rs b/scarb/src/compiler/compilers/starknet_contract.rs index bb1d81550..2223df3b4 100644 --- a/scarb/src/compiler/compilers/starknet_contract.rs +++ b/scarb/src/compiler/compilers/starknet_contract.rs @@ -22,7 +22,7 @@ use smol_str::SmolStr; use tracing::{debug, trace, trace_span}; use crate::compiler::helpers::{build_compiler_config, collect_main_crate_ids, write_json}; -use crate::compiler::{CompilationUnit, Compiler}; +use crate::compiler::{CairoCompilationUnit, CompilationUnitAttributes, Compiler}; use crate::core::{PackageName, TargetKind, Utf8PathWorkspaceExt, Workspace}; use crate::internal::serdex::RelativeUtf8PathBuf; use crate::internal::stable_hash::short_hash; @@ -199,7 +199,7 @@ impl Compiler for StarknetContractCompiler { fn compile( &self, - unit: CompilationUnit, + unit: CairoCompilationUnit, db: &mut RootDatabase, ws: &Workspace<'_>, ) -> Result<()> { @@ -372,7 +372,7 @@ fn check_allowed_libfuncs( contracts: &[&ContractDeclaration], classes: &[ContractClass], db: &RootDatabase, - unit: &CompilationUnit, + unit: &CairoCompilationUnit, ws: &Workspace<'_>, ) -> Result<()> { if !props.allowed_libfuncs { diff --git a/scarb/src/compiler/compilers/test.rs b/scarb/src/compiler/compilers/test.rs index 9dd00cf22..3af12ae4f 100644 --- a/scarb/src/compiler/compilers/test.rs +++ b/scarb/src/compiler/compilers/test.rs @@ -6,7 +6,7 @@ use tracing::trace_span; use crate::compiler::helpers::{ build_compiler_config, collect_all_crate_ids, collect_main_crate_ids, write_json, }; -use crate::compiler::{CompilationUnit, Compiler}; +use crate::compiler::{CairoCompilationUnit, CompilationUnitAttributes, Compiler}; use crate::core::{PackageName, SourceId, TargetKind, Workspace}; pub struct TestCompiler; @@ -18,7 +18,7 @@ impl Compiler for TestCompiler { fn compile( &self, - unit: CompilationUnit, + unit: CairoCompilationUnit, db: &mut RootDatabase, ws: &Workspace<'_>, ) -> Result<()> { diff --git a/scarb/src/compiler/db.rs b/scarb/src/compiler/db.rs index 424a60244..0df4ed91b 100644 --- a/scarb/src/compiler/db.rs +++ b/scarb/src/compiler/db.rs @@ -12,13 +12,13 @@ use std::sync::Arc; use tracing::trace; use crate::compiler::plugin::proc_macro::ProcMacroHost; -use crate::compiler::{CompilationUnit, CompilationUnitComponent}; +use crate::compiler::{CairoCompilationUnit, CompilationUnitAttributes, CompilationUnitComponent}; use crate::core::Workspace; use crate::DEFAULT_MODULE_MAIN_FILE; // TODO(mkaput): ScarbDatabase? pub(crate) fn build_scarb_root_database( - unit: &CompilationUnit, + unit: &CairoCompilationUnit, ws: &Workspace<'_>, ) -> Result { let mut b = RootDatabase::builder(); @@ -31,7 +31,7 @@ pub(crate) fn build_scarb_root_database( } fn load_plugins( - unit: &CompilationUnit, + unit: &CairoCompilationUnit, ws: &Workspace<'_>, builder: &mut RootDatabaseBuilder, ) -> Result<()> { @@ -55,7 +55,7 @@ fn load_plugins( /// This approach allows compiling crates that do not define `lib.cairo` file. /// For example, single file crates can be created this way. /// The actual single file module is defined as `mod` item in created lib file. -fn inject_virtual_wrapper_lib(db: &mut RootDatabase, unit: &CompilationUnit) -> Result<()> { +fn inject_virtual_wrapper_lib(db: &mut RootDatabase, unit: &CairoCompilationUnit) -> Result<()> { let components: Vec<&CompilationUnitComponent> = unit .components .iter() @@ -90,7 +90,7 @@ fn inject_virtual_wrapper_lib(db: &mut RootDatabase, unit: &CompilationUnit) -> Ok(()) } -fn build_project_config(unit: &CompilationUnit) -> Result { +fn build_project_config(unit: &CairoCompilationUnit) -> Result { let crate_roots = unit .components .iter() diff --git a/scarb/src/compiler/helpers.rs b/scarb/src/compiler/helpers.rs index d7f47e6bb..7a6285211 100644 --- a/scarb/src/compiler/helpers.rs +++ b/scarb/src/compiler/helpers.rs @@ -10,11 +10,14 @@ use cairo_lang_filesystem::ids::{CrateId, CrateLongId}; use serde::Serialize; use std::io::{BufWriter, Write}; -use crate::compiler::CompilationUnit; +use crate::compiler::{CairoCompilationUnit, CompilationUnitAttributes}; use crate::core::Workspace; use crate::flock::Filesystem; -pub fn build_compiler_config<'c>(unit: &CompilationUnit, ws: &Workspace<'c>) -> CompilerConfig<'c> { +pub fn build_compiler_config<'c>( + unit: &CairoCompilationUnit, + ws: &Workspace<'c>, +) -> CompilerConfig<'c> { let diagnostics_reporter = DiagnosticsReporter::callback({ let config = ws.config(); @@ -38,13 +41,13 @@ pub fn build_compiler_config<'c>(unit: &CompilationUnit, ws: &Workspace<'c>) -> } } -pub fn collect_main_crate_ids(unit: &CompilationUnit, db: &RootDatabase) -> Vec { +pub fn collect_main_crate_ids(unit: &CairoCompilationUnit, db: &RootDatabase) -> Vec { vec![db.intern_crate(CrateLongId::Real( unit.main_component().cairo_package_name(), ))] } -pub fn collect_all_crate_ids(unit: &CompilationUnit, db: &RootDatabase) -> Vec { +pub fn collect_all_crate_ids(unit: &CairoCompilationUnit, db: &RootDatabase) -> Vec { unit.components .iter() .map(|component| db.intern_crate(CrateLongId::Real(component.cairo_package_name()))) diff --git a/scarb/src/compiler/mod.rs b/scarb/src/compiler/mod.rs index e618354b9..0f750f361 100644 --- a/scarb/src/compiler/mod.rs +++ b/scarb/src/compiler/mod.rs @@ -20,7 +20,7 @@ pub trait Compiler: Sync { fn compile( &self, - unit: CompilationUnit, + unit: CairoCompilationUnit, db: &mut RootDatabase, ws: &Workspace<'_>, ) -> Result<()>; diff --git a/scarb/src/compiler/plugin/proc_macro/compilation.rs b/scarb/src/compiler/plugin/proc_macro/compilation.rs index fc48f7816..418f8c3e0 100644 --- a/scarb/src/compiler/plugin/proc_macro/compilation.rs +++ b/scarb/src/compiler/plugin/proc_macro/compilation.rs @@ -1,5 +1,5 @@ use crate::compiler::plugin::proc_macro::PROC_MACRO_BUILD_PROFILE; -use crate::compiler::CompilationUnit; +use crate::compiler::ProcMacroCompilationUnit; use crate::core::{Config, Package, Workspace}; use crate::flock::Filesystem; use anyhow::{ensure, Context, Result}; @@ -43,7 +43,7 @@ impl SharedLibraryProvider for Package { } } -pub fn compile_unit(unit: CompilationUnit, ws: &Workspace<'_>) -> Result<()> { +pub fn compile_unit(unit: ProcMacroCompilationUnit, ws: &Workspace<'_>) -> Result<()> { let main_package = unit.components.first().unwrap().package.clone(); let cmd = CargoCommand { current_dir: main_package.root().to_path_buf(), diff --git a/scarb/src/compiler/repository.rs b/scarb/src/compiler/repository.rs index 823f8e091..37e4479e9 100644 --- a/scarb/src/compiler/repository.rs +++ b/scarb/src/compiler/repository.rs @@ -8,7 +8,7 @@ use itertools::Itertools; use smol_str::SmolStr; use crate::compiler::compilers::{LibCompiler, StarknetContractCompiler, TestCompiler}; -use crate::compiler::{CompilationUnit, Compiler}; +use crate::compiler::{CairoCompilationUnit, CompilationUnitAttributes, Compiler}; use crate::core::Workspace; pub struct CompilerRepository { @@ -43,7 +43,7 @@ impl CompilerRepository { pub fn compile( &self, - unit: CompilationUnit, + unit: CairoCompilationUnit, db: &mut RootDatabase, ws: &Workspace<'_>, ) -> Result<()> { diff --git a/scarb/src/ops/compile.rs b/scarb/src/ops/compile.rs index aba52f77c..1c5d77707 100644 --- a/scarb/src/ops/compile.rs +++ b/scarb/src/ops/compile.rs @@ -10,7 +10,7 @@ use scarb_ui::HumanDuration; use crate::compiler::db::{build_scarb_root_database, has_starknet_plugin}; use crate::compiler::helpers::build_compiler_config; use crate::compiler::plugin::proc_macro; -use crate::compiler::CompilationUnit; +use crate::compiler::{CairoCompilationUnit, CompilationUnit, CompilationUnitAttributes}; use crate::core::{PackageId, PackageName, TargetKind, Utf8PathWorkspaceExt, Workspace}; use crate::ops; @@ -65,12 +65,12 @@ where let is_excluded = opts.exclude_targets.contains(&cu.target().kind); let is_included = opts.include_targets.is_empty() || opts.include_targets.contains(&cu.target().kind); - let is_selected = packages.contains(&cu.main_package_id); - let is_cairo_plugin = cu.components.first().unwrap().target.is_cairo_plugin(); + let is_selected = packages.contains(&cu.main_package_id()); + let is_cairo_plugin = matches!(cu, CompilationUnit::ProcMacro(_)); is_cairo_plugin || (is_selected && is_included && !is_excluded) }) .sorted_by_key(|cu| { - if cu.components.first().unwrap().target.is_cairo_plugin() { + if matches!(cu, CompilationUnit::ProcMacro(_)) { 0 } else { 1 @@ -95,18 +95,19 @@ where } fn compile_unit(unit: CompilationUnit, ws: &Workspace<'_>) -> Result<()> { - let package_name = unit.main_package_id.name.clone(); + let package_name = unit.main_package_id().name.clone(); ws.config() .ui() .print(Status::new("Compiling", &unit.name())); - let result = if unit.is_cairo_plugin() { - proc_macro::compile_unit(unit, ws) - } else { - let mut db = build_scarb_root_database(&unit, ws)?; - check_starknet_dependency(&unit, ws, &db, &package_name); - ws.config().compilers().compile(unit, &mut db, ws) + let result = match unit { + CompilationUnit::ProcMacro(unit) => proc_macro::compile_unit(unit, ws), + CompilationUnit::Cairo(unit) => { + let mut db = build_scarb_root_database(&unit, ws)?; + check_starknet_dependency(&unit, ws, &db, &package_name); + ws.config().compilers().compile(unit, &mut db, ws) + } }; result.map_err(|err| { @@ -119,35 +120,40 @@ fn compile_unit(unit: CompilationUnit, ws: &Workspace<'_>) -> Result<()> { } fn check_unit(unit: CompilationUnit, ws: &Workspace<'_>) -> Result<()> { - let package_name = unit.main_package_id.name.clone(); + let package_name = unit.main_package_id().name.clone(); ws.config() .ui() .print(Status::new("Checking", &unit.name())); - let db = build_scarb_root_database(&unit, ws)?; + match unit { + CompilationUnit::ProcMacro(_unit) => (), + CompilationUnit::Cairo(unit) => { + let db = build_scarb_root_database(&unit, ws)?; - check_starknet_dependency(&unit, ws, &db, &package_name); + check_starknet_dependency(&unit, ws, &db, &package_name); - let mut compiler_config = build_compiler_config(&unit, ws); + let mut compiler_config = build_compiler_config(&unit, ws); - compiler_config - .diagnostics_reporter - .ensure(&db) - .map_err(|err| { - let valid_error = err.into(); - if !suppress_error(&valid_error) { - ws.config().ui().anyhow(&valid_error); - } + compiler_config + .diagnostics_reporter + .ensure(&db) + .map_err(|err| { + let valid_error = err.into(); + if !suppress_error(&valid_error) { + ws.config().ui().anyhow(&valid_error); + } - anyhow!("could not check `{package_name}` due to previous error") - })?; + anyhow!("could not check `{package_name}` due to previous error") + })?; + } + } Ok(()) } fn check_starknet_dependency( - unit: &CompilationUnit, + unit: &CairoCompilationUnit, ws: &Workspace<'_>, db: &RootDatabase, package_name: &PackageName, diff --git a/scarb/src/ops/metadata.rs b/scarb/src/ops/metadata.rs index 3d16d0e72..cb31c1689 100644 --- a/scarb/src/ops/metadata.rs +++ b/scarb/src/ops/metadata.rs @@ -8,7 +8,10 @@ use smol_str::SmolStr; use scarb_metadata as m; use scarb_ui::args::PackagesSource; -use crate::compiler::CompilationUnit; +use crate::compiler::{ + CairoCompilationUnit, CompilationUnit, CompilationUnitAttributes, CompilationUnitComponent, + ProcMacroCompilationUnit, +}; use crate::core::{ edition_variant, DepKind, DependencyVersionReq, ManifestDependency, Package, PackageId, SourceId, Target, Workspace, @@ -202,27 +205,16 @@ fn collect_target_metadata(target: &Target) -> m::TargetMetadata { fn collect_compilation_unit_metadata( compilation_unit: &CompilationUnit, ) -> m::CompilationUnitMetadata { - let components: Vec = compilation_unit - .components - .iter() - .map(|c| { - m::CompilationUnitComponentMetadataBuilder::default() - .package(wrap_package_id(c.package.id)) - .name(c.cairo_package_name()) - .source_path(c.target.source_path.clone()) - .cfg(c.cfg_set.as_ref().map(|cfg_set| cfg_set - .iter() - .map(|cfg| { - serde_json::to_value(cfg) - .and_then(serde_json::from_value::) - .expect("Cairo's `Cfg` must serialize identically as Scarb Metadata's `Cfg`.") - }) - .collect::>())) - .build() - .unwrap() - }) - .sorted_by_key(|c| c.package.clone()) - .collect(); + match compilation_unit { + CompilationUnit::Cairo(cu) => collect_cairo_compilation_unit_metadata(cu), + CompilationUnit::ProcMacro(cu) => collect_proc_macro_compilation_unit_metadata(cu), + } +} + +fn collect_cairo_compilation_unit_metadata( + compilation_unit: &CairoCompilationUnit, +) -> m::CompilationUnitMetadata { + let components = collect_compilation_unit_components(compilation_unit.components.iter()); let cairo_plugins: Vec = compilation_unit .cairo_plugins @@ -270,6 +262,50 @@ fn collect_compilation_unit_metadata( .unwrap() } +fn collect_proc_macro_compilation_unit_metadata( + compilation_unit: &ProcMacroCompilationUnit, +) -> m::CompilationUnitMetadata { + let components = collect_compilation_unit_components(compilation_unit.components.iter()); + m::CompilationUnitMetadataBuilder::default() + .id(compilation_unit.id()) + .package(wrap_package_id(compilation_unit.main_package_id)) + .target(collect_target_metadata(compilation_unit.target())) + .components(components) + .cairo_plugins(Vec::new()) + .compiler_config(serde_json::Value::Null) + .cfg(Vec::new()) + .extra(HashMap::new()) + .build() + .unwrap() +} + +fn collect_compilation_unit_components<'a, I>( + components: I, +) -> Vec +where + I: Iterator, +{ + components.into_iter() + .map(|c| { + m::CompilationUnitComponentMetadataBuilder::default() + .package(wrap_package_id(c.package.id)) + .name(c.cairo_package_name()) + .source_path(c.target.source_path.clone()) + .cfg(c.cfg_set.as_ref().map(|cfg_set| cfg_set + .iter() + .map(|cfg| { + serde_json::to_value(cfg) + .and_then(serde_json::from_value::) + .expect("Cairo's `Cfg` must serialize identically as Scarb Metadata's `Cfg`.") + }) + .collect::>())) + .build() + .unwrap() + }) + .sorted_by_key(|c| c.package.clone()) + .collect() +} + fn collect_app_version_metadata() -> m::VersionInfo { let v = crate::version::get(); diff --git a/scarb/src/ops/resolve.rs b/scarb/src/ops/resolve.rs index 87c2ddcf5..41ed9c8a1 100644 --- a/scarb/src/ops/resolve.rs +++ b/scarb/src/ops/resolve.rs @@ -7,7 +7,10 @@ use indoc::formatdoc; use itertools::Itertools; use serde::{Deserialize, Serialize}; -use crate::compiler::{CompilationUnit, CompilationUnitCairoPlugin, CompilationUnitComponent}; +use crate::compiler::{ + CairoCompilationUnit, CompilationUnit, CompilationUnitAttributes, CompilationUnitCairoPlugin, + CompilationUnitComponent, ProcMacroCompilationUnit, +}; use crate::core::lockfile::Lockfile; use crate::core::package::{Package, PackageClass, PackageId}; use crate::core::registry::cache::RegistryCache; @@ -153,22 +156,25 @@ pub fn generate_compilation_units( ws: &Workspace<'_>, ) -> Result> { let mut units = Vec::with_capacity(ws.members().size_hint().0); - for member in ws.members() { - units.extend(if member.is_cairo_plugin() { - generate_cairo_plugin_compilation_units(&member, ws)? - } else { - generate_cairo_compilation_units(&member, resolve, ws)? - }); + for member in ws.members().filter(|member| !member.is_cairo_plugin()) { + units.extend(generate_cairo_compilation_units(&member, resolve, ws)?); } let cairo_plugins = units .iter() + .filter_map(|unit| match unit { + CompilationUnit::Cairo(unit) => Some(unit), + _ => None, + }) .flat_map(|unit| unit.cairo_plugins.clone()) .filter(|plugin| !plugin.builtin) .map(|plugin| plugin.package.clone()) + .chain(ws.members().filter(|member| member.is_cairo_plugin())) .unique_by(|plugin| plugin.id) .collect_vec(); + // cairo_plugins.extend(ws.members().filter(|member| member.is_cairo_plugin())); + for plugin in cairo_plugins { units.extend(generate_cairo_plugin_compilation_units(&plugin, ws)?); } @@ -286,14 +292,14 @@ fn generate_cairo_compilation_units( member.id }; - Ok(CompilationUnit { + Ok(CompilationUnit::Cairo(CairoCompilationUnit { main_package_id, components, cairo_plugins: cairo_plugins.clone(), profile: profile.clone(), compiler_config: member.manifest.compiler_config.clone(), cfg_set, - }) + })) }) .collect::>>() } @@ -439,10 +445,11 @@ fn check_cairo_version_compatibility(packages: &[Package], ws: &Workspace<'_>) - fn generate_cairo_plugin_compilation_units( member: &Package, - ws: &Workspace<'_>, + _ws: &Workspace<'_>, ) -> Result> { - Ok(vec![CompilationUnit { + Ok(vec![CompilationUnit::ProcMacro(ProcMacroCompilationUnit { main_package_id: member.id, + compiler_config: serde_json::Value::Null, components: vec![CompilationUnitComponent { package: member.clone(), cfg_set: None, @@ -452,9 +459,5 @@ fn generate_cairo_plugin_compilation_units( // Safe to unwrap, as member.is_cairo_plugin() has been ensured before. .expect("main component of procedural macro must define `cairo-plugin` target"), }], - cairo_plugins: Vec::new(), - profile: ws.current_profile()?, - compiler_config: member.manifest.compiler_config.clone(), - cfg_set: Default::default(), - }]) + })]) }