Skip to content

Commit 17cc206

Browse files
committed
Merge JSDoc of assignments from function expressions
1 parent 13ddc34 commit 17cc206

4 files changed

Lines changed: 71 additions & 22 deletions

File tree

src/compiler/utilities.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -603,9 +603,11 @@ namespace ts {
603603
}
604604

605605
export function getJsDocCommentsFromText(node: Node, text: string) {
606-
const commentRanges = (node.kind === SyntaxKind.Parameter || node.kind === SyntaxKind.TypeParameter) ?
607-
concatenate(getTrailingCommentRanges(text, node.pos),
608-
getLeadingCommentRanges(text, node.pos)) :
606+
const commentRanges = (node.kind === SyntaxKind.Parameter ||
607+
node.kind === SyntaxKind.TypeParameter ||
608+
node.kind === SyntaxKind.FunctionExpression ||
609+
node.kind === SyntaxKind.ArrowFunction) ?
610+
concatenate(getTrailingCommentRanges(text, node.pos), getLeadingCommentRanges(text, node.pos)) :
609611
getLeadingCommentRangesOfNodeFromText(node, text);
610612
return filter(commentRanges, isJsDocComment);
611613

src/services/services.ts

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -406,37 +406,56 @@ namespace ts {
406406
const sourceFileOfDeclaration = getSourceFileOfNode(declaration);
407407
// If it is parameter - try and get the jsDoc comment with @param tag from function declaration's jsDoc comments
408408
if (canUseParsedParamTagComments && declaration.kind === SyntaxKind.Parameter) {
409-
ts.forEach(getJsDocCommentTextRange(declaration.parent, sourceFileOfDeclaration), jsDocCommentTextRange => {
410-
const cleanedParamJsDocComment = getCleanedParamJsDocComment(jsDocCommentTextRange.pos, jsDocCommentTextRange.end, sourceFileOfDeclaration);
411-
if (cleanedParamJsDocComment) {
412-
addRange(jsDocCommentParts, cleanedParamJsDocComment);
413-
}
414-
});
409+
if ((declaration.parent.kind === SyntaxKind.FunctionExpression || declaration.parent.kind === SyntaxKind.ArrowFunction) &&
410+
declaration.parent.parent.kind === SyntaxKind.VariableDeclaration) {
411+
addCommentParts(declaration.parent.parent.parent, sourceFileOfDeclaration, getCleanedParamJsDocComment);
412+
}
413+
addCommentParts(declaration.parent, sourceFileOfDeclaration, getCleanedParamJsDocComment);
415414
}
416415

417416
// If this is left side of dotted module declaration, there is no doc comments associated with this node
418417
if (declaration.kind === SyntaxKind.ModuleDeclaration && (<ModuleDeclaration>declaration).body.kind === SyntaxKind.ModuleDeclaration) {
419418
return;
420419
}
421420

421+
if ((declaration.kind === SyntaxKind.FunctionExpression || declaration.kind === SyntaxKind.ArrowFunction) &&
422+
declaration.parent.kind === SyntaxKind.VariableDeclaration) {
423+
addCommentParts(declaration.parent.parent, sourceFileOfDeclaration, getCleanedJsDocComment);
424+
}
425+
422426
// If this is dotted module name, get the doc comments from the parent
423427
while (declaration.kind === SyntaxKind.ModuleDeclaration && declaration.parent.kind === SyntaxKind.ModuleDeclaration) {
424428
declaration = <ModuleDeclaration>declaration.parent;
425429
}
430+
addCommentParts(declaration.kind === SyntaxKind.VariableDeclaration ? declaration.parent.parent : declaration,
431+
sourceFileOfDeclaration,
432+
getCleanedJsDocComment);
426433

427-
// Get the cleaned js doc comment text from the declaration
428-
ts.forEach(getJsDocCommentTextRange(
429-
declaration.kind === SyntaxKind.VariableDeclaration ? declaration.parent.parent : declaration, sourceFileOfDeclaration), jsDocCommentTextRange => {
430-
const cleanedJsDocComment = getCleanedJsDocComment(jsDocCommentTextRange.pos, jsDocCommentTextRange.end, sourceFileOfDeclaration);
431-
if (cleanedJsDocComment) {
432-
addRange(jsDocCommentParts, cleanedJsDocComment);
433-
}
434-
});
434+
if (declaration.kind === SyntaxKind.VariableDeclaration) {
435+
const init = (declaration as VariableDeclaration).initializer;
436+
if (init && (init.kind === SyntaxKind.FunctionExpression || init.kind === SyntaxKind.ArrowFunction)) {
437+
// Get the cleaned js doc comment text from the initializer
438+
addCommentParts(init, sourceFileOfDeclaration, getCleanedJsDocComment);
439+
}
440+
}
435441
}
436442
});
437443

438444
return jsDocCommentParts;
439445

446+
function addCommentParts(commented: Node,
447+
sourceFileOfDeclaration: SourceFile,
448+
getCommentPart: (pos: number, end: number, file: SourceFile) => SymbolDisplayPart[]): void {
449+
const ranges = getJsDocCommentTextRange(commented, sourceFileOfDeclaration);
450+
// Get the cleaned js doc comment text from the declaration
451+
ts.forEach(ranges, jsDocCommentTextRange => {
452+
const cleanedComment = getCommentPart(jsDocCommentTextRange.pos, jsDocCommentTextRange.end, sourceFileOfDeclaration);
453+
if (cleanedComment) {
454+
addRange(jsDocCommentParts, cleanedComment);
455+
}
456+
});
457+
}
458+
440459
function getJsDocCommentTextRange(node: Node, sourceFile: SourceFile): TextRange[] {
441460
return ts.map(getJsDocComments(node, sourceFile),
442461
jsDocComment => {

tests/cases/fourslash/commentsFunction.ts

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,20 @@
3333
//// }
3434
//// return lamb/*31*/daVar("World") + /*32*/a;
3535
////}
36+
/////**
37+
//// * On variable
38+
//// * @param s the first parameter!
39+
//// * @returns the parameter's length
40+
//// */
41+
////var assi/*33*/gned = /**
42+
//// * Summary on expression
43+
//// * @param s param on expression
44+
//// * @returns return on expression
45+
//// */function(/** On parameter */s: string) {
46+
//// return s.length;
47+
////}
48+
////assig/*34*/ned/*35*/(/*36*/"hey");
49+
3650

3751
goTo.marker('1');
3852
verify.currentSignatureHelpDocCommentIs("This comment should appear for foo");
@@ -68,14 +82,15 @@ verify.completionListContains('a', '(parameter) a: string', 'this is comment abo
6882
verify.completionListContains('b', '(parameter) b: number', 'this is comment for b');
6983

7084
goTo.marker('11');
71-
verify.quickInfoIs("var lambdaFoo: (a: number, b: number) => number", "lamdaFoo var comment");
85+
verify.quickInfoIs("var lambdaFoo: (a: number, b: number) => number", "lamdaFoo var comment\nthis is lambda comment");
7286

7387
goTo.marker('12');
74-
verify.quickInfoIs("var lambddaNoVarComment: (a: number, b: number) => number", "");
88+
// pick up doccomments from the lambda itself
89+
verify.quickInfoIs("var lambddaNoVarComment: (a: number, b: number) => number", "this is lambda multiplication");
7590

7691
goTo.marker('13');
77-
verify.completionListContains('lambdaFoo', 'var lambdaFoo: (a: number, b: number) => number', '');
78-
verify.completionListContains('lambddaNoVarComment', 'var lambddaNoVarComment: (a: number, b: number) => number', '');
92+
verify.completionListContains('lambdaFoo', 'var lambdaFoo: (a: number, b: number) => number', 'lamdaFoo var comment\nthis is lambda comment');
93+
verify.completionListContains('lambddaNoVarComment', 'var lambddaNoVarComment: (a: number, b: number) => number', 'this is lambda multiplication');
7994

8095
goTo.marker('14');
8196
verify.currentParameterHelpArgumentDocCommentIs("param a");
@@ -129,3 +144,14 @@ goTo.marker('31');
129144
verify.quickInfoIs('(local var) lambdaVar: (b: string) => string', '');
130145
goTo.marker('32');
131146
verify.quickInfoIs('(parameter) a: number', '');
147+
148+
goTo.marker('33');
149+
verify.quickInfoIs("var assigned: (s: string) => number", "On variable\n@returns the parameter's length\nSummary on expression\n@returns return on expression");
150+
goTo.marker('34');
151+
verify.quickInfoIs("var assigned: (s: string) => number", "On variable\n@returns the parameter's length\nSummary on expression\n@returns return on expression");
152+
goTo.marker('35');
153+
verify.completionListContains("assigned", "var assigned: (s: string) => number", "On variable\n@returns the parameter's length\nSummary on expression\n@returns return on expression");
154+
goTo.marker('36');
155+
verify.currentSignatureHelpDocCommentIs("On variable\n@returns the parameter's length\nSummary on expression\n@returns return on expression");
156+
verify.currentParameterHelpArgumentDocCommentIs("param on expression\nthe first parameter!\nOn parameter ");
157+

tests/cases/fourslash/getJavaScriptQuickInfo7.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,6 @@
1717
//// x - /**/a1()
1818

1919
goTo.marker();
20-
verify.quickInfoExists();
20+
verify.quickInfoExists();
21+
verify.quickInfoIs('function a1(p: any): number',
22+
'This is a very cool function that is very nice.\n@returns something');

0 commit comments

Comments
 (0)