in tsdoc/src/parser/NodeParser.ts [1685:1789]
private _parseMemberIdentifier(
tokenReader: TokenReader,
tokenSequenceForErrorContext: TokenSequence,
nodeForErrorContext: DocNode
): DocMemberIdentifier | undefined {
let leftQuoteExcerpt: TokenSequence | undefined = undefined;
let rightQuoteExcerpt: TokenSequence | undefined = undefined;
// Is this a quoted identifier?
if (tokenReader.peekTokenKind() === TokenKind.DoubleQuote) {
// Read the opening '"'
tokenReader.readToken();
leftQuoteExcerpt = tokenReader.extractAccumulatedSequence();
// Read the text inside the quotes
while (tokenReader.peekTokenKind() !== TokenKind.DoubleQuote) {
if (tokenReader.peekTokenKind() === TokenKind.EndOfInput) {
this._parserContext.log.addMessageForTokenSequence(
TSDocMessageId.ReferenceMissingQuote,
'Unexpected end of input inside quoted member identifier',
leftQuoteExcerpt,
nodeForErrorContext
);
return undefined;
}
tokenReader.readToken();
}
if (tokenReader.isAccumulatedSequenceEmpty()) {
this._parserContext.log.addMessageForTokenSequence(
TSDocMessageId.ReferenceEmptyIdentifier,
'The quoted identifier cannot be empty',
leftQuoteExcerpt,
nodeForErrorContext
);
return undefined;
}
const identifierExcerpt: TokenSequence = tokenReader.extractAccumulatedSequence();
// Read the closing '""
tokenReader.readToken(); // read the quote
rightQuoteExcerpt = tokenReader.extractAccumulatedSequence();
return new DocMemberIdentifier({
parsed: true,
configuration: this._configuration,
leftQuoteExcerpt,
identifierExcerpt,
rightQuoteExcerpt
});
} else {
// Otherwise assume it's a valid TypeScript identifier
let done: boolean = false;
while (!done) {
switch (tokenReader.peekTokenKind()) {
case TokenKind.AsciiWord:
case TokenKind.DollarSign:
tokenReader.readToken();
break;
default:
done = true;
break;
}
}
if (tokenReader.isAccumulatedSequenceEmpty()) {
this._parserContext.log.addMessageForTokenSequence(
TSDocMessageId.ReferenceMissingIdentifier,
'Syntax error in declaration reference: expecting a member identifier',
tokenSequenceForErrorContext,
nodeForErrorContext
);
return undefined;
}
const identifierExcerpt: TokenSequence = tokenReader.extractAccumulatedSequence();
const identifier: string = identifierExcerpt.toString();
const explanation: string | undefined = StringChecks.explainIfInvalidUnquotedMemberIdentifier(
identifier
);
if (explanation) {
this._parserContext.log.addMessageForTokenSequence(
TSDocMessageId.ReferenceUnquotedIdentifier,
explanation,
identifierExcerpt,
nodeForErrorContext
);
return undefined;
}
return new DocMemberIdentifier({
parsed: true,
configuration: this._configuration,
leftQuoteExcerpt,
identifierExcerpt,
rightQuoteExcerpt
});
}
}