Mountain/Environment/LanguageFeatureProvider/
FeatureMethods.rs

1//! All LSP feature method implementations.
2
3use std::sync::Arc;
4
5use CommonLibrary::{
6	Environment::Requires::Requires,
7	Error::CommonError::CommonError,
8	IPC::IPCProvider::IPCProvider,
9	LanguageFeature::DTO::{
10		CompletionContextDTO::CompletionContextDTO,
11		CompletionListDTO::CompletionListDTO,
12		HoverResultDTO::HoverResultDTO,
13		LocationDTO::LocationDTO,
14		PositionDTO::PositionDTO,
15		ProviderType::ProviderType,
16		TextEditDTO::TextEditDTO,
17	},
18};
19use log::warn;
20use serde_json::{Value, json};
21use url::Url;
22
23use crate::ApplicationState::DTO::ProviderRegistrationDTO::ProviderRegistrationDTO;
24
25// All feature methods delegate to generic invoke pattern
26
27pub(super) async fn provide_code_actions(
28	environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
29	document_uri:Url,
30	range_or_selection_dto:Value,
31	context_dto:Value,
32) -> Result<Option<Value>, CommonError> {
33	let provider =
34		super::ProviderLookup::get_matching_provider(environment, &document_uri, ProviderType::CodeAction).await?;
35	match provider {
36		Some(registration) => {
37			let response = invoke_provider(
38				environment,
39				&registration,
40				vec![
41					json!(registration.Handle),
42					json!({ "external": document_uri.to_string(), "$mid": 1 }),
43					range_or_selection_dto,
44					context_dto,
45				],
46			)
47			.await?;
48			if response.is_null() { Ok(None) } else { Ok(Some(response)) }
49		},
50		None => Ok(None),
51	}
52}
53
54pub(super) async fn provide_code_lenses(
55	environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
56	document_uri:Url,
57) -> Result<Option<Value>, CommonError> {
58	let provider =
59		super::ProviderLookup::get_matching_provider(environment, &document_uri, ProviderType::CodeLens).await?;
60	match provider {
61		Some(registration) => {
62			let response = invoke_provider(
63				environment,
64				&registration,
65				vec![
66					json!(registration.Handle),
67					json!({ "external": document_uri.to_string(), "$mid": 1 }),
68				],
69			)
70			.await?;
71			if response.is_null() { Ok(None) } else { Ok(Some(response)) }
72		},
73		None => Ok(None),
74	}
75}
76
77pub(super) async fn provide_completions(
78	environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
79	document_uri:Url,
80	position_dto:PositionDTO,
81	context_dto:CompletionContextDTO,
82	cancellation_token_value:Option<Value>,
83) -> Result<Option<CompletionListDTO>, CommonError> {
84	let provider =
85		super::ProviderLookup::get_matching_provider(environment, &document_uri, ProviderType::Completion).await?;
86	match provider {
87		Some(registration) => {
88			let response = invoke_provider(
89				environment,
90				&registration,
91				vec![
92					json!(registration.Handle),
93					json!({ "external": document_uri.to_string(), "$mid": 1 }),
94					json!(position_dto),
95					json!(context_dto),
96					cancellation_token_value.unwrap_or_else(|| json!(null)),
97				],
98			)
99			.await?;
100			if response.is_null() {
101				Ok(None)
102			} else {
103				serde_json::from_value(response).map_err(|error| {
104					CommonError::SerializationError {
105						Description:format!("Failed to deserialize CompletionListDTO: {}", error),
106					}
107				})
108			}
109		},
110		None => Ok(None),
111	}
112}
113
114pub(super) async fn provide_definition(
115	environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
116	document_uri:Url,
117	position_dto:PositionDTO,
118) -> Result<Option<Vec<LocationDTO>>, CommonError> {
119	let provider =
120		super::ProviderLookup::get_matching_provider(environment, &document_uri, ProviderType::Definition).await?;
121	match provider {
122		Some(registration) => {
123			let response = invoke_provider(
124				environment,
125				&registration,
126				vec![
127					json!(registration.Handle),
128					json!({ "external": document_uri.to_string(), "$mid": 1 }),
129					json!(position_dto),
130				],
131			)
132			.await?;
133			if response.is_null() {
134				Ok(None)
135			} else {
136				serde_json::from_value(response).map_err(|error| {
137					CommonError::SerializationError {
138						Description:format!("Failed to deserialize Vec<LocationDTO>: {}", error),
139					}
140				})
141			}
142		},
143		None => Ok(None),
144	}
145}
146
147pub(super) async fn provide_document_formatting_edits(
148	environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
149	document_uri:Url,
150	options_dto:Value,
151) -> Result<Option<Vec<TextEditDTO>>, CommonError> {
152	let provider =
153		super::ProviderLookup::get_matching_provider(environment, &document_uri, ProviderType::DocumentFormatting)
154			.await?;
155	match provider {
156		Some(registration) => {
157			let response = invoke_provider(
158				environment,
159				&registration,
160				vec![
161					json!(registration.Handle),
162					json!({ "external": document_uri.to_string(), "$mid": 1 }),
163					options_dto,
164				],
165			)
166			.await?;
167			if response.is_null() {
168				Ok(None)
169			} else {
170				serde_json::from_value(response).map_err(|error| {
171					CommonError::SerializationError {
172						Description:format!("Failed to deserialize Vec<TextEditDTO>: {}", error),
173					}
174				})
175			}
176		},
177		None => Ok(None),
178	}
179}
180
181pub(super) async fn provide_document_highlights(
182	environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
183	document_uri:Url,
184	position_dto:PositionDTO,
185) -> Result<Option<Value>, CommonError> {
186	let provider =
187		super::ProviderLookup::get_matching_provider(environment, &document_uri, ProviderType::DocumentHighlight)
188			.await?;
189	match provider {
190		Some(registration) => {
191			let response = invoke_provider(
192				environment,
193				&registration,
194				vec![
195					json!(registration.Handle),
196					json!({ "external": document_uri.to_string(), "$mid": 1 }),
197					json!(position_dto),
198				],
199			)
200			.await?;
201			if response.is_null() { Ok(None) } else { Ok(Some(response)) }
202		},
203		None => Ok(None),
204	}
205}
206
207pub(super) async fn provide_document_links(
208	environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
209	document_uri:Url,
210) -> Result<Option<Value>, CommonError> {
211	let provider =
212		super::ProviderLookup::get_matching_provider(environment, &document_uri, ProviderType::DocumentLink).await?;
213	match provider {
214		Some(registration) => {
215			let response = invoke_provider(
216				environment,
217				&registration,
218				vec![
219					json!(registration.Handle),
220					json!({ "external": document_uri.to_string(), "$mid": 1 }),
221				],
222			)
223			.await?;
224			if response.is_null() { Ok(None) } else { Ok(Some(response)) }
225		},
226		None => Ok(None),
227	}
228}
229
230pub(super) async fn provide_document_range_formatting_edits(
231	environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
232	document_uri:Url,
233	range_dto:Value,
234	options_dto:Value,
235) -> Result<Option<Vec<TextEditDTO>>, CommonError> {
236	let provider =
237		super::ProviderLookup::get_matching_provider(environment, &document_uri, ProviderType::DocumentRangeFormatting)
238			.await?;
239	match provider {
240		Some(registration) => {
241			let response = invoke_provider(
242				environment,
243				&registration,
244				vec![
245					json!(registration.Handle),
246					json!({ "external": document_uri.to_string(), "$mid": 1 }),
247					range_dto,
248					options_dto,
249				],
250			)
251			.await?;
252			if response.is_null() {
253				Ok(None)
254			} else {
255				serde_json::from_value(response).map_err(|error| {
256					CommonError::SerializationError {
257						Description:format!("Failed to deserialize Vec<TextEditDTO>: {}", error),
258					}
259				})
260			}
261		},
262		None => Ok(None),
263	}
264}
265
266pub(super) async fn provide_hover(
267	environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
268	document_uri:Url,
269	position_dto:PositionDTO,
270) -> Result<Option<HoverResultDTO>, CommonError> {
271	let provider =
272		super::ProviderLookup::get_matching_provider(environment, &document_uri, ProviderType::Hover).await?;
273	match provider {
274		Some(registration) => {
275			let response = invoke_provider(
276				environment,
277				&registration,
278				vec![
279					json!(registration.Handle),
280					json!({ "external": document_uri.to_string(), "$mid": 1 }),
281					json!(position_dto),
282				],
283			)
284			.await?;
285			if response.is_null() {
286				Ok(None)
287			} else {
288				serde_json::from_value(response).map_err(|error| {
289					CommonError::SerializationError {
290						Description:format!("Failed to deserialize HoverResultDTO: {}", error),
291					}
292				})
293			}
294		},
295		None => Ok(None),
296	}
297}
298
299pub(super) async fn provide_references(
300	environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
301	document_uri:Url,
302	position_dto:PositionDTO,
303	context_dto:Value,
304) -> Result<Option<Vec<LocationDTO>>, CommonError> {
305	let provider =
306		super::ProviderLookup::get_matching_provider(environment, &document_uri, ProviderType::References).await?;
307	match provider {
308		Some(registration) => {
309			let response = invoke_provider(
310				environment,
311				&registration,
312				vec![
313					json!(registration.Handle),
314					json!({ "external": document_uri.to_string(), "$mid": 1 }),
315					json!(position_dto),
316					context_dto,
317				],
318			)
319			.await?;
320			if response.is_null() {
321				Ok(None)
322			} else {
323				serde_json::from_value(response).map_err(|error| {
324					CommonError::SerializationError {
325						Description:format!("Failed to deserialize Vec<LocationDTO>: {}", error),
326					}
327				})
328			}
329		},
330		None => Ok(None),
331	}
332}
333
334pub(super) async fn prepare_rename(
335	environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
336	document_uri:Url,
337	position_dto:PositionDTO,
338) -> Result<Option<Value>, CommonError> {
339	let provider =
340		super::ProviderLookup::get_matching_provider(environment, &document_uri, ProviderType::Rename).await?;
341	match provider {
342		Some(registration) => {
343			let response = invoke_provider(
344				environment,
345				&registration,
346				vec![
347					json!(registration.Handle),
348					json!({ "external": document_uri.to_string(), "$mid": 1 }),
349					json!(position_dto),
350				],
351			)
352			.await?;
353			if response.is_null() { Ok(None) } else { Ok(Some(response)) }
354		},
355		None => Ok(None),
356	}
357}
358
359async fn invoke_provider(
360	environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
361	registration:&ProviderRegistrationDTO,
362	arguments:Vec<Value>,
363) -> Result<Value, CommonError> {
364	let rpc_method = format!("$provide{}", registration.ProviderType.to_string());
365	let ipc_provider:Arc<dyn IPCProvider> = environment.Require();
366	ipc_provider
367		.SendRequestToSideCar(registration.SideCarIdentifier.clone(), rpc_method, json!(arguments), 5000)
368		.await
369}