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

feat: lsp file watcher. #1744

Merged
merged 5 commits into from
Nov 8, 2024
Merged
Show file tree
Hide file tree
Changes from 4 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
37 changes: 29 additions & 8 deletions kclvm/Cargo.lock

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

1 change: 0 additions & 1 deletion kclvm/driver/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ edition = "2021"

[dependencies]
serde_json = "1.0.86"
notify = "6.1.1"

kclvm-config ={ path = "../config"}
kclvm-runtime ={ path = "../runtime"}
Expand Down
1 change: 1 addition & 0 deletions kclvm/sema/src/resolver/import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ impl<'ctx> Resolver<'ctx> {
let real_path =
Path::new(&self.program.root).join(pkgpath.replace('.', "/"));
if !self.program.pkgs.contains_key(pkgpath) {
self.ctx.invalid_pkg_scope.insert(pkgpath.to_string());
if real_path.exists() {
self.handler.add_error(
ErrorKind::CannotFindModule,
Expand Down
10 changes: 8 additions & 2 deletions kclvm/sema/src/resolver/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ mod var;
#[cfg(test)]
mod tests;

use indexmap::IndexMap;
use indexmap::{IndexMap, IndexSet};
use kclvm_error::diagnostic::Range;
use std::sync::Arc;
use std::{cell::RefCell, rc::Rc};
Expand Down Expand Up @@ -99,8 +99,12 @@ impl<'ctx> Resolver<'ctx> {

pub(crate) fn check_and_lint(&mut self, pkgpath: &str) -> ProgramScope {
self.check(pkgpath);
let mut scope_map = self.scope_map.clone();
for invalid_pkg_scope in &self.ctx.invalid_pkg_scope {
scope_map.remove(invalid_pkg_scope);
}
let mut scope = ProgramScope {
scope_map: self.scope_map.clone(),
scope_map,
import_names: self.ctx.import_names.clone(),
node_ty_map: self.node_ty_map.clone(),
handler: self.handler.clone(),
Expand Down Expand Up @@ -145,6 +149,8 @@ pub struct Context {
pub ty_ctx: TypeContext,
/// Type alias mapping
pub type_alias_mapping: IndexMap<String, IndexMap<String, String>>,
/// invalid pkg scope, remove when after resolve
pub invalid_pkg_scope: IndexSet<String>,
}

/// Resolve options.
Expand Down
3 changes: 2 additions & 1 deletion kclvm/tools/src/LSP/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,14 @@ anyhow = { version = "1.0", default-features = false, features = ["std"] }
crossbeam-channel = { version = "0.5.7", default-features = false }
ra_ap_vfs = "0.0.149"
ra_ap_vfs-notify = "0.0.149"
lsp-types = { version = "0.93.0", features = ["proposed"]}
lsp-types = { version = "0.93.0", features = ["proposed"] }
threadpool = { version = "1.8.1", default-features = false }
salsa = { version = "0.16.1", default-features = false }
serde_json = { version = "1.0", default-features = false }
parking_lot = { version = "0.12.0", default-features = false }
rustc-hash = { version = "1.1.0", default-features = false }
proc_macro_crate = { path = "../../benches/proc_macro_crate" }
notify = "7.0.0"

[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
tokio = { version = "1.37.0", features = ["full"] }
Expand Down
26 changes: 1 addition & 25 deletions kclvm/tools/src/LSP/src/notification.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
use kclvm_config::{
modfile::{KCL_MOD_FILE, KCL_WORK_FILE},
settings::DEFAULT_SETTING_FILE,
};
use kclvm_driver::lookup_compile_workspaces;
use lsp_types::notification::{
Cancel, DidChangeTextDocument, DidChangeWatchedFiles, DidCloseTextDocument,
DidOpenTextDocument, DidSaveTextDocument,
};
use std::{collections::HashSet, sync::Arc};
use std::collections::HashSet;

use crate::util::apply_document_changes;
use crate::{
Expand Down Expand Up @@ -137,27 +132,8 @@ impl LanguageServerState {
for change in params.changes {
let path = from_lsp::abs_path(&change.uri)?;
self.loader.handle.invalidate(path.clone());
if KCL_CONFIG_FILE.contains(&path.file_name().unwrap().to_str().unwrap()) {
self.entry_cache.write().clear();
let parent_path = path.parent().unwrap();
let path = parent_path.as_os_str().to_str().unwrap().to_string();
let tool = Arc::clone(&self.tool);
let (workspaces, failed) = lookup_compile_workspaces(&*tool.read(), &path, true);

if let Some(failed) = failed {
for (key, err) in failed {
self.log_message(format!("parse kcl.work failed: {}: {}", key, err));
}
}

for (workspace, opts) in workspaces {
self.async_compile(workspace, opts, None, false);
}
}
}

Ok(())
}
}

const KCL_CONFIG_FILE: [&str; 3] = [DEFAULT_SETTING_FILE, KCL_MOD_FILE, KCL_WORK_FILE];
20 changes: 12 additions & 8 deletions kclvm/tools/src/LSP/src/request.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use anyhow::anyhow;
use crossbeam_channel::Sender;

use kclvm_driver::WorkSpaceKind;
use kclvm_sema::info::is_valid_kcl_name;
use lsp_types::{Location, SemanticTokensResult, TextEdit};
use ra_ap_vfs::VfsPath;
Expand Down Expand Up @@ -97,7 +98,7 @@ impl LanguageServerSnapshot {
) -> anyhow::Result<Option<Arc<AnalysisDatabase>>> {
match self.try_get_db_state(path) {
Ok(db) => match db {
Some(db) => match db {
Some((_, db)) => match db {
DBState::Ready(db) => Ok(Some(db.clone())),
DBState::Compiling(_) | DBState::Init => {
log_message(
Expand All @@ -124,7 +125,10 @@ impl LanguageServerSnapshot {
/// return Ok(Some(db)) -> Compile completed
/// return Ok(None) -> RWlock, retry to unlock
/// return Err(_) -> Compile failed
pub(crate) fn try_get_db_state(&self, path: &VfsPath) -> anyhow::Result<Option<DBState>> {
pub(crate) fn try_get_db_state(
&self,
path: &VfsPath,
) -> anyhow::Result<Option<(WorkSpaceKind, DBState)>> {
match self.vfs.try_read() {
Some(vfs) => match vfs.file_id(path) {
Some(file_id) => {
Expand All @@ -134,7 +138,7 @@ impl LanguageServerSnapshot {
Some(option_workspace) => match option_workspace {
Some(work_space) => match self.workspaces.try_read() {
Some(workspaces) => match workspaces.get(work_space) {
Some(db) => Ok(Some(db.clone())),
Some(db) => Ok(Some((work_space.clone(), db.clone()))),
None => Err(anyhow::anyhow!(
LSPError::AnalysisDatabaseNotFound(path.clone())
)),
Expand All @@ -154,7 +158,7 @@ impl LanguageServerSnapshot {
let work_space = file_info.workspaces.iter().next().unwrap();
match self.workspaces.try_read() {
Some(workspaces) => match workspaces.get(work_space) {
Some(db) => Ok(Some(db.clone())),
Some(db) => Ok(Some((work_space.clone(), db.clone()))),
None => Err(anyhow::anyhow!(
LSPError::AnalysisDatabaseNotFound(path.clone())
)),
Expand Down Expand Up @@ -310,7 +314,7 @@ pub(crate) fn handle_completion(
return Ok(None);
}

let db_state = match snapshot.try_get_db_state(&path) {
let (workspace, db_state) = match snapshot.try_get_db_state(&path) {
Ok(option_state) => match option_state {
Some(db) => db,
None => return Err(anyhow!(LSPError::Retry)),
Expand Down Expand Up @@ -341,10 +345,10 @@ pub(crate) fn handle_completion(
let kcl_pos = kcl_pos(&file, params.text_document_position.position);

let metadata = snapshot
.entry_cache
.workspace_config_cache
.read()
.get(&file)
.and_then(|metadata| metadata.0 .2.clone());
.get(&workspace)
.and_then(|opt| opt.2.clone());

let res = completion(
completion_trigger_character,
Expand Down
Loading
Loading