Skip to content

Commit 811ca02

Browse files
author
Grant Wuerker
committed
library2
1 parent 70fca41 commit 811ca02

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+927
-40
lines changed

Diff for: Cargo.lock

+53-13
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: crates/common2/src/input.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use crate::InputDb;
1010
#[salsa::input(constructor = __new_impl)]
1111
pub struct InputIngot {
1212
/// An absolute path to the ingot root directory.
13-
/// The all files in the ingot should be located under this directory.
13+
/// All files in the ingot should be located under this directory.
1414
#[return_ref]
1515
pub path: Utf8PathBuf,
1616

@@ -23,6 +23,7 @@ pub struct InputIngot {
2323

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

2829
/// A list of files which the current ingot contains.
@@ -72,6 +73,10 @@ impl InputIngot {
7273
pub fn root_file(&self, db: &dyn InputDb) -> InputFile {
7374
self.__get_root_file_impl(db).unwrap()
7475
}
76+
77+
pub fn set_external_ingots(self, db: &mut dyn InputDb, ingots: BTreeSet<IngotDependency>) {
78+
self.__set_external_ingots_impl(db).to(ingots);
79+
}
7580
}
7681

7782
#[salsa::input]

Diff for: crates/driver2/Cargo.toml

+6
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,9 @@ macros = { path = "../macros", package = "fe-macros" }
1919
hir-analysis = { path = "../hir-analysis", package = "fe-hir-analysis" }
2020
camino = "1.1.4"
2121
clap = { version = "4.3", features = ["derive"] }
22+
toml = "0.8.13"
23+
serde = { version = "1", features = ["derive"] }
24+
semver = "1.0.23"
25+
walkdir = "2"
26+
include_dir = "0.7"
27+
dirs = "5.0.1"

Diff for: crates/driver2/src/check.rs

+142
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
use crate::{load_ingot, CheckArgs};
2+
use common::input::IngotDependency;
3+
use common::{input::IngotKind, InputIngot};
4+
use fe_driver2::DriverDataBase;
5+
use include_dir::{include_dir, Dir};
6+
use semver::Version;
7+
use std::fs;
8+
use std::path::PathBuf;
9+
use std::{collections::BTreeSet, path::Path};
10+
11+
const STD_DIR: Dir = include_dir!("$CARGO_MANIFEST_DIR/../../library/std");
12+
13+
fn write_std_files(std_path: &Path) {
14+
write_files_recursive(&STD_DIR, std_path);
15+
}
16+
17+
fn write_files_recursive(dir: &Dir<'_>, base_path: &Path) {
18+
for file in dir.files() {
19+
let file_path = base_path.join(file.path());
20+
if let Some(parent_dir) = file_path.parent() {
21+
std::fs::create_dir_all(parent_dir).unwrap();
22+
}
23+
std::fs::write(file_path, file.contents()).unwrap();
24+
}
25+
26+
for subdir in dir.dirs() {
27+
let subdir_path = base_path.join(subdir.path());
28+
std::fs::create_dir_all(&subdir_path).unwrap();
29+
write_files_recursive(subdir, &base_path);
30+
}
31+
}
32+
33+
pub fn run_check(args: &CheckArgs) {
34+
let std_path = match &args.std_path {
35+
Some(path) => PathBuf::from(path.to_owned()),
36+
None => {
37+
let home_dir = dirs::home_dir().expect("Failed to get user home directory");
38+
home_dir.join(".fe/std")
39+
}
40+
};
41+
if !std_path.exists() {
42+
println!("The standard library is not installed. Do you want to perform the write? (y/n)");
43+
let mut input = String::new();
44+
std::io::stdin().read_line(&mut input).unwrap();
45+
let input = input.trim().to_lowercase();
46+
if input == "y" || input == "yes" {
47+
write_std_files(&std_path);
48+
} else {
49+
eprintln!(
50+
"Cannot perform the write without the standard library being installed on disk"
51+
);
52+
std::process::exit(2);
53+
}
54+
}
55+
56+
let path = Path::new(&args.path);
57+
if !path.exists() {
58+
eprintln!("Path '{}' does not exist", path.display());
59+
std::process::exit(2);
60+
}
61+
62+
let mut db = DriverDataBase::default();
63+
64+
let std_ingot = load_ingot(&std_path, &mut db, IngotKind::Std, &mut BTreeSet::new());
65+
66+
if path.is_file() {
67+
let source = fs::read_to_string(path).unwrap();
68+
check_single_file(path, source, std_ingot, &mut db, args.dump_scope_graph);
69+
} else if path.is_dir() {
70+
check_ingot(path, std_ingot, &mut db, args.dump_scope_graph);
71+
} else {
72+
eprintln!(
73+
"Path '{}' is neither a file nor a directory",
74+
path.display()
75+
);
76+
std::process::exit(2);
77+
}
78+
}
79+
80+
pub fn check_single_file(
81+
path: &Path,
82+
source: String,
83+
std_ingot: InputIngot,
84+
db: &mut DriverDataBase,
85+
dump_scope_graph: bool,
86+
) {
87+
let mut dependencies = BTreeSet::from([IngotDependency::new("std", std_ingot)]);
88+
let ingot = InputIngot::new(
89+
db,
90+
path.parent().unwrap().to_str().unwrap(),
91+
IngotKind::StandAlone,
92+
Version::new(0, 1, 0),
93+
dependencies.clone(),
94+
);
95+
96+
// let input_file = InputFile::new(
97+
// db,
98+
// ingot.clone(),
99+
// path.file_name().unwrap().to_str().unwrap().into(),
100+
// source,
101+
// );
102+
// ingot.set_files(db, BTreeSet::from([input_file.clone()]));
103+
// ingot.set_root_file(db, input_file);
104+
105+
let top_mod = db.top_mod_from_file(path, &source);
106+
db.run_on_top_mod(top_mod);
107+
db.emit_diags();
108+
109+
// if dump_scope_graph {
110+
// println!("{}", dump_scope_graph(db, top_mod));
111+
// }
112+
}
113+
114+
pub fn check_ingot(
115+
path: &Path,
116+
std_ingot: InputIngot,
117+
db: &mut DriverDataBase,
118+
dump_scope_graph: bool,
119+
) {
120+
let mut dependencies = BTreeSet::from([IngotDependency::new("std", std_ingot)]);
121+
let mut main_ingot = load_ingot(path, db, IngotKind::Local, &mut dependencies);
122+
123+
main_ingot.set_external_ingots(db, dependencies);
124+
125+
db.run_on_ingot(std_ingot);
126+
127+
let diags = db.format_diags();
128+
if !diags.is_empty() {
129+
panic!("{diags}")
130+
}
131+
132+
db.run_on_ingot(main_ingot);
133+
134+
let diags = db.format_diags();
135+
if !diags.is_empty() {
136+
panic!("{diags}")
137+
}
138+
139+
// if dump_scope_graph {
140+
// println!("{}", dump_scope_graph(db, top_mod));
141+
// }
142+
}

Diff for: crates/driver2/src/lib.rs

+21-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,11 @@ use common::{
1212
InputDb, InputFile, InputIngot,
1313
};
1414
use hir::{
15-
analysis_pass::AnalysisPassManager, diagnostics::DiagnosticVoucher, hir_def::TopLevelMod,
16-
lower::map_file_to_mod, HirDb, LowerHirDb, ParsingPass, SpannedHirDb,
15+
analysis_pass::AnalysisPassManager,
16+
diagnostics::DiagnosticVoucher,
17+
hir_def::TopLevelMod,
18+
lower::{map_file_to_mod, module_tree},
19+
HirDb, LowerHirDb, ParsingPass, SpannedHirDb,
1720
};
1821
use hir_analysis::{
1922
name_resolution::{DefConflictAnalysisPass, ImportAnalysisPass, PathAnalysisPass},
@@ -58,6 +61,10 @@ impl DriverDataBase {
5861
self.run_on_file_with_pass_manager(top_mod, initialize_analysis_pass);
5962
}
6063

64+
pub fn run_on_ingot(&mut self, ingot: InputIngot) {
65+
self.run_on_ingot_with_pass_manager(ingot, initialize_analysis_pass);
66+
}
67+
6168
pub fn run_on_file_with_pass_manager<F>(&mut self, top_mod: TopLevelMod, pm_builder: F)
6269
where
6370
F: FnOnce(&DriverDataBase) -> AnalysisPassManager<'_>,
@@ -69,6 +76,18 @@ impl DriverDataBase {
6976
};
7077
}
7178

79+
pub fn run_on_ingot_with_pass_manager<F>(&mut self, ingot: InputIngot, pm_builder: F)
80+
where
81+
F: FnOnce(&DriverDataBase) -> AnalysisPassManager<'_>,
82+
{
83+
self.diags.clear();
84+
let tree = module_tree(self, ingot);
85+
self.diags = {
86+
let mut pass_manager = pm_builder(self);
87+
pass_manager.run_on_module_tree(tree)
88+
};
89+
}
90+
7291
pub fn top_mod_from_file(&mut self, file_path: &path::Path, source: &str) -> TopLevelMod {
7392
let kind = IngotKind::StandAlone;
7493

0 commit comments

Comments
 (0)