From ab340756bc5a54bf61a9179206403d358ecba207 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Fri, 17 Jul 2015 16:32:29 -0700 Subject: [PATCH] Get Scaffolding --- src/services/services.ts | 47 +++++++++++++++++++-------------------- src/services/utilities.ts | 14 +++++++++--- 2 files changed, 34 insertions(+), 27 deletions(-) diff --git a/src/services/services.ts b/src/services/services.ts index 876d5646a13..058029af9f4 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -6762,31 +6762,30 @@ namespace ts { let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); log("getDocCommentScaffoldingAtPosition: getCurrentSourceFile: " + (new Date().getTime() - start)); - // Check if in comment context - if(isInString(sourceFile, position) || isInComment(sourceFile,position)) { return nullResult; } + // Check if in a context where we don't want to perform any insertion + if (isInString(sourceFile, position) || isInComment(sourceFile, position)) { + return nullResult; + } - // Get the next non-comment token - var nodeAtPos = getTokenAtPosition(sourceFile, position); - var containingFunction = getAncestor(nodeAtPos, SyntaxKind.FunctionDeclaration); - - // check if token is a function keyword - if(!containingFunction) { return emptyCompletion; } - - // Get the parsed object corresponding to the token - - // get the function's param list - - // map the params to JSDoc declarations. ie: - // foo: T -> '* @param foo ' - - // Get the indentation level - // * perhaps just use the carat's indentation? - - // Recall that the in-comment have one extra whitespace character - - // Create the JSDoc comment string from the parts - - return "/** getDocCommentScaffoldingAtPosition -- TS side! */"; + let nodeAtPos = getTokenAtPosition(sourceFile, position); + let containingFunction = getAncestor(nodeAtPos, SyntaxKind.FunctionDeclaration); + + if (hasDocComment(sourceFile, position) || !containingFunction) { + return emptyCompletion; + } + + let parameters = containingFunction.parameters; + let posLineAndChar = sourceFile.getLineAndCharacterOfPosition(position); + let lineStart = sourceFile.getLineStarts()[posLineAndChar.line]; + + let indentationStr = sourceFile.text.substr(lineStart, posLineAndChar.character).match(/\s*/).toString(); + + let docParams = parameters.map((p, index) => + indentationStr + " * @param " + (p.name.kind === SyntaxKind.Identifier ? (p.name).text : "param" + index.toString()) + "\n"); + + let result = "/**\n" + docParams.reduce((prev, cur) => prev + cur, "") + indentationStr + " */"; + + return result; } function getTodoComments(fileName: string, descriptors: TodoCommentDescriptor[]): TodoComment[] { diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 4c0ce77c522..999b3d30427 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -433,11 +433,8 @@ namespace ts { let token = getTokenAtPosition(sourceFile, position); if (token && position < token.getStart()) { - // First, we have to see if this position actually landed in a comment. let commentRanges = getLeadingCommentRanges(sourceFile.text, token.pos); - // Then we want to make sure that it wasn't in a "///<" directive comment - // We don't want to unintentionally update a file name. return forEach(commentRanges, c => c.pos < position && // The end marker of a single-line comment does not include the newline character. // In the following case, we are inside a comment (^ denotes the cursor position): @@ -455,6 +452,17 @@ namespace ts { return false; } + export function hasDocComment(sourceFile: SourceFile, position: number) { + let token = getTokenAtPosition(sourceFile, position); + + let JSDocPrefixRegex = /^\/\*\*\s*/; + + // First, we have to see if this position actually landed in a comment. + let commentRanges = getLeadingCommentRanges(sourceFile.text, token.pos); + + return forEach(commentRanges, c => JSDocPrefixRegex.test(sourceFile.text.substring(c.pos, c.end))); + } + function nodeHasTokens(n: Node): boolean { // If we have a token or node that has a non-zero width, it must have tokens. // Note, that getWidth() does not take trivia into account.