diff --git a/src/Docfx.Dotnet/ManagedReference/Resolvers/SetDerivedClass.cs b/src/Docfx.Dotnet/ManagedReference/Resolvers/SetDerivedClass.cs index cb23287b342..c134113a26a 100644 --- a/src/Docfx.Dotnet/ManagedReference/Resolvers/SetDerivedClass.cs +++ b/src/Docfx.Dotnet/ManagedReference/Resolvers/SetDerivedClass.cs @@ -1,6 +1,7 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Runtime.InteropServices; using Docfx.DataContracts.ManagedReference; namespace Docfx.Dotnet; @@ -22,6 +23,7 @@ private void UpdateDerivedClassMapping(List items, Dictionary()) { + // Handle class inheritance var inheritance = item.Inheritance; if (inheritance is { Count: > 0 }) { @@ -35,15 +37,30 @@ private void UpdateDerivedClassMapping(List items, Dictionary derivedClasses)) - { + ref var derivedClasses = ref CollectionsMarshal.GetValueRefOrAddDefault(_derivedClassMapping, superClass, out var exists); + if (exists) derivedClasses.Add(item.Name); - } else - { - _derivedClassMapping.Add(superClass, [item.Name]); - } + derivedClasses = [item.Name]; + } + } + + // Handle interface implementations + var implements = item.Implements; + if (implements is { Count: > 0 }) + { + var superClass = implements[implements.Count - 1]; + + if (reference.TryGetValue(superClass, out var referenceItem)) + { + superClass = referenceItem.Definition ?? superClass; } + + ref var derivedClasses = ref CollectionsMarshal.GetValueRefOrAddDefault(_derivedClassMapping, superClass, out var exists); + if (exists) + derivedClasses.Add(item.Name); + else + derivedClasses = [item.Name]; } } } @@ -52,13 +69,16 @@ private void AppendDerivedClass(List items) { foreach (var item in items ?? Enumerable.Empty()) { - if (item.Type == MemberType.Class) + switch (item.Type) { - if (_derivedClassMapping.TryGetValue(item.Name, out List derivedClasses)) - { - derivedClasses.Sort(); - item.DerivedClasses = derivedClasses; - } + case MemberType.Class: + case MemberType.Interface: + if (_derivedClassMapping.TryGetValue(item.Name, out List derivedClasses)) + { + derivedClasses.Sort(); + item.DerivedClasses = derivedClasses; + } + continue; } } } diff --git a/test/docfx.Snapshot.Tests/SamplesTest.CSharp/api/CSharp11.StaticAbstractMembersInInterfaces.IGetNext-1.html.view.verified.json b/test/docfx.Snapshot.Tests/SamplesTest.CSharp/api/CSharp11.StaticAbstractMembersInInterfaces.IGetNext-1.html.view.verified.json index a550122c93e..8ce41735e97 100644 --- a/test/docfx.Snapshot.Tests/SamplesTest.CSharp/api/CSharp11.StaticAbstractMembersInInterfaces.IGetNext-1.html.view.verified.json +++ b/test/docfx.Snapshot.Tests/SamplesTest.CSharp/api/CSharp11.StaticAbstractMembersInInterfaces.IGetNext-1.html.view.verified.json @@ -396,6 +396,24 @@ } ] }, + "derivedClasses": [ + { + "isEii": false, + "isExtensionMethod": false, + "specName": [ + { + "lang": "csharp", + "value": "" + }, + { + "lang": "vb", + "value": "" + } + ], + "level": 0, + "index": 1 + } + ], "level": 0, "_systemKeys": [ "uid", diff --git a/test/docfx.Snapshot.Tests/SamplesTest.Seed/api/BuildFromProject.Class1.IIssue8948.html.view.verified.json b/test/docfx.Snapshot.Tests/SamplesTest.Seed/api/BuildFromProject.Class1.IIssue8948.html.view.verified.json index 29157d2d34e..838e806223b 100644 --- a/test/docfx.Snapshot.Tests/SamplesTest.Seed/api/BuildFromProject.Class1.IIssue8948.html.view.verified.json +++ b/test/docfx.Snapshot.Tests/SamplesTest.Seed/api/BuildFromProject.Class1.IIssue8948.html.view.verified.json @@ -305,6 +305,24 @@ } ] }, + "derivedClasses": [ + { + "isEii": false, + "isExtensionMethod": false, + "specName": [ + { + "lang": "csharp", + "value": "" + }, + { + "lang": "vb", + "value": "" + } + ], + "level": 0, + "index": 1 + } + ], "level": 0, "_appName": "Seed", "_appTitle": "docfx seed website", diff --git a/test/docfx.Snapshot.Tests/SamplesTest.Seed/api/BuildFromProject.Inheritdoc.Issue9736.IJsonApiOptions.html.view.verified.json b/test/docfx.Snapshot.Tests/SamplesTest.Seed/api/BuildFromProject.Inheritdoc.Issue9736.IJsonApiOptions.html.view.verified.json index d0666050a9e..49fe6065d99 100644 --- a/test/docfx.Snapshot.Tests/SamplesTest.Seed/api/BuildFromProject.Inheritdoc.Issue9736.IJsonApiOptions.html.view.verified.json +++ b/test/docfx.Snapshot.Tests/SamplesTest.Seed/api/BuildFromProject.Inheritdoc.Issue9736.IJsonApiOptions.html.view.verified.json @@ -348,6 +348,24 @@ } ] }, + "derivedClasses": [ + { + "isEii": false, + "isExtensionMethod": false, + "specName": [ + { + "lang": "csharp", + "value": "" + }, + { + "lang": "vb", + "value": "" + } + ], + "level": 0, + "index": 1 + } + ], "level": 0, "_appName": "Seed", "_appTitle": "docfx seed website", diff --git a/test/docfx.Snapshot.Tests/SamplesTest.Seed/api/CatLibrary.IAnimal.html.view.verified.json b/test/docfx.Snapshot.Tests/SamplesTest.Seed/api/CatLibrary.IAnimal.html.view.verified.json index 3d76c107a9a..daecc8f53e9 100644 --- a/test/docfx.Snapshot.Tests/SamplesTest.Seed/api/CatLibrary.IAnimal.html.view.verified.json +++ b/test/docfx.Snapshot.Tests/SamplesTest.Seed/api/CatLibrary.IAnimal.html.view.verified.json @@ -1099,6 +1099,24 @@ } ] }, + "derivedClasses": [ + { + "isEii": false, + "isExtensionMethod": false, + "specName": [ + { + "lang": "csharp", + "value": "" + }, + { + "lang": "vb", + "value": "" + } + ], + "level": 0, + "index": 1 + } + ], "level": 0, "conceptual": "

Welcome to the Animal world!

\n", "_appName": "Seed",