microsoft / tsdoc

A doc comment standard for TypeScript
https://tsdoc.org/
MIT License
4.74k stars 131 forks source link

RFC: Add new @link syntax to leverage beta declaration reference format #202

Open rbuckton opened 4 years ago

rbuckton commented 4 years ago

The current TSDoc declaration reference syntax differs from the new proposed declaration reference syntax. I would propose the following additional syntax for {@link} and related tags as a means opt-in to the new proposed declaration reference syntax:

`{` `@link` `{` beta-declaration-reference `}` `}`
`{` `@link` `{` beta-declaration-reference `}` `|` link-title `}`

For example:

/**
 * Normal:
 * {@link package#MyClass}
 * {@link package#(Merged:interface)}
 * {@link (Merged:interface)}
 *
 * Beta:
 * {@link {package!MyClass}}
 * {@link {package!Merged:interface}}
 * {@link {Merged:interface}}
 */
octogonz commented 4 years ago

I'd prefer to simply remove the old syntax and got "all in" on the new syntax. We technically have this freedom, as we haven't published the version 1.0.0 of the parser library yet. We've been reasonably clear that the spec is still evolving.

To smooth the transition, I suspect that if we temporarily accepted both # and ! as the the package delimiter, most of the old references would continue to parse correctly. At least, in the code bases I'm familiar with, the number of member selectors using ( : ) is small enough that it could be fixed up relatively quickly.

Keep in mind that API Extractor will most likely allow MyClass.myMember as a synonym for MyClass#myMember:member in cases where there is no ambiguous static member using that name. (I'm fairly convinced that the # vs . distinction is too abstruse to inflict on casual users heheh.)

Maybe over the holiday I can see about implementing this. It really should be our top priority for enhancements to TSDoc.

rbuckton commented 4 years ago

How would you propose doing this? Replacing DocDeclarationReference in DocLinkTag with DocDeclarationReference | DeclarationReference, or having DocDeclarationReference store a DeclarationReference as an alternative to packageName/importPath/memberReferences?

rbuckton commented 4 years ago

There is still an ambiguity with # between the old and new formats. foo#bar in the previous format would be a package named foo with an export named bar, but in the new format its a type named foo with a non-static member named bar.

octogonz commented 4 years ago

How would you propose doing this? Replacing DocDeclarationReference in DocLinkTag with DocDeclarationReference | DeclarationReference, or having DocDeclarationReference store a DeclarationReference as an alternative to packageName/importPath/memberReferences?

No, I'm thinking we could redesign DocDeclarationReference, DocMemberReference, DocMemberSelector, etc to represent your new syntax.

I don't think we can use the DeclarationReference as-is. Its nodes would be inconsistent with the rest of the AST. For example, they do not track a DocExcerpt, which is needed for syntax highlighting. Also it has a separate tokenizer, and its error messages are thrown as exceptions, rather than being reported with a TSDocMessageId and token sequence.

If you have projects that are using the DeclarationReference API directly, it would be a good idea to call out any additional requirements. Ideally we'd want to improve the TSDoc parser to implement these requirements, so we have a single solution for declaration references and the full TSDoc grammar.

octogonz commented 4 years ago

There is still an ambiguity with # between the old and new formats. foo#bar in the previous format would be a package named foo with an export named bar, but in the new format its a type named foo with a non-static member named bar.

Yeah, you are right. 🤔 Hmm... If it really is important to provide backwards compatibility for the old syntax (which I'm not sure we do), maybe we could provide a configuration option to opt-in or opt-out of the new syntax. It could be specified in tsdoc.json so the ESLint plugin will validate it correctly.

(Or, it might be okay to go all-in on the new syntax. The current library has been stable for a while, so perhaps people could reasonably defer upgrading until they are ready.)

yoursunny commented 3 months ago

It seems that the parser (playground) and eslint-plugin-tsdoc doesn't accept the ! delimiter at all?