From 2510e70fc6ab6883b919d1f7dc588c0447f78a8d Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sun, 17 May 2026 08:30:25 +0200 Subject: [PATCH] Search: opt in to private/compiler-generated entities MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The default ApiVisibility=PublicOnly setting filters search results through CheckVisibility, which rejects private entities. Compiler- generated names — async/iterator state machines (d__N), display classes (<>c__DisplayClass), anonymous-method closures (<>c) — are all private, so they were unfindable even when the user typed the exact full name. Assisted-by: Claude:claude-opus-4-7:Claude Code --- ICSharpCode.ILSpyX/Search/AbstractEntitySearchStrategy.cs | 7 +++++++ ICSharpCode.ILSpyX/Search/AbstractSearchStrategy.cs | 8 ++++++++ ILSpy/Search/RunningSearch.cs | 7 +++++++ 3 files changed, 22 insertions(+) diff --git a/ICSharpCode.ILSpyX/Search/AbstractEntitySearchStrategy.cs b/ICSharpCode.ILSpyX/Search/AbstractEntitySearchStrategy.cs index 8534751eb..b9cbce1d2 100644 --- a/ICSharpCode.ILSpyX/Search/AbstractEntitySearchStrategy.cs +++ b/ICSharpCode.ILSpyX/Search/AbstractEntitySearchStrategy.cs @@ -43,6 +43,13 @@ namespace ICSharpCode.ILSpyX.Search if (apiVisibility == ApiVisibility.All) return true; + // The query parser sets IncludePrivateApi when the user types `<` or `>` — + // characteristic of compiler-generated names (state-machines, display classes, + // anonymous closures). Bypass the public-only filter so those names actually + // surface as results when the user is hunting for them specifically. + if (searchRequest.IncludePrivateApi) + return true; + while (entity != null) { if (apiVisibility == ApiVisibility.PublicOnly) diff --git a/ICSharpCode.ILSpyX/Search/AbstractSearchStrategy.cs b/ICSharpCode.ILSpyX/Search/AbstractSearchStrategy.cs index 1078d29b5..c225d0ab3 100644 --- a/ICSharpCode.ILSpyX/Search/AbstractSearchStrategy.cs +++ b/ICSharpCode.ILSpyX/Search/AbstractSearchStrategy.cs @@ -55,6 +55,14 @@ namespace ICSharpCode.ILSpyX.Search public Regex? RegEx; public bool FullNameSearch; public bool OmitGenerics; + // When set, CheckVisibility bypasses the api-visibility filter so private / + // compiler-generated entities (state-machines, display classes, anonymous + // closures — anything with `<...>` segments in its metadata name) become + // findable. Set by the query parser when the user types `<` or `>` in + // their search term: those characters are characteristically present in + // compiler-generated names and rare in everyday API names, so they're a + // reliable signal that the user wants the visibility filter relaxed. + public bool IncludePrivateApi; public string InNamespace; public string InAssembly; } diff --git a/ILSpy/Search/RunningSearch.cs b/ILSpy/Search/RunningSearch.cs index 641d9031f..4708a4789 100644 --- a/ILSpy/Search/RunningSearch.cs +++ b/ILSpy/Search/RunningSearch.cs @@ -337,6 +337,13 @@ namespace ILSpy.Search } if (!(term.Contains('<') || term.Contains('`'))) request.OmitGenerics = true; + // Angle brackets are characteristic of compiler-generated names + // (`d__N`, `<>c__DisplayClass`, etc.) and rare in everyday API + // names — treat them as the user opting in to private / + // compiler-generated entities even when the global visibility + // setting is PublicOnly. + if (term.Contains('<') || term.Contains('>')) + request.IncludePrivateApi = true; switch (prefix?.ToUpperInvariant()) {