From eeff7093c4f4cfcd12dcb722c288106d201b8860 Mon Sep 17 00:00:00 2001 From: Ilya Golovin Date: Sun, 29 Oct 2023 20:10:24 +0300 Subject: [PATCH] fix: prevent manual blocks name collisions --- typescript/src/utils.ts | 13 +++++++++++-- typescript/test/codeActions.spec.ts | 26 ++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/typescript/src/utils.ts b/typescript/src/utils.ts index eb184fc..45d5196 100644 --- a/typescript/src/utils.ts +++ b/typescript/src/utils.ts @@ -352,9 +352,18 @@ export const isValidInitializerForDestructure = (match: ts.Expression) => { } export const isNameUniqueAtLocation = (name: string, location: ts.Node | undefined, typeChecker: ts.TypeChecker) => { const checker = getFullTypeChecker(typeChecker) + let result: boolean | undefined - const newVariable = checker.resolveName(name, location as unknown as import('typescript-full').Node, ts.SymbolFlags.Value, true) - return !newVariable + const checkCollision = (childNode: ts.Node) => { + if (result) return + result = !!checker.resolveName(name, childNode as unknown as import('typescript-full').Node, ts.SymbolFlags.Value, true) + + if (ts.isBlock(childNode)) { + childNode.forEachChild(checkCollision) + } + } + location?.forEachChild(checkCollision) + return !result } export const isNameUniqueAtNodeClosestScope = (name: string, node: ts.Node, typeChecker: ts.TypeChecker) => { const closestScope = findClosestParent( diff --git a/typescript/test/codeActions.spec.ts b/typescript/test/codeActions.spec.ts index 9fd01a7..02b5ca9 100644 --- a/typescript/test/codeActions.spec.ts +++ b/typescript/test/codeActions.spec.ts @@ -317,4 +317,30 @@ describe('From destructure', () => { `, }) }) + test('Should work with name collisions in nested manual blocks', () => { + const { codeAction } = fourslashLikeTester( + /* ts */ ` + function fn({ /*t*/bar/*t*/, foo }) { + { + const newVariable = 5 + const something = bar + foo + } + }; + `, + undefined, + { dedent: true }, + ) + + codeAction(0, { + refactorName: 'From Destruct', + newContent: /* ts */ ` + function fn(newVariable_1) { + { + const newVariable = 5 + const something = newVariable_1.bar + newVariable_1.foo + } + }; + `, + }) + }) })