Skip to content

Commit

Permalink
feat: increment parse in lsp (#911)
Browse files Browse the repository at this point in the history
feat: increment parse in lsp. Add parse cache in lsp state and increment parse in lsp.

Signed-off-by: he1pa <[email protected]>
  • Loading branch information
He1pa authored Nov 23, 2023
1 parent be76556 commit d2dea8f
Show file tree
Hide file tree
Showing 8 changed files with 55 additions and 13 deletions.
13 changes: 6 additions & 7 deletions kclvm/parser/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,9 @@ use kclvm_utils::pkgpath::rm_external_pkg_name;

use lexer::parse_token_streams;
use parser::Parser;
use std::cell::RefCell;
use std::collections::HashMap;
use std::path::PathBuf;
use std::sync::Arc;
use std::sync::{Arc, RwLock};

use kclvm_span::create_session_globals_then;

Expand Down Expand Up @@ -310,7 +309,7 @@ pub fn load_program(
Loader::new(sess, paths, opts, module_cache).load_main()
}

pub type KCLModuleCache = Arc<RefCell<IndexMap<String, ast::Module>>>;
pub type KCLModuleCache = Arc<RwLock<IndexMap<String, ast::Module>>>;
struct Loader {
sess: Arc<ParseSession>,
paths: Vec<String>,
Expand All @@ -324,7 +323,7 @@ impl Loader {
sess: Arc<ParseSession>,
paths: &[&str],
opts: Option<LoadProgramOptions>,
module_cache: Option<Arc<RefCell<IndexMap<String, ast::Module>>>>,
module_cache: Option<Arc<RwLock<IndexMap<String, ast::Module>>>>,
) -> Self {
Self {
sess,
Expand Down Expand Up @@ -363,7 +362,7 @@ impl Loader {
filename,
maybe_k_codes[i].clone(),
)?;
let mut module_cache_ref = module_cache.borrow_mut();
let mut module_cache_ref = module_cache.write().unwrap();
module_cache_ref.insert(filename.clone(), m.clone());
m
} else {
Expand Down Expand Up @@ -584,13 +583,13 @@ impl Loader {
let k_files = pkg_info.k_files.clone();
for filename in k_files {
let mut m = if let Some(module_cache) = self.module_cache.as_ref() {
let module_cache_ref = module_cache.borrow();
let module_cache_ref = module_cache.read().unwrap();
if let Some(module) = module_cache_ref.get(&filename) {
module.clone()
} else {
let m = parse_file_with_session(self.sess.clone(), &filename, None)?;
drop(module_cache_ref);
let mut module_cache_ref = module_cache.borrow_mut();
let mut module_cache_ref = module_cache.write().unwrap();
module_cache_ref.insert(filename.clone(), m.clone());
m
}
Expand Down
9 changes: 9 additions & 0 deletions kclvm/tools/src/LSP/src/find_refs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::util::{parse_param_and_compile, Param};
use anyhow;
use kclvm_ast::ast::Program;
use kclvm_error::Position as KCLPos;
use kclvm_parser::KCLModuleCache;
use kclvm_sema::core::global_state::GlobalState;
use kclvm_sema::resolver::scope::ProgramScope;
use lsp_types::{Location, Url};
Expand All @@ -22,6 +23,7 @@ pub(crate) fn find_refs<F: Fn(String) -> Result<(), anyhow::Error>>(
vfs: Option<Arc<RwLock<Vfs>>>,
logger: F,
gs: &GlobalState,
module_cache: Option<KCLModuleCache>,
) -> Result<Vec<Location>, String> {
let def = find_def_with_gs(kcl_pos, &gs, true);
match def {
Expand All @@ -37,6 +39,7 @@ pub(crate) fn find_refs<F: Fn(String) -> Result<(), anyhow::Error>>(
obj.get_name(),
include_declaration,
logger,
module_cache,
))
} else {
Err(format!("Invalid file path: {0}", start.filename))
Expand All @@ -59,6 +62,7 @@ pub(crate) fn find_refs_from_def<F: Fn(String) -> Result<(), anyhow::Error>>(
name: String,
include_declaration: bool,
logger: F,
module_cache: Option<KCLModuleCache>,
) -> Vec<Location> {
let mut ref_locations = vec![];
for (_, word_index) in &mut *word_index_map.write() {
Expand All @@ -72,6 +76,7 @@ pub(crate) fn find_refs_from_def<F: Fn(String) -> Result<(), anyhow::Error>>(
match parse_param_and_compile(
Param {
file: file_path.clone(),
module_cache: module_cache.clone(),
},
vfs.clone(),
) {
Expand Down Expand Up @@ -189,6 +194,7 @@ mod tests {
"a".to_string(),
true,
logger,
None,
),
);
}
Expand Down Expand Up @@ -243,6 +249,7 @@ mod tests {
"a".to_string(),
false,
logger,
None,
),
);
}
Expand Down Expand Up @@ -297,6 +304,7 @@ mod tests {
"Name".to_string(),
true,
logger,
None,
),
);
}
Expand Down Expand Up @@ -344,6 +352,7 @@ mod tests {
"name".to_string(),
true,
logger,
None,
),
);
}
Expand Down
1 change: 1 addition & 0 deletions kclvm/tools/src/LSP/src/quick_fix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ mod tests {
let (_, _, diags, _) = parse_param_and_compile(
Param {
file: file.to_string(),
module_cache: None,
},
Some(Arc::new(RwLock::new(Default::default()))),
)
Expand Down
2 changes: 2 additions & 0 deletions kclvm/tools/src/LSP/src/rename.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ pub fn rename_symbol(
if let Ok((_, _, _, gs)) = parse_param_and_compile(
Param {
file: p.to_string(),
module_cache: None,
},
None,
) {
Expand Down Expand Up @@ -105,6 +106,7 @@ pub fn select_symbol(selector: &ast::SymbolSelectorSpec) -> Option<(String, diag
if let Ok((prog, _, _, gs)) = parse_param_and_compile(
Param {
file: pkgpath.to_string(),
module_cache: None,
},
None,
) {
Expand Down
13 changes: 11 additions & 2 deletions kclvm/tools/src/LSP/src/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ pub(crate) fn handle_reference(
let db = snapshot.get_db(&path.clone().into())?;
let pos = kcl_pos(&file, params.text_document_position.position);
let log = |msg: String| log_message(msg, &sender);
let module_cache = snapshot.module_cache.clone();
match find_refs(
&db.prog,
&pos,
Expand All @@ -179,6 +180,7 @@ pub(crate) fn handle_reference(
Some(snapshot.vfs.clone()),
log,
&db.gs,
module_cache,
) {
core::result::Result::Ok(locations) => Ok(Some(locations)),
Err(msg) => {
Expand All @@ -200,8 +202,14 @@ pub(crate) fn handle_completion(
return Ok(None);
}

let db =
parse_param_and_compile(Param { file: file.clone() }, Some(snapshot.vfs.clone())).unwrap();
let db = parse_param_and_compile(
Param {
file: file.clone(),
module_cache: snapshot.module_cache.clone(),
},
Some(snapshot.vfs.clone()),
)
.unwrap();

let kcl_pos = kcl_pos(&file, params.text_document_position.position);
let completion_trigger_character = params
Expand Down Expand Up @@ -286,6 +294,7 @@ pub(crate) fn handle_rename(
Some(snapshot.vfs.clone()),
log,
&db.gs,
snapshot.module_cache.clone(),
);
match references {
Result::Ok(locations) => {
Expand Down
13 changes: 12 additions & 1 deletion kclvm/tools/src/LSP/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::to_lsp::{kcl_diag_to_lsp_diags, url};
use crate::util::{build_word_index, get_file_name, parse_param_and_compile, to_json, Param};
use crossbeam_channel::{select, unbounded, Receiver, Sender};
use indexmap::IndexSet;
use kclvm_parser::KCLModuleCache;
use lsp_server::{ReqQueue, Response};
use lsp_types::Url;
use lsp_types::{
Expand Down Expand Up @@ -75,6 +76,9 @@ pub(crate) struct LanguageServerState {

/// The word index map
pub word_index_map: Arc<RwLock<HashMap<Url, HashMap<String, Vec<Location>>>>>,

/// KCL parse cache
pub module_cache: Option<KCLModuleCache>,
}

/// A snapshot of the state of the language server
Expand All @@ -88,6 +92,8 @@ pub(crate) struct LanguageServerSnapshot {
pub opened_files: IndexSet<FileId>,
/// The word index map
pub word_index_map: Arc<RwLock<HashMap<Url, HashMap<String, Vec<Location>>>>>,
/// KCL parse cache
pub module_cache: Option<KCLModuleCache>,
}

#[allow(unused)]
Expand Down Expand Up @@ -120,6 +126,7 @@ impl LanguageServerState {
opened_files: IndexSet::new(),
word_index_map: Arc::new(RwLock::new(HashMap::new())),
loader,
module_cache: Some(KCLModuleCache::default()),
};

let word_index_map = state.word_index_map.clone();
Expand Down Expand Up @@ -198,16 +205,19 @@ impl LanguageServerState {
// Construct an AnalysisChange to apply to the analysis
for file in changed_files {
let vfs = self.vfs.read();

let start = Instant::now();
match get_file_name(vfs, file.file_id) {
Ok(filename) => {
match parse_param_and_compile(
Param {
file: filename.clone(),
module_cache: self.module_cache.clone(),
},
Some(self.vfs.clone()),
) {
Ok((prog, scope, diags, gs)) => {
let end = start.elapsed();
self.log_message(format!("compile time: {:?}s", end.as_secs_f32()));
self.analysis.set_db(
file.file_id,
AnalysisDatabase {
Expand Down Expand Up @@ -278,6 +288,7 @@ impl LanguageServerState {
db: self.analysis.db.clone(),
opened_files: self.opened_files.clone(),
word_index_map: self.word_index_map.clone(),
module_cache: self.module_cache.clone(),
}
}

Expand Down
12 changes: 11 additions & 1 deletion kclvm/tools/src/LSP/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,10 @@ pub(crate) fn compile_test_file(
let file = test_file.to_str().unwrap().to_string();

let (program, prog_scope, diags, gs) = parse_param_and_compile(
Param { file: file.clone() },
Param {
file: file.clone(),
module_cache: None,
},
Some(Arc::new(RwLock::new(Default::default()))),
)
.unwrap();
Expand Down Expand Up @@ -260,6 +263,7 @@ fn diagnostics_test() {
let (_, _, diags, _) = parse_param_and_compile(
Param {
file: file.to_string(),
module_cache: None,
},
Some(Arc::new(RwLock::new(Default::default()))),
)
Expand Down Expand Up @@ -407,6 +411,7 @@ fn complete_import_external_file_test() {
let (program, prog_scope, _, gs) = parse_param_and_compile(
Param {
file: path.to_string(),
module_cache: None,
},
Some(Arc::new(RwLock::new(Default::default()))),
)
Expand Down Expand Up @@ -464,6 +469,7 @@ fn goto_import_external_file_test() {
let (program, prog_scope, diags, gs) = parse_param_and_compile(
Param {
file: path.to_string(),
module_cache: None,
},
Some(Arc::new(RwLock::new(Default::default()))),
)
Expand Down Expand Up @@ -1128,6 +1134,7 @@ fn konfig_goto_def_test_base() {
let (program, prog_scope, _, gs) = parse_param_and_compile(
Param {
file: base_path_str.clone(),
module_cache: None,
},
Some(Arc::new(RwLock::new(Default::default()))),
)
Expand Down Expand Up @@ -1219,6 +1226,7 @@ fn konfig_goto_def_test_main() {
let (program, prog_scope, _, gs) = parse_param_and_compile(
Param {
file: main_path_str.clone(),
module_cache: None,
},
Some(Arc::new(RwLock::new(Default::default()))),
)
Expand Down Expand Up @@ -1282,6 +1290,7 @@ fn konfig_completion_test_main() {
let (program, prog_scope, _, gs) = parse_param_and_compile(
Param {
file: main_path_str.clone(),
module_cache: None,
},
Some(Arc::new(RwLock::new(Default::default()))),
)
Expand Down Expand Up @@ -1428,6 +1437,7 @@ fn konfig_hover_test_main() {
let (program, prog_scope, _, gs) = parse_param_and_compile(
Param {
file: main_path_str.clone(),
module_cache: None,
},
Some(Arc::new(RwLock::new(Default::default()))),
)
Expand Down
5 changes: 3 additions & 2 deletions kclvm/tools/src/LSP/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use kclvm_driver::{get_kcl_files, lookup_compile_unit};
use kclvm_error::Diagnostic;
use kclvm_error::Position as KCLPos;
use kclvm_parser::entry::get_dir_files;
use kclvm_parser::{load_program, ParseSession};
use kclvm_parser::{load_program, KCLModuleCache, ParseSession};
use kclvm_sema::advanced_resolver::AdvancedResolver;
use kclvm_sema::core::global_state::GlobalState;
use kclvm_sema::namer::Namer;
Expand Down Expand Up @@ -63,6 +63,7 @@ pub fn get_file_name(vfs: RwLockReadGuard<Vfs>, file_id: FileId) -> anyhow::Resu

pub(crate) struct Param {
pub file: String,
pub module_cache: Option<KCLModuleCache>,
}

pub(crate) fn parse_param_and_compile(
Expand All @@ -80,7 +81,7 @@ pub(crate) fn parse_param_and_compile(
opt.k_code_list.append(&mut k_code_list);
}
let sess = Arc::new(ParseSession::default());
let mut program = load_program(sess.clone(), &files, Some(opt), None)
let mut program = load_program(sess.clone(), &files, Some(opt), param.module_cache)
.map_err(|err| anyhow::anyhow!("Compile failed: {}", err))?;

let prog_scope = resolve_program_with_opts(
Expand Down

0 comments on commit d2dea8f

Please sign in to comment.