diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 7442f74a13618..1f3e26ae77917 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -1380,6 +1380,7 @@ export function updateSourceFile(sourceFile: SourceFile, newText: string, textCh } /** @internal */ +// Exposed only for testing. export function parseIsolatedJSDocComment(content: string, start?: number, length?: number) { const result = Parser.JSDocParser.parseIsolatedJSDocComment(content, start, length); if (result && result.jsDoc) { diff --git a/src/services/classifier.ts b/src/services/classifier.ts index 74450102e3476..02ea022afd0f9 100644 --- a/src/services/classifier.ts +++ b/src/services/classifier.ts @@ -22,7 +22,6 @@ import { getMeaningFromLocation, getModuleInstanceState, getTypeArgumentOrTypeParameterList, - HasJSDoc, InterfaceDeclaration, isAccessibilityModifier, isConstTypeReference, @@ -60,12 +59,10 @@ import { Node, nodeIsMissing, ParameterDeclaration, - parseIsolatedJSDocComment, Push, Scanner, ScriptTarget, SemanticMeaning, - setParent, some, SourceFile, Symbol, @@ -727,7 +724,7 @@ export function getEncodedSyntacticClassifications(cancellationToken: Cancellati case SyntaxKind.SingleLineCommentTrivia: case SyntaxKind.MultiLineCommentTrivia: // Only bother with the trivia if it at least intersects the span of interest. - classifyComment(token, kind, start, width); + classifyComment(kind, start, width); // Classifying a comment might cause us to reuse the trivia scanner // (because of jsdoc comments). So after we classify the comment make @@ -762,15 +759,11 @@ export function getEncodedSyntacticClassifications(cancellationToken: Cancellati } } - function classifyComment(token: Node, kind: SyntaxKind, start: number, width: number) { + function classifyComment(kind: SyntaxKind, start: number, width: number) { if (kind === SyntaxKind.MultiLineCommentTrivia) { - // See if this is a doc comment. If so, we'll classify certain portions of it - // specially. - const docCommentAndDiagnostics = parseIsolatedJSDocComment(sourceFile.text, start, width); - if (docCommentAndDiagnostics && docCommentAndDiagnostics.jsDoc) { - // TODO: This should be predicated on `token["kind"]` being compatible with `HasJSDoc["kind"]` - setParent(docCommentAndDiagnostics.jsDoc, token as HasJSDoc); - classifyJSDocComment(docCommentAndDiagnostics.jsDoc); + // If it's JSDoc, we will have handled its node explicitly as another Node's child; skip. + const text = sourceFile.text.substr(start, 3); + if (text === "/**") { return; } } @@ -1014,6 +1007,7 @@ export function getEncodedSyntacticClassifications(cancellationToken: Cancellati */ function tryClassifyNode(node: Node): boolean { if (isJSDoc(node)) { + classifyJSDocComment(node); return true; } @@ -1028,6 +1022,12 @@ export function getEncodedSyntacticClassifications(cancellationToken: Cancellati const tokenStart = node.kind === SyntaxKind.JsxText ? node.pos : classifyLeadingTriviaAndGetTokenStart(node); + if (node.kind === SyntaxKind.EndOfFileToken) { + // There's no token for the end of the file, but return + // false so that a potential JSDoc child node is visited. + return false; + } + const tokenWidth = node.end - tokenStart; Debug.assert(tokenWidth >= 0); if (tokenWidth > 0) { diff --git a/tests/cases/fourslash/jsdocWithBarInTypeLiteral.ts b/tests/cases/fourslash/jsdocWithBarInTypeLiteral.ts new file mode 100644 index 0000000000000..f291335ca4fae --- /dev/null +++ b/tests/cases/fourslash/jsdocWithBarInTypeLiteral.ts @@ -0,0 +1,11 @@ +/// + +// @filename: index.js +//// class I18n { +//// /** +//// * @param {{dot|fulltext}} [stringMode] - which mode our translation keys use +//// */ +//// constructor(options = {}) {} +//// } + +verify.encodedSyntacticClassificationsLength(69);