Skip to content

Commit

Permalink
library2
Browse files Browse the repository at this point in the history
  • Loading branch information
Grant Wuerker committed Jul 1, 2024
1 parent 70fca41 commit 3339ca0
Show file tree
Hide file tree
Showing 41 changed files with 924 additions and 40 deletions.
66 changes: 53 additions & 13 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion crates/common2/src/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::InputDb;
#[salsa::input(constructor = __new_impl)]
pub struct InputIngot {
/// An absolute path to the ingot root directory.
/// The all files in the ingot should be located under this directory.
/// All files in the ingot should be located under this directory.
#[return_ref]
pub path: Utf8PathBuf,

Expand All @@ -23,6 +23,7 @@ pub struct InputIngot {

/// A list of ingots which the current ingot depends on.
#[return_ref]
#[set(__set_external_ingots_impl)]
pub external_ingots: BTreeSet<IngotDependency>,

/// A list of files which the current ingot contains.
Expand Down Expand Up @@ -72,6 +73,10 @@ impl InputIngot {
pub fn root_file(&self, db: &dyn InputDb) -> InputFile {
self.__get_root_file_impl(db).unwrap()
}

pub fn set_external_ingots(self, db: &mut dyn InputDb, ingots: BTreeSet<IngotDependency>) {
self.__set_external_ingots_impl(db).to(ingots);
}
}

#[salsa::input]
Expand Down
6 changes: 6 additions & 0 deletions crates/driver2/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,9 @@ macros = { path = "../macros", package = "fe-macros" }
hir-analysis = { path = "../hir-analysis", package = "fe-hir-analysis" }
camino = "1.1.4"
clap = { version = "4.3", features = ["derive"] }
toml = "0.8.13"
serde = { version = "1", features = ["derive"] }
semver = "1.0.23"
walkdir = "2"
include_dir = "0.7"
dirs = "5.0.1"
142 changes: 142 additions & 0 deletions crates/driver2/src/check.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
use crate::{load_ingot, CheckArgs};
use common::input::IngotDependency;
use common::{input::IngotKind, InputIngot};
use fe_driver2::DriverDataBase;
use include_dir::{include_dir, Dir};
use semver::Version;
use std::fs;
use std::path::PathBuf;
use std::{collections::BTreeSet, path::Path};

const STD_DIR: Dir = include_dir!("$CARGO_MANIFEST_DIR/../../library/std");

fn write_std_files(std_path: &Path) {
write_files_recursive(&STD_DIR, std_path);
}

fn write_files_recursive(dir: &Dir<'_>, base_path: &Path) {
for file in dir.files() {
let file_path = base_path.join(file.path());
if let Some(parent_dir) = file_path.parent() {
std::fs::create_dir_all(parent_dir).unwrap();
}
std::fs::write(file_path, file.contents()).unwrap();
}

for subdir in dir.dirs() {
let subdir_path = base_path.join(subdir.path());
std::fs::create_dir_all(&subdir_path).unwrap();
write_files_recursive(subdir, &base_path);
}
}

pub fn run_check(args: &CheckArgs) {
let std_path = match &args.std_path {
Some(path) => PathBuf::from(path.to_owned()),
None => {
let home_dir = dirs::home_dir().expect("Failed to get user home directory");
home_dir.join(".fe/std")
}
};
if !std_path.exists() {
println!("The standard library is not installed. Do you want to perform the write? (y/n)");
let mut input = String::new();
std::io::stdin().read_line(&mut input).unwrap();
let input = input.trim().to_lowercase();
if input == "y" || input == "yes" {
write_std_files(&std_path);
} else {
eprintln!(
"Cannot perform the write without the standard library being installed on disk"
);
std::process::exit(2);
}
}

let path = Path::new(&args.path);
if !path.exists() {
eprintln!("Path '{}' does not exist", path.display());
std::process::exit(2);
}

let mut db = DriverDataBase::default();

let std_ingot = load_ingot(&std_path, &mut db, IngotKind::Std, &mut BTreeSet::new());

if path.is_file() {
let source = fs::read_to_string(path).unwrap();
check_single_file(path, source, std_ingot, &mut db, args.dump_scope_graph);
} else if path.is_dir() {
check_ingot(path, std_ingot, &mut db, args.dump_scope_graph);
} else {
eprintln!(
"Path '{}' is neither a file nor a directory",
path.display()
);
std::process::exit(2);
}
}

pub fn check_single_file(
path: &Path,
source: String,
std_ingot: InputIngot,
db: &mut DriverDataBase,
dump_scope_graph: bool,
) {
let mut dependencies = BTreeSet::from([IngotDependency::new("std", std_ingot)]);
let ingot = InputIngot::new(
db,
path.parent().unwrap().to_str().unwrap(),
IngotKind::StandAlone,
Version::new(0, 1, 0),
dependencies.clone(),
);

// let input_file = InputFile::new(
// db,
// ingot.clone(),
// path.file_name().unwrap().to_str().unwrap().into(),
// source,
// );
// ingot.set_files(db, BTreeSet::from([input_file.clone()]));
// ingot.set_root_file(db, input_file);

let top_mod = db.top_mod_from_file(path, &source);
db.run_on_top_mod(top_mod);
db.emit_diags();

// if dump_scope_graph {
// println!("{}", dump_scope_graph(db, top_mod));
// }
}

pub fn check_ingot(
path: &Path,
std_ingot: InputIngot,
db: &mut DriverDataBase,
dump_scope_graph: bool,
) {
let mut dependencies = BTreeSet::from([IngotDependency::new("std", std_ingot)]);
let mut main_ingot = load_ingot(path, db, IngotKind::Local, &mut dependencies);

main_ingot.set_external_ingots(db, dependencies);

db.run_on_ingot(std_ingot);

let diags = db.format_diags();
if !diags.is_empty() {
panic!("{diags}")
}

db.run_on_ingot(main_ingot);

let diags = db.format_diags();
if !diags.is_empty() {
panic!("{diags}")
}

// if dump_scope_graph {
// println!("{}", dump_scope_graph(db, top_mod));
// }
}
23 changes: 21 additions & 2 deletions crates/driver2/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@ use common::{
InputDb, InputFile, InputIngot,
};
use hir::{
analysis_pass::AnalysisPassManager, diagnostics::DiagnosticVoucher, hir_def::TopLevelMod,
lower::map_file_to_mod, HirDb, LowerHirDb, ParsingPass, SpannedHirDb,
analysis_pass::AnalysisPassManager,
diagnostics::DiagnosticVoucher,
hir_def::TopLevelMod,
lower::{map_file_to_mod, module_tree},
HirDb, LowerHirDb, ParsingPass, SpannedHirDb,
};
use hir_analysis::{
name_resolution::{DefConflictAnalysisPass, ImportAnalysisPass, PathAnalysisPass},
Expand Down Expand Up @@ -58,6 +61,10 @@ impl DriverDataBase {
self.run_on_file_with_pass_manager(top_mod, initialize_analysis_pass);
}

pub fn run_on_ingot(&mut self, ingot: InputIngot) {
self.run_on_ingot_with_pass_manager(ingot, initialize_analysis_pass);
}

pub fn run_on_file_with_pass_manager<F>(&mut self, top_mod: TopLevelMod, pm_builder: F)
where
F: FnOnce(&DriverDataBase) -> AnalysisPassManager<'_>,
Expand All @@ -69,6 +76,18 @@ impl DriverDataBase {
};
}

pub fn run_on_ingot_with_pass_manager<F>(&mut self, ingot: InputIngot, pm_builder: F)
where
F: FnOnce(&DriverDataBase) -> AnalysisPassManager<'_>,
{
self.diags.clear();
let tree = module_tree(self, ingot);
self.diags = {
let mut pass_manager = pm_builder(self);
pass_manager.run_on_module_tree(tree)
};
}

pub fn top_mod_from_file(&mut self, file_path: &path::Path, source: &str) -> TopLevelMod {
let kind = IngotKind::StandAlone;

Expand Down
Loading

0 comments on commit 3339ca0

Please sign in to comment.