diff options
-rw-r--r-- | cli/lsp/diagnostics.rs | 52 | ||||
-rw-r--r-- | cli/lsp/language_server.rs | 23 | ||||
-rw-r--r-- | cli/lsp/performance.rs | 6 | ||||
-rw-r--r-- | cli/lsp/tsc.rs | 88 |
4 files changed, 85 insertions, 84 deletions
diff --git a/cli/lsp/diagnostics.rs b/cli/lsp/diagnostics.rs index 96153dacc..a3f6a65af 100644 --- a/cli/lsp/diagnostics.rs +++ b/cli/lsp/diagnostics.rs @@ -5,7 +5,9 @@ use super::client::Client; use super::documents; use super::documents::Documents; use super::language_server; +use super::performance::Performance; use super::tsc; +use super::tsc::TsServer; use crate::diagnostics; @@ -91,13 +93,30 @@ impl DiagnosticCollection { } } -#[derive(Debug, Default)] +#[derive(Debug)] pub(crate) struct DiagnosticsServer { channel: Option<mpsc::UnboundedSender<()>>, collection: Arc<Mutex<DiagnosticCollection>>, + client: Client, + performance: Arc<Performance>, + ts_server: Arc<TsServer>, } impl DiagnosticsServer { + pub fn new( + client: Client, + performance: Arc<Performance>, + ts_server: Arc<TsServer>, + ) -> Self { + DiagnosticsServer { + channel: Default::default(), + collection: Default::default(), + client, + performance, + ts_server, + } + } + pub(crate) async fn get( &self, specifier: &ModuleSpecifier, @@ -127,12 +146,13 @@ impl DiagnosticsServer { pub(crate) fn start( &mut self, language_server: Arc<Mutex<language_server::Inner>>, - client: Client, - ts_server: Arc<tsc::TsServer>, ) { let (tx, mut rx) = mpsc::unbounded_channel::<()>(); self.channel = Some(tx); let collection = self.collection.clone(); + let client = self.client.clone(); + let performance = self.performance.clone(); + let ts_server = self.ts_server.clone(); let _join_handle = thread::spawn(move || { let runtime = create_basic_runtime(); @@ -178,7 +198,8 @@ impl DiagnosticsServer { &client, collection.clone(), snapshot, - &ts_server + &ts_server, + performance.clone(), ).await; } } @@ -609,13 +630,12 @@ async fn update_diagnostics( collection: Arc<Mutex<DiagnosticCollection>>, snapshot: Arc<language_server::StateSnapshot>, ts_server: &tsc::TsServer, + performance: Arc<Performance>, ) { - let mark = snapshot.performance.mark("update_diagnostics", None::<()>); + let mark = performance.mark("update_diagnostics", None::<()>); let lint = async { - let mark = snapshot - .performance - .mark("update_diagnostics_lint", None::<()>); + let mark = performance.mark("update_diagnostics_lint", None::<()>); let collection = collection.clone(); let diagnostics = generate_lint_diagnostics(&snapshot, collection.clone()) .await @@ -629,13 +649,11 @@ async fn update_diagnostics( collection.set(DiagnosticSource::DenoLint, diagnostic_record); } publish_diagnostics(client, &mut collection, &snapshot).await; - snapshot.performance.measure(mark); + performance.measure(mark); }; let ts = async { - let mark = snapshot - .performance - .mark("update_diagnostics_ts", None::<()>); + let mark = performance.mark("update_diagnostics_ts", None::<()>); let collection = collection.clone(); let diagnostics = generate_ts_diagnostics(snapshot.clone(), collection.clone(), ts_server) @@ -649,13 +667,11 @@ async fn update_diagnostics( collection.set(DiagnosticSource::TypeScript, diagnostic_record); } publish_diagnostics(client, &mut collection, &snapshot).await; - snapshot.performance.measure(mark); + performance.measure(mark); }; let deps = async { - let mark = snapshot - .performance - .mark("update_diagnostics_deps", None::<()>); + let mark = performance.mark("update_diagnostics_deps", None::<()>); let collection = collection.clone(); let diagnostics = generate_deps_diagnostics(snapshot.clone(), collection.clone()) @@ -669,11 +685,11 @@ async fn update_diagnostics( collection.set(DiagnosticSource::Deno, diagnostic_record); } publish_diagnostics(client, &mut collection, &snapshot).await; - snapshot.performance.measure(mark); + performance.measure(mark); }; tokio::join!(lint, ts, deps); - snapshot.performance.measure(mark); + performance.measure(mark); } #[cfg(test)] diff --git a/cli/lsp/language_server.rs b/cli/lsp/language_server.rs index 24fbb2021..5b04b8a25 100644 --- a/cli/lsp/language_server.rs +++ b/cli/lsp/language_server.rs @@ -37,6 +37,7 @@ use super::config::ConfigSnapshot; use super::config::SETTINGS_SECTION; use super::diagnostics; use super::diagnostics::DiagnosticSource; +use super::diagnostics::DiagnosticsServer; use super::documents::to_hover_text; use super::documents::to_lsp_range; use super::documents::AssetOrDocument; @@ -80,7 +81,6 @@ pub(crate) struct StateSnapshot { pub maybe_lint_config: Option<LintConfig>, pub maybe_fmt_config: Option<FmtConfig>, pub module_registries: registries::ModuleRegistry, - pub performance: Performance, pub url_map: urls::LspUrlMap, } @@ -118,7 +118,7 @@ pub(crate) struct Inner { /// The URL for the import map which is used to determine relative imports. maybe_import_map_uri: Option<Url>, /// A collection of measurements which instrument that performance of the LSP. - performance: Performance, + performance: Arc<Performance>, /// A memoized version of fixable diagnostic codes retrieved from TypeScript. ts_fixable_diagnostics: Vec<String>, /// An abstraction that handles interactions with TypeScript. @@ -143,14 +143,20 @@ impl Inner { registries::ModuleRegistry::new(&module_registries_location); let location = dir.root.join(CACHE_PATH); let documents = Documents::new(&location); - let ts_server = Arc::new(TsServer::new()); + let performance = Arc::new(Performance::default()); + let ts_server = Arc::new(TsServer::new(performance.clone())); let config = Config::new(client.clone()); + let diagnostics_server = DiagnosticsServer::new( + client.clone(), + performance.clone(), + ts_server.clone(), + ); Self { assets: Default::default(), client, config, - diagnostics_server: Default::default(), + diagnostics_server, documents, maybe_cache_path: None, maybe_lint_config: None, @@ -161,7 +167,7 @@ impl Inner { maybe_import_map_uri: None, module_registries, module_registries_location, - performance: Default::default(), + performance, ts_fixable_diagnostics: Default::default(), ts_server, url_map: Default::default(), @@ -370,7 +376,6 @@ impl Inner { maybe_lint_config: self.maybe_lint_config.clone(), maybe_fmt_config: self.maybe_fmt_config.clone(), module_registries: self.module_registries.clone(), - performance: self.performance.clone(), url_map: self.url_map.clone(), })) } @@ -2360,11 +2365,7 @@ impl lspower::LanguageServer for LanguageServer { params: InitializeParams, ) -> LspResult<InitializeResult> { let mut language_server = self.0.lock().await; - let client = language_server.client.clone(); - let ts_server = language_server.ts_server.clone(); - language_server - .diagnostics_server - .start(self.0.clone(), client, ts_server); + language_server.diagnostics_server.start(self.0.clone()); language_server.initialize(params).await } diff --git a/cli/lsp/performance.rs b/cli/lsp/performance.rs index d251e012f..05e586ffd 100644 --- a/cli/lsp/performance.rs +++ b/cli/lsp/performance.rs @@ -72,11 +72,11 @@ impl From<PerformanceMark> for PerformanceMeasure { /// /// The structure will limit the size of measurements to the most recent 1000, /// and will roll off when that limit is reached. -#[derive(Debug, Clone)] +#[derive(Debug)] pub struct Performance { - counts: Arc<Mutex<HashMap<String, u32>>>, + counts: Mutex<HashMap<String, u32>>, max_size: usize, - measures: Arc<Mutex<VecDeque<PerformanceMeasure>>>, + measures: Mutex<VecDeque<PerformanceMeasure>>, } impl Default for Performance { diff --git a/cli/lsp/tsc.rs b/cli/lsp/tsc.rs index 6a8141d4d..bcaf7740f 100644 --- a/cli/lsp/tsc.rs +++ b/cli/lsp/tsc.rs @@ -4,6 +4,7 @@ use super::code_lens; use super::config; use super::language_server; use super::language_server::StateSnapshot; +use super::performance::Performance; use super::refactor::RefactorCodeActionData; use super::refactor::ALL_KNOWN_REFACTOR_ACTION_KINDS; use super::refactor::EXTRACT_CONSTANT; @@ -89,10 +90,10 @@ type Request = ( pub struct TsServer(mpsc::UnboundedSender<Request>); impl TsServer { - pub fn new() -> Self { + pub fn new(performance: Arc<Performance>) -> Self { let (tx, mut rx) = mpsc::unbounded_channel::<Request>(); let _join_handle = thread::spawn(move || { - let mut ts_runtime = js_runtime(); + let mut ts_runtime = js_runtime(performance); let runtime = create_basic_runtime(); runtime.block_on(async { @@ -2182,6 +2183,7 @@ struct Response { struct State<'a> { last_id: usize, + performance: Arc<Performance>, response: Option<Response>, state_snapshot: Arc<StateSnapshot>, snapshots: HashMap<(ModuleSpecifier, Cow<'a, str>), String>, @@ -2189,9 +2191,13 @@ struct State<'a> { } impl<'a> State<'a> { - fn new(state_snapshot: Arc<StateSnapshot>) -> Self { + fn new( + state_snapshot: Arc<StateSnapshot>, + performance: Arc<Performance>, + ) -> Self { Self { last_id: 1, + performance, response: None, state_snapshot, snapshots: HashMap::default(), @@ -2285,13 +2291,10 @@ fn op_dispose( state: &mut State, args: SourceSnapshotArgs, ) -> Result<bool, AnyError> { - let mark = state - .state_snapshot - .performance - .mark("op_dispose", Some(&args)); + let mark = state.performance.mark("op_dispose", Some(&args)); let specifier = state.normalize_specifier(&args.specifier)?; state.snapshots.remove(&(specifier, args.version.into())); - state.state_snapshot.performance.measure(mark); + state.performance.measure(mark); Ok(true) } @@ -2302,16 +2305,13 @@ struct SpecifierArgs { } fn op_exists(state: &mut State, args: SpecifierArgs) -> Result<bool, AnyError> { - let mark = state - .state_snapshot - .performance - .mark("op_exists", Some(&args)); + let mark = state.performance.mark("op_exists", Some(&args)); let specifier = state.normalize_specifier(args.specifier)?; let result = state .state_snapshot .documents .contains_specifier(&specifier); - state.state_snapshot.performance.measure(mark); + state.performance.measure(mark); Ok(result) } @@ -2330,10 +2330,7 @@ fn op_get_change_range( state: &mut State, args: GetChangeRangeArgs, ) -> Result<Value, AnyError> { - let mark = state - .state_snapshot - .performance - .mark("op_get_change_range", Some(&args)); + let mark = state.performance.mark("op_get_change_range", Some(&args)); let specifier = state.normalize_specifier(&args.specifier)?; cache_snapshot(state, &specifier, args.version.clone())?; let r = if let Some(current) = state @@ -2369,7 +2366,7 @@ fn op_get_change_range( )) }; - state.state_snapshot.performance.measure(mark); + state.performance.measure(mark); r } @@ -2377,10 +2374,7 @@ fn op_get_length( state: &mut State, args: SourceSnapshotArgs, ) -> Result<usize, AnyError> { - let mark = state - .state_snapshot - .performance - .mark("op_get_length", Some(&args)); + let mark = state.performance.mark("op_get_length", Some(&args)); let specifier = state.normalize_specifier(args.specifier)?; let r = if let Some(Some(asset)) = state.state_snapshot.assets.get(&specifier) { @@ -2393,7 +2387,7 @@ fn op_get_length( .unwrap(); Ok(content.encode_utf16().count()) }; - state.state_snapshot.performance.measure(mark); + state.performance.measure(mark); r } @@ -2410,10 +2404,7 @@ fn op_get_text( state: &mut State, args: GetTextArgs, ) -> Result<String, AnyError> { - let mark = state - .state_snapshot - .performance - .mark("op_get_text", Some(&args)); + let mark = state.performance.mark("op_get_text", Some(&args)); let specifier = state.normalize_specifier(args.specifier)?; let content = if let Some(Some(content)) = state.state_snapshot.assets.get(&specifier) { @@ -2425,7 +2416,7 @@ fn op_get_text( .get(&(specifier, args.version.into())) .unwrap() }; - state.state_snapshot.performance.measure(mark); + state.performance.measure(mark); Ok(text::slice(content, args.start..args.end).to_string()) } @@ -2433,13 +2424,10 @@ fn op_load( state: &mut State, args: SpecifierArgs, ) -> Result<Option<String>, AnyError> { - let mark = state - .state_snapshot - .performance - .mark("op_load", Some(&args)); + let mark = state.performance.mark("op_load", Some(&args)); let specifier = state.normalize_specifier(args.specifier)?; let document = state.state_snapshot.documents.get(&specifier); - state.state_snapshot.performance.measure(mark); + state.performance.measure(mark); Ok(document.map(|d| d.content().to_string())) } @@ -2447,10 +2435,7 @@ fn op_resolve( state: &mut State, args: ResolveArgs, ) -> Result<Vec<Option<(String, String)>>, AnyError> { - let mark = state - .state_snapshot - .performance - .mark("op_resolve", Some(&args)); + let mark = state.performance.mark("op_resolve", Some(&args)); let referrer = state.normalize_specifier(&args.base)?; let result = if let Some(resolved) = state @@ -2476,7 +2461,7 @@ fn op_resolve( )) }; - state.state_snapshot.performance.measure(mark); + state.performance.measure(mark); result } @@ -2510,10 +2495,7 @@ fn op_script_version( state: &mut State, args: ScriptVersionArgs, ) -> Result<Option<String>, AnyError> { - let mark = state - .state_snapshot - .performance - .mark("op_script_version", Some(&args)); + let mark = state.performance.mark("op_script_version", Some(&args)); let specifier = state.normalize_specifier(args.specifier)?; let r = if specifier.scheme() == "asset" { if state.state_snapshot.assets.contains_key(&specifier) { @@ -2530,22 +2512,22 @@ fn op_script_version( Ok(script_version) }; - state.state_snapshot.performance.measure(mark); + state.performance.measure(mark); r } /// Create and setup a JsRuntime based on a snapshot. It is expected that the /// supplied snapshot is an isolate that contains the TypeScript language /// server. -fn js_runtime() -> JsRuntime { +fn js_runtime(performance: Arc<Performance>) -> JsRuntime { JsRuntime::new(RuntimeOptions { - extensions: vec![init_extension()], + extensions: vec![init_extension(performance)], startup_snapshot: Some(tsc::compiler_snapshot()), ..Default::default() }) } -fn init_extension() -> Extension { +fn init_extension(performance: Arc<Performance>) -> Extension { Extension::builder() .ops(vec![ ("op_dispose", op_lsp(op_dispose)), @@ -2559,8 +2541,11 @@ fn init_extension() -> Extension { ("op_script_names", op_lsp(op_script_names)), ("op_script_version", op_lsp(op_script_version)), ]) - .state(|state| { - state.put(State::new(Arc::new(StateSnapshot::default()))); + .state(move |state| { + state.put(State::new( + Arc::new(StateSnapshot::default()), + performance.clone(), + )); Ok(()) }) .build() @@ -3019,15 +3004,14 @@ pub(crate) fn request( state_snapshot: Arc<StateSnapshot>, method: RequestMethod, ) -> Result<Value, AnyError> { - let performance = state_snapshot.performance.clone(); - let request_params = { + let (performance, request_params) = { let op_state = runtime.op_state(); let mut op_state = op_state.borrow_mut(); let state = op_state.borrow_mut::<State>(); state.state_snapshot = state_snapshot; state.last_id += 1; let id = state.last_id; - method.to_value(state, id) + (state.performance.clone(), method.to_value(state, id)) }; let mark = performance.mark("request", Some(request_params.clone())); let request_src = format!("globalThis.serverRequest({});", request_params); @@ -3090,7 +3074,7 @@ mod tests { let temp_dir = TempDir::new().expect("could not create temp dir"); let location = temp_dir.path().join("deps"); let state_snapshot = Arc::new(mock_state_snapshot(sources, &location)); - let mut runtime = js_runtime(); + let mut runtime = js_runtime(Default::default()); start(&mut runtime, debug, &state_snapshot) .expect("could not start server"); let ts_config = TsConfig::new(config); |