0
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-10-29 08:58:01 -04:00

reafactor(lsp): use generics with JSON values (#9587)

This commit is contained in:
Kitson Kelly 2021-02-25 14:15:55 +11:00 committed by GitHub
parent ae8874b4b2
commit 90e4c5dcde
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 189 additions and 196 deletions

View file

@ -227,14 +227,13 @@ impl Inner {
self.performance.measure(mark); self.performance.measure(mark);
Ok(navigation_tree.clone()) Ok(navigation_tree.clone())
} else { } else {
let res = self let navigation_tree: tsc::NavigationTree = self
.ts_server .ts_server
.request( .request(
self.snapshot(), self.snapshot(),
tsc::RequestMethod::GetNavigationTree(specifier.clone()), tsc::RequestMethod::GetNavigationTree(specifier.clone()),
) )
.await?; .await?;
let navigation_tree: tsc::NavigationTree = serde_json::from_value(res)?;
self self
.navigation_trees .navigation_trees
.insert(specifier.clone(), navigation_tree.clone()); .insert(specifier.clone(), navigation_tree.clone());
@ -512,7 +511,7 @@ impl Inner {
warn!("{}", ignored_options); warn!("{}", ignored_options);
} }
} }
self let _ok: bool = self
.ts_server .ts_server
.request(self.snapshot(), tsc::RequestMethod::Configure(tsconfig)) .request(self.snapshot(), tsc::RequestMethod::Configure(tsconfig))
.await?; .await?;
@ -588,7 +587,7 @@ impl Inner {
} }
if capabilities.code_action_provider.is_some() { if capabilities.code_action_provider.is_some() {
let res = self let fixable_diagnostics: Vec<String> = self
.ts_server .ts_server
.request(self.snapshot(), tsc::RequestMethod::GetSupportedCodeFixes) .request(self.snapshot(), tsc::RequestMethod::GetSupportedCodeFixes)
.await .await
@ -596,11 +595,6 @@ impl Inner {
error!("Unable to get fixable diagnostics: {}", err); error!("Unable to get fixable diagnostics: {}", err);
LspError::internal_error() LspError::internal_error()
})?; })?;
let fixable_diagnostics: Vec<String> =
from_value(res).map_err(|err| {
error!("Unable to get fixable diagnostics: {}", err);
LspError::internal_error()
})?;
self.ts_fixable_diagnostics = fixable_diagnostics; self.ts_fixable_diagnostics = fixable_diagnostics;
} }
@ -877,11 +871,14 @@ impl Inner {
specifier, specifier,
line_index.offset_tsc(params.text_document_position_params.position)?, line_index.offset_tsc(params.text_document_position_params.position)?,
)); ));
// TODO(lucacasonato): handle error correctly let maybe_quick_info: Option<tsc::QuickInfo> = self
let res = self.ts_server.request(self.snapshot(), req).await.unwrap(); .ts_server
// TODO(lucacasonato): handle error correctly .request(self.snapshot(), req)
let maybe_quick_info: Option<tsc::QuickInfo> = .await
serde_json::from_value(res).unwrap(); .map_err(|err| {
error!("Unable to get quick info: {}", err);
LspError::internal_error()
})?;
if let Some(quick_info) = maybe_quick_info { if let Some(quick_info) = maybe_quick_info {
let hover = quick_info.to_hover(&line_index); let hover = quick_info.to_hover(&line_index);
self.performance.measure(mark); self.performance.measure(mark);
@ -953,18 +950,13 @@ impl Inner {
line_index.offset_tsc(diagnostic.range.end)?, line_index.offset_tsc(diagnostic.range.end)?,
codes, codes,
)); ));
let res = let actions: Vec<tsc::CodeFixAction> =
self.ts_server.request(self.snapshot(), req).await.map_err( self.ts_server.request(self.snapshot(), req).await.map_err(
|err| { |err| {
error!("Error getting actions from TypeScript: {}", err); error!("Error getting actions from TypeScript: {}", err);
LspError::internal_error() LspError::internal_error()
}, },
)?; )?;
let actions: Vec<tsc::CodeFixAction> =
from_value(res).map_err(|err| {
error!("Cannot decode actions from TypeScript: {}", err);
LspError::internal_error()
})?;
for action in actions { for action in actions {
code_actions code_actions
.add_ts_fix_action(&action, diagnostic, self) .add_ts_fix_action(&action, diagnostic, self)
@ -1005,46 +997,42 @@ impl Inner {
params: CodeAction, params: CodeAction,
) -> LspResult<CodeAction> { ) -> LspResult<CodeAction> {
let mark = self.performance.mark("code_action_resolve"); let mark = self.performance.mark("code_action_resolve");
let result = let result = if let Some(data) = params.data.clone() {
if let Some(data) = params.data.clone() { let code_action_data: CodeActionData =
let code_action_data: CodeActionData = from_value(data).map_err(|err| {
from_value(data).map_err(|err| { error!("Unable to decode code action data: {}", err);
error!("Unable to decode code action data: {}", err); LspError::invalid_params("The CodeAction's data is invalid.")
LspError::invalid_params("The CodeAction's data is invalid.") })?;
})?; let req = tsc::RequestMethod::GetCombinedCodeFix((
let req = tsc::RequestMethod::GetCombinedCodeFix(( code_action_data.specifier,
code_action_data.specifier, json!(code_action_data.fix_id.clone()),
json!(code_action_data.fix_id.clone()), ));
)); let combined_code_actions: tsc::CombinedCodeActions = self
let res = self.ts_server.request(self.snapshot(), req).await.map_err( .ts_server
|err| { .request(self.snapshot(), req)
error!("Unable to get combined fix from TypeScript: {}", err); .await
LspError::internal_error() .map_err(|err| {
}, error!("Unable to get combined fix from TypeScript: {}", err);
)?; LspError::internal_error()
let combined_code_actions: tsc::CombinedCodeActions = })?;
from_value(res).map_err(|err| { if combined_code_actions.commands.is_some() {
error!("Cannot decode combined actions from TypeScript: {}", err); error!("Deno does not support code actions with commands.");
LspError::internal_error() Err(LspError::invalid_request())
})?;
if combined_code_actions.commands.is_some() {
error!("Deno does not support code actions with commands.");
Err(LspError::invalid_request())
} else {
let mut code_action = params.clone();
code_action.edit =
ts_changes_to_edit(&combined_code_actions.changes, self)
.await
.map_err(|err| {
error!("Unable to convert changes to edits: {}", err);
LspError::internal_error()
})?;
Ok(code_action)
}
} else { } else {
// The code action doesn't need to be resolved let mut code_action = params.clone();
Ok(params) code_action.edit =
}; ts_changes_to_edit(&combined_code_actions.changes, self)
.await
.map_err(|err| {
error!("Unable to convert changes to edits: {}", err);
LspError::internal_error()
})?;
Ok(code_action)
}
} else {
// The code action doesn't need to be resolved
Ok(params)
};
self.performance.measure(mark); self.performance.measure(mark);
result result
} }
@ -1191,18 +1179,13 @@ impl Inner {
code_lens_data.specifier.clone(), code_lens_data.specifier.clone(),
line_index.offset_tsc(params.range.start)?, line_index.offset_tsc(params.range.start)?,
)); ));
let res = let maybe_implementations: Option<Vec<tsc::ImplementationLocation>> =
self.ts_server.request(self.snapshot(), req).await.map_err( self.ts_server.request(self.snapshot(), req).await.map_err(
|err| { |err| {
error!("Error processing TypeScript request: {}", err); error!("Error processing TypeScript request: {}", err);
LspError::internal_error() LspError::internal_error()
}, },
)?; )?;
let maybe_implementations: Option<Vec<tsc::ImplementationLocation>> =
serde_json::from_value(res).map_err(|err| {
error!("Error deserializing response: {}", err);
LspError::internal_error()
})?;
if let Some(implementations) = maybe_implementations { if let Some(implementations) = maybe_implementations {
let mut locations = Vec::new(); let mut locations = Vec::new();
for implementation in implementations { for implementation in implementations {
@ -1275,18 +1258,13 @@ impl Inner {
code_lens_data.specifier.clone(), code_lens_data.specifier.clone(),
line_index.offset_tsc(params.range.start)?, line_index.offset_tsc(params.range.start)?,
)); ));
let res = let maybe_references: Option<Vec<tsc::ReferenceEntry>> =
self.ts_server.request(self.snapshot(), req).await.map_err( self.ts_server.request(self.snapshot(), req).await.map_err(
|err| { |err| {
error!("Error processing TypeScript request: {}", err); error!("Error processing TypeScript request: {}", err);
LspError::internal_error() LspError::internal_error()
}, },
)?; )?;
let maybe_references: Option<Vec<tsc::ReferenceEntry>> =
serde_json::from_value(res).map_err(|err| {
error!("Error deserializing response: {}", err);
LspError::internal_error()
})?;
if let Some(references) = maybe_references { if let Some(references) = maybe_references {
let mut locations = Vec::new(); let mut locations = Vec::new();
for reference in references { for reference in references {
@ -1393,11 +1371,14 @@ impl Inner {
line_index.offset_tsc(params.text_document_position_params.position)?, line_index.offset_tsc(params.text_document_position_params.position)?,
files_to_search, files_to_search,
)); ));
// TODO(lucacasonato): handle error correctly let maybe_document_highlights: Option<Vec<tsc::DocumentHighlights>> = self
let res = self.ts_server.request(self.snapshot(), req).await.unwrap(); .ts_server
// TODO(lucacasonato): handle error correctly .request(self.snapshot(), req)
let maybe_document_highlights: Option<Vec<tsc::DocumentHighlights>> = .await
serde_json::from_value(res).unwrap(); .map_err(|err| {
error!("Unable to get document highlights from TypeScript: {}", err);
LspError::internal_error()
})?;
if let Some(document_highlights) = maybe_document_highlights { if let Some(document_highlights) = maybe_document_highlights {
let result = document_highlights let result = document_highlights
@ -1437,11 +1418,14 @@ impl Inner {
specifier, specifier,
line_index.offset_tsc(params.text_document_position.position)?, line_index.offset_tsc(params.text_document_position.position)?,
)); ));
// TODO(lucacasonato): handle error correctly let maybe_references: Option<Vec<tsc::ReferenceEntry>> = self
let res = self.ts_server.request(self.snapshot(), req).await.unwrap(); .ts_server
// TODO(lucacasonato): handle error correctly .request(self.snapshot(), req)
let maybe_references: Option<Vec<tsc::ReferenceEntry>> = .await
serde_json::from_value(res).unwrap(); .map_err(|err| {
error!("Unable to get references from TypeScript: {}", err);
LspError::internal_error()
})?;
if let Some(references) = maybe_references { if let Some(references) = maybe_references {
let mut results = Vec::new(); let mut results = Vec::new();
@ -1489,11 +1473,14 @@ impl Inner {
specifier, specifier,
line_index.offset_tsc(params.text_document_position_params.position)?, line_index.offset_tsc(params.text_document_position_params.position)?,
)); ));
// TODO(lucacasonato): handle error correctly let maybe_definition: Option<tsc::DefinitionInfoAndBoundSpan> = self
let res = self.ts_server.request(self.snapshot(), req).await.unwrap(); .ts_server
// TODO(lucacasonato): handle error correctly .request(self.snapshot(), req)
let maybe_definition: Option<tsc::DefinitionInfoAndBoundSpan> = .await
serde_json::from_value(res).unwrap(); .map_err(|err| {
error!("Unable to get definition from TypeScript: {}", err);
LspError::internal_error()
})?;
if let Some(definition) = maybe_definition { if let Some(definition) = maybe_definition {
let results = definition.to_definition(&line_index, self).await; let results = definition.to_definition(&line_index, self).await;
@ -1535,11 +1522,14 @@ impl Inner {
..Default::default() ..Default::default()
}, },
)); ));
// TODO(lucacasonato): handle error correctly let maybe_completion_info: Option<tsc::CompletionInfo> = self
let res = self.ts_server.request(self.snapshot(), req).await.unwrap(); .ts_server
// TODO(lucacasonato): handle error correctly .request(self.snapshot(), req)
let maybe_completion_info: Option<tsc::CompletionInfo> = .await
serde_json::from_value(res).unwrap(); .map_err(|err| {
error!("Unable to get completion info from TypeScript: {}", err);
LspError::internal_error()
})?;
if let Some(completions) = maybe_completion_info { if let Some(completions) = maybe_completion_info {
let results = completions.into_completion_response(&line_index); let results = completions.into_completion_response(&line_index);
@ -1576,20 +1566,13 @@ impl Inner {
specifier, specifier,
line_index.offset_tsc(params.text_document_position_params.position)?, line_index.offset_tsc(params.text_document_position_params.position)?,
)); ));
let res = let maybe_implementations: Option<Vec<tsc::ImplementationLocation>> = self
self .ts_server
.ts_server .request(self.snapshot(), req)
.request(self.snapshot(), req) .await
.await
.map_err(|err| {
error!("Failed to request to tsserver {}", err);
LspError::invalid_request()
})?;
let maybe_implementations: Option<Vec<tsc::ImplementationLocation>> = serde_json::from_value(res)
.map_err(|err| { .map_err(|err| {
error!("Failed to deserialized tsserver response to Vec<ImplementationLocation> {}", err); error!("Failed to request to tsserver {}", err);
LspError::internal_error() LspError::invalid_request()
})?; })?;
let result = if let Some(implementations) = maybe_implementations { let result = if let Some(implementations) = maybe_implementations {
@ -1638,26 +1621,14 @@ impl Inner {
false, false,
)); ));
let res = let maybe_locations: Option<Vec<tsc::RenameLocation>> = self
self .ts_server
.ts_server .request(self.snapshot(), req)
.request(self.snapshot(), req) .await
.await .map_err(|err| {
.map_err(|err| { error!("Failed to request to tsserver {}", err);
error!("Failed to request to tsserver {}", err); LspError::invalid_request()
LspError::invalid_request() })?;
})?;
let maybe_locations = serde_json::from_value::<
Option<Vec<tsc::RenameLocation>>,
>(res)
.map_err(|err| {
error!(
"Failed to deserialize tsserver response to Vec<RenameLocation> {}",
err
);
LspError::internal_error()
})?;
if let Some(locations) = maybe_locations { if let Some(locations) = maybe_locations {
let rename_locations = tsc::RenameLocations { locations }; let rename_locations = tsc::RenameLocations { locations };
@ -1751,19 +1722,13 @@ impl Inner {
line_index.offset_tsc(params.text_document_position_params.position)?, line_index.offset_tsc(params.text_document_position_params.position)?,
options, options,
)); ));
let res = let maybe_signature_help_items: Option<tsc::SignatureHelpItems> = self
self .ts_server
.ts_server .request(self.snapshot(), req)
.request(self.snapshot(), req) .await
.await .map_err(|err| {
.map_err(|err| { error!("Failed to request to tsserver: {}", err);
error!("Failed to request to tsserver: {}", err); LspError::invalid_request()
LspError::invalid_request()
})?;
let maybe_signature_help_items: Option<tsc::SignatureHelpItems> =
serde_json::from_value(res).map_err(|err| {
error!("Failed to deserialize tsserver response: {}", err);
LspError::internal_error()
})?; })?;
if let Some(signature_help_items) = maybe_signature_help_items { if let Some(signature_help_items) = maybe_signature_help_items {

View file

@ -19,6 +19,7 @@ use deno_core::error::custom_error;
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_core::json_op_sync; use deno_core::json_op_sync;
use deno_core::resolve_url; use deno_core::resolve_url;
use deno_core::serde::de;
use deno_core::serde::Deserialize; use deno_core::serde::Deserialize;
use deno_core::serde::Serialize; use deno_core::serde::Serialize;
use deno_core::serde_json; use deno_core::serde_json;
@ -71,16 +72,19 @@ impl TsServer {
Self(tx) Self(tx)
} }
pub async fn request( pub async fn request<R>(
&self, &self,
snapshot: StateSnapshot, snapshot: StateSnapshot,
req: RequestMethod, req: RequestMethod,
) -> Result<Value, AnyError> { ) -> Result<R, AnyError>
where
R: de::DeserializeOwned,
{
let (tx, rx) = oneshot::channel::<Result<Value, AnyError>>(); let (tx, rx) = oneshot::channel::<Result<Value, AnyError>>();
if self.0.send((req, snapshot, tx)).is_err() { if self.0.send((req, snapshot, tx)).is_err() {
return Err(anyhow!("failed to send request to tsc thread")); return Err(anyhow!("failed to send request to tsc thread"));
} }
rx.await? rx.await?.map(|v| serde_json::from_value::<R>(v).unwrap())
} }
} }
@ -1104,9 +1108,11 @@ fn cache_snapshot(
Ok(()) Ok(())
} }
fn op<F>(op_fn: F) -> Box<OpFn> fn op<F, V, R>(op_fn: F) -> Box<OpFn>
where where
F: Fn(&mut State, Value) -> Result<Value, AnyError> + 'static, F: Fn(&mut State, V) -> Result<R, AnyError> + 'static,
V: de::DeserializeOwned,
R: Serialize,
{ {
json_op_sync(move |s, args, _bufs| { json_op_sync(move |s, args, _bufs| {
let state = s.borrow_mut::<State>(); let state = s.borrow_mut::<State>();
@ -1123,14 +1129,17 @@ struct SourceSnapshotArgs {
/// The language service is dropping a reference to a source file snapshot, and /// The language service is dropping a reference to a source file snapshot, and
/// we can drop our version of that document. /// we can drop our version of that document.
fn dispose(state: &mut State, args: Value) -> Result<Value, AnyError> { #[allow(clippy::unnecessary_wraps)]
fn dispose(
state: &mut State,
args: SourceSnapshotArgs,
) -> Result<bool, AnyError> {
let mark = state.state_snapshot.performance.mark("op_dispose"); let mark = state.state_snapshot.performance.mark("op_dispose");
let v: SourceSnapshotArgs = serde_json::from_value(args)?;
state state
.snapshots .snapshots
.remove(&(v.specifier.into(), v.version.into())); .remove(&(args.specifier.into(), args.version.into()));
state.state_snapshot.performance.measure(mark); state.state_snapshot.performance.measure(mark);
Ok(json!(true)) Ok(true)
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
@ -1144,18 +1153,20 @@ struct GetChangeRangeArgs {
/// The language service wants to compare an old snapshot with a new snapshot to /// The language service wants to compare an old snapshot with a new snapshot to
/// determine what source hash changed. /// determine what source hash changed.
fn get_change_range(state: &mut State, args: Value) -> Result<Value, AnyError> { fn get_change_range(
state: &mut State,
args: GetChangeRangeArgs,
) -> Result<Value, AnyError> {
let mark = state.state_snapshot.performance.mark("op_get_change_range"); let mark = state.state_snapshot.performance.mark("op_get_change_range");
let v: GetChangeRangeArgs = serde_json::from_value(args.clone())?; cache_snapshot(state, args.specifier.clone(), args.version.clone())?;
cache_snapshot(state, v.specifier.clone(), v.version.clone())?;
if let Some(current) = state if let Some(current) = state
.snapshots .snapshots
.get(&(v.specifier.clone().into(), v.version.into())) .get(&(args.specifier.clone().into(), args.version.clone().into()))
{ {
if let Some(prev) = state if let Some(prev) = state.snapshots.get(&(
.snapshots args.specifier.clone().into(),
.get(&(v.specifier.clone().into(), v.old_version.clone().into())) args.old_version.clone().into(),
{ )) {
state.state_snapshot.performance.measure(mark); state.state_snapshot.performance.measure(mark);
Ok(text::get_range_change(prev, current)) Ok(text::get_range_change(prev, current))
} else { } else {
@ -1168,7 +1179,7 @@ fn get_change_range(state: &mut State, args: Value) -> Result<Value, AnyError> {
Ok(json!({ Ok(json!({
"span": { "span": {
"start": 0, "start": 0,
"length": v.old_length, "length": args.old_length,
}, },
"newLength": new_length, "newLength": new_length,
})) }))
@ -1178,31 +1189,33 @@ fn get_change_range(state: &mut State, args: Value) -> Result<Value, AnyError> {
Err(custom_error( Err(custom_error(
"MissingSnapshot", "MissingSnapshot",
format!( format!(
"The current snapshot version is missing.\n Args: \"{}\"", "The current snapshot version is missing.\n Args: \"{:?}\"",
args args
), ),
)) ))
} }
} }
fn get_length(state: &mut State, args: Value) -> Result<Value, AnyError> { fn get_length(
state: &mut State,
args: SourceSnapshotArgs,
) -> Result<usize, AnyError> {
let mark = state.state_snapshot.performance.mark("op_get_length"); let mark = state.state_snapshot.performance.mark("op_get_length");
let v: SourceSnapshotArgs = serde_json::from_value(args)?; let specifier = resolve_url(&args.specifier)?;
let specifier = resolve_url(&v.specifier)?;
if let Some(Some(asset)) = state.state_snapshot.assets.get(&specifier) { if let Some(Some(asset)) = state.state_snapshot.assets.get(&specifier) {
Ok(json!(asset.length)) Ok(asset.length)
} else if state.state_snapshot.documents.contains_key(&specifier) { } else if state.state_snapshot.documents.contains_key(&specifier) {
cache_snapshot(state, v.specifier.clone(), v.version.clone())?; cache_snapshot(state, args.specifier.clone(), args.version.clone())?;
let content = state let content = state
.snapshots .snapshots
.get(&(v.specifier.into(), v.version.into())) .get(&(args.specifier.into(), args.version.into()))
.unwrap(); .unwrap();
state.state_snapshot.performance.measure(mark); state.state_snapshot.performance.measure(mark);
Ok(json!(content.encode_utf16().count())) Ok(content.encode_utf16().count())
} else { } else {
let sources = &mut state.state_snapshot.sources; let sources = &mut state.state_snapshot.sources;
state.state_snapshot.performance.measure(mark); state.state_snapshot.performance.measure(mark);
Ok(json!(sources.get_length_utf16(&specifier).unwrap())) Ok(sources.get_length_utf16(&specifier).unwrap())
} }
} }
@ -1215,39 +1228,40 @@ struct GetTextArgs {
end: usize, end: usize,
} }
fn get_text(state: &mut State, args: Value) -> Result<Value, AnyError> { fn get_text(state: &mut State, args: GetTextArgs) -> Result<String, AnyError> {
let mark = state.state_snapshot.performance.mark("op_get_text"); let mark = state.state_snapshot.performance.mark("op_get_text");
let v: GetTextArgs = serde_json::from_value(args)?; let specifier = resolve_url(&args.specifier)?;
let specifier = resolve_url(&v.specifier)?;
let content = let content =
if let Some(Some(content)) = state.state_snapshot.assets.get(&specifier) { if let Some(Some(content)) = state.state_snapshot.assets.get(&specifier) {
content.text.clone() content.text.clone()
} else if state.state_snapshot.documents.contains_key(&specifier) { } else if state.state_snapshot.documents.contains_key(&specifier) {
cache_snapshot(state, v.specifier.clone(), v.version.clone())?; cache_snapshot(state, args.specifier.clone(), args.version.clone())?;
state state
.snapshots .snapshots
.get(&(v.specifier.into(), v.version.into())) .get(&(args.specifier.into(), args.version.into()))
.unwrap() .unwrap()
.clone() .clone()
} else { } else {
state.state_snapshot.sources.get_source(&specifier).unwrap() state.state_snapshot.sources.get_source(&specifier).unwrap()
}; };
state.state_snapshot.performance.measure(mark); state.state_snapshot.performance.measure(mark);
Ok(json!(text::slice(&content, v.start..v.end))) Ok(text::slice(&content, args.start..args.end).to_string())
} }
fn resolve(state: &mut State, args: Value) -> Result<Value, AnyError> { fn resolve(
state: &mut State,
args: ResolveArgs,
) -> Result<Vec<Option<(String, String)>>, AnyError> {
let mark = state.state_snapshot.performance.mark("op_resolve"); let mark = state.state_snapshot.performance.mark("op_resolve");
let v: ResolveArgs = serde_json::from_value(args)?; let mut resolved = Vec::new();
let mut resolved = Vec::<Option<(String, String)>>::new(); let referrer = resolve_url(&args.base)?;
let referrer = resolve_url(&v.base)?;
let sources = &mut state.state_snapshot.sources; let sources = &mut state.state_snapshot.sources;
if state.state_snapshot.documents.contains_key(&referrer) { if state.state_snapshot.documents.contains_key(&referrer) {
if let Some(dependencies) = if let Some(dependencies) =
state.state_snapshot.documents.dependencies(&referrer) state.state_snapshot.documents.dependencies(&referrer)
{ {
for specifier in &v.specifiers { for specifier in &args.specifiers {
if specifier.starts_with("asset:///") { if specifier.starts_with("asset:///") {
resolved.push(Some(( resolved.push(Some((
specifier.clone(), specifier.clone(),
@ -1297,7 +1311,7 @@ fn resolve(state: &mut State, args: Value) -> Result<Value, AnyError> {
} }
} }
} else if sources.contains_key(&referrer) { } else if sources.contains_key(&referrer) {
for specifier in &v.specifiers { for specifier in &args.specifiers {
if let Some((resolved_specifier, media_type)) = if let Some((resolved_specifier, media_type)) =
sources.resolve_import(specifier, &referrer) sources.resolve_import(specifier, &referrer)
{ {
@ -1321,17 +1335,29 @@ fn resolve(state: &mut State, args: Value) -> Result<Value, AnyError> {
} }
state.state_snapshot.performance.measure(mark); state.state_snapshot.performance.measure(mark);
Ok(json!(resolved)) Ok(resolved)
}
fn respond(state: &mut State, args: Value) -> Result<Value, AnyError> {
state.response = Some(serde_json::from_value(args)?);
Ok(json!(true))
} }
#[allow(clippy::unnecessary_wraps)] #[allow(clippy::unnecessary_wraps)]
fn script_names(state: &mut State, _args: Value) -> Result<Value, AnyError> { fn respond(state: &mut State, args: Response) -> Result<bool, AnyError> {
Ok(json!(state.state_snapshot.documents.open_specifiers())) state.response = Some(args);
Ok(true)
}
#[allow(clippy::unnecessary_wraps)]
fn script_names(
state: &mut State,
_args: Value,
) -> Result<Vec<ModuleSpecifier>, AnyError> {
Ok(
state
.state_snapshot
.documents
.open_specifiers()
.into_iter()
.cloned()
.collect(),
)
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
@ -1340,29 +1366,31 @@ struct ScriptVersionArgs {
specifier: String, specifier: String,
} }
fn script_version(state: &mut State, args: Value) -> Result<Value, AnyError> { fn script_version(
state: &mut State,
args: ScriptVersionArgs,
) -> Result<Option<String>, AnyError> {
let mark = state.state_snapshot.performance.mark("op_script_version"); let mark = state.state_snapshot.performance.mark("op_script_version");
let v: ScriptVersionArgs = serde_json::from_value(args)?; let specifier = resolve_url(&args.specifier)?;
let specifier = resolve_url(&v.specifier)?;
if specifier.scheme() == "asset" { if specifier.scheme() == "asset" {
return if state.state_snapshot.assets.contains_key(&specifier) { return if state.state_snapshot.assets.contains_key(&specifier) {
Ok(json!("1")) Ok(Some("1".to_string()))
} else { } else {
Ok(json!(null)) Ok(None)
}; };
} else if let Some(version) = } else if let Some(version) =
state.state_snapshot.documents.version(&specifier) state.state_snapshot.documents.version(&specifier)
{ {
return Ok(json!(version.to_string())); return Ok(Some(version.to_string()));
} else { } else {
let sources = &mut state.state_snapshot.sources; let sources = &mut state.state_snapshot.sources;
if let Some(version) = sources.get_script_version(&specifier) { if let Some(version) = sources.get_script_version(&specifier) {
return Ok(json!(version)); return Ok(Some(version));
} }
} }
state.state_snapshot.performance.measure(mark); state.state_snapshot.performance.measure(mark);
Ok(json!(null)) Ok(None)
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
@ -1371,10 +1399,10 @@ struct SetAssetArgs {
text: Option<String>, text: Option<String>,
} }
fn set_asset(state: &mut State, args: Value) -> Result<Value, AnyError> { #[allow(clippy::unnecessary_wraps)]
let v: SetAssetArgs = serde_json::from_value(args)?; fn set_asset(state: &mut State, args: SetAssetArgs) -> Result<bool, AnyError> {
state.asset = v.text; state.asset = args.text;
Ok(json!(true)) Ok(true)
} }
/// Create and setup a JsRuntime based on a snapshot. It is expected that the /// Create and setup a JsRuntime based on a snapshot. It is expected that the