diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 33ff04697f9c5..be94a7ce4e39c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -10241,9 +10241,12 @@ namespace ts { return unknownType; } - if (noUnusedIdentifiers && (prop.flags & SymbolFlags.ClassMember)) { + if (noUnusedIdentifiers && + (prop.flags & SymbolFlags.ClassMember) && + prop.valueDeclaration && (prop.valueDeclaration.flags & NodeFlags.Private)) { if (prop.flags & SymbolFlags.Instantiated) { getSymbolLinks(prop).target.isReferenced = true; + } else { prop.isReferenced = true; @@ -14513,10 +14516,11 @@ namespace ts { checkUnusedTypeParameters(node); break; case SyntaxKind.Block: + case SyntaxKind.CaseBlock: case SyntaxKind.ForStatement: case SyntaxKind.ForInStatement: case SyntaxKind.ForOfStatement: - checkUnusedLocalsAndParameters(node); + checkUnusedLocalsAndParameters(node); break; case SyntaxKind.Constructor: case SyntaxKind.FunctionExpression: @@ -14543,7 +14547,7 @@ namespace ts { } } - function checkUnusedLocalsAndParameters(node: FunctionLikeDeclaration | ForStatement | Block): void { + function checkUnusedLocalsAndParameters(node: Node): void { if (node.parent.kind !== SyntaxKind.InterfaceDeclaration && noUnusedIdentifiers && !isInAmbientContext(node)) { for (const key in node.locals) { if (hasProperty(node.locals, key)) { @@ -14568,13 +14572,13 @@ namespace ts { if (node.members) { for (const member of node.members) { if (member.kind === SyntaxKind.MethodDeclaration || member.kind === SyntaxKind.PropertyDeclaration) { - if (isPrivateNode(member) && !member.symbol.isReferenced) { + if (!member.symbol.isReferenced && member.flags & NodeFlags.Private) { error(member.name, Diagnostics._0_is_declared_but_never_used, member.symbol.name); } } else if (member.kind === SyntaxKind.Constructor) { for (const parameter of (member).parameters) { - if (isPrivateNode(parameter) && !parameter.symbol.isReferenced) { + if (!parameter.symbol.isReferenced && parameter.flags & NodeFlags.Private) { error(parameter.name, Diagnostics._0_is_declared_but_never_used, parameter.symbol.name); } } @@ -14596,10 +14600,6 @@ namespace ts { } } - function isPrivateNode(node: Node): boolean { - return (node.flags & NodeFlags.Private) !== 0; - } - function checkUnusedModuleMembers(node: ModuleDeclaration | SourceFile): void { if (compilerOptions.noUnusedLocals && !isInAmbientContext(node)) { for (const key in node.locals) { @@ -15090,7 +15090,9 @@ namespace ts { if (node.condition) checkExpression(node.condition); if (node.incrementor) checkExpression(node.incrementor); checkSourceElement(node.statement); - registerForUnusedIdentifiersCheck(node); + if (node.locals) { + registerForUnusedIdentifiersCheck(node); + } } function checkForOfStatement(node: ForOfStatement): void { @@ -15556,6 +15558,9 @@ namespace ts { } forEach(clause.statements, checkSourceElement); }); + if (node.caseBlock.locals) { + registerForUnusedIdentifiersCheck(node.caseBlock); + } } function checkLabeledStatement(node: LabeledStatement) { diff --git a/tests/baselines/reference/unusedSwitchStatment.errors.txt b/tests/baselines/reference/unusedSwitchStatment.errors.txt new file mode 100644 index 0000000000000..58359eed90d27 --- /dev/null +++ b/tests/baselines/reference/unusedSwitchStatment.errors.txt @@ -0,0 +1,31 @@ +tests/cases/compiler/unusedSwitchStatment.ts(4,13): error TS6133: 'x' is declared but never used. +tests/cases/compiler/unusedSwitchStatment.ts(7,15): error TS6133: 'c' is declared but never used. +tests/cases/compiler/unusedSwitchStatment.ts(10,13): error TS6133: 'z' is declared but never used. + + +==== tests/cases/compiler/unusedSwitchStatment.ts (3 errors) ==== + + switch (1) { + case 0: + let x; + ~ +!!! error TS6133: 'x' is declared but never used. + break; + case 1: + const c = 1; + ~ +!!! error TS6133: 'c' is declared but never used. + break; + default: + let z = 2; + ~ +!!! error TS6133: 'z' is declared but never used. + } + + + switch (2) { + case 0: + let x; + case 1: + x++; + } \ No newline at end of file diff --git a/tests/baselines/reference/unusedSwitchStatment.js b/tests/baselines/reference/unusedSwitchStatment.js new file mode 100644 index 0000000000000..2fd0d1fc49ee8 --- /dev/null +++ b/tests/baselines/reference/unusedSwitchStatment.js @@ -0,0 +1,38 @@ +//// [unusedSwitchStatment.ts] + +switch (1) { + case 0: + let x; + break; + case 1: + const c = 1; + break; + default: + let z = 2; +} + + +switch (2) { + case 0: + let x; + case 1: + x++; +} + +//// [unusedSwitchStatment.js] +switch (1) { + case 0: + var x = void 0; + break; + case 1: + var c = 1; + break; + default: + var z = 2; +} +switch (2) { + case 0: + var x = void 0; + case 1: + x++; +} diff --git a/tests/cases/compiler/unusedSwitchStatment.ts b/tests/cases/compiler/unusedSwitchStatment.ts new file mode 100644 index 0000000000000..53f93b913aad0 --- /dev/null +++ b/tests/cases/compiler/unusedSwitchStatment.ts @@ -0,0 +1,21 @@ +//@noUnusedLocals:true +//@noUnusedParameters:true + +switch (1) { + case 0: + let x; + break; + case 1: + const c = 1; + break; + default: + let z = 2; +} + + +switch (2) { + case 0: + let x; + case 1: + x++; +} \ No newline at end of file