Skip to content

Commit

Permalink
feat(wip): Finished the refactor step of the project model using Cow …
Browse files Browse the repository at this point in the history
…instead of owned data. Code compiles but is far from finished yet
  • Loading branch information
TheRustifyer committed Jun 23, 2024
1 parent 87305b7 commit ffd6648
Show file tree
Hide file tree
Showing 17 changed files with 342 additions and 279 deletions.
5 changes: 3 additions & 2 deletions zork++/src/lib/bounds/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! The higher abstractions of the program

use core::fmt::Debug;
use std::borrow::Cow;
use std::fmt::Display;
use std::path::PathBuf;

Expand Down Expand Up @@ -28,10 +29,10 @@ pub trait TranslationUnit: Display + Debug {
fn path(&self) -> PathBuf;

/// Outputs the declared file stem for this translation unit
fn file_stem(&self) -> String;
fn file_stem(&self) -> Cow<'_, str>;

/// Outputs the declared extension for `self`
fn extension(&self) -> String;
fn extension(&self) -> Cow<'_, str>;

/// Outputs the file stem concatenated with the extension for a given tu
fn file_with_extension(&self) -> String {
Expand Down
68 changes: 37 additions & 31 deletions zork++/src/lib/cache/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ use walkdir::WalkDir;

/// Standalone utility for load from the file system the Zork++ cache file
/// for the target [`CppCompiler`]
pub fn load(program_data: &ZorkModel<'_>, cli_args: &CliArgs) -> Result<ZorkCache> {
pub fn load<'a>(program_data: &'a ZorkModel<'_>, cli_args: &CliArgs) -> Result<ZorkCache<'a>> {
let compiler = program_data.compiler.cpp_compiler;
let cache_path = &program_data
.build
Expand Down Expand Up @@ -88,22 +88,14 @@ pub fn save(
}

#[derive(Serialize, Deserialize, Default)]
pub struct ZorkCache {
pub struct ZorkCache<'a> {
pub compiler: CppCompiler,
pub last_program_execution: DateTime<Utc>,
pub compilers_metadata: CompilersMetadata,
pub compilers_metadata: CompilersMetadata<'a>,
pub generated_commands: Commands,
}

impl ZorkCache {
pub fn new() -> Self {
Self {
compiler: todo!(),
last_program_execution: todo!(),
compilers_metadata: todo!(),
generated_commands: todo!(),
}
}
impl<'a> ZorkCache<'a> {
pub fn last_program_execution(&self) -> &DateTime<Utc> {
&self.last_program_execution
}
Expand Down Expand Up @@ -150,7 +142,7 @@ impl ZorkCache {
}

/// The tasks associated with the cache after load it from the file system
pub fn run_tasks(&mut self, program_data: &ZorkModel<'_>) -> Result<()> {
pub fn run_tasks(&mut self, program_data: &'a ZorkModel<'_>) -> Result<()> {
let compiler = program_data.compiler.cpp_compiler;
if cfg!(target_os = "windows") && compiler == CppCompiler::MSVC {
msvc::load_metadata(self, program_data)?
Expand Down Expand Up @@ -186,9 +178,13 @@ impl ZorkCache {
}
}

if !(program_data.compiler.cpp_compiler == CppCompiler::MSVC) {
if !(program_data.compiler.cpp_compiler == CppCompiler::MSVC)
&& program_data.modules.is_some()
{
self.compilers_metadata.system_modules = program_data
.modules
.as_ref()
.unwrap()
.sys_modules
.iter()
.map(|e| e.to_string())
Expand Down Expand Up @@ -303,10 +299,10 @@ impl ZorkCache {
/// to avoid recompiling them on every process
/// NOTE: This feature should be deprecated and therefore, removed from Zork++ when GCC and
/// Clang fully implement the required procedures to build the C++ std library as a module
fn track_system_modules<'a>(
fn track_system_modules<'b: 'a>(
// TODO move it to helpers
program_data: &'a ZorkModel<'_>,
) -> impl Iterator<Item = String> + 'a {
program_data: &'b ZorkModel<'b>,
) -> impl Iterator<Item = String> + 'b {
let root = if program_data.compiler.cpp_compiler == CppCompiler::GCC {
Path::new(GCC_CACHE_DIR).to_path_buf()
} else {
Expand All @@ -327,11 +323,18 @@ impl ZorkCache {
.expect("Error retrieving metadata")
.is_file()
{
program_data
program_data // TODO: review this, since it's too late and I am just satisfying the borrow checker
.modules
.sys_modules
.as_ref()
.map(|modules| modules.sys_modules.clone())
.unwrap_or_default()
.iter()
.any(|sys_mod| file.file_name().to_str().unwrap().starts_with(sys_mod))
.any(|sys_mod| {
file.file_name()
.to_str()
.unwrap()
.starts_with(&sys_mod.to_string())
})
} else {
false
}
Expand Down Expand Up @@ -390,20 +393,22 @@ pub struct MainCommandLineDetail {
pub type EnvVars = HashMap<String, String>;

#[derive(Deserialize, Serialize, Debug, Default, Clone)]
pub struct CompilersMetadata {
pub struct CompilersMetadata<'a> {
// TODO: apply the same solution a have a fat pointer or better convert them into a Union/enum?
// ALL of them must be optional, since only exists
pub msvc: MsvcMetadata,
pub msvc: MsvcMetadata<'a>,
pub clang: ClangMetadata,
pub gcc: GccMetadata,
pub system_modules: Vec<String>, // TODO: This hopefully will dissappear soon
// TODO: Vec of Cow
}

#[derive(Deserialize, Serialize, Debug, Default, Clone)]
pub struct MsvcMetadata {
pub struct MsvcMetadata<'a> {
pub compiler_version: Option<String>,
pub dev_commands_prompt: Option<String>,
pub vs_stdlib_path: Option<SourceFile>, // std.ixx path for the MSVC std lib location
pub vs_c_stdlib_path: Option<SourceFile>, // std.compat.ixx path for the MSVC std lib location
pub vs_stdlib_path: Option<SourceFile<'a>>, // std.ixx path for the MSVC std lib location
pub vs_c_stdlib_path: Option<SourceFile<'a>>, // std.compat.ixx path for the MSVC std lib location
pub stdlib_bmi_path: PathBuf, // BMI byproduct after build in it at the target out dir of
// the user
pub stdlib_obj_path: PathBuf, // Same for the .obj file
Expand All @@ -414,8 +419,8 @@ pub struct MsvcMetadata {
pub env_vars: EnvVars,
}

impl MsvcMetadata {
pub fn is_loaded(&self) -> bool {
impl<'a> MsvcMetadata<'_> {
pub fn is_loaded(&'a self) -> bool {
self.dev_commands_prompt.is_some() && self.vs_stdlib_path.is_some()
}
}
Expand All @@ -439,6 +444,7 @@ mod msvc {
use crate::utils::constants;
use color_eyre::eyre::{Context, OptionExt};
use regex::Regex;
use std::borrow::Cow;
use std::collections::HashMap;
use std::path::Path;

Expand Down Expand Up @@ -484,13 +490,13 @@ mod msvc {
Path::new(msvc.env_vars.get("VCToolsInstallDir").unwrap()).join("modules");
msvc.vs_stdlib_path = Some(SourceFile {
path: vs_stdlib_path.clone(),
file_stem: String::from("std"),
extension: compiler.get_default_module_extension().to_string(),
file_stem: Cow::Borrowed("std"),
extension: compiler.default_module_extension(),
});
msvc.vs_c_stdlib_path = Some(SourceFile {
path: vs_stdlib_path,
file_stem: String::from("std.compat"),
extension: compiler.get_default_module_extension().to_string(),
file_stem: Cow::Borrowed("std.compat"),
extension: compiler.default_module_extension(),
});
let modular_stdlib_byproducts_path = Path::new(&program_data.build.output_dir)
.join(compiler.as_ref())
Expand Down
4 changes: 2 additions & 2 deletions zork++/src/lib/cli/output/arguments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ pub mod clang_args {
}

pub(crate) fn add_direct_module_interfaces_dependencies(
dependencies: &[&str],
dependencies: &[Cow<str>],
compiler: CppCompiler,
out_dir: &Path,
arguments: &mut Arguments,
Expand All @@ -196,7 +196,7 @@ pub mod clang_args {
.join(compiler.as_ref())
.join("modules")
.join("interfaces")
.join(ifc_dep)
.join::<&str>(ifc_dep)
.with_extension(compiler.get_typical_bmi_extension())
.display()
)))
Expand Down
5 changes: 4 additions & 1 deletion zork++/src/lib/cli/output/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
//! by Zork++

use std::collections::HashMap;
use std::ffi::OsStr;
use std::fmt::Debug;
use std::slice::Iter;
use std::{
Expand Down Expand Up @@ -131,7 +132,9 @@ fn execute_command(
)
);

std::process::Command::new(compiler.get_driver(&model.compiler))
let driver = compiler.get_driver(&model.compiler);
let os_driver = OsStr::new(driver.as_ref());
std::process::Command::new(os_driver)
.args(arguments)
.envs(cache.get_process_env_args())
.spawn()?
Expand Down
18 changes: 12 additions & 6 deletions zork++/src/lib/compiler/data_factory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
//! translation unit, having shared data without replicating it until the final command line must
//! be generated in order to be stored (in cache) and executed (in the underlying shell)

use std::{borrow::Cow, path::{Path, PathBuf}};
use std::{
borrow::Cow,
path::{Path, PathBuf},
};

use serde::{Deserialize, Serialize};

Expand Down Expand Up @@ -48,7 +51,10 @@ impl<'a> From<&'a ZorkModel<'_>> for CommonArgs {
pub trait CompilerCommonArguments {}
impl Default for Box<dyn CompilerCommonArguments> {
fn default() -> Self {
Box::new(ClangCommonArgs::default()) // TODO: isn't this a code smell?
Box::<ClangCommonArgs>::default() // TODO: isn't this a code smell?
// TODO: should we just panic? Or maybe fix the default? Or maybe have an associated
// and pass the compiler to the trait fn? So we can ensure that the default has sense?
// TODO: we can just fix as well the serialization function, removing the default
}
}

Expand Down Expand Up @@ -92,10 +98,10 @@ pub struct MsvcCommonArgs {
exception_handling_model: Cow<'static, str>,
/* no_logo: &'a str,
no_compile: &'a str, // TODO: should be in the general and pass in the model? */
// ref_stdlib: &'static str, // TODO: this are tecnically two args, /reference and the value
// ref_stdlib_compat: &'static str, // TODO: this are tecnically two args, /reference and the value
// TODO: split the dual cases per switches
// TODO: can we have switches like tuples? like switch-value pairs?
// ref_stdlib: &'static str, // TODO: this are tecnically two args, /reference and the value
// ref_stdlib_compat: &'static str, // TODO: this are tecnically two args, /reference and the value
// TODO: split the dual cases per switches
// TODO: can we have switches like tuples? like switch-value pairs?
}
impl MsvcCommonArgs {
pub fn new() -> Self {
Expand Down
Loading

0 comments on commit ffd6648

Please sign in to comment.