Skip to content

Add unified platform map for cross-platform API documentation#4327

Merged
AlexDaines merged 9 commits intodevelopmentfrom
adaines/unified-platform-map
Apr 6, 2026
Merged

Add unified platform map for cross-platform API documentation#4327
AlexDaines merged 9 commits intodevelopmentfrom
adaines/unified-platform-map

Conversation

@AlexDaines
Copy link
Copy Markdown
Contributor

@AlexDaines AlexDaines commented Feb 5, 2026

Description

Adds PlatformAvailabilityMap infrastructure for tracking API availability across .NET platforms (net472, netstandard2.0, netcoreapp3.1, net8.0). Enables documentation of platform-exclusive APIs like H2 eventstream methods that only exist in net8.0.

Motivation and Context

Fixes #3938 - Customers see documented APIs that don't exist on their target platform, wasting time trying to use APIs that won't compile.

This PR ships the infrastructure only. Badge UX deferred to follow-up PR pending design review.

Testing

Dryruns (03/31/26):
dotnetv4 (passed) - a4511f2c-a7d8-49ce-813a-f685abc46ed0
powershell5 (passed) - 6c0420ce-829e-42f9-a3a3-560b5dd86684

  • Built doc generator: dotnet build SDKDocGenerator/SDKDocGenerator.csproj
  • Generated test docs for BedrockRuntime and S3 services
  • Verified H2 exclusive method pages generated (InvokeModelWithBidirectionalStreamAsync)
  • Verified Version Information section unchanged
  • No new build errors (only expected obsolete warnings)

Breaking Changes Assessment

None. This is additive infrastructure with no changes to existing doc output behavior.

Screenshots (if appropriate)

TTranscribeStreamingClient.html methods section:
Before (live docs):
image

After (artifacts from dryrun of this branch):
image

Example of New Individual Method Page:
image

Beyond Compare
Comparing the latest release build's doc build output to the doc build output from the dryrun of this feature branch:
image

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist

  • My code follows the code style of this project
  • My change requires a change to the documentation
  • I have updated the documentation accordingly
  • I have read the README document
  • I have added tests to cover my changes
  • All new and existing tests passed

License

  • I confirm that this pull request can be released under the Apache 2 license

@AlexDaines AlexDaines requested a review from Copilot February 5, 2026 18:10
@AlexDaines AlexDaines marked this pull request as ready for review February 5, 2026 18:16
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds comprehensive platform availability mapping infrastructure to the AWS .NET SDK documentation generator to track API availability across different .NET platforms (net472, netstandard2.0, netcoreapp3.1, net8.0). This addresses issue #3938 where customers encountered documented APIs that don't exist on their target platform.

Changes:

  • Implements a unified platform availability map that scans all platforms upfront and maintains signature-to-platform mappings
  • Adds isolated assembly loading via AssemblyLoadContext to enable loading multiple platform versions of the same assembly simultaneously
  • Introduces infrastructure for generating documentation pages for platform-exclusive APIs (e.g., H2 bidirectional streaming methods only available in net8.0)

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
PlatformMap/*.cs New infrastructure for tracking member availability across platforms, including map builder, entry objects, assembly contexts, and signature generation utilities
SdkDocGenerator.cs Main execution flow updated to build platform maps upfront, generate exclusive content, and provide legacy fallback path
GenerationManifest.cs Extended to support platform maps, supplemental manifests, and exclusive page generation
GeneratorOptions.cs Added UseLegacySupplemental option with deprecation notice for rollback safety
ReflectionWrappers.cs Added IsolatedAssemblyLoadContext for loading same-named assemblies from different platforms
NDocUtilities.cs Extended signature generation helpers and added duplicate key protection for multi-platform doc loading
ClassWriter.cs Updated to merge supplemental methods from other platforms into class documentation pages
BaseWriter.cs Added platform display name mapping for user-friendly badge rendering
CommandLineParser.cs Added CLI flag for legacy supplemental mode
SDKDocGeneratorLib.csproj Added System.Runtime.Loader dependency for assembly isolation
sdkstyle.css Minor formatting fix (removed trailing whitespace)

@AlexDaines AlexDaines marked this pull request as draft February 5, 2026 18:32
@AlexDaines AlexDaines force-pushed the adaines/unified-platform-map branch from 70f14c9 to a2ed6fa Compare March 17, 2026 17:59
@AlexDaines AlexDaines requested a review from Copilot March 19, 2026 17:10
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 16 out of 16 changed files in this pull request and generated 11 comments.

@AlexDaines AlexDaines marked this pull request as ready for review March 20, 2026 17:10
@AlexDaines AlexDaines requested a review from boblodgett March 23, 2026 20:26
@GarrettBeatty GarrettBeatty self-requested a review March 26, 2026 23:56
@AlexDaines AlexDaines force-pushed the adaines/unified-platform-map branch from b6ee456 to 2cae95d Compare March 31, 2026 20:15
@GarrettBeatty
Copy link
Copy Markdown
Contributor

can you include screenshots of the before/after docs that get generated

Copy link
Copy Markdown
Contributor

@GarrettBeatty GarrettBeatty left a comment

Choose a reason for hiding this comment

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

one other small comment

@AlexDaines AlexDaines force-pushed the adaines/unified-platform-map branch from c4c92f3 to 177b501 Compare April 1, 2026 15:44
@dscpinheiro
Copy link
Copy Markdown
Contributor

Is this in the dry-run output expected?

EXEC : warning : Failed to scan netcoreapp3.1: Unable to load one or more of the requested types. [C:\codebuild\tmp\output\src974\src\s3\00\aws-sdk-net\buildtools\doc-build.proj]

@AlexDaines AlexDaines requested a review from GarrettBeatty April 1, 2026 20:13
GarrettBeatty
GarrettBeatty previously approved these changes Apr 2, 2026
Copy link
Copy Markdown
Contributor

@GarrettBeatty GarrettBeatty left a comment

Choose a reason for hiding this comment

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

talked via slack and showed screenshot of the diff. alex will upload to pr description.

can you re-run the dry run before merging

@AlexDaines
Copy link
Copy Markdown
Contributor Author

Is this in the dry-run output expected?

EXEC : warning : Failed to scan netcoreapp3.1: Unable to load one or more of the requested types. [C:\codebuild\tmp\output\src974\src\s3\00\aws-sdk-net\buildtools\doc-build.proj]

Yes expected. New from this pr. The platform scanner loads DLLs to reflect over types, (unlike the current generator which only reads XML doc files). netcoreapp3.1 throws a ReflectionTypeLoadException because of missing dependencies in the build env. The catch block at PlatformMapBuilder.cs:117 handles it and moves on. net8.0 and net472 both load normally

The SDK doc generator previously used net472 as the sole source of all
APIs. H2 eventstream APIs (e.g., TranscribeStreaming's StartTranscription)
only exist in the net8.0 target and get zero API reference documentation.

This adds a PlatformMap subsystem that scans multiple target frameworks
and generates documentation for platform-exclusive APIs:

- PlatformMapBuilder: Scans assemblies from each target framework using
  isolated assembly load contexts to build a cross-platform member index
- PlatformAvailabilityMap: Queryable map of which members exist on which
  platforms, with wrapper-based lookup for page generation
- PlatformAssemblyContext: Manages per-platform assembly loading with
  proper isolation and disposal
- MemberSignature: Deterministic signature generation for cross-platform
  member identity comparison
- PlatformMemberEntry: Per-member platform availability tracking

Key design decisions:
- Uses FullName comparison for cross-assembly type identity (Equals()
  fails across assembly load contexts)
- Inherited members attributed to their declaring type, not every
  derived class, preventing false exclusive method proliferation
- Per-service exception handling wraps map building for resilience
- First-wins cache strategy in NDocUtilities prevents cross-platform
  assembly interference

Also includes minor NDocUtilities improvement for rendering <list>,
<item>, <term>, and <description> XML doc elements to HTML.

Addresses DOTNET-8085. Design: DOTNET-8116.
Tests cover:
- MemberSignature utility methods (GetMemberType, GetMemberName,
  GetDeclaringTypeName, ExtractMethodName) and delegation consistency
- PlatformAvailabilityMap query behavior with hand-crafted test data:
  universal members, exclusive members, platform case insensitivity,
  statistics, disposal, and edge cases
- NDoc signature generation gaps: array parameters, nested generics,
  parameterless and parameterized constructor signatures

Adds InternalsVisibleTo for test access to internal PlatformAvailabilityMap
constructor.
- Add null check for coreManifest before accessing its assembly context
  to prevent NullReferenceException when Core assembly is absent
- Correct misleading "first-wins ensures primary platform precedence"
  comment: docIds are per-service+platform, so cache entries never
  collide across platforms; the guard is a de-duplication check for
  same (service, platform) pair
- Remove unused methodName variable in FindMethodInAssembly (PlatformMapBuilder)
- Replace ad-hoc signature format with MemberSignature.ForMethod in ClassWriter
  supplemental method dedup (guards against null FullName on generic type params)
- Revert unrelated using System addition in GeneratorOptions.cs
- Revert whitespace-only changes in sdkstyle.css
- Prevent discarding ManifestAssemblyContext when platform map has
  exclusive members that need it for page generation (NullReferenceException)
- Remove unused ExclusivePlatform property from PlatformMemberEntry
- Simplify platform lookup in ResolveExclusiveMethodWrappers using
  FirstOrDefault (all platforms already filtered to non-primary)
- Remove unused InfoVerbose overloads from SdkDocGenerator
@AlexDaines AlexDaines force-pushed the adaines/unified-platform-map branch 2 times, most recently from 4d15116 to 3bf966b Compare April 6, 2026 00:05
bool isVerbose)
{
if (string.IsNullOrEmpty(serviceName))
throw new ArgumentNullException(nameof(serviceName));
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.

Non-blocking but ArgumentNullException is misleading because it can also be empty on all of these except platformsToScan. ArgumentException with information that it could be null or empty would have been more accurate.

@AlexDaines AlexDaines merged commit 4a96444 into development Apr 6, 2026
6 checks passed
@dscpinheiro dscpinheiro deleted the adaines/unified-platform-map branch April 6, 2026 16:06
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.

5 participants