From d8aafeef0a125de8f6a4a65b5f26b26c5ba26aca Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Mon, 30 Oct 2017 11:07:04 -0700 Subject: [PATCH 1/3] Add regression test for #19395 Thanks to @mjbvz for finding it and @sandersn for reducing it. --- tests/cases/fourslash/extract-method27.ts | 34 +++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 tests/cases/fourslash/extract-method27.ts diff --git a/tests/cases/fourslash/extract-method27.ts b/tests/cases/fourslash/extract-method27.ts new file mode 100644 index 00000000000..a5bb86e2f14 --- /dev/null +++ b/tests/cases/fourslash/extract-method27.ts @@ -0,0 +1,34 @@ +/// + +// Repro https://github.com/Microsoft/TypeScript/issues/19395 + +// @Filename: test.ts +//// export const b = 2; +//// interface Interface { } +//// +//// async function handle(i: Interface) { +//// /*a*/const x = 3, y = i;/*b*/ +//// } +// @Filename: library.d.ts +//// export as namespace NS; +//// export const a = 1; + + +goTo.select('a', 'b') +edit.applyRefactor({ + refactorName: "Extract Symbol", + actionName: "function_scope_1", + actionDescription: "Extract to function in module scope", + newContent: +`export const b = 2; +interface Interface { } + +async function handle(i: Interface) { + /*RENAME*/newFunction(i); +} + +function newFunction(i: Interface) { + const x = 3, y = i; +} +` +}); From aa59a69e143620463eb355597643265ff913dd9f Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Mon, 30 Oct 2017 11:15:20 -0700 Subject: [PATCH 2/3] Correct typo - pass correct argument All of the other calls in extractSymbol are already correct. --- src/services/refactors/extractSymbol.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/refactors/extractSymbol.ts b/src/services/refactors/extractSymbol.ts index b18e12d2b96..5013acafc52 100644 --- a/src/services/refactors/extractSymbol.ts +++ b/src/services/refactors/extractSymbol.ts @@ -730,7 +730,7 @@ namespace ts.refactor.extractSymbol { let type = checker.getTypeOfSymbolAtLocation(usage.symbol, usage.node); // Widen the type so we don't emit nonsense annotations like "function fn(x: 3) {" type = checker.getBaseTypeOfLiteralType(type); - typeNode = checker.typeToTypeNode(type, node, NodeBuilderFlags.NoTruncation); + typeNode = checker.typeToTypeNode(type, scope, NodeBuilderFlags.NoTruncation); } const paramDecl = createParameter( From 1f93526fd9a4419bfb7c476241a6a6b55c1f044b Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Mon, 30 Oct 2017 11:11:16 -0700 Subject: [PATCH 3/3] Assert that enclosing declaration is not synthesized --- src/compiler/checker.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 72438fa27af..a5712d8af4e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2444,18 +2444,21 @@ namespace ts { function createNodeBuilder() { return { typeToTypeNode: (type: Type, enclosingDeclaration?: Node, flags?: NodeBuilderFlags) => { + Debug.assert(enclosingDeclaration === undefined || (enclosingDeclaration.flags & NodeFlags.Synthesized) === 0); const context = createNodeBuilderContext(enclosingDeclaration, flags); const resultingNode = typeToTypeNodeHelper(type, context); const result = context.encounteredError ? undefined : resultingNode; return result; }, indexInfoToIndexSignatureDeclaration: (indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags) => { + Debug.assert(enclosingDeclaration === undefined || (enclosingDeclaration.flags & NodeFlags.Synthesized) === 0); const context = createNodeBuilderContext(enclosingDeclaration, flags); const resultingNode = indexInfoToIndexSignatureDeclarationHelper(indexInfo, kind, context); const result = context.encounteredError ? undefined : resultingNode; return result; }, signatureToSignatureDeclaration: (signature: Signature, kind: SyntaxKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags) => { + Debug.assert(enclosingDeclaration === undefined || (enclosingDeclaration.flags & NodeFlags.Synthesized) === 0); const context = createNodeBuilderContext(enclosingDeclaration, flags); const resultingNode = signatureToSignatureDeclarationHelper(signature, kind, context); const result = context.encounteredError ? undefined : resultingNode;