diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e7a3d6d6ab706..6dbc8e1a83ad8 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -311,7 +311,22 @@ namespace ts { return node && getTypeArgumentConstraint(node); }, - getSuggestionDiagnostics: file => suggestionDiagnostics.get(file.fileName) || emptyArray, + getSuggestionDiagnostics: file => { + return (suggestionDiagnostics.get(file.fileName) || emptyArray).concat(getUnusedDiagnostics()); + function getUnusedDiagnostics(): ReadonlyArray { + checkSourceFile(file); + const diagnostics: Diagnostic[] = []; + Debug.assert(!!(getNodeLinks(file).flags & NodeCheckFlags.TypeChecked)); + if (!file.isDeclarationFile) { + checkUnusedIdentifiers(allPotentiallyUnusedIdentifiers.get(file.fileName)!, (kind, diag) => { + if (!unusedIsError(kind)) { + diagnostics.push({ ...diag, category: DiagnosticCategory.Suggestion }); + } + }); + } + return diagnostics; + } + }, }; const tupleTypes: GenericType[] = []; @@ -420,7 +435,8 @@ namespace ts { let deferredGlobalTemplateStringsArrayType: ObjectType; let deferredNodes: Node[]; - let deferredUnusedIdentifierNodes: Node[]; + const allPotentiallyUnusedIdentifiers = createMap>(); // key is file name + let potentiallyUnusedIdentifiers: PotentiallyUnusedIdentifier[]; // Potentially unused identifiers in the source file currently being checked. let flowLoopStart = 0; let flowLoopCount = 0; @@ -610,6 +626,12 @@ namespace ts { resolvedMembers = "resolvedMembers" } + const enum UnusedKind { + Local, + Parameter, + } + type AddUnusedDiagnostic = (type: UnusedKind, diagnostic: Diagnostic) => void; + const builtinGlobals = createSymbolTable(); builtinGlobals.set(undefinedSymbol.escapedName, undefinedSymbol); @@ -10300,8 +10322,7 @@ namespace ts { // related to Y, where X' is an instantiation of X in which P is replaced with Q. Notice // that S and T are contra-variant whereas X and Y are co-variant. function mappedTypeRelatedTo(source: MappedType, target: MappedType, reportErrors: boolean): Ternary { - const modifiersRelated = relation === comparableRelation || ( - relation === identityRelation ? getMappedTypeModifiers(source) === getMappedTypeModifiers(target) : + const modifiersRelated = relation === comparableRelation || (relation === identityRelation ? getMappedTypeModifiers(source) === getMappedTypeModifiers(target) : getCombinedMappedTypeOptionality(source) <= getCombinedMappedTypeOptionality(target)); if (modifiersRelated) { let result: Ternary; @@ -14674,7 +14695,7 @@ namespace ts { } } - return getUnionType(map(signatures, ctor ? t => getJsxPropsTypeFromConstructSignature(t, isJs, context) : t => getJsxPropsTypeFromCallSignature(t, context)), UnionReduction.None); + return getUnionType(map(signatures, ctor ? (t => getJsxPropsTypeFromConstructSignature(t, isJs, context)) : (t => getJsxPropsTypeFromCallSignature(t, context))), UnionReduction.None); } function getJsxPropsTypeFromCallSignature(sig: Signature, context: Node) { @@ -18771,7 +18792,6 @@ namespace ts { } } } - registerForUnusedIdentifiersCheck(node); } } @@ -20101,8 +20121,8 @@ namespace ts { checkAsyncFunctionReturnType(node); } } - if (!(node).body) { - checkUnusedTypeParameters(node); + if (node.kind !== SyntaxKind.IndexSignature && node.kind !== SyntaxKind.JSDocFunctionType) { + registerForUnusedIdentifiersCheck(node); } } } @@ -20303,7 +20323,6 @@ namespace ts { if (!checkGrammarConstructorTypeParameters(node)) checkGrammarConstructorTypeAnnotation(node); checkSourceElement(node.body); - registerForUnusedIdentifiersCheck(node); const symbol = getSymbolOfNode(node); const firstDeclaration = getDeclarationOfKind(symbol, node.kind); @@ -20423,7 +20442,6 @@ namespace ts { } } checkSourceElement(node.body); - registerForUnusedIdentifiersCheck(node); } function checkAccessorDeclarationTypesIdentical(first: AccessorDeclaration, second: AccessorDeclaration, getAnnotatedType: (a: AccessorDeclaration) => Type, message: DiagnosticMessage) { @@ -21557,67 +21575,75 @@ namespace ts { getReturnTypeOfSignature(getSignatureFromDeclaration(node)); } } - - registerForUnusedIdentifiersCheck(node); } - function registerForUnusedIdentifiersCheck(node: Node) { - if (deferredUnusedIdentifierNodes) { - deferredUnusedIdentifierNodes.push(node); + function registerForUnusedIdentifiersCheck(node: PotentiallyUnusedIdentifier): void { + // May be in a call such as getTypeOfNode that happened to call this. But potentiallyUnusedIdentifiers is only defined in the scope of `checkSourceFile`. + if (potentiallyUnusedIdentifiers === undefined) return; + + if (contains(potentiallyUnusedIdentifiers, node)) { + // TODO: GH#22491 Apparently we check the BlockStatement in the callback in `getPropertyAssignment` twice. + // Debug.fail(); + } + else { + potentiallyUnusedIdentifiers.push(node); } } - function checkUnusedIdentifiers() { - if (deferredUnusedIdentifierNodes) { - for (const node of deferredUnusedIdentifierNodes) { - switch (node.kind) { - case SyntaxKind.SourceFile: - case SyntaxKind.ModuleDeclaration: - checkUnusedModuleMembers(node); - break; - case SyntaxKind.ClassDeclaration: - case SyntaxKind.ClassExpression: - checkUnusedClassMembers(node); - checkUnusedTypeParameters(node); - break; - case SyntaxKind.InterfaceDeclaration: - checkUnusedTypeParameters(node); - break; - case SyntaxKind.Block: - case SyntaxKind.CaseBlock: - case SyntaxKind.ForStatement: - case SyntaxKind.ForInStatement: - case SyntaxKind.ForOfStatement: - checkUnusedLocalsAndParameters(node); - break; - case SyntaxKind.Constructor: - case SyntaxKind.FunctionExpression: - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.ArrowFunction: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - if ((node).body) { - checkUnusedLocalsAndParameters(node); - } - checkUnusedTypeParameters(node); - break; - case SyntaxKind.MethodSignature: - case SyntaxKind.CallSignature: - case SyntaxKind.ConstructSignature: - case SyntaxKind.FunctionType: - case SyntaxKind.ConstructorType: - case SyntaxKind.TypeAliasDeclaration: - checkUnusedTypeParameters(node); - break; - default: - Debug.fail("Node should not have been registered for unused identifiers check"); - } + type PotentiallyUnusedIdentifier = + | SourceFile | ModuleDeclaration | ClassLikeDeclaration | InterfaceDeclaration + | Block | CaseBlock | ForStatement | ForInStatement | ForOfStatement + | Exclude | TypeAliasDeclaration; + + function checkUnusedIdentifiers(potentiallyUnusedIdentifiers: ReadonlyArray, addDiagnostic: AddUnusedDiagnostic) { + for (const node of potentiallyUnusedIdentifiers) { + switch (node.kind) { + case SyntaxKind.SourceFile: + case SyntaxKind.ModuleDeclaration: + checkUnusedModuleMembers(node, addDiagnostic); + break; + case SyntaxKind.ClassDeclaration: + case SyntaxKind.ClassExpression: + checkUnusedClassMembers(node, addDiagnostic); + checkUnusedTypeParameters(node, addDiagnostic); + break; + case SyntaxKind.InterfaceDeclaration: + checkUnusedTypeParameters(node, addDiagnostic); + break; + case SyntaxKind.Block: + case SyntaxKind.CaseBlock: + case SyntaxKind.ForStatement: + case SyntaxKind.ForInStatement: + case SyntaxKind.ForOfStatement: + checkUnusedLocalsAndParameters(node, addDiagnostic); + break; + case SyntaxKind.Constructor: + case SyntaxKind.FunctionExpression: + case SyntaxKind.FunctionDeclaration: + case SyntaxKind.ArrowFunction: + case SyntaxKind.MethodDeclaration: + case SyntaxKind.GetAccessor: + case SyntaxKind.SetAccessor: + if (node.body) { + checkUnusedLocalsAndParameters(node, addDiagnostic); + } + checkUnusedTypeParameters(node, addDiagnostic); + break; + case SyntaxKind.MethodSignature: + case SyntaxKind.CallSignature: + case SyntaxKind.ConstructSignature: + case SyntaxKind.FunctionType: + case SyntaxKind.ConstructorType: + case SyntaxKind.TypeAliasDeclaration: + checkUnusedTypeParameters(node, addDiagnostic); + break; + default: + Debug.assertNever(node, "Node should not have been registered for unused identifiers check"); } } } - function checkUnusedLocalsAndParameters(node: Node): void { + function checkUnusedLocalsAndParameters(node: Node, addDiagnostic: AddUnusedDiagnostic): void { if (!(node.flags & NodeFlags.Ambient)) { node.locals.forEach(local => { // If it's purely a type parameter, ignore, will be checked in `checkUnusedTypeParameters`. @@ -21627,11 +21653,11 @@ namespace ts { const parameter = getRootDeclaration(local.valueDeclaration); const name = getNameOfDeclaration(local.valueDeclaration); if (!isParameterPropertyDeclaration(parameter) && !parameterIsThisKeyword(parameter) && !parameterNameStartsWithUnderscore(name)) { - errorOrSuggestion(/*isError*/ compilerOptions.noUnusedParameters, name, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolName(local)); + addDiagnostic(UnusedKind.Parameter, createDiagnosticForNode(name, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolName(local))); } } else { - forEach(local.declarations, d => errorUnusedLocal(d, symbolName(local))); + forEach(local.declarations, d => errorUnusedLocal(d, symbolName(local), addDiagnostic)); } } }); @@ -21646,7 +21672,7 @@ namespace ts { return false; } - function errorUnusedLocal(declaration: Declaration, name: string) { + function errorUnusedLocal(declaration: Declaration, name: string, addDiagnostic: AddUnusedDiagnostic) { const node = getNameOfDeclaration(declaration) || declaration; if (isIdentifierThatStartsWithUnderScore(node)) { const declaration = getRootDeclaration(node.parent); @@ -21657,7 +21683,7 @@ namespace ts { } if (!isRemovedPropertyFromObjectSpread(node.kind === SyntaxKind.Identifier ? node.parent : node)) { - addErrorOrSuggestion(/*isError*/ compilerOptions.noUnusedLocals, createDiagnosticForNodeSpan(getSourceFileOfNode(declaration), declaration, node, Diagnostics._0_is_declared_but_its_value_is_never_read, name)); + addDiagnostic(UnusedKind.Local, createDiagnosticForNodeSpan(getSourceFileOfNode(declaration), declaration, node, Diagnostics._0_is_declared_but_its_value_is_never_read, name)); } } @@ -21669,7 +21695,7 @@ namespace ts { return isIdentifier(node) && idText(node).charCodeAt(0) === CharacterCodes._; } - function checkUnusedClassMembers(node: ClassDeclaration | ClassExpression): void { + function checkUnusedClassMembers(node: ClassDeclaration | ClassExpression, addDiagnostic: AddUnusedDiagnostic): void { if (!(node.flags & NodeFlags.Ambient)) { for (const member of node.members) { switch (member.kind) { @@ -21683,13 +21709,13 @@ namespace ts { } const symbol = getSymbolOfNode(member); if (!symbol.isReferenced && hasModifier(member, ModifierFlags.Private)) { - errorOrSuggestion(/*isError*/ compilerOptions.noUnusedLocals, member.name, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolToString(symbol)); + addDiagnostic(UnusedKind.Local, createDiagnosticForNode(member.name, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolToString(symbol))); } break; case SyntaxKind.Constructor: for (const parameter of (member).parameters) { if (!parameter.symbol.isReferenced && hasModifier(parameter, ModifierFlags.Private)) { - errorOrSuggestion(/*isError*/ compilerOptions.noUnusedLocals, parameter.name, Diagnostics.Property_0_is_declared_but_its_value_is_never_read, symbolName(parameter.symbol)); + addDiagnostic(UnusedKind.Local, createDiagnosticForNode(parameter.name, Diagnostics.Property_0_is_declared_but_its_value_is_never_read, symbolName(parameter.symbol))); } } break; @@ -21704,19 +21730,22 @@ namespace ts { } } - function checkUnusedTypeParameters(node: ClassDeclaration | ClassExpression | FunctionDeclaration | MethodDeclaration | FunctionExpression | ArrowFunction | ConstructorDeclaration | SignatureDeclaration | InterfaceDeclaration | TypeAliasDeclaration) { + function checkUnusedTypeParameters( + node: ClassDeclaration | ClassExpression | FunctionDeclaration | MethodDeclaration | FunctionExpression | ArrowFunction | ConstructorDeclaration | SignatureDeclaration | InterfaceDeclaration | TypeAliasDeclaration, + addDiagnostic: AddUnusedDiagnostic, + ): void { // Only report errors on the last declaration for the type parameter container; // this ensures that all uses have been accounted for. if (!(node.flags & NodeFlags.Ambient) && node.typeParameters && last(getSymbolOfNode(node)!.declarations) === node) { for (const typeParameter of node.typeParameters) { if (!(getMergedSymbol(typeParameter.symbol).isReferenced & SymbolFlags.TypeParameter) && !isIdentifierThatStartsWithUnderScore(typeParameter.name)) { - errorOrSuggestion(/*isError*/ compilerOptions.noUnusedParameters, typeParameter.name, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolName(typeParameter.symbol)); + addDiagnostic(UnusedKind.Parameter, createDiagnosticForNode(typeParameter.name, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolName(typeParameter.symbol))); } } } } - function checkUnusedModuleMembers(node: ModuleDeclaration | SourceFile): void { + function checkUnusedModuleMembers(node: ModuleDeclaration | SourceFile, addDiagnostic: AddUnusedDiagnostic): void { if (!(node.flags & NodeFlags.Ambient)) { // Ideally we could use the ImportClause directly as a key, but must wait until we have full ES6 maps. So must store key along with value. const unusedImports = createMap<[ImportClause, ImportedDeclaration[]]>(); @@ -21736,7 +21765,7 @@ namespace ts { } } else { - errorUnusedLocal(declaration, symbolName(local)); + errorUnusedLocal(declaration, symbolName(local), addDiagnostic); } } }); @@ -21744,13 +21773,13 @@ namespace ts { unusedImports.forEach(([importClause, unuseds]) => { const importDecl = importClause.parent; if (forEachImportedDeclaration(importClause, d => !contains(unuseds, d))) { - for (const unused of unuseds) errorUnusedLocal(unused, idText(unused.name)); + for (const unused of unuseds) errorUnusedLocal(unused, idText(unused.name), addDiagnostic); } else if (unuseds.length === 1) { - error(importDecl, Diagnostics._0_is_declared_but_its_value_is_never_read, idText(first(unuseds).name)); + addDiagnostic(UnusedKind.Local, createDiagnosticForNode(importDecl, Diagnostics._0_is_declared_but_its_value_is_never_read, idText(first(unuseds).name))); } else { - error(importDecl, Diagnostics.All_imports_in_import_declaration_are_unused, showModuleSpecifier(importDecl)); + addDiagnostic(UnusedKind.Local, createDiagnosticForNode(importDecl, Diagnostics.All_imports_in_import_declaration_are_unused, showModuleSpecifier(importDecl))); } }); } @@ -24528,6 +24557,17 @@ namespace ts { performance.measure("Check", "beforeCheck", "afterCheck"); } + function unusedIsError(kind: UnusedKind): boolean { + switch (kind) { + case UnusedKind.Local: + return compilerOptions.noUnusedLocals; + case UnusedKind.Parameter: + return compilerOptions.noUnusedParameters; + default: + return Debug.assertNever(kind); + } + } + // Fully type check a source file and collect the relevant diagnostics. function checkSourceFileWorker(node: SourceFile) { const links = getNodeLinks(node); @@ -24546,8 +24586,10 @@ namespace ts { clear(potentialNewTargetCollisions); deferredNodes = []; - deferredUnusedIdentifierNodes = produceDiagnostics ? [] : undefined; - flowAnalysisDisabled = false; + if (produceDiagnostics) { + Debug.assert(!allPotentiallyUnusedIdentifiers.has(node.fileName)); + allPotentiallyUnusedIdentifiers.set(node.fileName, potentiallyUnusedIdentifiers = []); + } forEach(node.statements, checkSourceElement); @@ -24557,12 +24599,16 @@ namespace ts { registerForUnusedIdentifiersCheck(node); } - if (!node.isDeclarationFile) { - checkUnusedIdentifiers(); + if (!node.isDeclarationFile && (compilerOptions.noUnusedLocals || compilerOptions.noUnusedParameters)) { + checkUnusedIdentifiers(potentiallyUnusedIdentifiers, (kind, diag) => { + if (unusedIsError(kind)) { + diagnostics.add(diag); + } + }); } deferredNodes = undefined; - deferredUnusedIdentifierNodes = undefined; + potentiallyUnusedIdentifiers = undefined; if (isExternalOrCommonJsModule(node)) { checkExternalModuleExports(node); diff --git a/tests/cases/fourslash/annotateWithTypeFromJSDoc15.ts b/tests/cases/fourslash/annotateWithTypeFromJSDoc15.ts index 2f15a8f811296..9d26eaa8cdeb0 100644 --- a/tests/cases/fourslash/annotateWithTypeFromJSDoc15.ts +++ b/tests/cases/fourslash/annotateWithTypeFromJSDoc15.ts @@ -30,14 +30,6 @@ verify.codeFix({ * @param {promise} zeta */ function f(x: boolean, y: string, z: number, alpha: object, beta: Date, gamma: Promise, delta: Array, epsilon: Array, zeta: Promise) { - x; - y; - z; - alpha; - beta; - gamma; - delta; - epsilon; - zeta; + x; y; z; alpha; beta; gamma; delta; epsilon; zeta; }`, }); diff --git a/tests/cases/fourslash/annotateWithTypeFromJSDoc22.ts b/tests/cases/fourslash/annotateWithTypeFromJSDoc22.ts index d66b9b1be0272..9163805bfcfdd 100644 --- a/tests/cases/fourslash/annotateWithTypeFromJSDoc22.ts +++ b/tests/cases/fourslash/annotateWithTypeFromJSDoc22.ts @@ -14,7 +14,6 @@ verify.codeFix({ /** @param {Object} sb * @param {Object} ns */ function f(sb: { [s: string]: boolean; }, ns: { [n: number]: string; }) { - sb; - ns; + sb; ns; }`, }); diff --git a/tests/cases/fourslash/annotateWithTypeFromJSDoc3.ts b/tests/cases/fourslash/annotateWithTypeFromJSDoc3.ts index fd59072bca441..c5013b80cf17b 100644 --- a/tests/cases/fourslash/annotateWithTypeFromJSDoc3.ts +++ b/tests/cases/fourslash/annotateWithTypeFromJSDoc3.ts @@ -27,10 +27,6 @@ verify.codeFix({ * @param {*} beta - I have no idea how this got here */ function f(x: number, y: { a: string; b: Date; }, z: string, alpha, beta: any) { - x; - y; - z; - alpha; - beta; + x; y; z; alpha; beta; }`, }); diff --git a/tests/cases/fourslash/annotateWithTypeFromJSDoc4.ts b/tests/cases/fourslash/annotateWithTypeFromJSDoc4.ts index 36abea171e078..c6010bf6cd002 100644 --- a/tests/cases/fourslash/annotateWithTypeFromJSDoc4.ts +++ b/tests/cases/fourslash/annotateWithTypeFromJSDoc4.ts @@ -26,12 +26,6 @@ verify.codeFix({ * @param {number!} delta */ function f(x: any, y: any, z: number | undefined, alpha: number[], beta: (this: { a: string; }, arg1: string, arg2: number) => boolean, gamma: number | null, delta: number) { - x; - y; - z; - alpha; - beta; - gamma; - delta; + x; y; z; alpha; beta; gamma; delta; }`, }); diff --git a/tests/cases/fourslash/annotateWithTypeFromJSDoc8.ts b/tests/cases/fourslash/annotateWithTypeFromJSDoc8.ts index b53159144eb85..40ddf4fad0e8a 100644 --- a/tests/cases/fourslash/annotateWithTypeFromJSDoc8.ts +++ b/tests/cases/fourslash/annotateWithTypeFromJSDoc8.ts @@ -15,7 +15,7 @@ verify.codeFix({ * @param {number} x * @returns {number} */ -var f = function(x: number): number { +var f = function (x: number): number { return x }`, }); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_referenced.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_referenced.ts index ff87d3c6948c2..ef7c1bcf4dedc 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_export_referenced.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_referenced.ts @@ -11,12 +11,13 @@ ////exports.y; //// ////exports.z = 2; -////function f(z) { -//// exports.z; +////exports.f = function(z) { +//// exports.z; z; ////} verify.codeFix({ description: "Convert to ES6 module", + // TODO: GH#22492 newFileContent: `export const x = 0; x; @@ -28,7 +29,7 @@ _y; const _z = 2; export { _z as z }; -function f(z) { - _z; +export function f(z) { + _z z; }`, }); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_expressionToDeclaration.ts b/tests/cases/fourslash/refactorConvertToEs6Module_expressionToDeclaration.ts index 746524e849c85..0525a2b881cca 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_expressionToDeclaration.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_expressionToDeclaration.ts @@ -3,13 +3,13 @@ // @allowJs: true // @Filename: /a.js -////exports.f = async function* f(p) {} +////exports.f = async function* f(p) { p; } ////exports.C = class C extends D { m() {} } verify.codeFix({ description: "Convert to ES6 module", newFileContent: -`export async function* f(p) { } +`export async function* f(p) { p; } export class C extends D { m() { } }`, diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_arrayBindingPattern.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_arrayBindingPattern.ts index d7e857b5d5e41..2c53f48a6ebdb 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_import_arrayBindingPattern.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_arrayBindingPattern.ts @@ -4,9 +4,11 @@ // @Filename: /a.js ////const [x, y] = /*a*/require/*b*/("x"); +////x; y; verify.codeFix({ description: "Convert to ES6 module", newFileContent: `import _x from "x"; -const [x, y] = _x;`, +const [x, y] = _x; +x; y;`, }); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_multipleUniqueIdentifiers.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_multipleUniqueIdentifiers.ts index a42f1fe5321d7..44750b76e6ee9 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_import_multipleUniqueIdentifiers.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_multipleUniqueIdentifiers.ts @@ -6,6 +6,7 @@ ////const x = require("x"); ////const [a, b] = require("x"); ////const {c, ...d} = require("x"); +////x; a; b; c; d; verify.codeFix({ description: "Convert to ES6 module", @@ -14,5 +15,6 @@ verify.codeFix({ import _x from "x"; const [a, b] = _x; import __x from "x"; -const { c, ...d } = __x;`, +const { c, ...d } = __x; +x; a; b; c; d;`, }); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_multipleVariableDeclarations.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_multipleVariableDeclarations.ts index 3c45950c90d93..ae387c060c748 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_import_multipleVariableDeclarations.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_multipleVariableDeclarations.ts @@ -6,11 +6,13 @@ // @Filename: /a.js ////const x = require("x"), y = 0, { z } = require("z"); +////x; y; z; verify.codeFix({ description: "Convert to ES6 module", newFileContent: `import x from "x"; const y = 0; -import { z } from "z";`, +import { z } from "z"; +x; y; z;`, }); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_complex.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_complex.ts index 32df990696490..f1397e462076d 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_complex.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_complex.ts @@ -4,10 +4,12 @@ // @Filename: /a.js ////const { x: { a, b } } = require("x"); +////a; b; verify.codeFix({ description: "Convert to ES6 module", newFileContent: `import x from "x"; -const { x: { a, b } } = x;`, +const { x: { a, b } } = x; +a; b;`, }); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_plain.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_plain.ts index 4bff560e530c1..52cb72783b1e0 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_plain.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_plain.ts @@ -4,8 +4,11 @@ // @Filename: /a.js ////const { x, y: z } = require("x"); +////x; z; verify.codeFix({ description: "Convert to ES6 module", - newFileContent: 'import { x, y as z } from "x";', + newFileContent: +`import { x, y as z } from "x"; +x; z;`, }); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_propertyAccess.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_propertyAccess.ts index 34c6ee6aa57f1..8d299d4f0ecb0 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_import_propertyAccess.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_propertyAccess.ts @@ -8,6 +8,7 @@ ////const a = require("a").a; ////const [a, b] = require("c").d; ////const [a, b] = require("c").a; // Test that we avoid shadowing the earlier local variable 'a' from 'const [a,b] = d;'. +////x; a; b; verify.codeFix({ description: "Convert to ES6 module", @@ -18,5 +19,6 @@ import { a } from "a"; import { d } from "c"; const [a, b] = d; import { a as _a } from "c"; -const [a, b] = _a; // Test that we avoid shadowing the earlier local variable 'a' from 'const [a,b] = d;'.`, +const [a, b] = _a; // Test that we avoid shadowing the earlier local variable 'a' from 'const [a,b] = d;'. +x; a; b;`, });