Skip to content

Commit

Permalink
Implement per-crate plugin collection
Browse files Browse the repository at this point in the history
commit-id:c3b7ca8a
  • Loading branch information
integraledelebesgue committed Jan 29, 2025
1 parent 170b636 commit 6da3e46
Showing 1 changed file with 98 additions and 1 deletion.
99 changes: 98 additions & 1 deletion scarb/src/compiler/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::compiler::{
};
use crate::core::Workspace;
use crate::DEFAULT_MODULE_MAIN_FILE;
use anyhow::{anyhow, Result};
use anyhow::{anyhow, Context, Result};
use cairo_lang_compiler::db::{RootDatabase, RootDatabaseBuilder};
use cairo_lang_compiler::project::{AllCratesConfig, ProjectConfig, ProjectConfigContent};
use cairo_lang_defs::db::DefsGroup;
Expand All @@ -15,13 +15,18 @@ use cairo_lang_filesystem::db::{
AsFilesGroupMut, CrateIdentifier, CrateSettings, DependencySettings, FilesGroup, FilesGroupEx,
};
use cairo_lang_filesystem::ids::CrateLongId;
use cairo_lang_semantic::inline_macros::get_default_plugin_suite;
use cairo_lang_semantic::plugin::PluginSuite;
use cairo_lang_utils::ordered_hash_map::OrderedHashMap;
use smol_str::SmolStr;
use std::collections::HashMap;
use std::path::PathBuf;
use std::sync::Arc;
use tracing::trace;

use super::plugin::proc_macro::ProcMacroRepository;
use super::CompilationUnitComponentId;

pub struct ScarbDatabase {
pub db: RootDatabase,
pub proc_macro_host: Arc<ProcMacroHostPlugin>,
Expand Down Expand Up @@ -51,6 +56,98 @@ pub(crate) fn build_scarb_root_database(
})
}

/// Collects all procedural macros defined in the [`CairoCompilationUnit`],
/// loads their shared libraries and stores them in the [`ProcMacroRepository`].
#[allow(dead_code)] // Will be used in the next PR.
fn collect_proc_macros(
unit: &CairoCompilationUnit,
ws: &Workspace<'_>,
) -> Result<ProcMacroRepository> {
// TODO: Discuss
// Is it possible the same plugin is allowed
// to be pre-built in one manifest and not allowed in the other?
// Should we bother inserting the pre-builts without checking?

let mut repository = ProcMacroRepository::default();

for plugin_info in unit.cairo_plugins.iter() {
if plugin_info.builtin {
continue;
}

let package_id = plugin_info.component_dependency_id.package_id;

if let Some(prebuilt) = &plugin_info.prebuilt {
repository.insert_prebuilt_unchecked(package_id, prebuilt.clone())?;
} else {
repository.get_or_load(plugin_info.package.clone(), ws.config())?;
}
}

Ok(repository)
}

/// Associates the IDs of the Library components of the [`CairoCompilationUnit`]
/// with suites of plugins they depend on.
#[allow(dead_code)] // Will be used in the next PR.
fn collect_plugins_for_components(
unit: &CairoCompilationUnit,
ws: &Workspace<'_>,
additional_plugins: Vec<PluginSuite>,
proc_macro_repository: &ProcMacroRepository,
) -> Result<HashMap<CompilationUnitComponentId, PluginSuite>> {
let mut plugins_for_packages = HashMap::new();

for component in unit.components.iter() {
if component.is_cairo_plugin() {
continue;
}

let mut component_suite = PluginSuite::default();

for dependency in component.dependencies.iter() {
let CompilationUnitDependency::Plugin(dependency_id) = dependency else {
continue;
};

let plugin_info = unit
.cairo_plugins
.iter()
.find(|plugin| &plugin.component_dependency_id == dependency_id)
.with_context(
|| format!("Plugin with discriminator `{dependency:?}` not found in the compilation unit"),
)?;

if !plugin_info.builtin {
let proc_macro = proc_macro_repository
.get(&plugin_info.package.id)
.context("Procedural macro with discriminator `{dependency_id}` not found in the compilation unit")?;

component_suite.add(ProcMacroHostPlugin::build_plugin_suite(proc_macro.clone()));
continue;
}

let package_id = plugin_info.package.id;
let plugin = ws.config().cairo_plugins().fetch(package_id)?;
let instance = plugin.instantiate()?;
let suite = instance.plugin_suite();

component_suite.add(suite);
}

for additional_suite in additional_plugins.iter() {
component_suite.add(additional_suite.clone());
}

component_suite.add(get_default_plugin_suite());

let package_id = component.id.clone();
plugins_for_packages.insert(package_id, component_suite);
}

Ok(plugins_for_packages)
}

fn load_plugins(
unit: &CairoCompilationUnit,
ws: &Workspace<'_>,
Expand Down

0 comments on commit 6da3e46

Please sign in to comment.