From 0b6aeeca9d201d7611efdcb0595cf1da4b21add3 Mon Sep 17 00:00:00 2001 From: zhengbli Date: Tue, 11 Aug 2015 20:18:05 -0700 Subject: [PATCH] Add JsDoc intellisense for JavaScript files --- src/services/services.ts | 54 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/src/services/services.ts b/src/services/services.ts index 07ba30f4e1d..51ac758a28a 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -3653,6 +3653,10 @@ namespace ts { let completionData = getCompletionData(fileName, position); if (!completionData) { + let entries = getJsDocCompletionEntries(fileName, position); + if (entries) { + return { isMemberCompletion: false, isNewIdentifierLocation: false, entries }; + } return undefined; } @@ -3705,6 +3709,56 @@ namespace ts { return entries; } + function getJsDocCompletionEntries(fileName: string, position: number): CompletionEntry[] { + let sourceFile = getValidSourceFile(fileName); + let hasJsDocComment = ts.hasDocComment(sourceFile, position); + if (!hasJsDocComment) { + return undefined; + } + + // If the current position is right after an At sign + if (sourceFile.text.charCodeAt(position - 1) === CharacterCodes.at) { + return getAllJsDocCompletionEntries(); + } + + // Or if the current position is in a tag name + let jsDocCommentNode: JSDocComment; + let node = ts.getTokenAtPosition(sourceFile, position); + while (true) { + if (node === sourceFile || + node.kind === SyntaxKind.VariableStatement || + node.kind === SyntaxKind.FunctionDeclaration || + node.kind === SyntaxKind.Parameter || + node.jsDocComment) { + jsDocCommentNode = node.jsDocComment; + break; + } + node = node.parent; + } + if (jsDocCommentNode) { + for (let tag of jsDocCommentNode.tags) { + if (position >= tag.atToken.pos && position <= tag.tagName.end) { + return getAllJsDocCompletionEntries(); + } + } + return undefined; + } + } + + function getAllJsDocCompletionEntries(): CompletionEntry[] { + let tagNames = ["augments", "author", "argument", "borrows", "class", "constant", "constructor", "constructs", "default", "deprecated", "description", "event", "example", "extends", "field", "fileOverview", "function", "ignore", "inner", "lends", "link", "memberOf", "name", "namespace", "param", "private", "property", "public", "requires", "returns", "see", "since", "static", "throws", "type", "version"]; + let entries: CompletionEntry[] = []; + for (let tagName of tagNames) { + entries.push({ + name: tagName, + kind: ScriptElementKind.keyword, + kindModifiers: "", + sortText: "0", + }); + } + return entries; + } + function createCompletionEntry(symbol: Symbol, location: Node): CompletionEntry { // Try to get a valid display name for this symbol, if we could not find one, then ignore it. // We would like to only show things that can be added after a dot, so for instance numeric properties can