From c9c9f859f3f9118e707ff3cef6a2a02e2d599890 Mon Sep 17 00:00:00 2001 From: xiaofa Date: Thu, 17 Jan 2019 05:51:57 +0800 Subject: [PATCH 1/2] fix quick fix infer parameter types from usage in js file --- src/services/textChanges.ts | 4 +++- .../fourslash/codeFixInferFromUsageArrowJS.ts | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 tests/cases/fourslash/codeFixInferFromUsageArrowJS.ts diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index 4689e18508c..7dab7205841 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -340,7 +340,9 @@ namespace ts.textChanges { } public insertJsdocCommentBefore(sourceFile: SourceFile, node: HasJSDoc, tag: JSDoc): void { - const fnStart = node.getStart(sourceFile); + const fnStart = node.kind === SyntaxKind.ArrowFunction + ? node.parent.parent.getStart(sourceFile) + : node.getStart(sourceFile); if (node.jsDoc) { for (const jsdoc of node.jsDoc) { this.deleteRange(sourceFile, { diff --git a/tests/cases/fourslash/codeFixInferFromUsageArrowJS.ts b/tests/cases/fourslash/codeFixInferFromUsageArrowJS.ts new file mode 100644 index 00000000000..e867ae99c75 --- /dev/null +++ b/tests/cases/fourslash/codeFixInferFromUsageArrowJS.ts @@ -0,0 +1,18 @@ +/// +// @allowJs: true +// @checkJs: true +// @noEmit: true +// @noImplicitAny: true +// @Filename: test.js + +////const foo = x => x.y + 1; + +verify.codeFix({ + description: "Infer parameter types from usage", + index: 0, + newFileContent: +`/** + * @param {{ y: number; }} x + */ +const foo = x => x.y + 1;`, +}); \ No newline at end of file From ddbac8f3fe87bb6044ceab2f68eacd81d7dd6977 Mon Sep 17 00:00:00 2001 From: xiaofa Date: Sat, 26 Jan 2019 23:59:32 +0800 Subject: [PATCH 2/2] get appropriate parent jsdoc node for arrow functions --- src/services/codefixes/inferFromUsage.ts | 12 +++++++++++- src/services/textChanges.ts | 4 +--- .../fourslash/codeFixInferFromUsageArrowJS.ts | 17 +++++++++++++---- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/services/codefixes/inferFromUsage.ts b/src/services/codefixes/inferFromUsage.ts index 8e5b962116d..f47f618f79d 100644 --- a/src/services/codefixes/inferFromUsage.ts +++ b/src/services/codefixes/inferFromUsage.ts @@ -274,7 +274,17 @@ namespace ts.codefix { return !!merged; })); const tag = createJSDocComment(comments.join("\n"), createNodeArray([...(oldTags || emptyArray), ...unmergedNewTags])); - changes.insertJsdocCommentBefore(sourceFile, parent, tag); + const jsDocNode = parent.kind === SyntaxKind.ArrowFunction ? getJsDocNodeForArrowFunction(parent) : parent; + jsDocNode.jsDoc = parent.jsDoc; + jsDocNode.jsDocCache = parent.jsDocCache; + changes.insertJsdocCommentBefore(sourceFile, jsDocNode, tag); + } + + function getJsDocNodeForArrowFunction(signature: ArrowFunction): HasJSDoc { + if (signature.parent.kind === SyntaxKind.PropertyDeclaration) { + return signature.parent; + } + return signature.parent.parent; } function tryMergeJsdocTags(oldTag: JSDocTag, newTag: JSDocTag): JSDocTag | undefined { diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index 7dab7205841..4689e18508c 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -340,9 +340,7 @@ namespace ts.textChanges { } public insertJsdocCommentBefore(sourceFile: SourceFile, node: HasJSDoc, tag: JSDoc): void { - const fnStart = node.kind === SyntaxKind.ArrowFunction - ? node.parent.parent.getStart(sourceFile) - : node.getStart(sourceFile); + const fnStart = node.getStart(sourceFile); if (node.jsDoc) { for (const jsdoc of node.jsDoc) { this.deleteRange(sourceFile, { diff --git a/tests/cases/fourslash/codeFixInferFromUsageArrowJS.ts b/tests/cases/fourslash/codeFixInferFromUsageArrowJS.ts index e867ae99c75..0a800fd7d63 100644 --- a/tests/cases/fourslash/codeFixInferFromUsageArrowJS.ts +++ b/tests/cases/fourslash/codeFixInferFromUsageArrowJS.ts @@ -6,13 +6,22 @@ // @Filename: test.js ////const foo = x => x.y + 1; +////class C { +//// m = x => x.y + 1; +////} -verify.codeFix({ - description: "Infer parameter types from usage", - index: 0, +verify.codeFixAll({ + fixId: "inferFromUsage", + fixAllDescription: "Infer all types from usage", newFileContent: `/** * @param {{ y: number; }} x */ -const foo = x => x.y + 1;`, +const foo = x => x.y + 1; +class C { + /** + * @param {{ y: number; }} x + */ + m = x => x.y + 1; +}`, }); \ No newline at end of file