Skip to content

Exclude compiler-generated nested types at --visibility All - #46

Merged
Malcolmnixon merged 1 commit into
mainfrom
fix/visibility-all-compiler-generated-nested-types
Oct 3, 2026
Merged

Malcolmnixon merged 1 commit into
mainfrom
fix/visibility-all-compiler-generated-nested-types

Conversation

@Malcolmnixon

Copy link
Copy Markdown
Member

Summary

Fixes --visibility All (and ApiMarkVisibility=All) crashing on Windows with an I/O error when an assembly contains compiler-generated types or members (lambdas, closures, async/iterator state machines).

Repro: apimark dotnet --assembly Repro.dll --xml-doc Repro.xml --output out --visibility All on an assembly with a lambda or async method fails with:

Error: The filename, directory name, or volume label syntax is incorrect. : ''out\Repro\Sample\<>c.md''

Root cause

DotNetEmitter.GetVisibleNestedTypes was the only visibility filter that didn''t exclude compiler-generated nested types (<>c, <>c__DisplayClass*, <RunAsync>d__5, etc.). Top-level types and members already filtered these out via IsCompilerGenerated, but nested types only show up at All visibility (they''re private/internal), so the gap went unnoticed until this report. Several of these names contain <, >, | — invalid in Windows paths.

DocumentationCoverageChecker (used by --enforce-docs) already filtered these correctly, so no change was needed there.

Fix

  • Added .Where(t => !IsCompilerGenerated(t)) to GetVisibleNestedTypes in src/ApiMark.DotNet/DotNetEmitter.cs, excluding compiler-generated nested types at every visibility, including All.
  • Added a regression fixture (CompilerGeneratedNestedClass.cs, two lambda-using methods) and a test (DotNetEmitter_GetVisibleNestedTypes_AllVisibility_ExcludesCompilerGeneratedTypes) confirming none of the synthesized nested types are visible at ApiVisibility.All.
  • Updated the DotNetEmitter design doc to describe the exclusion rule and rationale.

Validation

  • dotnet test test\ApiMark.DotNet.Tests — 332/332 passing on net8.0/net9.0/net10.0.
  • Manually ran apimark dotnet ... --visibility All against the fixtures assembly (which now includes lambdas) — completes without error.
  • pwsh ./fix.ps1 — no formatting changes needed.
  • Ran code-review and formal-review agents against the affected review-sets (ApiMark-DotNet-DotNetEmitter, ApiMark-DotNet-DotNetEmitterGradualDisclosure, ApiMark-DotNet-DotNetEmitterSingleFile) — all now pass; one Medium design-doc gap found and fixed during review.

GetVisibleNestedTypes was the only visibility filter that didn''t exclude
compiler-generated types (closures, cached-lambda classes, async/iterator
state machines, etc.). At --visibility All these were emitted as
documentation pages, and several of their names contain characters
(<, >, |) invalid in Windows file paths, causing an I/O error.

- Exclude compiler-generated nested types via the existing
  IsCompilerGenerated helper, matching the filtering already applied to
  top-level types and members.
- Add a regression fixture/test exercising lambdas that synthesize a
  cached-lambda class and a closure, confirming neither is visible at
  ApiVisibility.All.
- Document the exclusion rule in the DotNetEmitter design doc.

Fixes the reported crash: "The filename, directory name, or volume label
syntax is incorrect. : ''out\Repro\Sample\<>c.md''"

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI lite review requested due to automatic review settings October 3, 2026 13:03

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟢 Approval recommended

No unresolved blocking issues remain.

Review effort: Lite
Findings: None

What changed in this PR

Fixes --visibility All failures by excluding compiler-generated nested types from .NET API output.

Changes:

  • Filters compiler-generated nested types.
  • Adds regression fixture and test coverage.
  • Documents the exclusion behavior and rationale.
File Description
test/​ApiMark.DotNet.Tests/​DotNetEmitterTests.cs Verifies generated nested types are omitted at All visibility.
test/​ApiMark.DotNet.Fixtures/​CompilerGeneratedNestedClass.cs Adds lambda-based compiler-generated types.
src/​ApiMark.DotNet/​DotNetEmitter.cs Excludes compiler-generated nested types.
docs/​design/​api-mark-dot-net/​dot-net-emitter.md Documents the filtering rule.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants