[Bug] xrefs from xrefmaps are not resolved for types defined in CSPROJ ProjectReferences
- 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
Assessment
This issue has not been assessed yet.