Skip to content

Commit

Permalink
Change compilation unit to enum
Browse files Browse the repository at this point in the history
commit-id:bf749c51
  • Loading branch information
maciektr committed Feb 21, 2024
1 parent b4bd47c commit 3f081e2
Show file tree
Hide file tree
Showing 12 changed files with 246 additions and 120 deletions.
148 changes: 113 additions & 35 deletions scarb/src/compiler/compilation_unit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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<CompilationUnitComponent>,

/// 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,
Expand All @@ -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
Expand All @@ -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();
Expand All @@ -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 {
Expand All @@ -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()
Expand Down
4 changes: 2 additions & 2 deletions scarb/src/compiler/compilers/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -37,7 +37,7 @@ impl Compiler for LibCompiler {

fn compile(
&self,
unit: CompilationUnit,
unit: CairoCompilationUnit,
db: &mut RootDatabase,
ws: &Workspace<'_>,
) -> Result<()> {
Expand Down
6 changes: 3 additions & 3 deletions scarb/src/compiler/compilers/starknet_contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -199,7 +199,7 @@ impl Compiler for StarknetContractCompiler {

fn compile(
&self,
unit: CompilationUnit,
unit: CairoCompilationUnit,
db: &mut RootDatabase,
ws: &Workspace<'_>,
) -> Result<()> {
Expand Down Expand Up @@ -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 {
Expand Down
4 changes: 2 additions & 2 deletions scarb/src/compiler/compilers/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -18,7 +18,7 @@ impl Compiler for TestCompiler {

fn compile(
&self,
unit: CompilationUnit,
unit: CairoCompilationUnit,
db: &mut RootDatabase,
ws: &Workspace<'_>,
) -> Result<()> {
Expand Down
10 changes: 5 additions & 5 deletions scarb/src/compiler/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<RootDatabase> {
let mut b = RootDatabase::builder();
Expand All @@ -31,7 +31,7 @@ pub(crate) fn build_scarb_root_database(
}

fn load_plugins(
unit: &CompilationUnit,
unit: &CairoCompilationUnit,
ws: &Workspace<'_>,
builder: &mut RootDatabaseBuilder,
) -> Result<()> {
Expand All @@ -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()
Expand Down Expand Up @@ -90,7 +90,7 @@ fn inject_virtual_wrapper_lib(db: &mut RootDatabase, unit: &CompilationUnit) ->
Ok(())
}

fn build_project_config(unit: &CompilationUnit) -> Result<ProjectConfig> {
fn build_project_config(unit: &CairoCompilationUnit) -> Result<ProjectConfig> {
let crate_roots = unit
.components
.iter()
Expand Down
11 changes: 7 additions & 4 deletions scarb/src/compiler/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand All @@ -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<CrateId> {
pub fn collect_main_crate_ids(unit: &CairoCompilationUnit, db: &RootDatabase) -> Vec<CrateId> {
vec![db.intern_crate(CrateLongId::Real(
unit.main_component().cairo_package_name(),
))]
}

pub fn collect_all_crate_ids(unit: &CompilationUnit, db: &RootDatabase) -> Vec<CrateId> {
pub fn collect_all_crate_ids(unit: &CairoCompilationUnit, db: &RootDatabase) -> Vec<CrateId> {
unit.components
.iter()
.map(|component| db.intern_crate(CrateLongId::Real(component.cairo_package_name())))
Expand Down
2 changes: 1 addition & 1 deletion scarb/src/compiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub trait Compiler: Sync {

fn compile(
&self,
unit: CompilationUnit,
unit: CairoCompilationUnit,
db: &mut RootDatabase,
ws: &Workspace<'_>,
) -> Result<()>;
Expand Down
4 changes: 2 additions & 2 deletions scarb/src/compiler/plugin/proc_macro/compilation.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand Down Expand Up @@ -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(),
Expand Down
4 changes: 2 additions & 2 deletions scarb/src/compiler/repository.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -43,7 +43,7 @@ impl CompilerRepository {

pub fn compile(
&self,
unit: CompilationUnit,
unit: CairoCompilationUnit,
db: &mut RootDatabase,
ws: &Workspace<'_>,
) -> Result<()> {
Expand Down
Loading

0 comments on commit 3f081e2

Please sign in to comment.