Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[experimental, for study purposes] salsa tracked core ingot input #1063

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions crates/hir/src/hir_def/module_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,10 +219,15 @@ impl<'db> ModuleTreeBuilder<'db> {
continue;
}

assert!(child_path
.parent()
.unwrap()
.starts_with(root_path.parent().unwrap()));
assert!(
child_path
.parent()
.unwrap()
.starts_with(root_path.parent().unwrap()),
"Parent of child path '{}' must start with the parent of the root path '{}'",
child_path,
root_path
);

if let Some(parent_mod) = self.parent_module(child) {
let cur_mod = self.mod_map[&child_mod];
Expand Down
15 changes: 14 additions & 1 deletion crates/language-server/src/backend/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ use common::{impl_db_traits, InputDb};

use hir::{HirDb, LowerHirDb, SpannedHirDb};
use hir_analysis::{diagnostics::SpannedHirAnalysisDb, HirAnalysisDb};

use super::get_core::init_core_ingot;
// xxx use salsa::{ParallelDatabase, Snapshot};

#[salsa::db]
Expand All @@ -24,11 +26,22 @@ impl<DB> LanguageServerDb for DB where
}

#[salsa::db]
#[derive(Default, Clone)]
#[derive(Clone)]
pub struct LanguageServerDatabase {
storage: salsa::Storage<Self>,
}

impl Default for LanguageServerDatabase {
fn default() -> Self {
let mut db = LanguageServerDatabase {
storage: Default::default(),
};

init_core_ingot(&mut db);
db
}
}

impl_db_traits!(
LanguageServerDatabase,
InputDb,
Expand Down
85 changes: 85 additions & 0 deletions crates/language-server/src/backend/get_core.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
use camino::Utf8PathBuf;
use common::{
input::{IngotKind, Version},
InputDb, InputFile, InputIngot,
};
use tracing::info;

#[derive(rust_embed::RustEmbed)]
#[folder = "../../library/core"]
pub struct CoreLib;

#[salsa::tracked]
pub fn get_core_ingot(db: &dyn InputDb) -> InputIngot {
InputIngot::new(
db,
"core", // this should be handled by the driver crate default behavior
IngotKind::Core,
Version::new(0, 0, 1),
Default::default(),
)
}

pub fn init_core_ingot(db: &mut dyn InputDb) -> InputIngot {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be better implemented in the driver of course, I just kept it here for this sketch

info!("Loading std lib...");

// First collect all files and create the InputFiles
let mut std_files = Vec::new();
let mut root_file = None;

for path in CoreLib::iter() {
let path: Utf8PathBuf = path.as_ref().into();
info!("Loading stdlib file: {}", path);

if let Some(file) = CoreLib::get(path.as_str()) {
if !path.starts_with("src") {
continue;
};
if let Ok(contents) = String::from_utf8(file.data.as_ref().to_vec()) {
// Create InputFile with paths relative to std root
let input_file = InputFile::new(db, path.clone().into(), contents);

// Identify the root file (probably src/lib.fe or similar)
if path.as_str() == "src/lib.fe" {
root_file = Some(input_file);
}

std_files.push(input_file);
}
}
}

let core_ingot = get_core_ingot(db);
// Set up the ingot structure
if let Some(root) = root_file {
core_ingot.set_root_file(db, root);
}

assert!(root_file.is_some(), "std library must have a root file");

// Add all files to the ingot
core_ingot.set_files(db, std_files.into_iter().collect());

core_ingot
}

#[cfg(test)]
mod tests {
use crate::backend::db::LanguageServerDatabase;

use super::*;

#[test]
fn is_core_deduplicated() {
let mut db = LanguageServerDatabase::default();
let core_1 = get_core_ingot(&db);
let core_2 = get_core_ingot(&db);

let foo = InputFile::new(&db, "src/mod1/foo.fe".into(), "".into());

core_2.set_root_file(&mut db, foo);

assert!(core_1.eq(&core_2));
assert!(core_1.root_file(&db).eq(&core_2.root_file(&db)));
}
}
1 change: 1 addition & 0 deletions crates/language-server/src/backend/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub(crate) mod db;
pub(crate) mod get_core;
pub(crate) mod workspace;
use async_lsp::ClientSocket;
use db::LanguageServerDatabase;
Expand Down
48 changes: 11 additions & 37 deletions crates/language-server/src/backend/workspace.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
use std::path::{Path, PathBuf};

use super::db::LanguageServerDatabase;
use super::{db::LanguageServerDatabase, get_core::get_core_ingot};
use anyhow::Result;
use common::{
indexmap::IndexSet,
input::{IngotKind, Version},
input::{IngotDependency, IngotKind, Version},
InputFile, InputIngot,
};

use patricia_tree::StringPatriciaMap;
use salsa::Setter;
use tracing::info;

// #[derive(RustEmbed)]
// #[folder = "../library/std"]
// struct StdLib;

const FE_CONFIG_SUFFIX: &str = "fe.toml";

fn ingot_directory_key(path: String) -> String {
Expand Down Expand Up @@ -82,13 +78,20 @@ pub fn get_containing_ingot<'a, T>(

impl LocalIngotContext {
pub fn new(db: &LanguageServerDatabase, config_path: &str) -> Option<Self> {
let mut default_dependencies = IndexSet::new();
let core = get_core_ingot(db);

let std_library = IngotDependency::new("core", core);
default_dependencies.insert(std_library);

let ingot = InputIngot::new(
db,
config_path,
IngotKind::Local,
Version::new(0, 0, 0),
IndexSet::new(),
default_dependencies,
);

Some(Self {
ingot,
files: StringPatriciaMap::new(),
Expand Down Expand Up @@ -243,6 +246,7 @@ pub struct Workspace {

impl Workspace {
pub fn default() -> Self {
// let default_core_ingot = Some(get_core_ingot(db.as_input_db()));
Self {
ingot_contexts: StringPatriciaMap::new(),
standalone_ingot_context: StandaloneIngotContext::new(),
Expand All @@ -264,36 +268,6 @@ impl Workspace {
ingot_files.chain(standalone_files)
}

// pub fn load_std_lib(
// &mut self,
// db: &mut LanguageServerDatabase,
// root_path: &Path,
// ) -> Result<()> {
// let root_path_str = root_path.to_str().unwrap();
// self.touch_ingot_for_file_path(db, &format!("{}/std/{}", root_path_str, FE_CONFIG_SUFFIX))
// .unwrap();

// info!("Loading std lib...");

// // Collect paths to avoid borrowing `db` mutably during the closure
// let paths: Vec<_> = StdLib::iter().collect();

// for path in paths {
// let path_str = path.as_ref();
// let std_path = format!("{}/std/{}", root_path_str, path_str);
// info!("adding std file... {:?} --- {:?}", std_path, path_str);
// if let Some(file) = StdLib::get(path_str) {
// let contents = String::from_utf8(file.data.as_ref().to_vec());
// if let Ok(contents) = contents {
// if let Some((_ingot, file)) = self.touch_input_for_file_path(db, &std_path) {
// file.set_text(db).to(contents);
// }
// }
// }
// }
// Ok(())
// }

pub fn set_workspace_root(
&mut self,
db: &mut LanguageServerDatabase,
Expand Down
2 changes: 0 additions & 2 deletions crates/language-server/src/functionality/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,6 @@ pub async fn initialize(
.unwrap_or_else(|| std::env::current_dir().unwrap());

let _ = backend.workspace.set_workspace_root(&mut backend.db, &root);
// let _ = backend.workspace.load_std_lib(&mut backend.db, &root);
// let _ = backend.workspace.sync();

let capabilities = server_capabilities();
let initialize_result = InitializeResult {
Expand Down
Loading