Skip to content

Package reusable cDAC usage graph analyzer - #132234

Open
max-charlamb wants to merge 4 commits into
dotnet:mainfrom
max-charlamb:maxcharlamb/cdac-usage-package
Open

Package reusable cDAC usage graph analyzer#132234
max-charlamb wants to merge 4 commits into
dotnet:mainfrom
max-charlamb:maxcharlamb/cdac-usage-package

Conversation

@max-charlamb

Copy link
Copy Markdown
Member

Summary

  • package the existing cDAC usage graph analyzer for reuse by other repositories
  • replace the CoreCLR-specific analysis entry point with configurable project and registration inputs
  • support contract registrations that return default-valued struct implementations
  • update the runtime CLI and usage tests to use the configurable analysis options

Testing

  • CdacUsageGraph.Tests (85 passed)
  • Microsoft.Diagnostics.DataContractReader.Usage.Tests (4 passed)
  • regenerated cDAC contract documentation (no changes)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 95c4aedd-f09e-42d7-8c9f-f439297576a6
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 4 pipeline(s).
12 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @steveisok, @tommcdon, @dotnet/dotnet-diag
See info in area-owners.md if you want to be subscribed.

@max-charlamb
max-charlamb marked this pull request as ready for review August 12, 2026 21:08
@max-charlamb
max-charlamb requested review from noahfalk and rcj1 August 12, 2026 21:08
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 4 pipeline(s).
12 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

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.

Pull request overview

This PR packages the existing cDAC usage graph analyzer for reuse by making its analysis entrypoints configurable (contracts project path + registration type), updating the CLI and tests accordingly, and expanding registration discovery to cover default-valued struct registrations.

Changes:

  • Replace the CoreCLR-rooted analysis entrypoint with UsageGraphAnalysisOptions (project path, registration type name, source root, optional output directory).
  • Update the CLI pipeline and tests to use the configurable analysis options and project-loading APIs.
  • Extend contract registration discovery to recognize default(T) returns in registration factories.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/native/managed/cdac/tools/CdacUsageGraph/tests/CdacUsageGraph.Tests/UsageWalkerIntegrationTests.cs Updates integration test to run analysis via configurable options and explicit contracts project path.
src/native/managed/cdac/tools/CdacUsageGraph/tests/CdacUsageGraph.Tests/DataTypeIndexTests.cs Updates parser call sites and adds a test covering default-valued struct registration discovery.
src/native/managed/cdac/tools/CdacUsageGraph/src/CdacUsageGraph/UsageGraphAnalyzer.cs Introduces UsageGraphAnalysisOptions and updates public analyzer entrypoint to accept options.
src/native/managed/cdac/tools/CdacUsageGraph/src/CdacUsageGraph/Docs/DocGenerator.cs Minor descriptor-key parsing tweak (LastIndexOf('.')).
src/native/managed/cdac/tools/CdacUsageGraph/src/CdacUsageGraph/Docs/DocDescriptorOverrides.cs Minor descriptor-key validation tweak (LastIndexOf('.')).
src/native/managed/cdac/tools/CdacUsageGraph/src/CdacUsageGraph/Docs/DocDescriptorMeanings.cs Minor descriptor-key validation tweak (LastIndexOf('.')).
src/native/managed/cdac/tools/CdacUsageGraph/src/CdacUsageGraph/Discovery/ContractRegistrationParser.cs Makes registration discovery configurable and adds handling for default(T) returns.
src/native/managed/cdac/tools/CdacUsageGraph/src/CdacUsageGraph/Compilation/CdacCompilationLoader.cs Replaces root-based loading with explicit LoadProject(projectPath).
src/native/managed/cdac/tools/CdacUsageGraph/src/CdacUsageGraph/Commands.cs Updates CLI wiring to construct and pass UsageGraphAnalysisOptions.
src/native/managed/cdac/tools/CdacUsageGraph/src/CdacUsageGraph/CdacUsageGraph.csproj Renames assembly, switches to $(CDacTfm), enables packing, and updates Roslyn package version properties.
src/native/managed/cdac/tools/CdacUsageGraph/src/CdacUsageGraph/AnalysisPipeline.cs Refactors pipeline to use UsageGraphAnalysisOptions, including output-dir handling.
src/native/managed/cdac/tools/CdacUsageGraph/src/CdacUsageGraph/AnalysisOptions.cs Removes old CLI-only AnalysisOptions record in favor of shared analysis options.
src/native/managed/cdac/tests/UsageTests/UsageGraphFixture.cs Updates usage tests to use UsageGraphAnalysisOptions with explicit project + registration type.
src/native/managed/cdac/tests/UsageTests/Microsoft.Diagnostics.DataContractReader.Usage.Tests.csproj Removes JsonSerializerIsReflectionEnabledByDefault override from the test project.

Comment on lines +83 to +97
foreach (IDefaultValueOperation defaultValue in inv.Descendants().OfType<IDefaultValueOperation>())
{
if (defaultValue.Type is INamedTypeSymbol impl &&
comparer.Equals(impl.ContainingAssembly, compilation.Assembly) &&
compilation.IsAssignableTo(impl, iface) &&
compilation.IsAssignableTo(impl, iContract))
{
registrations.Add(new ContractRegistration(
new ContractVersion(new ContractInterface(iface.Name), version),
iface,
impl,
impl.InstanceConstructors.Single(
candidate => candidate.Parameters.Length == 0)));
}
}
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 95c4aedd-f09e-42d7-8c9f-f439297576a6
Copilot AI review requested due to automatic review settings August 12, 2026 21:39

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.

Pull request overview

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

Suppressed comments (1)

src/native/managed/cdac/tools/CdacUsageGraph/src/CdacUsageGraph/Discovery/ContractRegistrationParser.cs:97

  • The default-value registration path treats any default(T) as a concrete implementation and then assumes it can obtain a parameterless constructor. For reference types, default(T) is null (not an instance) and InstanceConstructors.Single(...) can throw if there is no parameterless ctor, so this can either mis-record registrations or crash analysis.

Restrict this path to value-type implementations (structs) and avoid Single throwing on unexpected shapes.

                    foreach (IDefaultValueOperation defaultValue in inv.Descendants().OfType<IDefaultValueOperation>())
                    {
                        if (defaultValue.Type is INamedTypeSymbol impl &&
                            comparer.Equals(impl.ContainingAssembly, compilation.Assembly) &&
                            compilation.IsAssignableTo(impl, iface) &&

Record the ManagedTypeSource layout fallback discovered through generic ContractRegistry lookups.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 95c4aedd-f09e-42d7-8c9f-f439297576a6
Copilot AI review requested due to automatic review settings August 13, 2026 15:29

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.

Pull request overview

Copilot reviewed 40 out of 40 changed files in this pull request and generated no new comments.

Suppressed comments (2)

src/native/managed/cdac/tools/CdacUsageGraph/src/CdacUsageGraph/UsageGraphAnalyzer.cs:17

  • This introduces new public API surface (UsageGraphAnalyzer.Analyze(UsageGraphAnalysisOptions) and UsageGraphAnalysisOptions). Per repo process, new public APIs need a linked issue with the api-approved label; if this isn’t yet approved, keep the API internal until the approval is in place.
    src/native/managed/cdac/tools/CdacUsageGraph/src/CdacUsageGraph/Discovery/ContractRegistrationParser.cs:97
  • default(T) registrations can yield IDefaultValueOperation where Type is the interface itself (e.g., default(ITest)), which would make impl.InstanceConstructors.Single(...) throw (interfaces have no instance constructors). The default-value path should be constrained to value-type implementations (or otherwise ensure a parameterless ctor exists) before adding a registration.

Stop traversal at the generated LayoutSet helper so its ManagedTypeSource fallback is not attributed to every IData consumer.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 95c4aedd-f09e-42d7-8c9f-f439297576a6
Copilot AI review requested due to automatic review settings August 13, 2026 15:46

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.

Pull request overview

Copilot reviewed 17 out of 17 changed files in this pull request and generated no new comments.

Suppressed comments (2)

src/native/managed/cdac/tests/UsageTests/Microsoft.Diagnostics.DataContractReader.Usage.Tests.csproj:6

  • This project is the only cDAC test project that no longer disables reflection-based System.Text.Json serialization by default. Other cDAC projects keep JsonSerializerIsReflectionEnabledByDefault set to false (e.g. src/native/managed/cdac/tests/DumpTests/Microsoft.Diagnostics.DataContractReader.DumpTests.csproj:8). Consider restoring it here to keep the same runtime behavior/coverage across the cDAC test suite.
  <PropertyGroup>
    <TargetFramework>$(NetCoreAppToolCurrent)</TargetFramework>
    <Nullable>enable</Nullable>
    <IsTestProject>true</IsTestProject>
    <AssemblyName>Microsoft.Diagnostics.DataContractReader.Usage.Tests</AssemblyName>

src/native/managed/cdac/tools/CdacUsageGraph/src/CdacUsageGraph/Discovery/ContractRegistrationParser.cs:97

  • The default-value registration discovery treats any default(T) found under a Register<IFace> invocation as an implementation type and then unconditionally calls impl.InstanceConstructors.Single(...). This can (1) incorrectly treat reference-type default(T) (which is null) as a registration and (2) throw if the default is target-typed to an interface/abstract type (no instance constructors). Restrict this path to value-type implementations and only add a registration when a parameterless ctor symbol is available.
                    foreach (IDefaultValueOperation defaultValue in inv.Descendants().OfType<IDefaultValueOperation>())
                    {
                        if (defaultValue.Type is INamedTypeSymbol impl &&
                            comparer.Equals(impl.ContainingAssembly, compilation.Assembly) &&
                            compilation.IsAssignableTo(impl, iface) &&
                            compilation.IsAssignableTo(impl, iContract))
                        {
                            registrations.Add(new ContractRegistration(
                                new ContractVersion(new ContractInterface(iface.Name), version),
                                iface,
                                impl,
                                impl.InstanceConstructors.Single(
                                    candidate => candidate.Parameters.Length == 0)));
                        }

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants