pub struct NuGetEcosystem { /* private fields */ }Expand description
NuGet/.NET ecosystem implementation.
Provides LSP functionality for .csproj/.fsproj/.vbproj, Directory.Packages.props,
and packages.config files, backed by the NuGet V3 registry API.
Implementations§
Source§impl NuGetEcosystem
impl NuGetEcosystem
pub fn new(cache: Arc<HttpCache>) -> Self
Sourcepub fn with_context(
registry: Arc<NuGetRegistry>,
context: NuGetParseContext,
) -> Self
pub fn with_context( registry: Arc<NuGetRegistry>, context: NuGetParseContext, ) -> Self
Creates a new NuGet ecosystem sharing context’s reachability policy and
NuGet.Config memoization cache, around an existing NuGetRegistry instance — the
production constructor, used by deps-lsp’s register_ecosystems so
initialize/workspace/didChangeConfiguration can update the same
Arc<RegistryAccessPolicy> this ecosystem’s every parse reads (mirrors deps-npm’s/
deps-pypi’s identical split — Self::new’s default, disconnected policy would never
see a live update).
Trait Implementations§
Source§impl Ecosystem for NuGetEcosystem
impl Ecosystem for NuGetEcosystem
Source§fn generate_hover<'a>(
&'a self,
parse_result: &'a dyn ParseResultTrait,
position: Position,
versions: VersionData<'a>,
freshness: FreshnessSettings,
) -> BoxFuture<'a, Option<Hover>>
fn generate_hover<'a>( &'a self, parse_result: &'a dyn ParseResultTrait, position: Position, versions: VersionData<'a>, freshness: FreshnessSettings, ) -> BoxFuture<'a, Option<Hover>>
Overrides the default (lsp_helpers::generate_hover) to add a hover-only unlisted
marker (D1, #451): alongside the ordinary hover render, a separate
NuGetRegistry::unlisted_versions_for_hover fetch decorates each unlisted entry
in the “Recent versions” list with *(unlisted)*, matching how other ecosystems in
this codebase mark a *(yanked)* version — see that method’s doc comment for why
this enrichment is deliberately kept out of Version::removal_status (and so out of
completion/inlay hints/diagnostics, which all share the cached version list hover
itself renders via the ordinary, non-enriched path above).
The two fetches run concurrently via tokio::join!, not sequentially (S4, #451
follow-up): serializing them would double hover’s worst-case latency, and the
unlisted fetch alone is additionally bounded by HOVER_UNLISTED_TIMEOUT — without
it, a pathological feed’s registration-hive walk (up to MAX_EXTERNAL_PAGE_FETCHES
sequential page fetches, each with its own HTTP-client timeout) could run
unbounded, exactly the failure mode deps_core::lsp_helpers::hover’s own
HOVER_FALLBACK_TIMEOUT exists to prevent for its analogous fallback fetch. dep is
resolved once, up front, and reused for the unlisted lookup rather than re-derived
from the rendered hover afterward.
Issue #523 fix: the unlisted fetch is only issued when dep.source() is plain
DependencySource::Registry — self.registry here is always the Public-tier root,
so calling unlisted_versions_for_hover unconditionally would send a private-feed
dependency’s real package name to api.nuget.org, defeating the entire feature
(NuGetRegistry::unlisted_versions_for_hover’s own tier gate only fires when the
callee instance is WorkspaceDeclared, which the root never is). A private-feed
dependency simply renders without the *(unlisted)* decoration — registration-hive
enrichment is already skipped entirely for alternate feeds in phase 1 (see that
method’s own tier gate), so this loses nothing a private-feed hover would have shown
anyway.
Source§fn display_name(&self) -> &'static str
fn display_name(&self) -> &'static str
Source§fn manifest_filenames(&self) -> &[&'static str]
fn manifest_filenames(&self) -> &[&'static str]
Source§fn manifest_extensions(&self) -> &[&'static str]
fn manifest_extensions(&self) -> &[&'static str]
[".csproj", ".fsproj"] for NuGet project files). Read moreSource§fn lockfile_filenames(&self) -> &[&'static str]
fn lockfile_filenames(&self) -> &[&'static str]
Source§fn parse_manifest<'a>(
&'a self,
content: &'a str,
uri: &'a Uri,
) -> BoxFuture<'a, Result<Box<dyn ParseResultTrait>>>
fn parse_manifest<'a>( &'a self, content: &'a str, uri: &'a Uri, ) -> BoxFuture<'a, Result<Box<dyn ParseResultTrait>>>
Source§fn lockfile_provider(&self) -> Option<Arc<dyn LockFileProvider>>
fn lockfile_provider(&self) -> Option<Arc<dyn LockFileProvider>>
Source§fn formatter(&self) -> &dyn EcosystemFormatter
fn formatter(&self) -> &dyn EcosystemFormatter
Source§fn generate_completions<'a>(
&'a self,
parse_result: &'a dyn ParseResultTrait,
position: Position,
content: &'a str,
freshness: FreshnessSettings,
) -> BoxFuture<'a, Completions>
fn generate_completions<'a>( &'a self, parse_result: &'a dyn ParseResultTrait, position: Position, content: &'a str, freshness: FreshnessSettings, ) -> BoxFuture<'a, Completions>
Source§fn manifest_patterns(&self) -> &[&'static str]
fn manifest_patterns(&self) -> &[&'static str]
* wildcard (e.g. ["requirements*.txt"]). Read moreSource§fn manifest_directory_patterns(&self) -> &[(&'static str, &'static str)]
fn manifest_directory_patterns(&self) -> &[(&'static str, &'static str)]
(directory_path, file_suffix) pairs identifying a file solely by its
containing directory path and suffix. directory_path may be a single
segment (e.g. [("requirements", ".txt")] for Python’s
requirements/base.txt split-file layout) or multiple /-joined
segments (e.g. [(".github/workflows", ".yml")] for GitHub Actions
workflow files) — either way it is matched against the tail of the
file’s directory path on segment boundaries, not just the immediate
parent, so a multi-segment pattern matches regardless of how many
ancestor directories precede it. Used when the basename alone carries
no ecosystem signal. Read moreSource§fn watched_config_filenames(&self) -> &[&'static str]
fn watched_config_filenames(&self) -> &[&'static str]
Self::parse_manifest
(e.g. ["pnpm-workspace.yaml", ".npmrc"] for npm’s catalog and registry resolution),
whose values end up baked into a manifest’s ParseResult rather than looked up
separately the way a Self::lockfile_provider is. Read moreSource§fn generate_inlay_hints<'a>(
&'a self,
parse_result: &'a dyn ParseResult,
versions: VersionData<'a>,
loading_state: LoadingState,
config: &'a EcosystemConfig,
) -> Pin<Box<dyn Future<Output = Vec<InlayHint>> + Send + 'a>>
fn generate_inlay_hints<'a>( &'a self, parse_result: &'a dyn ParseResult, versions: VersionData<'a>, loading_state: LoadingState, config: &'a EcosystemConfig, ) -> Pin<Box<dyn Future<Output = Vec<InlayHint>> + Send + 'a>>
Source§fn generate_code_actions<'a>(
&'a self,
parse_result: &'a dyn ParseResult,
position: Position,
uri: &'a Uri,
versions: VersionData<'a>,
content: &'a str,
) -> Pin<Box<dyn Future<Output = Vec<CodeAction>> + Send + 'a>>
fn generate_code_actions<'a>( &'a self, parse_result: &'a dyn ParseResult, position: Position, uri: &'a Uri, versions: VersionData<'a>, content: &'a str, ) -> Pin<Box<dyn Future<Output = Vec<CodeAction>> + Send + 'a>>
Source§fn generate_diagnostics<'a>(
&'a self,
parse_result: &'a dyn ParseResult,
versions: VersionData<'a>,
uri: &'a Uri,
freshness: FreshnessSettings,
severities: DiagnosticSeverities,
) -> Pin<Box<dyn Future<Output = Vec<Diagnostic>> + Send + 'a>>
fn generate_diagnostics<'a>( &'a self, parse_result: &'a dyn ParseResult, versions: VersionData<'a>, uri: &'a Uri, freshness: FreshnessSettings, severities: DiagnosticSeverities, ) -> Pin<Box<dyn Future<Output = Vec<Diagnostic>> + Send + 'a>>
Source§fn generate_document_links(
&self,
_parse_result: &dyn ParseResult,
_uri: &Uri,
) -> Vec<DocumentLink>
fn generate_document_links( &self, _parse_result: &dyn ParseResult, _uri: &Uri, ) -> Vec<DocumentLink>
textDocument/documentLink targets for the document. Read moreSource§fn generate_code_lenses<'a>(
&'a self,
parse_result: &'a dyn ParseResult,
content: &'a str,
versions: VersionData<'a>,
uri: &'a Uri,
command_id: &'a str,
) -> Pin<Box<dyn Future<Output = Vec<CodeLens>> + Send + 'a>>
fn generate_code_lenses<'a>( &'a self, parse_result: &'a dyn ParseResult, content: &'a str, versions: VersionData<'a>, uri: &'a Uri, command_id: &'a str, ) -> Pin<Box<dyn Future<Output = Vec<CodeLens>> + Send + 'a>>
Source§fn package_search_is_incomplete(&self) -> bool
fn package_search_is_incomplete(&self) -> bool
PypiRegistry::search’s doc comment). Read more