dotnet / dotnet/docfx

[Bug] xrefs from xrefmaps are not resolved for types defined in CSPROJ ProjectReferences

Open
#9,043 0 comments 1 reaction 0 assignees View on GitHub
dotnet
Dominant language
C#
Stars
4.4k
Forks
890
Avg merge
2h 9m
Merged PRs (30d)
11

Description

**Describe the bug**
xrefmaps are not used for API in CSPROJ ProjectReferences.

**To Reproduce**
Steps to reproduce the behavior:
1. Create a CSPROJ `ParentProject.csproj` that includes a documented public class `ParentClass`.
2. Use DocFX to generate documentation and an xrefmap for ParentProject.
3. Create a CSPROJ `ChildProject.csproj` that includes a documented public class `ChildClass : ParentClass` and a `ProjectReference` to `ParentProject.csproj`
4. Use DocFX to generate documentation for `ChildProject.csproj` *only* (do not directly include `ParentProject.csproj` in the docfx.json) and include the xrefmap for ParentProject.

**Expected behavior**
The API documentation entry for `ChildClass` describes `ParentClass` as its direct ancestor, and `ParentClass` is a cross reference to its entry in the `ParentProject` API documentation website.

**Actual behavior**
The API documentation entry for `ChildClass` describes `ParentClass` as its direct ancestor, but `ParentClass` is not a cross reference at all.

**Context (please complete the following information):**
- OS: Windows
- Docfx version: 2.67.5

**Additional context**
*Deep breath*. The proximate cause of this issue is that DocFX flags `ParentClass` as an _Internal_ API, and does not try to resolve it as an external xref. It does not have an internal href either, because `ParentProject.csproj` is not listed in the DocFX config, so API documentation for `ParentClass` is not part of *this* documentation set.

I got lost in the weeds trying to figure out why `ParentClass` was being marked as internal, when the source code is not *directly* part of any CSPROJ being passed to DocFX for this build. I have hacked around the issue at a later stage of the process, by removing the `!spec.IsSpec` check from the following code (isSpec seems to resolve to IsInternal, which resolves to !IsExternalPath in the model generation code):
```
public void ResolveExternalXRefSpecForNoneSpecsAsync()
{
// remove internal xref.
var uidList =
(from uid in XRef
where !ExternalXRefSpec.ContainsKey(uid) && !XRefSpecMap.ContainsKey(uid)
select uid)
.Concat(
from spec in ExternalXRefSpec.Values
where spec.Href == null && !spec.IsSpec && !XRefSpecMap.ContainsKey(spec.Uid)
select spec.Uid)
.ToList();
```

I wonder if this hack may actually be an improvement independently of treating ProjectReference code as external code. If a `spec.Href` is `null` at this stage of the program, and there's a matching xrefmap entry, it might be better to use the xrefmap entry in any case.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.