diff --git a/common/changes/@microsoft/tsdoc/octogonz-issue-148_2019-03-12-04-16.json b/common/changes/@microsoft/tsdoc/octogonz-issue-148_2019-03-12-04-16.json new file mode 100644 index 00000000..f172f0e9 --- /dev/null +++ b/common/changes/@microsoft/tsdoc/octogonz-issue-148_2019-03-12-04-16.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@microsoft/tsdoc", + "comment": "Fix an issue where tsdoc-param-tag-with-invalid-name was sometimes incorrectly reported certain identifiers (issue #148)", + "type": "patch" + } + ], + "packageName": "@microsoft/tsdoc", + "email": "4673363+octogonz@users.noreply.github.com" +} \ No newline at end of file diff --git a/tsdoc/src/nodes/DocMemberIdentifier.ts b/tsdoc/src/nodes/DocMemberIdentifier.ts index 6bdc1fea..92c41b0c 100644 --- a/tsdoc/src/nodes/DocMemberIdentifier.ts +++ b/tsdoc/src/nodes/DocMemberIdentifier.ts @@ -33,12 +33,16 @@ export class DocMemberIdentifier extends DocNode { private readonly _rightQuoteExcerpt: DocExcerpt | undefined; /** - * Returns true if the specified string is a valid TypeScript - * identifier. If not, {@link DocMemberIdentifier.hasQuotes} will be - * required. + * Tests whether the input string can be used without quotes as a member identifier in a declaration reference. + * If not, {@link DocMemberIdentifier.hasQuotes} will be required. + * + * @remarks + * In order to be used without quotes, the string must follow the identifier syntax for ECMAScript / TypeScript, + * and it must not be one of the reserved words used for system selectors (such as `instance`, `static`, + * `constructor`, etc). */ public static isValidIdentifier(identifier: string): boolean { - return !StringChecks.explainIfInvalidUnquotedIdentifier(identifier); + return !StringChecks.explainIfInvalidUnquotedMemberIdentifier(identifier); } /** diff --git a/tsdoc/src/parser/NodeParser.ts b/tsdoc/src/parser/NodeParser.ts index f0120cbb..ad2c0006 100644 --- a/tsdoc/src/parser/NodeParser.ts +++ b/tsdoc/src/parser/NodeParser.ts @@ -1377,7 +1377,7 @@ export class NodeParser { const identifierExcerpt: TokenSequence = tokenReader.extractAccumulatedSequence(); const identifier: string = identifierExcerpt.toString(); - const explanation: string | undefined = StringChecks.explainIfInvalidUnquotedIdentifier(identifier); + const explanation: string | undefined = StringChecks.explainIfInvalidUnquotedMemberIdentifier(identifier); if (explanation) { this._parserContext.log.addMessageForTokenSequence( TSDocMessageId.ReferenceUnquotedIdentifier, diff --git a/tsdoc/src/parser/StringChecks.ts b/tsdoc/src/parser/StringChecks.ts index 7e5a8c7c..e55e8357 100644 --- a/tsdoc/src/parser/StringChecks.ts +++ b/tsdoc/src/parser/StringChecks.ts @@ -164,6 +164,19 @@ export class StringChecks { return 'The identifier must not start with a number'; } + return undefined; + } + + /** + * Tests whether the input string can be used without quotes as a member identifier in a declaration reference. + * If not, it should be enclosed in quotes. + */ + public static explainIfInvalidUnquotedMemberIdentifier(identifier: string): string | undefined { + const explanation: string | undefined = StringChecks.explainIfInvalidUnquotedIdentifier(identifier); + if (explanation !== undefined) { + return explanation; + } + if (StringChecks.isSystemSelector(identifier)) { // We do this to avoid confusion about the declaration reference syntax rules. // For example if someone were to see "MyClass.(static:instance)" it would be unclear which