diff options
author | Nayeem Rahman <nayeemrmn99@gmail.com> | 2024-06-26 23:47:01 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-06-26 23:47:01 +0100 |
commit | 67dcd6db518446574d3a1e33f4ce536fcdc4fd25 (patch) | |
tree | 23d6aa1d867b1efded9c0e638c89513ca492a44f /cli/lsp/documents.rs | |
parent | 2a2ff96be13047cb50612fde0f12e5f6df374ad3 (diff) |
feat(lsp): ts language service scopes (#24345)
Diffstat (limited to 'cli/lsp/documents.rs')
-rw-r--r-- | cli/lsp/documents.rs | 49 |
1 files changed, 34 insertions, 15 deletions
diff --git a/cli/lsp/documents.rs b/cli/lsp/documents.rs index 93fcfe808..29308e9f7 100644 --- a/cli/lsp/documents.rs +++ b/cli/lsp/documents.rs @@ -144,6 +144,20 @@ impl AssetOrDocument { } } + pub fn file_referrer(&self) -> Option<&ModuleSpecifier> { + match self { + AssetOrDocument::Asset(_) => None, + AssetOrDocument::Document(doc) => doc.file_referrer(), + } + } + + pub fn scope(&self) -> Option<&ModuleSpecifier> { + match self { + AssetOrDocument::Asset(_) => None, + AssetOrDocument::Document(doc) => doc.scope(), + } + } + pub fn maybe_semantic_tokens(&self) -> Option<lsp::SemanticTokens> { match self { AssetOrDocument::Asset(_) => None, @@ -605,6 +619,13 @@ impl Document { self.file_referrer.as_ref() } + pub fn scope(&self) -> Option<&ModuleSpecifier> { + self + .file_referrer + .as_ref() + .and_then(|r| self.config.tree.scope_for_specifier(r)) + } + pub fn content(&self) -> &Arc<str> { &self.text } @@ -926,9 +947,9 @@ pub struct Documents { /// The npm package requirements found in npm specifiers. npm_reqs_by_scope: Arc<BTreeMap<Option<ModuleSpecifier>, BTreeSet<PackageReq>>>, - /// Gets if any document had a node: specifier such that a @types/node package - /// should be injected. - has_injected_types_node_package: bool, + /// Config scopes that contain a node: specifier such that a @types/node + /// package should be injected. + scopes_with_node_specifier: Arc<HashSet<Option<ModuleSpecifier>>>, } impl Documents { @@ -1122,10 +1143,10 @@ impl Documents { self.npm_reqs_by_scope.clone() } - /// Returns if a @types/node package was injected into the npm - /// resolver based on the state of the documents. - pub fn has_injected_types_node_package(&self) -> bool { - self.has_injected_types_node_package + pub fn scopes_with_node_specifier( + &self, + ) -> &Arc<HashSet<Option<ModuleSpecifier>>> { + &self.scopes_with_node_specifier } /// Return a document for the specifier. @@ -1346,20 +1367,18 @@ impl Documents { /// document. fn calculate_npm_reqs_if_dirty(&mut self) { let mut npm_reqs_by_scope: BTreeMap<_, BTreeSet<_>> = Default::default(); - let mut scopes_with_node_builtin_specifier = HashSet::new(); + let mut scopes_with_specifier = HashSet::new(); 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 - .file_referrer() - .and_then(|r| self.config.tree.scope_for_specifier(r)); + let scope = doc.scope(); let reqs = npm_reqs_by_scope.entry(scope.cloned()).or_default(); for dependency in doc.dependencies().values() { if let Some(dep) = dependency.get_code() { if dep.scheme() == "node" { - scopes_with_node_builtin_specifier.insert(scope.cloned()); + scopes_with_specifier.insert(scope.cloned()); } if let Ok(reference) = NpmPackageReqReference::from_specifier(dep) { reqs.insert(reference.into_inner().req); @@ -1402,15 +1421,15 @@ 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_node_builtin_specifier { - let reqs = npm_reqs_by_scope.entry(scope).or_default(); + 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") { - self.has_injected_types_node_package = true; 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.dirty = false; } |