diff --git a/src/services/services.ts b/src/services/services.ts index 4326e57f93e..13f7d4c15e0 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -7059,7 +7059,7 @@ namespace ts { return undefined; } - let parameters = isFunctionLike(commentOwner) ? commentOwner.parameters : emptyArray; + let parameters = getParametersForJsDocOwningNode(commentOwner); let posLineAndChar = sourceFile.getLineAndCharacterOfPosition(position); let lineStart = sourceFile.getLineStarts()[posLineAndChar.line]; @@ -7096,6 +7096,52 @@ namespace ts { return { newText: result, caretOffset: preamble.length }; } + function getParametersForJsDocOwningNode(commentOwner: Node): ParameterDeclaration[] { + if (isFunctionLike(commentOwner)) { + return commentOwner.parameters; + } + + if (commentOwner.kind === SyntaxKind.VariableStatement) { + const varStatement = commentOwner; + const varDeclarations = varStatement.declarationList.declarations; + + if (varDeclarations.length === 1 && varDeclarations[0].initializer) { + return getParametersFromRightHandSideOfAssignment(varDeclarations[0].initializer); + } + } + + return emptyArray; + } + + /** + * Digs into an an initializer or RHS operand of an assignment operation + * to get the parameters from an apst signature corresponding to a + * function expression or a class expression. + * + * @param rightHandSide the expression which may contain an appropriate set of parameters + * @returns the parameters of a signature found on the RHS if one exists; otherwise 'emptyArray'. + */ + function getParametersFromRightHandSideOfAssignment(rightHandSide: Expression): ParameterDeclaration[] { + while (rightHandSide.kind === SyntaxKind.ParenthesizedExpression) { + rightHandSide = (rightHandSide).expression; + } + + switch (rightHandSide.kind) { + case SyntaxKind.FunctionExpression: + case SyntaxKind.ArrowFunction: + return (rightHandSide).parameters; + case SyntaxKind.ClassExpression: + for (let member of (rightHandSide).members) { + if (member.kind === SyntaxKind.Constructor) { + return (member).parameters; + } + } + break; + } + + return emptyArray; + } + function getTodoComments(fileName: string, descriptors: TodoCommentDescriptor[]): TodoComment[] { // Note: while getting todo comments seems like a syntactic operation, we actually // treat it as a semantic operation here. This is because we expect our host to call