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

enhance lsp diags. #1371

Merged
merged 2 commits into from
May 28, 2024
Merged
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
6 changes: 4 additions & 2 deletions kclvm/tools/src/LSP/src/find_refs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,10 @@ pub(crate) fn find_refs_from_def<F: Fn(String) -> Result<(), anyhow::Error>>(
vfs: vfs.clone(),
entry_cache: entry_cache.clone(),
tool: Arc::new(RwLock::new(toolchain::default())),
}) {
Ok((_, _, gs)) => {
})
.1
{
Ok((_, gs)) => {
let ref_pos = kcl_pos(&file_path, ref_loc.range.start);
if *ref_loc == def_loc && !include_declaration {
return false;
Expand Down
4 changes: 2 additions & 2 deletions kclvm/tools/src/LSP/src/quick_fix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,15 +183,15 @@ mod tests {
test_file.push("src/test_data/quick_fix.k");
let file = test_file.to_str().unwrap();

let (_, diags, _) = compile_with_params(Params {
let diags = compile_with_params(Params {
file: file.to_string(),
module_cache: None,
scope_cache: None,
vfs: Some(KCLVfs::default()),
entry_cache: None,
tool: Arc::new(RwLock::new(toolchain::default())),
})
.unwrap();
.0;

let diagnostics = diags
.iter()
Expand Down
89 changes: 45 additions & 44 deletions kclvm/tools/src/LSP/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,24 +228,46 @@ impl LanguageServerState {
let version =
snapshot.opened_files.read().get(&file.file_id).cloned();
let mut db = snapshot.db.write();
match compile_with_params(Params {
let (diags, compile_res) = compile_with_params(Params {
file: filename.clone(),
module_cache: Some(module_cache),
scope_cache: Some(scope_cache),
vfs: Some(snapshot.vfs),
entry_cache: Some(entry),
tool,
}) {
Ok((prog, diags, gs)) => {
let current_version = snapshot
.opened_files
.read()
.get(&file.file_id)
.cloned();
match (version, current_version) {
(Some(version), Some(current_version)) => {
// If the text is updated during compilation(current_version > version), the current compilation result will not be output.
if current_version == version {
});

let current_version =
snapshot.opened_files.read().get(&file.file_id).cloned();

match (version, current_version) {
(Some(version), Some(current_version)) => {
// If the text is updated during compilation(current_version > version), the current compilation result will not be output.
if current_version == version {
let diagnostics = diags
.iter()
.flat_map(|diag| {
kcl_diag_to_lsp_diags(
diag,
filename.as_str(),
)
})
.collect::<Vec<Diagnostic>>();
sender.send(Task::Notify(
lsp_server::Notification {
method: PublishDiagnostics::METHOD
.to_owned(),
params: to_json(PublishDiagnosticsParams {
uri,
diagnostics,
version: None,
})
.unwrap(),
},
));

match compile_res {
Ok((prog, gs)) => {
db.insert(
file.file_id,
Arc::new(AnalysisDatabase {
Expand All @@ -254,42 +276,21 @@ impl LanguageServerState {
version,
}),
);

let diagnostics = diags
.iter()
.flat_map(|diag| {
kcl_diag_to_lsp_diags(
diag,
filename.as_str(),
)
})
.collect::<Vec<Diagnostic>>();
sender.send(Task::Notify(
lsp_server::Notification {
method: PublishDiagnostics::METHOD
.to_owned(),
params: to_json(
PublishDiagnosticsParams {
uri,
diagnostics,
version: None,
},
)
.unwrap(),
},
));
}
Err(err) => {
db.remove(&file.file_id);
log_message(
format!(
"Compile failed: {:?}",
err.to_string()
),
&sender,
);
}
}
_ => {}
}
}
Err(err) => {
db.remove(&file.file_id);
log_message(
format!("Compile failed: {:?}", err.to_string()),
&sender,
);
}
_ => {}
}
}
Err(_) => {
Expand Down
37 changes: 22 additions & 15 deletions kclvm/tools/src/LSP/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,15 +127,15 @@ pub(crate) fn compile_test_file(

let file = test_file.to_str().unwrap().to_string();

let (program, diags, gs) = compile_with_params(Params {
let (diags, compile_res) = compile_with_params(Params {
file: file.clone(),
module_cache: Some(KCLModuleCache::default()),
scope_cache: Some(KCLScopeCache::default()),
vfs: Some(KCLVfs::default()),
entry_cache: Some(KCLEntryCache::default()),
tool: Arc::new(RwLock::new(toolchain::default())),
})
.unwrap();
});
let (program, gs) = compile_res.unwrap();
(file, program, diags, gs)
}

Expand Down Expand Up @@ -290,15 +290,15 @@ fn diagnostics_test() {
test_file.push("src/test_data/diagnostics.k");
let file = test_file.to_str().unwrap();

let (_, diags, _) = compile_with_params(Params {
let diags = compile_with_params(Params {
file: file.to_string(),
module_cache: None,
scope_cache: None,
vfs: Some(KCLVfs::default()),
entry_cache: Some(KCLEntryCache::default()),
tool: Arc::new(RwLock::new(toolchain::default())),
})
.unwrap();
.0;

let diagnostics = diags
.iter()
Expand Down Expand Up @@ -478,14 +478,15 @@ fn complete_import_external_file_test() {
.output()
.unwrap();

let (program, _, gs) = compile_with_params(Params {
let (program, gs) = compile_with_params(Params {
file: path.to_string(),
module_cache: None,
scope_cache: None,
vfs: Some(KCLVfs::default()),
entry_cache: Some(KCLEntryCache::default()),
tool: Arc::new(RwLock::new(toolchain::default())),
})
.1
.unwrap();

let pos = KCLPos {
Expand Down Expand Up @@ -538,15 +539,15 @@ fn goto_import_external_file_test() {
.output()
.unwrap();

let (_program, diags, gs) = compile_with_params(Params {
let (diags, compile_res) = compile_with_params(Params {
file: path.to_string(),
module_cache: None,
scope_cache: None,
vfs: Some(KCLVfs::default()),
entry_cache: Some(KCLEntryCache::default()),
tool: Arc::new(RwLock::new(toolchain::default())),
})
.unwrap();
});
let gs = compile_res.unwrap().1;

assert_eq!(diags.len(), 0);

Expand Down Expand Up @@ -1393,14 +1394,15 @@ fn konfig_goto_def_test_base() {
let mut base_path = konfig_path.clone();
base_path.push("appops/nginx-example/base/base.k");
let base_path_str = base_path.to_str().unwrap().to_string();
let (_program, _, gs) = compile_with_params(Params {
let (_program, gs) = compile_with_params(Params {
file: base_path_str.clone(),
module_cache: None,
scope_cache: None,
vfs: Some(KCLVfs::default()),
entry_cache: Some(KCLEntryCache::default()),
tool: Arc::new(RwLock::new(toolchain::default())),
})
.1
.unwrap();

// schema def
Expand Down Expand Up @@ -1486,14 +1488,15 @@ fn konfig_goto_def_test_main() {
let mut main_path = konfig_path.clone();
main_path.push("appops/nginx-example/dev/main.k");
let main_path_str = main_path.to_str().unwrap().to_string();
let (_program, _, gs) = compile_with_params(Params {
let (_program, gs) = compile_with_params(Params {
file: main_path_str.clone(),
module_cache: None,
scope_cache: None,
vfs: Some(KCLVfs::default()),
entry_cache: Some(KCLEntryCache::default()),
tool: Arc::new(RwLock::new(toolchain::default())),
})
.1
.unwrap();

// schema def
Expand Down Expand Up @@ -1551,14 +1554,15 @@ fn konfig_completion_test_main() {
let mut main_path = konfig_path.clone();
main_path.push("appops/nginx-example/dev/main.k");
let main_path_str = main_path.to_str().unwrap().to_string();
let (program, _, gs) = compile_with_params(Params {
let (program, gs) = compile_with_params(Params {
file: main_path_str.clone(),
module_cache: None,
scope_cache: None,
vfs: Some(KCLVfs::default()),
entry_cache: Some(KCLEntryCache::default()),
tool: Arc::new(RwLock::new(toolchain::default())),
})
.1
.unwrap();

// pkg's definition(schema) completion
Expand Down Expand Up @@ -1665,14 +1669,15 @@ fn konfig_hover_test_main() {
let mut main_path = konfig_path.clone();
main_path.push("appops/nginx-example/dev/main.k");
let main_path_str = main_path.to_str().unwrap().to_string();
let (_program, _, gs) = compile_with_params(Params {
let (_program, gs) = compile_with_params(Params {
file: main_path_str.clone(),
module_cache: None,
scope_cache: None,
vfs: Some(KCLVfs::default()),
entry_cache: Some(KCLEntryCache::default()),
tool: Arc::new(RwLock::new(toolchain::default())),
})
.1
.unwrap();

// schema def hover
Expand Down Expand Up @@ -2099,15 +2104,17 @@ fn compile_unit_test() {
test_file.push("src/test_data/compile_unit/b.k");
let file = test_file.to_str().unwrap();

let (prog, ..) = compile_with_params(Params {
let prog = compile_with_params(Params {
file: file.to_string(),
module_cache: None,
scope_cache: None,
vfs: Some(KCLVfs::default()),
entry_cache: Some(KCLEntryCache::default()),
tool: Arc::new(RwLock::new(toolchain::default())),
})
.unwrap();
.1
.unwrap()
.0;
// b.k is not contained in kcl.yaml but need to be contained in main pkg
assert!(prog
.pkgs
Expand Down
69 changes: 39 additions & 30 deletions kclvm/tools/src/LSP/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ use parking_lot::RwLockReadGuard;
use ra_ap_vfs::{FileId, Vfs};
use serde::{de::DeserializeOwned, Serialize};

use std::fs;
use std::path::Path;
use std::{fs, panic};

#[allow(unused)]
/// Deserializes a `T` from a json value.
Expand Down Expand Up @@ -92,7 +92,7 @@ pub(crate) fn lookup_compile_unit_with_cache(

pub(crate) fn compile_with_params(
params: Params,
) -> anyhow::Result<(Program, IndexSet<Diagnostic>, GlobalState)> {
) -> (IndexSet<Diagnostic>, anyhow::Result<(Program, GlobalState)>) {
// Lookup compile unit (kcl.mod or kcl.yaml) from the entry file.
let (mut files, opt) =
lookup_compile_unit_with_cache(&*params.tool.read(), &params.entry_cache, &params.file);
Expand All @@ -105,36 +105,45 @@ pub(crate) fn compile_with_params(
opt.load_plugins = true;
// Update opt.k_code_list
if let Some(vfs) = params.vfs {
let mut k_code_list = load_files_code_from_vfs(&files, vfs)?;
let mut k_code_list = match load_files_code_from_vfs(&files, vfs) {
Ok(code_list) => code_list,
Err(e) => {
return (
IndexSet::new(),
Err(anyhow::anyhow!("Compile failed: {:?}", e)),
)
}
};
opt.k_code_list.append(&mut k_code_list);
}
match panic::catch_unwind(move || {
// Parser
let sess = ParseSessionRef::default();
let mut program = load_program(sess.clone(), &files, Some(opt), params.module_cache)
.unwrap()
.program;
// Resolver
let prog_scope = resolve_program_with_opts(
&mut program,
kclvm_sema::resolver::Options {
merge_program: false,
type_erasure: false,
..Default::default()
},
params.scope_cache,
);
// Please note that there is no global state cache at this stage.
let gs = GlobalState::default();
let gs = Namer::find_symbols(&program, gs);
let gs = AdvancedResolver::resolve_program(&program, gs, prog_scope.node_ty_map.clone())?;
// Merge parse diagnostic and resolve diagnostic
sess.append_diagnostic(prog_scope.handler.diagnostics.clone());
let diags = sess.1.borrow().diagnostics.clone();
Ok((program, diags, gs))
}) {
Ok(res) => res,
Err(e) => Err(anyhow::anyhow!("Compile failed: {:?}", e)),

let mut diags = IndexSet::new();

// Parser
let sess = ParseSessionRef::default();
let mut program = match load_program(sess.clone(), &files, Some(opt), params.module_cache) {
Ok(r) => r.program,
Err(e) => return (diags, Err(anyhow::anyhow!("Parse failed: {:?}", e))),
};
diags.extend(sess.1.borrow().diagnostics.clone());
// Resolver
let prog_scope = resolve_program_with_opts(
&mut program,
kclvm_sema::resolver::Options {
merge_program: false,
type_erasure: false,
..Default::default()
},
params.scope_cache,
);
diags.extend(prog_scope.handler.diagnostics);

// Please note that there is no global state cache at this stage.
let gs = GlobalState::default();
let gs = Namer::find_symbols(&program, gs);
match AdvancedResolver::resolve_program(&program, gs, prog_scope.node_ty_map.clone()) {
Ok(gs) => (diags, Ok((program, gs))),
Err(e) => (diags, Err(anyhow::anyhow!("Parse failed: {:?}", e))),
}
}

Expand Down
Loading