-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow for XML documentation comments on DU Case fields #948
Comments
If this is approved, I have an RFC and implementation ready to go. |
I like this syntax. Could it apply to regular class constructors too? |
@baronfel Thinking about this with respect to three things
On (1) the question is whether we should allow this on other similar language constructs, in particular
If we add what you've shown then I think there becomes an expectation that
also works. I'm not opposed to making this work but if we do one I feel we should do the other. However that's a big job. An alternative is that we use what we already use for parameters, namely the /// <summary>Describes F# syntax for type parameter applications to a base type.</summary>
/// <param name="typeName">the base type to which type arguments are being applied</param>
/// <param name="lessRange">the range of the `<` token, signifying the start of the type arguments list</param>
| App of
typeName: SynType *
lessRange: range option *
... To be honest this does feel like the orthogonal way to do things from a language design consistency point of view. There are some complications though - the implementation would have to extract and associate these docs with the union field specs. Also we would need the completeness checking for parameter names for docs to apply to union cases as well. On (3), some relevant code is here and here and here. Today, for a multi-case union type module M
type A =
/// ABC
| ABC of xyz: int * def: string
/// DEF
| ABC2 of xyz: int * def: string we're emitting the docs into the XML file as the generated type for each case: <member name="T:M.A.ABC2"><summary>DEF</summary></member>
<member name="T:M.A.ABC"><summary>ABC</summary></member> This is not really perfect from - it should also really be attached to the module M
type A =
/// ABC
| ABC of xyz: int * def: string we're actually emitting a bad documentation file referencing a non-existent type
The underlying problem here is that the "Erase Unions" part of the compiler just isn't doing anything with the docs, and the CML doc file writer was written to just emit whatever information. Now, looking at your addition I have a similar concern - currently these docs will not be written to the XML file at all. So I think at the very minimum this code would need to be adjusted to write docs for the union field to the XML file. You would also need to adjust this code to actually populate the |
So basically, this suggestion raises questions about both union case docs and parameter docs - and whatever we do we should do systematically |
Your comments echo a lot of what @charlesroddie and I were discussing offline with his comment. For what it's worth, I was looking at this mainly as a way to plug a gap that currently exists in terms of DU documentation compared to how record fields can be independenly documented, as an intermediate step towards the kind of holistic parameter-handling that you speak of. It would be lovely to fold parameter documentation into constructors where appropriate in a more general fashion, but it would in my opinion require a significant chunk of work around the structure of xml documentation as you point out. Regarding the technical aspects, I have been able to get the parser and xmldoc writer plumbed through and have an RFC describing the changes. It's pretty much exactly as you describe in terms of work, the only other change is slightly modifying the parser to collect and flow through the PreXmlDoc. My overall thought process was something like:
|
On the alternative of allowing the If we allowed that syntax then I'd want to be able to 'project' subsets of the source XML based on the viewer's context, I think. |
I've got a prototype implementation of this proposal at my fork for reference. Should the 'need to attach Union Case docs to the NewABC' members generated by the compiler portion of your comments be treated as a bug in the existing implementation? If so I'd be happy to write it up and begin looking at an implementation independently of this suggestion. |
@baronfel TBH the prototype looks good. In balance I think I'm ok with going ahead with your proposal even if the most "natural" approach would be to use
Yes, I think so |
Can we generalize this feature to make it work on not only DU fields, but also on parts of any declaration in general? i.e.
cf. how Haskell does it: https://haskell-haddock.readthedocs.io/en/latest/markup.html#documenting-parts-of-a-declaration |
@srid currently this can be done for record fields. Given the F# code: /// An event describing a change to a text document. If range and rangeLength are omitted
/// the new text is considered to be the full content of the document.
type TextDocumentContentChangeEvent = {
/// The range of the document that changed.
Range: Range option
/// The length of the range that got replaced.
RangeLength: int option
/// The new text of the range/document.
Text: string
} hovering over the definition or usage of the |
I'll mark this as approved, though it is a surprisingly difficult area to make progress on |
I propose we extend the parser and language spec to allow for DU Case fields to accept XML documentation comments like record fields already do. For example, allowing
The existing way of approaching this problem in F# is to describe each of the fields in the overall DU Case type constructor, but this interacts poorly with tooling (the DU fields themselves have no documentation, so it's trickier to display the docs for the parent type when docs for the field are requested) and is less maintainable because it separates the docs from the element they describe.
The existing way can be seen on several DUs used in the compiler itself: https://github.com/dotnet/fsharp/blob/main/src/fsharp/SyntaxTree.fs#L422-L431
It would be much nicer in my opinion to be able to write something like the following instead, and have access to these details on a field-by-field basis when consuming these types:
Pros and Cons
The advantages of making this adjustment to F# are a more uniform experience for authoring comments on Union types.
The disadvantages of making this adjustment to F# are a bit of increased work done by
Extra information
Estimated cost (XS, S, M, L, XL, XXL): S
Related suggestions: None that I could find
Affidavit (please submit!)
Please tick this by placing a cross in the box:
Please tick all that apply:
For Readers
If you would like to see this issue implemented, please click the 👍 emoji on this issue. These counts are used to generally order the suggestions by engagement.
The text was updated successfully, but these errors were encountered: