Documentare il codice con commenti XML

È possibile produrre documentazione da commenti di codice a barre (///) in F#. I commenti XML possono precedere le dichiarazioni nei file di codice (con estensione .fs) o nei file di firma (.fsi).

I commenti della documentazione XML sono un tipo speciale di commento, aggiunto sopra la definizione di qualsiasi tipo o membro definito dall'utente. Sono speciali perché possono essere elaborati dal compilatore per generare un file di documentazione XML in fase di compilazione. Il file XML generato dal compilatore può essere distribuito insieme all'assembly .NET affinché gli IDE possano utilizzare i tooltip per visualizzare rapidamente informazioni sui tipi o sui membri. Inoltre, il file XML può essere eseguito tramite strumenti come fsdocs per generare siti Web di riferimento api.

Per impostazione predefinita, i commenti della documentazione XML vengono ignorati dal compilatore. Per modificare questa impostazione, impostare --warnon:3390. Il compilatore verificherà quindi la sintassi del codice XML e i parametri a cui si fa riferimento nei tag <param> e <paramref>.

È possibile abilitare questo avviso nel file di progetto aggiungendo un <WarnOn> elemento a una <PropertyGroup> sezione:

<WarnOn>3390</WarnOn>

È possibile generare il file XML in fase di compilazione eseguendo una delle operazioni seguenti:

  • È possibile aggiungere un elemento GenerateDocumentationFile alla sezione <PropertyGroup> del file di progetto .fsproj, che genera un file XML nella directory del progetto con lo stesso nome file radice dell'assembly. Per esempio:

    <GenerateDocumentationFile>true</GenerateDocumentationFile>
    

    Per ulteriori informazioni, vedere la proprietà GenerateDocumentationFile.

  • Se stai sviluppando un'applicazione usando Visual Studio, fai clic con il pulsante destro del mouse sul progetto e seleziona Proprietà. Nella finestra di dialogo delle proprietà, selezionare la scheda Build e spuntare la casella file di documentazione XML. È anche possibile modificare il percorso in cui il compilatore scrive il file.

Esistono due modi per scrivere commenti della documentazione XML: con e senza tag XML. Entrambi usano commenti con tripla barra.

Commenti senza tag XML

Se un commento /// non inizia con un <, l'intero testo del commento viene preso come documentazione di riepilogo per il costrutto di codice che segue immediatamente. Utilizzare questo metodo quando si desidera scrivere solo un breve riepilogo per ogni costrutto.

Il commento viene codificato in XML durante la preparazione della documentazione, quindi non è necessario applicare l'escape a caratteri come <, >e &. Se non si specifica un tag di riepilogo in modo esplicito, non è consigliabile specificare altri tag, ad esempio param o restituisce tag.

Annotazioni

Quando si usano commenti senza tag XML, qualsiasi markup incluso (ad esempio tag HTML o sintassi simile a XML) non verrà analizzato o controllato dal compilatore o dagli strumenti F#. Alcuni strumenti esterni come GitHub potrebbero tentare di analizzare il markup, ma possono non riuscire se la sintassi contiene errori. Se è necessario usare tag XML nella documentazione, eseguire il wrapping dei commenti con tag XML appropriati, <summary> ad esempio per assicurarsi che vengano convalidati dal compilatore quando --warnon:3390 è abilitato.

Nell'esempio seguente viene illustrato il metodo alternativo, senza tag XML. In questo esempio l'intero testo nel commento viene considerato un riepilogo.

/// Creates a new string whose characters are the result of applying
/// the function mapping to each of the characters of the input string
/// and concatenating the resulting strings.
val collect : (char -> string) -> string -> string

Commenti con tag XML

Se un corpo del commento inizia con < (in genere <summary>), viene considerato come un corpo di commento in formato XML usando tag XML. Questo secondo approccio consente di specificare note separate per un breve riepilogo, osservazioni aggiuntive, documentazione per ogni parametro e parametro di tipo e eccezioni generate e una descrizione del valore restituito.

Di seguito è riportato un commento tipico della documentazione XML in un file di firma:

/// <summary>Builds a new string whose characters are the results of applying the function <c>mapping</c>
/// to each of the characters of the input string and concatenating the resulting
/// strings.</summary>
/// <param name="mapping">The function to produce a string from each character of the input string.</param>
///<param name="str">The input string.</param>
///<returns>The concatenated string.</returns>
///<exception cref="System.ArgumentNullException">Thrown when the input string is null.</exception>
val collect : (char -> string) -> string -> string

Se si usano tag XML, nella tabella seguente vengono descritti i tag esterni riconosciuti nei commenti di codice XML F#.

Sintassi dei tag Descrizione
<summary> testo</summary> Specifica che il testo è una breve descrizione dell'elemento del programma. La descrizione è in genere una o due frasi.
<remarks> testo</remarks> Specifica che il testo fornisce informazioni supplementari sull'elemento del programma.
<param name=" nome">descrizione</param> Specifica il nome e la descrizione per un parametro di funzione o metodo.
<typeparam name=" nome">descrizione</typeparam> Specifica il nome e la descrizione per un parametro di tipo.
<returns> testo</returns> Specifica che il testo descrive un valore restituito di una funzione o di un metodo.
<exception cref=" tipo">descrizione</exception> Specifica il tipo di eccezione che può essere generata e le circostanze in cui viene generata.
<seealso cref=" riferimento"/> Specifica un collegamento Vedere anche alla documentazione per un altro tipo. Il riferimento è il nome come appare nel file di documentazione XML. I collegamenti "Vedi Anche" vengono visualizzati di solito nella parte inferiore di una pagina della documentazione.
<include file="path.xml" path="XPath"/> A partire dal compilatore F# 11, include elementi XML selezionati da un file esterno nella documentazione generata.
<inheritdoc/> Richiede la documentazione ereditata dagli strumenti compatibili. Il tag rimane nel codice XML generato dal compilatore.

Nella tabella seguente vengono descritti i tag da usare nelle sezioni di descrizione:

Sintassi dei tag Descrizione
<para> testo</para> Specifica un paragrafo di testo. Viene utilizzato per separare il testo all'interno del tag delle note .
<code> testo</code> Specifica che il testo è costituito da più righe di codice. Questo tag può essere usato dai generatori di documentazione per visualizzare il testo in un tipo di carattere appropriato per il codice.
<paramref name=" nome"/> Specifica un riferimento a un parametro nello stesso commento della documentazione.
<typeparamref name=" nome"/> Specifica un riferimento a un parametro di tipo nello stesso commento della documentazione.
<c> testo</c> Specifica che testo è codice inline. Questo tag può essere usato dai generatori di documentazione per visualizzare il testo in un tipo di carattere appropriato per il codice.
<see cref=" testo di riferimento"></see> Specifica un collegamento inline a un altro elemento del programma. Il riferimento è il nome come appare nel file di documentazione XML. Il testo è il testo visualizzato nel collegamento.

Tag definiti dall'utente

I tag precedenti rappresentano quelli riconosciuti dal compilatore F# e dagli strumenti tipici dell'editor F#. Tuttavia, un utente è libero di definire i propri tag. Strumenti come fsdocs supportano tag aggiuntivi come <namespacedoc>. Strumenti di generazione di documentazione personalizzati o interni possono essere utilizzati con i tag standard e supportano più formati di output, da HTML a PDF.

Controllo in fase di compilazione

Quando --warnon:3390 è abilitato, il compilatore verifica la sintassi del codice XML e i parametri a cui si fa riferimento nei tag <param> e <paramref>.

Documentazione di costrutti F#

I costrutti F# come moduli, membri, casi di unione e campi di record sono documentati da un commento /// immediatamente prima della loro dichiarazione. Se necessario, i costruttori impliciti delle classi sono documentati assegnando un commento /// prima dell'elenco di argomenti. Per esempio:

/// This is the type
type SomeType
      /// This is the implicit constructor
      (a: int, b: int) =

    /// This is the member
    member _.Sum() = a + b

Riutilizzare ed ereditare la documentazione

Per mantenere le osservazioni condivise una sola volta, inserirle accanto all'origine shared.xml :

<docs>
  <tracking>
    <remarks>An unrecognized tracking identifier has status Unknown.</remarks>
  </tracking>
</docs>

Entrambi i membri selezionano gli elementi con la stessa espressione XPath:

/// <summary>Find the latest status of a shipment.</summary>
/// <include file="shared.xml" path="/docs/tracking/*"/>
let status trackingId =
    if trackingId = "SHP-1042" then "Dispatched" else "Unknown"

/// <summary>Find the latest statuses of several shipments.</summary>
/// <include file="shared.xml" path="/docs/tracking/*"/>
let statuses trackingIds =
    trackingIds |> List.map (fun id -> id, status id)

Abilitare GenerateDocumentationFile o passare --doc:Tracking.xml. A partire da F# 11, le voci generate contengono le osservazioni selezionate e i riepiloghi locali, non solo i tag.

Il progetto di esempio tiene traccia del codice XML come input di compilazione in modo da modificare la rigenerazione dei trigger. Non è necessario alcun consenso esplicito per la versione della lingua. Include l'espansione in XML generato, non informazioni rapide in tempo reale.

Includere la risoluzione e gli errori

I nomi di file relativi vengono risolti prima nella directory del file di origine, quindi nella directory di lavoro del compilatore. Annidato include la risoluzione relativa al file XML che lo contiene. Selezionare elementi, ad esempio /docs/tracking/*, anziché nodi di testo o attributo.

I file mancanti, xml in formato non valido, XPath non validi e cicli generano la diagnostica. Un XPath valido senza corrispondenze mantiene il tag e aggiunge un commento senza alcun avviso. L'elaborazione DTD e la risoluzione XML esterna sono disabilitate; Gli elementi dello spazio dei nomi include esterno rimangono contenuti ordinari. Vedere le informazioni di riferimento per la<include> sintassi XPath.

Documentazione ereditata negli strumenti

Per evitare di copiare la descrizione di un membro di base in ogni override, usare <inheritdoc/>:

[<AbstractClass>]
type TrackingBase() =
    /// <summary>Find the latest status of a shipment.</summary>
    abstract Status: trackingId: string -> string

type TrackingService() =
    inherit TrackingBase()
    /// <inheritdoc/>
    override _.Status trackingId = status trackingId

Gli strumenti F# 11 e FSharp.Compiler.Service espongono la descrizione ereditata per TrackingService.Status. Il compilatore lascia <inheritdoc/> il file XML generato per gli strumenti downstream da interpretare. L'aggiornamento di Core da solo non aggiorna il sistema di risoluzione di un editor.

Usare il primo livello <inheritdoc/>, non un tag annidato all'interno <summary>di . I casi espliciti cref, costruttori e cross-language o tra assembly dipendono dal consumer della documentazione. Usare gli identificatori completi della documentazione XML e controllare lo strumento di destinazione. Consultare il <inheritdoc> riferimento.

Limitazioni

Alcune funzionalità della documentazione XML in C# e altri linguaggi .NET non sono supportate in F#.

  • In F# i riferimenti incrociati devono usare la firma XML completa del simbolo corrispondente, ad esempio cref="T:System.Console". I semplici riferimenti incrociati in stile C#, ad esempio cref="Console", non vengono elaborati in firme XML complete e questi elementi non vengono controllati dal compilatore F#. Alcuni strumenti di documentazione possono consentire l'uso di questi riferimenti incrociati tramite l'elaborazione successiva, ma è consigliabile usare le firme complete.

  • Prima di F# 11, il compilatore copia <include> senza espanderlo. <inheritdoc> richiede comunque un consumer di documentazione per risolvere il contenuto ereditato, come descritto in Riutilizzare ed ereditare la documentazione.

  • I riferimenti incrociati non vengono controllati dal compilatore F#, anche quando viene usato -warnon:3390.

  • I nomi usati nei tag <typeparam> e <typeparamref> non vengono controllati dal compilatore F#, anche quando si usa --warnon:3390.

  • Se la documentazione non è presente, non viene visualizzato alcun avviso, anche quando viene usata --warnon:3390.

Consigli

La documentazione del codice è consigliata per molti motivi. Di seguito sono riportate alcune procedure consigliate, scenari di casi d'uso generali e aspetti da conoscere quando si usano tag di documentazione XML nel codice F#.

  • Abilitare l'opzione --warnon:3390 nel codice per assicurarsi che la documentazione XML sia xml valida.

  • Si consiglia di aggiungere file di firma per separare i lunghi commenti di documentazione XML dall'implementazione.

  • Per garantire la coerenza, tutti i tipi visibili pubblicamente e i relativi membri devono essere documentati. Se dovete farlo, fate tutto.

  • Come minimo, i moduli, i tipi e i relativi membri devono avere un semplice commento /// o un tag <summary>. Negli strumenti di modifica di F#, verrà visualizzata una finestra di tooltip di completamento automatico.

  • Il testo della documentazione deve essere scritto usando frasi complete che terminano con interruzioni complete.

Vedere anche