summaryrefslogtreecommitdiff
path: root/cli/lsp/documents.rs
diff options
context:
space:
mode:
authorhaturau <135221985+haturatu@users.noreply.github.com>2024-11-20 01:20:47 +0900
committerGitHub <noreply@github.com>2024-11-20 01:20:47 +0900
commit85719a67e59c7aa45bead26e4942d7df8b1b42d4 (patch)
treeface0aecaac53e93ce2f23b53c48859bcf1a36ec /cli/lsp/documents.rs
parent67697bc2e4a62a9670699fd18ad0dd8efc5bd955 (diff)
parent186b52731c6bb326c4d32905c5e732d082e83465 (diff)
Merge branch 'denoland:main' into main
Diffstat (limited to 'cli/lsp/documents.rs')
-rw-r--r--cli/lsp/documents.rs304
1 files changed, 204 insertions, 100 deletions
diff --git a/cli/lsp/documents.rs b/cli/lsp/documents.rs
index 7d1ca6810..b01544ddf 100644
--- a/cli/lsp/documents.rs
+++ b/cli/lsp/documents.rs
@@ -3,7 +3,10 @@
use super::cache::calculate_fs_version;
use super::cache::LspCache;
use super::config::Config;
+use super::resolver::LspIsCjsResolver;
use super::resolver::LspResolver;
+use super::resolver::ScopeDepInfo;
+use super::resolver::SingleReferrerGraphResolver;
use super::testing::TestCollector;
use super::testing::TestModule;
use super::text::LineIndex;
@@ -33,9 +36,9 @@ use deno_semver::npm::NpmPackageReqReference;
use deno_semver::package::PackageReq;
use indexmap::IndexMap;
use indexmap::IndexSet;
+use node_resolver::NodeModuleKind;
use std::borrow::Cow;
use std::collections::BTreeMap;
-use std::collections::BTreeSet;
use std::collections::HashMap;
use std::collections::HashSet;
use std::fs;
@@ -272,7 +275,7 @@ fn get_maybe_test_module_fut(
parsed_source.specifier().clone(),
parsed_source.text_info_lazy().clone(),
);
- parsed_source.module().visit_with(&mut collector);
+ parsed_source.program().visit_with(&mut collector);
Arc::new(collector.take())
})
.map(Result::ok)
@@ -293,6 +296,8 @@ pub struct Document {
/// Contains the last-known-good set of dependencies from parsing the module.
config: Arc<Config>,
dependencies: Arc<IndexMap<String, deno_graph::Dependency>>,
+ /// If this is maybe a CJS script and maybe not an ES module.
+ is_script: Option<bool>,
// TODO(nayeemrmn): This is unused, use it for scope attribution for remote
// modules.
file_referrer: Option<ModuleSpecifier>,
@@ -323,6 +328,7 @@ impl Document {
maybe_lsp_version: Option<i32>,
maybe_language_id: Option<LanguageId>,
maybe_headers: Option<HashMap<String, String>>,
+ is_cjs_resolver: &LspIsCjsResolver,
resolver: Arc<LspResolver>,
config: Arc<Config>,
cache: &Arc<LspCache>,
@@ -332,12 +338,8 @@ impl Document {
.filter(|s| cache.is_valid_file_referrer(s))
.cloned()
.or(file_referrer);
- let media_type = resolve_media_type(
- &specifier,
- maybe_headers.as_ref(),
- maybe_language_id,
- &resolver,
- );
+ let media_type =
+ resolve_media_type(&specifier, maybe_headers.as_ref(), maybe_language_id);
let (maybe_parsed_source, maybe_module) =
if media_type_is_diagnosable(media_type) {
parse_and_analyze_module(
@@ -346,6 +348,7 @@ impl Document {
maybe_headers.as_ref(),
media_type,
file_referrer.as_ref(),
+ is_cjs_resolver,
&resolver,
)
} else {
@@ -371,6 +374,7 @@ impl Document {
file_referrer.as_ref(),
),
file_referrer,
+ is_script: maybe_module.as_ref().map(|m| m.is_script),
maybe_types_dependency,
line_index,
maybe_language_id,
@@ -392,6 +396,7 @@ impl Document {
fn with_new_config(
&self,
+ is_cjs_resolver: &LspIsCjsResolver,
resolver: Arc<LspResolver>,
config: Arc<Config>,
) -> Arc<Self> {
@@ -399,11 +404,11 @@ impl Document {
&self.specifier,
self.maybe_headers.as_ref(),
self.maybe_language_id,
- &resolver,
);
let dependencies;
let maybe_types_dependency;
let maybe_parsed_source;
+ let is_script;
let maybe_test_module_fut;
if media_type != self.media_type {
let parsed_source_result =
@@ -413,6 +418,7 @@ impl Document {
&parsed_source_result,
self.maybe_headers.as_ref(),
self.file_referrer.as_ref(),
+ is_cjs_resolver,
&resolver,
)
.ok();
@@ -420,6 +426,7 @@ impl Document {
.as_ref()
.map(|m| Arc::new(m.dependencies.clone()))
.unwrap_or_default();
+ is_script = maybe_module.as_ref().map(|m| m.is_script);
maybe_types_dependency = maybe_module
.as_ref()
.and_then(|m| Some(Arc::new(m.maybe_types_dependency.clone()?)));
@@ -427,10 +434,19 @@ impl Document {
maybe_test_module_fut =
get_maybe_test_module_fut(maybe_parsed_source.as_ref(), &config);
} else {
- let graph_resolver =
- resolver.as_graph_resolver(self.file_referrer.as_ref());
+ let cli_resolver = resolver.as_cli_resolver(self.file_referrer.as_ref());
let npm_resolver =
resolver.create_graph_npm_resolver(self.file_referrer.as_ref());
+ let config_data = resolver.as_config_data(self.file_referrer.as_ref());
+ let jsx_import_source_config =
+ config_data.and_then(|d| d.maybe_jsx_import_source_config());
+ let resolver = SingleReferrerGraphResolver {
+ valid_referrer: &self.specifier,
+ referrer_kind: is_cjs_resolver
+ .get_lsp_referrer_kind(&self.specifier, self.is_script),
+ cli_resolver,
+ jsx_import_source_config: jsx_import_source_config.as_ref(),
+ };
dependencies = Arc::new(
self
.dependencies
@@ -441,7 +457,7 @@ impl Document {
d.with_new_resolver(
s,
&CliJsrUrlProvider,
- Some(graph_resolver),
+ Some(&resolver),
Some(&npm_resolver),
),
)
@@ -451,10 +467,11 @@ impl Document {
maybe_types_dependency = self.maybe_types_dependency.as_ref().map(|d| {
Arc::new(d.with_new_resolver(
&CliJsrUrlProvider,
- Some(graph_resolver),
+ Some(&resolver),
Some(&npm_resolver),
))
});
+ is_script = self.is_script;
maybe_parsed_source = self.maybe_parsed_source().cloned();
maybe_test_module_fut = self
.maybe_test_module_fut
@@ -466,6 +483,7 @@ impl Document {
// updated properties
dependencies,
file_referrer: self.file_referrer.clone(),
+ is_script,
maybe_types_dependency,
maybe_navigation_tree: Mutex::new(None),
// maintain - this should all be copies/clones
@@ -490,6 +508,7 @@ impl Document {
fn with_change(
&self,
+ is_cjs_resolver: &LspIsCjsResolver,
version: i32,
changes: Vec<lsp::TextDocumentContentChangeEvent>,
) -> Result<Arc<Self>, AnyError> {
@@ -523,6 +542,7 @@ impl Document {
self.maybe_headers.as_ref(),
media_type,
self.file_referrer.as_ref(),
+ is_cjs_resolver,
self.resolver.as_ref(),
)
} else {
@@ -546,6 +566,7 @@ impl Document {
get_maybe_test_module_fut(maybe_parsed_source.as_ref(), &self.config);
Ok(Arc::new(Self {
config: self.config.clone(),
+ is_script: maybe_module.as_ref().map(|m| m.is_script),
specifier: self.specifier.clone(),
file_referrer: self.file_referrer.clone(),
maybe_fs_version: self.maybe_fs_version.clone(),
@@ -580,6 +601,7 @@ impl Document {
),
maybe_language_id: self.maybe_language_id,
dependencies: self.dependencies.clone(),
+ is_script: self.is_script,
maybe_types_dependency: self.maybe_types_dependency.clone(),
text: self.text.clone(),
text_info_cell: once_cell::sync::OnceCell::new(),
@@ -607,6 +629,7 @@ impl Document {
),
maybe_language_id: self.maybe_language_id,
dependencies: self.dependencies.clone(),
+ is_script: self.is_script,
maybe_types_dependency: self.maybe_types_dependency.clone(),
text: self.text.clone(),
text_info_cell: once_cell::sync::OnceCell::new(),
@@ -655,6 +678,13 @@ impl Document {
})
}
+ /// If this is maybe a CJS script and maybe not an ES module.
+ ///
+ /// Use `LspIsCjsResolver` to determine for sure.
+ pub fn is_script(&self) -> Option<bool> {
+ self.is_script
+ }
+
pub fn line_index(&self) -> Arc<LineIndex> {
self.line_index.clone()
}
@@ -764,14 +794,7 @@ fn resolve_media_type(
specifier: &ModuleSpecifier,
maybe_headers: Option<&HashMap<String, String>>,
maybe_language_id: Option<LanguageId>,
- resolver: &LspResolver,
) -> MediaType {
- if resolver.in_node_modules(specifier) {
- if let Some(media_type) = resolver.node_media_type(specifier) {
- return media_type;
- }
- }
-
if let Some(language_id) = maybe_language_id {
return MediaType::from_specifier_and_content_type(
specifier,
@@ -809,6 +832,7 @@ impl FileSystemDocuments {
pub fn get(
&self,
specifier: &ModuleSpecifier,
+ is_cjs_resolver: &LspIsCjsResolver,
resolver: &Arc<LspResolver>,
config: &Arc<Config>,
cache: &Arc<LspCache>,
@@ -832,7 +856,14 @@ impl FileSystemDocuments {
};
if dirty {
// attempt to update the file on the file system
- self.refresh_document(specifier, resolver, config, cache, file_referrer)
+ self.refresh_document(
+ specifier,
+ is_cjs_resolver,
+ resolver,
+ config,
+ cache,
+ file_referrer,
+ )
} else {
old_doc
}
@@ -843,6 +874,7 @@ impl FileSystemDocuments {
fn refresh_document(
&self,
specifier: &ModuleSpecifier,
+ is_cjs_resolver: &LspIsCjsResolver,
resolver: &Arc<LspResolver>,
config: &Arc<Config>,
cache: &Arc<LspCache>,
@@ -859,6 +891,7 @@ impl FileSystemDocuments {
None,
None,
None,
+ is_cjs_resolver,
resolver.clone(),
config.clone(),
cache,
@@ -875,6 +908,7 @@ impl FileSystemDocuments {
None,
None,
None,
+ is_cjs_resolver,
resolver.clone(),
config.clone(),
cache,
@@ -902,6 +936,7 @@ impl FileSystemDocuments {
None,
None,
maybe_headers,
+ is_cjs_resolver,
resolver.clone(),
config.clone(),
cache,
@@ -942,6 +977,11 @@ pub struct Documents {
/// The DENO_DIR that the documents looks for non-file based modules.
cache: Arc<LspCache>,
config: Arc<Config>,
+ /// Resolver for detecting if a document is CJS or ESM.
+ is_cjs_resolver: Arc<LspIsCjsResolver>,
+ /// A resolver that takes into account currently loaded import map and JSX
+ /// settings.
+ resolver: Arc<LspResolver>,
/// A flag that indicates that stated data is potentially invalid and needs to
/// be recalculated before being considered valid.
dirty: bool,
@@ -949,15 +989,7 @@ pub struct Documents {
open_docs: HashMap<ModuleSpecifier, Arc<Document>>,
/// Documents stored on the file system.
file_system_docs: Arc<FileSystemDocuments>,
- /// A resolver that takes into account currently loaded import map and JSX
- /// settings.
- resolver: Arc<LspResolver>,
- /// The npm package requirements found in npm specifiers.
- npm_reqs_by_scope:
- Arc<BTreeMap<Option<ModuleSpecifier>, BTreeSet<PackageReq>>>,
- /// Config scopes that contain a node: specifier such that a @types/node
- /// package should be injected.
- scopes_with_node_specifier: Arc<HashSet<Option<ModuleSpecifier>>>,
+ dep_info_by_scope: Arc<BTreeMap<Option<ModuleSpecifier>, Arc<ScopeDepInfo>>>,
}
impl Documents {
@@ -982,6 +1014,7 @@ impl Documents {
// the cache for remote modules here in order to get the
// x-typescript-types?
None,
+ &self.is_cjs_resolver,
self.resolver.clone(),
self.config.clone(),
&self.cache,
@@ -1016,7 +1049,7 @@ impl Documents {
))
})?;
self.dirty = true;
- let doc = doc.with_change(version, changes)?;
+ let doc = doc.with_change(&self.is_cjs_resolver, version, changes)?;
self.open_docs.insert(doc.specifier().clone(), doc.clone());
Ok(doc)
}
@@ -1071,34 +1104,6 @@ impl Documents {
self.cache.is_valid_file_referrer(specifier)
}
- /// Return `true` if the provided specifier can be resolved to a document,
- /// otherwise `false`.
- pub fn contains_import(
- &self,
- specifier: &str,
- referrer: &ModuleSpecifier,
- ) -> bool {
- let file_referrer = self.get_file_referrer(referrer);
- let maybe_specifier = self
- .resolver
- .as_graph_resolver(file_referrer.as_deref())
- .resolve(
- specifier,
- &deno_graph::Range {
- specifier: referrer.clone(),
- start: deno_graph::Position::zeroed(),
- end: deno_graph::Position::zeroed(),
- },
- ResolutionMode::Types,
- )
- .ok();
- if let Some(import_specifier) = maybe_specifier {
- self.exists(&import_specifier, file_referrer.as_deref())
- } else {
- false
- }
- }
-
pub fn resolve_document_specifier(
&self,
specifier: &ModuleSpecifier,
@@ -1147,17 +1152,20 @@ impl Documents {
false
}
- pub fn npm_reqs_by_scope(
+ pub fn dep_info_by_scope(
&mut self,
- ) -> Arc<BTreeMap<Option<ModuleSpecifier>, BTreeSet<PackageReq>>> {
- self.calculate_npm_reqs_if_dirty();
- self.npm_reqs_by_scope.clone()
+ ) -> Arc<BTreeMap<Option<ModuleSpecifier>, Arc<ScopeDepInfo>>> {
+ self.calculate_dep_info_if_dirty();
+ self.dep_info_by_scope.clone()
}
- pub fn scopes_with_node_specifier(
- &self,
- ) -> &Arc<HashSet<Option<ModuleSpecifier>>> {
- &self.scopes_with_node_specifier
+ pub fn scopes_with_node_specifier(&self) -> HashSet<Option<ModuleSpecifier>> {
+ self
+ .dep_info_by_scope
+ .iter()
+ .filter(|(_, i)| i.has_node_specifier)
+ .map(|(s, _)| s.clone())
+ .collect::<HashSet<_>>()
}
/// Return a document for the specifier.
@@ -1173,6 +1181,7 @@ impl Documents {
if let Some(old_doc) = old_doc {
self.file_system_docs.get(
specifier,
+ &self.is_cjs_resolver,
&self.resolver,
&self.config,
&self.cache,
@@ -1197,6 +1206,7 @@ impl Documents {
} else {
self.file_system_docs.get(
&specifier,
+ &self.is_cjs_resolver,
&self.resolver,
&self.config,
&self.cache,
@@ -1255,12 +1265,15 @@ impl Documents {
referrer: &ModuleSpecifier,
file_referrer: Option<&ModuleSpecifier>,
) -> Vec<Option<(ModuleSpecifier, MediaType)>> {
- let document = self.get(referrer);
- let file_referrer = document
+ let referrer_doc = self.get(referrer);
+ let file_referrer = referrer_doc
.as_ref()
.and_then(|d| d.file_referrer())
.or(file_referrer);
- let dependencies = document.as_ref().map(|d| d.dependencies());
+ let dependencies = referrer_doc.as_ref().map(|d| d.dependencies());
+ let referrer_kind = self
+ .is_cjs_resolver
+ .get_maybe_doc_module_kind(referrer, referrer_doc.as_deref());
let mut results = Vec::new();
for raw_specifier in raw_specifiers {
if raw_specifier.starts_with("asset:") {
@@ -1277,31 +1290,35 @@ impl Documents {
results.push(self.resolve_dependency(
specifier,
referrer,
+ referrer_kind,
file_referrer,
));
} else if let Some(specifier) = dep.maybe_code.maybe_specifier() {
results.push(self.resolve_dependency(
specifier,
referrer,
+ referrer_kind,
file_referrer,
));
} else {
results.push(None);
}
} else if let Ok(specifier) =
- self.resolver.as_graph_resolver(file_referrer).resolve(
+ self.resolver.as_cli_resolver(file_referrer).resolve(
raw_specifier,
&deno_graph::Range {
specifier: referrer.clone(),
start: deno_graph::Position::zeroed(),
end: deno_graph::Position::zeroed(),
},
+ referrer_kind,
ResolutionMode::Types,
)
{
results.push(self.resolve_dependency(
&specifier,
referrer,
+ referrer_kind,
file_referrer,
));
} else {
@@ -1320,7 +1337,11 @@ impl Documents {
) {
self.config = Arc::new(config.clone());
self.cache = Arc::new(cache.clone());
+ self.is_cjs_resolver = Arc::new(LspIsCjsResolver::new(cache));
self.resolver = resolver.clone();
+
+ node_resolver::PackageJsonThreadLocalCache::clear();
+
{
let fs_docs = &self.file_system_docs;
// Clean up non-existent documents.
@@ -1340,14 +1361,21 @@ impl Documents {
if !config.specifier_enabled(doc.specifier()) {
continue;
}
- *doc = doc.with_new_config(self.resolver.clone(), self.config.clone());
+ *doc = doc.with_new_config(
+ &self.is_cjs_resolver,
+ self.resolver.clone(),
+ self.config.clone(),
+ );
}
for mut doc in self.file_system_docs.docs.iter_mut() {
if !config.specifier_enabled(doc.specifier()) {
continue;
}
- *doc.value_mut() =
- doc.with_new_config(self.resolver.clone(), self.config.clone());
+ *doc.value_mut() = doc.with_new_config(
+ &self.is_cjs_resolver,
+ self.resolver.clone(),
+ self.config.clone(),
+ );
}
self.open_docs = open_docs;
let mut preload_count = 0;
@@ -1364,6 +1392,7 @@ impl Documents {
{
fs_docs.refresh_document(
specifier,
+ &self.is_cjs_resolver,
&self.resolver,
&self.config,
&self.cache,
@@ -1379,34 +1408,46 @@ impl Documents {
/// Iterate through the documents, building a map where the key is a unique
/// document and the value is a set of specifiers that depend on that
/// document.
- fn calculate_npm_reqs_if_dirty(&mut self) {
- let mut npm_reqs_by_scope: BTreeMap<_, BTreeSet<_>> = Default::default();
- let mut scopes_with_specifier = HashSet::new();
+ fn calculate_dep_info_if_dirty(&mut self) {
+ let mut dep_info_by_scope: BTreeMap<_, ScopeDepInfo> = Default::default();
let is_fs_docs_dirty = self.file_system_docs.set_dirty(false);
if !is_fs_docs_dirty && !self.dirty {
return;
}
let mut visit_doc = |doc: &Arc<Document>| {
let scope = doc.scope();
- let reqs = npm_reqs_by_scope.entry(scope.cloned()).or_default();
+ let dep_info = dep_info_by_scope.entry(scope.cloned()).or_default();
for dependency in doc.dependencies().values() {
- if let Some(dep) = dependency.get_code() {
+ let code_specifier = dependency.get_code();
+ let type_specifier = dependency.get_type();
+ if let Some(dep) = code_specifier {
if dep.scheme() == "node" {
- scopes_with_specifier.insert(scope.cloned());
+ dep_info.has_node_specifier = true;
}
if let Ok(reference) = NpmPackageReqReference::from_specifier(dep) {
- reqs.insert(reference.into_inner().req);
+ dep_info.npm_reqs.insert(reference.into_inner().req);
}
}
- if let Some(dep) = dependency.get_type() {
+ if let Some(dep) = type_specifier {
if let Ok(reference) = NpmPackageReqReference::from_specifier(dep) {
- reqs.insert(reference.into_inner().req);
+ dep_info.npm_reqs.insert(reference.into_inner().req);
+ }
+ }
+ if dependency.maybe_deno_types_specifier.is_some() {
+ if let (Some(code_specifier), Some(type_specifier)) =
+ (code_specifier, type_specifier)
+ {
+ if MediaType::from_specifier(type_specifier).is_declaration() {
+ dep_info
+ .deno_types_to_code_resolutions
+ .insert(type_specifier.clone(), code_specifier.clone());
+ }
}
}
}
if let Some(dep) = doc.maybe_types_dependency().maybe_specifier() {
if let Ok(reference) = NpmPackageReqReference::from_specifier(dep) {
- reqs.insert(reference.into_inner().req);
+ dep_info.npm_reqs.insert(reference.into_inner().req);
}
}
};
@@ -1417,14 +1458,49 @@ impl Documents {
visit_doc(doc);
}
- // fill the reqs from the lockfile
for (scope, config_data) in self.config.tree.data_by_scope().as_ref() {
+ let dep_info = dep_info_by_scope.entry(Some(scope.clone())).or_default();
+ (|| {
+ let config_file = config_data.maybe_deno_json()?;
+ let jsx_config =
+ config_file.to_maybe_jsx_import_source_config().ok()??;
+ let type_specifier = jsx_config.default_types_specifier.as_ref()?;
+ let code_specifier = jsx_config.default_specifier.as_ref()?;
+ let cli_resolver = self.resolver.as_cli_resolver(Some(scope));
+ let range = deno_graph::Range {
+ specifier: jsx_config.base_url.clone(),
+ start: deno_graph::Position::zeroed(),
+ end: deno_graph::Position::zeroed(),
+ };
+ let type_specifier = cli_resolver
+ .resolve(
+ type_specifier,
+ &range,
+ // todo(dsherret): this is wrong because it doesn't consider CJS referrers
+ deno_package_json::NodeModuleKind::Esm,
+ ResolutionMode::Types,
+ )
+ .ok()?;
+ let code_specifier = cli_resolver
+ .resolve(
+ code_specifier,
+ &range,
+ // todo(dsherret): this is wrong because it doesn't consider CJS referrers
+ deno_package_json::NodeModuleKind::Esm,
+ ResolutionMode::Execution,
+ )
+ .ok()?;
+ dep_info
+ .deno_types_to_code_resolutions
+ .insert(type_specifier, code_specifier);
+ Some(())
+ })();
+ // fill the reqs from the lockfile
if let Some(lockfile) = config_data.lockfile.as_ref() {
- let reqs = npm_reqs_by_scope.entry(Some(scope.clone())).or_default();
let lockfile = lockfile.lock();
for dep_req in lockfile.content.packages.specifiers.keys() {
if dep_req.kind == deno_semver::package::PackageKind::Npm {
- reqs.insert(dep_req.req.clone());
+ dep_info.npm_reqs.insert(dep_req.req.clone());
}
}
}
@@ -1433,15 +1509,22 @@ impl Documents {
// Ensure a @types/node package exists when any module uses a node: specifier.
// Unlike on the command line, here we just add @types/node to the npm package
// requirements since this won't end up in the lockfile.
- for scope in &scopes_with_specifier {
- let reqs = npm_reqs_by_scope.entry(scope.clone()).or_default();
- if !reqs.iter().any(|r| r.name == "@types/node") {
- reqs.insert(PackageReq::from_str("@types/node").unwrap());
+ for dep_info in dep_info_by_scope.values_mut() {
+ if dep_info.has_node_specifier
+ && !dep_info.npm_reqs.iter().any(|r| r.name == "@types/node")
+ {
+ dep_info
+ .npm_reqs
+ .insert(PackageReq::from_str("@types/node").unwrap());
}
}
- self.npm_reqs_by_scope = Arc::new(npm_reqs_by_scope);
- self.scopes_with_node_specifier = Arc::new(scopes_with_specifier);
+ self.dep_info_by_scope = Arc::new(
+ dep_info_by_scope
+ .into_iter()
+ .map(|(s, i)| (s, Arc::new(i)))
+ .collect(),
+ );
self.dirty = false;
}
@@ -1449,6 +1532,7 @@ impl Documents {
&self,
specifier: &ModuleSpecifier,
referrer: &ModuleSpecifier,
+ referrer_kind: NodeModuleKind,
file_referrer: Option<&ModuleSpecifier>,
) -> Option<(ModuleSpecifier, MediaType)> {
if let Some(module_name) = specifier.as_str().strip_prefix("node:") {
@@ -1462,10 +1546,12 @@ impl Documents {
let mut specifier = specifier.clone();
let mut media_type = None;
if let Ok(npm_ref) = NpmPackageReqReference::from_specifier(&specifier) {
- let (s, mt) =
- self
- .resolver
- .npm_to_file_url(&npm_ref, referrer, file_referrer)?;
+ let (s, mt) = self.resolver.npm_to_file_url(
+ &npm_ref,
+ referrer,
+ referrer_kind,
+ file_referrer,
+ )?;
specifier = s;
media_type = Some(mt);
}
@@ -1475,7 +1561,8 @@ impl Documents {
return Some((specifier, media_type));
};
if let Some(types) = doc.maybe_types_dependency().maybe_specifier() {
- self.resolve_dependency(types, &specifier, file_referrer)
+ let specifier_kind = self.is_cjs_resolver.get_doc_module_kind(&doc);
+ self.resolve_dependency(types, &specifier, specifier_kind, file_referrer)
} else {
Some((doc.specifier().clone(), doc.media_type()))
}
@@ -1543,6 +1630,7 @@ fn parse_and_analyze_module(
maybe_headers: Option<&HashMap<String, String>>,
media_type: MediaType,
file_referrer: Option<&ModuleSpecifier>,
+ is_cjs_resolver: &LspIsCjsResolver,
resolver: &LspResolver,
) -> (Option<ParsedSourceResult>, Option<ModuleResult>) {
let parsed_source_result = parse_source(specifier.clone(), text, media_type);
@@ -1551,6 +1639,7 @@ fn parse_and_analyze_module(
&parsed_source_result,
maybe_headers,
file_referrer,
+ is_cjs_resolver,
resolver,
);
(Some(parsed_source_result), Some(module_result))
@@ -1561,7 +1650,7 @@ fn parse_source(
text: Arc<str>,
media_type: MediaType,
) -> ParsedSourceResult {
- deno_ast::parse_module(deno_ast::ParseParams {
+ deno_ast::parse_program(deno_ast::ParseParams {
specifier,
text,
media_type,
@@ -1576,11 +1665,26 @@ fn analyze_module(
parsed_source_result: &ParsedSourceResult,
maybe_headers: Option<&HashMap<String, String>>,
file_referrer: Option<&ModuleSpecifier>,
+ is_cjs_resolver: &LspIsCjsResolver,
resolver: &LspResolver,
) -> ModuleResult {
match parsed_source_result {
Ok(parsed_source) => {
let npm_resolver = resolver.create_graph_npm_resolver(file_referrer);
+ let cli_resolver = resolver.as_cli_resolver(file_referrer);
+ let config_data = resolver.as_config_data(file_referrer);
+ let valid_referrer = specifier.clone();
+ let jsx_import_source_config =
+ config_data.and_then(|d| d.maybe_jsx_import_source_config());
+ let resolver = SingleReferrerGraphResolver {
+ valid_referrer: &valid_referrer,
+ referrer_kind: is_cjs_resolver.get_lsp_referrer_kind(
+ &specifier,
+ Some(parsed_source.compute_is_script()),
+ ),
+ cli_resolver,
+ jsx_import_source_config: jsx_import_source_config.as_ref(),
+ };
Ok(deno_graph::parse_module_from_ast(
deno_graph::ParseModuleFromAstOptions {
graph_kind: deno_graph::GraphKind::TypesOnly,
@@ -1591,7 +1695,7 @@ fn analyze_module(
// dynamic imports like import(`./dir/${something}`) in the LSP
file_system: &deno_graph::source::NullFileSystem,
jsr_url_provider: &CliJsrUrlProvider,
- maybe_resolver: Some(resolver.as_graph_resolver(file_referrer)),
+ maybe_resolver: Some(&resolver),
maybe_npm_resolver: Some(&npm_resolver),
},
))