refactor(lsp): use fallback resolution in op_resolve() (#23329)

This commit is contained in:
Nayeem Rahman 2024-04-14 22:42:58 +01:00 committed by GitHub
parent e277490c82
commit 8f1a92f3c3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 42 additions and 47 deletions

View file

@ -1173,15 +1173,11 @@ impl Documents {
/// tsc when type checking. /// tsc when type checking.
pub fn resolve( pub fn resolve(
&self, &self,
specifiers: Vec<String>, specifiers: &[String],
referrer_doc: &AssetOrDocument, referrer: &ModuleSpecifier,
maybe_npm: Option<&StateNpmSnapshot>, maybe_npm: Option<&StateNpmSnapshot>,
) -> Vec<Option<(ModuleSpecifier, MediaType)>> { ) -> Vec<Option<(ModuleSpecifier, MediaType)>> {
let referrer = referrer_doc.specifier(); let dependencies = self.get(referrer).map(|d| d.dependencies.clone());
let dependencies = match referrer_doc {
AssetOrDocument::Asset(_) => None,
AssetOrDocument::Document(doc) => Some(doc.dependencies.clone()),
};
let mut results = Vec::new(); let mut results = Vec::new();
for specifier in specifiers { for specifier in specifiers {
if let Some(npm) = maybe_npm { if let Some(npm) = maybe_npm {
@ -1191,7 +1187,7 @@ impl Documents {
npm npm
.node_resolver .node_resolver
.resolve( .resolve(
&specifier, specifier,
referrer, referrer,
NodeResolutionMode::Types, NodeResolutionMode::Types,
&PermissionsContainer::allow_all(), &PermissionsContainer::allow_all(),
@ -1203,14 +1199,14 @@ impl Documents {
} }
} }
if specifier.starts_with("asset:") { if specifier.starts_with("asset:") {
if let Ok(specifier) = ModuleSpecifier::parse(&specifier) { if let Ok(specifier) = ModuleSpecifier::parse(specifier) {
let media_type = MediaType::from_specifier(&specifier); let media_type = MediaType::from_specifier(&specifier);
results.push(Some((specifier, media_type))); results.push(Some((specifier, media_type)));
} else { } else {
results.push(None); results.push(None);
} }
} else if let Some(dep) = } else if let Some(dep) =
dependencies.as_ref().and_then(|d| d.deps.get(&specifier)) dependencies.as_ref().and_then(|d| d.deps.get(specifier))
{ {
if let Some(specifier) = dep.maybe_type.maybe_specifier() { if let Some(specifier) = dep.maybe_type.maybe_specifier() {
results.push(self.resolve_dependency(specifier, maybe_npm, referrer)); results.push(self.resolve_dependency(specifier, maybe_npm, referrer));
@ -1220,18 +1216,28 @@ impl Documents {
results.push(None); results.push(None);
} }
} else if let Some(specifier) = self } else if let Some(specifier) = self
.resolve_imports_dependency(&specifier) .resolve_imports_dependency(specifier)
.and_then(|r| r.maybe_specifier()) .and_then(|r| r.maybe_specifier())
{ {
results.push(self.resolve_dependency(specifier, maybe_npm, referrer)); results.push(self.resolve_dependency(specifier, maybe_npm, referrer));
} else if let Ok(npm_req_ref) = } else if let Ok(npm_req_ref) =
NpmPackageReqReference::from_str(&specifier) NpmPackageReqReference::from_str(specifier)
{ {
results.push(node_resolve_npm_req_ref( results.push(node_resolve_npm_req_ref(
&npm_req_ref, &npm_req_ref,
maybe_npm, maybe_npm,
referrer, referrer,
)); ));
} else if let Ok(specifier) = self.get_resolver().resolve(
specifier,
&deno_graph::Range {
specifier: referrer.clone(),
start: deno_graph::Position::zeroed(),
end: deno_graph::Position::zeroed(),
},
ResolutionMode::Types,
) {
results.push(self.resolve_dependency(&specifier, maybe_npm, referrer));
} else { } else {
results.push(None); results.push(None);
} }
@ -1495,7 +1501,9 @@ impl Documents {
if let Ok(npm_ref) = NpmPackageReqReference::from_specifier(specifier) { if let Ok(npm_ref) = NpmPackageReqReference::from_specifier(specifier) {
return node_resolve_npm_req_ref(&npm_ref, maybe_npm, referrer); return node_resolve_npm_req_ref(&npm_ref, maybe_npm, referrer);
} }
let doc = self.get(specifier)?; let Some(doc) = self.get(specifier) else {
return Some((specifier.clone(), MediaType::from_specifier(specifier)));
};
let maybe_module = doc.maybe_js_module().and_then(|r| r.as_ref().ok()); let maybe_module = doc.maybe_js_module().and_then(|r| r.as_ref().ok());
let maybe_types_dependency = maybe_module let maybe_types_dependency = maybe_module
.and_then(|m| m.maybe_types_dependency.as_ref().map(|d| &d.dependency)); .and_then(|m| m.maybe_types_dependency.as_ref().map(|d| &d.dependency));

View file

@ -4043,37 +4043,24 @@ fn op_resolve_inner(
let state = state.borrow_mut::<State>(); let state = state.borrow_mut::<State>();
let mark = state.performance.mark_with_args("tsc.op.op_resolve", &args); let mark = state.performance.mark_with_args("tsc.op.op_resolve", &args);
let referrer = state.specifier_map.normalize(&args.base)?; let referrer = state.specifier_map.normalize(&args.base)?;
let specifiers = match state.get_asset_or_document(&referrer) { let specifiers = state
Some(referrer_doc) => { .state_snapshot
let resolved = state.state_snapshot.documents.resolve( .documents
args.specifiers, .resolve(
&referrer_doc, &args.specifiers,
state.state_snapshot.npm.as_ref(), &referrer,
); state.state_snapshot.npm.as_ref(),
resolved )
.into_iter() .into_iter()
// Resolved `node:` specifier means the user doesn't have @types/node, .map(|o| {
// resolve to stub. o.map(|(s, mt)| {
.map(|o| match o.filter(|(s, _)| s.scheme() != "node") { (
Some((s, mt)) => Some(( state.specifier_map.denormalize(&s),
state.specifier_map.denormalize(&s), mt.as_ts_extension().to_string(),
mt.as_ts_extension().to_string(), )
)), })
None => Some(( })
MISSING_DEPENDENCY_SPECIFIER.to_string(), .collect();
MediaType::Dts.as_ts_extension().to_string(),
)),
})
.collect()
}
None => {
lsp_warn!(
"Error resolving. Referring specifier \"{}\" was not found.",
args.base
);
vec![None; args.specifiers.len()]
}
};
state.performance.measure(mark); state.performance.measure(mark);
Ok(specifiers) Ok(specifiers)
@ -5572,7 +5559,7 @@ mod tests {
} }
#[tokio::test] #[tokio::test]
async fn resolve_unknown_dependency_to_stub_module() { async fn resolve_unknown_dependency() {
let temp_dir = TempDir::new(); let temp_dir = TempDir::new();
let (_, snapshot, _) = setup( let (_, snapshot, _) = setup(
&temp_dir, &temp_dir,
@ -5597,8 +5584,8 @@ mod tests {
assert_eq!( assert_eq!(
resolved, resolved,
vec![Some(( vec![Some((
MISSING_DEPENDENCY_SPECIFIER.to_string(), "file:///b.ts".to_string(),
MediaType::Dts.as_ts_extension().to_string() MediaType::TypeScript.as_ts_extension().to_string()
))] ))]
); );
} }