From 0c4ceeec24f16f87e75386355c86ac38612a1175 Mon Sep 17 00:00:00 2001 From: Andy Date: Fri, 16 Nov 2018 08:35:36 -0800 Subject: [PATCH] Don't consider 'typeof a' as using 'a' (#28528) * Don't consider 'typeof a' as using 'a' * Also handle markPropertyAsReferenced * Use isInTypeQuery --- src/compiler/checker.ts | 4 ++-- .../unusedParameterUsedInTypeOf.errors.txt | 9 +++++++++ .../unusedPropertyUsedInTypeOf.errors.txt | 11 +++++++++++ .../reference/unusedPropertyUsedInTypeOf.js | 14 ++++++++++++++ .../reference/unusedPropertyUsedInTypeOf.symbols | 16 ++++++++++++++++ .../reference/unusedPropertyUsedInTypeOf.types | 16 ++++++++++++++++ .../cases/compiler/unusedPropertyUsedInTypeOf.ts | 7 +++++++ 7 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/unusedParameterUsedInTypeOf.errors.txt create mode 100644 tests/baselines/reference/unusedPropertyUsedInTypeOf.errors.txt create mode 100644 tests/baselines/reference/unusedPropertyUsedInTypeOf.js create mode 100644 tests/baselines/reference/unusedPropertyUsedInTypeOf.symbols create mode 100644 tests/baselines/reference/unusedPropertyUsedInTypeOf.types create mode 100644 tests/cases/compiler/unusedPropertyUsedInTypeOf.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e88da2c261..1ad721ad5b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1478,7 +1478,7 @@ namespace ts { // We just climbed up parents looking for the name, meaning that we started in a descendant node of `lastLocation`. // If `result === lastSelfReferenceLocation.symbol`, that means that we are somewhere inside `lastSelfReferenceLocation` 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 && (!lastSelfReferenceLocation || result !== lastSelfReferenceLocation.symbol)) { + if (isUse && result && (!lastSelfReferenceLocation || result !== lastSelfReferenceLocation.symbol) && !isInTypeQuery(originalLocation!)) { result.isReferenced! |= meaning; } @@ -19022,7 +19022,7 @@ namespace ts { } function markPropertyAsReferenced(prop: Symbol, nodeForCheckWriteOnly: Node | undefined, isThisAccess: boolean) { - if (!prop || !(prop.flags & SymbolFlags.ClassMember) || !prop.valueDeclaration || !hasModifier(prop.valueDeclaration, ModifierFlags.Private)) { + if (nodeForCheckWriteOnly && isInTypeQuery(nodeForCheckWriteOnly) || !prop || !(prop.flags & SymbolFlags.ClassMember) || !prop.valueDeclaration || !hasModifier(prop.valueDeclaration, ModifierFlags.Private)) { return; } if (nodeForCheckWriteOnly && isWriteOnlyAccess(nodeForCheckWriteOnly) && !(prop.flags & SymbolFlags.SetAccessor && !(prop.flags & SymbolFlags.GetAccessor))) { diff --git a/tests/baselines/reference/unusedParameterUsedInTypeOf.errors.txt b/tests/baselines/reference/unusedParameterUsedInTypeOf.errors.txt new file mode 100644 index 0000000000..a2a30badc4 --- /dev/null +++ b/tests/baselines/reference/unusedParameterUsedInTypeOf.errors.txt @@ -0,0 +1,9 @@ +tests/cases/compiler/unusedParameterUsedInTypeOf.ts(1,14): error TS6133: 'a' is declared but its value is never read. + + +==== tests/cases/compiler/unusedParameterUsedInTypeOf.ts (1 errors) ==== + function f1 (a: number, b: typeof a) { + ~ +!!! error TS6133: 'a' is declared but its value is never read. + return b; + } \ No newline at end of file diff --git a/tests/baselines/reference/unusedPropertyUsedInTypeOf.errors.txt b/tests/baselines/reference/unusedPropertyUsedInTypeOf.errors.txt new file mode 100644 index 0000000000..60657d9c8c --- /dev/null +++ b/tests/baselines/reference/unusedPropertyUsedInTypeOf.errors.txt @@ -0,0 +1,11 @@ +tests/cases/compiler/unusedPropertyUsedInTypeOf.ts(2,29): error TS6133: 'x' is declared but its value is never read. + + +==== tests/cases/compiler/unusedPropertyUsedInTypeOf.ts (1 errors) ==== + class C { + private static readonly x: number; + ~ +!!! error TS6133: 'x' is declared but its value is never read. + m(p: typeof C.x) { return p; } + } + \ No newline at end of file diff --git a/tests/baselines/reference/unusedPropertyUsedInTypeOf.js b/tests/baselines/reference/unusedPropertyUsedInTypeOf.js new file mode 100644 index 0000000000..98a1e9f002 --- /dev/null +++ b/tests/baselines/reference/unusedPropertyUsedInTypeOf.js @@ -0,0 +1,14 @@ +//// [unusedPropertyUsedInTypeOf.ts] +class C { + private static readonly x: number; + m(p: typeof C.x) { return p; } +} + + +//// [unusedPropertyUsedInTypeOf.js] +var C = /** @class */ (function () { + function C() { + } + C.prototype.m = function (p) { return p; }; + return C; +}()); diff --git a/tests/baselines/reference/unusedPropertyUsedInTypeOf.symbols b/tests/baselines/reference/unusedPropertyUsedInTypeOf.symbols new file mode 100644 index 0000000000..9715c3fa11 --- /dev/null +++ b/tests/baselines/reference/unusedPropertyUsedInTypeOf.symbols @@ -0,0 +1,16 @@ +=== tests/cases/compiler/unusedPropertyUsedInTypeOf.ts === +class C { +>C : Symbol(C, Decl(unusedPropertyUsedInTypeOf.ts, 0, 0)) + + private static readonly x: number; +>x : Symbol(C.x, Decl(unusedPropertyUsedInTypeOf.ts, 0, 9)) + + m(p: typeof C.x) { return p; } +>m : Symbol(C.m, Decl(unusedPropertyUsedInTypeOf.ts, 1, 38)) +>p : Symbol(p, Decl(unusedPropertyUsedInTypeOf.ts, 2, 6)) +>C.x : Symbol(C.x, Decl(unusedPropertyUsedInTypeOf.ts, 0, 9)) +>C : Symbol(C, Decl(unusedPropertyUsedInTypeOf.ts, 0, 0)) +>x : Symbol(C.x, Decl(unusedPropertyUsedInTypeOf.ts, 0, 9)) +>p : Symbol(p, Decl(unusedPropertyUsedInTypeOf.ts, 2, 6)) +} + diff --git a/tests/baselines/reference/unusedPropertyUsedInTypeOf.types b/tests/baselines/reference/unusedPropertyUsedInTypeOf.types new file mode 100644 index 0000000000..12b40eb5ff --- /dev/null +++ b/tests/baselines/reference/unusedPropertyUsedInTypeOf.types @@ -0,0 +1,16 @@ +=== tests/cases/compiler/unusedPropertyUsedInTypeOf.ts === +class C { +>C : C + + private static readonly x: number; +>x : number + + m(p: typeof C.x) { return p; } +>m : (p: number) => number +>p : number +>C.x : number +>C : typeof C +>x : number +>p : number +} + diff --git a/tests/cases/compiler/unusedPropertyUsedInTypeOf.ts b/tests/cases/compiler/unusedPropertyUsedInTypeOf.ts new file mode 100644 index 0000000000..41c685e4b0 --- /dev/null +++ b/tests/cases/compiler/unusedPropertyUsedInTypeOf.ts @@ -0,0 +1,7 @@ +// @noUnusedLocals:true +// @noUnusedParameters:true + +class C { + private static readonly x: number; + m(p: typeof C.x) { return p; } +}