Skip to content

Commit 65b808a

Browse files
Cache Reference Directories (#18)
1 parent f41d431 commit 65b808a

File tree

3 files changed

+46
-76
lines changed

3 files changed

+46
-76
lines changed

server/src/config.rs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,41 @@
11
// Copyright (c) ZeroC, Inc.
22

3+
use slicec::slice_options::SliceOptions;
34
use tower_lsp::{
45
lsp_types::{ConfigurationItem, DidChangeConfigurationParams, Url},
56
Client,
67
};
78

89
#[derive(Default, Debug)]
910
pub struct SliceConfig {
10-
built_in_slice_path: String,
1111
references: Option<Vec<String>>,
12+
built_in_slice_path: String,
1213
root_uri: Option<Url>,
14+
cached_slice_options: SliceOptions,
1315
}
1416

1517
impl SliceConfig {
1618
pub fn set_root_uri(&mut self, root: Url) {
1719
self.root_uri = Some(root);
20+
self.refresh_reference_paths();
1821
}
1922

20-
pub fn set_built_in_reference(&mut self, path: impl Into<String>) {
21-
self.built_in_slice_path = path.into();
23+
pub fn set_built_in_reference(&mut self, path: String) {
24+
self.built_in_slice_path = path;
25+
self.refresh_reference_paths();
2226
}
2327

24-
pub fn try_update_from_params(&mut self, params: &DidChangeConfigurationParams) {
28+
pub fn update_from_params(&mut self, params: &DidChangeConfigurationParams) {
2529
self.references = Self::parse_reference_directories(params);
30+
self.refresh_reference_paths();
2631
}
2732

2833
pub async fn try_update_from_client(
2934
&mut self,
3035
client: &Client,
3136
) -> tower_lsp::jsonrpc::Result<()> {
3237
self.references = Self::fetch_reference_directories(client).await?;
38+
self.refresh_reference_paths();
3339
Ok(())
3440
}
3541

@@ -70,8 +76,13 @@ impl SliceConfig {
7076
})
7177
}
7278

79+
// This function should be called whenever the configuration changes.
80+
fn refresh_reference_paths(&mut self) {
81+
self.cached_slice_options.references = self.resolve_reference_paths();
82+
}
83+
7384
// Resolve reference URIs to file paths to be used by the Slice compiler.
74-
pub fn resolve_reference_paths(&self) -> Vec<String> {
85+
fn resolve_reference_paths(&self) -> Vec<String> {
7586
// If `root_uri` isn't set, or doesn't represent a valid file path, path resolution is impossible, so we return.
7687
let Some(Ok(root_path)) = self.root_uri.as_ref().map(Url::to_file_path) else {
7788
return vec![];
@@ -119,4 +130,8 @@ impl SliceConfig {
119130
paths.push(self.built_in_slice_path.clone());
120131
paths
121132
}
133+
134+
pub fn as_slice_options(&self) -> &SliceOptions {
135+
&self.cached_slice_options
136+
}
122137
}

server/src/main.rs

Lines changed: 26 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ use config::SliceConfig;
44
use diagnostic_ext::try_into_lsp_diagnostic;
55
use hover::get_hover_info;
66
use jump_definition::get_definition_span;
7-
use shared_state::SharedState;
8-
use slicec::{compilation_state::CompilationState, slice_options::SliceOptions};
7+
use slicec::compilation_state::CompilationState;
98
use std::{
109
collections::{HashMap, HashSet},
1110
sync::Arc,
@@ -18,7 +17,6 @@ mod config;
1817
mod diagnostic_ext;
1918
mod hover;
2019
mod jump_definition;
21-
mod shared_state;
2220
mod utils;
2321

2422
#[tokio::main]
@@ -27,9 +25,9 @@ async fn main() {
2725
let stdout = tokio::io::stdout();
2826

2927
let (service, socket) = LspService::new(|client| Backend {
30-
slice_config: Arc::new(Mutex::new(SliceConfig::default())),
3128
client,
32-
shared_state: Arc::new(Mutex::new(SharedState::new())),
29+
slice_config: Arc::new(Mutex::new(SliceConfig::default())),
30+
compilation_state: Arc::new(Mutex::new(CompilationState::create())),
3331
});
3432

3533
Server::new(stdin, stdout, socket).serve(service).await;
@@ -38,7 +36,7 @@ async fn main() {
3836
struct Backend {
3937
client: Client,
4038
slice_config: Arc<Mutex<SliceConfig>>,
41-
shared_state: Arc<Mutex<SharedState>>,
39+
compilation_state: Arc<Mutex<CompilationState>>,
4240
}
4341

4442
#[tower_lsp::async_trait]
@@ -65,7 +63,7 @@ impl LanguageServer for Backend {
6563
options.get("builtInSlicePath").and_then(|v| v.as_str())
6664
{
6765
let mut slice_config = self.slice_config.lock().await;
68-
slice_config.set_built_in_reference(built_in_slice_path);
66+
slice_config.set_built_in_reference(built_in_slice_path.to_owned());
6967
}
7068
}
7169

@@ -109,19 +107,15 @@ impl LanguageServer for Backend {
109107
.await;
110108
}
111109

112-
let mut shared_state_lock = self.shared_state.lock().await;
113-
114110
// Compile the Slice files and publish diagnostics
115-
let (updated_state, options) = self.compile_slice_files().await;
116-
117-
shared_state_lock.compilation_state = updated_state;
118-
shared_state_lock.compilation_options = options;
111+
let mut compilation_state_lock = self.compilation_state.lock().await;
112+
*compilation_state_lock = self.compile_slice_files().await;
119113

120114
self.client
121115
.log_message(MessageType::INFO, "Slice Language Server initialized")
122116
.await;
123117

124-
self.publish_diagnostics_for_all_files(&mut shared_state_lock)
118+
self.publish_diagnostics_for_all_files(&mut compilation_state_lock)
125119
.await;
126120
}
127121

@@ -137,22 +131,21 @@ impl LanguageServer for Backend {
137131
// Update the slice configuration
138132
{
139133
let mut slice_config = self.slice_config.lock().await;
140-
slice_config.try_update_from_params(&params);
134+
slice_config.update_from_params(&params);
141135
}
142136

143137
// Store the current files in the compilation state before re-compiling
144138
let current_files = &self
145-
.shared_state
139+
.compilation_state
146140
.lock()
147141
.await
148-
.compilation_state
149142
.files
150143
.keys()
151144
.cloned()
152145
.collect::<HashSet<_>>();
153146

154147
// Re-compile the Slice files considering the updated references
155-
let (updated_state, options) = self.compile_slice_files().await;
148+
let updated_state = self.compile_slice_files().await;
156149

157150
// Clear the diagnostics from files that are no longer in the compilation state
158151
let new_files = &updated_state.files.keys().cloned().collect::<HashSet<_>>();
@@ -163,12 +156,10 @@ impl LanguageServer for Backend {
163156
self.client.publish_diagnostics(uri, vec![], None).await;
164157
}
165158

166-
let mut shared_state_lock = self.shared_state.lock().await;
167-
168-
shared_state_lock.compilation_state = updated_state;
169-
shared_state_lock.compilation_options = options;
159+
let mut compilation_state_lock = self.compilation_state.lock().await;
160+
*compilation_state_lock = updated_state;
170161

171-
self.publish_diagnostics_for_all_files(&mut shared_state_lock)
162+
self.publish_diagnostics_for_all_files(&mut compilation_state_lock)
172163
.await;
173164
}
174165

@@ -187,7 +178,7 @@ impl LanguageServer for Backend {
187178
.unwrap();
188179

189180
let position = params.text_document_position_params.position;
190-
let compilation_state = &self.shared_state.lock().await.compilation_state;
181+
let compilation_state = &self.compilation_state.lock().await;
191182

192183
let location = match get_definition_span(compilation_state, param_uri, position) {
193184
Some(location) => location,
@@ -224,7 +215,7 @@ impl LanguageServer for Backend {
224215
)
225216
.unwrap();
226217
let position = params.text_document_position_params.position;
227-
let compilation_state = &self.shared_state.lock().await.compilation_state;
218+
let compilation_state = &self.compilation_state.lock().await;
228219
Ok(
229220
get_hover_info(compilation_state, uri, position).map(|info| Hover {
230221
contents: HoverContents::Scalar(MarkedString::String(info)),
@@ -247,49 +238,31 @@ impl LanguageServer for Backend {
247238

248239
impl Backend {
249240
async fn handle_file_change(&self) {
250-
let (updated_state, options) = self.compile_slice_files().await;
241+
let updated_state = self.compile_slice_files().await;
251242

252-
let mut shared_state_lock = self.shared_state.lock().await;
243+
let mut compilation_state_lock = self.compilation_state.lock().await;
244+
*compilation_state_lock = updated_state;
253245

254-
shared_state_lock.compilation_state = updated_state;
255-
shared_state_lock.compilation_options = options;
256-
257-
self.publish_diagnostics_for_all_files(&mut shared_state_lock)
246+
self.publish_diagnostics_for_all_files(&mut compilation_state_lock)
258247
.await;
259248
}
260249

261-
async fn compile_slice_files(&self) -> (CompilationState, SliceOptions) {
250+
async fn compile_slice_files(&self) -> CompilationState {
262251
self.client
263252
.log_message(MessageType::INFO, "compiling slice")
264253
.await;
265254

266-
let references = self.slice_config.lock().await.resolve_reference_paths();
267-
268-
// If debug is enabled, log the resolved references
269-
#[cfg(debug_assertions)]
270-
self.client
271-
.log_message(MessageType::LOG, format!("references: {:?}", references))
272-
.await;
273-
274-
// Compile the Slice files
275-
let options = SliceOptions {
276-
references,
277-
..Default::default()
278-
};
279-
(
280-
slicec::compile_from_options(&options, |_| {}, |_| {}),
281-
options,
282-
)
255+
let config = self.slice_config.lock().await;
256+
slicec::compile_from_options(config.as_slice_options(), |_| {}, |_| {})
283257
}
284258

285-
async fn publish_diagnostics_for_all_files(&self, shared_state: &mut SharedState) {
286-
let compilation_options = &shared_state.compilation_options;
287-
let compilation_state = &mut shared_state.compilation_state;
259+
async fn publish_diagnostics_for_all_files(&self, compilation_state: &mut CompilationState) {
260+
let config = self.slice_config.lock().await;
288261

289262
let diagnostics = std::mem::take(&mut compilation_state.diagnostics).into_updated(
290263
&compilation_state.ast,
291264
&compilation_state.files,
292-
compilation_options,
265+
config.as_slice_options(),
293266
);
294267

295268
// Group the diagnostics by file since diagnostics are published per file and diagnostic.span contains the file URL

server/src/shared_state.rs

Lines changed: 0 additions & 18 deletions
This file was deleted.

0 commit comments

Comments
 (0)