Don't count self-reference in more cases (skip more nodes when setting lastNonBlockLocation) (#21095)

This commit is contained in:
Andy 2018-01-09 09:53:39 -08:00 committed by GitHub
parent 062f97a6fa
commit 5ab5694a5b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 161 additions and 2 deletions

View File

@ -1187,7 +1187,7 @@ namespace ts {
}
break;
}
if (location.kind !== SyntaxKind.Block) {
if (isNonBlockLocation(location)) {
lastNonBlockLocation = location;
}
lastLocation = location;
@ -1195,7 +1195,7 @@ namespace ts {
}
// We just climbed up parents looking for the name, meaning that we started in a descendant node of `lastLocation`.
// If `result === lastLocation.symbol`, that means that we are somewhere inside `lastLocation` looking up a name, and resolving to `lastLocation` itself.
// If `result === lastNonBlockLocation.symbol`, that means that we are somewhere inside `lastNonBlockLocation` looking up a name, and resolving to `lastLocation` itself.
// That means that this is a self-reference of `lastLocation`, and shouldn't count this when considering whether `lastLocation` is used.
if (isUse && result && nameNotFoundMessage && noUnusedIdentifiers && result !== lastNonBlockLocation.symbol) {
result.isReferenced = true;
@ -1278,6 +1278,20 @@ namespace ts {
return result;
}
function isNonBlockLocation({ kind }: Node): boolean {
switch (kind) {
case SyntaxKind.Block:
case SyntaxKind.ModuleBlock:
case SyntaxKind.SwitchStatement:
case SyntaxKind.CaseBlock:
case SyntaxKind.CaseClause:
case SyntaxKind.DefaultClause:
return false;
default:
return true;
}
}
function diagnosticName(nameArg: __String | Identifier) {
return isString(nameArg) ? unescapeLeadingUnderscores(nameArg as __String) : declarationNameToString(nameArg as Identifier);
}

View File

@ -0,0 +1,29 @@
tests/cases/compiler/noUnusedLocals_selfReference_skipsBlockLocations.ts(2,14): error TS6133: 'f' is declared but its value is never read.
tests/cases/compiler/noUnusedLocals_selfReference_skipsBlockLocations.ts(8,22): error TS6133: 'g' is declared but its value is never read.
tests/cases/compiler/noUnusedLocals_selfReference_skipsBlockLocations.ts(12,22): error TS6133: 'h' is declared but its value is never read.
==== tests/cases/compiler/noUnusedLocals_selfReference_skipsBlockLocations.ts (3 errors) ====
namespace n {
function f() {
~
!!! error TS6133: 'f' is declared but its value is never read.
f;
}
switch (0) {
case 0:
function g() {
~
!!! error TS6133: 'g' is declared but its value is never read.
g;
}
default:
function h() {
~
!!! error TS6133: 'h' is declared but its value is never read.
h;
}
}
}

View File

@ -0,0 +1,36 @@
//// [noUnusedLocals_selfReference_skipsBlockLocations.ts]
namespace n {
function f() {
f;
}
switch (0) {
case 0:
function g() {
g;
}
default:
function h() {
h;
}
}
}
//// [noUnusedLocals_selfReference_skipsBlockLocations.js]
var n;
(function (n) {
function f() {
f;
}
switch (0) {
case 0:
function g() {
g;
}
default:
function h() {
h;
}
}
})(n || (n = {}));

View File

@ -0,0 +1,29 @@
=== tests/cases/compiler/noUnusedLocals_selfReference_skipsBlockLocations.ts ===
namespace n {
>n : Symbol(n, Decl(noUnusedLocals_selfReference_skipsBlockLocations.ts, 0, 0))
function f() {
>f : Symbol(f, Decl(noUnusedLocals_selfReference_skipsBlockLocations.ts, 0, 13))
f;
>f : Symbol(f, Decl(noUnusedLocals_selfReference_skipsBlockLocations.ts, 0, 13))
}
switch (0) {
case 0:
function g() {
>g : Symbol(g, Decl(noUnusedLocals_selfReference_skipsBlockLocations.ts, 6, 15))
g;
>g : Symbol(g, Decl(noUnusedLocals_selfReference_skipsBlockLocations.ts, 6, 15))
}
default:
function h() {
>h : Symbol(h, Decl(noUnusedLocals_selfReference_skipsBlockLocations.ts, 10, 16))
h;
>h : Symbol(h, Decl(noUnusedLocals_selfReference_skipsBlockLocations.ts, 10, 16))
}
}
}

View File

@ -0,0 +1,33 @@
=== tests/cases/compiler/noUnusedLocals_selfReference_skipsBlockLocations.ts ===
namespace n {
>n : typeof n
function f() {
>f : () => void
f;
>f : () => void
}
switch (0) {
>0 : 0
case 0:
>0 : 0
function g() {
>g : () => void
g;
>g : () => void
}
default:
function h() {
>h : () => void
h;
>h : () => void
}
}
}

View File

@ -0,0 +1,18 @@
// @noUnusedLocals: true
namespace n {
function f() {
f;
}
switch (0) {
case 0:
function g() {
g;
}
default:
function h() {
h;
}
}
}