Skip to content

Commit

Permalink
test: add compile unit cache e2e test
Browse files Browse the repository at this point in the history
Signed-off-by: he1pa <18012015693@163.com>
  • Loading branch information
He1pa committed Apr 7, 2024
1 parent 836ee48 commit def7169
Show file tree
Hide file tree
Showing 3 changed files with 144 additions and 14 deletions.
7 changes: 3 additions & 4 deletions kclvm/tools/src/LSP/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::word_index::build_word_index;
use anyhow::Result;
use crossbeam_channel::{select, unbounded, Receiver, Sender};
use kclvm_parser::{KCLModuleCache, LoadProgramOptions};
use kclvm_sema::resolver::scope::{CachedScope, KCLScopeCache};
use kclvm_sema::resolver::scope::KCLScopeCache;
use lsp_server::{ReqQueue, Request, Response};
use lsp_types::Url;
use lsp_types::{
Expand All @@ -18,7 +18,6 @@ use lsp_types::{
use parking_lot::RwLock;
use ra_ap_vfs::{ChangeKind, ChangedFile, FileId, Vfs};
use std::collections::HashMap;
use std::sync::Mutex;
use std::thread;
use std::time::Duration;
use std::{sync::Arc, time::Instant};
Expand Down Expand Up @@ -149,8 +148,8 @@ impl LanguageServerState {
word_index_map: Arc::new(RwLock::new(HashMap::new())),
loader,
module_cache: KCLModuleCache::default(),
scope_cache: Arc::new(Mutex::new(CachedScope::default())),
compile_unit_cache: Arc::new(RwLock::new(HashMap::default())),
scope_cache: KCLScopeCache::default(),
compile_unit_cache: KCLCompileUnitCache::default(),
};

let word_index_map = state.word_index_map.clone();
Expand Down
124 changes: 124 additions & 0 deletions kclvm/tools/src/LSP/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ use lsp_types::CompletionResponse;
use lsp_types::CompletionTriggerKind;
use lsp_types::DocumentFormattingParams;
use lsp_types::DocumentSymbolParams;
use lsp_types::FileChangeType;
use lsp_types::FileEvent;
use lsp_types::GotoDefinitionParams;
use lsp_types::GotoDefinitionResponse;
use lsp_types::Hover;
Expand Down Expand Up @@ -45,8 +47,10 @@ use std::path::Path;
use std::path::PathBuf;
use std::process::Command;

use std::sync::Arc;
use std::thread;
use std::time::Duration;
use std::time::Instant;

use kclvm_ast::ast::Program;
use kclvm_error::Diagnostic as KCLDiagnostic;
Expand Down Expand Up @@ -74,6 +78,7 @@ use crate::main_loop::main_loop;
use crate::state::KCLCompileUnitCache;
use crate::state::KCLVfs;
use crate::to_lsp::kcl_diag_to_lsp_diags;
use crate::util::compile_unit_with_cache;
use crate::util::to_json;
use crate::util::{apply_document_changes, compile_with_params, Params};

Expand Down Expand Up @@ -882,6 +887,125 @@ fn cancel_test() {
assert!(server.receive_response(id.into()).is_none());
}

#[test]
fn compile_unit_cache_test() {
let root = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
let mut path = root.clone();
path.push("src/test_data/compile_unit/b.k");

let path = path.to_str().unwrap();

let compile_unit_cache = KCLCompileUnitCache::default();
let start = Instant::now();
let _ = compile_unit_with_cache(&Some(Arc::clone(&compile_unit_cache)), &path.to_string());
let first_compile_time = start.elapsed();

let start = Instant::now();
let _ = compile_unit_with_cache(&Some(compile_unit_cache), &path.to_string());
let second_compile_time = start.elapsed();

assert!(first_compile_time > second_compile_time);
}

#[test]
fn compile_unit_cache_e2e_test() {
let root = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
let mut path = root.clone();
let mut kcl_yaml = root.clone();
path.push("src/test_data/compile_unit/b.k");
kcl_yaml.push("src/test_data/compile_unit/kcl.yaml");

let path = path.to_str().unwrap();

let kcl_yaml = kcl_yaml.to_str().unwrap();
let src = std::fs::read_to_string(path).unwrap();
let server = Project {}.server(InitializeParams::default());

// Mock open file
server.notification::<lsp_types::notification::DidOpenTextDocument>(
lsp_types::DidOpenTextDocumentParams {
text_document: TextDocumentItem {
uri: Url::from_file_path(path).unwrap(),
language_id: "KCL".to_string(),
version: 0,
text: src,
},
},
);

let id = server.next_request_id.get();
server.next_request_id.set(id.wrapping_add(1));

let r: Request = Request::new(
id.into(),
"textDocument/documentSymbol".to_string(),
DocumentSymbolParams {
text_document: TextDocumentIdentifier {
uri: Url::from_file_path(path).unwrap(),
},
work_done_progress_params: Default::default(),
partial_result_params: Default::default(),
},
);

// First time send request and wait for it's response
let start = Instant::now();
let _ = server.send_and_receive(r);
let first_compile_time = start.elapsed();

let id = server.next_request_id.get();
server.next_request_id.set(id.wrapping_add(1));

// Second time send request and wait for it's response
let r: Request = Request::new(
id.into(),
"textDocument/documentSymbol".to_string(),
DocumentSymbolParams {
text_document: TextDocumentIdentifier {
uri: Url::from_file_path(path).unwrap(),
},
work_done_progress_params: Default::default(),
partial_result_params: Default::default(),
},
);

let start = Instant::now();
let _ = server.send_and_receive(r);
let second_compile_time = start.elapsed();
assert!(first_compile_time > second_compile_time);

// Mock edit config file, clear cache
server.notification::<lsp_types::notification::DidChangeWatchedFiles>(
lsp_types::DidChangeWatchedFilesParams {
changes: vec![FileEvent {
uri: Url::from_file_path(kcl_yaml).unwrap(),
typ: FileChangeType::CHANGED,
}],
},
);

let id = server.next_request_id.get();
server.next_request_id.set(id.wrapping_add(1));

// Third time send request and wait for it's response
let r: Request = Request::new(
id.into(),
"textDocument/documentSymbol".to_string(),
DocumentSymbolParams {
text_document: TextDocumentIdentifier {
uri: Url::from_file_path(path).unwrap(),
},
work_done_progress_params: Default::default(),
partial_result_params: Default::default(),
},
);

let start = Instant::now();
let _ = server.send_and_receive(r);
let third_compile_time = start.elapsed();
assert!(third_compile_time > second_compile_time);
}

#[test]
fn goto_def_test() {
let root = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
Expand Down
27 changes: 17 additions & 10 deletions kclvm/tools/src/LSP/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use kclvm_driver::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, KCLModuleCache, ParseSessionRef};
use kclvm_parser::{load_program, KCLModuleCache, LoadProgramOptions, ParseSessionRef};
use kclvm_sema::advanced_resolver::AdvancedResolver;
use kclvm_sema::core::global_state::GlobalState;
use kclvm_sema::namer::Namer;
Expand Down Expand Up @@ -67,20 +67,27 @@ pub(crate) struct Params {
pub compile_unit_cache: Option<KCLCompileUnitCache>,
}

pub(crate) fn compile_with_params(
params: Params,
) -> anyhow::Result<(Program, IndexSet<Diagnostic>, GlobalState)> {
// Lookup compile unit (kcl.mod or kcl.yaml) from the entry file.
let (mut files, opt) = match &params.compile_unit_cache {
pub(crate) fn compile_unit_with_cache(
compile_unit_cache: &Option<KCLCompileUnitCache>,
file: &String,
) -> (Vec<String>, Option<LoadProgramOptions>) {
match compile_unit_cache {
Some(cache) => {
let map = cache.read();
match map.get(&params.file) {
match map.get(file) {
Some(compile_unit) => compile_unit.clone(),
None => lookup_compile_unit(&params.file, true),
None => lookup_compile_unit(file, true),
}
}
None => lookup_compile_unit(&params.file, true),
};
None => lookup_compile_unit(file, true),
}
}

pub(crate) fn compile_with_params(
params: Params,
) -> anyhow::Result<(Program, IndexSet<Diagnostic>, GlobalState)> {
// Lookup compile unit (kcl.mod or kcl.yaml) from the entry file.
let (mut files, opt) = compile_unit_with_cache(&params.compile_unit_cache, &params.file);

if let Some(cache) = params.compile_unit_cache {
cache
Expand Down

0 comments on commit def7169

Please sign in to comment.