mono / api-doc-tools

.NET Reference API Toolchain
MIT License
68 stars 48 forks source link

Duplicate `<Docs>` node is added when using /// <include> #650

Closed jfversluis closed 2 years ago

jfversluis commented 2 years ago

For the .NET MAUI repo we're getting ramped up to publish the API docs. What we did is we first ported over our docs from Xamarin.Forms (the predecessor of .NET MAUI) to .NET MAUI. This resulted in all comments being added like so:

/// <include file="../../docs/Microsoft.Maui.Controls/Button.xml" path="Type[@FullName='Microsoft.Maui.Controls.Button']/Docs" />
public partial class Button : View, IFontElement, ITextElement, IBorderElement, IButtonController, IElementConfiguration<Button>, IPaddingElement, IImageController, IViewController, IButtonElement, IImageElement
{
    const double DefaultSpacing = 10;

    /// <include file="../../docs/Microsoft.Maui.Controls/Button.xml" path="//Member[@MemberName='CommandProperty']/Docs" />
    public static readonly BindableProperty CommandProperty = ButtonElement.CommandProperty;

    // all the rest
}

Newly added docs are added through the "normal" way by just doing it inline. However, when running this through the apidrop pipeline something strange happens and at this point I can only conclude it might be something in mdoc.

If we stick with the button example, the file linked above can be found here. This seems to look fine.

However, when we run it through the pipeline, the result can be found here (mirror here in case you can't access it). Notice how the resulting doc, that ran through mdoc has duplicate <Docs> nodes. The first one always seemingly being "To be added."

<Docs>
    <summary>To be added.</summary>
    <remarks>To be added.</remarks>
    <Docs>
      <summary>A button <see cref="T:Microsoft.Maui.Controls.View" /> that reacts to touch events.</summary>
      <remarks>
      ...

This results in the API docs not being filled correctly as seen here. If we manually tweak the resulting XML to not include those extra <Docs> nodes then it shows up as we expect.

All the inline documentation from code shows up without any issues, so the only explanation I have right now is that it's because we're using the <include> tags. And since the XML resulting from Visual Studio doesn't have the extra formatting it seemingly happens somewhere during the mdoc process.

The set of binaries and XMLs we have been using is attached here. The command that is being executed in the pipeline is: mdoc.exe update -o D:\a\1\s\target_repo\docs\xml -fx D:\a\1\s\source_repo\dotnet-maui -lang docid -index false --debug --delete -L "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\PublicAssemblies" -L "C:\Program Files (x86)\Microsoft.NET\Primary Interop Assemblies" -L "C:\Program Files\WindowsPowerShell\Modules\PackageManagement\1.0.0.1" -L "C:\Program Files\dotnet" -lang vb.net -lang c++/cli -lang fsharp

Curious to hear your thoughts about this. Thanks!

jfversluis commented 2 years ago

Talked with Jonathan Pryor and seems the extra Docs nodes are coming from our side... My bad! 😬

jonpryor commented 2 years ago

Discussed this elsewhere; summarizing here.

The problem is that more wildcards need to be used.

Instead of src/Controls/src/Core/Button.cs:

    /// <include file="../../docs/Microsoft.Maui.Controls/Button.xml" path="Type[@FullName='Microsoft.Maui.Controls.Button']/Docs" />

You should append with /*:

    /// <include file="../../docs/Microsoft.Maui.Controls/Button.xml" path="Type[@FullName='Microsoft.Maui.Controls.Button']/Docs/*" />

See e.g. xamarin/Java.Interop/src/Java.Interop/Java.Interop/IJavaPeerable.cs:

    /// <include file="../Documentation/Java.Interop/IJavaPeerable.xml" path="/docs/member[@name='T:IJavaPeerable']/*" />

<Docs/> is not an element that should ever appear in csc /doc output, and by not appending /* to the include/@path value, the Docs node is copied as-is, resulting in a <Docs/> element in the csc /doc output.