From 2cc6c4cc289c1e6f8d622a8c5da616357d1230f0 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 8 Dec 2015 14:28:35 -0800 Subject: [PATCH 01/79] Fixed test to explicitly have return type annotation. --- .../types/stringLiteral/stringLiteralTypesOverloads01.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cases/conformance/types/stringLiteral/stringLiteralTypesOverloads01.ts b/tests/cases/conformance/types/stringLiteral/stringLiteralTypesOverloads01.ts index d88167eaeff..00441134405 100644 --- a/tests/cases/conformance/types/stringLiteral/stringLiteralTypesOverloads01.ts +++ b/tests/cases/conformance/types/stringLiteral/stringLiteralTypesOverloads01.ts @@ -9,7 +9,7 @@ function getFalsyPrimitive(x: "boolean" | "string"): boolean | string; function getFalsyPrimitive(x: "boolean" | "number"): boolean | number; function getFalsyPrimitive(x: "number" | "string"): number | string; function getFalsyPrimitive(x: "number" | "string" | "boolean"): number | string | boolean; -function getFalsyPrimitive(x: PrimitiveName) { +function getFalsyPrimitive(x: PrimitiveName): number | string | boolean { if (x === "string") { return ""; } From 5ef8a306422abded21cb09e87f6b4cada7d4fb2d Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 8 Dec 2015 14:34:20 -0800 Subject: [PATCH 02/79] Accepted baselines. --- .../reference/stringLiteralTypesOverloads01.errors.txt | 8 ++++---- .../baselines/reference/stringLiteralTypesOverloads01.js | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/baselines/reference/stringLiteralTypesOverloads01.errors.txt b/tests/baselines/reference/stringLiteralTypesOverloads01.errors.txt index 1592427208b..0a3fdb91929 100644 --- a/tests/baselines/reference/stringLiteralTypesOverloads01.errors.txt +++ b/tests/baselines/reference/stringLiteralTypesOverloads01.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/types/stringLiteral/stringLiteralTypesOverloads01.ts(11,10): error TS2354: No best common type exists among return expressions. +tests/cases/conformance/types/stringLiteral/stringLiteralTypesOverloads01.ts(7,10): error TS2394: Overload signature is not compatible with function implementation. ==== tests/cases/conformance/types/stringLiteral/stringLiteralTypesOverloads01.ts (1 errors) ==== @@ -9,12 +9,12 @@ tests/cases/conformance/types/stringLiteral/stringLiteralTypesOverloads01.ts(11, function getFalsyPrimitive(x: "number"): number; function getFalsyPrimitive(x: "boolean"): boolean; function getFalsyPrimitive(x: "boolean" | "string"): boolean | string; + ~~~~~~~~~~~~~~~~~ +!!! error TS2394: Overload signature is not compatible with function implementation. function getFalsyPrimitive(x: "boolean" | "number"): boolean | number; function getFalsyPrimitive(x: "number" | "string"): number | string; function getFalsyPrimitive(x: "number" | "string" | "boolean"): number | string | boolean; - function getFalsyPrimitive(x: PrimitiveName) { - ~~~~~~~~~~~~~~~~~ -!!! error TS2354: No best common type exists among return expressions. + function getFalsyPrimitive(x: PrimitiveName): number | string | boolean { if (x === "string") { return ""; } diff --git a/tests/baselines/reference/stringLiteralTypesOverloads01.js b/tests/baselines/reference/stringLiteralTypesOverloads01.js index 73dabd26fab..f3331c9f717 100644 --- a/tests/baselines/reference/stringLiteralTypesOverloads01.js +++ b/tests/baselines/reference/stringLiteralTypesOverloads01.js @@ -9,7 +9,7 @@ function getFalsyPrimitive(x: "boolean" | "string"): boolean | string; function getFalsyPrimitive(x: "boolean" | "number"): boolean | number; function getFalsyPrimitive(x: "number" | "string"): number | string; function getFalsyPrimitive(x: "number" | "string" | "boolean"): number | string | boolean; -function getFalsyPrimitive(x: PrimitiveName) { +function getFalsyPrimitive(x: PrimitiveName): number | string | boolean { if (x === "string") { return ""; } From 2c2b8be2386f5a29b085ecb489b22786b8acba03 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 8 Dec 2015 14:53:05 -0800 Subject: [PATCH 03/79] Remove empty test. --- .../functions/conformanceFunctionOverloads.ts | 22 ------------------- 1 file changed, 22 deletions(-) delete mode 100644 tests/cases/conformance/functions/conformanceFunctionOverloads.ts diff --git a/tests/cases/conformance/functions/conformanceFunctionOverloads.ts b/tests/cases/conformance/functions/conformanceFunctionOverloads.ts deleted file mode 100644 index f1e08782a51..00000000000 --- a/tests/cases/conformance/functions/conformanceFunctionOverloads.ts +++ /dev/null @@ -1,22 +0,0 @@ -// Function overloads do not emit code - -// Function overload signature with optional parameter - -// Function overload signature with optional parameter - -// Function overloads with generic and non-generic overloads - -// Function overloads whose only difference is returning different unconstrained generic parameters - -// Function overloads whose only difference is returning different constrained generic parameters - -// Function overloads that differ only by type parameter constraints - -// Function overloads with matching accessibility - -// Function overloads with matching export - -// Function overloads with more params than implementation signature - -// Function overloads where return types are same infinitely recursive type reference - From 820a2cb257ae3926b7752c69f0bf31959e4114bb Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 8 Dec 2015 15:03:58 -0800 Subject: [PATCH 04/79] Added some tests for overload compatibility. --- tests/cases/compiler/functionOverloads43.ts | 12 +++++++++++ tests/cases/compiler/functionOverloads44.ts | 22 +++++++++++++++++++++ tests/cases/compiler/functionOverloads45.ts | 22 +++++++++++++++++++++ 3 files changed, 56 insertions(+) create mode 100644 tests/cases/compiler/functionOverloads43.ts create mode 100644 tests/cases/compiler/functionOverloads44.ts create mode 100644 tests/cases/compiler/functionOverloads45.ts diff --git a/tests/cases/compiler/functionOverloads43.ts b/tests/cases/compiler/functionOverloads43.ts new file mode 100644 index 00000000000..8822fd86c1b --- /dev/null +++ b/tests/cases/compiler/functionOverloads43.ts @@ -0,0 +1,12 @@ +function foo(bar: { a:number }[]): number; +function foo(bar: { a:string }[]): string; +function foo([x]: { a:number | string }[]): string | number { + if (x) { + return x.a; + } + + return undefined; +} + +var x = foo([{a: "str"}]); +var y = foo([{a: 100}]); \ No newline at end of file diff --git a/tests/cases/compiler/functionOverloads44.ts b/tests/cases/compiler/functionOverloads44.ts new file mode 100644 index 00000000000..20a7ed540f0 --- /dev/null +++ b/tests/cases/compiler/functionOverloads44.ts @@ -0,0 +1,22 @@ +interface Animal { animal } +interface Dog extends Animal { dog } +interface Cat extends Animal { cat } + +function foo1(bar: { a:number }[]): Dog; +function foo1(bar: { a:string }[]): Animal; +function foo1([x]: { a:number | string }[]): Dog { + return undefined; +} + +function foo2(bar: { a:number }[]): Cat; +function foo2(bar: { a:string }[]): Cat | Dog; +function foo2([x]: { a:number | string }[]): Cat { + return undefined; +} + + +var x1 = foo1([{a: "str"}]); +var y1 = foo1([{a: 100}]); + +var x2 = foo2([{a: "str"}]); +var y2 = foo2([{a: 100}]); \ No newline at end of file diff --git a/tests/cases/compiler/functionOverloads45.ts b/tests/cases/compiler/functionOverloads45.ts new file mode 100644 index 00000000000..6210bd13427 --- /dev/null +++ b/tests/cases/compiler/functionOverloads45.ts @@ -0,0 +1,22 @@ +interface Animal { animal } +interface Dog extends Animal { dog } +interface Cat extends Animal { cat } + +function foo1(bar: { a:number }[]): Cat; +function foo1(bar: { a:string }[]): Dog; +function foo1([x]: { a:number | string }[]): Animal { + return undefined; +} + +function foo2(bar: { a:number }[]): Cat; +function foo2(bar: { a:string }[]): Dog; +function foo2([x]: { a:number | string }[]): Cat | Dog { + return undefined; +} + + +var x1 = foo1([{a: "str"}]); +var y1 = foo1([{a: 100}]); + +var x2 = foo2([{a: "str"}]); +var y2 = foo2([{a: 100}]); \ No newline at end of file From 5d94e48e42a680eabb5969bb62047c6f9277a788 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 8 Dec 2015 15:12:52 -0800 Subject: [PATCH 05/79] Accepted baselines. --- .../reference/conformanceFunctionOverloads.js | 37 ------- .../conformanceFunctionOverloads.symbols | 25 ----- .../conformanceFunctionOverloads.types | 25 ----- .../reference/functionOverloads43.errors.txt | 18 ++++ .../reference/functionOverloads43.js | 24 +++++ .../reference/functionOverloads44.js | 37 +++++++ .../reference/functionOverloads44.symbols | 81 ++++++++++++++++ .../reference/functionOverloads44.types | 97 +++++++++++++++++++ .../reference/functionOverloads45.errors.txt | 31 ++++++ .../reference/functionOverloads45.js | 37 +++++++ 10 files changed, 325 insertions(+), 87 deletions(-) delete mode 100644 tests/baselines/reference/conformanceFunctionOverloads.js delete mode 100644 tests/baselines/reference/conformanceFunctionOverloads.symbols delete mode 100644 tests/baselines/reference/conformanceFunctionOverloads.types create mode 100644 tests/baselines/reference/functionOverloads43.errors.txt create mode 100644 tests/baselines/reference/functionOverloads43.js create mode 100644 tests/baselines/reference/functionOverloads44.js create mode 100644 tests/baselines/reference/functionOverloads44.symbols create mode 100644 tests/baselines/reference/functionOverloads44.types create mode 100644 tests/baselines/reference/functionOverloads45.errors.txt create mode 100644 tests/baselines/reference/functionOverloads45.js diff --git a/tests/baselines/reference/conformanceFunctionOverloads.js b/tests/baselines/reference/conformanceFunctionOverloads.js deleted file mode 100644 index b245f6a2c91..00000000000 --- a/tests/baselines/reference/conformanceFunctionOverloads.js +++ /dev/null @@ -1,37 +0,0 @@ -//// [conformanceFunctionOverloads.ts] -// Function overloads do not emit code - -// Function overload signature with optional parameter - -// Function overload signature with optional parameter - -// Function overloads with generic and non-generic overloads - -// Function overloads whose only difference is returning different unconstrained generic parameters - -// Function overloads whose only difference is returning different constrained generic parameters - -// Function overloads that differ only by type parameter constraints - -// Function overloads with matching accessibility - -// Function overloads with matching export - -// Function overloads with more params than implementation signature - -// Function overloads where return types are same infinitely recursive type reference - - - -//// [conformanceFunctionOverloads.js] -// Function overloads do not emit code -// Function overload signature with optional parameter -// Function overload signature with optional parameter -// Function overloads with generic and non-generic overloads -// Function overloads whose only difference is returning different unconstrained generic parameters -// Function overloads whose only difference is returning different constrained generic parameters -// Function overloads that differ only by type parameter constraints -// Function overloads with matching accessibility -// Function overloads with matching export -// Function overloads with more params than implementation signature -// Function overloads where return types are same infinitely recursive type reference diff --git a/tests/baselines/reference/conformanceFunctionOverloads.symbols b/tests/baselines/reference/conformanceFunctionOverloads.symbols deleted file mode 100644 index a80814ea93e..00000000000 --- a/tests/baselines/reference/conformanceFunctionOverloads.symbols +++ /dev/null @@ -1,25 +0,0 @@ -=== tests/cases/conformance/functions/conformanceFunctionOverloads.ts === -// Function overloads do not emit code -No type information for this code. -No type information for this code.// Function overload signature with optional parameter -No type information for this code. -No type information for this code.// Function overload signature with optional parameter -No type information for this code. -No type information for this code.// Function overloads with generic and non-generic overloads -No type information for this code. -No type information for this code.// Function overloads whose only difference is returning different unconstrained generic parameters -No type information for this code. -No type information for this code.// Function overloads whose only difference is returning different constrained generic parameters -No type information for this code. -No type information for this code.// Function overloads that differ only by type parameter constraints -No type information for this code. -No type information for this code.// Function overloads with matching accessibility -No type information for this code. -No type information for this code.// Function overloads with matching export -No type information for this code. -No type information for this code.// Function overloads with more params than implementation signature -No type information for this code. -No type information for this code.// Function overloads where return types are same infinitely recursive type reference -No type information for this code. -No type information for this code. -No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/conformanceFunctionOverloads.types b/tests/baselines/reference/conformanceFunctionOverloads.types deleted file mode 100644 index a80814ea93e..00000000000 --- a/tests/baselines/reference/conformanceFunctionOverloads.types +++ /dev/null @@ -1,25 +0,0 @@ -=== tests/cases/conformance/functions/conformanceFunctionOverloads.ts === -// Function overloads do not emit code -No type information for this code. -No type information for this code.// Function overload signature with optional parameter -No type information for this code. -No type information for this code.// Function overload signature with optional parameter -No type information for this code. -No type information for this code.// Function overloads with generic and non-generic overloads -No type information for this code. -No type information for this code.// Function overloads whose only difference is returning different unconstrained generic parameters -No type information for this code. -No type information for this code.// Function overloads whose only difference is returning different constrained generic parameters -No type information for this code. -No type information for this code.// Function overloads that differ only by type parameter constraints -No type information for this code. -No type information for this code.// Function overloads with matching accessibility -No type information for this code. -No type information for this code.// Function overloads with matching export -No type information for this code. -No type information for this code.// Function overloads with more params than implementation signature -No type information for this code. -No type information for this code.// Function overloads where return types are same infinitely recursive type reference -No type information for this code. -No type information for this code. -No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/functionOverloads43.errors.txt b/tests/baselines/reference/functionOverloads43.errors.txt new file mode 100644 index 00000000000..769bb467186 --- /dev/null +++ b/tests/baselines/reference/functionOverloads43.errors.txt @@ -0,0 +1,18 @@ +tests/cases/compiler/functionOverloads43.ts(1,10): error TS2394: Overload signature is not compatible with function implementation. + + +==== tests/cases/compiler/functionOverloads43.ts (1 errors) ==== + function foo(bar: { a:number }[]): number; + ~~~ +!!! error TS2394: Overload signature is not compatible with function implementation. + function foo(bar: { a:string }[]): string; + function foo([x]: { a:number | string }[]): string | number { + if (x) { + return x.a; + } + + return undefined; + } + + var x = foo([{a: "str"}]); + var y = foo([{a: 100}]); \ No newline at end of file diff --git a/tests/baselines/reference/functionOverloads43.js b/tests/baselines/reference/functionOverloads43.js new file mode 100644 index 00000000000..2bb4b61af14 --- /dev/null +++ b/tests/baselines/reference/functionOverloads43.js @@ -0,0 +1,24 @@ +//// [functionOverloads43.ts] +function foo(bar: { a:number }[]): number; +function foo(bar: { a:string }[]): string; +function foo([x]: { a:number | string }[]): string | number { + if (x) { + return x.a; + } + + return undefined; +} + +var x = foo([{a: "str"}]); +var y = foo([{a: 100}]); + +//// [functionOverloads43.js] +function foo(_a) { + var x = _a[0]; + if (x) { + return x.a; + } + return undefined; +} +var x = foo([{ a: "str" }]); +var y = foo([{ a: 100 }]); diff --git a/tests/baselines/reference/functionOverloads44.js b/tests/baselines/reference/functionOverloads44.js new file mode 100644 index 00000000000..916204d123c --- /dev/null +++ b/tests/baselines/reference/functionOverloads44.js @@ -0,0 +1,37 @@ +//// [functionOverloads44.ts] +interface Animal { animal } +interface Dog extends Animal { dog } +interface Cat extends Animal { cat } + +function foo1(bar: { a:number }[]): Dog; +function foo1(bar: { a:string }[]): Animal; +function foo1([x]: { a:number | string }[]): Dog { + return undefined; +} + +function foo2(bar: { a:number }[]): Cat; +function foo2(bar: { a:string }[]): Cat | Dog; +function foo2([x]: { a:number | string }[]): Cat { + return undefined; +} + + +var x1 = foo1([{a: "str"}]); +var y1 = foo1([{a: 100}]); + +var x2 = foo2([{a: "str"}]); +var y2 = foo2([{a: 100}]); + +//// [functionOverloads44.js] +function foo1(_a) { + var x = _a[0]; + return undefined; +} +function foo2(_a) { + var x = _a[0]; + return undefined; +} +var x1 = foo1([{ a: "str" }]); +var y1 = foo1([{ a: 100 }]); +var x2 = foo2([{ a: "str" }]); +var y2 = foo2([{ a: 100 }]); diff --git a/tests/baselines/reference/functionOverloads44.symbols b/tests/baselines/reference/functionOverloads44.symbols new file mode 100644 index 00000000000..3520777a835 --- /dev/null +++ b/tests/baselines/reference/functionOverloads44.symbols @@ -0,0 +1,81 @@ +=== tests/cases/compiler/functionOverloads44.ts === +interface Animal { animal } +>Animal : Symbol(Animal, Decl(functionOverloads44.ts, 0, 0)) +>animal : Symbol(animal, Decl(functionOverloads44.ts, 0, 18)) + +interface Dog extends Animal { dog } +>Dog : Symbol(Dog, Decl(functionOverloads44.ts, 0, 27)) +>Animal : Symbol(Animal, Decl(functionOverloads44.ts, 0, 0)) +>dog : Symbol(dog, Decl(functionOverloads44.ts, 1, 30)) + +interface Cat extends Animal { cat } +>Cat : Symbol(Cat, Decl(functionOverloads44.ts, 1, 36)) +>Animal : Symbol(Animal, Decl(functionOverloads44.ts, 0, 0)) +>cat : Symbol(cat, Decl(functionOverloads44.ts, 2, 30)) + +function foo1(bar: { a:number }[]): Dog; +>foo1 : Symbol(foo1, Decl(functionOverloads44.ts, 2, 36), Decl(functionOverloads44.ts, 4, 40), Decl(functionOverloads44.ts, 5, 43)) +>bar : Symbol(bar, Decl(functionOverloads44.ts, 4, 14)) +>a : Symbol(a, Decl(functionOverloads44.ts, 4, 20)) +>Dog : Symbol(Dog, Decl(functionOverloads44.ts, 0, 27)) + +function foo1(bar: { a:string }[]): Animal; +>foo1 : Symbol(foo1, Decl(functionOverloads44.ts, 2, 36), Decl(functionOverloads44.ts, 4, 40), Decl(functionOverloads44.ts, 5, 43)) +>bar : Symbol(bar, Decl(functionOverloads44.ts, 5, 14)) +>a : Symbol(a, Decl(functionOverloads44.ts, 5, 20)) +>Animal : Symbol(Animal, Decl(functionOverloads44.ts, 0, 0)) + +function foo1([x]: { a:number | string }[]): Dog { +>foo1 : Symbol(foo1, Decl(functionOverloads44.ts, 2, 36), Decl(functionOverloads44.ts, 4, 40), Decl(functionOverloads44.ts, 5, 43)) +>x : Symbol(x, Decl(functionOverloads44.ts, 6, 15)) +>a : Symbol(a, Decl(functionOverloads44.ts, 6, 20)) +>Dog : Symbol(Dog, Decl(functionOverloads44.ts, 0, 27)) + + return undefined; +>undefined : Symbol(undefined) +} + +function foo2(bar: { a:number }[]): Cat; +>foo2 : Symbol(foo2, Decl(functionOverloads44.ts, 8, 1), Decl(functionOverloads44.ts, 10, 40), Decl(functionOverloads44.ts, 11, 46)) +>bar : Symbol(bar, Decl(functionOverloads44.ts, 10, 14)) +>a : Symbol(a, Decl(functionOverloads44.ts, 10, 20)) +>Cat : Symbol(Cat, Decl(functionOverloads44.ts, 1, 36)) + +function foo2(bar: { a:string }[]): Cat | Dog; +>foo2 : Symbol(foo2, Decl(functionOverloads44.ts, 8, 1), Decl(functionOverloads44.ts, 10, 40), Decl(functionOverloads44.ts, 11, 46)) +>bar : Symbol(bar, Decl(functionOverloads44.ts, 11, 14)) +>a : Symbol(a, Decl(functionOverloads44.ts, 11, 20)) +>Cat : Symbol(Cat, Decl(functionOverloads44.ts, 1, 36)) +>Dog : Symbol(Dog, Decl(functionOverloads44.ts, 0, 27)) + +function foo2([x]: { a:number | string }[]): Cat { +>foo2 : Symbol(foo2, Decl(functionOverloads44.ts, 8, 1), Decl(functionOverloads44.ts, 10, 40), Decl(functionOverloads44.ts, 11, 46)) +>x : Symbol(x, Decl(functionOverloads44.ts, 12, 15)) +>a : Symbol(a, Decl(functionOverloads44.ts, 12, 20)) +>Cat : Symbol(Cat, Decl(functionOverloads44.ts, 1, 36)) + + return undefined; +>undefined : Symbol(undefined) +} + + +var x1 = foo1([{a: "str"}]); +>x1 : Symbol(x1, Decl(functionOverloads44.ts, 17, 3)) +>foo1 : Symbol(foo1, Decl(functionOverloads44.ts, 2, 36), Decl(functionOverloads44.ts, 4, 40), Decl(functionOverloads44.ts, 5, 43)) +>a : Symbol(a, Decl(functionOverloads44.ts, 17, 16)) + +var y1 = foo1([{a: 100}]); +>y1 : Symbol(y1, Decl(functionOverloads44.ts, 18, 3)) +>foo1 : Symbol(foo1, Decl(functionOverloads44.ts, 2, 36), Decl(functionOverloads44.ts, 4, 40), Decl(functionOverloads44.ts, 5, 43)) +>a : Symbol(a, Decl(functionOverloads44.ts, 18, 16)) + +var x2 = foo2([{a: "str"}]); +>x2 : Symbol(x2, Decl(functionOverloads44.ts, 20, 3)) +>foo2 : Symbol(foo2, Decl(functionOverloads44.ts, 8, 1), Decl(functionOverloads44.ts, 10, 40), Decl(functionOverloads44.ts, 11, 46)) +>a : Symbol(a, Decl(functionOverloads44.ts, 20, 16)) + +var y2 = foo2([{a: 100}]); +>y2 : Symbol(y2, Decl(functionOverloads44.ts, 21, 3)) +>foo2 : Symbol(foo2, Decl(functionOverloads44.ts, 8, 1), Decl(functionOverloads44.ts, 10, 40), Decl(functionOverloads44.ts, 11, 46)) +>a : Symbol(a, Decl(functionOverloads44.ts, 21, 16)) + diff --git a/tests/baselines/reference/functionOverloads44.types b/tests/baselines/reference/functionOverloads44.types new file mode 100644 index 00000000000..56cad09b472 --- /dev/null +++ b/tests/baselines/reference/functionOverloads44.types @@ -0,0 +1,97 @@ +=== tests/cases/compiler/functionOverloads44.ts === +interface Animal { animal } +>Animal : Animal +>animal : any + +interface Dog extends Animal { dog } +>Dog : Dog +>Animal : Animal +>dog : any + +interface Cat extends Animal { cat } +>Cat : Cat +>Animal : Animal +>cat : any + +function foo1(bar: { a:number }[]): Dog; +>foo1 : { (bar: { a: number; }[]): Dog; (bar: { a: string; }[]): Animal; } +>bar : { a: number; }[] +>a : number +>Dog : Dog + +function foo1(bar: { a:string }[]): Animal; +>foo1 : { (bar: { a: number; }[]): Dog; (bar: { a: string; }[]): Animal; } +>bar : { a: string; }[] +>a : string +>Animal : Animal + +function foo1([x]: { a:number | string }[]): Dog { +>foo1 : { (bar: { a: number; }[]): Dog; (bar: { a: string; }[]): Animal; } +>x : { a: number | string; } +>a : number | string +>Dog : Dog + + return undefined; +>undefined : undefined +} + +function foo2(bar: { a:number }[]): Cat; +>foo2 : { (bar: { a: number; }[]): Cat; (bar: { a: string; }[]): Cat | Dog; } +>bar : { a: number; }[] +>a : number +>Cat : Cat + +function foo2(bar: { a:string }[]): Cat | Dog; +>foo2 : { (bar: { a: number; }[]): Cat; (bar: { a: string; }[]): Cat | Dog; } +>bar : { a: string; }[] +>a : string +>Cat : Cat +>Dog : Dog + +function foo2([x]: { a:number | string }[]): Cat { +>foo2 : { (bar: { a: number; }[]): Cat; (bar: { a: string; }[]): Cat | Dog; } +>x : { a: number | string; } +>a : number | string +>Cat : Cat + + return undefined; +>undefined : undefined +} + + +var x1 = foo1([{a: "str"}]); +>x1 : Animal +>foo1([{a: "str"}]) : Animal +>foo1 : { (bar: { a: number; }[]): Dog; (bar: { a: string; }[]): Animal; } +>[{a: "str"}] : { a: string; }[] +>{a: "str"} : { a: string; } +>a : string +>"str" : string + +var y1 = foo1([{a: 100}]); +>y1 : Dog +>foo1([{a: 100}]) : Dog +>foo1 : { (bar: { a: number; }[]): Dog; (bar: { a: string; }[]): Animal; } +>[{a: 100}] : { a: number; }[] +>{a: 100} : { a: number; } +>a : number +>100 : number + +var x2 = foo2([{a: "str"}]); +>x2 : Cat | Dog +>foo2([{a: "str"}]) : Cat | Dog +>foo2 : { (bar: { a: number; }[]): Cat; (bar: { a: string; }[]): Cat | Dog; } +>[{a: "str"}] : { a: string; }[] +>{a: "str"} : { a: string; } +>a : string +>"str" : string + +var y2 = foo2([{a: 100}]); +>y2 : Cat +>foo2([{a: 100}]) : Cat +>foo2 : { (bar: { a: number; }[]): Cat; (bar: { a: string; }[]): Cat | Dog; } +>[{a: 100}] : { a: number; }[] +>{a: 100} : { a: number; } +>a : number +>100 : number + diff --git a/tests/baselines/reference/functionOverloads45.errors.txt b/tests/baselines/reference/functionOverloads45.errors.txt new file mode 100644 index 00000000000..38ed387d9a1 --- /dev/null +++ b/tests/baselines/reference/functionOverloads45.errors.txt @@ -0,0 +1,31 @@ +tests/cases/compiler/functionOverloads45.ts(5,10): error TS2394: Overload signature is not compatible with function implementation. +tests/cases/compiler/functionOverloads45.ts(11,10): error TS2394: Overload signature is not compatible with function implementation. + + +==== tests/cases/compiler/functionOverloads45.ts (2 errors) ==== + interface Animal { animal } + interface Dog extends Animal { dog } + interface Cat extends Animal { cat } + + function foo1(bar: { a:number }[]): Cat; + ~~~~ +!!! error TS2394: Overload signature is not compatible with function implementation. + function foo1(bar: { a:string }[]): Dog; + function foo1([x]: { a:number | string }[]): Animal { + return undefined; + } + + function foo2(bar: { a:number }[]): Cat; + ~~~~ +!!! error TS2394: Overload signature is not compatible with function implementation. + function foo2(bar: { a:string }[]): Dog; + function foo2([x]: { a:number | string }[]): Cat | Dog { + return undefined; + } + + + var x1 = foo1([{a: "str"}]); + var y1 = foo1([{a: 100}]); + + var x2 = foo2([{a: "str"}]); + var y2 = foo2([{a: 100}]); \ No newline at end of file diff --git a/tests/baselines/reference/functionOverloads45.js b/tests/baselines/reference/functionOverloads45.js new file mode 100644 index 00000000000..89bf41893c9 --- /dev/null +++ b/tests/baselines/reference/functionOverloads45.js @@ -0,0 +1,37 @@ +//// [functionOverloads45.ts] +interface Animal { animal } +interface Dog extends Animal { dog } +interface Cat extends Animal { cat } + +function foo1(bar: { a:number }[]): Cat; +function foo1(bar: { a:string }[]): Dog; +function foo1([x]: { a:number | string }[]): Animal { + return undefined; +} + +function foo2(bar: { a:number }[]): Cat; +function foo2(bar: { a:string }[]): Dog; +function foo2([x]: { a:number | string }[]): Cat | Dog { + return undefined; +} + + +var x1 = foo1([{a: "str"}]); +var y1 = foo1([{a: 100}]); + +var x2 = foo2([{a: "str"}]); +var y2 = foo2([{a: 100}]); + +//// [functionOverloads45.js] +function foo1(_a) { + var x = _a[0]; + return undefined; +} +function foo2(_a) { + var x = _a[0]; + return undefined; +} +var x1 = foo1([{ a: "str" }]); +var y1 = foo1([{ a: 100 }]); +var x2 = foo2([{ a: "str" }]); +var y2 = foo2([{ a: 100 }]); From dc2af2fb7fd1ca54e05c8cc211d05041b23dc708 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 8 Dec 2015 17:08:23 -0800 Subject: [PATCH 06/79] Use different relation for overload compatibility. --- src/compiler/checker.ts | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 30d4818592b..212d863e575 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4959,6 +4959,25 @@ namespace ts { return checkTypeRelatedTo(sourceType, targetType, assignableRelation, /*errorNode*/ undefined); } + function isImplementationCompatibleWithOverload(implementation: Signature, overload: Signature): boolean { + const erasedSource = getErasedSignature(implementation); + const erasedTarget = getErasedSignature(overload); + + const sourceReturnType = getReturnTypeOfSignature(erasedSource); + const targetReturnType = getReturnTypeOfSignature(erasedTarget); + if (checkTypeRelatedTo(sourceReturnType, targetReturnType, assignableRelation, /*errorNode*/ undefined) + || checkTypeRelatedTo(targetReturnType, sourceReturnType, assignableRelation, /*errorNode*/ undefined)) { + const anyReturningSource = cloneSignature(erasedSource); + const anyReturningTarget = cloneSignature(erasedTarget); + anyReturningSource.resolvedReturnType = anyType; + anyReturningTarget.resolvedReturnType = anyType; + + const anyReturningSourceType = getOrCreateTypeFromSignature(anyReturningSource); + const anyReturningTargetType = getOrCreateTypeFromSignature(anyReturningTarget); + return checkTypeRelatedTo(anyReturningSourceType, anyReturningTargetType, assignableRelation, /*errorNode*/ undefined); + } + } + /** * Checks if 'source' is related to 'target' (e.g.: is a assignable to). * @param source The left-hand-side of the relation. @@ -11683,7 +11702,7 @@ namespace ts { // // The implementation is completely unrelated to the specialized signature, yet we do not check this. for (const signature of signatures) { - if (!signature.hasStringLiterals && !isSignatureAssignableTo(bodySignature, signature)) { + if (!signature.hasStringLiterals && !isImplementationCompatibleWithOverload(bodySignature, signature)) { error(signature.declaration, Diagnostics.Overload_signature_is_not_compatible_with_function_implementation); break; } From e1004fac60608142dff3941ef0ac586c71942fc8 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 8 Dec 2015 17:13:16 -0800 Subject: [PATCH 07/79] Removed misleading comment from test. --- tests/cases/compiler/overloadOnConstConstraintChecks4.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cases/compiler/overloadOnConstConstraintChecks4.ts b/tests/cases/compiler/overloadOnConstConstraintChecks4.ts index f63c5b46349..55425f63393 100644 --- a/tests/cases/compiler/overloadOnConstConstraintChecks4.ts +++ b/tests/cases/compiler/overloadOnConstConstraintChecks4.ts @@ -6,7 +6,7 @@ class C extends A { } function foo(name: 'hi'): B; function foo(name: 'bye'): C; -function foo(name: string): A; // error +function foo(name: string): A; function foo(name: any): Z { return null; } From 51d240989aada5f805808c4a1025f13ecbfba68f Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 8 Dec 2015 17:13:46 -0800 Subject: [PATCH 08/79] Accepted baselines. --- .../reference/functionOverloads22.errors.txt | 10 - .../reference/functionOverloads22.symbols | 19 ++ .../reference/functionOverloads22.types | 22 +++ .../reference/functionOverloads43.errors.txt | 18 -- .../reference/functionOverloads43.symbols | 39 ++++ .../reference/functionOverloads43.types | 47 +++++ .../reference/functionOverloads45.errors.txt | 31 ---- .../reference/functionOverloads45.symbols | 81 ++++++++ .../reference/functionOverloads45.types | 97 ++++++++++ ...verloadOnConstConstraintChecks4.errors.txt | 19 -- .../overloadOnConstConstraintChecks4.js | 2 +- .../overloadOnConstConstraintChecks4.symbols | 43 +++++ .../overloadOnConstConstraintChecks4.types | 45 +++++ .../stringLiteralTypesOverloads01.errors.txt | 59 ------ .../stringLiteralTypesOverloads01.symbols | 144 +++++++++++++++ .../stringLiteralTypesOverloads01.types | 174 ++++++++++++++++++ 16 files changed, 712 insertions(+), 138 deletions(-) delete mode 100644 tests/baselines/reference/functionOverloads22.errors.txt create mode 100644 tests/baselines/reference/functionOverloads22.symbols create mode 100644 tests/baselines/reference/functionOverloads22.types delete mode 100644 tests/baselines/reference/functionOverloads43.errors.txt create mode 100644 tests/baselines/reference/functionOverloads43.symbols create mode 100644 tests/baselines/reference/functionOverloads43.types delete mode 100644 tests/baselines/reference/functionOverloads45.errors.txt create mode 100644 tests/baselines/reference/functionOverloads45.symbols create mode 100644 tests/baselines/reference/functionOverloads45.types delete mode 100644 tests/baselines/reference/overloadOnConstConstraintChecks4.errors.txt create mode 100644 tests/baselines/reference/overloadOnConstConstraintChecks4.symbols create mode 100644 tests/baselines/reference/overloadOnConstConstraintChecks4.types delete mode 100644 tests/baselines/reference/stringLiteralTypesOverloads01.errors.txt create mode 100644 tests/baselines/reference/stringLiteralTypesOverloads01.symbols create mode 100644 tests/baselines/reference/stringLiteralTypesOverloads01.types diff --git a/tests/baselines/reference/functionOverloads22.errors.txt b/tests/baselines/reference/functionOverloads22.errors.txt deleted file mode 100644 index c9fc8aa2b2f..00000000000 --- a/tests/baselines/reference/functionOverloads22.errors.txt +++ /dev/null @@ -1,10 +0,0 @@ -tests/cases/compiler/functionOverloads22.ts(2,10): error TS2394: Overload signature is not compatible with function implementation. - - -==== tests/cases/compiler/functionOverloads22.ts (1 errors) ==== - function foo(bar:number):{a:number;}[]; - function foo(bar:string):{a:number; b:string;}[]; - ~~~ -!!! error TS2394: Overload signature is not compatible with function implementation. - function foo(bar:any):{a:any;b?:any;}[] { return [{a:""}] } - \ No newline at end of file diff --git a/tests/baselines/reference/functionOverloads22.symbols b/tests/baselines/reference/functionOverloads22.symbols new file mode 100644 index 00000000000..7924da073b0 --- /dev/null +++ b/tests/baselines/reference/functionOverloads22.symbols @@ -0,0 +1,19 @@ +=== tests/cases/compiler/functionOverloads22.ts === +function foo(bar:number):{a:number;}[]; +>foo : Symbol(foo, Decl(functionOverloads22.ts, 0, 0), Decl(functionOverloads22.ts, 0, 39), Decl(functionOverloads22.ts, 1, 49)) +>bar : Symbol(bar, Decl(functionOverloads22.ts, 0, 13)) +>a : Symbol(a, Decl(functionOverloads22.ts, 0, 26)) + +function foo(bar:string):{a:number; b:string;}[]; +>foo : Symbol(foo, Decl(functionOverloads22.ts, 0, 0), Decl(functionOverloads22.ts, 0, 39), Decl(functionOverloads22.ts, 1, 49)) +>bar : Symbol(bar, Decl(functionOverloads22.ts, 1, 13)) +>a : Symbol(a, Decl(functionOverloads22.ts, 1, 26)) +>b : Symbol(b, Decl(functionOverloads22.ts, 1, 35)) + +function foo(bar:any):{a:any;b?:any;}[] { return [{a:""}] } +>foo : Symbol(foo, Decl(functionOverloads22.ts, 0, 0), Decl(functionOverloads22.ts, 0, 39), Decl(functionOverloads22.ts, 1, 49)) +>bar : Symbol(bar, Decl(functionOverloads22.ts, 2, 13)) +>a : Symbol(a, Decl(functionOverloads22.ts, 2, 23)) +>b : Symbol(b, Decl(functionOverloads22.ts, 2, 29)) +>a : Symbol(a, Decl(functionOverloads22.ts, 2, 51)) + diff --git a/tests/baselines/reference/functionOverloads22.types b/tests/baselines/reference/functionOverloads22.types new file mode 100644 index 00000000000..7557b1c049f --- /dev/null +++ b/tests/baselines/reference/functionOverloads22.types @@ -0,0 +1,22 @@ +=== tests/cases/compiler/functionOverloads22.ts === +function foo(bar:number):{a:number;}[]; +>foo : { (bar: number): { a: number; }[]; (bar: string): { a: number; b: string; }[]; } +>bar : number +>a : number + +function foo(bar:string):{a:number; b:string;}[]; +>foo : { (bar: number): { a: number; }[]; (bar: string): { a: number; b: string; }[]; } +>bar : string +>a : number +>b : string + +function foo(bar:any):{a:any;b?:any;}[] { return [{a:""}] } +>foo : { (bar: number): { a: number; }[]; (bar: string): { a: number; b: string; }[]; } +>bar : any +>a : any +>b : any +>[{a:""}] : { a: string; }[] +>{a:""} : { a: string; } +>a : string +>"" : string + diff --git a/tests/baselines/reference/functionOverloads43.errors.txt b/tests/baselines/reference/functionOverloads43.errors.txt deleted file mode 100644 index 769bb467186..00000000000 --- a/tests/baselines/reference/functionOverloads43.errors.txt +++ /dev/null @@ -1,18 +0,0 @@ -tests/cases/compiler/functionOverloads43.ts(1,10): error TS2394: Overload signature is not compatible with function implementation. - - -==== tests/cases/compiler/functionOverloads43.ts (1 errors) ==== - function foo(bar: { a:number }[]): number; - ~~~ -!!! error TS2394: Overload signature is not compatible with function implementation. - function foo(bar: { a:string }[]): string; - function foo([x]: { a:number | string }[]): string | number { - if (x) { - return x.a; - } - - return undefined; - } - - var x = foo([{a: "str"}]); - var y = foo([{a: 100}]); \ No newline at end of file diff --git a/tests/baselines/reference/functionOverloads43.symbols b/tests/baselines/reference/functionOverloads43.symbols new file mode 100644 index 00000000000..179ba3e3fed --- /dev/null +++ b/tests/baselines/reference/functionOverloads43.symbols @@ -0,0 +1,39 @@ +=== tests/cases/compiler/functionOverloads43.ts === +function foo(bar: { a:number }[]): number; +>foo : Symbol(foo, Decl(functionOverloads43.ts, 0, 0), Decl(functionOverloads43.ts, 0, 42), Decl(functionOverloads43.ts, 1, 42)) +>bar : Symbol(bar, Decl(functionOverloads43.ts, 0, 13)) +>a : Symbol(a, Decl(functionOverloads43.ts, 0, 19)) + +function foo(bar: { a:string }[]): string; +>foo : Symbol(foo, Decl(functionOverloads43.ts, 0, 0), Decl(functionOverloads43.ts, 0, 42), Decl(functionOverloads43.ts, 1, 42)) +>bar : Symbol(bar, Decl(functionOverloads43.ts, 1, 13)) +>a : Symbol(a, Decl(functionOverloads43.ts, 1, 19)) + +function foo([x]: { a:number | string }[]): string | number { +>foo : Symbol(foo, Decl(functionOverloads43.ts, 0, 0), Decl(functionOverloads43.ts, 0, 42), Decl(functionOverloads43.ts, 1, 42)) +>x : Symbol(x, Decl(functionOverloads43.ts, 2, 14)) +>a : Symbol(a, Decl(functionOverloads43.ts, 2, 19)) + + if (x) { +>x : Symbol(x, Decl(functionOverloads43.ts, 2, 14)) + + return x.a; +>x.a : Symbol(a, Decl(functionOverloads43.ts, 2, 19)) +>x : Symbol(x, Decl(functionOverloads43.ts, 2, 14)) +>a : Symbol(a, Decl(functionOverloads43.ts, 2, 19)) + } + + return undefined; +>undefined : Symbol(undefined) +} + +var x = foo([{a: "str"}]); +>x : Symbol(x, Decl(functionOverloads43.ts, 10, 3)) +>foo : Symbol(foo, Decl(functionOverloads43.ts, 0, 0), Decl(functionOverloads43.ts, 0, 42), Decl(functionOverloads43.ts, 1, 42)) +>a : Symbol(a, Decl(functionOverloads43.ts, 10, 14)) + +var y = foo([{a: 100}]); +>y : Symbol(y, Decl(functionOverloads43.ts, 11, 3)) +>foo : Symbol(foo, Decl(functionOverloads43.ts, 0, 0), Decl(functionOverloads43.ts, 0, 42), Decl(functionOverloads43.ts, 1, 42)) +>a : Symbol(a, Decl(functionOverloads43.ts, 11, 14)) + diff --git a/tests/baselines/reference/functionOverloads43.types b/tests/baselines/reference/functionOverloads43.types new file mode 100644 index 00000000000..7c0fa8eb818 --- /dev/null +++ b/tests/baselines/reference/functionOverloads43.types @@ -0,0 +1,47 @@ +=== tests/cases/compiler/functionOverloads43.ts === +function foo(bar: { a:number }[]): number; +>foo : { (bar: { a: number; }[]): number; (bar: { a: string; }[]): string; } +>bar : { a: number; }[] +>a : number + +function foo(bar: { a:string }[]): string; +>foo : { (bar: { a: number; }[]): number; (bar: { a: string; }[]): string; } +>bar : { a: string; }[] +>a : string + +function foo([x]: { a:number | string }[]): string | number { +>foo : { (bar: { a: number; }[]): number; (bar: { a: string; }[]): string; } +>x : { a: number | string; } +>a : number | string + + if (x) { +>x : { a: number | string; } + + return x.a; +>x.a : number | string +>x : { a: number | string; } +>a : number | string + } + + return undefined; +>undefined : undefined +} + +var x = foo([{a: "str"}]); +>x : string +>foo([{a: "str"}]) : string +>foo : { (bar: { a: number; }[]): number; (bar: { a: string; }[]): string; } +>[{a: "str"}] : { a: string; }[] +>{a: "str"} : { a: string; } +>a : string +>"str" : string + +var y = foo([{a: 100}]); +>y : number +>foo([{a: 100}]) : number +>foo : { (bar: { a: number; }[]): number; (bar: { a: string; }[]): string; } +>[{a: 100}] : { a: number; }[] +>{a: 100} : { a: number; } +>a : number +>100 : number + diff --git a/tests/baselines/reference/functionOverloads45.errors.txt b/tests/baselines/reference/functionOverloads45.errors.txt deleted file mode 100644 index 38ed387d9a1..00000000000 --- a/tests/baselines/reference/functionOverloads45.errors.txt +++ /dev/null @@ -1,31 +0,0 @@ -tests/cases/compiler/functionOverloads45.ts(5,10): error TS2394: Overload signature is not compatible with function implementation. -tests/cases/compiler/functionOverloads45.ts(11,10): error TS2394: Overload signature is not compatible with function implementation. - - -==== tests/cases/compiler/functionOverloads45.ts (2 errors) ==== - interface Animal { animal } - interface Dog extends Animal { dog } - interface Cat extends Animal { cat } - - function foo1(bar: { a:number }[]): Cat; - ~~~~ -!!! error TS2394: Overload signature is not compatible with function implementation. - function foo1(bar: { a:string }[]): Dog; - function foo1([x]: { a:number | string }[]): Animal { - return undefined; - } - - function foo2(bar: { a:number }[]): Cat; - ~~~~ -!!! error TS2394: Overload signature is not compatible with function implementation. - function foo2(bar: { a:string }[]): Dog; - function foo2([x]: { a:number | string }[]): Cat | Dog { - return undefined; - } - - - var x1 = foo1([{a: "str"}]); - var y1 = foo1([{a: 100}]); - - var x2 = foo2([{a: "str"}]); - var y2 = foo2([{a: 100}]); \ No newline at end of file diff --git a/tests/baselines/reference/functionOverloads45.symbols b/tests/baselines/reference/functionOverloads45.symbols new file mode 100644 index 00000000000..28599339099 --- /dev/null +++ b/tests/baselines/reference/functionOverloads45.symbols @@ -0,0 +1,81 @@ +=== tests/cases/compiler/functionOverloads45.ts === +interface Animal { animal } +>Animal : Symbol(Animal, Decl(functionOverloads45.ts, 0, 0)) +>animal : Symbol(animal, Decl(functionOverloads45.ts, 0, 18)) + +interface Dog extends Animal { dog } +>Dog : Symbol(Dog, Decl(functionOverloads45.ts, 0, 27)) +>Animal : Symbol(Animal, Decl(functionOverloads45.ts, 0, 0)) +>dog : Symbol(dog, Decl(functionOverloads45.ts, 1, 30)) + +interface Cat extends Animal { cat } +>Cat : Symbol(Cat, Decl(functionOverloads45.ts, 1, 36)) +>Animal : Symbol(Animal, Decl(functionOverloads45.ts, 0, 0)) +>cat : Symbol(cat, Decl(functionOverloads45.ts, 2, 30)) + +function foo1(bar: { a:number }[]): Cat; +>foo1 : Symbol(foo1, Decl(functionOverloads45.ts, 2, 36), Decl(functionOverloads45.ts, 4, 40), Decl(functionOverloads45.ts, 5, 40)) +>bar : Symbol(bar, Decl(functionOverloads45.ts, 4, 14)) +>a : Symbol(a, Decl(functionOverloads45.ts, 4, 20)) +>Cat : Symbol(Cat, Decl(functionOverloads45.ts, 1, 36)) + +function foo1(bar: { a:string }[]): Dog; +>foo1 : Symbol(foo1, Decl(functionOverloads45.ts, 2, 36), Decl(functionOverloads45.ts, 4, 40), Decl(functionOverloads45.ts, 5, 40)) +>bar : Symbol(bar, Decl(functionOverloads45.ts, 5, 14)) +>a : Symbol(a, Decl(functionOverloads45.ts, 5, 20)) +>Dog : Symbol(Dog, Decl(functionOverloads45.ts, 0, 27)) + +function foo1([x]: { a:number | string }[]): Animal { +>foo1 : Symbol(foo1, Decl(functionOverloads45.ts, 2, 36), Decl(functionOverloads45.ts, 4, 40), Decl(functionOverloads45.ts, 5, 40)) +>x : Symbol(x, Decl(functionOverloads45.ts, 6, 15)) +>a : Symbol(a, Decl(functionOverloads45.ts, 6, 20)) +>Animal : Symbol(Animal, Decl(functionOverloads45.ts, 0, 0)) + + return undefined; +>undefined : Symbol(undefined) +} + +function foo2(bar: { a:number }[]): Cat; +>foo2 : Symbol(foo2, Decl(functionOverloads45.ts, 8, 1), Decl(functionOverloads45.ts, 10, 40), Decl(functionOverloads45.ts, 11, 40)) +>bar : Symbol(bar, Decl(functionOverloads45.ts, 10, 14)) +>a : Symbol(a, Decl(functionOverloads45.ts, 10, 20)) +>Cat : Symbol(Cat, Decl(functionOverloads45.ts, 1, 36)) + +function foo2(bar: { a:string }[]): Dog; +>foo2 : Symbol(foo2, Decl(functionOverloads45.ts, 8, 1), Decl(functionOverloads45.ts, 10, 40), Decl(functionOverloads45.ts, 11, 40)) +>bar : Symbol(bar, Decl(functionOverloads45.ts, 11, 14)) +>a : Symbol(a, Decl(functionOverloads45.ts, 11, 20)) +>Dog : Symbol(Dog, Decl(functionOverloads45.ts, 0, 27)) + +function foo2([x]: { a:number | string }[]): Cat | Dog { +>foo2 : Symbol(foo2, Decl(functionOverloads45.ts, 8, 1), Decl(functionOverloads45.ts, 10, 40), Decl(functionOverloads45.ts, 11, 40)) +>x : Symbol(x, Decl(functionOverloads45.ts, 12, 15)) +>a : Symbol(a, Decl(functionOverloads45.ts, 12, 20)) +>Cat : Symbol(Cat, Decl(functionOverloads45.ts, 1, 36)) +>Dog : Symbol(Dog, Decl(functionOverloads45.ts, 0, 27)) + + return undefined; +>undefined : Symbol(undefined) +} + + +var x1 = foo1([{a: "str"}]); +>x1 : Symbol(x1, Decl(functionOverloads45.ts, 17, 3)) +>foo1 : Symbol(foo1, Decl(functionOverloads45.ts, 2, 36), Decl(functionOverloads45.ts, 4, 40), Decl(functionOverloads45.ts, 5, 40)) +>a : Symbol(a, Decl(functionOverloads45.ts, 17, 16)) + +var y1 = foo1([{a: 100}]); +>y1 : Symbol(y1, Decl(functionOverloads45.ts, 18, 3)) +>foo1 : Symbol(foo1, Decl(functionOverloads45.ts, 2, 36), Decl(functionOverloads45.ts, 4, 40), Decl(functionOverloads45.ts, 5, 40)) +>a : Symbol(a, Decl(functionOverloads45.ts, 18, 16)) + +var x2 = foo2([{a: "str"}]); +>x2 : Symbol(x2, Decl(functionOverloads45.ts, 20, 3)) +>foo2 : Symbol(foo2, Decl(functionOverloads45.ts, 8, 1), Decl(functionOverloads45.ts, 10, 40), Decl(functionOverloads45.ts, 11, 40)) +>a : Symbol(a, Decl(functionOverloads45.ts, 20, 16)) + +var y2 = foo2([{a: 100}]); +>y2 : Symbol(y2, Decl(functionOverloads45.ts, 21, 3)) +>foo2 : Symbol(foo2, Decl(functionOverloads45.ts, 8, 1), Decl(functionOverloads45.ts, 10, 40), Decl(functionOverloads45.ts, 11, 40)) +>a : Symbol(a, Decl(functionOverloads45.ts, 21, 16)) + diff --git a/tests/baselines/reference/functionOverloads45.types b/tests/baselines/reference/functionOverloads45.types new file mode 100644 index 00000000000..257a615e334 --- /dev/null +++ b/tests/baselines/reference/functionOverloads45.types @@ -0,0 +1,97 @@ +=== tests/cases/compiler/functionOverloads45.ts === +interface Animal { animal } +>Animal : Animal +>animal : any + +interface Dog extends Animal { dog } +>Dog : Dog +>Animal : Animal +>dog : any + +interface Cat extends Animal { cat } +>Cat : Cat +>Animal : Animal +>cat : any + +function foo1(bar: { a:number }[]): Cat; +>foo1 : { (bar: { a: number; }[]): Cat; (bar: { a: string; }[]): Dog; } +>bar : { a: number; }[] +>a : number +>Cat : Cat + +function foo1(bar: { a:string }[]): Dog; +>foo1 : { (bar: { a: number; }[]): Cat; (bar: { a: string; }[]): Dog; } +>bar : { a: string; }[] +>a : string +>Dog : Dog + +function foo1([x]: { a:number | string }[]): Animal { +>foo1 : { (bar: { a: number; }[]): Cat; (bar: { a: string; }[]): Dog; } +>x : { a: number | string; } +>a : number | string +>Animal : Animal + + return undefined; +>undefined : undefined +} + +function foo2(bar: { a:number }[]): Cat; +>foo2 : { (bar: { a: number; }[]): Cat; (bar: { a: string; }[]): Dog; } +>bar : { a: number; }[] +>a : number +>Cat : Cat + +function foo2(bar: { a:string }[]): Dog; +>foo2 : { (bar: { a: number; }[]): Cat; (bar: { a: string; }[]): Dog; } +>bar : { a: string; }[] +>a : string +>Dog : Dog + +function foo2([x]: { a:number | string }[]): Cat | Dog { +>foo2 : { (bar: { a: number; }[]): Cat; (bar: { a: string; }[]): Dog; } +>x : { a: number | string; } +>a : number | string +>Cat : Cat +>Dog : Dog + + return undefined; +>undefined : undefined +} + + +var x1 = foo1([{a: "str"}]); +>x1 : Dog +>foo1([{a: "str"}]) : Dog +>foo1 : { (bar: { a: number; }[]): Cat; (bar: { a: string; }[]): Dog; } +>[{a: "str"}] : { a: string; }[] +>{a: "str"} : { a: string; } +>a : string +>"str" : string + +var y1 = foo1([{a: 100}]); +>y1 : Cat +>foo1([{a: 100}]) : Cat +>foo1 : { (bar: { a: number; }[]): Cat; (bar: { a: string; }[]): Dog; } +>[{a: 100}] : { a: number; }[] +>{a: 100} : { a: number; } +>a : number +>100 : number + +var x2 = foo2([{a: "str"}]); +>x2 : Dog +>foo2([{a: "str"}]) : Dog +>foo2 : { (bar: { a: number; }[]): Cat; (bar: { a: string; }[]): Dog; } +>[{a: "str"}] : { a: string; }[] +>{a: "str"} : { a: string; } +>a : string +>"str" : string + +var y2 = foo2([{a: 100}]); +>y2 : Cat +>foo2([{a: 100}]) : Cat +>foo2 : { (bar: { a: number; }[]): Cat; (bar: { a: string; }[]): Dog; } +>[{a: 100}] : { a: number; }[] +>{a: 100} : { a: number; } +>a : number +>100 : number + diff --git a/tests/baselines/reference/overloadOnConstConstraintChecks4.errors.txt b/tests/baselines/reference/overloadOnConstConstraintChecks4.errors.txt deleted file mode 100644 index 7a8037b3dd7..00000000000 --- a/tests/baselines/reference/overloadOnConstConstraintChecks4.errors.txt +++ /dev/null @@ -1,19 +0,0 @@ -tests/cases/compiler/overloadOnConstConstraintChecks4.ts(9,10): error TS2394: Overload signature is not compatible with function implementation. - - -==== tests/cases/compiler/overloadOnConstConstraintChecks4.ts (1 errors) ==== - class Z { } - class A extends Z { private x = 1 } - class B extends A {} - class C extends A { - public foo() { } - } - function foo(name: 'hi'): B; - function foo(name: 'bye'): C; - function foo(name: string): A; // error - ~~~ -!!! error TS2394: Overload signature is not compatible with function implementation. - function foo(name: any): Z { - return null; - } - \ No newline at end of file diff --git a/tests/baselines/reference/overloadOnConstConstraintChecks4.js b/tests/baselines/reference/overloadOnConstConstraintChecks4.js index 17ec3779620..c0422e3611e 100644 --- a/tests/baselines/reference/overloadOnConstConstraintChecks4.js +++ b/tests/baselines/reference/overloadOnConstConstraintChecks4.js @@ -7,7 +7,7 @@ class C extends A { } function foo(name: 'hi'): B; function foo(name: 'bye'): C; -function foo(name: string): A; // error +function foo(name: string): A; function foo(name: any): Z { return null; } diff --git a/tests/baselines/reference/overloadOnConstConstraintChecks4.symbols b/tests/baselines/reference/overloadOnConstConstraintChecks4.symbols new file mode 100644 index 00000000000..6e2a34b55e9 --- /dev/null +++ b/tests/baselines/reference/overloadOnConstConstraintChecks4.symbols @@ -0,0 +1,43 @@ +=== tests/cases/compiler/overloadOnConstConstraintChecks4.ts === +class Z { } +>Z : Symbol(Z, Decl(overloadOnConstConstraintChecks4.ts, 0, 0)) + +class A extends Z { private x = 1 } +>A : Symbol(A, Decl(overloadOnConstConstraintChecks4.ts, 0, 11)) +>Z : Symbol(Z, Decl(overloadOnConstConstraintChecks4.ts, 0, 0)) +>x : Symbol(x, Decl(overloadOnConstConstraintChecks4.ts, 1, 19)) + +class B extends A {} +>B : Symbol(B, Decl(overloadOnConstConstraintChecks4.ts, 1, 35)) +>A : Symbol(A, Decl(overloadOnConstConstraintChecks4.ts, 0, 11)) + +class C extends A { +>C : Symbol(C, Decl(overloadOnConstConstraintChecks4.ts, 2, 20)) +>A : Symbol(A, Decl(overloadOnConstConstraintChecks4.ts, 0, 11)) + + public foo() { } +>foo : Symbol(foo, Decl(overloadOnConstConstraintChecks4.ts, 3, 19)) +} +function foo(name: 'hi'): B; +>foo : Symbol(foo, Decl(overloadOnConstConstraintChecks4.ts, 5, 1), Decl(overloadOnConstConstraintChecks4.ts, 6, 28), Decl(overloadOnConstConstraintChecks4.ts, 7, 29), Decl(overloadOnConstConstraintChecks4.ts, 8, 30)) +>name : Symbol(name, Decl(overloadOnConstConstraintChecks4.ts, 6, 13)) +>B : Symbol(B, Decl(overloadOnConstConstraintChecks4.ts, 1, 35)) + +function foo(name: 'bye'): C; +>foo : Symbol(foo, Decl(overloadOnConstConstraintChecks4.ts, 5, 1), Decl(overloadOnConstConstraintChecks4.ts, 6, 28), Decl(overloadOnConstConstraintChecks4.ts, 7, 29), Decl(overloadOnConstConstraintChecks4.ts, 8, 30)) +>name : Symbol(name, Decl(overloadOnConstConstraintChecks4.ts, 7, 13)) +>C : Symbol(C, Decl(overloadOnConstConstraintChecks4.ts, 2, 20)) + +function foo(name: string): A; +>foo : Symbol(foo, Decl(overloadOnConstConstraintChecks4.ts, 5, 1), Decl(overloadOnConstConstraintChecks4.ts, 6, 28), Decl(overloadOnConstConstraintChecks4.ts, 7, 29), Decl(overloadOnConstConstraintChecks4.ts, 8, 30)) +>name : Symbol(name, Decl(overloadOnConstConstraintChecks4.ts, 8, 13)) +>A : Symbol(A, Decl(overloadOnConstConstraintChecks4.ts, 0, 11)) + +function foo(name: any): Z { +>foo : Symbol(foo, Decl(overloadOnConstConstraintChecks4.ts, 5, 1), Decl(overloadOnConstConstraintChecks4.ts, 6, 28), Decl(overloadOnConstConstraintChecks4.ts, 7, 29), Decl(overloadOnConstConstraintChecks4.ts, 8, 30)) +>name : Symbol(name, Decl(overloadOnConstConstraintChecks4.ts, 9, 13)) +>Z : Symbol(Z, Decl(overloadOnConstConstraintChecks4.ts, 0, 0)) + + return null; +} + diff --git a/tests/baselines/reference/overloadOnConstConstraintChecks4.types b/tests/baselines/reference/overloadOnConstConstraintChecks4.types new file mode 100644 index 00000000000..6ca7288ead9 --- /dev/null +++ b/tests/baselines/reference/overloadOnConstConstraintChecks4.types @@ -0,0 +1,45 @@ +=== tests/cases/compiler/overloadOnConstConstraintChecks4.ts === +class Z { } +>Z : Z + +class A extends Z { private x = 1 } +>A : A +>Z : Z +>x : number +>1 : number + +class B extends A {} +>B : B +>A : A + +class C extends A { +>C : C +>A : A + + public foo() { } +>foo : () => void +} +function foo(name: 'hi'): B; +>foo : { (name: "hi"): B; (name: "bye"): C; (name: string): A; } +>name : "hi" +>B : B + +function foo(name: 'bye'): C; +>foo : { (name: "hi"): B; (name: "bye"): C; (name: string): A; } +>name : "bye" +>C : C + +function foo(name: string): A; +>foo : { (name: "hi"): B; (name: "bye"): C; (name: string): A; } +>name : string +>A : A + +function foo(name: any): Z { +>foo : { (name: "hi"): B; (name: "bye"): C; (name: string): A; } +>name : any +>Z : Z + + return null; +>null : null +} + diff --git a/tests/baselines/reference/stringLiteralTypesOverloads01.errors.txt b/tests/baselines/reference/stringLiteralTypesOverloads01.errors.txt deleted file mode 100644 index 0a3fdb91929..00000000000 --- a/tests/baselines/reference/stringLiteralTypesOverloads01.errors.txt +++ /dev/null @@ -1,59 +0,0 @@ -tests/cases/conformance/types/stringLiteral/stringLiteralTypesOverloads01.ts(7,10): error TS2394: Overload signature is not compatible with function implementation. - - -==== tests/cases/conformance/types/stringLiteral/stringLiteralTypesOverloads01.ts (1 errors) ==== - - type PrimitiveName = 'string' | 'number' | 'boolean'; - - function getFalsyPrimitive(x: "string"): string; - function getFalsyPrimitive(x: "number"): number; - function getFalsyPrimitive(x: "boolean"): boolean; - function getFalsyPrimitive(x: "boolean" | "string"): boolean | string; - ~~~~~~~~~~~~~~~~~ -!!! error TS2394: Overload signature is not compatible with function implementation. - function getFalsyPrimitive(x: "boolean" | "number"): boolean | number; - function getFalsyPrimitive(x: "number" | "string"): number | string; - function getFalsyPrimitive(x: "number" | "string" | "boolean"): number | string | boolean; - function getFalsyPrimitive(x: PrimitiveName): number | string | boolean { - if (x === "string") { - return ""; - } - if (x === "number") { - return 0; - } - if (x === "boolean") { - return false; - } - - // Should be unreachable. - throw "Invalid value"; - } - - namespace Consts1 { - const EMPTY_STRING = getFalsyPrimitive("string"); - const ZERO = getFalsyPrimitive('number'); - const FALSE = getFalsyPrimitive("boolean"); - } - - const string: "string" = "string" - const number: "number" = "number" - const boolean: "boolean" = "boolean" - - const stringOrNumber = string || number; - const stringOrBoolean = string || boolean; - const booleanOrNumber = number || boolean; - const stringOrBooleanOrNumber = stringOrBoolean || number; - - namespace Consts2 { - const EMPTY_STRING = getFalsyPrimitive(string); - const ZERO = getFalsyPrimitive(number); - const FALSE = getFalsyPrimitive(boolean); - - const a = getFalsyPrimitive(stringOrNumber); - const b = getFalsyPrimitive(stringOrBoolean); - const c = getFalsyPrimitive(booleanOrNumber); - const d = getFalsyPrimitive(stringOrBooleanOrNumber); - } - - - \ No newline at end of file diff --git a/tests/baselines/reference/stringLiteralTypesOverloads01.symbols b/tests/baselines/reference/stringLiteralTypesOverloads01.symbols new file mode 100644 index 00000000000..c92fe134076 --- /dev/null +++ b/tests/baselines/reference/stringLiteralTypesOverloads01.symbols @@ -0,0 +1,144 @@ +=== tests/cases/conformance/types/stringLiteral/stringLiteralTypesOverloads01.ts === + +type PrimitiveName = 'string' | 'number' | 'boolean'; +>PrimitiveName : Symbol(PrimitiveName, Decl(stringLiteralTypesOverloads01.ts, 0, 0)) + +function getFalsyPrimitive(x: "string"): string; +>getFalsyPrimitive : Symbol(getFalsyPrimitive, Decl(stringLiteralTypesOverloads01.ts, 1, 53), Decl(stringLiteralTypesOverloads01.ts, 3, 48), Decl(stringLiteralTypesOverloads01.ts, 4, 48), Decl(stringLiteralTypesOverloads01.ts, 5, 50), Decl(stringLiteralTypesOverloads01.ts, 6, 70), Decl(stringLiteralTypesOverloads01.ts, 7, 70), Decl(stringLiteralTypesOverloads01.ts, 8, 68), Decl(stringLiteralTypesOverloads01.ts, 9, 90)) +>x : Symbol(x, Decl(stringLiteralTypesOverloads01.ts, 3, 27)) + +function getFalsyPrimitive(x: "number"): number; +>getFalsyPrimitive : Symbol(getFalsyPrimitive, Decl(stringLiteralTypesOverloads01.ts, 1, 53), Decl(stringLiteralTypesOverloads01.ts, 3, 48), Decl(stringLiteralTypesOverloads01.ts, 4, 48), Decl(stringLiteralTypesOverloads01.ts, 5, 50), Decl(stringLiteralTypesOverloads01.ts, 6, 70), Decl(stringLiteralTypesOverloads01.ts, 7, 70), Decl(stringLiteralTypesOverloads01.ts, 8, 68), Decl(stringLiteralTypesOverloads01.ts, 9, 90)) +>x : Symbol(x, Decl(stringLiteralTypesOverloads01.ts, 4, 27)) + +function getFalsyPrimitive(x: "boolean"): boolean; +>getFalsyPrimitive : Symbol(getFalsyPrimitive, Decl(stringLiteralTypesOverloads01.ts, 1, 53), Decl(stringLiteralTypesOverloads01.ts, 3, 48), Decl(stringLiteralTypesOverloads01.ts, 4, 48), Decl(stringLiteralTypesOverloads01.ts, 5, 50), Decl(stringLiteralTypesOverloads01.ts, 6, 70), Decl(stringLiteralTypesOverloads01.ts, 7, 70), Decl(stringLiteralTypesOverloads01.ts, 8, 68), Decl(stringLiteralTypesOverloads01.ts, 9, 90)) +>x : Symbol(x, Decl(stringLiteralTypesOverloads01.ts, 5, 27)) + +function getFalsyPrimitive(x: "boolean" | "string"): boolean | string; +>getFalsyPrimitive : Symbol(getFalsyPrimitive, Decl(stringLiteralTypesOverloads01.ts, 1, 53), Decl(stringLiteralTypesOverloads01.ts, 3, 48), Decl(stringLiteralTypesOverloads01.ts, 4, 48), Decl(stringLiteralTypesOverloads01.ts, 5, 50), Decl(stringLiteralTypesOverloads01.ts, 6, 70), Decl(stringLiteralTypesOverloads01.ts, 7, 70), Decl(stringLiteralTypesOverloads01.ts, 8, 68), Decl(stringLiteralTypesOverloads01.ts, 9, 90)) +>x : Symbol(x, Decl(stringLiteralTypesOverloads01.ts, 6, 27)) + +function getFalsyPrimitive(x: "boolean" | "number"): boolean | number; +>getFalsyPrimitive : Symbol(getFalsyPrimitive, Decl(stringLiteralTypesOverloads01.ts, 1, 53), Decl(stringLiteralTypesOverloads01.ts, 3, 48), Decl(stringLiteralTypesOverloads01.ts, 4, 48), Decl(stringLiteralTypesOverloads01.ts, 5, 50), Decl(stringLiteralTypesOverloads01.ts, 6, 70), Decl(stringLiteralTypesOverloads01.ts, 7, 70), Decl(stringLiteralTypesOverloads01.ts, 8, 68), Decl(stringLiteralTypesOverloads01.ts, 9, 90)) +>x : Symbol(x, Decl(stringLiteralTypesOverloads01.ts, 7, 27)) + +function getFalsyPrimitive(x: "number" | "string"): number | string; +>getFalsyPrimitive : Symbol(getFalsyPrimitive, Decl(stringLiteralTypesOverloads01.ts, 1, 53), Decl(stringLiteralTypesOverloads01.ts, 3, 48), Decl(stringLiteralTypesOverloads01.ts, 4, 48), Decl(stringLiteralTypesOverloads01.ts, 5, 50), Decl(stringLiteralTypesOverloads01.ts, 6, 70), Decl(stringLiteralTypesOverloads01.ts, 7, 70), Decl(stringLiteralTypesOverloads01.ts, 8, 68), Decl(stringLiteralTypesOverloads01.ts, 9, 90)) +>x : Symbol(x, Decl(stringLiteralTypesOverloads01.ts, 8, 27)) + +function getFalsyPrimitive(x: "number" | "string" | "boolean"): number | string | boolean; +>getFalsyPrimitive : Symbol(getFalsyPrimitive, Decl(stringLiteralTypesOverloads01.ts, 1, 53), Decl(stringLiteralTypesOverloads01.ts, 3, 48), Decl(stringLiteralTypesOverloads01.ts, 4, 48), Decl(stringLiteralTypesOverloads01.ts, 5, 50), Decl(stringLiteralTypesOverloads01.ts, 6, 70), Decl(stringLiteralTypesOverloads01.ts, 7, 70), Decl(stringLiteralTypesOverloads01.ts, 8, 68), Decl(stringLiteralTypesOverloads01.ts, 9, 90)) +>x : Symbol(x, Decl(stringLiteralTypesOverloads01.ts, 9, 27)) + +function getFalsyPrimitive(x: PrimitiveName): number | string | boolean { +>getFalsyPrimitive : Symbol(getFalsyPrimitive, Decl(stringLiteralTypesOverloads01.ts, 1, 53), Decl(stringLiteralTypesOverloads01.ts, 3, 48), Decl(stringLiteralTypesOverloads01.ts, 4, 48), Decl(stringLiteralTypesOverloads01.ts, 5, 50), Decl(stringLiteralTypesOverloads01.ts, 6, 70), Decl(stringLiteralTypesOverloads01.ts, 7, 70), Decl(stringLiteralTypesOverloads01.ts, 8, 68), Decl(stringLiteralTypesOverloads01.ts, 9, 90)) +>x : Symbol(x, Decl(stringLiteralTypesOverloads01.ts, 10, 27)) +>PrimitiveName : Symbol(PrimitiveName, Decl(stringLiteralTypesOverloads01.ts, 0, 0)) + + if (x === "string") { +>x : Symbol(x, Decl(stringLiteralTypesOverloads01.ts, 10, 27)) + + return ""; + } + if (x === "number") { +>x : Symbol(x, Decl(stringLiteralTypesOverloads01.ts, 10, 27)) + + return 0; + } + if (x === "boolean") { +>x : Symbol(x, Decl(stringLiteralTypesOverloads01.ts, 10, 27)) + + return false; + } + + // Should be unreachable. + throw "Invalid value"; +} + +namespace Consts1 { +>Consts1 : Symbol(Consts1, Decl(stringLiteralTypesOverloads01.ts, 23, 1)) + + const EMPTY_STRING = getFalsyPrimitive("string"); +>EMPTY_STRING : Symbol(EMPTY_STRING, Decl(stringLiteralTypesOverloads01.ts, 26, 9)) +>getFalsyPrimitive : Symbol(getFalsyPrimitive, Decl(stringLiteralTypesOverloads01.ts, 1, 53), Decl(stringLiteralTypesOverloads01.ts, 3, 48), Decl(stringLiteralTypesOverloads01.ts, 4, 48), Decl(stringLiteralTypesOverloads01.ts, 5, 50), Decl(stringLiteralTypesOverloads01.ts, 6, 70), Decl(stringLiteralTypesOverloads01.ts, 7, 70), Decl(stringLiteralTypesOverloads01.ts, 8, 68), Decl(stringLiteralTypesOverloads01.ts, 9, 90)) + + const ZERO = getFalsyPrimitive('number'); +>ZERO : Symbol(ZERO, Decl(stringLiteralTypesOverloads01.ts, 27, 9)) +>getFalsyPrimitive : Symbol(getFalsyPrimitive, Decl(stringLiteralTypesOverloads01.ts, 1, 53), Decl(stringLiteralTypesOverloads01.ts, 3, 48), Decl(stringLiteralTypesOverloads01.ts, 4, 48), Decl(stringLiteralTypesOverloads01.ts, 5, 50), Decl(stringLiteralTypesOverloads01.ts, 6, 70), Decl(stringLiteralTypesOverloads01.ts, 7, 70), Decl(stringLiteralTypesOverloads01.ts, 8, 68), Decl(stringLiteralTypesOverloads01.ts, 9, 90)) + + const FALSE = getFalsyPrimitive("boolean"); +>FALSE : Symbol(FALSE, Decl(stringLiteralTypesOverloads01.ts, 28, 9)) +>getFalsyPrimitive : Symbol(getFalsyPrimitive, Decl(stringLiteralTypesOverloads01.ts, 1, 53), Decl(stringLiteralTypesOverloads01.ts, 3, 48), Decl(stringLiteralTypesOverloads01.ts, 4, 48), Decl(stringLiteralTypesOverloads01.ts, 5, 50), Decl(stringLiteralTypesOverloads01.ts, 6, 70), Decl(stringLiteralTypesOverloads01.ts, 7, 70), Decl(stringLiteralTypesOverloads01.ts, 8, 68), Decl(stringLiteralTypesOverloads01.ts, 9, 90)) +} + +const string: "string" = "string" +>string : Symbol(string, Decl(stringLiteralTypesOverloads01.ts, 31, 5)) + +const number: "number" = "number" +>number : Symbol(number, Decl(stringLiteralTypesOverloads01.ts, 32, 5)) + +const boolean: "boolean" = "boolean" +>boolean : Symbol(boolean, Decl(stringLiteralTypesOverloads01.ts, 33, 5)) + +const stringOrNumber = string || number; +>stringOrNumber : Symbol(stringOrNumber, Decl(stringLiteralTypesOverloads01.ts, 35, 5)) +>string : Symbol(string, Decl(stringLiteralTypesOverloads01.ts, 31, 5)) +>number : Symbol(number, Decl(stringLiteralTypesOverloads01.ts, 32, 5)) + +const stringOrBoolean = string || boolean; +>stringOrBoolean : Symbol(stringOrBoolean, Decl(stringLiteralTypesOverloads01.ts, 36, 5)) +>string : Symbol(string, Decl(stringLiteralTypesOverloads01.ts, 31, 5)) +>boolean : Symbol(boolean, Decl(stringLiteralTypesOverloads01.ts, 33, 5)) + +const booleanOrNumber = number || boolean; +>booleanOrNumber : Symbol(booleanOrNumber, Decl(stringLiteralTypesOverloads01.ts, 37, 5)) +>number : Symbol(number, Decl(stringLiteralTypesOverloads01.ts, 32, 5)) +>boolean : Symbol(boolean, Decl(stringLiteralTypesOverloads01.ts, 33, 5)) + +const stringOrBooleanOrNumber = stringOrBoolean || number; +>stringOrBooleanOrNumber : Symbol(stringOrBooleanOrNumber, Decl(stringLiteralTypesOverloads01.ts, 38, 5)) +>stringOrBoolean : Symbol(stringOrBoolean, Decl(stringLiteralTypesOverloads01.ts, 36, 5)) +>number : Symbol(number, Decl(stringLiteralTypesOverloads01.ts, 32, 5)) + +namespace Consts2 { +>Consts2 : Symbol(Consts2, Decl(stringLiteralTypesOverloads01.ts, 38, 58)) + + const EMPTY_STRING = getFalsyPrimitive(string); +>EMPTY_STRING : Symbol(EMPTY_STRING, Decl(stringLiteralTypesOverloads01.ts, 41, 9)) +>getFalsyPrimitive : Symbol(getFalsyPrimitive, Decl(stringLiteralTypesOverloads01.ts, 1, 53), Decl(stringLiteralTypesOverloads01.ts, 3, 48), Decl(stringLiteralTypesOverloads01.ts, 4, 48), Decl(stringLiteralTypesOverloads01.ts, 5, 50), Decl(stringLiteralTypesOverloads01.ts, 6, 70), Decl(stringLiteralTypesOverloads01.ts, 7, 70), Decl(stringLiteralTypesOverloads01.ts, 8, 68), Decl(stringLiteralTypesOverloads01.ts, 9, 90)) +>string : Symbol(string, Decl(stringLiteralTypesOverloads01.ts, 31, 5)) + + const ZERO = getFalsyPrimitive(number); +>ZERO : Symbol(ZERO, Decl(stringLiteralTypesOverloads01.ts, 42, 9)) +>getFalsyPrimitive : Symbol(getFalsyPrimitive, Decl(stringLiteralTypesOverloads01.ts, 1, 53), Decl(stringLiteralTypesOverloads01.ts, 3, 48), Decl(stringLiteralTypesOverloads01.ts, 4, 48), Decl(stringLiteralTypesOverloads01.ts, 5, 50), Decl(stringLiteralTypesOverloads01.ts, 6, 70), Decl(stringLiteralTypesOverloads01.ts, 7, 70), Decl(stringLiteralTypesOverloads01.ts, 8, 68), Decl(stringLiteralTypesOverloads01.ts, 9, 90)) +>number : Symbol(number, Decl(stringLiteralTypesOverloads01.ts, 32, 5)) + + const FALSE = getFalsyPrimitive(boolean); +>FALSE : Symbol(FALSE, Decl(stringLiteralTypesOverloads01.ts, 43, 9)) +>getFalsyPrimitive : Symbol(getFalsyPrimitive, Decl(stringLiteralTypesOverloads01.ts, 1, 53), Decl(stringLiteralTypesOverloads01.ts, 3, 48), Decl(stringLiteralTypesOverloads01.ts, 4, 48), Decl(stringLiteralTypesOverloads01.ts, 5, 50), Decl(stringLiteralTypesOverloads01.ts, 6, 70), Decl(stringLiteralTypesOverloads01.ts, 7, 70), Decl(stringLiteralTypesOverloads01.ts, 8, 68), Decl(stringLiteralTypesOverloads01.ts, 9, 90)) +>boolean : Symbol(boolean, Decl(stringLiteralTypesOverloads01.ts, 33, 5)) + + const a = getFalsyPrimitive(stringOrNumber); +>a : Symbol(a, Decl(stringLiteralTypesOverloads01.ts, 45, 9)) +>getFalsyPrimitive : Symbol(getFalsyPrimitive, Decl(stringLiteralTypesOverloads01.ts, 1, 53), Decl(stringLiteralTypesOverloads01.ts, 3, 48), Decl(stringLiteralTypesOverloads01.ts, 4, 48), Decl(stringLiteralTypesOverloads01.ts, 5, 50), Decl(stringLiteralTypesOverloads01.ts, 6, 70), Decl(stringLiteralTypesOverloads01.ts, 7, 70), Decl(stringLiteralTypesOverloads01.ts, 8, 68), Decl(stringLiteralTypesOverloads01.ts, 9, 90)) +>stringOrNumber : Symbol(stringOrNumber, Decl(stringLiteralTypesOverloads01.ts, 35, 5)) + + const b = getFalsyPrimitive(stringOrBoolean); +>b : Symbol(b, Decl(stringLiteralTypesOverloads01.ts, 46, 9)) +>getFalsyPrimitive : Symbol(getFalsyPrimitive, Decl(stringLiteralTypesOverloads01.ts, 1, 53), Decl(stringLiteralTypesOverloads01.ts, 3, 48), Decl(stringLiteralTypesOverloads01.ts, 4, 48), Decl(stringLiteralTypesOverloads01.ts, 5, 50), Decl(stringLiteralTypesOverloads01.ts, 6, 70), Decl(stringLiteralTypesOverloads01.ts, 7, 70), Decl(stringLiteralTypesOverloads01.ts, 8, 68), Decl(stringLiteralTypesOverloads01.ts, 9, 90)) +>stringOrBoolean : Symbol(stringOrBoolean, Decl(stringLiteralTypesOverloads01.ts, 36, 5)) + + const c = getFalsyPrimitive(booleanOrNumber); +>c : Symbol(c, Decl(stringLiteralTypesOverloads01.ts, 47, 9)) +>getFalsyPrimitive : Symbol(getFalsyPrimitive, Decl(stringLiteralTypesOverloads01.ts, 1, 53), Decl(stringLiteralTypesOverloads01.ts, 3, 48), Decl(stringLiteralTypesOverloads01.ts, 4, 48), Decl(stringLiteralTypesOverloads01.ts, 5, 50), Decl(stringLiteralTypesOverloads01.ts, 6, 70), Decl(stringLiteralTypesOverloads01.ts, 7, 70), Decl(stringLiteralTypesOverloads01.ts, 8, 68), Decl(stringLiteralTypesOverloads01.ts, 9, 90)) +>booleanOrNumber : Symbol(booleanOrNumber, Decl(stringLiteralTypesOverloads01.ts, 37, 5)) + + const d = getFalsyPrimitive(stringOrBooleanOrNumber); +>d : Symbol(d, Decl(stringLiteralTypesOverloads01.ts, 48, 9)) +>getFalsyPrimitive : Symbol(getFalsyPrimitive, Decl(stringLiteralTypesOverloads01.ts, 1, 53), Decl(stringLiteralTypesOverloads01.ts, 3, 48), Decl(stringLiteralTypesOverloads01.ts, 4, 48), Decl(stringLiteralTypesOverloads01.ts, 5, 50), Decl(stringLiteralTypesOverloads01.ts, 6, 70), Decl(stringLiteralTypesOverloads01.ts, 7, 70), Decl(stringLiteralTypesOverloads01.ts, 8, 68), Decl(stringLiteralTypesOverloads01.ts, 9, 90)) +>stringOrBooleanOrNumber : Symbol(stringOrBooleanOrNumber, Decl(stringLiteralTypesOverloads01.ts, 38, 5)) +} + + + diff --git a/tests/baselines/reference/stringLiteralTypesOverloads01.types b/tests/baselines/reference/stringLiteralTypesOverloads01.types new file mode 100644 index 00000000000..6ba8d482117 --- /dev/null +++ b/tests/baselines/reference/stringLiteralTypesOverloads01.types @@ -0,0 +1,174 @@ +=== tests/cases/conformance/types/stringLiteral/stringLiteralTypesOverloads01.ts === + +type PrimitiveName = 'string' | 'number' | 'boolean'; +>PrimitiveName : "string" | "number" | "boolean" + +function getFalsyPrimitive(x: "string"): string; +>getFalsyPrimitive : { (x: "string"): string; (x: "number"): number; (x: "boolean"): boolean; (x: "boolean" | "string"): boolean | string; (x: "boolean" | "number"): boolean | number; (x: "number" | "string"): number | string; (x: "number" | "string" | "boolean"): number | string | boolean; } +>x : "string" + +function getFalsyPrimitive(x: "number"): number; +>getFalsyPrimitive : { (x: "string"): string; (x: "number"): number; (x: "boolean"): boolean; (x: "boolean" | "string"): boolean | string; (x: "boolean" | "number"): boolean | number; (x: "number" | "string"): number | string; (x: "number" | "string" | "boolean"): number | string | boolean; } +>x : "number" + +function getFalsyPrimitive(x: "boolean"): boolean; +>getFalsyPrimitive : { (x: "string"): string; (x: "number"): number; (x: "boolean"): boolean; (x: "boolean" | "string"): boolean | string; (x: "boolean" | "number"): boolean | number; (x: "number" | "string"): number | string; (x: "number" | "string" | "boolean"): number | string | boolean; } +>x : "boolean" + +function getFalsyPrimitive(x: "boolean" | "string"): boolean | string; +>getFalsyPrimitive : { (x: "string"): string; (x: "number"): number; (x: "boolean"): boolean; (x: "boolean" | "string"): boolean | string; (x: "boolean" | "number"): boolean | number; (x: "number" | "string"): number | string; (x: "number" | "string" | "boolean"): number | string | boolean; } +>x : "boolean" | "string" + +function getFalsyPrimitive(x: "boolean" | "number"): boolean | number; +>getFalsyPrimitive : { (x: "string"): string; (x: "number"): number; (x: "boolean"): boolean; (x: "boolean" | "string"): boolean | string; (x: "boolean" | "number"): boolean | number; (x: "number" | "string"): number | string; (x: "number" | "string" | "boolean"): number | string | boolean; } +>x : "boolean" | "number" + +function getFalsyPrimitive(x: "number" | "string"): number | string; +>getFalsyPrimitive : { (x: "string"): string; (x: "number"): number; (x: "boolean"): boolean; (x: "boolean" | "string"): boolean | string; (x: "boolean" | "number"): boolean | number; (x: "number" | "string"): number | string; (x: "number" | "string" | "boolean"): number | string | boolean; } +>x : "number" | "string" + +function getFalsyPrimitive(x: "number" | "string" | "boolean"): number | string | boolean; +>getFalsyPrimitive : { (x: "string"): string; (x: "number"): number; (x: "boolean"): boolean; (x: "boolean" | "string"): boolean | string; (x: "boolean" | "number"): boolean | number; (x: "number" | "string"): number | string; (x: "number" | "string" | "boolean"): number | string | boolean; } +>x : "number" | "string" | "boolean" + +function getFalsyPrimitive(x: PrimitiveName): number | string | boolean { +>getFalsyPrimitive : { (x: "string"): string; (x: "number"): number; (x: "boolean"): boolean; (x: "boolean" | "string"): boolean | string; (x: "boolean" | "number"): boolean | number; (x: "number" | "string"): number | string; (x: "number" | "string" | "boolean"): number | string | boolean; } +>x : "string" | "number" | "boolean" +>PrimitiveName : "string" | "number" | "boolean" + + if (x === "string") { +>x === "string" : boolean +>x : "string" | "number" | "boolean" +>"string" : string + + return ""; +>"" : string + } + if (x === "number") { +>x === "number" : boolean +>x : "string" | "number" | "boolean" +>"number" : string + + return 0; +>0 : number + } + if (x === "boolean") { +>x === "boolean" : boolean +>x : "string" | "number" | "boolean" +>"boolean" : string + + return false; +>false : boolean + } + + // Should be unreachable. + throw "Invalid value"; +>"Invalid value" : string +} + +namespace Consts1 { +>Consts1 : typeof Consts1 + + const EMPTY_STRING = getFalsyPrimitive("string"); +>EMPTY_STRING : string +>getFalsyPrimitive("string") : string +>getFalsyPrimitive : { (x: "string"): string; (x: "number"): number; (x: "boolean"): boolean; (x: "boolean" | "string"): boolean | string; (x: "boolean" | "number"): boolean | number; (x: "number" | "string"): number | string; (x: "number" | "string" | "boolean"): number | string | boolean; } +>"string" : "string" + + const ZERO = getFalsyPrimitive('number'); +>ZERO : number +>getFalsyPrimitive('number') : number +>getFalsyPrimitive : { (x: "string"): string; (x: "number"): number; (x: "boolean"): boolean; (x: "boolean" | "string"): boolean | string; (x: "boolean" | "number"): boolean | number; (x: "number" | "string"): number | string; (x: "number" | "string" | "boolean"): number | string | boolean; } +>'number' : "number" + + const FALSE = getFalsyPrimitive("boolean"); +>FALSE : boolean +>getFalsyPrimitive("boolean") : boolean +>getFalsyPrimitive : { (x: "string"): string; (x: "number"): number; (x: "boolean"): boolean; (x: "boolean" | "string"): boolean | string; (x: "boolean" | "number"): boolean | number; (x: "number" | "string"): number | string; (x: "number" | "string" | "boolean"): number | string | boolean; } +>"boolean" : "boolean" +} + +const string: "string" = "string" +>string : "string" +>"string" : "string" + +const number: "number" = "number" +>number : "number" +>"number" : "number" + +const boolean: "boolean" = "boolean" +>boolean : "boolean" +>"boolean" : "boolean" + +const stringOrNumber = string || number; +>stringOrNumber : "string" | "number" +>string || number : "string" | "number" +>string : "string" +>number : "number" + +const stringOrBoolean = string || boolean; +>stringOrBoolean : "string" | "boolean" +>string || boolean : "string" | "boolean" +>string : "string" +>boolean : "boolean" + +const booleanOrNumber = number || boolean; +>booleanOrNumber : "number" | "boolean" +>number || boolean : "number" | "boolean" +>number : "number" +>boolean : "boolean" + +const stringOrBooleanOrNumber = stringOrBoolean || number; +>stringOrBooleanOrNumber : "string" | "boolean" | "number" +>stringOrBoolean || number : "string" | "boolean" | "number" +>stringOrBoolean : "string" | "boolean" +>number : "number" + +namespace Consts2 { +>Consts2 : typeof Consts2 + + const EMPTY_STRING = getFalsyPrimitive(string); +>EMPTY_STRING : string +>getFalsyPrimitive(string) : string +>getFalsyPrimitive : { (x: "string"): string; (x: "number"): number; (x: "boolean"): boolean; (x: "boolean" | "string"): boolean | string; (x: "boolean" | "number"): boolean | number; (x: "number" | "string"): number | string; (x: "number" | "string" | "boolean"): number | string | boolean; } +>string : "string" + + const ZERO = getFalsyPrimitive(number); +>ZERO : number +>getFalsyPrimitive(number) : number +>getFalsyPrimitive : { (x: "string"): string; (x: "number"): number; (x: "boolean"): boolean; (x: "boolean" | "string"): boolean | string; (x: "boolean" | "number"): boolean | number; (x: "number" | "string"): number | string; (x: "number" | "string" | "boolean"): number | string | boolean; } +>number : "number" + + const FALSE = getFalsyPrimitive(boolean); +>FALSE : boolean +>getFalsyPrimitive(boolean) : boolean +>getFalsyPrimitive : { (x: "string"): string; (x: "number"): number; (x: "boolean"): boolean; (x: "boolean" | "string"): boolean | string; (x: "boolean" | "number"): boolean | number; (x: "number" | "string"): number | string; (x: "number" | "string" | "boolean"): number | string | boolean; } +>boolean : "boolean" + + const a = getFalsyPrimitive(stringOrNumber); +>a : number | string +>getFalsyPrimitive(stringOrNumber) : number | string +>getFalsyPrimitive : { (x: "string"): string; (x: "number"): number; (x: "boolean"): boolean; (x: "boolean" | "string"): boolean | string; (x: "boolean" | "number"): boolean | number; (x: "number" | "string"): number | string; (x: "number" | "string" | "boolean"): number | string | boolean; } +>stringOrNumber : "string" | "number" + + const b = getFalsyPrimitive(stringOrBoolean); +>b : boolean | string +>getFalsyPrimitive(stringOrBoolean) : boolean | string +>getFalsyPrimitive : { (x: "string"): string; (x: "number"): number; (x: "boolean"): boolean; (x: "boolean" | "string"): boolean | string; (x: "boolean" | "number"): boolean | number; (x: "number" | "string"): number | string; (x: "number" | "string" | "boolean"): number | string | boolean; } +>stringOrBoolean : "string" | "boolean" + + const c = getFalsyPrimitive(booleanOrNumber); +>c : boolean | number +>getFalsyPrimitive(booleanOrNumber) : boolean | number +>getFalsyPrimitive : { (x: "string"): string; (x: "number"): number; (x: "boolean"): boolean; (x: "boolean" | "string"): boolean | string; (x: "boolean" | "number"): boolean | number; (x: "number" | "string"): number | string; (x: "number" | "string" | "boolean"): number | string | boolean; } +>booleanOrNumber : "number" | "boolean" + + const d = getFalsyPrimitive(stringOrBooleanOrNumber); +>d : number | string | boolean +>getFalsyPrimitive(stringOrBooleanOrNumber) : number | string | boolean +>getFalsyPrimitive : { (x: "string"): string; (x: "number"): number; (x: "boolean"): boolean; (x: "boolean" | "string"): boolean | string; (x: "boolean" | "number"): boolean | number; (x: "number" | "string"): number | string; (x: "number" | "string" | "boolean"): number | string | boolean; } +>stringOrBooleanOrNumber : "string" | "boolean" | "number" +} + + + From 6cd5a4dac9599122eff78d016a82ac0d362850ab Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 10 Dec 2015 11:03:45 -0800 Subject: [PATCH 09/79] Compare enums semi-structurally. 1. Unqualified names must match. 2. Target contains members with same names as all source members. --- src/compiler/checker.ts | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 50a3aee9955..0f04daf2983 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5040,6 +5040,11 @@ namespace ts { if (source === undefinedType) return Ternary.True; if (source === nullType && target !== undefinedType) return Ternary.True; if (source.flags & TypeFlags.Enum && target === numberType) return Ternary.True; + if (source.flags & TypeFlags.Enum && target.flags & TypeFlags.Enum) { + if (result = enumRelatedTo(source, target)) { + return result; + } + } if (source.flags & TypeFlags.StringLiteral && target === stringType) return Ternary.True; if (relation === assignableRelation) { if (isTypeAny(source)) return Ternary.True; @@ -5750,6 +5755,25 @@ namespace ts { } return Ternary.False; } + + function enumRelatedTo(source: Type, target: Type) { + if (source.symbol.name !== target.symbol.name) { + return Ternary.False; + } + const sourceDecl = getMergedSymbol(source.symbol).valueDeclaration; + const targetDecl = getMergedSymbol(target.symbol).valueDeclaration; + const targetMembers = arrayToMap(targetDecl.members, member => getTextOfPropertyName(member.name)); + for (const member of sourceDecl.members) { + const name = getTextOfPropertyName(member.name); + if (!targetMembers[name]) { + reportError(Diagnostics.Property_0_is_missing_in_type_1, + name, + typeToString(target, /*enclosingDeclaration*/ undefined, TypeFormatFlags.UseFullyQualifiedType)); + return Ternary.False; + } + } + return Ternary.True; + } } // Return true if the given type is part of a deeply nested chain of generic instantiations. We consider this to be the case From 6ed5b59f751f57532e43cbc0ac71ff097bcc899b Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 10 Dec 2015 11:05:25 -0800 Subject: [PATCH 10/79] Add test case and accept baseline --- .../enumAssignmentCompat3.errors.txt | 75 ++++++++++++ .../reference/enumAssignmentCompat3.js | 115 ++++++++++++++++++ tests/cases/compiler/enumAssignmentCompat3.ts | 45 +++++++ 3 files changed, 235 insertions(+) create mode 100644 tests/baselines/reference/enumAssignmentCompat3.errors.txt create mode 100644 tests/baselines/reference/enumAssignmentCompat3.js create mode 100644 tests/cases/compiler/enumAssignmentCompat3.ts diff --git a/tests/baselines/reference/enumAssignmentCompat3.errors.txt b/tests/baselines/reference/enumAssignmentCompat3.errors.txt new file mode 100644 index 00000000000..d82a4b7d490 --- /dev/null +++ b/tests/baselines/reference/enumAssignmentCompat3.errors.txt @@ -0,0 +1,75 @@ +tests/cases/compiler/enumAssignmentCompat3.ts(37,1): error TS2322: Type 'Abcd.E' is not assignable to type 'First.E'. + Property 'd' is missing in type 'First.E'. +tests/cases/compiler/enumAssignmentCompat3.ts(39,1): error TS2322: Type 'Cd.E' is not assignable to type 'First.E'. + Property 'd' is missing in type 'First.E'. +tests/cases/compiler/enumAssignmentCompat3.ts(40,1): error TS2322: Type 'Nope' is not assignable to type 'E'. +tests/cases/compiler/enumAssignmentCompat3.ts(43,1): error TS2322: Type 'First.E' is not assignable to type 'Ab.E'. + Property 'c' is missing in type 'Ab.E'. +tests/cases/compiler/enumAssignmentCompat3.ts(44,1): error TS2322: Type 'First.E' is not assignable to type 'Cd.E'. + Property 'a' is missing in type 'Cd.E'. +tests/cases/compiler/enumAssignmentCompat3.ts(45,1): error TS2322: Type 'E' is not assignable to type 'Nope'. + + +==== tests/cases/compiler/enumAssignmentCompat3.ts (6 errors) ==== + namespace First { + export enum E { + a, b, c, + } + } + namespace Abc { + export enum E { + a, b, c, + } + export enum Nope { + a, b, c, + } + } + namespace Abcd { + export enum E { + a, b, c, d, + } + } + namespace Ab { + export enum E { + a, b, + } + } + namespace Cd { + export enum E { + c, d, + } + } + + var abc: First.E; + var secondAbc: Abc.E; + var secondAbcd: Abcd.E; + var secondAb: Ab.E; + var secondCd: Cd.E; + var nope: Abc.Nope; + abc = secondAbc; // ok + abc = secondAbcd; // missing 'd' + ~~~ +!!! error TS2322: Type 'Abcd.E' is not assignable to type 'First.E'. +!!! error TS2322: Property 'd' is missing in type 'First.E'. + abc = secondAb; // ok + abc = secondCd; // missing 'd' + ~~~ +!!! error TS2322: Type 'Cd.E' is not assignable to type 'First.E'. +!!! error TS2322: Property 'd' is missing in type 'First.E'. + abc = nope; // nope! + ~~~ +!!! error TS2322: Type 'Nope' is not assignable to type 'E'. + secondAbc = abc; // ok + secondAbcd = abc; // ok + secondAb = abc; // missing 'c' + ~~~~~~~~ +!!! error TS2322: Type 'First.E' is not assignable to type 'Ab.E'. +!!! error TS2322: Property 'c' is missing in type 'Ab.E'. + secondCd = abc; // missing 'a' and 'b' + ~~~~~~~~ +!!! error TS2322: Type 'First.E' is not assignable to type 'Cd.E'. +!!! error TS2322: Property 'a' is missing in type 'Cd.E'. + nope = abc; // nope! + ~~~~ +!!! error TS2322: Type 'E' is not assignable to type 'Nope'. + \ No newline at end of file diff --git a/tests/baselines/reference/enumAssignmentCompat3.js b/tests/baselines/reference/enumAssignmentCompat3.js new file mode 100644 index 00000000000..33cfdd28e88 --- /dev/null +++ b/tests/baselines/reference/enumAssignmentCompat3.js @@ -0,0 +1,115 @@ +//// [enumAssignmentCompat3.ts] +namespace First { + export enum E { + a, b, c, + } +} +namespace Abc { + export enum E { + a, b, c, + } + export enum Nope { + a, b, c, + } +} +namespace Abcd { + export enum E { + a, b, c, d, + } +} +namespace Ab { + export enum E { + a, b, + } +} +namespace Cd { + export enum E { + c, d, + } +} + +var abc: First.E; +var secondAbc: Abc.E; +var secondAbcd: Abcd.E; +var secondAb: Ab.E; +var secondCd: Cd.E; +var nope: Abc.Nope; +abc = secondAbc; // ok +abc = secondAbcd; // missing 'd' +abc = secondAb; // ok +abc = secondCd; // missing 'd' +abc = nope; // nope! +secondAbc = abc; // ok +secondAbcd = abc; // ok +secondAb = abc; // missing 'c' +secondCd = abc; // missing 'a' and 'b' +nope = abc; // nope! + + +//// [enumAssignmentCompat3.js] +var First; +(function (First) { + (function (E) { + E[E["a"] = 0] = "a"; + E[E["b"] = 1] = "b"; + E[E["c"] = 2] = "c"; + })(First.E || (First.E = {})); + var E = First.E; +})(First || (First = {})); +var Abc; +(function (Abc) { + (function (E) { + E[E["a"] = 0] = "a"; + E[E["b"] = 1] = "b"; + E[E["c"] = 2] = "c"; + })(Abc.E || (Abc.E = {})); + var E = Abc.E; + (function (Nope) { + Nope[Nope["a"] = 0] = "a"; + Nope[Nope["b"] = 1] = "b"; + Nope[Nope["c"] = 2] = "c"; + })(Abc.Nope || (Abc.Nope = {})); + var Nope = Abc.Nope; +})(Abc || (Abc = {})); +var Abcd; +(function (Abcd) { + (function (E) { + E[E["a"] = 0] = "a"; + E[E["b"] = 1] = "b"; + E[E["c"] = 2] = "c"; + E[E["d"] = 3] = "d"; + })(Abcd.E || (Abcd.E = {})); + var E = Abcd.E; +})(Abcd || (Abcd = {})); +var Ab; +(function (Ab) { + (function (E) { + E[E["a"] = 0] = "a"; + E[E["b"] = 1] = "b"; + })(Ab.E || (Ab.E = {})); + var E = Ab.E; +})(Ab || (Ab = {})); +var Cd; +(function (Cd) { + (function (E) { + E[E["c"] = 0] = "c"; + E[E["d"] = 1] = "d"; + })(Cd.E || (Cd.E = {})); + var E = Cd.E; +})(Cd || (Cd = {})); +var abc; +var secondAbc; +var secondAbcd; +var secondAb; +var secondCd; +var nope; +abc = secondAbc; // ok +abc = secondAbcd; // missing 'd' +abc = secondAb; // ok +abc = secondCd; // missing 'd' +abc = nope; // nope! +secondAbc = abc; // ok +secondAbcd = abc; // ok +secondAb = abc; // missing 'c' +secondCd = abc; // missing 'a' and 'b' +nope = abc; // nope! diff --git a/tests/cases/compiler/enumAssignmentCompat3.ts b/tests/cases/compiler/enumAssignmentCompat3.ts new file mode 100644 index 00000000000..94a22c7f346 --- /dev/null +++ b/tests/cases/compiler/enumAssignmentCompat3.ts @@ -0,0 +1,45 @@ +namespace First { + export enum E { + a, b, c, + } +} +namespace Abc { + export enum E { + a, b, c, + } + export enum Nope { + a, b, c, + } +} +namespace Abcd { + export enum E { + a, b, c, d, + } +} +namespace Ab { + export enum E { + a, b, + } +} +namespace Cd { + export enum E { + c, d, + } +} + +var abc: First.E; +var secondAbc: Abc.E; +var secondAbcd: Abcd.E; +var secondAb: Ab.E; +var secondCd: Cd.E; +var nope: Abc.Nope; +abc = secondAbc; // ok +abc = secondAbcd; // missing 'd' +abc = secondAb; // ok +abc = secondCd; // missing 'd' +abc = nope; // nope! +secondAbc = abc; // ok +secondAbcd = abc; // ok +secondAb = abc; // missing 'c' +secondCd = abc; // missing 'a' and 'b' +nope = abc; // nope! From cc1d8cf395eebdf5e1f6e2f9ddb90111fbad95b7 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 10 Dec 2015 13:47:18 -0800 Subject: [PATCH 11/79] Address review comments --- src/compiler/checker.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0f04daf2983..857fa97ca06 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5757,15 +5757,17 @@ namespace ts { } function enumRelatedTo(source: Type, target: Type) { - if (source.symbol.name !== target.symbol.name) { + if (source.symbol.name !== target.symbol.name || + source.symbol.flags & SymbolFlags.ConstEnum || + target.symbol.flags & SymbolFlags.ConstEnum) { return Ternary.False; } - const sourceDecl = getMergedSymbol(source.symbol).valueDeclaration; - const targetDecl = getMergedSymbol(target.symbol).valueDeclaration; + const sourceDecl = getDeclarationOfKind(source.symbol, SyntaxKind.EnumDeclaration); + const targetDecl = getDeclarationOfKind(target.symbol, SyntaxKind.EnumDeclaration); const targetMembers = arrayToMap(targetDecl.members, member => getTextOfPropertyName(member.name)); for (const member of sourceDecl.members) { const name = getTextOfPropertyName(member.name); - if (!targetMembers[name]) { + if (!hasProperty(targetMembers, name)) { reportError(Diagnostics.Property_0_is_missing_in_type_1, name, typeToString(target, /*enclosingDeclaration*/ undefined, TypeFormatFlags.UseFullyQualifiedType)); From ff0138878ddbe5823df3d37073e875758f23ec18 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 10 Dec 2015 13:47:31 -0800 Subject: [PATCH 12/79] Add tests from review --- .../enumAssignmentCompat3.errors.txt | 38 +++++++++++++++---- .../reference/enumAssignmentCompat3.js | 28 ++++++++++++++ tests/cases/compiler/enumAssignmentCompat3.ts | 18 +++++++++ 3 files changed, 77 insertions(+), 7 deletions(-) diff --git a/tests/baselines/reference/enumAssignmentCompat3.errors.txt b/tests/baselines/reference/enumAssignmentCompat3.errors.txt index d82a4b7d490..b9ab92adec1 100644 --- a/tests/baselines/reference/enumAssignmentCompat3.errors.txt +++ b/tests/baselines/reference/enumAssignmentCompat3.errors.txt @@ -1,16 +1,18 @@ -tests/cases/compiler/enumAssignmentCompat3.ts(37,1): error TS2322: Type 'Abcd.E' is not assignable to type 'First.E'. +tests/cases/compiler/enumAssignmentCompat3.ts(49,1): error TS2322: Type 'Abcd.E' is not assignable to type 'First.E'. Property 'd' is missing in type 'First.E'. -tests/cases/compiler/enumAssignmentCompat3.ts(39,1): error TS2322: Type 'Cd.E' is not assignable to type 'First.E'. +tests/cases/compiler/enumAssignmentCompat3.ts(51,1): error TS2322: Type 'Cd.E' is not assignable to type 'First.E'. Property 'd' is missing in type 'First.E'. -tests/cases/compiler/enumAssignmentCompat3.ts(40,1): error TS2322: Type 'Nope' is not assignable to type 'E'. -tests/cases/compiler/enumAssignmentCompat3.ts(43,1): error TS2322: Type 'First.E' is not assignable to type 'Ab.E'. +tests/cases/compiler/enumAssignmentCompat3.ts(52,1): error TS2322: Type 'Nope' is not assignable to type 'E'. +tests/cases/compiler/enumAssignmentCompat3.ts(56,1): error TS2322: Type 'First.E' is not assignable to type 'Ab.E'. Property 'c' is missing in type 'Ab.E'. -tests/cases/compiler/enumAssignmentCompat3.ts(44,1): error TS2322: Type 'First.E' is not assignable to type 'Cd.E'. +tests/cases/compiler/enumAssignmentCompat3.ts(57,1): error TS2322: Type 'First.E' is not assignable to type 'Cd.E'. Property 'a' is missing in type 'Cd.E'. -tests/cases/compiler/enumAssignmentCompat3.ts(45,1): error TS2322: Type 'E' is not assignable to type 'Nope'. +tests/cases/compiler/enumAssignmentCompat3.ts(58,1): error TS2322: Type 'E' is not assignable to type 'Nope'. +tests/cases/compiler/enumAssignmentCompat3.ts(62,1): error TS2322: Type 'Const.E' is not assignable to type 'First.E'. +tests/cases/compiler/enumAssignmentCompat3.ts(63,1): error TS2322: Type 'First.E' is not assignable to type 'Const.E'. -==== tests/cases/compiler/enumAssignmentCompat3.ts (6 errors) ==== +==== tests/cases/compiler/enumAssignmentCompat3.ts (8 errors) ==== namespace First { export enum E { a, b, c, @@ -39,6 +41,16 @@ tests/cases/compiler/enumAssignmentCompat3.ts(45,1): error TS2322: Type 'E' is n c, d, } } + namespace Const { + export const enum E { + a, b, c, + } + } + namespace Decl { + export declare enum E { + a, b, c = 3, + } + } var abc: First.E; var secondAbc: Abc.E; @@ -46,6 +58,8 @@ tests/cases/compiler/enumAssignmentCompat3.ts(45,1): error TS2322: Type 'E' is n var secondAb: Ab.E; var secondCd: Cd.E; var nope: Abc.Nope; + var k: Const.E; + var decl: Decl.E; abc = secondAbc; // ok abc = secondAbcd; // missing 'd' ~~~ @@ -59,6 +73,7 @@ tests/cases/compiler/enumAssignmentCompat3.ts(45,1): error TS2322: Type 'E' is n abc = nope; // nope! ~~~ !!! error TS2322: Type 'Nope' is not assignable to type 'E'. + abc = decl; // ok secondAbc = abc; // ok secondAbcd = abc; // ok secondAb = abc; // missing 'c' @@ -72,4 +87,13 @@ tests/cases/compiler/enumAssignmentCompat3.ts(45,1): error TS2322: Type 'E' is n nope = abc; // nope! ~~~~ !!! error TS2322: Type 'E' is not assignable to type 'Nope'. + decl = abc; // ok + + k = k; // const is only assignable to itself + abc = k; // error + ~~~ +!!! error TS2322: Type 'Const.E' is not assignable to type 'First.E'. + k = abc; + ~ +!!! error TS2322: Type 'First.E' is not assignable to type 'Const.E'. \ No newline at end of file diff --git a/tests/baselines/reference/enumAssignmentCompat3.js b/tests/baselines/reference/enumAssignmentCompat3.js index 33cfdd28e88..1173bfa1812 100644 --- a/tests/baselines/reference/enumAssignmentCompat3.js +++ b/tests/baselines/reference/enumAssignmentCompat3.js @@ -27,6 +27,16 @@ namespace Cd { c, d, } } +namespace Const { + export const enum E { + a, b, c, + } +} +namespace Decl { + export declare enum E { + a, b, c = 3, + } +} var abc: First.E; var secondAbc: Abc.E; @@ -34,16 +44,24 @@ var secondAbcd: Abcd.E; var secondAb: Ab.E; var secondCd: Cd.E; var nope: Abc.Nope; +var k: Const.E; +var decl: Decl.E; abc = secondAbc; // ok abc = secondAbcd; // missing 'd' abc = secondAb; // ok abc = secondCd; // missing 'd' abc = nope; // nope! +abc = decl; // ok secondAbc = abc; // ok secondAbcd = abc; // ok secondAb = abc; // missing 'c' secondCd = abc; // missing 'a' and 'b' nope = abc; // nope! +decl = abc; // ok + +k = k; // const is only assignable to itself +abc = k; // error +k = abc; //// [enumAssignmentCompat3.js] @@ -97,19 +115,29 @@ var Cd; })(Cd.E || (Cd.E = {})); var E = Cd.E; })(Cd || (Cd = {})); +var Decl; +(function (Decl) { +})(Decl || (Decl = {})); var abc; var secondAbc; var secondAbcd; var secondAb; var secondCd; var nope; +var k; +var decl; abc = secondAbc; // ok abc = secondAbcd; // missing 'd' abc = secondAb; // ok abc = secondCd; // missing 'd' abc = nope; // nope! +abc = decl; // ok secondAbc = abc; // ok secondAbcd = abc; // ok secondAb = abc; // missing 'c' secondCd = abc; // missing 'a' and 'b' nope = abc; // nope! +decl = abc; // ok +k = k; // const is only assignable to itself +abc = k; // error +k = abc; diff --git a/tests/cases/compiler/enumAssignmentCompat3.ts b/tests/cases/compiler/enumAssignmentCompat3.ts index 94a22c7f346..aaaf96b69c8 100644 --- a/tests/cases/compiler/enumAssignmentCompat3.ts +++ b/tests/cases/compiler/enumAssignmentCompat3.ts @@ -26,6 +26,16 @@ namespace Cd { c, d, } } +namespace Const { + export const enum E { + a, b, c, + } +} +namespace Decl { + export declare enum E { + a, b, c = 3, + } +} var abc: First.E; var secondAbc: Abc.E; @@ -33,13 +43,21 @@ var secondAbcd: Abcd.E; var secondAb: Ab.E; var secondCd: Cd.E; var nope: Abc.Nope; +var k: Const.E; +var decl: Decl.E; abc = secondAbc; // ok abc = secondAbcd; // missing 'd' abc = secondAb; // ok abc = secondCd; // missing 'd' abc = nope; // nope! +abc = decl; // ok secondAbc = abc; // ok secondAbcd = abc; // ok secondAb = abc; // missing 'c' secondCd = abc; // missing 'a' and 'b' nope = abc; // nope! +decl = abc; // ok + +k = k; // const is only assignable to itself +abc = k; // error +k = abc; From a995b23e4a00e252de81cdf0d1685700314eefa6 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 10 Dec 2015 14:28:29 -0800 Subject: [PATCH 13/79] Handle merged enums --- src/compiler/checker.ts | 23 ++++++++++++++++++----- src/compiler/utilities.ts | 15 +++++++++++++++ 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 857fa97ca06..2fb0296c1c7 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5762,12 +5762,11 @@ namespace ts { target.symbol.flags & SymbolFlags.ConstEnum) { return Ternary.False; } - const sourceDecl = getDeclarationOfKind(source.symbol, SyntaxKind.EnumDeclaration); - const targetDecl = getDeclarationOfKind(target.symbol, SyntaxKind.EnumDeclaration); - const targetMembers = arrayToMap(targetDecl.members, member => getTextOfPropertyName(member.name)); - for (const member of sourceDecl.members) { + const targetMembers = getEnumMembers(target.symbol); + const targetNames = arrayToMap(targetMembers, member => getTextOfPropertyName(member.name)); + for (const member of getEnumMembers(source.symbol)) { const name = getTextOfPropertyName(member.name); - if (!hasProperty(targetMembers, name)) { + if (!hasProperty(targetNames, name)) { reportError(Diagnostics.Property_0_is_missing_in_type_1, name, typeToString(target, /*enclosingDeclaration*/ undefined, TypeFormatFlags.UseFullyQualifiedType)); @@ -5778,6 +5777,20 @@ namespace ts { } } + function getEnumMembers(symbol: Symbol): EnumMember[] { + const declarations = getDeclarationsOfKind(symbol, SyntaxKind.EnumDeclaration); + if (!declarations) { + return emptyArray; + } + const members: EnumMember[] = []; + for (const declaration of declarations) { + for (const member of (declaration).members) { + members.push(member); + } + } + return members; + } + // Return true if the given type is part of a deeply nested chain of generic instantiations. We consider this to be the case // when structural type comparisons have been started for 10 or more instantiations of the same generic type. It is possible, // though highly unlikely, for this test to be true in a situation where a chain of instantiations is not infinitely expanding. diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 95bf4ff7fa3..24e2149ab3e 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -27,6 +27,21 @@ namespace ts { return undefined; } + export function getDeclarationsOfKind(symbol: Symbol, kind: SyntaxKind): Declaration[] { + const declarations = symbol.declarations; + if (declarations) { + const declarationsOfKind: Declaration[] = []; + for (const declaration of declarations) { + if (declaration.kind === kind) { + declarationsOfKind.push(declaration); + } + } + return declarationsOfKind; + } + + return undefined; + } + export interface StringSymbolWriter extends SymbolWriter { string(): string; } From 75304096959652551cdeed4140753f44940e45b6 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 10 Dec 2015 14:28:46 -0800 Subject: [PATCH 14/79] Add merged enum test --- .../enumAssignmentCompat3.errors.txt | 40 ++++++++++++++----- .../reference/enumAssignmentCompat3.js | 37 +++++++++++++++-- tests/cases/compiler/enumAssignmentCompat3.ts | 16 +++++++- 3 files changed, 78 insertions(+), 15 deletions(-) diff --git a/tests/baselines/reference/enumAssignmentCompat3.errors.txt b/tests/baselines/reference/enumAssignmentCompat3.errors.txt index b9ab92adec1..c34ad434347 100644 --- a/tests/baselines/reference/enumAssignmentCompat3.errors.txt +++ b/tests/baselines/reference/enumAssignmentCompat3.errors.txt @@ -1,18 +1,20 @@ -tests/cases/compiler/enumAssignmentCompat3.ts(49,1): error TS2322: Type 'Abcd.E' is not assignable to type 'First.E'. +tests/cases/compiler/enumAssignmentCompat3.ts(58,1): error TS2322: Type 'Abcd.E' is not assignable to type 'First.E'. Property 'd' is missing in type 'First.E'. -tests/cases/compiler/enumAssignmentCompat3.ts(51,1): error TS2322: Type 'Cd.E' is not assignable to type 'First.E'. +tests/cases/compiler/enumAssignmentCompat3.ts(60,1): error TS2322: Type 'Cd.E' is not assignable to type 'First.E'. Property 'd' is missing in type 'First.E'. -tests/cases/compiler/enumAssignmentCompat3.ts(52,1): error TS2322: Type 'Nope' is not assignable to type 'E'. -tests/cases/compiler/enumAssignmentCompat3.ts(56,1): error TS2322: Type 'First.E' is not assignable to type 'Ab.E'. +tests/cases/compiler/enumAssignmentCompat3.ts(61,1): error TS2322: Type 'Nope' is not assignable to type 'E'. +tests/cases/compiler/enumAssignmentCompat3.ts(65,1): error TS2322: Type 'First.E' is not assignable to type 'Ab.E'. Property 'c' is missing in type 'Ab.E'. -tests/cases/compiler/enumAssignmentCompat3.ts(57,1): error TS2322: Type 'First.E' is not assignable to type 'Cd.E'. +tests/cases/compiler/enumAssignmentCompat3.ts(66,1): error TS2322: Type 'First.E' is not assignable to type 'Cd.E'. Property 'a' is missing in type 'Cd.E'. -tests/cases/compiler/enumAssignmentCompat3.ts(58,1): error TS2322: Type 'E' is not assignable to type 'Nope'. -tests/cases/compiler/enumAssignmentCompat3.ts(62,1): error TS2322: Type 'Const.E' is not assignable to type 'First.E'. -tests/cases/compiler/enumAssignmentCompat3.ts(63,1): error TS2322: Type 'First.E' is not assignable to type 'Const.E'. +tests/cases/compiler/enumAssignmentCompat3.ts(67,1): error TS2322: Type 'E' is not assignable to type 'Nope'. +tests/cases/compiler/enumAssignmentCompat3.ts(72,1): error TS2322: Type 'Const.E' is not assignable to type 'First.E'. +tests/cases/compiler/enumAssignmentCompat3.ts(73,1): error TS2322: Type 'First.E' is not assignable to type 'Const.E'. +tests/cases/compiler/enumAssignmentCompat3.ts(76,1): error TS2322: Type 'Merged.E' is not assignable to type 'First.E'. + Property 'd' is missing in type 'First.E'. -==== tests/cases/compiler/enumAssignmentCompat3.ts (8 errors) ==== +==== tests/cases/compiler/enumAssignmentCompat3.ts (9 errors) ==== namespace First { export enum E { a, b, c, @@ -51,6 +53,14 @@ tests/cases/compiler/enumAssignmentCompat3.ts(63,1): error TS2322: Type 'First.E a, b, c = 3, } } + namespace Merged { + export enum E { + a, b, + } + export enum E { + c = 3, d, + } + } var abc: First.E; var secondAbc: Abc.E; @@ -60,6 +70,7 @@ tests/cases/compiler/enumAssignmentCompat3.ts(63,1): error TS2322: Type 'First.E var nope: Abc.Nope; var k: Const.E; var decl: Decl.E; + var merged: Merged.E; abc = secondAbc; // ok abc = secondAbcd; // missing 'd' ~~~ @@ -89,11 +100,18 @@ tests/cases/compiler/enumAssignmentCompat3.ts(63,1): error TS2322: Type 'First.E !!! error TS2322: Type 'E' is not assignable to type 'Nope'. decl = abc; // ok - k = k; // const is only assignable to itself + // const is only assignable to itself + k = k; abc = k; // error ~~~ !!! error TS2322: Type 'Const.E' is not assignable to type 'First.E'. k = abc; ~ !!! error TS2322: Type 'First.E' is not assignable to type 'Const.E'. - \ No newline at end of file + + // merged enums compare all their members + abc = merged; // missing 'd' + ~~~ +!!! error TS2322: Type 'Merged.E' is not assignable to type 'First.E'. +!!! error TS2322: Property 'd' is missing in type 'First.E'. + merged = abc; // ok \ No newline at end of file diff --git a/tests/baselines/reference/enumAssignmentCompat3.js b/tests/baselines/reference/enumAssignmentCompat3.js index 1173bfa1812..e43874911ce 100644 --- a/tests/baselines/reference/enumAssignmentCompat3.js +++ b/tests/baselines/reference/enumAssignmentCompat3.js @@ -37,6 +37,14 @@ namespace Decl { a, b, c = 3, } } +namespace Merged { + export enum E { + a, b, + } + export enum E { + c = 3, d, + } +} var abc: First.E; var secondAbc: Abc.E; @@ -46,6 +54,7 @@ var secondCd: Cd.E; var nope: Abc.Nope; var k: Const.E; var decl: Decl.E; +var merged: Merged.E; abc = secondAbc; // ok abc = secondAbcd; // missing 'd' abc = secondAb; // ok @@ -59,10 +68,14 @@ secondCd = abc; // missing 'a' and 'b' nope = abc; // nope! decl = abc; // ok -k = k; // const is only assignable to itself +// const is only assignable to itself +k = k; abc = k; // error k = abc; - + +// merged enums compare all their members +abc = merged; // missing 'd' +merged = abc; // ok //// [enumAssignmentCompat3.js] var First; @@ -118,6 +131,19 @@ var Cd; var Decl; (function (Decl) { })(Decl || (Decl = {})); +var Merged; +(function (Merged) { + (function (E) { + E[E["a"] = 0] = "a"; + E[E["b"] = 1] = "b"; + })(Merged.E || (Merged.E = {})); + var E = Merged.E; + (function (E) { + E[E["c"] = 3] = "c"; + E[E["d"] = 4] = "d"; + })(Merged.E || (Merged.E = {})); + var E = Merged.E; +})(Merged || (Merged = {})); var abc; var secondAbc; var secondAbcd; @@ -126,6 +152,7 @@ var secondCd; var nope; var k; var decl; +var merged; abc = secondAbc; // ok abc = secondAbcd; // missing 'd' abc = secondAb; // ok @@ -138,6 +165,10 @@ secondAb = abc; // missing 'c' secondCd = abc; // missing 'a' and 'b' nope = abc; // nope! decl = abc; // ok -k = k; // const is only assignable to itself +// const is only assignable to itself +k = k; abc = k; // error k = abc; +// merged enums compare all their members +abc = merged; // missing 'd' +merged = abc; // ok diff --git a/tests/cases/compiler/enumAssignmentCompat3.ts b/tests/cases/compiler/enumAssignmentCompat3.ts index aaaf96b69c8..33070572661 100644 --- a/tests/cases/compiler/enumAssignmentCompat3.ts +++ b/tests/cases/compiler/enumAssignmentCompat3.ts @@ -36,6 +36,14 @@ namespace Decl { a, b, c = 3, } } +namespace Merged { + export enum E { + a, b, + } + export enum E { + c = 3, d, + } +} var abc: First.E; var secondAbc: Abc.E; @@ -45,6 +53,7 @@ var secondCd: Cd.E; var nope: Abc.Nope; var k: Const.E; var decl: Decl.E; +var merged: Merged.E; abc = secondAbc; // ok abc = secondAbcd; // missing 'd' abc = secondAb; // ok @@ -58,6 +67,11 @@ secondCd = abc; // missing 'a' and 'b' nope = abc; // nope! decl = abc; // ok -k = k; // const is only assignable to itself +// const is only assignable to itself +k = k; abc = k; // error k = abc; + +// merged enums compare all their members +abc = merged; // missing 'd' +merged = abc; // ok \ No newline at end of file From da8e19e191ef508d18f400db62c9297e44002da7 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 10 Dec 2015 15:25:01 -0800 Subject: [PATCH 15/79] Use typeof enum to resolve members. Use getTypeOfSymbol >> resolveStructuredTypeMembers >> properties instead of looking at declarations. --- src/compiler/checker.ts | 26 ++++++-------------------- src/compiler/utilities.ts | 15 --------------- 2 files changed, 6 insertions(+), 35 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2fb0296c1c7..bccbede909b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5762,13 +5762,13 @@ namespace ts { target.symbol.flags & SymbolFlags.ConstEnum) { return Ternary.False; } - const targetMembers = getEnumMembers(target.symbol); - const targetNames = arrayToMap(targetMembers, member => getTextOfPropertyName(member.name)); - for (const member of getEnumMembers(source.symbol)) { - const name = getTextOfPropertyName(member.name); - if (!hasProperty(targetNames, name)) { + const sourceMembers = resolveStructuredTypeMembers(getTypeOfSymbol(source.symbol)).properties; + const targetMembers = resolveStructuredTypeMembers(getTypeOfSymbol(target.symbol)).properties; + const targetNames = arrayToMap(targetMembers, member => member.name); + for (const member of sourceMembers) { + if (!hasProperty(targetNames, member.name)) { reportError(Diagnostics.Property_0_is_missing_in_type_1, - name, + member.name, typeToString(target, /*enclosingDeclaration*/ undefined, TypeFormatFlags.UseFullyQualifiedType)); return Ternary.False; } @@ -5777,20 +5777,6 @@ namespace ts { } } - function getEnumMembers(symbol: Symbol): EnumMember[] { - const declarations = getDeclarationsOfKind(symbol, SyntaxKind.EnumDeclaration); - if (!declarations) { - return emptyArray; - } - const members: EnumMember[] = []; - for (const declaration of declarations) { - for (const member of (declaration).members) { - members.push(member); - } - } - return members; - } - // Return true if the given type is part of a deeply nested chain of generic instantiations. We consider this to be the case // when structural type comparisons have been started for 10 or more instantiations of the same generic type. It is possible, // though highly unlikely, for this test to be true in a situation where a chain of instantiations is not infinitely expanding. diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 24e2149ab3e..95bf4ff7fa3 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -27,21 +27,6 @@ namespace ts { return undefined; } - export function getDeclarationsOfKind(symbol: Symbol, kind: SyntaxKind): Declaration[] { - const declarations = symbol.declarations; - if (declarations) { - const declarationsOfKind: Declaration[] = []; - for (const declaration of declarations) { - if (declaration.kind === kind) { - declarationsOfKind.push(declaration); - } - } - return declarationsOfKind; - } - - return undefined; - } - export interface StringSymbolWriter extends SymbolWriter { string(): string; } From 8202576ab2d503258dbd18b7ebc1035607ebd173 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Fri, 11 Dec 2015 09:56:13 -0800 Subject: [PATCH 16/79] Filter for enum members only. --- src/compiler/checker.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index bccbede909b..9944cebf54a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5762,10 +5762,8 @@ namespace ts { target.symbol.flags & SymbolFlags.ConstEnum) { return Ternary.False; } - const sourceMembers = resolveStructuredTypeMembers(getTypeOfSymbol(source.symbol)).properties; - const targetMembers = resolveStructuredTypeMembers(getTypeOfSymbol(target.symbol)).properties; - const targetNames = arrayToMap(targetMembers, member => member.name); - for (const member of sourceMembers) { + const targetNames = arrayToMap(getEnumMembersOfEnumType(target), member => member.name); + for (const member of getEnumMembersOfEnumType(source)) { if (!hasProperty(targetNames, member.name)) { reportError(Diagnostics.Property_0_is_missing_in_type_1, member.name, @@ -5775,6 +5773,11 @@ namespace ts { } return Ternary.True; } + + function getEnumMembersOfEnumType(type: Type) { + return filter(resolveStructuredTypeMembers(getTypeOfSymbol(type.symbol)).properties, + property => !!(property.flags & SymbolFlags.EnumMember)); + } } // Return true if the given type is part of a deeply nested chain of generic instantiations. We consider this to be the case From dc9d307f137dc2a7b812cea42aac6927711b419a Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Fri, 11 Dec 2015 10:08:01 -0800 Subject: [PATCH 17/79] Fix lint --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9944cebf54a..8d9fe1f7ba5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5775,7 +5775,7 @@ namespace ts { } function getEnumMembersOfEnumType(type: Type) { - return filter(resolveStructuredTypeMembers(getTypeOfSymbol(type.symbol)).properties, + return filter(resolveStructuredTypeMembers(getTypeOfSymbol(type.symbol)).properties, property => !!(property.flags & SymbolFlags.EnumMember)); } } From e9dc011080e274e39f6eeecc27b5534b842739c3 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 11 Dec 2015 14:10:12 -0800 Subject: [PATCH 18/79] Fixed unnecessary error in test. --- .../types/stringLiteral/stringLiteralTypesAsTags01.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cases/conformance/types/stringLiteral/stringLiteralTypesAsTags01.ts b/tests/cases/conformance/types/stringLiteral/stringLiteralTypesAsTags01.ts index cea04f0818e..ba189406533 100644 --- a/tests/cases/conformance/types/stringLiteral/stringLiteralTypesAsTags01.ts +++ b/tests/cases/conformance/types/stringLiteral/stringLiteralTypesAsTags01.ts @@ -20,7 +20,7 @@ function hasKind(entity: Entity, kind: "A"): entity is A; function hasKind(entity: Entity, kind: "B"): entity is B; function hasKind(entity: Entity, kind: Kind): entity is Entity; function hasKind(entity: Entity, kind: Kind): boolean { - return kind === is; + return entity.kind === kind; } let x: A = { From 8cceedd725a848e9e65002b1d4871cb54c579fb9 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 11 Dec 2015 14:11:45 -0800 Subject: [PATCH 19/79] Accepted baselines. --- .../stringLiteralTypesAsTags01.errors.txt | 51 -------- .../reference/stringLiteralTypesAsTags01.js | 4 +- .../stringLiteralTypesAsTags01.symbols | 112 ++++++++++++++++ .../stringLiteralTypesAsTags01.types | 121 ++++++++++++++++++ .../reference/superPropertyAccess_ES5.js | 8 +- 5 files changed, 239 insertions(+), 57 deletions(-) delete mode 100644 tests/baselines/reference/stringLiteralTypesAsTags01.errors.txt create mode 100644 tests/baselines/reference/stringLiteralTypesAsTags01.symbols create mode 100644 tests/baselines/reference/stringLiteralTypesAsTags01.types diff --git a/tests/baselines/reference/stringLiteralTypesAsTags01.errors.txt b/tests/baselines/reference/stringLiteralTypesAsTags01.errors.txt deleted file mode 100644 index 90c8c3efdf7..00000000000 --- a/tests/baselines/reference/stringLiteralTypesAsTags01.errors.txt +++ /dev/null @@ -1,51 +0,0 @@ -tests/cases/conformance/types/stringLiteral/stringLiteralTypesAsTags01.ts(20,10): error TS2394: Overload signature is not compatible with function implementation. -tests/cases/conformance/types/stringLiteral/stringLiteralTypesAsTags01.ts(22,21): error TS2304: Cannot find name 'is'. - - -==== tests/cases/conformance/types/stringLiteral/stringLiteralTypesAsTags01.ts (2 errors) ==== - - type Kind = "A" | "B" - - interface Entity { - kind: Kind; - } - - interface A extends Entity { - kind: "A"; - a: number; - } - - interface B extends Entity { - kind: "B"; - b: string; - } - - function hasKind(entity: Entity, kind: "A"): entity is A; - function hasKind(entity: Entity, kind: "B"): entity is B; - function hasKind(entity: Entity, kind: Kind): entity is Entity; - ~~~~~~~ -!!! error TS2394: Overload signature is not compatible with function implementation. - function hasKind(entity: Entity, kind: Kind): boolean { - return kind === is; - ~~ -!!! error TS2304: Cannot find name 'is'. - } - - let x: A = { - kind: "A", - a: 100, - } - - if (hasKind(x, "A")) { - let a = x; - } - else { - let b = x; - } - - if (!hasKind(x, "B")) { - let c = x; - } - else { - let d = x; - } \ No newline at end of file diff --git a/tests/baselines/reference/stringLiteralTypesAsTags01.js b/tests/baselines/reference/stringLiteralTypesAsTags01.js index 3fe33ace487..b7b3872ce66 100644 --- a/tests/baselines/reference/stringLiteralTypesAsTags01.js +++ b/tests/baselines/reference/stringLiteralTypesAsTags01.js @@ -20,7 +20,7 @@ function hasKind(entity: Entity, kind: "A"): entity is A; function hasKind(entity: Entity, kind: "B"): entity is B; function hasKind(entity: Entity, kind: Kind): entity is Entity; function hasKind(entity: Entity, kind: Kind): boolean { - return kind === is; + return entity.kind === kind; } let x: A = { @@ -44,7 +44,7 @@ else { //// [stringLiteralTypesAsTags01.js] function hasKind(entity, kind) { - return kind === is; + return entity.kind === kind; } var x = { kind: "A", diff --git a/tests/baselines/reference/stringLiteralTypesAsTags01.symbols b/tests/baselines/reference/stringLiteralTypesAsTags01.symbols new file mode 100644 index 00000000000..afdeeff71a6 --- /dev/null +++ b/tests/baselines/reference/stringLiteralTypesAsTags01.symbols @@ -0,0 +1,112 @@ +=== tests/cases/conformance/types/stringLiteral/stringLiteralTypesAsTags01.ts === + +type Kind = "A" | "B" +>Kind : Symbol(Kind, Decl(stringLiteralTypesAsTags01.ts, 0, 0)) + +interface Entity { +>Entity : Symbol(Entity, Decl(stringLiteralTypesAsTags01.ts, 1, 21)) + + kind: Kind; +>kind : Symbol(kind, Decl(stringLiteralTypesAsTags01.ts, 3, 18)) +>Kind : Symbol(Kind, Decl(stringLiteralTypesAsTags01.ts, 0, 0)) +} + +interface A extends Entity { +>A : Symbol(A, Decl(stringLiteralTypesAsTags01.ts, 5, 1)) +>Entity : Symbol(Entity, Decl(stringLiteralTypesAsTags01.ts, 1, 21)) + + kind: "A"; +>kind : Symbol(kind, Decl(stringLiteralTypesAsTags01.ts, 7, 28)) + + a: number; +>a : Symbol(a, Decl(stringLiteralTypesAsTags01.ts, 8, 14)) +} + +interface B extends Entity { +>B : Symbol(B, Decl(stringLiteralTypesAsTags01.ts, 10, 1)) +>Entity : Symbol(Entity, Decl(stringLiteralTypesAsTags01.ts, 1, 21)) + + kind: "B"; +>kind : Symbol(kind, Decl(stringLiteralTypesAsTags01.ts, 12, 28)) + + b: string; +>b : Symbol(b, Decl(stringLiteralTypesAsTags01.ts, 13, 14)) +} + +function hasKind(entity: Entity, kind: "A"): entity is A; +>hasKind : Symbol(hasKind, Decl(stringLiteralTypesAsTags01.ts, 15, 1), Decl(stringLiteralTypesAsTags01.ts, 17, 57), Decl(stringLiteralTypesAsTags01.ts, 18, 57), Decl(stringLiteralTypesAsTags01.ts, 19, 63)) +>entity : Symbol(entity, Decl(stringLiteralTypesAsTags01.ts, 17, 17)) +>Entity : Symbol(Entity, Decl(stringLiteralTypesAsTags01.ts, 1, 21)) +>kind : Symbol(kind, Decl(stringLiteralTypesAsTags01.ts, 17, 32)) +>entity : Symbol(entity, Decl(stringLiteralTypesAsTags01.ts, 17, 17)) +>A : Symbol(A, Decl(stringLiteralTypesAsTags01.ts, 5, 1)) + +function hasKind(entity: Entity, kind: "B"): entity is B; +>hasKind : Symbol(hasKind, Decl(stringLiteralTypesAsTags01.ts, 15, 1), Decl(stringLiteralTypesAsTags01.ts, 17, 57), Decl(stringLiteralTypesAsTags01.ts, 18, 57), Decl(stringLiteralTypesAsTags01.ts, 19, 63)) +>entity : Symbol(entity, Decl(stringLiteralTypesAsTags01.ts, 18, 17)) +>Entity : Symbol(Entity, Decl(stringLiteralTypesAsTags01.ts, 1, 21)) +>kind : Symbol(kind, Decl(stringLiteralTypesAsTags01.ts, 18, 32)) +>entity : Symbol(entity, Decl(stringLiteralTypesAsTags01.ts, 18, 17)) +>B : Symbol(B, Decl(stringLiteralTypesAsTags01.ts, 10, 1)) + +function hasKind(entity: Entity, kind: Kind): entity is Entity; +>hasKind : Symbol(hasKind, Decl(stringLiteralTypesAsTags01.ts, 15, 1), Decl(stringLiteralTypesAsTags01.ts, 17, 57), Decl(stringLiteralTypesAsTags01.ts, 18, 57), Decl(stringLiteralTypesAsTags01.ts, 19, 63)) +>entity : Symbol(entity, Decl(stringLiteralTypesAsTags01.ts, 19, 17)) +>Entity : Symbol(Entity, Decl(stringLiteralTypesAsTags01.ts, 1, 21)) +>kind : Symbol(kind, Decl(stringLiteralTypesAsTags01.ts, 19, 32)) +>Kind : Symbol(Kind, Decl(stringLiteralTypesAsTags01.ts, 0, 0)) +>entity : Symbol(entity, Decl(stringLiteralTypesAsTags01.ts, 19, 17)) +>Entity : Symbol(Entity, Decl(stringLiteralTypesAsTags01.ts, 1, 21)) + +function hasKind(entity: Entity, kind: Kind): boolean { +>hasKind : Symbol(hasKind, Decl(stringLiteralTypesAsTags01.ts, 15, 1), Decl(stringLiteralTypesAsTags01.ts, 17, 57), Decl(stringLiteralTypesAsTags01.ts, 18, 57), Decl(stringLiteralTypesAsTags01.ts, 19, 63)) +>entity : Symbol(entity, Decl(stringLiteralTypesAsTags01.ts, 20, 17)) +>Entity : Symbol(Entity, Decl(stringLiteralTypesAsTags01.ts, 1, 21)) +>kind : Symbol(kind, Decl(stringLiteralTypesAsTags01.ts, 20, 32)) +>Kind : Symbol(Kind, Decl(stringLiteralTypesAsTags01.ts, 0, 0)) + + return entity.kind === kind; +>entity.kind : Symbol(Entity.kind, Decl(stringLiteralTypesAsTags01.ts, 3, 18)) +>entity : Symbol(entity, Decl(stringLiteralTypesAsTags01.ts, 20, 17)) +>kind : Symbol(Entity.kind, Decl(stringLiteralTypesAsTags01.ts, 3, 18)) +>kind : Symbol(kind, Decl(stringLiteralTypesAsTags01.ts, 20, 32)) +} + +let x: A = { +>x : Symbol(x, Decl(stringLiteralTypesAsTags01.ts, 24, 3)) +>A : Symbol(A, Decl(stringLiteralTypesAsTags01.ts, 5, 1)) + + kind: "A", +>kind : Symbol(kind, Decl(stringLiteralTypesAsTags01.ts, 24, 12)) + + a: 100, +>a : Symbol(a, Decl(stringLiteralTypesAsTags01.ts, 25, 14)) +} + +if (hasKind(x, "A")) { +>hasKind : Symbol(hasKind, Decl(stringLiteralTypesAsTags01.ts, 15, 1), Decl(stringLiteralTypesAsTags01.ts, 17, 57), Decl(stringLiteralTypesAsTags01.ts, 18, 57), Decl(stringLiteralTypesAsTags01.ts, 19, 63)) +>x : Symbol(x, Decl(stringLiteralTypesAsTags01.ts, 24, 3)) + + let a = x; +>a : Symbol(a, Decl(stringLiteralTypesAsTags01.ts, 30, 7)) +>x : Symbol(x, Decl(stringLiteralTypesAsTags01.ts, 24, 3)) +} +else { + let b = x; +>b : Symbol(b, Decl(stringLiteralTypesAsTags01.ts, 33, 7)) +>x : Symbol(x, Decl(stringLiteralTypesAsTags01.ts, 24, 3)) +} + +if (!hasKind(x, "B")) { +>hasKind : Symbol(hasKind, Decl(stringLiteralTypesAsTags01.ts, 15, 1), Decl(stringLiteralTypesAsTags01.ts, 17, 57), Decl(stringLiteralTypesAsTags01.ts, 18, 57), Decl(stringLiteralTypesAsTags01.ts, 19, 63)) +>x : Symbol(x, Decl(stringLiteralTypesAsTags01.ts, 24, 3)) + + let c = x; +>c : Symbol(c, Decl(stringLiteralTypesAsTags01.ts, 37, 7)) +>x : Symbol(x, Decl(stringLiteralTypesAsTags01.ts, 24, 3)) +} +else { + let d = x; +>d : Symbol(d, Decl(stringLiteralTypesAsTags01.ts, 40, 7)) +>x : Symbol(x, Decl(stringLiteralTypesAsTags01.ts, 24, 3)) +} diff --git a/tests/baselines/reference/stringLiteralTypesAsTags01.types b/tests/baselines/reference/stringLiteralTypesAsTags01.types new file mode 100644 index 00000000000..6966ede5482 --- /dev/null +++ b/tests/baselines/reference/stringLiteralTypesAsTags01.types @@ -0,0 +1,121 @@ +=== tests/cases/conformance/types/stringLiteral/stringLiteralTypesAsTags01.ts === + +type Kind = "A" | "B" +>Kind : "A" | "B" + +interface Entity { +>Entity : Entity + + kind: Kind; +>kind : "A" | "B" +>Kind : "A" | "B" +} + +interface A extends Entity { +>A : A +>Entity : Entity + + kind: "A"; +>kind : "A" + + a: number; +>a : number +} + +interface B extends Entity { +>B : B +>Entity : Entity + + kind: "B"; +>kind : "B" + + b: string; +>b : string +} + +function hasKind(entity: Entity, kind: "A"): entity is A; +>hasKind : { (entity: Entity, kind: "A"): entity is A; (entity: Entity, kind: "B"): entity is B; (entity: Entity, kind: "A" | "B"): entity is Entity; } +>entity : Entity +>Entity : Entity +>kind : "A" +>entity : any +>A : A + +function hasKind(entity: Entity, kind: "B"): entity is B; +>hasKind : { (entity: Entity, kind: "A"): entity is A; (entity: Entity, kind: "B"): entity is B; (entity: Entity, kind: "A" | "B"): entity is Entity; } +>entity : Entity +>Entity : Entity +>kind : "B" +>entity : any +>B : B + +function hasKind(entity: Entity, kind: Kind): entity is Entity; +>hasKind : { (entity: Entity, kind: "A"): entity is A; (entity: Entity, kind: "B"): entity is B; (entity: Entity, kind: "A" | "B"): entity is Entity; } +>entity : Entity +>Entity : Entity +>kind : "A" | "B" +>Kind : "A" | "B" +>entity : any +>Entity : Entity + +function hasKind(entity: Entity, kind: Kind): boolean { +>hasKind : { (entity: Entity, kind: "A"): entity is A; (entity: Entity, kind: "B"): entity is B; (entity: Entity, kind: "A" | "B"): entity is Entity; } +>entity : Entity +>Entity : Entity +>kind : "A" | "B" +>Kind : "A" | "B" + + return entity.kind === kind; +>entity.kind === kind : boolean +>entity.kind : "A" | "B" +>entity : Entity +>kind : "A" | "B" +>kind : "A" | "B" +} + +let x: A = { +>x : A +>A : A +>{ kind: "A", a: 100,} : { kind: "A"; a: number; } + + kind: "A", +>kind : "A" +>"A" : "A" + + a: 100, +>a : number +>100 : number +} + +if (hasKind(x, "A")) { +>hasKind(x, "A") : entity is A +>hasKind : { (entity: Entity, kind: "A"): entity is A; (entity: Entity, kind: "B"): entity is B; (entity: Entity, kind: "A" | "B"): entity is Entity; } +>x : A +>"A" : "A" + + let a = x; +>a : A +>x : A +} +else { + let b = x; +>b : A +>x : A +} + +if (!hasKind(x, "B")) { +>!hasKind(x, "B") : boolean +>hasKind(x, "B") : entity is B +>hasKind : { (entity: Entity, kind: "A"): entity is A; (entity: Entity, kind: "B"): entity is B; (entity: Entity, kind: "A" | "B"): entity is Entity; } +>x : A +>"B" : "B" + + let c = x; +>c : A +>x : A +} +else { + let d = x; +>d : A +>x : A +} diff --git a/tests/baselines/reference/superPropertyAccess_ES5.js b/tests/baselines/reference/superPropertyAccess_ES5.js index a31c1dfdcba..63f5f6f316a 100644 --- a/tests/baselines/reference/superPropertyAccess_ES5.js +++ b/tests/baselines/reference/superPropertyAccess_ES5.js @@ -45,7 +45,7 @@ var MyBase = (function () { configurable: true }); return MyBase; -})(); +}()); var MyDerived = (function (_super) { __extends(MyDerived, _super); function MyDerived() { @@ -54,7 +54,7 @@ var MyDerived = (function (_super) { var f2 = _super.prototype.value; } return MyDerived; -})(MyBase); +}(MyBase)); var d = new MyDerived(); var f3 = d.value; var A = (function () { @@ -67,7 +67,7 @@ var A = (function () { configurable: true }); return A; -})(); +}()); var B = (function (_super) { __extends(B, _super); function B() { @@ -81,4 +81,4 @@ var B = (function (_super) { configurable: true }); return B; -})(A); +}(A)); From 3cdfc36109aff6243d22962f47fa331b8be84f8d Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 11 Dec 2015 15:02:43 -0800 Subject: [PATCH 20/79] Added tests for 'void' return type compatibilty on overloads and implementations. --- .../functions/functionOverloadCompatibilityWithVoid01.ts | 4 ++++ .../functions/functionOverloadCompatibilityWithVoid02.ts | 4 ++++ .../functions/functionOverloadCompatibilityWithVoid03.ts | 4 ++++ 3 files changed, 12 insertions(+) create mode 100644 tests/cases/conformance/functions/functionOverloadCompatibilityWithVoid01.ts create mode 100644 tests/cases/conformance/functions/functionOverloadCompatibilityWithVoid02.ts create mode 100644 tests/cases/conformance/functions/functionOverloadCompatibilityWithVoid03.ts diff --git a/tests/cases/conformance/functions/functionOverloadCompatibilityWithVoid01.ts b/tests/cases/conformance/functions/functionOverloadCompatibilityWithVoid01.ts new file mode 100644 index 00000000000..d973c946bb9 --- /dev/null +++ b/tests/cases/conformance/functions/functionOverloadCompatibilityWithVoid01.ts @@ -0,0 +1,4 @@ +function f(x: string): number; +function f(x: string): void { + return; +} \ No newline at end of file diff --git a/tests/cases/conformance/functions/functionOverloadCompatibilityWithVoid02.ts b/tests/cases/conformance/functions/functionOverloadCompatibilityWithVoid02.ts new file mode 100644 index 00000000000..ef89d790ff7 --- /dev/null +++ b/tests/cases/conformance/functions/functionOverloadCompatibilityWithVoid02.ts @@ -0,0 +1,4 @@ +function f(x: string): void; +function f(x: string): number { + return 0; +} \ No newline at end of file diff --git a/tests/cases/conformance/functions/functionOverloadCompatibilityWithVoid03.ts b/tests/cases/conformance/functions/functionOverloadCompatibilityWithVoid03.ts new file mode 100644 index 00000000000..5f0a2327d74 --- /dev/null +++ b/tests/cases/conformance/functions/functionOverloadCompatibilityWithVoid03.ts @@ -0,0 +1,4 @@ +function f(x: string): void; +function f(x: string): void { + return; +} \ No newline at end of file From 069fada0ce3e15622ed2da14d9c8a3edf042bde8 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 11 Dec 2015 15:04:59 -0800 Subject: [PATCH 21/79] Accepted baselines. --- ...functionOverloadCompatibilityWithVoid01.errors.txt | 10 ++++++++++ .../functionOverloadCompatibilityWithVoid01.js | 10 ++++++++++ ...functionOverloadCompatibilityWithVoid02.errors.txt | 10 ++++++++++ .../functionOverloadCompatibilityWithVoid02.js | 10 ++++++++++ .../functionOverloadCompatibilityWithVoid03.js | 10 ++++++++++ .../functionOverloadCompatibilityWithVoid03.symbols | 11 +++++++++++ .../functionOverloadCompatibilityWithVoid03.types | 11 +++++++++++ 7 files changed, 72 insertions(+) create mode 100644 tests/baselines/reference/functionOverloadCompatibilityWithVoid01.errors.txt create mode 100644 tests/baselines/reference/functionOverloadCompatibilityWithVoid01.js create mode 100644 tests/baselines/reference/functionOverloadCompatibilityWithVoid02.errors.txt create mode 100644 tests/baselines/reference/functionOverloadCompatibilityWithVoid02.js create mode 100644 tests/baselines/reference/functionOverloadCompatibilityWithVoid03.js create mode 100644 tests/baselines/reference/functionOverloadCompatibilityWithVoid03.symbols create mode 100644 tests/baselines/reference/functionOverloadCompatibilityWithVoid03.types diff --git a/tests/baselines/reference/functionOverloadCompatibilityWithVoid01.errors.txt b/tests/baselines/reference/functionOverloadCompatibilityWithVoid01.errors.txt new file mode 100644 index 00000000000..56951e380e4 --- /dev/null +++ b/tests/baselines/reference/functionOverloadCompatibilityWithVoid01.errors.txt @@ -0,0 +1,10 @@ +tests/cases/conformance/functions/functionOverloadCompatibilityWithVoid01.ts(1,10): error TS2394: Overload signature is not compatible with function implementation. + + +==== tests/cases/conformance/functions/functionOverloadCompatibilityWithVoid01.ts (1 errors) ==== + function f(x: string): number; + ~ +!!! error TS2394: Overload signature is not compatible with function implementation. + function f(x: string): void { + return; + } \ No newline at end of file diff --git a/tests/baselines/reference/functionOverloadCompatibilityWithVoid01.js b/tests/baselines/reference/functionOverloadCompatibilityWithVoid01.js new file mode 100644 index 00000000000..b2d7e64d58e --- /dev/null +++ b/tests/baselines/reference/functionOverloadCompatibilityWithVoid01.js @@ -0,0 +1,10 @@ +//// [functionOverloadCompatibilityWithVoid01.ts] +function f(x: string): number; +function f(x: string): void { + return; +} + +//// [functionOverloadCompatibilityWithVoid01.js] +function f(x) { + return; +} diff --git a/tests/baselines/reference/functionOverloadCompatibilityWithVoid02.errors.txt b/tests/baselines/reference/functionOverloadCompatibilityWithVoid02.errors.txt new file mode 100644 index 00000000000..33155afb5f5 --- /dev/null +++ b/tests/baselines/reference/functionOverloadCompatibilityWithVoid02.errors.txt @@ -0,0 +1,10 @@ +tests/cases/conformance/functions/functionOverloadCompatibilityWithVoid02.ts(1,10): error TS2394: Overload signature is not compatible with function implementation. + + +==== tests/cases/conformance/functions/functionOverloadCompatibilityWithVoid02.ts (1 errors) ==== + function f(x: string): void; + ~ +!!! error TS2394: Overload signature is not compatible with function implementation. + function f(x: string): number { + return 0; + } \ No newline at end of file diff --git a/tests/baselines/reference/functionOverloadCompatibilityWithVoid02.js b/tests/baselines/reference/functionOverloadCompatibilityWithVoid02.js new file mode 100644 index 00000000000..4f53be1f9c3 --- /dev/null +++ b/tests/baselines/reference/functionOverloadCompatibilityWithVoid02.js @@ -0,0 +1,10 @@ +//// [functionOverloadCompatibilityWithVoid02.ts] +function f(x: string): void; +function f(x: string): number { + return 0; +} + +//// [functionOverloadCompatibilityWithVoid02.js] +function f(x) { + return 0; +} diff --git a/tests/baselines/reference/functionOverloadCompatibilityWithVoid03.js b/tests/baselines/reference/functionOverloadCompatibilityWithVoid03.js new file mode 100644 index 00000000000..b83939442cb --- /dev/null +++ b/tests/baselines/reference/functionOverloadCompatibilityWithVoid03.js @@ -0,0 +1,10 @@ +//// [functionOverloadCompatibilityWithVoid03.ts] +function f(x: string): void; +function f(x: string): void { + return; +} + +//// [functionOverloadCompatibilityWithVoid03.js] +function f(x) { + return; +} diff --git a/tests/baselines/reference/functionOverloadCompatibilityWithVoid03.symbols b/tests/baselines/reference/functionOverloadCompatibilityWithVoid03.symbols new file mode 100644 index 00000000000..57fe6006ced --- /dev/null +++ b/tests/baselines/reference/functionOverloadCompatibilityWithVoid03.symbols @@ -0,0 +1,11 @@ +=== tests/cases/conformance/functions/functionOverloadCompatibilityWithVoid03.ts === +function f(x: string): void; +>f : Symbol(f, Decl(functionOverloadCompatibilityWithVoid03.ts, 0, 0), Decl(functionOverloadCompatibilityWithVoid03.ts, 0, 28)) +>x : Symbol(x, Decl(functionOverloadCompatibilityWithVoid03.ts, 0, 11)) + +function f(x: string): void { +>f : Symbol(f, Decl(functionOverloadCompatibilityWithVoid03.ts, 0, 0), Decl(functionOverloadCompatibilityWithVoid03.ts, 0, 28)) +>x : Symbol(x, Decl(functionOverloadCompatibilityWithVoid03.ts, 1, 11)) + + return; +} diff --git a/tests/baselines/reference/functionOverloadCompatibilityWithVoid03.types b/tests/baselines/reference/functionOverloadCompatibilityWithVoid03.types new file mode 100644 index 00000000000..74dfa28c142 --- /dev/null +++ b/tests/baselines/reference/functionOverloadCompatibilityWithVoid03.types @@ -0,0 +1,11 @@ +=== tests/cases/conformance/functions/functionOverloadCompatibilityWithVoid03.ts === +function f(x: string): void; +>f : (x: string) => void +>x : string + +function f(x: string): void { +>f : (x: string) => void +>x : string + + return; +} From 9b507b7512290b28bcd710a363f7a98be261a077 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 11 Dec 2015 15:08:30 -0800 Subject: [PATCH 22/79] Specifically test for 'void' to permit implementations to return more than what was guaranteed. --- src/compiler/checker.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ac8a4ac89a4..a83c1027ad1 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4987,7 +4987,8 @@ namespace ts { const sourceReturnType = getReturnTypeOfSignature(erasedSource); const targetReturnType = getReturnTypeOfSignature(erasedTarget); - if (checkTypeRelatedTo(sourceReturnType, targetReturnType, assignableRelation, /*errorNode*/ undefined) + if (targetReturnType === voidType + || checkTypeRelatedTo(sourceReturnType, targetReturnType, assignableRelation, /*errorNode*/ undefined) || checkTypeRelatedTo(targetReturnType, sourceReturnType, assignableRelation, /*errorNode*/ undefined)) { const anyReturningSource = cloneSignature(erasedSource); const anyReturningTarget = cloneSignature(erasedTarget); From e012645309eadc7496b26380edf49acff044fe93 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 11 Dec 2015 15:08:45 -0800 Subject: [PATCH 23/79] Accepted baselines. --- ...unctionOverloadCompatibilityWithVoid02.errors.txt | 10 ---------- .../functionOverloadCompatibilityWithVoid02.symbols | 11 +++++++++++ .../functionOverloadCompatibilityWithVoid02.types | 12 ++++++++++++ 3 files changed, 23 insertions(+), 10 deletions(-) delete mode 100644 tests/baselines/reference/functionOverloadCompatibilityWithVoid02.errors.txt create mode 100644 tests/baselines/reference/functionOverloadCompatibilityWithVoid02.symbols create mode 100644 tests/baselines/reference/functionOverloadCompatibilityWithVoid02.types diff --git a/tests/baselines/reference/functionOverloadCompatibilityWithVoid02.errors.txt b/tests/baselines/reference/functionOverloadCompatibilityWithVoid02.errors.txt deleted file mode 100644 index 33155afb5f5..00000000000 --- a/tests/baselines/reference/functionOverloadCompatibilityWithVoid02.errors.txt +++ /dev/null @@ -1,10 +0,0 @@ -tests/cases/conformance/functions/functionOverloadCompatibilityWithVoid02.ts(1,10): error TS2394: Overload signature is not compatible with function implementation. - - -==== tests/cases/conformance/functions/functionOverloadCompatibilityWithVoid02.ts (1 errors) ==== - function f(x: string): void; - ~ -!!! error TS2394: Overload signature is not compatible with function implementation. - function f(x: string): number { - return 0; - } \ No newline at end of file diff --git a/tests/baselines/reference/functionOverloadCompatibilityWithVoid02.symbols b/tests/baselines/reference/functionOverloadCompatibilityWithVoid02.symbols new file mode 100644 index 00000000000..210f7e3e4ee --- /dev/null +++ b/tests/baselines/reference/functionOverloadCompatibilityWithVoid02.symbols @@ -0,0 +1,11 @@ +=== tests/cases/conformance/functions/functionOverloadCompatibilityWithVoid02.ts === +function f(x: string): void; +>f : Symbol(f, Decl(functionOverloadCompatibilityWithVoid02.ts, 0, 0), Decl(functionOverloadCompatibilityWithVoid02.ts, 0, 28)) +>x : Symbol(x, Decl(functionOverloadCompatibilityWithVoid02.ts, 0, 11)) + +function f(x: string): number { +>f : Symbol(f, Decl(functionOverloadCompatibilityWithVoid02.ts, 0, 0), Decl(functionOverloadCompatibilityWithVoid02.ts, 0, 28)) +>x : Symbol(x, Decl(functionOverloadCompatibilityWithVoid02.ts, 1, 11)) + + return 0; +} diff --git a/tests/baselines/reference/functionOverloadCompatibilityWithVoid02.types b/tests/baselines/reference/functionOverloadCompatibilityWithVoid02.types new file mode 100644 index 00000000000..aa6fda7222b --- /dev/null +++ b/tests/baselines/reference/functionOverloadCompatibilityWithVoid02.types @@ -0,0 +1,12 @@ +=== tests/cases/conformance/functions/functionOverloadCompatibilityWithVoid02.ts === +function f(x: string): void; +>f : (x: string) => void +>x : string + +function f(x: string): number { +>f : (x: string) => void +>x : string + + return 0; +>0 : number +} From a236461358691e9773ef02b61e3ef5fa4cc79f25 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 11 Dec 2015 15:10:50 -0800 Subject: [PATCH 24/79] Reversed order of checks, since the implementation will typically be more general than the overload. --- src/compiler/checker.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a83c1027ad1..cd95267589b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4988,8 +4988,8 @@ namespace ts { const sourceReturnType = getReturnTypeOfSignature(erasedSource); const targetReturnType = getReturnTypeOfSignature(erasedTarget); if (targetReturnType === voidType - || checkTypeRelatedTo(sourceReturnType, targetReturnType, assignableRelation, /*errorNode*/ undefined) - || checkTypeRelatedTo(targetReturnType, sourceReturnType, assignableRelation, /*errorNode*/ undefined)) { + || checkTypeRelatedTo(targetReturnType, sourceReturnType, assignableRelation, /*errorNode*/ undefined) + || checkTypeRelatedTo(sourceReturnType, targetReturnType, assignableRelation, /*errorNode*/ undefined)) { const anyReturningSource = cloneSignature(erasedSource); const anyReturningTarget = cloneSignature(erasedTarget); anyReturningSource.resolvedReturnType = anyType; From 73526cf39ab2086f25e3f7157edeee0897a47973 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 11 Dec 2015 16:01:42 -0800 Subject: [PATCH 25/79] Do some caching so that we don't repeat the same work for the implementation signature for every overload. --- src/compiler/checker.ts | 21 +++++++++++++++++---- src/compiler/types.ts | 2 ++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index cd95267589b..fac21177aae 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4115,6 +4115,16 @@ namespace ts { return signature.erasedSignatureCache; } + function getAnyReturningErasedSignature(signature: Signature): Signature { + if (!signature.anyReturningErasedSignatureCache) { + const erasedSignature = getErasedSignature(signature); + const anyReturningErasedSignature = cloneSignature(erasedSignature); + anyReturningErasedSignature.resolvedReturnType = anyType; + signature.anyReturningErasedSignatureCache = anyReturningErasedSignature; + } + return signature.anyReturningErasedSignatureCache; + } + function getOrCreateTypeFromSignature(signature: Signature): ObjectType { // There are two ways to declare a construct signature, one is by declaring a class constructor // using the constructor keyword, and the other is declaring a bare construct signature in an @@ -4985,16 +4995,19 @@ namespace ts { const erasedSource = getErasedSignature(implementation); const erasedTarget = getErasedSignature(overload); + // First see if the return types are compatible in either direction. const sourceReturnType = getReturnTypeOfSignature(erasedSource); const targetReturnType = getReturnTypeOfSignature(erasedTarget); if (targetReturnType === voidType || checkTypeRelatedTo(targetReturnType, sourceReturnType, assignableRelation, /*errorNode*/ undefined) || checkTypeRelatedTo(sourceReturnType, targetReturnType, assignableRelation, /*errorNode*/ undefined)) { - const anyReturningSource = cloneSignature(erasedSource); - const anyReturningTarget = cloneSignature(erasedTarget); - anyReturningSource.resolvedReturnType = anyType; - anyReturningTarget.resolvedReturnType = anyType; + // The return types are compatible, so create versions of the signature with 'any' as the return type. + // We need to do this so that we can check assignability while disregarding the return type. + const anyReturningSource = getAnyReturningErasedSignature(implementation); + const anyReturningTarget = getAnyReturningErasedSignature(overload); + + // Create object types to actually perform relation checks. const anyReturningSourceType = getOrCreateTypeFromSignature(anyReturningSource); const anyReturningTargetType = getOrCreateTypeFromSignature(anyReturningTarget); return checkTypeRelatedTo(anyReturningSourceType, anyReturningTargetType, assignableRelation, /*errorNode*/ undefined); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index ff8ffa4ebd2..c6c78709300 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2280,6 +2280,8 @@ namespace ts { /* @internal */ erasedSignatureCache?: Signature; // Erased version of signature (deferred) /* @internal */ + anyReturningErasedSignatureCache?: Signature; // A version of the erased signature whose type returns 'any' + /* @internal */ isolatedSignatureType?: ObjectType; // A manufactured type that just contains the signature for purposes of signature comparison } From 60e1f301822daba4afa67a37ec777b4fa47b6691 Mon Sep 17 00:00:00 2001 From: vladima Date: Fri, 11 Dec 2015 17:16:28 -0800 Subject: [PATCH 26/79] allow usage of 'super' in object literal expressions --- src/compiler/checker.ts | 86 ++++++----- src/compiler/diagnosticMessages.json | 8 ++ src/compiler/utilities.ts | 54 ++++--- src/services/services.ts | 4 +- .../computedPropertyNames24_ES5.errors.txt | 4 +- .../computedPropertyNames24_ES6.errors.txt | 4 +- .../computedPropertyNames26_ES5.errors.txt | 4 +- .../computedPropertyNames26_ES6.errors.txt | 4 +- .../computedPropertyNames27_ES5.errors.txt | 4 +- .../computedPropertyNames27_ES6.errors.txt | 4 +- .../decoratorOnClassMethod12.errors.txt | 4 +- .../emitThisInSuperMethodCall.errors.txt | 12 +- .../reference/errorSuperCalls.errors.txt | 32 ++--- .../errorSuperPropertyAccess.errors.txt | 16 +-- .../superCallFromFunction1.errors.txt | 4 +- .../reference/superErrors.errors.txt | 32 ++--- .../superInObjectLiterals_ES5.errors.txt | 95 +++++++++++++ .../reference/superInObjectLiterals_ES5.js | 133 ++++++++++++++++++ .../superInObjectLiterals_ES6.errors.txt | 77 ++++++++++ .../reference/superInObjectLiterals_ES6.js | 119 ++++++++++++++++ ...essInComputedPropertiesOfNestedType_ES5.js | 46 ++++++ ...ComputedPropertiesOfNestedType_ES5.symbols | 29 ++++ ...InComputedPropertiesOfNestedType_ES5.types | 35 +++++ ...essInComputedPropertiesOfNestedType_ES6.js | 31 ++++ ...ComputedPropertiesOfNestedType_ES6.symbols | 29 ++++ ...InComputedPropertiesOfNestedType_ES6.types | 35 +++++ ...ect-literal-getters-and-setters.errors.txt | 16 +-- ...side-object-literal-getters-and-setters.js | 6 +- .../compiler/superInObjectLiterals_ES5.ts | 60 ++++++++ .../compiler/superInObjectLiterals_ES6.ts | 60 ++++++++ ...essInComputedPropertiesOfNestedType_ES5.ts | 15 ++ ...essInComputedPropertiesOfNestedType_ES6.ts | 15 ++ 32 files changed, 940 insertions(+), 137 deletions(-) create mode 100644 tests/baselines/reference/superInObjectLiterals_ES5.errors.txt create mode 100644 tests/baselines/reference/superInObjectLiterals_ES5.js create mode 100644 tests/baselines/reference/superInObjectLiterals_ES6.errors.txt create mode 100644 tests/baselines/reference/superInObjectLiterals_ES6.js create mode 100644 tests/baselines/reference/superPropertyAccessInComputedPropertiesOfNestedType_ES5.js create mode 100644 tests/baselines/reference/superPropertyAccessInComputedPropertiesOfNestedType_ES5.symbols create mode 100644 tests/baselines/reference/superPropertyAccessInComputedPropertiesOfNestedType_ES5.types create mode 100644 tests/baselines/reference/superPropertyAccessInComputedPropertiesOfNestedType_ES6.js create mode 100644 tests/baselines/reference/superPropertyAccessInComputedPropertiesOfNestedType_ES6.symbols create mode 100644 tests/baselines/reference/superPropertyAccessInComputedPropertiesOfNestedType_ES6.types create mode 100644 tests/cases/compiler/superInObjectLiterals_ES5.ts create mode 100644 tests/cases/compiler/superInObjectLiterals_ES6.ts create mode 100644 tests/cases/compiler/superPropertyAccessInComputedPropertiesOfNestedType_ES5.ts create mode 100644 tests/cases/compiler/superPropertyAccessInComputedPropertiesOfNestedType_ES6.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 76bd39a00bf..6af7ddba419 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7037,17 +7037,14 @@ namespace ts { function checkSuperExpression(node: Node): Type { const isCallExpression = node.parent.kind === SyntaxKind.CallExpression && (node.parent).expression === node; - const classDeclaration = getContainingClass(node); - const classType = classDeclaration && getDeclaredTypeOfSymbol(getSymbolOfNode(classDeclaration)); - const baseClassType = classType && getBaseTypes(classType)[0]; - let container = getSuperContainer(node, /*includeFunctions*/ true); + let container = getSuperContainer(node, /*stopOnFunctions*/ true); let needToCaptureLexicalThis = false; if (!isCallExpression) { // adjust the container reference in case if super is used inside arrow functions with arbitrary deep nesting while (container && container.kind === SyntaxKind.ArrowFunction) { - container = getSuperContainer(container, /*includeFunctions*/ true); + container = getSuperContainer(container, /*stopOnFunctions*/ true); needToCaptureLexicalThis = languageVersion < ScriptTarget.ES6; } } @@ -7055,43 +7052,64 @@ namespace ts { const canUseSuperExpression = isLegalUsageOfSuperExpression(container); let nodeCheckFlag: NodeCheckFlags = 0; - // always set NodeCheckFlags for 'super' expression node - if (canUseSuperExpression) { - if ((container.flags & NodeFlags.Static) || isCallExpression) { - nodeCheckFlag = NodeCheckFlags.SuperStatic; + if (!canUseSuperExpression) { + if (isCallExpression) { + error(node, Diagnostics.Super_calls_are_not_permitted_outside_constructors_or_in_nested_functions_inside_constructors); + } + else if (!container || !container.parent || !(isClassLike(container.parent) || container.parent.kind === SyntaxKind.ObjectLiteralExpression)) { + error(node, Diagnostics.super_can_only_be_referenced_in_members_of_derived_classes_or_object_literal_expressions); } else { - nodeCheckFlag = NodeCheckFlags.SuperInstance; - } - - getNodeLinks(node).flags |= nodeCheckFlag; - - if (needToCaptureLexicalThis) { - // call expressions are allowed only in constructors so they should always capture correct 'this' - // super property access expressions can also appear in arrow functions - - // in this case they should also use correct lexical this - captureLexicalThis(node.parent, container); - } - } - - if (!baseClassType) { - if (!classDeclaration || !getClassExtendsHeritageClauseElement(classDeclaration)) { - error(node, Diagnostics.super_can_only_be_referenced_in_a_derived_class); + // issue more specific error if super is used in computed property name + let current = node; + while (current && current !== container && current.kind !== SyntaxKind.ComputedPropertyName) { + current = current.parent; + } + if (current && current.kind === SyntaxKind.ComputedPropertyName) { + error(node, Diagnostics.super_cannot_be_referenced_in_a_computed_property_name); + } + else { + error(node, Diagnostics.super_property_access_is_permitted_only_in_a_constructor_member_function_or_member_accessor_of_a_derived_class); + } } return unknownType; } - if (!canUseSuperExpression) { - if (container && container.kind === SyntaxKind.ComputedPropertyName) { - error(node, Diagnostics.super_cannot_be_referenced_in_a_computed_property_name); - } - else if (isCallExpression) { - error(node, Diagnostics.Super_calls_are_not_permitted_outside_constructors_or_in_nested_functions_inside_constructors); + if ((container.flags & NodeFlags.Static) || isCallExpression) { + nodeCheckFlag = NodeCheckFlags.SuperStatic; + } + else { + nodeCheckFlag = NodeCheckFlags.SuperInstance; + } + + getNodeLinks(node).flags |= nodeCheckFlag; + + if (needToCaptureLexicalThis) { + // call expressions are allowed only in constructors so they should always capture correct 'this' + // super property access expressions can also appear in arrow functions - + // in this case they should also use correct lexical this + captureLexicalThis(node.parent, container); + } + + if (container.parent.kind === SyntaxKind.ObjectLiteralExpression) { + if (languageVersion < ScriptTarget.ES6) { + error(node, Diagnostics.super_in_members_of_object_literal_expressions_is_only_allowed_when_option_target_is_ES2015_or_higher); + return unknownType; } else { - error(node, Diagnostics.super_property_access_is_permitted_only_in_a_constructor_member_function_or_member_accessor_of_a_derived_class); + // for object literal assume that type of 'super' is 'any' + return anyType; } + } + // at this point the only legal case for parent is ClassLikeDeclaration + const classLikeDeclaration = container.parent; + const classType = getDeclaredTypeOfSymbol(getSymbolOfNode(classLikeDeclaration)); + const baseClassType = classType && getBaseTypes(classType)[0]; + if (!baseClassType) { + if (!getClassExtendsHeritageClauseElement(classLikeDeclaration)) { + error(node, Diagnostics.super_can_only_be_referenced_in_a_derived_class); + } return unknownType; } @@ -7121,8 +7139,8 @@ namespace ts { // - In a constructor, instance member function, instance member accessor, or instance member variable initializer where this references a derived class instance // - In a static member function or static member accessor - // topmost container must be something that is directly nested in the class declaration - if (container && isClassLike(container.parent)) { + // topmost container must be something that is directly nested in the class declaration\object literal expression + if (isClassLike(container.parent) || container.parent.kind === SyntaxKind.ObjectLiteralExpression) { if (container.flags & NodeFlags.Static) { return container.kind === SyntaxKind.MethodDeclaration || container.kind === SyntaxKind.MethodSignature || diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 54123808932..30b46e5cde2 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1759,6 +1759,14 @@ "category": "Error", "code": 2658 }, + "'super' in members of object literal expressions is only allowed when option 'target' is 'ES2015' or higher.": { + "category": "Error", + "code": 2659 + }, + "'super' can only be referenced in members of derived classes or object literal expressions.": { + "category": "Error", + "code": 2660 + }, "Import declaration '{0}' is using private name '{1}'.": { "category": "Error", "code": 4000 diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index eee09fc641f..a85432418cc 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -775,26 +775,38 @@ namespace ts { } } - export function getSuperContainer(node: Node, includeFunctions: boolean): Node { + /** + * Given an super call\property node returns a closest node where either + * - super call\property is legal in the node and not legal in the parent node the node. + * i.e. super call is legal in constructor but not legal in the class body. + * - node is arrow function (so caller might need to call getSuperContainer in case if he needs to climb higher) + * - super call\property is definitely illegal in the node (but might be legal in some subnode) + * i.e. super property access is illegal in function declaration but can be legal in the statement list + */ + export function getSuperContainer(node: Node, stopOnFunctions: boolean): Node { while (true) { node = node.parent; - if (!node) return node; + if (!node) { + return node; + } switch (node.kind) { case SyntaxKind.ComputedPropertyName: - // If the grandparent node is an object literal (as opposed to a class), - // then the computed property is not a 'super' container. - // A computed property name in a class needs to be a super container - // so that we can error on it. - if (isClassLike(node.parent.parent)) { - return node; - } - // If this is a computed property, then the parent should not - // make it a super container. The parent might be a property - // in an object literal, like a method or accessor. But in order for - // such a parent to be a super container, the reference must be in - // the *body* of the container. node = node.parent; break; + case SyntaxKind.FunctionDeclaration: + case SyntaxKind.FunctionExpression: + case SyntaxKind.ArrowFunction: + if (!stopOnFunctions) { + continue; + } + case SyntaxKind.PropertyDeclaration: + case SyntaxKind.PropertySignature: + case SyntaxKind.MethodDeclaration: + case SyntaxKind.MethodSignature: + case SyntaxKind.Constructor: + case SyntaxKind.GetAccessor: + case SyntaxKind.SetAccessor: + return node; case SyntaxKind.Decorator: // Decorators are always applied outside of the body of a class or method. if (node.parent.kind === SyntaxKind.Parameter && isClassElement(node.parent.parent)) { @@ -808,20 +820,6 @@ namespace ts { node = node.parent; } break; - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.FunctionExpression: - case SyntaxKind.ArrowFunction: - if (!includeFunctions) { - continue; - } - case SyntaxKind.PropertyDeclaration: - case SyntaxKind.PropertySignature: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.MethodSignature: - case SyntaxKind.Constructor: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - return node; } } } diff --git a/src/services/services.ts b/src/services/services.ts index a9dda549ead..2d42172832f 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -5780,7 +5780,7 @@ namespace ts { } function getReferencesForSuperKeyword(superKeyword: Node): ReferencedSymbol[] { - let searchSpaceNode = getSuperContainer(superKeyword, /*includeFunctions*/ false); + let searchSpaceNode = getSuperContainer(superKeyword, /*stopOnFunctions*/ false); if (!searchSpaceNode) { return undefined; } @@ -5815,7 +5815,7 @@ namespace ts { return; } - let container = getSuperContainer(node, /*includeFunctions*/ false); + let container = getSuperContainer(node, /*stopOnFunctions*/ false); // If we have a 'super' container, we must have an enclosing class. // Now make sure the owning class is the same as the search-space diff --git a/tests/baselines/reference/computedPropertyNames24_ES5.errors.txt b/tests/baselines/reference/computedPropertyNames24_ES5.errors.txt index 121b39450a6..e06373fb1e3 100644 --- a/tests/baselines/reference/computedPropertyNames24_ES5.errors.txt +++ b/tests/baselines/reference/computedPropertyNames24_ES5.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/es6/computedProperties/computedPropertyNames24_ES5.ts(7,6): error TS2466: 'super' cannot be referenced in a computed property name. +tests/cases/conformance/es6/computedProperties/computedPropertyNames24_ES5.ts(7,6): error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. ==== tests/cases/conformance/es6/computedProperties/computedPropertyNames24_ES5.ts (1 errors) ==== @@ -10,5 +10,5 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames24_ES5.ts(7, class C extends Base { [super.bar()]() { } ~~~~~ -!!! error TS2466: 'super' cannot be referenced in a computed property name. +!!! error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. } \ No newline at end of file diff --git a/tests/baselines/reference/computedPropertyNames24_ES6.errors.txt b/tests/baselines/reference/computedPropertyNames24_ES6.errors.txt index cab0ba6a85c..331723afe34 100644 --- a/tests/baselines/reference/computedPropertyNames24_ES6.errors.txt +++ b/tests/baselines/reference/computedPropertyNames24_ES6.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/es6/computedProperties/computedPropertyNames24_ES6.ts(9,6): error TS2466: 'super' cannot be referenced in a computed property name. +tests/cases/conformance/es6/computedProperties/computedPropertyNames24_ES6.ts(9,6): error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. ==== tests/cases/conformance/es6/computedProperties/computedPropertyNames24_ES6.ts (1 errors) ==== @@ -12,5 +12,5 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames24_ES6.ts(9, // use of super in static properties initializers. [super.bar()]() { } ~~~~~ -!!! error TS2466: 'super' cannot be referenced in a computed property name. +!!! error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. } \ No newline at end of file diff --git a/tests/baselines/reference/computedPropertyNames26_ES5.errors.txt b/tests/baselines/reference/computedPropertyNames26_ES5.errors.txt index e7039712734..c8e24abfa9d 100644 --- a/tests/baselines/reference/computedPropertyNames26_ES5.errors.txt +++ b/tests/baselines/reference/computedPropertyNames26_ES5.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/es6/computedProperties/computedPropertyNames26_ES5.ts(8,12): error TS2466: 'super' cannot be referenced in a computed property name. +tests/cases/conformance/es6/computedProperties/computedPropertyNames26_ES5.ts(8,12): error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. ==== tests/cases/conformance/es6/computedProperties/computedPropertyNames26_ES5.ts (1 errors) ==== @@ -11,6 +11,6 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames26_ES5.ts(8, [ { [super.bar()]: 1 }[0] ~~~~~ -!!! error TS2466: 'super' cannot be referenced in a computed property name. +!!! error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. ]() { } } \ No newline at end of file diff --git a/tests/baselines/reference/computedPropertyNames26_ES6.errors.txt b/tests/baselines/reference/computedPropertyNames26_ES6.errors.txt index d7e2b5ce7c5..ec20ed57144 100644 --- a/tests/baselines/reference/computedPropertyNames26_ES6.errors.txt +++ b/tests/baselines/reference/computedPropertyNames26_ES6.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/es6/computedProperties/computedPropertyNames26_ES6.ts(10,12): error TS2466: 'super' cannot be referenced in a computed property name. +tests/cases/conformance/es6/computedProperties/computedPropertyNames26_ES6.ts(10,12): error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. ==== tests/cases/conformance/es6/computedProperties/computedPropertyNames26_ES6.ts (1 errors) ==== @@ -13,6 +13,6 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames26_ES6.ts(10 [ { [super.bar()]: 1 }[0] ~~~~~ -!!! error TS2466: 'super' cannot be referenced in a computed property name. +!!! error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. ]() { } } \ No newline at end of file diff --git a/tests/baselines/reference/computedPropertyNames27_ES5.errors.txt b/tests/baselines/reference/computedPropertyNames27_ES5.errors.txt index 1fbc7b37543..97964d48176 100644 --- a/tests/baselines/reference/computedPropertyNames27_ES5.errors.txt +++ b/tests/baselines/reference/computedPropertyNames27_ES5.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/es6/computedProperties/computedPropertyNames27_ES5.ts(4,7): error TS2466: 'super' cannot be referenced in a computed property name. +tests/cases/conformance/es6/computedProperties/computedPropertyNames27_ES5.ts(4,7): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors. ==== tests/cases/conformance/es6/computedProperties/computedPropertyNames27_ES5.ts (1 errors) ==== @@ -7,5 +7,5 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames27_ES5.ts(4, class C extends Base { [(super(), "prop")]() { } ~~~~~ -!!! error TS2466: 'super' cannot be referenced in a computed property name. +!!! error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors. } \ No newline at end of file diff --git a/tests/baselines/reference/computedPropertyNames27_ES6.errors.txt b/tests/baselines/reference/computedPropertyNames27_ES6.errors.txt index edf84201647..30e1ce5b14f 100644 --- a/tests/baselines/reference/computedPropertyNames27_ES6.errors.txt +++ b/tests/baselines/reference/computedPropertyNames27_ES6.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/es6/computedProperties/computedPropertyNames27_ES6.ts(4,7): error TS2466: 'super' cannot be referenced in a computed property name. +tests/cases/conformance/es6/computedProperties/computedPropertyNames27_ES6.ts(4,7): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors. ==== tests/cases/conformance/es6/computedProperties/computedPropertyNames27_ES6.ts (1 errors) ==== @@ -7,5 +7,5 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames27_ES6.ts(4, class C extends Base { [(super(), "prop")]() { } ~~~~~ -!!! error TS2466: 'super' cannot be referenced in a computed property name. +!!! error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors. } \ No newline at end of file diff --git a/tests/baselines/reference/decoratorOnClassMethod12.errors.txt b/tests/baselines/reference/decoratorOnClassMethod12.errors.txt index 3ad3cabebe2..c285d5f12c9 100644 --- a/tests/baselines/reference/decoratorOnClassMethod12.errors.txt +++ b/tests/baselines/reference/decoratorOnClassMethod12.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/decorators/class/method/decoratorOnClassMethod12.ts(6,10): error TS2338: 'super' property access is permitted only in a constructor, member function, or member accessor of a derived class. +tests/cases/conformance/decorators/class/method/decoratorOnClassMethod12.ts(6,10): error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. ==== tests/cases/conformance/decorators/class/method/decoratorOnClassMethod12.ts (1 errors) ==== @@ -9,7 +9,7 @@ tests/cases/conformance/decorators/class/method/decoratorOnClassMethod12.ts(6,10 class C extends S { @super.decorator ~~~~~ -!!! error TS2338: 'super' property access is permitted only in a constructor, member function, or member accessor of a derived class. +!!! error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. method() { } } } \ No newline at end of file diff --git a/tests/baselines/reference/emitThisInSuperMethodCall.errors.txt b/tests/baselines/reference/emitThisInSuperMethodCall.errors.txt index 06211ef771f..c8d694c8567 100644 --- a/tests/baselines/reference/emitThisInSuperMethodCall.errors.txt +++ b/tests/baselines/reference/emitThisInSuperMethodCall.errors.txt @@ -1,6 +1,6 @@ -tests/cases/compiler/emitThisInSuperMethodCall.ts(10,17): error TS2338: 'super' property access is permitted only in a constructor, member function, or member accessor of a derived class. -tests/cases/compiler/emitThisInSuperMethodCall.ts(17,17): error TS2338: 'super' property access is permitted only in a constructor, member function, or member accessor of a derived class. -tests/cases/compiler/emitThisInSuperMethodCall.ts(23,13): error TS2338: 'super' property access is permitted only in a constructor, member function, or member accessor of a derived class. +tests/cases/compiler/emitThisInSuperMethodCall.ts(10,17): error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. +tests/cases/compiler/emitThisInSuperMethodCall.ts(17,17): error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. +tests/cases/compiler/emitThisInSuperMethodCall.ts(23,13): error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. ==== tests/cases/compiler/emitThisInSuperMethodCall.ts (3 errors) ==== @@ -15,7 +15,7 @@ tests/cases/compiler/emitThisInSuperMethodCall.ts(23,13): error TS2338: 'super' function inner() { super.sayHello(); ~~~~~ -!!! error TS2338: 'super' property access is permitted only in a constructor, member function, or member accessor of a derived class. +!!! error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. } }; } @@ -24,7 +24,7 @@ tests/cases/compiler/emitThisInSuperMethodCall.ts(23,13): error TS2338: 'super' () => { super.sayHello(); ~~~~~ -!!! error TS2338: 'super' property access is permitted only in a constructor, member function, or member accessor of a derived class. +!!! error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. } } } @@ -32,7 +32,7 @@ tests/cases/compiler/emitThisInSuperMethodCall.ts(23,13): error TS2338: 'super' function inner() { super.sayHello(); ~~~~~ -!!! error TS2338: 'super' property access is permitted only in a constructor, member function, or member accessor of a derived class. +!!! error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. } } } diff --git a/tests/baselines/reference/errorSuperCalls.errors.txt b/tests/baselines/reference/errorSuperCalls.errors.txt index 9ecc7a1565e..49bcb4b4d45 100644 --- a/tests/baselines/reference/errorSuperCalls.errors.txt +++ b/tests/baselines/reference/errorSuperCalls.errors.txt @@ -1,12 +1,12 @@ tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(4,9): error TS2335: 'super' can only be referenced in a derived class. -tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(9,9): error TS2335: 'super' can only be referenced in a derived class. -tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(14,9): error TS2335: 'super' can only be referenced in a derived class. -tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(18,9): error TS2335: 'super' can only be referenced in a derived class. -tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(22,9): error TS2335: 'super' can only be referenced in a derived class. -tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(26,9): error TS2335: 'super' can only be referenced in a derived class. -tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(30,16): error TS2335: 'super' can only be referenced in a derived class. -tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(34,9): error TS2335: 'super' can only be referenced in a derived class. -tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(38,9): error TS2335: 'super' can only be referenced in a derived class. +tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(9,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors. +tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(14,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors. +tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(18,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors. +tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(22,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors. +tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(26,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors. +tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(30,16): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors. +tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(34,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors. +tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(38,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors. tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(46,14): error TS1034: 'super' must be followed by an argument list or member access. tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(58,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors. tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(62,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors. @@ -27,50 +27,50 @@ tests/cases/conformance/expressions/superCalls/errorSuperCalls.ts(71,9): error T fn() { super(); ~~~~~ -!!! error TS2335: 'super' can only be referenced in a derived class. +!!! error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors. } //super call in class accessor (get and set) with no base type get foo() { super(); ~~~~~ -!!! error TS2335: 'super' can only be referenced in a derived class. +!!! error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors. return null; } set foo(v) { super(); ~~~~~ -!!! error TS2335: 'super' can only be referenced in a derived class. +!!! error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors. } //super call in class member initializer with no base type p = super(); ~~~~~ -!!! error TS2335: 'super' can only be referenced in a derived class. +!!! error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors. //super call in static class member function with no base type static fn() { super(); ~~~~~ -!!! error TS2335: 'super' can only be referenced in a derived class. +!!! error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors. } //super call in static class member initializer with no base type static k = super(); ~~~~~ -!!! error TS2335: 'super' can only be referenced in a derived class. +!!! error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors. //super call in static class accessor (get and set) with no base type static get q() { super(); ~~~~~ -!!! error TS2335: 'super' can only be referenced in a derived class. +!!! error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors. return null; } static set q(n) { super(); ~~~~~ -!!! error TS2335: 'super' can only be referenced in a derived class. +!!! error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors. } } diff --git a/tests/baselines/reference/errorSuperPropertyAccess.errors.txt b/tests/baselines/reference/errorSuperPropertyAccess.errors.txt index c34ed912046..c54ace99f17 100644 --- a/tests/baselines/reference/errorSuperPropertyAccess.errors.txt +++ b/tests/baselines/reference/errorSuperPropertyAccess.errors.txt @@ -15,8 +15,8 @@ tests/cases/conformance/expressions/superPropertyAccess/errorSuperPropertyAccess tests/cases/conformance/expressions/superPropertyAccess/errorSuperPropertyAccess.ts(65,23): error TS2340: Only public and protected methods of the base class are accessible via the 'super' keyword. tests/cases/conformance/expressions/superPropertyAccess/errorSuperPropertyAccess.ts(68,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. tests/cases/conformance/expressions/superPropertyAccess/errorSuperPropertyAccess.ts(69,19): error TS2340: Only public and protected methods of the base class are accessible via the 'super' keyword. -tests/cases/conformance/expressions/superPropertyAccess/errorSuperPropertyAccess.ts(73,13): error TS2338: 'super' property access is permitted only in a constructor, member function, or member accessor of a derived class. -tests/cases/conformance/expressions/superPropertyAccess/errorSuperPropertyAccess.ts(76,40): error TS2338: 'super' property access is permitted only in a constructor, member function, or member accessor of a derived class. +tests/cases/conformance/expressions/superPropertyAccess/errorSuperPropertyAccess.ts(73,13): error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. +tests/cases/conformance/expressions/superPropertyAccess/errorSuperPropertyAccess.ts(76,40): error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. tests/cases/conformance/expressions/superPropertyAccess/errorSuperPropertyAccess.ts(87,15): error TS2340: Only public and protected methods of the base class are accessible via the 'super' keyword. tests/cases/conformance/expressions/superPropertyAccess/errorSuperPropertyAccess.ts(91,23): error TS2340: Only public and protected methods of the base class are accessible via the 'super' keyword. tests/cases/conformance/expressions/superPropertyAccess/errorSuperPropertyAccess.ts(94,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. @@ -34,8 +34,8 @@ tests/cases/conformance/expressions/superPropertyAccess/errorSuperPropertyAccess tests/cases/conformance/expressions/superPropertyAccess/errorSuperPropertyAccess.ts(120,15): error TS2340: Only public and protected methods of the base class are accessible via the 'super' keyword. tests/cases/conformance/expressions/superPropertyAccess/errorSuperPropertyAccess.ts(121,15): error TS2340: Only public and protected methods of the base class are accessible via the 'super' keyword. tests/cases/conformance/expressions/superPropertyAccess/errorSuperPropertyAccess.ts(122,9): error TS2341: Property 'privateStaticFunc' is private and only accessible within class 'SomeBase'. -tests/cases/conformance/expressions/superPropertyAccess/errorSuperPropertyAccess.ts(127,16): error TS2335: 'super' can only be referenced in a derived class. -tests/cases/conformance/expressions/superPropertyAccess/errorSuperPropertyAccess.ts(127,30): error TS2335: 'super' can only be referenced in a derived class. +tests/cases/conformance/expressions/superPropertyAccess/errorSuperPropertyAccess.ts(127,16): error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. +tests/cases/conformance/expressions/superPropertyAccess/errorSuperPropertyAccess.ts(127,30): error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. ==== tests/cases/conformance/expressions/superPropertyAccess/errorSuperPropertyAccess.ts (38 errors) ==== @@ -147,12 +147,12 @@ tests/cases/conformance/expressions/superPropertyAccess/errorSuperPropertyAccess function inner() { super.publicFunc(); ~~~~~ -!!! error TS2338: 'super' property access is permitted only in a constructor, member function, or member accessor of a derived class. +!!! error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. } var x = { test: function () { return super.publicFunc(); } ~~~~~ -!!! error TS2338: 'super' property access is permitted only in a constructor, member function, or member accessor of a derived class. +!!! error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. } } } @@ -239,7 +239,7 @@ tests/cases/conformance/expressions/superPropertyAccess/errorSuperPropertyAccess // In object literal var obj = { n: super.wat, p: super.foo() }; ~~~~~ -!!! error TS2335: 'super' can only be referenced in a derived class. +!!! error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. ~~~~~ -!!! error TS2335: 'super' can only be referenced in a derived class. +!!! error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. \ No newline at end of file diff --git a/tests/baselines/reference/superCallFromFunction1.errors.txt b/tests/baselines/reference/superCallFromFunction1.errors.txt index 374a3aeb16c..b993d9f1253 100644 --- a/tests/baselines/reference/superCallFromFunction1.errors.txt +++ b/tests/baselines/reference/superCallFromFunction1.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/superCallFromFunction1.ts(3,5): error TS2335: 'super' can only be referenced in a derived class. +tests/cases/compiler/superCallFromFunction1.ts(3,5): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors. ==== tests/cases/compiler/superCallFromFunction1.ts (1 errors) ==== @@ -6,5 +6,5 @@ tests/cases/compiler/superCallFromFunction1.ts(3,5): error TS2335: 'super' can o function foo() { super(value => String(value)); ~~~~~ -!!! error TS2335: 'super' can only be referenced in a derived class. +!!! error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors. } \ No newline at end of file diff --git a/tests/baselines/reference/superErrors.errors.txt b/tests/baselines/reference/superErrors.errors.txt index 26e0ba3a6c4..5c6d7365a67 100644 --- a/tests/baselines/reference/superErrors.errors.txt +++ b/tests/baselines/reference/superErrors.errors.txt @@ -1,15 +1,15 @@ -tests/cases/compiler/superErrors.ts(3,13): error TS2335: 'super' can only be referenced in a derived class. +tests/cases/compiler/superErrors.ts(3,13): error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. tests/cases/compiler/superErrors.ts(3,18): error TS1034: 'super' must be followed by an argument list or member access. -tests/cases/compiler/superErrors.ts(4,19): error TS2335: 'super' can only be referenced in a derived class. +tests/cases/compiler/superErrors.ts(4,19): error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. tests/cases/compiler/superErrors.ts(4,24): error TS1034: 'super' must be followed by an argument list or member access. -tests/cases/compiler/superErrors.ts(5,31): error TS2335: 'super' can only be referenced in a derived class. +tests/cases/compiler/superErrors.ts(5,31): error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. tests/cases/compiler/superErrors.ts(5,36): error TS1034: 'super' must be followed by an argument list or member access. -tests/cases/compiler/superErrors.ts(22,13): error TS2338: 'super' property access is permitted only in a constructor, member function, or member accessor of a derived class. -tests/cases/compiler/superErrors.ts(27,27): error TS2338: 'super' property access is permitted only in a constructor, member function, or member accessor of a derived class. -tests/cases/compiler/superErrors.ts(31,36): error TS2338: 'super' property access is permitted only in a constructor, member function, or member accessor of a derived class. +tests/cases/compiler/superErrors.ts(22,13): error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. +tests/cases/compiler/superErrors.ts(27,27): error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. +tests/cases/compiler/superErrors.ts(31,36): error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. tests/cases/compiler/superErrors.ts(31,41): error TS1034: 'super' must be followed by an argument list or member access. -tests/cases/compiler/superErrors.ts(39,27): error TS2338: 'super' property access is permitted only in a constructor, member function, or member accessor of a derived class. -tests/cases/compiler/superErrors.ts(43,36): error TS2338: 'super' property access is permitted only in a constructor, member function, or member accessor of a derived class. +tests/cases/compiler/superErrors.ts(39,27): error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. +tests/cases/compiler/superErrors.ts(43,36): error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. tests/cases/compiler/superErrors.ts(43,41): error TS1034: 'super' must be followed by an argument list or member access. tests/cases/compiler/superErrors.ts(47,22): error TS1034: 'super' must be followed by an argument list or member access. tests/cases/compiler/superErrors.ts(48,28): error TS1034: 'super' must be followed by an argument list or member access. @@ -21,17 +21,17 @@ tests/cases/compiler/superErrors.ts(49,40): error TS1034: 'super' must be follow // super in a non class context var x = super; ~~~~~ -!!! error TS2335: 'super' can only be referenced in a derived class. +!!! error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. ~ !!! error TS1034: 'super' must be followed by an argument list or member access. var y = () => super; ~~~~~ -!!! error TS2335: 'super' can only be referenced in a derived class. +!!! error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. ~ !!! error TS1034: 'super' must be followed by an argument list or member access. var z = () => () => () => super; ~~~~~ -!!! error TS2335: 'super' can only be referenced in a derived class. +!!! error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. ~ !!! error TS1034: 'super' must be followed by an argument list or member access. } @@ -52,20 +52,20 @@ tests/cases/compiler/superErrors.ts(49,40): error TS1034: 'super' must be follow function inner() { super.sayHello(); ~~~~~ -!!! error TS2338: 'super' property access is permitted only in a constructor, member function, or member accessor of a derived class. +!!! error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. } // super call in a lambda in an inner function in a constructor function inner2() { var x = () => super.sayHello(); ~~~~~ -!!! error TS2338: 'super' property access is permitted only in a constructor, member function, or member accessor of a derived class. +!!! error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. } // super call in a lambda in a function expression in a constructor (function() { return () => super; })(); ~~~~~ -!!! error TS2338: 'super' property access is permitted only in a constructor, member function, or member accessor of a derived class. +!!! error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. ~ !!! error TS1034: 'super' must be followed by an argument list or member access. } @@ -77,13 +77,13 @@ tests/cases/compiler/superErrors.ts(49,40): error TS1034: 'super' must be follow function inner() { var x = () => super.sayHello(); ~~~~~ -!!! error TS2338: 'super' property access is permitted only in a constructor, member function, or member accessor of a derived class. +!!! error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. } // super call in a lambda in a function expression in a constructor (function() { return () => super; })(); ~~~~~ -!!! error TS2338: 'super' property access is permitted only in a constructor, member function, or member accessor of a derived class. +!!! error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. ~ !!! error TS1034: 'super' must be followed by an argument list or member access. } diff --git a/tests/baselines/reference/superInObjectLiterals_ES5.errors.txt b/tests/baselines/reference/superInObjectLiterals_ES5.errors.txt new file mode 100644 index 00000000000..944766cb5ae --- /dev/null +++ b/tests/baselines/reference/superInObjectLiterals_ES5.errors.txt @@ -0,0 +1,95 @@ +tests/cases/compiler/superInObjectLiterals_ES5.ts(7,9): error TS2659: 'super' in members of object literal expressions is only allowed when option 'target' is 'ES2015' or higher. +tests/cases/compiler/superInObjectLiterals_ES5.ts(10,9): error TS2659: 'super' in members of object literal expressions is only allowed when option 'target' is 'ES2015' or higher. +tests/cases/compiler/superInObjectLiterals_ES5.ts(14,9): error TS2659: 'super' in members of object literal expressions is only allowed when option 'target' is 'ES2015' or higher. +tests/cases/compiler/superInObjectLiterals_ES5.ts(17,9): error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. +tests/cases/compiler/superInObjectLiterals_ES5.ts(20,9): error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. +tests/cases/compiler/superInObjectLiterals_ES5.ts(23,9): error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. +tests/cases/compiler/superInObjectLiterals_ES5.ts(39,17): error TS2659: 'super' in members of object literal expressions is only allowed when option 'target' is 'ES2015' or higher. +tests/cases/compiler/superInObjectLiterals_ES5.ts(42,17): error TS2659: 'super' in members of object literal expressions is only allowed when option 'target' is 'ES2015' or higher. +tests/cases/compiler/superInObjectLiterals_ES5.ts(46,17): error TS2659: 'super' in members of object literal expressions is only allowed when option 'target' is 'ES2015' or higher. +tests/cases/compiler/superInObjectLiterals_ES5.ts(49,17): error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. +tests/cases/compiler/superInObjectLiterals_ES5.ts(52,17): error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. + + +==== tests/cases/compiler/superInObjectLiterals_ES5.ts (11 errors) ==== + var obj = { + __proto__: { + method() { + } + }, + method() { + super.method(); + ~~~~~ +!!! error TS2659: 'super' in members of object literal expressions is only allowed when option 'target' is 'ES2015' or higher. + }, + get prop() { + super.method(); + ~~~~~ +!!! error TS2659: 'super' in members of object literal expressions is only allowed when option 'target' is 'ES2015' or higher. + return 10; + }, + set prop(value) { + super.method(); + ~~~~~ +!!! error TS2659: 'super' in members of object literal expressions is only allowed when option 'target' is 'ES2015' or higher. + }, + p1: function () { + super.method(); + ~~~~~ +!!! error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. + }, + p2: function f() { + super.method(); + ~~~~~ +!!! error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. + }, + p3: () => { + super.method(); + ~~~~~ +!!! error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. + } + }; + + class A { + method() { } + } + + class B extends A { + f() { + var obj = { + __proto__: { + method() { + } + }, + method() { + super.method(); + ~~~~~ +!!! error TS2659: 'super' in members of object literal expressions is only allowed when option 'target' is 'ES2015' or higher. + }, + get prop() { + super.method(); + ~~~~~ +!!! error TS2659: 'super' in members of object literal expressions is only allowed when option 'target' is 'ES2015' or higher. + return 10; + }, + set prop(value) { + super.method(); + ~~~~~ +!!! error TS2659: 'super' in members of object literal expressions is only allowed when option 'target' is 'ES2015' or higher. + }, + p1: function () { + super.method(); + ~~~~~ +!!! error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. + }, + p2: function f() { + super.method(); + ~~~~~ +!!! error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. + }, + p3: () => { + super.method(); + } + }; + } + } \ No newline at end of file diff --git a/tests/baselines/reference/superInObjectLiterals_ES5.js b/tests/baselines/reference/superInObjectLiterals_ES5.js new file mode 100644 index 00000000000..f701ca7df7b --- /dev/null +++ b/tests/baselines/reference/superInObjectLiterals_ES5.js @@ -0,0 +1,133 @@ +//// [superInObjectLiterals_ES5.ts] +var obj = { + __proto__: { + method() { + } + }, + method() { + super.method(); + }, + get prop() { + super.method(); + return 10; + }, + set prop(value) { + super.method(); + }, + p1: function () { + super.method(); + }, + p2: function f() { + super.method(); + }, + p3: () => { + super.method(); + } +}; + +class A { + method() { } +} + +class B extends A { + f() { + var obj = { + __proto__: { + method() { + } + }, + method() { + super.method(); + }, + get prop() { + super.method(); + return 10; + }, + set prop(value) { + super.method(); + }, + p1: function () { + super.method(); + }, + p2: function f() { + super.method(); + }, + p3: () => { + super.method(); + } + }; + } +} + +//// [superInObjectLiterals_ES5.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var obj = { + __proto__: { + method: function () { + } + }, + method: function () { + _super.prototype.method.call(this); + }, + get prop() { + _super.prototype.method.call(this); + return 10; + }, + set prop(value) { + _super.prototype.method.call(this); + }, + p1: function () { + _super.method.call(this); + }, + p2: function f() { + _super.method.call(this); + }, + p3: function () { + _super.method.call(this); + } +}; +var A = (function () { + function A() { + } + A.prototype.method = function () { }; + return A; +}()); +var B = (function (_super) { + __extends(B, _super); + function B() { + _super.apply(this, arguments); + } + B.prototype.f = function () { + var _this = this; + var obj = { + __proto__: { + method: function () { + } + }, + method: function () { + _super.prototype.method.call(this); + }, + get prop() { + _super.prototype.method.call(this); + return 10; + }, + set prop(value) { + _super.prototype.method.call(this); + }, + p1: function () { + _super.method.call(this); + }, + p2: function f() { + _super.method.call(this); + }, + p3: function () { + _super.prototype.method.call(_this); + } + }; + }; + return B; +}(A)); diff --git a/tests/baselines/reference/superInObjectLiterals_ES6.errors.txt b/tests/baselines/reference/superInObjectLiterals_ES6.errors.txt new file mode 100644 index 00000000000..dcd9692f5e3 --- /dev/null +++ b/tests/baselines/reference/superInObjectLiterals_ES6.errors.txt @@ -0,0 +1,77 @@ +tests/cases/compiler/superInObjectLiterals_ES6.ts(17,9): error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. +tests/cases/compiler/superInObjectLiterals_ES6.ts(20,9): error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. +tests/cases/compiler/superInObjectLiterals_ES6.ts(23,9): error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. +tests/cases/compiler/superInObjectLiterals_ES6.ts(49,17): error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. +tests/cases/compiler/superInObjectLiterals_ES6.ts(52,17): error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. + + +==== tests/cases/compiler/superInObjectLiterals_ES6.ts (5 errors) ==== + var obj = { + __proto__: { + method() { + } + }, + method() { + super.method(); + }, + get prop() { + super.method(); + return 10; + }, + set prop(value) { + super.method(); + }, + p1: function () { + super.method(); + ~~~~~ +!!! error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. + }, + p2: function f() { + super.method(); + ~~~~~ +!!! error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. + }, + p3: () => { + super.method(); + ~~~~~ +!!! error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. + } + }; + + class A { + method() { } + } + + class B extends A { + f() { + var obj = { + __proto__: { + method() { + } + }, + method() { + super.method(); + }, + get prop() { + super.method(); + return 10; + }, + set prop(value) { + super.method(); + }, + p1: function () { + super.method(); + ~~~~~ +!!! error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. + }, + p2: function f() { + super.method(); + ~~~~~ +!!! error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. + }, + p3: () => { + super.method(); + } + }; + } + } \ No newline at end of file diff --git a/tests/baselines/reference/superInObjectLiterals_ES6.js b/tests/baselines/reference/superInObjectLiterals_ES6.js new file mode 100644 index 00000000000..4cd62e68947 --- /dev/null +++ b/tests/baselines/reference/superInObjectLiterals_ES6.js @@ -0,0 +1,119 @@ +//// [superInObjectLiterals_ES6.ts] +var obj = { + __proto__: { + method() { + } + }, + method() { + super.method(); + }, + get prop() { + super.method(); + return 10; + }, + set prop(value) { + super.method(); + }, + p1: function () { + super.method(); + }, + p2: function f() { + super.method(); + }, + p3: () => { + super.method(); + } +}; + +class A { + method() { } +} + +class B extends A { + f() { + var obj = { + __proto__: { + method() { + } + }, + method() { + super.method(); + }, + get prop() { + super.method(); + return 10; + }, + set prop(value) { + super.method(); + }, + p1: function () { + super.method(); + }, + p2: function f() { + super.method(); + }, + p3: () => { + super.method(); + } + }; + } +} + +//// [superInObjectLiterals_ES6.js] +var obj = { + __proto__: { + method() { + } + }, + method() { + super.method(); + }, + get prop() { + super.method(); + return 10; + }, + set prop(value) { + super.method(); + }, + p1: function () { + super.method(); + }, + p2: function f() { + super.method(); + }, + p3: () => { + super.method(); + } +}; +class A { + method() { } +} +class B extends A { + f() { + var obj = { + __proto__: { + method() { + } + }, + method() { + super.method(); + }, + get prop() { + super.method(); + return 10; + }, + set prop(value) { + super.method(); + }, + p1: function () { + super.method(); + }, + p2: function f() { + super.method(); + }, + p3: () => { + super.method(); + } + }; + } +} diff --git a/tests/baselines/reference/superPropertyAccessInComputedPropertiesOfNestedType_ES5.js b/tests/baselines/reference/superPropertyAccessInComputedPropertiesOfNestedType_ES5.js new file mode 100644 index 00000000000..a91dfc76e3d --- /dev/null +++ b/tests/baselines/reference/superPropertyAccessInComputedPropertiesOfNestedType_ES5.js @@ -0,0 +1,46 @@ +//// [superPropertyAccessInComputedPropertiesOfNestedType_ES5.ts] +class A { + foo() { return 1; } +} + +class B extends A { + foo() { return 2; } + bar() { + return class { + [super.foo()]() { + return 100; + } + } + } +} + +//// [superPropertyAccessInComputedPropertiesOfNestedType_ES5.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var A = (function () { + function A() { + } + A.prototype.foo = function () { return 1; }; + return A; +}()); +var B = (function (_super) { + __extends(B, _super); + function B() { + _super.apply(this, arguments); + } + B.prototype.foo = function () { return 2; }; + B.prototype.bar = function () { + return (function () { + function class_1() { + } + class_1.prototype[_super.prototype.foo.call(this)] = function () { + return 100; + }; + return class_1; + }()); + }; + return B; +}(A)); diff --git a/tests/baselines/reference/superPropertyAccessInComputedPropertiesOfNestedType_ES5.symbols b/tests/baselines/reference/superPropertyAccessInComputedPropertiesOfNestedType_ES5.symbols new file mode 100644 index 00000000000..1379d50179f --- /dev/null +++ b/tests/baselines/reference/superPropertyAccessInComputedPropertiesOfNestedType_ES5.symbols @@ -0,0 +1,29 @@ +=== tests/cases/compiler/superPropertyAccessInComputedPropertiesOfNestedType_ES5.ts === +class A { +>A : Symbol(A, Decl(superPropertyAccessInComputedPropertiesOfNestedType_ES5.ts, 0, 0)) + + foo() { return 1; } +>foo : Symbol(foo, Decl(superPropertyAccessInComputedPropertiesOfNestedType_ES5.ts, 0, 9)) +} + +class B extends A { +>B : Symbol(B, Decl(superPropertyAccessInComputedPropertiesOfNestedType_ES5.ts, 2, 1)) +>A : Symbol(A, Decl(superPropertyAccessInComputedPropertiesOfNestedType_ES5.ts, 0, 0)) + + foo() { return 2; } +>foo : Symbol(foo, Decl(superPropertyAccessInComputedPropertiesOfNestedType_ES5.ts, 4, 19)) + + bar() { +>bar : Symbol(bar, Decl(superPropertyAccessInComputedPropertiesOfNestedType_ES5.ts, 5, 23)) + + return class { + [super.foo()]() { +>super.foo : Symbol(A.foo, Decl(superPropertyAccessInComputedPropertiesOfNestedType_ES5.ts, 0, 9)) +>super : Symbol(A, Decl(superPropertyAccessInComputedPropertiesOfNestedType_ES5.ts, 0, 0)) +>foo : Symbol(A.foo, Decl(superPropertyAccessInComputedPropertiesOfNestedType_ES5.ts, 0, 9)) + + return 100; + } + } + } +} diff --git a/tests/baselines/reference/superPropertyAccessInComputedPropertiesOfNestedType_ES5.types b/tests/baselines/reference/superPropertyAccessInComputedPropertiesOfNestedType_ES5.types new file mode 100644 index 00000000000..d435bff69b5 --- /dev/null +++ b/tests/baselines/reference/superPropertyAccessInComputedPropertiesOfNestedType_ES5.types @@ -0,0 +1,35 @@ +=== tests/cases/compiler/superPropertyAccessInComputedPropertiesOfNestedType_ES5.ts === +class A { +>A : A + + foo() { return 1; } +>foo : () => number +>1 : number +} + +class B extends A { +>B : B +>A : A + + foo() { return 2; } +>foo : () => number +>2 : number + + bar() { +>bar : () => typeof (Anonymous class) + + return class { +>class { [super.foo()]() { return 100; } } : typeof (Anonymous class) + + [super.foo()]() { +>super.foo() : number +>super.foo : () => number +>super : A +>foo : () => number + + return 100; +>100 : number + } + } + } +} diff --git a/tests/baselines/reference/superPropertyAccessInComputedPropertiesOfNestedType_ES6.js b/tests/baselines/reference/superPropertyAccessInComputedPropertiesOfNestedType_ES6.js new file mode 100644 index 00000000000..825fa7682e2 --- /dev/null +++ b/tests/baselines/reference/superPropertyAccessInComputedPropertiesOfNestedType_ES6.js @@ -0,0 +1,31 @@ +//// [superPropertyAccessInComputedPropertiesOfNestedType_ES6.ts] +class A { + foo() { return 1; } +} + +class B extends A { + foo() { return 2; } + bar() { + return class { + [super.foo()]() { + return 100; + } + } + } +} + +//// [superPropertyAccessInComputedPropertiesOfNestedType_ES6.js] +class A { + foo() { return 1; } +} +class B extends A { + foo() { return 2; } + bar() { + return class { + [super.foo()]() { + return 100; + } + } + ; + } +} diff --git a/tests/baselines/reference/superPropertyAccessInComputedPropertiesOfNestedType_ES6.symbols b/tests/baselines/reference/superPropertyAccessInComputedPropertiesOfNestedType_ES6.symbols new file mode 100644 index 00000000000..12446259f32 --- /dev/null +++ b/tests/baselines/reference/superPropertyAccessInComputedPropertiesOfNestedType_ES6.symbols @@ -0,0 +1,29 @@ +=== tests/cases/compiler/superPropertyAccessInComputedPropertiesOfNestedType_ES6.ts === +class A { +>A : Symbol(A, Decl(superPropertyAccessInComputedPropertiesOfNestedType_ES6.ts, 0, 0)) + + foo() { return 1; } +>foo : Symbol(foo, Decl(superPropertyAccessInComputedPropertiesOfNestedType_ES6.ts, 0, 9)) +} + +class B extends A { +>B : Symbol(B, Decl(superPropertyAccessInComputedPropertiesOfNestedType_ES6.ts, 2, 1)) +>A : Symbol(A, Decl(superPropertyAccessInComputedPropertiesOfNestedType_ES6.ts, 0, 0)) + + foo() { return 2; } +>foo : Symbol(foo, Decl(superPropertyAccessInComputedPropertiesOfNestedType_ES6.ts, 4, 19)) + + bar() { +>bar : Symbol(bar, Decl(superPropertyAccessInComputedPropertiesOfNestedType_ES6.ts, 5, 23)) + + return class { + [super.foo()]() { +>super.foo : Symbol(A.foo, Decl(superPropertyAccessInComputedPropertiesOfNestedType_ES6.ts, 0, 9)) +>super : Symbol(A, Decl(superPropertyAccessInComputedPropertiesOfNestedType_ES6.ts, 0, 0)) +>foo : Symbol(A.foo, Decl(superPropertyAccessInComputedPropertiesOfNestedType_ES6.ts, 0, 9)) + + return 100; + } + } + } +} diff --git a/tests/baselines/reference/superPropertyAccessInComputedPropertiesOfNestedType_ES6.types b/tests/baselines/reference/superPropertyAccessInComputedPropertiesOfNestedType_ES6.types new file mode 100644 index 00000000000..817e3b73ba4 --- /dev/null +++ b/tests/baselines/reference/superPropertyAccessInComputedPropertiesOfNestedType_ES6.types @@ -0,0 +1,35 @@ +=== tests/cases/compiler/superPropertyAccessInComputedPropertiesOfNestedType_ES6.ts === +class A { +>A : A + + foo() { return 1; } +>foo : () => number +>1 : number +} + +class B extends A { +>B : B +>A : A + + foo() { return 2; } +>foo : () => number +>2 : number + + bar() { +>bar : () => typeof (Anonymous class) + + return class { +>class { [super.foo()]() { return 100; } } : typeof (Anonymous class) + + [super.foo()]() { +>super.foo() : number +>super.foo : () => number +>super : A +>foo : () => number + + return 100; +>100 : number + } + } + } +} diff --git a/tests/baselines/reference/super_inside-object-literal-getters-and-setters.errors.txt b/tests/baselines/reference/super_inside-object-literal-getters-and-setters.errors.txt index 4f1faf78a78..16a66bf6fa4 100644 --- a/tests/baselines/reference/super_inside-object-literal-getters-and-setters.errors.txt +++ b/tests/baselines/reference/super_inside-object-literal-getters-and-setters.errors.txt @@ -1,10 +1,10 @@ tests/cases/compiler/super_inside-object-literal-getters-and-setters.ts(4,13): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. -tests/cases/compiler/super_inside-object-literal-getters-and-setters.ts(5,20): error TS2335: 'super' can only be referenced in a derived class. +tests/cases/compiler/super_inside-object-literal-getters-and-setters.ts(5,20): error TS2659: 'super' in members of object literal expressions is only allowed when option 'target' is 'ES2015' or higher. tests/cases/compiler/super_inside-object-literal-getters-and-setters.ts(7,13): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. -tests/cases/compiler/super_inside-object-literal-getters-and-setters.ts(8,13): error TS2335: 'super' can only be referenced in a derived class. -tests/cases/compiler/super_inside-object-literal-getters-and-setters.ts(11,20): error TS2335: 'super' can only be referenced in a derived class. +tests/cases/compiler/super_inside-object-literal-getters-and-setters.ts(8,13): error TS2659: 'super' in members of object literal expressions is only allowed when option 'target' is 'ES2015' or higher. +tests/cases/compiler/super_inside-object-literal-getters-and-setters.ts(11,20): error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. tests/cases/compiler/super_inside-object-literal-getters-and-setters.ts(20,17): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. -tests/cases/compiler/super_inside-object-literal-getters-and-setters.ts(21,24): error TS2338: 'super' property access is permitted only in a constructor, member function, or member accessor of a derived class. +tests/cases/compiler/super_inside-object-literal-getters-and-setters.ts(21,24): error TS2659: 'super' in members of object literal expressions is only allowed when option 'target' is 'ES2015' or higher. ==== tests/cases/compiler/super_inside-object-literal-getters-and-setters.ts (7 errors) ==== @@ -16,19 +16,19 @@ tests/cases/compiler/super_inside-object-literal-getters-and-setters.ts(21,24): !!! error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. return super._foo; ~~~~~ -!!! error TS2335: 'super' can only be referenced in a derived class. +!!! error TS2659: 'super' in members of object literal expressions is only allowed when option 'target' is 'ES2015' or higher. }, set foo(value: string) { ~~~ !!! error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. super._foo = value; ~~~~~ -!!! error TS2335: 'super' can only be referenced in a derived class. +!!! error TS2659: 'super' in members of object literal expressions is only allowed when option 'target' is 'ES2015' or higher. }, test: function () { return super._foo; ~~~~~ -!!! error TS2335: 'super' can only be referenced in a derived class. +!!! error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. } } } @@ -42,7 +42,7 @@ tests/cases/compiler/super_inside-object-literal-getters-and-setters.ts(21,24): !!! error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. return super.test(); ~~~~~ -!!! error TS2338: 'super' property access is permitted only in a constructor, member function, or member accessor of a derived class. +!!! error TS2659: 'super' in members of object literal expressions is only allowed when option 'target' is 'ES2015' or higher. } }; } diff --git a/tests/baselines/reference/super_inside-object-literal-getters-and-setters.js b/tests/baselines/reference/super_inside-object-literal-getters-and-setters.js index be70ee33183..db6db37ac8a 100644 --- a/tests/baselines/reference/super_inside-object-literal-getters-and-setters.js +++ b/tests/baselines/reference/super_inside-object-literal-getters-and-setters.js @@ -38,10 +38,10 @@ var ObjectLiteral; var ThisInObjectLiteral = { _foo: '1', get foo() { - return _super._foo; + return _super.prototype._foo; }, set foo(value) { - _super._foo = value; + _super.prototype._foo = value; }, test: function () { return _super._foo; @@ -62,7 +62,7 @@ var SuperObjectTest = (function (_super) { SuperObjectTest.prototype.testing = function () { var test = { get F() { - return _super.test.call(this); + return _super.prototype.test.call(this); } }; }; diff --git a/tests/cases/compiler/superInObjectLiterals_ES5.ts b/tests/cases/compiler/superInObjectLiterals_ES5.ts new file mode 100644 index 00000000000..96cdfaa5b7b --- /dev/null +++ b/tests/cases/compiler/superInObjectLiterals_ES5.ts @@ -0,0 +1,60 @@ +// @target: ES5 +var obj = { + __proto__: { + method() { + } + }, + method() { + super.method(); + }, + get prop() { + super.method(); + return 10; + }, + set prop(value) { + super.method(); + }, + p1: function () { + super.method(); + }, + p2: function f() { + super.method(); + }, + p3: () => { + super.method(); + } +}; + +class A { + method() { } +} + +class B extends A { + f() { + var obj = { + __proto__: { + method() { + } + }, + method() { + super.method(); + }, + get prop() { + super.method(); + return 10; + }, + set prop(value) { + super.method(); + }, + p1: function () { + super.method(); + }, + p2: function f() { + super.method(); + }, + p3: () => { + super.method(); + } + }; + } +} \ No newline at end of file diff --git a/tests/cases/compiler/superInObjectLiterals_ES6.ts b/tests/cases/compiler/superInObjectLiterals_ES6.ts new file mode 100644 index 00000000000..05b2853a90b --- /dev/null +++ b/tests/cases/compiler/superInObjectLiterals_ES6.ts @@ -0,0 +1,60 @@ +// @target: ES6 +var obj = { + __proto__: { + method() { + } + }, + method() { + super.method(); + }, + get prop() { + super.method(); + return 10; + }, + set prop(value) { + super.method(); + }, + p1: function () { + super.method(); + }, + p2: function f() { + super.method(); + }, + p3: () => { + super.method(); + } +}; + +class A { + method() { } +} + +class B extends A { + f() { + var obj = { + __proto__: { + method() { + } + }, + method() { + super.method(); + }, + get prop() { + super.method(); + return 10; + }, + set prop(value) { + super.method(); + }, + p1: function () { + super.method(); + }, + p2: function f() { + super.method(); + }, + p3: () => { + super.method(); + } + }; + } +} \ No newline at end of file diff --git a/tests/cases/compiler/superPropertyAccessInComputedPropertiesOfNestedType_ES5.ts b/tests/cases/compiler/superPropertyAccessInComputedPropertiesOfNestedType_ES5.ts new file mode 100644 index 00000000000..9c7d28f96a4 --- /dev/null +++ b/tests/cases/compiler/superPropertyAccessInComputedPropertiesOfNestedType_ES5.ts @@ -0,0 +1,15 @@ +// @target: ES5 +class A { + foo() { return 1; } +} + +class B extends A { + foo() { return 2; } + bar() { + return class { + [super.foo()]() { + return 100; + } + } + } +} \ No newline at end of file diff --git a/tests/cases/compiler/superPropertyAccessInComputedPropertiesOfNestedType_ES6.ts b/tests/cases/compiler/superPropertyAccessInComputedPropertiesOfNestedType_ES6.ts new file mode 100644 index 00000000000..6a8c2e1a7d6 --- /dev/null +++ b/tests/cases/compiler/superPropertyAccessInComputedPropertiesOfNestedType_ES6.ts @@ -0,0 +1,15 @@ +// @target: ES6 +class A { + foo() { return 1; } +} + +class B extends A { + foo() { return 2; } + bar() { + return class { + [super.foo()]() { + return 100; + } + } + } +} \ No newline at end of file From 0f3eb0a058cee9a858c8d17fdc74e5d1494d4e3a Mon Sep 17 00:00:00 2001 From: Yui T Date: Fri, 11 Dec 2015 19:27:24 -0800 Subject: [PATCH 27/79] Initial fix for rename for parameter property declaration --- src/compiler/binder.ts | 5 +---- src/compiler/checker.ts | 11 +++++++++++ src/compiler/types.ts | 1 + src/compiler/utilities.ts | 6 ++++++ src/services/services.ts | 11 +++++++++++ 5 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 2682a5938d1..9ce8b4f4eda 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1444,10 +1444,7 @@ namespace ts { // If this is a property-parameter, then also declare the property symbol into the // containing class. - if (node.flags & NodeFlags.AccessibilityModifier && - node.parent.kind === SyntaxKind.Constructor && - isClassLike(node.parent.parent)) { - + if (isPropertyParameterDeclaration(node)) { const classDeclaration = node.parent.parent; declareSymbol(classDeclaration.symbol.members, classDeclaration.symbol, node, SymbolFlags.Property, SymbolFlags.PropertyExcludes); } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7d4bfb43de7..57c4353baf1 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -67,6 +67,7 @@ namespace ts { // The language service will always care about the narrowed type of a symbol, because that is // the type the language says the symbol should have. getTypeOfSymbolAtLocation: getNarrowedTypeOfSymbol, + getSymbolOfParameterPropertyDeclaration, getDeclaredTypeOfSymbol, getPropertiesOfType, getPropertyOfType, @@ -427,6 +428,16 @@ namespace ts { } // return undefined if we can't find a symbol. } + + function getSymbolOfParameterPropertyDeclaration(parameter: ParameterDeclaration, parameterName: string): Symbol[] { + const constructoDeclaration = parameter.parent; + const classDeclaration = parameter.parent.parent; + + const parameterSymbol = getSymbol(constructoDeclaration.locals, parameterName, SymbolFlags.Value); + const propertySymbol = getSymbol(classDeclaration.symbol.members, parameterName, SymbolFlags.Value); + + return parameterSymbol && propertySymbol ? [parameterSymbol, propertySymbol] : undefined; + } function isBlockScopedNameDeclaredBeforeUse(declaration: Declaration, usage: Node): boolean { const declarationFile = getSourceFileOfNode(declaration); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index ff8ffa4ebd2..4c1fb2bb1cd 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1723,6 +1723,7 @@ namespace ts { getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[]; getSymbolAtLocation(node: Node): Symbol; + getSymbolOfParameterPropertyDeclaration(parameter: ParameterDeclaration, parameterName: string): Symbol[]; getShorthandAssignmentValueSymbol(location: Node): Symbol; getTypeAtLocation(node: Node): Type; typeToString(type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags): string; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index eee09fc641f..472225d31e5 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -2741,4 +2741,10 @@ namespace ts { } } } + + export function isPropertyParameterDeclaration(node: ParameterDeclaration): boolean { + // If this is a property-parameter, then also declare the property symbol into the + // containing class. + return node.flags & NodeFlags.AccessibilityModifier && node.parent.kind === SyntaxKind.Constructor && isClassLike(node.parent.parent); + } } diff --git a/src/services/services.ts b/src/services/services.ts index a9dda549ead..4f2af5c35c4 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -5967,6 +5967,15 @@ namespace ts { } } + // If the symbol.valueDeclaration is a property parameter declaration, + // we should include both parameter declaration symbol and property declaration symbol + // Parameter Declaration symbol is only visible within function scope, so the symbol is stored in contructor.locals. + // Property Declaration symbol is a member of the class, so the symbol is stored in its class Declaration.symbol.members + if (symbol.valueDeclaration && symbol.valueDeclaration.kind === SyntaxKind.Parameter && + isPropertyParameterDeclaration(symbol.valueDeclaration)) { + result = result.concat(typeChecker.getSymbolOfParameterPropertyDeclaration(symbol.valueDeclaration, symbol.name)); + } + // If this is a union property, add all the symbols from all its source symbols in all unioned types. // If the symbol is an instantiation from a another symbol (e.g. widened symbol) , add the root the list forEach(typeChecker.getRootSymbols(symbol), rootSymbol => { @@ -6036,6 +6045,8 @@ namespace ts { }); } + // If the reference + // Unwrap symbols to get to the root (e.g. transient symbols as a result of widening) // Or a union property, use its underlying unioned symbols return forEach(typeChecker.getRootSymbols(referenceSymbol), rootSymbol => { From af65e86aaa9cbc28ac9cc767d12f74864de52f28 Mon Sep 17 00:00:00 2001 From: Yui T Date: Fri, 11 Dec 2015 19:28:21 -0800 Subject: [PATCH 28/79] Add tests --- .../renameParameterPropertyDeclaration.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 tests/cases/fourslash/renameParameterPropertyDeclaration.ts diff --git a/tests/cases/fourslash/renameParameterPropertyDeclaration.ts b/tests/cases/fourslash/renameParameterPropertyDeclaration.ts new file mode 100644 index 00000000000..34d8c9ef428 --- /dev/null +++ b/tests/cases/fourslash/renameParameterPropertyDeclaration.ts @@ -0,0 +1,17 @@ +/// + +//// class Foo { +//// constructor(private privateParam: number, +//// public publicParam: string, +//// protected protectedParam: boolean) { +//// +//// let localPrivate = privateParam; +//// this.privateParam += 10; +//// +//// let localPublic = publicParam; +//// this.publicParam += " Hello!"; +//// +//// let localProtected = protectedParam; +//// this.protectedParam = !this.protectedParam; +//// } +//// } \ No newline at end of file From b00fa42dea98cdf3c9fd00923b6cd2a5ba288131 Mon Sep 17 00:00:00 2001 From: Yui T Date: Sat, 12 Dec 2015 15:52:55 -0800 Subject: [PATCH 29/79] Update tests --- ...HighlightAtParameterPropertyDeclaration.ts | 24 +++++++++++++++++++ ...indAllRefsParameterPropertyDeclaration1.ts | 18 ++++++++++++++ ...indAllRefsParameterPropertyDeclaration2.ts | 18 ++++++++++++++ ...indAllRefsParameterPropertyDeclaration3.ts | 18 ++++++++++++++ ...referenceInParameterPropertyDeclaration.ts | 24 +++++++++++++++++++ .../renameParameterPropertyDeclaration.ts | 17 ------------- .../renameParameterPropeterDeclaration1.ts | 14 +++++++++++ .../renameParameterPropeterDeclaration2.ts | 14 +++++++++++ .../renameParameterPropeterDeclaration3.ts | 14 +++++++++++ 9 files changed, 144 insertions(+), 17 deletions(-) create mode 100644 tests/cases/fourslash/documentHighlightAtParameterPropertyDeclaration.ts create mode 100644 tests/cases/fourslash/findAllRefsParameterPropertyDeclaration1.ts create mode 100644 tests/cases/fourslash/findAllRefsParameterPropertyDeclaration2.ts create mode 100644 tests/cases/fourslash/findAllRefsParameterPropertyDeclaration3.ts create mode 100644 tests/cases/fourslash/referenceInParameterPropertyDeclaration.ts delete mode 100644 tests/cases/fourslash/renameParameterPropertyDeclaration.ts create mode 100644 tests/cases/fourslash/renameParameterPropeterDeclaration1.ts create mode 100644 tests/cases/fourslash/renameParameterPropeterDeclaration2.ts create mode 100644 tests/cases/fourslash/renameParameterPropeterDeclaration3.ts diff --git a/tests/cases/fourslash/documentHighlightAtParameterPropertyDeclaration.ts b/tests/cases/fourslash/documentHighlightAtParameterPropertyDeclaration.ts new file mode 100644 index 00000000000..aeccd252fe9 --- /dev/null +++ b/tests/cases/fourslash/documentHighlightAtParameterPropertyDeclaration.ts @@ -0,0 +1,24 @@ +/// + +// @Filename: file1.ts +//// class Foo { +//// constructor(private /*0*/privateParam: number, +//// public /*1*/publicParam: string, +//// protected /*2*/protectedParam: boolean) { +//// +//// let localPrivate = /*3*/privateParam; +//// this./*4*/privateParam += 10; +//// +//// let localPublic = /*5*/publicParam; +//// this./*6*/publicParam += " Hello!"; +//// +//// let localProtected = /*7*/protectedParam; +//// this./*8*/protectedParam = false; +//// } +//// } + +let markers = test.markers() +for (let marker of markers) { + goTo.position(marker.position); + verify.documentHighlightsAtPositionCount(3, ["file1.ts"]); +} \ No newline at end of file diff --git a/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration1.ts b/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration1.ts new file mode 100644 index 00000000000..d0854262828 --- /dev/null +++ b/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration1.ts @@ -0,0 +1,18 @@ +/// + +//// class Foo { +//// constructor(private |privateParam|: number) { +//// let localPrivate = |privateParam|; +//// this.|privateParam| += 10; +//// } +//// } + +let ranges = test.ranges(); +for (let range of ranges) { + goTo.position(range.start); + + verify.referencesCountIs(ranges.length); + for (let expectedRange of ranges) { + verify.referencesAtPositionContains(expectedRange); + } +} \ No newline at end of file diff --git a/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration2.ts b/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration2.ts new file mode 100644 index 00000000000..7e59567364a --- /dev/null +++ b/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration2.ts @@ -0,0 +1,18 @@ +/// + +//// class Foo { +//// constructor(public |publicParam|: number) { +//// let localPublic = |publicParam|; +//// this.|publicParam| += 10; +//// } +//// } + +let ranges = test.ranges(); +for (let range of ranges) { + goTo.position(range.start); + + verify.referencesCountIs(ranges.length); + for (let expectedRange of ranges) { + verify.referencesAtPositionContains(expectedRange); + } +} \ No newline at end of file diff --git a/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration3.ts b/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration3.ts new file mode 100644 index 00000000000..2d78e9793f7 --- /dev/null +++ b/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration3.ts @@ -0,0 +1,18 @@ +/// + +//// class Foo { +//// constructor(protected |protectedParam|: number) { +//// let localProtected = |protectedParam|; +//// this.|protectedParam| += 10; +//// } +//// } + +let ranges = test.ranges(); +for (let range of ranges) { + goTo.position(range.start); + + verify.referencesCountIs(ranges.length); + for (let expectedRange of ranges) { + verify.referencesAtPositionContains(expectedRange); + } +} \ No newline at end of file diff --git a/tests/cases/fourslash/referenceInParameterPropertyDeclaration.ts b/tests/cases/fourslash/referenceInParameterPropertyDeclaration.ts new file mode 100644 index 00000000000..4e86e7a4915 --- /dev/null +++ b/tests/cases/fourslash/referenceInParameterPropertyDeclaration.ts @@ -0,0 +1,24 @@ +/// + +// @Filename: file1.ts +//// class Foo { +//// constructor(private /*0*/privateParam: number, +//// public /*1*/publicParam: string, +//// protected /*2*/protectedParam: boolean) { +//// +//// let localPrivate = /*3*/privateParam; +//// this./*4*/privateParam += 10; +//// +//// let localPublic = /*5*/publicParam; +//// this./*6*/publicParam += " Hello!"; +//// +//// let localProtected = /*7*/protectedParam; +//// this./*8*/protectedParam = false; +//// } +//// } + +let markers = test.markers() +for (let marker of markers) { + goTo.position(marker.position); + verify.referencesCountIs(3); +} \ No newline at end of file diff --git a/tests/cases/fourslash/renameParameterPropertyDeclaration.ts b/tests/cases/fourslash/renameParameterPropertyDeclaration.ts deleted file mode 100644 index 34d8c9ef428..00000000000 --- a/tests/cases/fourslash/renameParameterPropertyDeclaration.ts +++ /dev/null @@ -1,17 +0,0 @@ -/// - -//// class Foo { -//// constructor(private privateParam: number, -//// public publicParam: string, -//// protected protectedParam: boolean) { -//// -//// let localPrivate = privateParam; -//// this.privateParam += 10; -//// -//// let localPublic = publicParam; -//// this.publicParam += " Hello!"; -//// -//// let localProtected = protectedParam; -//// this.protectedParam = !this.protectedParam; -//// } -//// } \ No newline at end of file diff --git a/tests/cases/fourslash/renameParameterPropeterDeclaration1.ts b/tests/cases/fourslash/renameParameterPropeterDeclaration1.ts new file mode 100644 index 00000000000..1faed546d91 --- /dev/null +++ b/tests/cases/fourslash/renameParameterPropeterDeclaration1.ts @@ -0,0 +1,14 @@ +/// + +//// class Foo { +//// constructor(private |privateParam|: number) { +//// let localPrivate = |privateParam|; +//// this.|privateParam| += 10; +//// } +//// } + +let ranges = test.ranges() +for (let range of ranges) { + goTo.position(range.start); + verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); +} \ No newline at end of file diff --git a/tests/cases/fourslash/renameParameterPropeterDeclaration2.ts b/tests/cases/fourslash/renameParameterPropeterDeclaration2.ts new file mode 100644 index 00000000000..e8eec5d3a0a --- /dev/null +++ b/tests/cases/fourslash/renameParameterPropeterDeclaration2.ts @@ -0,0 +1,14 @@ +/// + +//// class Foo { +//// constructor(public |publicParam|: number) { +//// let publicParam = |publicParam|; +//// this.|publicParam| += 10; +//// } +//// } + +let ranges = test.ranges() +for (let range of ranges) { + goTo.position(range.start); + verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); +} \ No newline at end of file diff --git a/tests/cases/fourslash/renameParameterPropeterDeclaration3.ts b/tests/cases/fourslash/renameParameterPropeterDeclaration3.ts new file mode 100644 index 00000000000..44f4cf68858 --- /dev/null +++ b/tests/cases/fourslash/renameParameterPropeterDeclaration3.ts @@ -0,0 +1,14 @@ +/// + +//// class Foo { +//// constructor(protected |protectedParam|: number) { +//// let protectedParam = |protectedParam|; +//// this.|protectedParam| += 10; +//// } +//// } + +let ranges = test.ranges() +for (let range of ranges) { + goTo.position(range.start); + verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); +} \ No newline at end of file From 94c3d27f411b4f72d8f6adb422e98d38324b23e6 Mon Sep 17 00:00:00 2001 From: Yui T Date: Sat, 12 Dec 2015 15:53:04 -0800 Subject: [PATCH 30/79] Fix linting --- src/compiler/checker.ts | 6 +++--- src/compiler/utilities.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 57c4353baf1..1646b51702a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -428,14 +428,14 @@ namespace ts { } // return undefined if we can't find a symbol. } - + function getSymbolOfParameterPropertyDeclaration(parameter: ParameterDeclaration, parameterName: string): Symbol[] { const constructoDeclaration = parameter.parent; const classDeclaration = parameter.parent.parent; - + const parameterSymbol = getSymbol(constructoDeclaration.locals, parameterName, SymbolFlags.Value); const propertySymbol = getSymbol(classDeclaration.symbol.members, parameterName, SymbolFlags.Value); - + return parameterSymbol && propertySymbol ? [parameterSymbol, propertySymbol] : undefined; } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 472225d31e5..566a578cedf 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -2741,7 +2741,7 @@ namespace ts { } } } - + export function isPropertyParameterDeclaration(node: ParameterDeclaration): boolean { // If this is a property-parameter, then also declare the property symbol into the // containing class. From b44f6e47d653419b1f47baf6734bd0942a3f15d0 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 12 Dec 2015 15:56:43 -0800 Subject: [PATCH 31/79] Simplify deferred checking of function, class, and accessor bodies. --- src/compiler/checker.ts | 155 +++++++++++----------------------------- 1 file changed, 40 insertions(+), 115 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ea23255472d..e4cf101946a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -161,6 +161,8 @@ namespace ts { let jsxElementClassType: Type; + let deferredNodes: Node[]; + const tupleTypes: Map = {}; const unionTypes: Map = {}; const intersectionTypes: Map = {}; @@ -10123,6 +10125,7 @@ namespace ts { if (!contextChecked) { checkSignatureDeclaration(node); + checkNodeDeferred(node); } } } @@ -10135,7 +10138,7 @@ namespace ts { return type; } - function checkFunctionExpressionOrObjectLiteralMethodBody(node: ArrowFunction | FunctionExpression | MethodDeclaration) { + function checkFunctionExpressionOrObjectLiteralMethodDeferred(node: ArrowFunction | FunctionExpression | MethodDeclaration) { Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isObjectLiteralMethod(node)); const isAsync = isAsyncFunctionLike(node); @@ -10178,8 +10181,6 @@ namespace ts { checkTypeAssignableTo(exprType, returnOrPromisedType, node.body); } } - - checkFunctionAndClassExpressionBodies(node.body); } } } @@ -11428,13 +11429,13 @@ namespace ts { if (node.parent.kind !== SyntaxKind.ObjectLiteralExpression) { checkSourceElement(node.body); } + else { + checkNodeDeferred(node); + } } - function checkObjectLiteralAccessorBody(node: AccessorDeclaration) { - if (node.body) { - checkSourceElement(node.body); - checkFunctionAndClassExpressionBodies(node.body); - } + function checkAccessorDeferred(node: AccessorDeclaration) { + checkSourceElement(node.body); } function checkMissingDeclaration(node: Node) { @@ -12373,11 +12374,7 @@ namespace ts { if (node.kind === SyntaxKind.Block) { checkGrammarStatementInAmbientContext(node); } - forEach(node.statements, checkSourceElement); - if (isFunctionBlock(node) || node.kind === SyntaxKind.ModuleBlock) { - checkFunctionAndClassExpressionBodies(node); - } } function checkCollisionWithArgumentsInGeneratedCode(node: SignatureDeclaration) { @@ -13406,15 +13403,19 @@ namespace ts { function checkClassExpression(node: ClassExpression): Type { checkClassLikeDeclaration(node); + checkNodeDeferred(node); return getTypeOfSymbol(getSymbolOfNode(node)); } + function checkClassExpressionDeferred(node: ClassExpression) { + forEach(node.members, checkSourceElement); + } + function checkClassDeclaration(node: ClassDeclaration) { if (!node.name && !(node.flags & NodeFlags.Default)) { grammarErrorOnFirstToken(node, Diagnostics.A_class_declaration_without_the_default_modifier_must_have_a_name); } checkClassLikeDeclaration(node); - forEach(node.members, checkSourceElement); } @@ -14478,107 +14479,29 @@ namespace ts { // Here, performing a full type check of the body of the function expression whilst in the process of // determining the type of foo would cause foo to be given type any because of the recursive reference. // Delaying the type check of the body ensures foo has been assigned a type. - function checkFunctionAndClassExpressionBodies(node: Node): void { - switch (node.kind) { - case SyntaxKind.FunctionExpression: - case SyntaxKind.ArrowFunction: - forEach((node).parameters, checkFunctionAndClassExpressionBodies); - checkFunctionExpressionOrObjectLiteralMethodBody(node); - break; - case SyntaxKind.ClassExpression: - forEach((node).members, checkSourceElement); - forEachChild(node, checkFunctionAndClassExpressionBodies); - break; - case SyntaxKind.MethodDeclaration: - case SyntaxKind.MethodSignature: - forEach(node.decorators, checkFunctionAndClassExpressionBodies); - forEach((node).parameters, checkFunctionAndClassExpressionBodies); - if (isObjectLiteralMethod(node)) { - checkFunctionExpressionOrObjectLiteralMethodBody(node); - } - break; - case SyntaxKind.Constructor: - case SyntaxKind.FunctionDeclaration: - forEach((node).parameters, checkFunctionAndClassExpressionBodies); - break; - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - forEach((node).parameters, checkFunctionAndClassExpressionBodies); - if (node.parent.kind === SyntaxKind.ObjectLiteralExpression) { - checkObjectLiteralAccessorBody(node); - } - break; - case SyntaxKind.WithStatement: - checkFunctionAndClassExpressionBodies((node).expression); - break; - case SyntaxKind.Decorator: - case SyntaxKind.Parameter: - case SyntaxKind.PropertyDeclaration: - case SyntaxKind.PropertySignature: - case SyntaxKind.ObjectBindingPattern: - case SyntaxKind.ArrayBindingPattern: - case SyntaxKind.BindingElement: - case SyntaxKind.ArrayLiteralExpression: - case SyntaxKind.ObjectLiteralExpression: - case SyntaxKind.PropertyAssignment: - case SyntaxKind.PropertyAccessExpression: - case SyntaxKind.ElementAccessExpression: - case SyntaxKind.CallExpression: - case SyntaxKind.NewExpression: - case SyntaxKind.TaggedTemplateExpression: - case SyntaxKind.TemplateExpression: - case SyntaxKind.TemplateSpan: - case SyntaxKind.TypeAssertionExpression: - case SyntaxKind.AsExpression: - case SyntaxKind.ParenthesizedExpression: - case SyntaxKind.TypeOfExpression: - case SyntaxKind.VoidExpression: - case SyntaxKind.AwaitExpression: - case SyntaxKind.DeleteExpression: - case SyntaxKind.PrefixUnaryExpression: - case SyntaxKind.PostfixUnaryExpression: - case SyntaxKind.BinaryExpression: - case SyntaxKind.ConditionalExpression: - case SyntaxKind.SpreadElementExpression: - case SyntaxKind.YieldExpression: - case SyntaxKind.Block: - case SyntaxKind.ModuleBlock: - case SyntaxKind.VariableStatement: - case SyntaxKind.ExpressionStatement: - case SyntaxKind.IfStatement: - case SyntaxKind.DoStatement: - case SyntaxKind.WhileStatement: - case SyntaxKind.ForStatement: - case SyntaxKind.ForInStatement: - case SyntaxKind.ForOfStatement: - case SyntaxKind.ContinueStatement: - case SyntaxKind.BreakStatement: - case SyntaxKind.ReturnStatement: - case SyntaxKind.SwitchStatement: - case SyntaxKind.CaseBlock: - case SyntaxKind.CaseClause: - case SyntaxKind.DefaultClause: - case SyntaxKind.LabeledStatement: - case SyntaxKind.ThrowStatement: - case SyntaxKind.TryStatement: - case SyntaxKind.CatchClause: - case SyntaxKind.VariableDeclaration: - case SyntaxKind.VariableDeclarationList: - case SyntaxKind.ClassDeclaration: - case SyntaxKind.HeritageClause: - case SyntaxKind.ExpressionWithTypeArguments: - case SyntaxKind.EnumDeclaration: - case SyntaxKind.EnumMember: - case SyntaxKind.ExportAssignment: - case SyntaxKind.SourceFile: - case SyntaxKind.JsxExpression: - case SyntaxKind.JsxElement: - case SyntaxKind.JsxSelfClosingElement: - case SyntaxKind.JsxAttribute: - case SyntaxKind.JsxSpreadAttribute: - case SyntaxKind.JsxOpeningElement: - forEachChild(node, checkFunctionAndClassExpressionBodies); - break; + function checkNodeDeferred(node: Node) { + if (deferredNodes) { + deferredNodes.push(node); + } + } + + function checkDeferredNodes() { + for (const node of deferredNodes) { + switch (node.kind) { + case SyntaxKind.FunctionExpression: + case SyntaxKind.ArrowFunction: + case SyntaxKind.MethodDeclaration: + case SyntaxKind.MethodSignature: + checkFunctionExpressionOrObjectLiteralMethodDeferred(node); + break; + case SyntaxKind.GetAccessor: + case SyntaxKind.SetAccessor: + checkAccessorDeferred(node); + break; + case SyntaxKind.ClassExpression: + checkClassExpressionDeferred(node); + break; + } } } @@ -14613,8 +14536,10 @@ namespace ts { emitAwaiter = false; potentialThisCollisions.length = 0; + deferredNodes = []; forEach(node.statements, checkSourceElement); - checkFunctionAndClassExpressionBodies(node); + checkDeferredNodes(); + deferredNodes = undefined; if (isExternalOrCommonJsModule(node)) { checkExternalModuleExports(node); From 91b93439f12a911bc83fbc3399a9a739a619721a Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 12 Dec 2015 15:57:39 -0800 Subject: [PATCH 32/79] Accepting new baselines --- ...nePropertyAccessAndArrowFunctionIndent1.errors.txt | 11 +---------- .../multiLinePropertyAccessAndArrowFunctionIndent1.js | 3 +-- ...atementIsNotAMemberVariableDeclaration1.errors.txt | 5 +---- 3 files changed, 3 insertions(+), 16 deletions(-) diff --git a/tests/baselines/reference/multiLinePropertyAccessAndArrowFunctionIndent1.errors.txt b/tests/baselines/reference/multiLinePropertyAccessAndArrowFunctionIndent1.errors.txt index abf11dc9dba..48a1da7d22c 100644 --- a/tests/baselines/reference/multiLinePropertyAccessAndArrowFunctionIndent1.errors.txt +++ b/tests/baselines/reference/multiLinePropertyAccessAndArrowFunctionIndent1.errors.txt @@ -1,20 +1,11 @@ tests/cases/compiler/multiLinePropertyAccessAndArrowFunctionIndent1.ts(1,1): error TS1108: A 'return' statement can only be used within a function body. -tests/cases/compiler/multiLinePropertyAccessAndArrowFunctionIndent1.ts(1,18): error TS2304: Cannot find name 'role'. -tests/cases/compiler/multiLinePropertyAccessAndArrowFunctionIndent1.ts(2,18): error TS2304: Cannot find name 'Role'. -tests/cases/compiler/multiLinePropertyAccessAndArrowFunctionIndent1.ts(4,26): error TS2503: Cannot find namespace 'ng'. -==== tests/cases/compiler/multiLinePropertyAccessAndArrowFunctionIndent1.ts (4 errors) ==== +==== tests/cases/compiler/multiLinePropertyAccessAndArrowFunctionIndent1.ts (1 errors) ==== return this.edit(role) ~~~~~~ !!! error TS1108: A 'return' statement can only be used within a function body. - ~~~~ -!!! error TS2304: Cannot find name 'role'. .then((role: Role) => - ~~~~ -!!! error TS2304: Cannot find name 'Role'. this.roleService.add(role) .then((data: ng.IHttpPromiseCallbackArg) => data.data)); - ~~ -!!! error TS2503: Cannot find namespace 'ng'. \ No newline at end of file diff --git a/tests/baselines/reference/multiLinePropertyAccessAndArrowFunctionIndent1.js b/tests/baselines/reference/multiLinePropertyAccessAndArrowFunctionIndent1.js index 2ada9f1bb52..4821f1fe69c 100644 --- a/tests/baselines/reference/multiLinePropertyAccessAndArrowFunctionIndent1.js +++ b/tests/baselines/reference/multiLinePropertyAccessAndArrowFunctionIndent1.js @@ -6,9 +6,8 @@ return this.edit(role) //// [multiLinePropertyAccessAndArrowFunctionIndent1.js] -var _this = this; return this.edit(role) .then(function (role) { - return _this.roleService.add(role) + return this.roleService.add(role) .then(function (data) { return data.data; }); }); diff --git a/tests/baselines/reference/parserStatementIsNotAMemberVariableDeclaration1.errors.txt b/tests/baselines/reference/parserStatementIsNotAMemberVariableDeclaration1.errors.txt index 72cfee58e54..0532fd28d63 100644 --- a/tests/baselines/reference/parserStatementIsNotAMemberVariableDeclaration1.errors.txt +++ b/tests/baselines/reference/parserStatementIsNotAMemberVariableDeclaration1.errors.txt @@ -1,8 +1,7 @@ tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserStatementIsNotAMemberVariableDeclaration1.ts(1,1): error TS1108: A 'return' statement can only be used within a function body. -tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserStatementIsNotAMemberVariableDeclaration1.ts(6,5): error TS2304: Cannot find name 'private'. -==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserStatementIsNotAMemberVariableDeclaration1.ts (2 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserStatementIsNotAMemberVariableDeclaration1.ts (1 errors) ==== return { ~~~~~~ !!! error TS1108: A 'return' statement can only be used within a function body. @@ -11,8 +10,6 @@ tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserStatementIsNotAMe // 'private' should not be considered a member variable here. private[key] = value; - ~~~~~~~ -!!! error TS2304: Cannot find name 'private'. } From f138953d887f8e5fd37af81e66adab662039bdba Mon Sep 17 00:00:00 2001 From: Yui T Date: Sat, 12 Dec 2015 16:13:30 -0800 Subject: [PATCH 33/79] Fix comment --- src/compiler/checker.ts | 8 +++++++- src/services/services.ts | 2 -- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 31665734167..a2338c5ba5b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -429,7 +429,13 @@ namespace ts { // return undefined if we can't find a symbol. } - function getSymbolOfParameterPropertyDeclaration(parameter: ParameterDeclaration, parameterName: string): Symbol[] { + /** + * Get symbols that represent parameter-property-declaration as parameter and as property declaration + * @param parameter a parameterDeclaration node + * @param parameterName a name of the parameter to get the symbols for. + * @return a tuple of two symbols + */ + function getSymbolOfParameterPropertyDeclaration(parameter: ParameterDeclaration, parameterName: string): [Symbol, Symbol] { const constructoDeclaration = parameter.parent; const classDeclaration = parameter.parent.parent; diff --git a/src/services/services.ts b/src/services/services.ts index 4f2af5c35c4..6728c0d5ebc 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -6045,8 +6045,6 @@ namespace ts { }); } - // If the reference - // Unwrap symbols to get to the root (e.g. transient symbols as a result of widening) // Or a union property, use its underlying unioned symbols return forEach(typeChecker.getRootSymbols(referenceSymbol), rootSymbol => { From 99722e442cb2e0bd018f133cad04afd29cc8c756 Mon Sep 17 00:00:00 2001 From: Yui T Date: Sat, 12 Dec 2015 16:38:11 -0800 Subject: [PATCH 34/79] Add tests for binding pattern in parameter property declaration --- ...ghlightAtParameterPropertyDeclaration1.ts} | 0 ...ighlightAtParameterPropertyDeclaration2.ts | 24 +++++++++++++++++++ ...ighlightAtParameterPropertyDeclaration3.ts | 24 +++++++++++++++++++ ...=> renameParameterPropertyDeclaration1.ts} | 0 ...=> renameParameterPropertyDeclaration2.ts} | 0 ...=> renameParameterPropertyDeclaration3.ts} | 0 .../renameParameterPropertyDeclaration4.ts | 13 ++++++++++ .../renameParameterPropertyDeclaration5.ts | 13 ++++++++++ 8 files changed, 74 insertions(+) rename tests/cases/fourslash/{documentHighlightAtParameterPropertyDeclaration.ts => documentHighlightAtParameterPropertyDeclaration1.ts} (100%) create mode 100644 tests/cases/fourslash/documentHighlightAtParameterPropertyDeclaration2.ts create mode 100644 tests/cases/fourslash/documentHighlightAtParameterPropertyDeclaration3.ts rename tests/cases/fourslash/{renameParameterPropeterDeclaration1.ts => renameParameterPropertyDeclaration1.ts} (100%) rename tests/cases/fourslash/{renameParameterPropeterDeclaration2.ts => renameParameterPropertyDeclaration2.ts} (100%) rename tests/cases/fourslash/{renameParameterPropeterDeclaration3.ts => renameParameterPropertyDeclaration3.ts} (100%) create mode 100644 tests/cases/fourslash/renameParameterPropertyDeclaration4.ts create mode 100644 tests/cases/fourslash/renameParameterPropertyDeclaration5.ts diff --git a/tests/cases/fourslash/documentHighlightAtParameterPropertyDeclaration.ts b/tests/cases/fourslash/documentHighlightAtParameterPropertyDeclaration1.ts similarity index 100% rename from tests/cases/fourslash/documentHighlightAtParameterPropertyDeclaration.ts rename to tests/cases/fourslash/documentHighlightAtParameterPropertyDeclaration1.ts diff --git a/tests/cases/fourslash/documentHighlightAtParameterPropertyDeclaration2.ts b/tests/cases/fourslash/documentHighlightAtParameterPropertyDeclaration2.ts new file mode 100644 index 00000000000..2658dd56371 --- /dev/null +++ b/tests/cases/fourslash/documentHighlightAtParameterPropertyDeclaration2.ts @@ -0,0 +1,24 @@ +/// + +// @Filename: file1.ts +//// class Foo { +//// constructor(private {/*0*/privateParam}: number, +//// public {/*1*/publicParam}: string, +//// protected {/*2*/protectedParam}: boolean) { +//// +//// let localPrivate = /*3*/privateParam; +//// this.privateParam += 10; // this is not valid syntax +//// +//// let localPublic = /*4*/publicParam; +//// this.publicParam += " Hello!"; // this is not valid syntax +//// +//// let localProtected = /*5*/protectedParam; +//// this.protectedParam = false; // this is not valid syntax +//// } +//// } + +let markers = test.markers() +for (let marker of markers) { + goTo.position(marker.position); + verify.documentHighlightsAtPositionCount(3, ["file1.ts"]); +} \ No newline at end of file diff --git a/tests/cases/fourslash/documentHighlightAtParameterPropertyDeclaration3.ts b/tests/cases/fourslash/documentHighlightAtParameterPropertyDeclaration3.ts new file mode 100644 index 00000000000..958e3bb45c9 --- /dev/null +++ b/tests/cases/fourslash/documentHighlightAtParameterPropertyDeclaration3.ts @@ -0,0 +1,24 @@ +/// + +// @Filename: file1.ts +//// class Foo { +//// constructor(private [/*0*/privateParam]: number, +//// public [/*1*/publicParam]: string, +//// protected [/*2*/protectedParam]: boolean) { +//// +//// let localPrivate = /*3*/privateParam; +//// this.privateParam += 10; // this is not valid syntax +//// +//// let localPublic = /*4*/publicParam; +//// this.publicParam += " Hello!"; // this is not valid syntax +//// +//// let localProtected = /*5*/protectedParam; +//// this.protectedParam = false; // this is not valid syntax +//// } +//// } + +let markers = test.markers() +for (let marker of markers) { + goTo.position(marker.position); + verify.documentHighlightsAtPositionCount(2, ["file1.ts"]); +} \ No newline at end of file diff --git a/tests/cases/fourslash/renameParameterPropeterDeclaration1.ts b/tests/cases/fourslash/renameParameterPropertyDeclaration1.ts similarity index 100% rename from tests/cases/fourslash/renameParameterPropeterDeclaration1.ts rename to tests/cases/fourslash/renameParameterPropertyDeclaration1.ts diff --git a/tests/cases/fourslash/renameParameterPropeterDeclaration2.ts b/tests/cases/fourslash/renameParameterPropertyDeclaration2.ts similarity index 100% rename from tests/cases/fourslash/renameParameterPropeterDeclaration2.ts rename to tests/cases/fourslash/renameParameterPropertyDeclaration2.ts diff --git a/tests/cases/fourslash/renameParameterPropeterDeclaration3.ts b/tests/cases/fourslash/renameParameterPropertyDeclaration3.ts similarity index 100% rename from tests/cases/fourslash/renameParameterPropeterDeclaration3.ts rename to tests/cases/fourslash/renameParameterPropertyDeclaration3.ts diff --git a/tests/cases/fourslash/renameParameterPropertyDeclaration4.ts b/tests/cases/fourslash/renameParameterPropertyDeclaration4.ts new file mode 100644 index 00000000000..21ba7da4141 --- /dev/null +++ b/tests/cases/fourslash/renameParameterPropertyDeclaration4.ts @@ -0,0 +1,13 @@ +/// + +//// class Foo { +//// constructor(protected { |protectedParam| }) { +//// let myProtectedParam = |protectedParam|; +//// } +//// } + +let ranges = test.ranges() +for (let range of ranges) { + goTo.position(range.start); + verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); +} \ No newline at end of file diff --git a/tests/cases/fourslash/renameParameterPropertyDeclaration5.ts b/tests/cases/fourslash/renameParameterPropertyDeclaration5.ts new file mode 100644 index 00000000000..a4bc00b697b --- /dev/null +++ b/tests/cases/fourslash/renameParameterPropertyDeclaration5.ts @@ -0,0 +1,13 @@ +/// + +//// class Foo { +//// constructor(protected [ |protectedParam| ]) { +//// let myProtectedParam = |protectedParam|; +//// } +//// } + +let ranges = test.ranges() +for (let range of ranges) { + goTo.position(range.start); + verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); +} \ No newline at end of file From b65c5779a2e543c26849e4eb07d09fc849e07c87 Mon Sep 17 00:00:00 2001 From: vladima Date: Sat, 12 Dec 2015 23:07:18 -0800 Subject: [PATCH 35/79] addressed PR feedback --- src/compiler/checker.ts | 26 ++++++++++--------- .../computedPropertyNames24_ES5.errors.txt | 4 +-- .../computedPropertyNames24_ES6.errors.txt | 4 +-- .../computedPropertyNames26_ES5.errors.txt | 4 +-- .../computedPropertyNames26_ES6.errors.txt | 4 +-- .../computedPropertyNames27_ES5.errors.txt | 4 +-- .../computedPropertyNames27_ES6.errors.txt | 4 +-- .../computedPropertyNames30_ES5.errors.txt | 4 +-- .../computedPropertyNames30_ES6.errors.txt | 4 +-- 9 files changed, 30 insertions(+), 28 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6af7ddba419..2dd567cbe90 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7053,24 +7053,26 @@ namespace ts { let nodeCheckFlag: NodeCheckFlags = 0; if (!canUseSuperExpression) { - if (isCallExpression) { + // issue more specific error if super is used in computed property name + // class A { foo() { return "1" }} + // class B { + // [super.foo()]() {} + // } + let current = node; + while (current && current !== container && current.kind !== SyntaxKind.ComputedPropertyName) { + current = current.parent; + } + if (current && current.kind === SyntaxKind.ComputedPropertyName) { + error(node, Diagnostics.super_cannot_be_referenced_in_a_computed_property_name); + } + else if (isCallExpression) { error(node, Diagnostics.Super_calls_are_not_permitted_outside_constructors_or_in_nested_functions_inside_constructors); } else if (!container || !container.parent || !(isClassLike(container.parent) || container.parent.kind === SyntaxKind.ObjectLiteralExpression)) { error(node, Diagnostics.super_can_only_be_referenced_in_members_of_derived_classes_or_object_literal_expressions); } else { - // issue more specific error if super is used in computed property name - let current = node; - while (current && current !== container && current.kind !== SyntaxKind.ComputedPropertyName) { - current = current.parent; - } - if (current && current.kind === SyntaxKind.ComputedPropertyName) { - error(node, Diagnostics.super_cannot_be_referenced_in_a_computed_property_name); - } - else { - error(node, Diagnostics.super_property_access_is_permitted_only_in_a_constructor_member_function_or_member_accessor_of_a_derived_class); - } + error(node, Diagnostics.super_property_access_is_permitted_only_in_a_constructor_member_function_or_member_accessor_of_a_derived_class); } return unknownType; } diff --git a/tests/baselines/reference/computedPropertyNames24_ES5.errors.txt b/tests/baselines/reference/computedPropertyNames24_ES5.errors.txt index e06373fb1e3..121b39450a6 100644 --- a/tests/baselines/reference/computedPropertyNames24_ES5.errors.txt +++ b/tests/baselines/reference/computedPropertyNames24_ES5.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/es6/computedProperties/computedPropertyNames24_ES5.ts(7,6): error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. +tests/cases/conformance/es6/computedProperties/computedPropertyNames24_ES5.ts(7,6): error TS2466: 'super' cannot be referenced in a computed property name. ==== tests/cases/conformance/es6/computedProperties/computedPropertyNames24_ES5.ts (1 errors) ==== @@ -10,5 +10,5 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames24_ES5.ts(7, class C extends Base { [super.bar()]() { } ~~~~~ -!!! error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. +!!! error TS2466: 'super' cannot be referenced in a computed property name. } \ No newline at end of file diff --git a/tests/baselines/reference/computedPropertyNames24_ES6.errors.txt b/tests/baselines/reference/computedPropertyNames24_ES6.errors.txt index 331723afe34..cab0ba6a85c 100644 --- a/tests/baselines/reference/computedPropertyNames24_ES6.errors.txt +++ b/tests/baselines/reference/computedPropertyNames24_ES6.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/es6/computedProperties/computedPropertyNames24_ES6.ts(9,6): error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. +tests/cases/conformance/es6/computedProperties/computedPropertyNames24_ES6.ts(9,6): error TS2466: 'super' cannot be referenced in a computed property name. ==== tests/cases/conformance/es6/computedProperties/computedPropertyNames24_ES6.ts (1 errors) ==== @@ -12,5 +12,5 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames24_ES6.ts(9, // use of super in static properties initializers. [super.bar()]() { } ~~~~~ -!!! error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. +!!! error TS2466: 'super' cannot be referenced in a computed property name. } \ No newline at end of file diff --git a/tests/baselines/reference/computedPropertyNames26_ES5.errors.txt b/tests/baselines/reference/computedPropertyNames26_ES5.errors.txt index c8e24abfa9d..e7039712734 100644 --- a/tests/baselines/reference/computedPropertyNames26_ES5.errors.txt +++ b/tests/baselines/reference/computedPropertyNames26_ES5.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/es6/computedProperties/computedPropertyNames26_ES5.ts(8,12): error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. +tests/cases/conformance/es6/computedProperties/computedPropertyNames26_ES5.ts(8,12): error TS2466: 'super' cannot be referenced in a computed property name. ==== tests/cases/conformance/es6/computedProperties/computedPropertyNames26_ES5.ts (1 errors) ==== @@ -11,6 +11,6 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames26_ES5.ts(8, [ { [super.bar()]: 1 }[0] ~~~~~ -!!! error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. +!!! error TS2466: 'super' cannot be referenced in a computed property name. ]() { } } \ No newline at end of file diff --git a/tests/baselines/reference/computedPropertyNames26_ES6.errors.txt b/tests/baselines/reference/computedPropertyNames26_ES6.errors.txt index ec20ed57144..d7e2b5ce7c5 100644 --- a/tests/baselines/reference/computedPropertyNames26_ES6.errors.txt +++ b/tests/baselines/reference/computedPropertyNames26_ES6.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/es6/computedProperties/computedPropertyNames26_ES6.ts(10,12): error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. +tests/cases/conformance/es6/computedProperties/computedPropertyNames26_ES6.ts(10,12): error TS2466: 'super' cannot be referenced in a computed property name. ==== tests/cases/conformance/es6/computedProperties/computedPropertyNames26_ES6.ts (1 errors) ==== @@ -13,6 +13,6 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames26_ES6.ts(10 [ { [super.bar()]: 1 }[0] ~~~~~ -!!! error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. +!!! error TS2466: 'super' cannot be referenced in a computed property name. ]() { } } \ No newline at end of file diff --git a/tests/baselines/reference/computedPropertyNames27_ES5.errors.txt b/tests/baselines/reference/computedPropertyNames27_ES5.errors.txt index 97964d48176..1fbc7b37543 100644 --- a/tests/baselines/reference/computedPropertyNames27_ES5.errors.txt +++ b/tests/baselines/reference/computedPropertyNames27_ES5.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/es6/computedProperties/computedPropertyNames27_ES5.ts(4,7): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors. +tests/cases/conformance/es6/computedProperties/computedPropertyNames27_ES5.ts(4,7): error TS2466: 'super' cannot be referenced in a computed property name. ==== tests/cases/conformance/es6/computedProperties/computedPropertyNames27_ES5.ts (1 errors) ==== @@ -7,5 +7,5 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames27_ES5.ts(4, class C extends Base { [(super(), "prop")]() { } ~~~~~ -!!! error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors. +!!! error TS2466: 'super' cannot be referenced in a computed property name. } \ No newline at end of file diff --git a/tests/baselines/reference/computedPropertyNames27_ES6.errors.txt b/tests/baselines/reference/computedPropertyNames27_ES6.errors.txt index 30e1ce5b14f..edf84201647 100644 --- a/tests/baselines/reference/computedPropertyNames27_ES6.errors.txt +++ b/tests/baselines/reference/computedPropertyNames27_ES6.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/es6/computedProperties/computedPropertyNames27_ES6.ts(4,7): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors. +tests/cases/conformance/es6/computedProperties/computedPropertyNames27_ES6.ts(4,7): error TS2466: 'super' cannot be referenced in a computed property name. ==== tests/cases/conformance/es6/computedProperties/computedPropertyNames27_ES6.ts (1 errors) ==== @@ -7,5 +7,5 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames27_ES6.ts(4, class C extends Base { [(super(), "prop")]() { } ~~~~~ -!!! error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors. +!!! error TS2466: 'super' cannot be referenced in a computed property name. } \ No newline at end of file diff --git a/tests/baselines/reference/computedPropertyNames30_ES5.errors.txt b/tests/baselines/reference/computedPropertyNames30_ES5.errors.txt index deb80dbcca8..e64b83f609e 100644 --- a/tests/baselines/reference/computedPropertyNames30_ES5.errors.txt +++ b/tests/baselines/reference/computedPropertyNames30_ES5.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/es6/computedProperties/computedPropertyNames30_ES5.ts(11,19): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors. +tests/cases/conformance/es6/computedProperties/computedPropertyNames30_ES5.ts(11,19): error TS2466: 'super' cannot be referenced in a computed property name. ==== tests/cases/conformance/es6/computedProperties/computedPropertyNames30_ES5.ts (1 errors) ==== @@ -14,7 +14,7 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames30_ES5.ts(11 //treatment of other similar violations. [(super(), "prop")]() { } ~~~~~ -!!! error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors. +!!! error TS2466: 'super' cannot be referenced in a computed property name. }; } } diff --git a/tests/baselines/reference/computedPropertyNames30_ES6.errors.txt b/tests/baselines/reference/computedPropertyNames30_ES6.errors.txt index b10d184f799..a5771629ac2 100644 --- a/tests/baselines/reference/computedPropertyNames30_ES6.errors.txt +++ b/tests/baselines/reference/computedPropertyNames30_ES6.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/es6/computedProperties/computedPropertyNames30_ES6.ts(11,19): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors. +tests/cases/conformance/es6/computedProperties/computedPropertyNames30_ES6.ts(11,19): error TS2466: 'super' cannot be referenced in a computed property name. ==== tests/cases/conformance/es6/computedProperties/computedPropertyNames30_ES6.ts (1 errors) ==== @@ -14,7 +14,7 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames30_ES6.ts(11 //treatment of other similar violations. [(super(), "prop")]() { } ~~~~~ -!!! error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors. +!!! error TS2466: 'super' cannot be referenced in a computed property name. }; } } From 7e71686b1a969b083ee347bdb105fc8a30da6664 Mon Sep 17 00:00:00 2001 From: Yui T Date: Mon, 14 Dec 2015 10:14:35 -0800 Subject: [PATCH 36/79] Fix broken tests --- src/compiler/binder.ts | 2 +- src/compiler/checker.ts | 4 ++-- src/compiler/types.ts | 2 +- src/compiler/utilities.ts | 4 +--- src/services/services.ts | 4 ++-- .../documentHighlightAtParameterPropertyDeclaration2.ts | 2 +- 6 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 9ce8b4f4eda..b63348bfb60 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1444,7 +1444,7 @@ namespace ts { // If this is a property-parameter, then also declare the property symbol into the // containing class. - if (isPropertyParameterDeclaration(node)) { + if (isParameterPropertyDeclaration(node)) { const classDeclaration = node.parent.parent; declareSymbol(classDeclaration.symbol.members, classDeclaration.symbol, node, SymbolFlags.Property, SymbolFlags.PropertyExcludes); } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a2338c5ba5b..9d14bb39206 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -67,7 +67,7 @@ namespace ts { // The language service will always care about the narrowed type of a symbol, because that is // the type the language says the symbol should have. getTypeOfSymbolAtLocation: getNarrowedTypeOfSymbol, - getSymbolOfParameterPropertyDeclaration, + getSymbolsOfParameterPropertyDeclaration, getDeclaredTypeOfSymbol, getPropertiesOfType, getPropertyOfType, @@ -435,7 +435,7 @@ namespace ts { * @param parameterName a name of the parameter to get the symbols for. * @return a tuple of two symbols */ - function getSymbolOfParameterPropertyDeclaration(parameter: ParameterDeclaration, parameterName: string): [Symbol, Symbol] { + function getSymbolsOfParameterPropertyDeclaration(parameter: ParameterDeclaration, parameterName: string): [Symbol, Symbol] { const constructoDeclaration = parameter.parent; const classDeclaration = parameter.parent.parent; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 4c1fb2bb1cd..ad446792f04 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1723,7 +1723,7 @@ namespace ts { getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[]; getSymbolAtLocation(node: Node): Symbol; - getSymbolOfParameterPropertyDeclaration(parameter: ParameterDeclaration, parameterName: string): Symbol[]; + getSymbolsOfParameterPropertyDeclaration(parameter: ParameterDeclaration, parameterName: string): Symbol[]; getShorthandAssignmentValueSymbol(location: Node): Symbol; getTypeAtLocation(node: Node): Type; typeToString(type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags): string; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 566a578cedf..384f27c8868 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -2742,9 +2742,7 @@ namespace ts { } } - export function isPropertyParameterDeclaration(node: ParameterDeclaration): boolean { - // If this is a property-parameter, then also declare the property symbol into the - // containing class. + export function isParameterPropertyDeclaration(node: ParameterDeclaration): boolean { return node.flags & NodeFlags.AccessibilityModifier && node.parent.kind === SyntaxKind.Constructor && isClassLike(node.parent.parent); } } diff --git a/src/services/services.ts b/src/services/services.ts index 6728c0d5ebc..8e2e4913edd 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -5972,8 +5972,8 @@ namespace ts { // Parameter Declaration symbol is only visible within function scope, so the symbol is stored in contructor.locals. // Property Declaration symbol is a member of the class, so the symbol is stored in its class Declaration.symbol.members if (symbol.valueDeclaration && symbol.valueDeclaration.kind === SyntaxKind.Parameter && - isPropertyParameterDeclaration(symbol.valueDeclaration)) { - result = result.concat(typeChecker.getSymbolOfParameterPropertyDeclaration(symbol.valueDeclaration, symbol.name)); + isParameterPropertyDeclaration(symbol.valueDeclaration)) { + result = result.concat(typeChecker.getSymbolsOfParameterPropertyDeclaration(symbol.valueDeclaration, symbol.name)); } // If this is a union property, add all the symbols from all its source symbols in all unioned types. diff --git a/tests/cases/fourslash/documentHighlightAtParameterPropertyDeclaration2.ts b/tests/cases/fourslash/documentHighlightAtParameterPropertyDeclaration2.ts index 2658dd56371..f5d6764205b 100644 --- a/tests/cases/fourslash/documentHighlightAtParameterPropertyDeclaration2.ts +++ b/tests/cases/fourslash/documentHighlightAtParameterPropertyDeclaration2.ts @@ -20,5 +20,5 @@ let markers = test.markers() for (let marker of markers) { goTo.position(marker.position); - verify.documentHighlightsAtPositionCount(3, ["file1.ts"]); + verify.documentHighlightsAtPositionCount(2, ["file1.ts"]); } \ No newline at end of file From c5df5d768e34486f6cff985d9ad521ec906a8e6a Mon Sep 17 00:00:00 2001 From: Yui T Date: Mon, 14 Dec 2015 12:57:02 -0800 Subject: [PATCH 37/79] Fix linting issue --- Jakefile.js | 3 +- src/services/services.ts | 1073 +++++++++++++++++++------------------- 2 files changed, 538 insertions(+), 538 deletions(-) diff --git a/Jakefile.js b/Jakefile.js index beb16d2886f..91bd805a27b 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -924,7 +924,8 @@ function lintFileAsync(options, path, cb) { var lintTargets = compilerSources .concat(harnessCoreSources) .concat(serverCoreSources) - .concat(scriptSources); + .concat(scriptSources) + .concat([path.join(servicesDirectory,"services.ts")]); desc("Runs tslint on the compiler sources"); task("lint", ["build-rules"], function() { diff --git a/src/services/services.ts b/src/services/services.ts index 8e2e4913edd..092f987eb5a 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -12,7 +12,7 @@ namespace ts { /** The version of the language service API */ - export let servicesVersion = "0.4" + export const servicesVersion = "0.4"; export interface Node { getSourceFile(): SourceFile; @@ -48,7 +48,7 @@ namespace ts { getConstructSignatures(): Signature[]; getStringIndexType(): Type; getNumberIndexType(): Type; - getBaseTypes(): ObjectType[] + getBaseTypes(): ObjectType[]; } export interface Signature { @@ -97,7 +97,7 @@ namespace ts { dispose?(): void; } - export module ScriptSnapshot { + export namespace ScriptSnapshot { class StringScriptSnapshot implements IScriptSnapshot { constructor(private text: string) { @@ -126,12 +126,12 @@ namespace ts { referencedFiles: FileReference[]; importedFiles: FileReference[]; ambientExternalModules: string[]; - isLibFile: boolean + isLibFile: boolean; } - let scanner: Scanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ true); + const scanner: Scanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ true); - let emptyArray: any[] = []; + const emptyArray: any[] = []; const jsDocTagNames = [ "augments", @@ -174,7 +174,7 @@ namespace ts { let jsDocCompletionEntries: CompletionEntry[]; function createNode(kind: SyntaxKind, pos: number, end: number, flags: NodeFlags, parent?: Node): NodeObject { - let node = new NodeObject(kind, pos, end); + const node = new NodeObject(kind, pos, end); node.flags = flags; node.parent = parent; return node; @@ -235,8 +235,8 @@ namespace ts { private addSyntheticNodes(nodes: Node[], pos: number, end: number): number { scanner.setTextPos(pos); while (pos < end) { - let token = scanner.scan(); - let textPos = scanner.getTextPos(); + const token = scanner.scan(); + const textPos = scanner.getTextPos(); nodes.push(createNode(token, pos, textPos, NodeFlags.Synthetic, this)); pos = textPos; } @@ -244,13 +244,11 @@ namespace ts { } private createSyntaxList(nodes: NodeArray): Node { - let list = createNode(SyntaxKind.SyntaxList, nodes.pos, nodes.end, NodeFlags.Synthetic, this); + const list = createNode(SyntaxKind.SyntaxList, nodes.pos, nodes.end, NodeFlags.Synthetic, this); list._children = []; let pos = nodes.pos; - - - for (let node of nodes) { + for (const node of nodes) { if (pos < node.pos) { pos = this.addSyntheticNodes(list._children, pos, node.pos); } @@ -269,14 +267,14 @@ namespace ts { scanner.setText((sourceFile || this.getSourceFile()).text); children = []; let pos = this.pos; - let processNode = (node: Node) => { + const processNode = (node: Node) => { if (pos < node.pos) { pos = this.addSyntheticNodes(children, pos, node.pos); } children.push(node); pos = node.end; }; - let processNodes = (nodes: NodeArray) => { + const processNodes = (nodes: NodeArray) => { if (pos < nodes.pos) { pos = this.addSyntheticNodes(children, pos, nodes.pos); } @@ -308,20 +306,20 @@ namespace ts { } public getFirstToken(sourceFile?: SourceFile): Node { - let children = this.getChildren(sourceFile); + const children = this.getChildren(sourceFile); if (!children.length) { return undefined; } - let child = children[0]; + const child = children[0]; return child.kind < SyntaxKind.FirstNode ? child : child.getFirstToken(sourceFile); } public getLastToken(sourceFile?: SourceFile): Node { - let children = this.getChildren(sourceFile); + const children = this.getChildren(sourceFile); - let child = lastOrUndefined(children); + const child = lastOrUndefined(children); if (!child) { return undefined; } @@ -366,8 +364,8 @@ namespace ts { } function getJsDocCommentsFromDeclarations(declarations: Declaration[], name: string, canUseParsedParamTagComments: boolean) { - let documentationComment = []; - let docComments = getJsDocCommentsSeparatedByNewLines(); + const documentationComment = []; + const docComments = getJsDocCommentsSeparatedByNewLines(); ts.forEach(docComments, docComment => { if (documentationComment.length) { documentationComment.push(lineBreakPart()); @@ -378,22 +376,22 @@ namespace ts { return documentationComment; function getJsDocCommentsSeparatedByNewLines() { - let paramTag = "@param"; - let jsDocCommentParts: SymbolDisplayPart[] = []; + const paramTag = "@param"; + const jsDocCommentParts: SymbolDisplayPart[] = []; ts.forEach(declarations, (declaration, indexOfDeclaration) => { // Make sure we are collecting doc comment from declaration once, // In case of union property there might be same declaration multiple times // which only varies in type parameter - // Eg. let a: Array | Array; a.length + // Eg. const a: Array | Array; a.length // The property length will have two declarations of property length coming // from Array - Array and Array if (indexOf(declarations, declaration) === indexOfDeclaration) { - let sourceFileOfDeclaration = getSourceFileOfNode(declaration); + const sourceFileOfDeclaration = getSourceFileOfNode(declaration); // If it is parameter - try and get the jsDoc comment with @param tag from function declaration's jsDoc comments if (canUseParsedParamTagComments && declaration.kind === SyntaxKind.Parameter) { ts.forEach(getJsDocCommentTextRange(declaration.parent, sourceFileOfDeclaration), jsDocCommentTextRange => { - let cleanedParamJsDocComment = getCleanedParamJsDocComment(jsDocCommentTextRange.pos, jsDocCommentTextRange.end, sourceFileOfDeclaration); + const cleanedParamJsDocComment = getCleanedParamJsDocComment(jsDocCommentTextRange.pos, jsDocCommentTextRange.end, sourceFileOfDeclaration); if (cleanedParamJsDocComment) { addRange(jsDocCommentParts, cleanedParamJsDocComment); } @@ -413,7 +411,7 @@ namespace ts { // Get the cleaned js doc comment text from the declaration ts.forEach(getJsDocCommentTextRange( declaration.kind === SyntaxKind.VariableDeclaration ? declaration.parent.parent : declaration, sourceFileOfDeclaration), jsDocCommentTextRange => { - let cleanedJsDocComment = getCleanedJsDocComment(jsDocCommentTextRange.pos, jsDocCommentTextRange.end, sourceFileOfDeclaration); + const cleanedJsDocComment = getCleanedJsDocComment(jsDocCommentTextRange.pos, jsDocCommentTextRange.end, sourceFileOfDeclaration); if (cleanedJsDocComment) { addRange(jsDocCommentParts, cleanedJsDocComment); } @@ -439,7 +437,7 @@ namespace ts { } for (; pos < end; pos++) { - let ch = sourceFile.text.charCodeAt(pos); + const ch = sourceFile.text.charCodeAt(pos); if (!isWhiteSpace(ch) || isLineBreak(ch)) { // Either found lineBreak or non whiteSpace return pos; @@ -480,7 +478,7 @@ namespace ts { function getCleanedJsDocComment(pos: number, end: number, sourceFile: SourceFile) { let spacesToRemoveAfterAsterisk: number; - let docComments: SymbolDisplayPart[] = []; + const docComments: SymbolDisplayPart[] = []; let blankLineCount = 0; let isInParamTag = false; @@ -491,7 +489,7 @@ namespace ts { // If the comment starts with '*' consume the spaces on this line if (pos < end && sourceFile.text.charCodeAt(pos) === CharacterCodes.asterisk) { - let lineStartPos = pos + 1; + const lineStartPos = pos + 1; pos = consumeWhiteSpacesOnTheLine(pos + 1, end, sourceFile, spacesToRemoveAfterAsterisk); // Set the spaces to remove after asterisk as margin if not already set @@ -505,7 +503,7 @@ namespace ts { // Analyse text on this line while (pos < end && !isLineBreak(sourceFile.text.charCodeAt(pos))) { - let ch = sourceFile.text.charAt(pos); + const ch = sourceFile.text.charAt(pos); if (ch === "@") { // If it is @param tag if (isParamTag(pos, end, sourceFile)) { @@ -544,7 +542,7 @@ namespace ts { function getCleanedParamJsDocComment(pos: number, end: number, sourceFile: SourceFile) { let paramHelpStringMargin: number; - let paramDocComments: SymbolDisplayPart[] = []; + const paramDocComments: SymbolDisplayPart[] = []; while (pos < end) { if (isParamTag(pos, end, sourceFile)) { let blankLineCount = 0; @@ -559,7 +557,7 @@ namespace ts { if (sourceFile.text.charCodeAt(pos) === CharacterCodes.openBrace) { pos++; for (let curlies = 1; pos < end; pos++) { - let charCode = sourceFile.text.charCodeAt(pos); + const charCode = sourceFile.text.charCodeAt(pos); // { character means we need to find another } to match the found one if (charCode === CharacterCodes.openBrace) { @@ -603,9 +601,9 @@ namespace ts { } let paramHelpString = ""; - let firstLineParamHelpStringPos = pos; + const firstLineParamHelpStringPos = pos; while (pos < end) { - let ch = sourceFile.text.charCodeAt(pos); + const ch = sourceFile.text.charCodeAt(pos); // at line break, set this comment line text and go to next line if (isLineBreak(ch)) { @@ -674,15 +672,15 @@ namespace ts { } // Now consume white spaces max - let startOfLinePos = pos; + const startOfLinePos = pos; pos = consumeWhiteSpacesOnTheLine(pos, end, sourceFile, paramHelpStringMargin); if (pos >= end) { return; } - let consumedSpaces = pos - startOfLinePos; + const consumedSpaces = pos - startOfLinePos; if (consumedSpaces < paramHelpStringMargin) { - let ch = sourceFile.text.charCodeAt(pos); + const ch = sourceFile.text.charCodeAt(pos); if (ch === CharacterCodes.asterisk) { // Consume more spaces after asterisk pos = consumeWhiteSpacesOnTheLine(pos + 1, end, sourceFile, paramHelpStringMargin - consumedSpaces - 1); @@ -815,7 +813,7 @@ namespace ts { private namedDeclarations: Map; constructor(kind: SyntaxKind, pos: number, end: number) { - super(kind, pos, end) + super(kind, pos, end); } public update(newText: string, textChangeRange: TextChangeRange): SourceFile { @@ -843,16 +841,16 @@ namespace ts { } private computeNamedDeclarations(): Map { - let result: Map = {}; + const result: Map = {}; forEachChild(this, visit); return result; function addDeclaration(declaration: Declaration) { - let name = getDeclarationName(declaration); + const name = getDeclarationName(declaration); if (name) { - let declarations = getDeclarations(name); + const declarations = getDeclarations(name); declarations.push(declaration); } } @@ -863,13 +861,13 @@ namespace ts { function getDeclarationName(declaration: Declaration) { if (declaration.name) { - let result = getTextOfIdentifierOrLiteral(declaration.name); + const result = getTextOfIdentifierOrLiteral(declaration.name); if (result !== undefined) { return result; } if (declaration.name.kind === SyntaxKind.ComputedPropertyName) { - let expr = (declaration.name).expression; + const expr = (declaration.name).expression; if (expr.kind === SyntaxKind.PropertyAccessExpression) { return (expr).name.text; } @@ -899,12 +897,12 @@ namespace ts { case SyntaxKind.FunctionDeclaration: case SyntaxKind.MethodDeclaration: case SyntaxKind.MethodSignature: - let functionDeclaration = node; - let declarationName = getDeclarationName(functionDeclaration); + const functionDeclaration = node; + const declarationName = getDeclarationName(functionDeclaration); if (declarationName) { - let declarations = getDeclarations(declarationName); - let lastDeclaration = lastOrUndefined(declarations); + const declarations = getDeclarations(declarationName); + const lastDeclaration = lastOrUndefined(declarations); // Check whether this declaration belongs to an "overload group". if (lastDeclaration && functionDeclaration.parent === lastDeclaration.parent && functionDeclaration.symbol === lastDeclaration.symbol) { @@ -980,7 +978,7 @@ namespace ts { break; case SyntaxKind.ImportDeclaration: - let importClause = (node).importClause; + const importClause = (node).importClause; if (importClause) { // Handle default import case e.g.: // import d from "mod"; @@ -1113,8 +1111,8 @@ namespace ts { } export interface Classifications { - spans: number[], - endOfLineState: EndOfLineState + spans: number[]; + endOfLineState: EndOfLineState; } export interface ClassifiedSpan { @@ -1171,7 +1169,7 @@ namespace ts { highlightSpans: HighlightSpan[]; } - export module HighlightSpanKind { + export namespace HighlightSpanKind { export const none = "none"; export const definition = "definition"; export const reference = "reference"; @@ -1220,7 +1218,7 @@ namespace ts { InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: boolean; PlaceOpenBraceOnNewLineForFunctions: boolean; PlaceOpenBraceOnNewLineForControlBlocks: boolean; - [s: string]: boolean | number| string; + [s: string]: boolean | number | string; } export interface DefinitionInfo { @@ -1500,7 +1498,7 @@ namespace ts { } // TODO: move these to enums - export module ScriptElementKind { + export namespace ScriptElementKind { export const unknown = ""; export const warning = "warning"; @@ -1529,7 +1527,7 @@ namespace ts { export const enumElement = "enum"; // Inside module and script only - // let v = .. + // const v = .. export const variableElement = "var"; // Inside function @@ -1581,7 +1579,7 @@ namespace ts { export const letElement = "let"; } - export module ScriptElementKindModifier { + export namespace ScriptElementKindModifier { export const none = ""; export const publicMemberModifier = "public"; export const privateMemberModifier = "private"; @@ -1723,8 +1721,8 @@ namespace ts { this.fileNameToEntry = createFileMap(); // Initialize the list with the root file names - let rootFileNames = host.getScriptFileNames(); - for (let fileName of rootFileNames) { + const rootFileNames = host.getScriptFileNames(); + for (const fileName of rootFileNames) { this.createEntry(fileName, toPath(fileName, this.currentDirectory, getCanonicalFileName)); } @@ -1738,7 +1736,7 @@ namespace ts { private createEntry(fileName: string, path: Path) { let entry: HostFileInformation; - let scriptSnapshot = this.host.getScriptSnapshot(fileName); + const scriptSnapshot = this.host.getScriptSnapshot(fileName); if (scriptSnapshot) { entry = { hostFileName: fileName, @@ -1760,7 +1758,7 @@ namespace ts { } public getOrCreateEntry(fileName: string): HostFileInformation { - let path = toPath(fileName, this.currentDirectory, this.getCanonicalFileName) + const path = toPath(fileName, this.currentDirectory, this.getCanonicalFileName); if (this.contains(path)) { return this.getEntry(path); } @@ -1769,7 +1767,7 @@ namespace ts { } public getRootFileNames(): string[] { - let fileNames: string[] = []; + const fileNames: string[] = []; this.fileNameToEntry.forEachValue((path, value) => { if (value) { @@ -1781,12 +1779,12 @@ namespace ts { } public getVersion(path: Path): string { - let file = this.getEntry(path); + const file = this.getEntry(path); return file && file.version; } public getScriptSnapshot(path: Path): IScriptSnapshot { - let file = this.getEntry(path); + const file = this.getEntry(path); return file && file.scriptSnapshot; } } @@ -1803,22 +1801,22 @@ namespace ts { } public getCurrentSourceFile(fileName: string): SourceFile { - let scriptSnapshot = this.host.getScriptSnapshot(fileName); + const scriptSnapshot = this.host.getScriptSnapshot(fileName); if (!scriptSnapshot) { // The host does not know about this file. throw new Error("Could not find file: '" + fileName + "'."); } - let version = this.host.getScriptVersion(fileName); + const version = this.host.getScriptVersion(fileName); let sourceFile: SourceFile; if (this.currentFileName !== fileName) { // This is a new file, just parse it - sourceFile = createLanguageServiceSourceFile(fileName, scriptSnapshot, ScriptTarget.Latest, version, /*setNodeParents:*/ true); + sourceFile = createLanguageServiceSourceFile(fileName, scriptSnapshot, ScriptTarget.Latest, version, /*setNodeParents*/ true); } else if (this.currentFileVersion !== version) { // This is the same file, just a newer version. Incrementally parse the file. - let editRange = scriptSnapshot.getChangeRange(this.currentFileScriptSnapshot); + const editRange = scriptSnapshot.getChangeRange(this.currentFileScriptSnapshot); sourceFile = updateLanguageServiceSourceFile(this.currentSourceFile, scriptSnapshot, version, editRange); } @@ -1863,7 +1861,7 @@ namespace ts { * - noResolve = true */ export function transpileModule(input: string, transpileOptions: TranspileOptions): TranspileOutput { - let options = transpileOptions.compilerOptions ? clone(transpileOptions.compilerOptions) : getDefaultCompilerOptions(); + const options = transpileOptions.compilerOptions ? clone(transpileOptions.compilerOptions) : getDefaultCompilerOptions(); options.isolatedModules = true; @@ -1879,21 +1877,22 @@ namespace ts { options.noResolve = true; // if jsx is specified then treat file as .tsx - let inputFileName = transpileOptions.fileName || (options.jsx ? "module.tsx" : "module.ts"); - let sourceFile = createSourceFile(inputFileName, input, options.target); + const inputFileName = transpileOptions.fileName || (options.jsx ? "module.tsx" : "module.ts"); + const sourceFile = createSourceFile(inputFileName, input, options.target); if (transpileOptions.moduleName) { sourceFile.moduleName = transpileOptions.moduleName; } sourceFile.renamedDependencies = transpileOptions.renamedDependencies; - let newLine = getNewLineCharacter(options); + const newLine = getNewLineCharacter(options); // Output let outputText: string; let sourceMapText: string; + // Create a compilerHost object to allow the compiler to read and write files - let compilerHost: CompilerHost = { + const compilerHost: CompilerHost = { getSourceFile: (fileName, target) => fileName === normalizeSlashes(inputFileName) ? sourceFile : undefined, writeFile: (name, text, writeByteOrderMark) => { if (fileExtensionIs(name, ".map")) { @@ -1914,7 +1913,7 @@ namespace ts { readFile: (fileName): string => "" }; - let program = createProgram([inputFileName], options, compilerHost); + const program = createProgram([inputFileName], options, compilerHost); let diagnostics: Diagnostic[]; if (transpileOptions.reportDiagnostics) { @@ -1934,22 +1933,22 @@ namespace ts { * This is a shortcut function for transpileModule - it accepts transpileOptions as parameters and returns only outputText part of the result. */ export function transpile(input: string, compilerOptions?: CompilerOptions, fileName?: string, diagnostics?: Diagnostic[], moduleName?: string): string { - let output = transpileModule(input, { compilerOptions, fileName, reportDiagnostics: !!diagnostics, moduleName }); + const output = transpileModule(input, { compilerOptions, fileName, reportDiagnostics: !!diagnostics, moduleName }); // addRange correctly handles cases when wither 'from' or 'to' argument is missing addRange(diagnostics, output.diagnostics); return output.outputText; } export function createLanguageServiceSourceFile(fileName: string, scriptSnapshot: IScriptSnapshot, scriptTarget: ScriptTarget, version: string, setNodeParents: boolean): SourceFile { - let text = scriptSnapshot.getText(0, scriptSnapshot.getLength()); - let sourceFile = createSourceFile(fileName, text, scriptTarget, setNodeParents); + const text = scriptSnapshot.getText(0, scriptSnapshot.getLength()); + const sourceFile = createSourceFile(fileName, text, scriptTarget, setNodeParents); setSourceFileFields(sourceFile, scriptSnapshot, version); // after full parsing we can use table with interned strings as name table sourceFile.nameTable = sourceFile.identifiers; return sourceFile; } - export let disableIncrementalParsing = false; + export const disableIncrementalParsing = false; export function updateLanguageServiceSourceFile(sourceFile: SourceFile, scriptSnapshot: IScriptSnapshot, version: string, textChangeRange: TextChangeRange, aggressiveChecks?: boolean): SourceFile { // If we were given a text change range, and our version or open-ness changed, then @@ -1961,12 +1960,12 @@ namespace ts { let newText: string; // grab the fragment from the beginning of the original text to the beginning of the span - let prefix = textChangeRange.span.start !== 0 + const prefix = textChangeRange.span.start !== 0 ? sourceFile.text.substr(0, textChangeRange.span.start) : ""; // grab the fragment from the end of the span till the end of the original text - let suffix = textSpanEnd(textChangeRange.span) !== sourceFile.text.length + const suffix = textSpanEnd(textChangeRange.span) !== sourceFile.text.length ? sourceFile.text.substr(textSpanEnd(textChangeRange.span)) : ""; @@ -1976,7 +1975,7 @@ namespace ts { } else { // it was actual edit, fetch the fragment of new text that correspond to new span - let changedText = scriptSnapshot.getText(textChangeRange.span.start, textChangeRange.span.start + textChangeRange.newLength); + const changedText = scriptSnapshot.getText(textChangeRange.span.start, textChangeRange.span.start + textChangeRange.newLength); // combine prefix, changed text and suffix newText = prefix && suffix ? prefix + changedText + suffix @@ -1985,7 +1984,7 @@ namespace ts { : (changedText + suffix); } - let newSourceFile = updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks); + const newSourceFile = updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks); setSourceFileFields(newSourceFile, scriptSnapshot, version); // after incremental parsing nameTable might not be up-to-date // drop it so it can be lazily recreated later @@ -2006,7 +2005,7 @@ namespace ts { } // Otherwise, just create a new source file. - return createLanguageServiceSourceFile(sourceFile.fileName, scriptSnapshot, sourceFile.languageVersion, version, /*setNodeParents:*/ true); + return createLanguageServiceSourceFile(sourceFile.fileName, scriptSnapshot, sourceFile.languageVersion, version, /*setNodeParents*/ true); } export function createGetCanonicalFileName(useCaseSensitivefileNames: boolean): (fileName: string) => string { @@ -2019,15 +2018,15 @@ namespace ts { export function createDocumentRegistry(useCaseSensitiveFileNames?: boolean, currentDirectory = ""): DocumentRegistry { // Maps from compiler setting target (ES3, ES5, etc.) to all the cached documents we have // for those settings. - let buckets: Map> = {}; - let getCanonicalFileName = createGetCanonicalFileName(!!useCaseSensitiveFileNames); + const buckets: Map> = {}; + const getCanonicalFileName = createGetCanonicalFileName(!!useCaseSensitiveFileNames); function getKeyFromCompilationSettings(settings: CompilerOptions): string { return "_" + settings.target + "|" + settings.module + "|" + settings.noResolve + "|" + settings.jsx + +"|" + settings.allowJs; } function getBucketForCompilationSettings(settings: CompilerOptions, createIfMissing: boolean): FileMap { - let key = getKeyFromCompilationSettings(settings); + const key = getKeyFromCompilationSettings(settings); let bucket = lookUp(buckets, key); if (!bucket && createIfMissing) { buckets[key] = bucket = createFileMap(); @@ -2036,9 +2035,9 @@ namespace ts { } function reportStats() { - let bucketInfoArray = Object.keys(buckets).filter(name => name && name.charAt(0) === '_').map(name => { - let entries = lookUp(buckets, name); - let sourceFiles: { name: string; refCount: number; references: string[]; }[] = []; + const bucketInfoArray = Object.keys(buckets).filter(name => name && name.charAt(0) === "_").map(name => { + const entries = lookUp(buckets, name); + const sourceFiles: { name: string; refCount: number; references: string[]; }[] = []; entries.forEachValue((key, entry) => { sourceFiles.push({ name: key, @@ -2052,15 +2051,15 @@ namespace ts { sourceFiles }; }); - return JSON.stringify(bucketInfoArray, null, 2); + return JSON.stringify(bucketInfoArray, undefined, 2); } function acquireDocument(fileName: string, compilationSettings: CompilerOptions, scriptSnapshot: IScriptSnapshot, version: string): SourceFile { - return acquireOrUpdateDocument(fileName, compilationSettings, scriptSnapshot, version, /*acquiring:*/ true); + return acquireOrUpdateDocument(fileName, compilationSettings, scriptSnapshot, version, /*acquiring*/ true); } function updateDocument(fileName: string, compilationSettings: CompilerOptions, scriptSnapshot: IScriptSnapshot, version: string): SourceFile { - return acquireOrUpdateDocument(fileName, compilationSettings, scriptSnapshot, version, /*acquiring:*/ false); + return acquireOrUpdateDocument(fileName, compilationSettings, scriptSnapshot, version, /*acquiring*/ false); } function acquireOrUpdateDocument( @@ -2070,14 +2069,14 @@ namespace ts { version: string, acquiring: boolean): SourceFile { - let bucket = getBucketForCompilationSettings(compilationSettings, /*createIfMissing*/ true); - let path = toPath(fileName, currentDirectory, getCanonicalFileName); + const bucket = getBucketForCompilationSettings(compilationSettings, /*createIfMissing*/ true); + const path = toPath(fileName, currentDirectory, getCanonicalFileName); let entry = bucket.get(path); if (!entry) { Debug.assert(acquiring, "How could we be trying to update a document that the registry doesn't have?"); // Have never seen this file with these settings. Create a new source file for it. - let sourceFile = createLanguageServiceSourceFile(fileName, scriptSnapshot, compilationSettings.target, version, /*setNodeParents:*/ false); + const sourceFile = createLanguageServiceSourceFile(fileName, scriptSnapshot, compilationSettings.target, version, /*setNodeParents*/ false); entry = { sourceFile: sourceFile, @@ -2109,12 +2108,12 @@ namespace ts { } function releaseDocument(fileName: string, compilationSettings: CompilerOptions): void { - let bucket = getBucketForCompilationSettings(compilationSettings, false); + const bucket = getBucketForCompilationSettings(compilationSettings, /*createIfMissing*/false); Debug.assert(bucket !== undefined); - let path = toPath(fileName, currentDirectory, getCanonicalFileName); + const path = toPath(fileName, currentDirectory, getCanonicalFileName); - let entry = bucket.get(path); + const entry = bucket.get(path); entry.languageServiceRefCount--; Debug.assert(entry.languageServiceRefCount >= 0); @@ -2132,19 +2131,19 @@ namespace ts { } export function preProcessFile(sourceText: string, readImportFiles = true, detectJavaScriptImports = false): PreProcessedFileInfo { - let referencedFiles: FileReference[] = []; - let importedFiles: FileReference[] = []; + const referencedFiles: FileReference[] = []; + const importedFiles: FileReference[] = []; let ambientExternalModules: string[]; let isNoDefaultLib = false; function processTripleSlashDirectives(): void { - let commentRanges = getLeadingCommentRanges(sourceText, 0); + const commentRanges = getLeadingCommentRanges(sourceText, 0); forEach(commentRanges, commentRange => { - let comment = sourceText.substring(commentRange.pos, commentRange.end); - let referencePathMatchResult = getFileReferenceFromReferencePath(comment, commentRange); + const comment = sourceText.substring(commentRange.pos, commentRange.end); + const referencePathMatchResult = getFileReferenceFromReferencePath(comment, commentRange); if (referencePathMatchResult) { isNoDefaultLib = referencePathMatchResult.isNoDefaultLib; - let fileReference = referencePathMatchResult.fileReference; + const fileReference = referencePathMatchResult.fileReference; if (fileReference) { referencedFiles.push(fileReference); } @@ -2160,8 +2159,8 @@ namespace ts { } function recordModuleName() { - let importPath = scanner.getTokenValue(); - let pos = scanner.getTokenPos(); + const importPath = scanner.getTokenValue(); + const pos = scanner.getTokenPos(); importedFiles.push({ fileName: importPath, pos: pos, @@ -2213,7 +2212,7 @@ namespace ts { } } else if (token === SyntaxKind.EqualsToken) { - if (tryConsumeRequireCall(/* skipCurrentToken */ true)) { + if (tryConsumeRequireCall(/*skipCurrentToken*/ true)) { return true; } } @@ -2311,7 +2310,7 @@ namespace ts { if (token === SyntaxKind.Identifier || isKeyword(token)) { token = scanner.scan(); if (token === SyntaxKind.EqualsToken) { - if (tryConsumeRequireCall(/* skipCurrentToken */ true)) { + if (tryConsumeRequireCall(/*skipCurrentToken*/ true)) { return true; } } @@ -2410,7 +2409,7 @@ namespace ts { if (tryConsumeDeclare() || tryConsumeImport() || tryConsumeExport() || - (detectJavaScriptImports && (tryConsumeRequireCall(/* skipCurrentToken */ false) || tryConsumeDefine()))) { + (detectJavaScriptImports && (tryConsumeRequireCall(/*skipCurrentToken*/ false) || tryConsumeDefine()))) { continue; } else { @@ -2550,8 +2549,8 @@ namespace ts { return true; } else if (position === comment.end) { - let text = sourceFile.text; - let width = comment.end - comment.pos; + const text = sourceFile.text; + const width = comment.end - comment.pos; // is single line comment or just /* if (width <= 2 || text.charCodeAt(comment.pos + 1) === CharacterCodes.slash) { return true; @@ -2583,7 +2582,7 @@ namespace ts { } // A cache of completion entries for keywords, these do not change between sessions - let keywordCompletions: CompletionEntry[] = []; + const keywordCompletions: CompletionEntry[] = []; for (let i = SyntaxKind.FirstKeyword; i <= SyntaxKind.LastKeyword; i++) { keywordCompletions.push({ name: tokenToString(i), @@ -2673,15 +2672,15 @@ namespace ts { export function createLanguageService(host: LanguageServiceHost, documentRegistry: DocumentRegistry = createDocumentRegistry(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames(), host.getCurrentDirectory())): LanguageService { - let syntaxTreeCache: SyntaxTreeCache = new SyntaxTreeCache(host); + const syntaxTreeCache: SyntaxTreeCache = new SyntaxTreeCache(host); let ruleProvider: formatting.RulesProvider; let program: Program; let lastProjectVersion: string; - let useCaseSensitivefileNames = false; - let cancellationToken = new CancellationTokenObject(host.getCancellationToken && host.getCancellationToken()); + const useCaseSensitivefileNames = false; + const cancellationToken = new CancellationTokenObject(host.getCancellationToken && host.getCancellationToken()); - let currentDirectory = host.getCurrentDirectory(); + const currentDirectory = host.getCurrentDirectory(); // Check if the localized messages json is set, otherwise query the host for it if (!localizedDiagnosticMessages && host.getLocalizedDiagnosticMessages) { localizedDiagnosticMessages = host.getLocalizedDiagnosticMessages(); @@ -2693,10 +2692,10 @@ namespace ts { } } - let getCanonicalFileName = createGetCanonicalFileName(useCaseSensitivefileNames); + const getCanonicalFileName = createGetCanonicalFileName(useCaseSensitivefileNames); function getValidSourceFile(fileName: string): SourceFile { - let sourceFile = program.getSourceFile(fileName); + const sourceFile = program.getSourceFile(fileName); if (!sourceFile) { throw new Error("Could not find file: '" + fileName + "'."); } @@ -2716,7 +2715,7 @@ namespace ts { function synchronizeHostData(): void { // perform fast check if host supports it if (host.getProjectVersion) { - let hostProjectVersion = host.getProjectVersion(); + const hostProjectVersion = host.getProjectVersion(); if (hostProjectVersion) { if (lastProjectVersion === hostProjectVersion) { return; @@ -2740,17 +2739,17 @@ namespace ts { // the program points to old source files that have been invalidated because of // incremental parsing. - let oldSettings = program && program.getCompilerOptions(); - let newSettings = hostCache.compilationSettings(); - let changesInCompilationSettingsAffectSyntax = oldSettings && + const oldSettings = program && program.getCompilerOptions(); + const newSettings = hostCache.compilationSettings(); + const changesInCompilationSettingsAffectSyntax = oldSettings && (oldSettings.target !== newSettings.target || oldSettings.module !== newSettings.module || oldSettings.noResolve !== newSettings.noResolve || - oldSettings.jsx !== newSettings.jsx || + oldSettings.jsx !== newSettings.jsx || oldSettings.allowJs !== newSettings.allowJs); // Now create a new compiler - let compilerHost: CompilerHost = { + const compilerHost: CompilerHost = { getSourceFile: getOrCreateSourceFile, getCancellationToken: () => cancellationToken, getCanonicalFileName, @@ -2766,22 +2765,22 @@ namespace ts { }, readFile: (fileName): string => { // stub missing host functionality - let entry = hostCache.getOrCreateEntry(fileName); + const entry = hostCache.getOrCreateEntry(fileName); return entry && entry.scriptSnapshot.getText(0, entry.scriptSnapshot.getLength()); } }; if (host.resolveModuleNames) { - compilerHost.resolveModuleNames = (moduleNames, containingFile) => host.resolveModuleNames(moduleNames, containingFile) + compilerHost.resolveModuleNames = (moduleNames, containingFile) => host.resolveModuleNames(moduleNames, containingFile); } - let newProgram = createProgram(hostCache.getRootFileNames(), newSettings, compilerHost, program); + const newProgram = createProgram(hostCache.getRootFileNames(), newSettings, compilerHost, program); // Release any files we have acquired in the old program but are // not part of the new program. if (program) { - let oldSourceFiles = program.getSourceFiles(); - for (let oldSourceFile of oldSourceFiles) { + const oldSourceFiles = program.getSourceFiles(); + for (const oldSourceFile of oldSourceFiles) { if (!newProgram.getSourceFile(oldSourceFile.fileName) || changesInCompilationSettingsAffectSyntax) { documentRegistry.releaseDocument(oldSourceFile.fileName, oldSettings); } @@ -2804,7 +2803,7 @@ namespace ts { // The program is asking for this file, check first if the host can locate it. // If the host can not locate the file, then it does not exist. return undefined // to the program to allow reporting of errors for missing files. - let hostFileInformation = hostCache.getOrCreateEntry(fileName); + const hostFileInformation = hostCache.getOrCreateEntry(fileName); if (!hostFileInformation) { return undefined; } @@ -2814,7 +2813,7 @@ namespace ts { // can not be reused. we have to dump all syntax trees and create new ones. if (!changesInCompilationSettingsAffectSyntax) { // Check if the old program had this file already - let oldSourceFile = program && program.getSourceFile(fileName); + const oldSourceFile = program && program.getSourceFile(fileName); if (oldSourceFile) { // We already had a source file for this file name. Go to the registry to // ensure that we get the right up to date version of it. We need this to @@ -2851,7 +2850,7 @@ namespace ts { if (!sourceFile) { return false; } - let path = sourceFile.path || toPath(sourceFile.fileName, currentDirectory, getCanonicalFileName); + const path = sourceFile.path || toPath(sourceFile.fileName, currentDirectory, getCanonicalFileName); return sourceFile.version === hostCache.getVersion(path); } @@ -2862,13 +2861,13 @@ namespace ts { } // If number of files in the program do not match, it is not up-to-date - let rootFileNames = hostCache.getRootFileNames(); + const rootFileNames = hostCache.getRootFileNames(); if (program.getSourceFiles().length !== rootFileNames.length) { return false; } // If any file is not up-to-date, then the whole program is not up-to-date - for (let fileName of rootFileNames) { + for (const fileName of rootFileNames) { if (!sourceFileUpToDate(program.getSourceFile(fileName))) { return false; } @@ -2910,18 +2909,18 @@ namespace ts { function getSemanticDiagnostics(fileName: string): Diagnostic[] { synchronizeHostData(); - let targetSourceFile = getValidSourceFile(fileName); + const targetSourceFile = getValidSourceFile(fileName); // Only perform the action per file regardless of '-out' flag as LanguageServiceHost is expected to call this function per file. // Therefore only get diagnostics for given file. - let semanticDiagnostics = program.getSemanticDiagnostics(targetSourceFile, cancellationToken); + const semanticDiagnostics = program.getSemanticDiagnostics(targetSourceFile, cancellationToken); if (!program.getCompilerOptions().declaration) { return semanticDiagnostics; } // If '-d' is enabled, check for emitter error. One example of emitter error is export class implements non-export interface - let declarationDiagnostics = program.getDeclarationDiagnostics(targetSourceFile, cancellationToken); + const declarationDiagnostics = program.getDeclarationDiagnostics(targetSourceFile, cancellationToken); return concatenate(semanticDiagnostics, declarationDiagnostics); } @@ -2937,14 +2936,14 @@ namespace ts { * @return undefined if the name is of external module otherwise a name with striped of any quote */ function getCompletionEntryDisplayNameForSymbol(symbol: Symbol, target: ScriptTarget, performCharacterChecks: boolean, location: Node): string { - let displayName: string = getDeclaredName(program.getTypeChecker(), symbol, location); + const displayName: string = getDeclaredName(program.getTypeChecker(), symbol, location); if (displayName) { - let firstCharCode = displayName.charCodeAt(0); + const firstCharCode = displayName.charCodeAt(0); // First check of the displayName is not external module; if it is an external module, it is not valid entry if ((symbol.flags & SymbolFlags.Namespace) && (firstCharCode === CharacterCodes.singleQuote || firstCharCode === CharacterCodes.doubleQuote)) { // If the symbol is external module, don't show it in the completion list - // (i.e declare module "http" { let x; } | // <= request completion here, "http" should not be there) + // (i.e declare module "http" { const x; } | // <= request completion here, "http" should not be there) return undefined; } } @@ -2987,20 +2986,20 @@ namespace ts { } function getCompletionData(fileName: string, position: number) { - let typeChecker = program.getTypeChecker(); - let syntacticStart = new Date().getTime(); - let sourceFile = getValidSourceFile(fileName); - let isJavaScriptFile = isSourceFileJavaScript(sourceFile); + const typeChecker = program.getTypeChecker(); + const syntacticStart = new Date().getTime(); + const sourceFile = getValidSourceFile(fileName); + const isJavaScriptFile = isSourceFileJavaScript(sourceFile); let isJsDocTagName = false; let start = new Date().getTime(); - let currentToken = getTokenAtPosition(sourceFile, position); + const currentToken = getTokenAtPosition(sourceFile, position); log("getCompletionData: Get current token: " + (new Date().getTime() - start)); start = new Date().getTime(); // Completion not allowed inside comments, bail out if this is the case - let insideComment = isInsideComment(sourceFile, currentToken, position); + const insideComment = isInsideComment(sourceFile, currentToken, position); log("getCompletionData: Is inside comment: " + (new Date().getTime() - start)); if (insideComment) { @@ -3014,7 +3013,7 @@ namespace ts { // /** @type {number | string} */ // Completion should work in the brackets let insideJsDocTagExpression = false; - let tag = getJsDocTagAtPosition(sourceFile, position); + const tag = getJsDocTagAtPosition(sourceFile, position); if (tag) { if (tag.tagName.pos <= position && position <= tag.tagName.end) { isJsDocTagName = true; @@ -3024,7 +3023,7 @@ namespace ts { case SyntaxKind.JSDocTypeTag: case SyntaxKind.JSDocParameterTag: case SyntaxKind.JSDocReturnTag: - let tagWithExpression = tag; + const tagWithExpression = tag; if (tagWithExpression.typeExpression) { insideJsDocTagExpression = tagWithExpression.typeExpression.pos < position && position < tagWithExpression.typeExpression.end; } @@ -3045,7 +3044,7 @@ namespace ts { } start = new Date().getTime(); - let previousToken = findPrecedingToken(position, sourceFile); + const previousToken = findPrecedingToken(position, sourceFile); log("getCompletionData: Get previous token 1: " + (new Date().getTime() - start)); // The decision to provide completion depends on the contextToken, which is determined through the previousToken. @@ -3055,7 +3054,7 @@ namespace ts { // Check if the caret is at the end of an identifier; this is a partial identifier that we want to complete: e.g. a.toS| // Skip this partial identifier and adjust the contextToken to the token that precedes it. if (contextToken && position <= contextToken.end && isWord(contextToken.kind)) { - let start = new Date().getTime(); + const start = new Date().getTime(); contextToken = findPrecedingToken(contextToken.getFullStart(), sourceFile); log("getCompletionData: Get previous token 2: " + (new Date().getTime() - start)); } @@ -3076,7 +3075,7 @@ namespace ts { return undefined; } - let { parent, kind } = contextToken; + const { parent, kind } = contextToken; if (kind === SyntaxKind.DotToken) { if (parent.kind === SyntaxKind.PropertyAccessExpression) { node = (contextToken.parent).expression; @@ -3103,7 +3102,7 @@ namespace ts { } } - let semanticStart = new Date().getTime(); + const semanticStart = new Date().getTime(); let isMemberCompletion: boolean; let isNewIdentifierLocation: boolean; let symbols: Symbol[] = []; @@ -3112,7 +3111,7 @@ namespace ts { getTypeScriptMemberSymbols(); } else if (isRightOfOpenTag) { - let tagSymbols = typeChecker.getJsxIntrinsicTagNames(); + const tagSymbols = typeChecker.getJsxIntrinsicTagNames(); if (tryGetGlobalSymbols()) { symbols = tagSymbols.concat(symbols.filter(s => !!(s.flags & SymbolFlags.Value))); } @@ -3123,7 +3122,7 @@ namespace ts { isNewIdentifierLocation = false; } else if (isStartingCloseTag) { - let tagName = (contextToken.parent.parent).openingElement.tagName; + const tagName = (contextToken.parent.parent).openingElement.tagName; symbols = [typeChecker.getSymbolAtLocation(tagName)]; isMemberCompletion = true; @@ -3157,7 +3156,7 @@ namespace ts { if (symbol && symbol.flags & SymbolFlags.HasExports) { // Extract module or enum members - let exportedSymbols = typeChecker.getExportsOfModule(symbol); + const exportedSymbols = typeChecker.getExportsOfModule(symbol); forEach(exportedSymbols, symbol => { if (typeChecker.isValidPropertyAccess((node.parent), symbol.name)) { symbols.push(symbol); @@ -3166,14 +3165,14 @@ namespace ts { } } - let type = typeChecker.getTypeAtLocation(node); + const type = typeChecker.getTypeAtLocation(node); addTypeProperties(type); } function addTypeProperties(type: Type) { if (type) { // Filter private properties - for (let symbol of type.getApparentProperties()) { + for (const symbol of type.getApparentProperties()) { if (typeChecker.isValidPropertyAccess((node.parent), symbol.name)) { symbols.push(symbol); } @@ -3185,8 +3184,8 @@ namespace ts { // each individual type has. This is because we're going to add all identifiers // anyways. So we might as well elevate the members that were at least part // of the individual types to a higher status since we know what they are. - let unionType = type; - for (let elementType of unionType.types) { + const unionType = type; + for (const elementType of unionType.types) { addTypeProperties(elementType); } } @@ -3256,14 +3255,14 @@ namespace ts { // - 'contextToken' was adjusted to the token prior to 'previousToken' // because we were at the end of an identifier. // - 'previousToken' is defined. - let adjustedPosition = previousToken !== contextToken ? + const adjustedPosition = previousToken !== contextToken ? previousToken.getStart() : position; - let scopeNode = getScopeNode(contextToken, adjustedPosition, sourceFile) || sourceFile; + const scopeNode = getScopeNode(contextToken, adjustedPosition, sourceFile) || sourceFile; /// TODO filter meaning based on the current context - let symbolMeanings = SymbolFlags.Type | SymbolFlags.Value | SymbolFlags.Namespace | SymbolFlags.Alias; + const symbolMeanings = SymbolFlags.Type | SymbolFlags.Value | SymbolFlags.Namespace | SymbolFlags.Alias; symbols = typeChecker.getSymbolsInScope(scopeNode, symbolMeanings); return true; @@ -3282,8 +3281,8 @@ namespace ts { } function isCompletionListBlocker(contextToken: Node): boolean { - let start = new Date().getTime(); - let result = isInStringOrRegularExpressionOrTemplateLiteral(contextToken) || + const start = new Date().getTime(); + const result = isInStringOrRegularExpressionOrTemplateLiteral(contextToken) || isSolelyIdentifierDefinitionLocation(contextToken) || isDotOfNumericLiteral(contextToken) || isInJsxText(contextToken); @@ -3310,27 +3309,27 @@ namespace ts { function isNewIdentifierDefinitionLocation(previousToken: Node): boolean { if (previousToken) { - let containingNodeKind = previousToken.parent.kind; + const containingNodeKind = previousToken.parent.kind; switch (previousToken.kind) { case SyntaxKind.CommaToken: return containingNodeKind === SyntaxKind.CallExpression // func( a, | || containingNodeKind === SyntaxKind.Constructor // constructor( a, | /* public, protected, private keywords are allowed here, so show completion */ || containingNodeKind === SyntaxKind.NewExpression // new C(a, | || containingNodeKind === SyntaxKind.ArrayLiteralExpression // [a, | - || containingNodeKind === SyntaxKind.BinaryExpression // let x = (a, | + || containingNodeKind === SyntaxKind.BinaryExpression // const x = (a, | || containingNodeKind === SyntaxKind.FunctionType; // var x: (s: string, list| case SyntaxKind.OpenParenToken: return containingNodeKind === SyntaxKind.CallExpression // func( | || containingNodeKind === SyntaxKind.Constructor // constructor( | || containingNodeKind === SyntaxKind.NewExpression // new C(a| - || containingNodeKind === SyntaxKind.ParenthesizedExpression // let x = (a| + || containingNodeKind === SyntaxKind.ParenthesizedExpression // const x = (a| || containingNodeKind === SyntaxKind.ParenthesizedType; // function F(pred: (a| /* this can become an arrow function, where 'a' is the argument */ case SyntaxKind.OpenBracketToken: return containingNodeKind === SyntaxKind.ArrayLiteralExpression // [ | || containingNodeKind === SyntaxKind.IndexSignature // [ | : string ] - || containingNodeKind === SyntaxKind.ComputedPropertyName // [ | /* this can become an index signature */ + || containingNodeKind === SyntaxKind.ComputedPropertyName; // [ | /* this can become an index signature */ case SyntaxKind.ModuleKeyword: // module | case SyntaxKind.NamespaceKeyword: // namespace | @@ -3343,7 +3342,7 @@ namespace ts { return containingNodeKind === SyntaxKind.ClassDeclaration; // class A{ | case SyntaxKind.EqualsToken: - return containingNodeKind === SyntaxKind.VariableDeclaration // let x = a| + return containingNodeKind === SyntaxKind.VariableDeclaration // const x = a| || containingNodeKind === SyntaxKind.BinaryExpression; // x = a| case SyntaxKind.TemplateHead: @@ -3375,8 +3374,8 @@ namespace ts { || contextToken.kind === SyntaxKind.StringLiteralType || contextToken.kind === SyntaxKind.RegularExpressionLiteral || isTemplateLiteralKind(contextToken.kind)) { - let start = contextToken.getStart(); - let end = contextToken.getEnd(); + const start = contextToken.getStart(); + const end = contextToken.getEnd(); // To be "in" one of these literals, the position has to be: // 1. entirely within the token text. @@ -3420,7 +3419,7 @@ namespace ts { // We are *only* completing on properties from the type being destructured. isNewIdentifierLocation = false; - let rootDeclaration = getRootDeclaration(objectLikeContainer.parent); + const rootDeclaration = getRootDeclaration(objectLikeContainer.parent); if (isVariableLike(rootDeclaration)) { // We don't want to complete using the type acquired by the shape // of the binding pattern; we are only interested in types acquired @@ -3431,7 +3430,7 @@ namespace ts { } } else { - Debug.fail("Root declaration is not variable-like.") + Debug.fail("Root declaration is not variable-like."); } } else { @@ -3442,7 +3441,7 @@ namespace ts { return false; } - let typeMembers = typeChecker.getPropertiesOfType(typeForObject); + const typeMembers = typeChecker.getPropertiesOfType(typeForObject); if (typeMembers && typeMembers.length > 0) { // Add filtered items to the completion list symbols = filterObjectMembersList(typeMembers, existingMembers); @@ -3466,11 +3465,11 @@ namespace ts { * @returns true if 'symbols' was successfully populated; false otherwise. */ function tryGetImportOrExportClauseCompletionSymbols(namedImportsOrExports: NamedImportsOrExports): boolean { - let declarationKind = namedImportsOrExports.kind === SyntaxKind.NamedImports ? + const declarationKind = namedImportsOrExports.kind === SyntaxKind.NamedImports ? SyntaxKind.ImportDeclaration : SyntaxKind.ExportDeclaration; - let importOrExportDeclaration = getAncestor(namedImportsOrExports, declarationKind); - let moduleSpecifier = importOrExportDeclaration.moduleSpecifier; + const importOrExportDeclaration = getAncestor(namedImportsOrExports, declarationKind); + const moduleSpecifier = importOrExportDeclaration.moduleSpecifier; if (!moduleSpecifier) { return false; @@ -3480,7 +3479,7 @@ namespace ts { isNewIdentifierLocation = false; let exports: Symbol[]; - let moduleSpecifierSymbol = typeChecker.getSymbolAtLocation(importOrExportDeclaration.moduleSpecifier); + const moduleSpecifierSymbol = typeChecker.getSymbolAtLocation(importOrExportDeclaration.moduleSpecifier); if (moduleSpecifierSymbol) { exports = typeChecker.getExportsOfModule(moduleSpecifierSymbol); } @@ -3497,9 +3496,9 @@ namespace ts { function tryGetObjectLikeCompletionContainer(contextToken: Node): ObjectLiteralExpression | BindingPattern { if (contextToken) { switch (contextToken.kind) { - case SyntaxKind.OpenBraceToken: // let x = { | - case SyntaxKind.CommaToken: // let x = { a: 0, | - let parent = contextToken.parent; + case SyntaxKind.OpenBraceToken: // const x = { | + case SyntaxKind.CommaToken: // const x = { a: 0, | + const parent = contextToken.parent; if (parent && (parent.kind === SyntaxKind.ObjectLiteralExpression || parent.kind === SyntaxKind.ObjectBindingPattern)) { return parent; } @@ -3532,8 +3531,8 @@ namespace ts { function tryGetContainingJsxElement(contextToken: Node): JsxOpeningLikeElement { if (contextToken) { - let parent = contextToken.parent; - switch(contextToken.kind) { + const parent = contextToken.parent; + switch (contextToken.kind) { case SyntaxKind.LessThanSlashToken: case SyntaxKind.SlashToken: case SyntaxKind.Identifier: @@ -3596,7 +3595,7 @@ namespace ts { * @returns true if we are certain that the currently edited location must define a new location; false otherwise. */ function isSolelyIdentifierDefinitionLocation(contextToken: Node): boolean { - let containingNodeKind = contextToken.parent.kind; + const containingNodeKind = contextToken.parent.kind; switch (contextToken.kind) { case SyntaxKind.CommaToken: return containingNodeKind === SyntaxKind.VariableDeclaration || @@ -3626,13 +3625,13 @@ namespace ts { case SyntaxKind.OpenBraceToken: return containingNodeKind === SyntaxKind.EnumDeclaration || // enum a { | containingNodeKind === SyntaxKind.InterfaceDeclaration || // interface a { | - containingNodeKind === SyntaxKind.TypeLiteral; // let x : { | + containingNodeKind === SyntaxKind.TypeLiteral; // const x : { | case SyntaxKind.SemicolonToken: return containingNodeKind === SyntaxKind.PropertySignature && contextToken.parent && contextToken.parent.parent && (contextToken.parent.parent.kind === SyntaxKind.InterfaceDeclaration || // interface a { f; | - contextToken.parent.parent.kind === SyntaxKind.TypeLiteral); // let x : { a; | + contextToken.parent.parent.kind === SyntaxKind.TypeLiteral); // const x : { a; | case SyntaxKind.LessThanToken: return containingNodeKind === SyntaxKind.ClassDeclaration || // class A< | @@ -3699,7 +3698,7 @@ namespace ts { function isDotOfNumericLiteral(contextToken: Node): boolean { if (contextToken.kind === SyntaxKind.NumericLiteral) { - let text = contextToken.getFullText(); + const text = contextToken.getFullText(); return text.charAt(text.length - 1) === "."; } @@ -3716,15 +3715,15 @@ namespace ts { * do not occur at the current position and have not otherwise been typed. */ function filterNamedImportOrExportCompletionItems(exportsOfModule: Symbol[], namedImportsOrExports: ImportOrExportSpecifier[]): Symbol[] { - let exisingImportsOrExports: Map = {}; + const exisingImportsOrExports: Map = {}; - for (let element of namedImportsOrExports) { + for (const element of namedImportsOrExports) { // If this is the current item we are editing right now, do not filter it out if (element.getStart() <= position && position <= element.getEnd()) { continue; } - let name = element.propertyName || element.name; + const name = element.propertyName || element.name; exisingImportsOrExports[name.text] = true; } @@ -3746,8 +3745,8 @@ namespace ts { return contextualMemberSymbols; } - let existingMemberNames: Map = {}; - for (let m of existingMembers) { + const existingMemberNames: Map = {}; + for (const m of existingMembers) { // Ignore omitted expressions for missing members if (m.kind !== SyntaxKind.PropertyAssignment && m.kind !== SyntaxKind.ShorthandPropertyAssignment && @@ -3766,7 +3765,7 @@ namespace ts { if (m.kind === SyntaxKind.BindingElement && (m).propertyName) { // include only identifiers in completion list if ((m).propertyName.kind === SyntaxKind.Identifier) { - existingName = ((m).propertyName).text + existingName = ((m).propertyName).text; } } else { @@ -3789,8 +3788,8 @@ namespace ts { * do not occur at the current position and have not otherwise been typed. */ function filterJsxAttributes(symbols: Symbol[], attributes: NodeArray): Symbol[] { - let seenNames: Map = {}; - for (let attr of attributes) { + const seenNames: Map = {}; + for (const attr of attributes) { // If this is the current item we are editing right now, do not filter it out if (attr.getStart() <= position && position <= attr.getEnd()) { continue; @@ -3809,21 +3808,21 @@ namespace ts { function getCompletionsAtPosition(fileName: string, position: number): CompletionInfo { synchronizeHostData(); - let completionData = getCompletionData(fileName, position); + const completionData = getCompletionData(fileName, position); if (!completionData) { return undefined; } - let { symbols, isMemberCompletion, isNewIdentifierLocation, location, isRightOfDot, isJsDocTagName } = completionData; + const { symbols, isMemberCompletion, isNewIdentifierLocation, location, isRightOfDot, isJsDocTagName } = completionData; if (isJsDocTagName) { // If the current position is a jsDoc tag name, only tag names should be provided for completion return { isMemberCompletion: false, isNewIdentifierLocation: false, entries: getAllJsDocCompletionEntries() }; } - let sourceFile = getValidSourceFile(fileName); + const sourceFile = getValidSourceFile(fileName); - let entries: CompletionEntry[] = []; + const entries: CompletionEntry[] = []; if (isRightOfDot && isSourceFileJavaScript(sourceFile)) { const uniqueNames = getCompletionEntriesFromSymbols(symbols, entries); @@ -3845,16 +3844,16 @@ namespace ts { return { isMemberCompletion, isNewIdentifierLocation, entries }; function getJavaScriptCompletionEntries(sourceFile: SourceFile, uniqueNames: Map): CompletionEntry[] { - let entries: CompletionEntry[] = []; - let target = program.getCompilerOptions().target; + const entries: CompletionEntry[] = []; + const target = program.getCompilerOptions().target; - let nameTable = getNameTable(sourceFile); - for (let name in nameTable) { + const nameTable = getNameTable(sourceFile); + for (const name in nameTable) { if (!uniqueNames[name]) { uniqueNames[name] = name; - let displayName = getCompletionEntryDisplayName(name, target, /*performCharacterChecks:*/ true); + const displayName = getCompletionEntryDisplayName(name, target, /*performCharacterChecks*/ true); if (displayName) { - let entry = { + const entry = { name: displayName, kind: ScriptElementKind.warning, kindModifiers: "", @@ -3875,7 +3874,7 @@ namespace ts { kind: ScriptElementKind.keyword, kindModifiers: "", sortText: "0", - } + }; })); } @@ -3883,7 +3882,7 @@ namespace ts { // Try to get a valid display name for this symbol, if we could not find one, then ignore it. // We would like to only show things that can be added after a dot, so for instance numeric properties can // not be accessed with a dot (a.1 <- invalid) - let displayName = getCompletionEntryDisplayNameForSymbol(symbol, program.getCompilerOptions().target, /*performCharacterChecks:*/ true, location); + const displayName = getCompletionEntryDisplayNameForSymbol(symbol, program.getCompilerOptions().target, /*performCharacterChecks*/ true, location); if (!displayName) { return undefined; } @@ -3905,13 +3904,13 @@ namespace ts { } function getCompletionEntriesFromSymbols(symbols: Symbol[], entries: CompletionEntry[]): Map { - let start = new Date().getTime(); - let uniqueNames: Map = {}; + const start = new Date().getTime(); + const uniqueNames: Map = {}; if (symbols) { - for (let symbol of symbols) { - let entry = createCompletionEntry(symbol, location); + for (const symbol of symbols) { + const entry = createCompletionEntry(symbol, location); if (entry) { - let id = escapeIdentifier(entry.name); + const id = escapeIdentifier(entry.name); if (!lookUp(uniqueNames, id)) { entries.push(entry); uniqueNames[id] = id; @@ -3929,19 +3928,19 @@ namespace ts { synchronizeHostData(); // Compute all the completion symbols again. - let completionData = getCompletionData(fileName, position); + const completionData = getCompletionData(fileName, position); if (completionData) { - let { symbols, location } = completionData; + const { symbols, location } = completionData; // Find the symbol with the matching entry name. - let target = program.getCompilerOptions().target; + const target = program.getCompilerOptions().target; // We don't need to perform character checks here because we're only comparing the // name against 'entryName' (which is known to be good), not building a new // completion entry. - let symbol = forEach(symbols, s => getCompletionEntryDisplayNameForSymbol(s, target, /*performCharacterChecks:*/ false, location) === entryName ? s : undefined); + const symbol = forEach(symbols, s => getCompletionEntryDisplayNameForSymbol(s, target, /*performCharacterChecks*/ false, location) === entryName ? s : undefined); if (symbol) { - let { displayParts, documentation, symbolKind } = getSymbolDisplayPartsDocumentationAndSymbolKind(symbol, getValidSourceFile(fileName), location, location, SemanticMeaning.All); + const { displayParts, documentation, symbolKind } = getSymbolDisplayPartsDocumentationAndSymbolKind(symbol, getValidSourceFile(fileName), location, location, SemanticMeaning.All); return { name: entryName, kindModifiers: getSymbolModifiers(symbol), @@ -3953,7 +3952,7 @@ namespace ts { } // Didn't find a symbol with this name. See if we can find a keyword instead. - let keywordCompletion = forEach(keywordCompletions, c => c.name === entryName); + const keywordCompletion = forEach(keywordCompletions, c => c.name === entryName); if (keywordCompletion) { return { name: entryName, @@ -3969,7 +3968,7 @@ namespace ts { // TODO(drosen): use contextual SemanticMeaning. function getSymbolKind(symbol: Symbol, location: Node): string { - let flags = symbol.getFlags(); + const flags = symbol.getFlags(); if (flags & SymbolFlags.Class) return getDeclarationOfKind(symbol, SyntaxKind.ClassExpression) ? ScriptElementKind.localClassElement : ScriptElementKind.classElement; @@ -3978,7 +3977,7 @@ namespace ts { if (flags & SymbolFlags.Interface) return ScriptElementKind.interfaceElement; if (flags & SymbolFlags.TypeParameter) return ScriptElementKind.typeParameterElement; - let result = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(symbol, flags, location); + const result = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(symbol, flags, location); if (result === ScriptElementKind.unknown) { if (flags & SymbolFlags.TypeParameter) return ScriptElementKind.typeParameterElement; if (flags & SymbolFlags.EnumMember) return ScriptElementKind.variableElement; @@ -3990,7 +3989,7 @@ namespace ts { } function getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(symbol: Symbol, flags: SymbolFlags, location: Node) { - let typeChecker = program.getTypeChecker(); + const typeChecker = program.getTypeChecker(); if (typeChecker.isUndefinedSymbol(symbol)) { return ScriptElementKind.variableElement; @@ -4019,8 +4018,8 @@ namespace ts { if (flags & SymbolFlags.Property) { if (flags & SymbolFlags.SyntheticProperty) { // If union property is result of union of non method (property/accessors/variables), it is labeled as property - let unionPropertyKind = forEach(typeChecker.getRootSymbols(symbol), rootSymbol => { - let rootSymbolFlags = rootSymbol.getFlags(); + const unionPropertyKind = forEach(typeChecker.getRootSymbols(symbol), rootSymbol => { + const rootSymbolFlags = rootSymbol.getFlags(); if (rootSymbolFlags & (SymbolFlags.PropertyOrAccessor | SymbolFlags.Variable)) { return ScriptElementKind.memberVariableElement; } @@ -4028,8 +4027,8 @@ namespace ts { }); if (!unionPropertyKind) { // If this was union of all methods, - //make sure it has call signatures before we can label it as method - let typeOfUnionProperty = typeChecker.getTypeOfSymbolAtLocation(symbol, location); + // make sure it has call signatures before we can label it as method + const typeOfUnionProperty = typeChecker.getTypeOfSymbolAtLocation(symbol, location); if (typeOfUnionProperty.getCallSignatures().length) { return ScriptElementKind.memberFunctionElement; } @@ -4053,11 +4052,11 @@ namespace ts { function getSymbolDisplayPartsDocumentationAndSymbolKind(symbol: Symbol, sourceFile: SourceFile, enclosingDeclaration: Node, location: Node, semanticMeaning = getMeaningFromLocation(location)) { - let typeChecker = program.getTypeChecker(); + const typeChecker = program.getTypeChecker(); - let displayParts: SymbolDisplayPart[] = []; + const displayParts: SymbolDisplayPart[] = []; let documentation: SymbolDisplayPart[]; - let symbolFlags = symbol.flags; + const symbolFlags = symbol.flags; let symbolKind = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(symbol, symbolFlags, location); let hasAddedSymbolInfo: boolean; let type: Type; @@ -4073,7 +4072,7 @@ namespace ts { type = typeChecker.getTypeOfSymbolAtLocation(symbol, location); if (type) { if (location.parent && location.parent.kind === SyntaxKind.PropertyAccessExpression) { - let right = (location.parent).name; + const right = (location.parent).name; // Either the location is on the right of a property access, or on the left and the right is missing if (right === location || (right && right.getFullWidth() === 0)) { location = location.parent; @@ -4090,15 +4089,15 @@ namespace ts { } if (callExpression) { - let candidateSignatures: Signature[] = []; + const candidateSignatures: Signature[] = []; signature = typeChecker.getResolvedSignature(callExpression, candidateSignatures); if (!signature && candidateSignatures.length) { // Use the first candidate: signature = candidateSignatures[0]; } - let useConstructSignatures = callExpression.kind === SyntaxKind.NewExpression || callExpression.expression.kind === SyntaxKind.SuperKeyword; - let allSignatures = useConstructSignatures ? type.getConstructSignatures() : type.getCallSignatures(); + const useConstructSignatures = callExpression.kind === SyntaxKind.NewExpression || callExpression.expression.kind === SyntaxKind.SuperKeyword; + const allSignatures = useConstructSignatures ? type.getConstructSignatures() : type.getCallSignatures(); if (!contains(allSignatures, signature.target) && !contains(allSignatures, signature)) { // Get the first signature if there is one -- allSignatures may contain @@ -4156,8 +4155,8 @@ namespace ts { else if ((isNameOfFunctionDeclaration(location) && !(symbol.flags & SymbolFlags.Accessor)) || // name of function declaration (location.kind === SyntaxKind.ConstructorKeyword && location.parent.kind === SyntaxKind.Constructor)) { // At constructor keyword of constructor declaration // get the signature from the declaration and write it - let functionDeclaration = location.parent; - let allSignatures = functionDeclaration.kind === SyntaxKind.Constructor ? type.getConstructSignatures() : type.getCallSignatures(); + const functionDeclaration = location.parent; + const allSignatures = functionDeclaration.kind === SyntaxKind.Constructor ? type.getConstructSignatures() : type.getCallSignatures(); if (!typeChecker.isImplementationOfOverload(functionDeclaration)) { signature = typeChecker.getSignatureFromDeclaration(functionDeclaration); } @@ -4226,8 +4225,8 @@ namespace ts { } if (symbolFlags & SymbolFlags.Module) { addNewLineIfDisplayPartsExist(); - let declaration = getDeclarationOfKind(symbol, SyntaxKind.ModuleDeclaration); - let isNamespace = declaration && declaration.name && declaration.name.kind === SyntaxKind.Identifier; + const declaration = getDeclarationOfKind(symbol, SyntaxKind.ModuleDeclaration); + const isNamespace = declaration && declaration.name && declaration.name.kind === SyntaxKind.Identifier; displayParts.push(keywordPart(isNamespace ? SyntaxKind.NamespaceKeyword : SyntaxKind.ModuleKeyword)); displayParts.push(spacePart()); addFullSymbolName(symbol); @@ -4279,9 +4278,9 @@ namespace ts { } if (symbolFlags & SymbolFlags.EnumMember) { addPrefixForAnyFunctionOrVar(symbol, "enum member"); - let declaration = symbol.declarations[0]; + const declaration = symbol.declarations[0]; if (declaration.kind === SyntaxKind.EnumMember) { - let constantValue = typeChecker.getConstantValue(declaration); + const constantValue = typeChecker.getConstantValue(declaration); if (constantValue !== undefined) { displayParts.push(spacePart()); displayParts.push(operatorPart(SyntaxKind.EqualsToken)); @@ -4297,7 +4296,7 @@ namespace ts { addFullSymbolName(symbol); ts.forEach(symbol.declarations, declaration => { if (declaration.kind === SyntaxKind.ImportEqualsDeclaration) { - let importEqualsDeclaration = declaration; + const importEqualsDeclaration = declaration; if (isExternalModuleImportEqualsDeclaration(importEqualsDeclaration)) { displayParts.push(spacePart()); displayParts.push(operatorPart(SyntaxKind.EqualsToken)); @@ -4308,7 +4307,7 @@ namespace ts { displayParts.push(punctuationPart(SyntaxKind.CloseParenToken)); } else { - let internalAliasSymbol = typeChecker.getSymbolAtLocation(importEqualsDeclaration.moduleReference); + const internalAliasSymbol = typeChecker.getSymbolAtLocation(importEqualsDeclaration.moduleReference); if (internalAliasSymbol) { displayParts.push(spacePart()); displayParts.push(operatorPart(SyntaxKind.EqualsToken)); @@ -4332,7 +4331,7 @@ namespace ts { displayParts.push(spacePart()); // If the type is type parameter, format it specially if (type.symbol && type.symbol.flags & SymbolFlags.TypeParameter) { - let typeParameterParts = mapToDisplayParts(writer => { + const typeParameterParts = mapToDisplayParts(writer => { typeChecker.getSymbolDisplayBuilder().buildTypeParameterDisplay(type, writer, enclosingDeclaration); }); addRange(displayParts, typeParameterParts); @@ -4347,7 +4346,7 @@ namespace ts { symbolFlags & SymbolFlags.Signature || symbolFlags & SymbolFlags.Accessor || symbolKind === ScriptElementKind.memberFunctionElement) { - let allSignatures = type.getCallSignatures(); + const allSignatures = type.getCallSignatures(); addSignatureDisplayParts(allSignatures[0], allSignatures); } } @@ -4370,7 +4369,7 @@ namespace ts { } function addFullSymbolName(symbol: Symbol, enclosingDeclaration?: Node) { - let fullSymbolDisplayParts = symbolToDisplayParts(typeChecker, symbol, enclosingDeclaration || sourceFile, /*meaning*/ undefined, + const fullSymbolDisplayParts = symbolToDisplayParts(typeChecker, symbol, enclosingDeclaration || sourceFile, /*meaning*/ undefined, SymbolFormatFlags.WriteTypeParametersOrArguments | SymbolFormatFlags.UseOnlyExternalAliasing); addRange(displayParts, fullSymbolDisplayParts); } @@ -4416,7 +4415,7 @@ namespace ts { } function writeTypeParametersOfSymbol(symbol: Symbol, enclosingDeclaration: Node) { - let typeParameterParts = mapToDisplayParts(writer => { + const typeParameterParts = mapToDisplayParts(writer => { typeChecker.getSymbolDisplayBuilder().buildTypeParameterDisplayFromSymbol(symbol, writer, enclosingDeclaration); }); addRange(displayParts, typeParameterParts); @@ -4426,8 +4425,8 @@ namespace ts { function getQuickInfoAtPosition(fileName: string, position: number): QuickInfo { synchronizeHostData(); - let sourceFile = getValidSourceFile(fileName); - let node = getTouchingPropertyName(sourceFile, position); + const sourceFile = getValidSourceFile(fileName); + const node = getTouchingPropertyName(sourceFile, position); if (!node) { return undefined; } @@ -4436,8 +4435,8 @@ namespace ts { return undefined; } - let typeChecker = program.getTypeChecker(); - let symbol = typeChecker.getSymbolAtLocation(node); + const typeChecker = program.getTypeChecker(); + const symbol = typeChecker.getSymbolAtLocation(node); if (!symbol) { // Try getting just type at this position and show @@ -4449,7 +4448,7 @@ namespace ts { case SyntaxKind.ThisType: case SyntaxKind.SuperKeyword: // For the identifiers/this/super etc get the type at position - let type = typeChecker.getTypeAtLocation(node); + const type = typeChecker.getTypeAtLocation(node); if (type) { return { kind: ScriptElementKind.unknown, @@ -4464,7 +4463,7 @@ namespace ts { return undefined; } - let displayPartsDocumentationsAndKind = getSymbolDisplayPartsDocumentationAndSymbolKind(symbol, sourceFile, getContainerNode(node), node); + const displayPartsDocumentationsAndKind = getSymbolDisplayPartsDocumentationAndSymbolKind(symbol, sourceFile, getContainerNode(node), node); return { kind: displayPartsDocumentationsAndKind.symbolKind, kindModifiers: getSymbolModifiers(symbol), @@ -4486,13 +4485,13 @@ namespace ts { } function getDefinitionFromSymbol(symbol: Symbol, node: Node): DefinitionInfo[] { - let typeChecker = program.getTypeChecker(); - let result: DefinitionInfo[] = []; - let declarations = symbol.getDeclarations(); - let symbolName = typeChecker.symbolToString(symbol); // Do not get scoped name, just the name of the symbol - let symbolKind = getSymbolKind(symbol, node); - let containerSymbol = symbol.parent; - let containerName = containerSymbol ? typeChecker.symbolToString(containerSymbol, node) : ""; + const typeChecker = program.getTypeChecker(); + const result: DefinitionInfo[] = []; + const declarations = symbol.getDeclarations(); + const symbolName = typeChecker.symbolToString(symbol); // Do not get scoped name, just the name of the symbol + const symbolKind = getSymbolKind(symbol, node); + const containerSymbol = symbol.parent; + const containerName = containerSymbol ? typeChecker.symbolToString(containerSymbol, node) : ""; if (!tryAddConstructSignature(symbol, node, symbolKind, symbolName, containerName, result) && !tryAddCallSignature(symbol, node, symbolKind, symbolName, containerName, result)) { @@ -4510,7 +4509,7 @@ namespace ts { if (isNewExpressionTarget(location) || location.kind === SyntaxKind.ConstructorKeyword) { if (symbol.flags & SymbolFlags.Class) { // Find the first class-like declaration and try to get the construct signature. - for (let declaration of symbol.getDeclarations()) { + for (const declaration of symbol.getDeclarations()) { if (isClassLike(declaration)) { return tryAddSignature(declaration.members, /*selectConstructors*/ true, @@ -4535,7 +4534,7 @@ namespace ts { } function tryAddSignature(signatureDeclarations: Declaration[], selectConstructors: boolean, symbolKind: string, symbolName: string, containerName: string, result: DefinitionInfo[]) { - let declarations: Declaration[] = []; + const declarations: Declaration[] = []; let definition: Declaration; forEach(signatureDeclarations, d => { @@ -4563,24 +4562,24 @@ namespace ts { function getDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[] { synchronizeHostData(); - let sourceFile = getValidSourceFile(fileName); + const sourceFile = getValidSourceFile(fileName); - let node = getTouchingPropertyName(sourceFile, position); + const node = getTouchingPropertyName(sourceFile, position); if (!node) { return undefined; } // Labels if (isJumpStatementTarget(node)) { - let labelName = (node).text; - let label = getTargetLabel((node.parent), (node).text); + const labelName = (node).text; + const label = getTargetLabel((node.parent), (node).text); return label ? [createDefinitionInfo(label, ScriptElementKind.label, labelName, /*containerName*/ undefined)] : undefined; } /// Triple slash reference comments - let comment = forEach(sourceFile.referencedFiles, r => (r.pos <= position && position < r.end) ? r : undefined); + const comment = forEach(sourceFile.referencedFiles, r => (r.pos <= position && position < r.end) ? r : undefined); if (comment) { - let referenceFile = tryResolveScriptReference(program, sourceFile, comment); + const referenceFile = tryResolveScriptReference(program, sourceFile, comment); if (referenceFile) { return [{ fileName: referenceFile.fileName, @@ -4594,7 +4593,7 @@ namespace ts { return undefined; } - let typeChecker = program.getTypeChecker(); + const typeChecker = program.getTypeChecker(); let symbol = typeChecker.getSymbolAtLocation(node); // Could not find a symbol e.g. node is string or number keyword, @@ -4608,7 +4607,7 @@ namespace ts { // import {A, B} from "mod"; // to jump to the implementation directly. if (symbol.flags & SymbolFlags.Alias) { - let declaration = symbol.declarations[0]; + const declaration = symbol.declarations[0]; if (node.kind === SyntaxKind.Identifier && node.parent === declaration) { symbol = typeChecker.getAliasedSymbol(symbol); } @@ -4620,15 +4619,15 @@ namespace ts { // is performed at the location of property access, we would like to go to definition of the property in the short-hand // assignment. This case and others are handled by the following code. if (node.parent.kind === SyntaxKind.ShorthandPropertyAssignment) { - let shorthandSymbol = typeChecker.getShorthandAssignmentValueSymbol(symbol.valueDeclaration); + const shorthandSymbol = typeChecker.getShorthandAssignmentValueSymbol(symbol.valueDeclaration); if (!shorthandSymbol) { return []; } - let shorthandDeclarations = shorthandSymbol.getDeclarations(); - let shorthandSymbolKind = getSymbolKind(shorthandSymbol, node); - let shorthandSymbolName = typeChecker.symbolToString(shorthandSymbol); - let shorthandContainerName = typeChecker.symbolToString(symbol.parent, node); + const shorthandDeclarations = shorthandSymbol.getDeclarations(); + const shorthandSymbolKind = getSymbolKind(shorthandSymbol, node); + const shorthandSymbolName = typeChecker.symbolToString(shorthandSymbol); + const shorthandContainerName = typeChecker.symbolToString(symbol.parent, node); return map(shorthandDeclarations, declaration => createDefinitionInfo(declaration, shorthandSymbolKind, shorthandSymbolName, shorthandContainerName)); } @@ -4640,27 +4639,27 @@ namespace ts { function getTypeDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[] { synchronizeHostData(); - let sourceFile = getValidSourceFile(fileName); + const sourceFile = getValidSourceFile(fileName); - let node = getTouchingPropertyName(sourceFile, position); + const node = getTouchingPropertyName(sourceFile, position); if (!node) { return undefined; } - let typeChecker = program.getTypeChecker(); + const typeChecker = program.getTypeChecker(); - let symbol = typeChecker.getSymbolAtLocation(node); + const symbol = typeChecker.getSymbolAtLocation(node); if (!symbol) { return undefined; } - let type = typeChecker.getTypeOfSymbolAtLocation(symbol, node); + const type = typeChecker.getTypeOfSymbolAtLocation(symbol, node); if (!type) { return undefined; } if (type.flags & TypeFlags.Union) { - let result: DefinitionInfo[] = []; + const result: DefinitionInfo[] = []; forEach((type).types, t => { if (t.symbol) { addRange(/*to*/ result, /*from*/ getDefinitionFromSymbol(t.symbol, node)); @@ -4680,7 +4679,7 @@ namespace ts { let results = getOccurrencesAtPositionCore(fileName, position); if (results) { - let sourceFile = getCanonicalFileName(normalizeSlashes(fileName)); + const sourceFile = getCanonicalFileName(normalizeSlashes(fileName)); // Get occurrences only supports reporting occurrences for the file queried. So // filter down to that list. @@ -4694,10 +4693,10 @@ namespace ts { synchronizeHostData(); filesToSearch = map(filesToSearch, normalizeSlashes); - let sourceFilesToSearch = filter(program.getSourceFiles(), f => contains(filesToSearch, f.fileName)); - let sourceFile = getValidSourceFile(fileName); + const sourceFilesToSearch = filter(program.getSourceFiles(), f => contains(filesToSearch, f.fileName)); + const sourceFile = getValidSourceFile(fileName); - let node = getTouchingWord(sourceFile, position); + const node = getTouchingWord(sourceFile, position); if (!node) { return undefined; } @@ -4705,8 +4704,8 @@ namespace ts { return getSemanticDocumentHighlights(node) || getSyntacticDocumentHighlights(node); function getHighlightSpanForNode(node: Node): HighlightSpan { - let start = node.getStart(); - let end = node.getEnd(); + const start = node.getStart(); + const end = node.getEnd(); return { fileName: sourceFile.fileName, @@ -4723,7 +4722,7 @@ namespace ts { isLiteralNameOfPropertyDeclarationOrIndexAccess(node) || isNameOfExternalModuleImportOrDeclaration(node)) { - let referencedSymbols = getReferencedSymbolsForNode(node, sourceFilesToSearch, /*findInStrings:*/ false, /*findInComments:*/ false); + const referencedSymbols = getReferencedSymbolsForNode(node, sourceFilesToSearch, /*findInStrings*/ false, /*findInComments*/ false); return convertReferencedSymbols(referencedSymbols); } @@ -4734,11 +4733,11 @@ namespace ts { return undefined; } - let fileNameToDocumentHighlights: Map = {}; - let result: DocumentHighlights[] = []; - for (let referencedSymbol of referencedSymbols) { - for (let referenceEntry of referencedSymbol.references) { - let fileName = referenceEntry.fileName; + const fileNameToDocumentHighlights: Map = {}; + const result: DocumentHighlights[] = []; + for (const referencedSymbol of referencedSymbols) { + for (const referenceEntry of referencedSymbol.references) { + const fileName = referenceEntry.fileName; let documentHighlights = getProperty(fileNameToDocumentHighlights, fileName); if (!documentHighlights) { documentHighlights = { fileName, highlightSpans: [] }; @@ -4759,9 +4758,9 @@ namespace ts { } function getSyntacticDocumentHighlights(node: Node): DocumentHighlights[] { - let fileName = sourceFile.fileName; + const fileName = sourceFile.fileName; - let highlightSpans = getHighlightSpans(node); + const highlightSpans = getHighlightSpans(node); if (!highlightSpans || highlightSpans.length === 0) { return undefined; } @@ -4865,7 +4864,7 @@ namespace ts { * into function boundaries and try-blocks with catch-clauses. */ function aggregateOwnedThrowStatements(node: Node): ThrowStatement[] { - let statementAccumulator: ThrowStatement[] = [] + const statementAccumulator: ThrowStatement[] = []; aggregate(node); return statementAccumulator; @@ -4874,7 +4873,7 @@ namespace ts { statementAccumulator.push(node); } else if (node.kind === SyntaxKind.TryStatement) { - let tryStatement = node; + const tryStatement = node; if (tryStatement.catchClause) { aggregate(tryStatement.catchClause); @@ -4905,7 +4904,7 @@ namespace ts { let child: Node = throwStatement; while (child.parent) { - let parent = child.parent; + const parent = child.parent; if (isFunctionBlock(parent) || parent.kind === SyntaxKind.SourceFile) { return parent; @@ -4914,7 +4913,7 @@ namespace ts { // A throw-statement is only owned by a try-statement if the try-statement has // a catch clause, and if the throw-statement occurs within the try block. if (parent.kind === SyntaxKind.TryStatement) { - let tryStatement = parent; + const tryStatement = parent; if (tryStatement.tryBlock === child && tryStatement.catchClause) { return child; @@ -4928,7 +4927,7 @@ namespace ts { } function aggregateAllBreakAndContinueStatements(node: Node): BreakOrContinueStatement[] { - let statementAccumulator: BreakOrContinueStatement[] = [] + const statementAccumulator: BreakOrContinueStatement[] = []; aggregate(node); return statementAccumulator; @@ -4944,7 +4943,7 @@ namespace ts { } function ownsBreakOrContinueStatement(owner: Node, statement: BreakOrContinueStatement): boolean { - let actualOwner = getBreakOrContinueOwner(statement); + const actualOwner = getBreakOrContinueOwner(statement); return actualOwner && actualOwner === owner; } @@ -4979,7 +4978,7 @@ namespace ts { } function getModifierOccurrences(modifier: SyntaxKind, declaration: Node): HighlightSpan[] { - let container = declaration.parent; + const container = declaration.parent; // Make sure we only highlight the keyword when it makes sense to do so. if (isAccessibilityModifier(modifier)) { @@ -5009,8 +5008,8 @@ namespace ts { return undefined; } - let keywords: Node[] = []; - let modifierFlag: NodeFlags = getFlagFromModifier(modifier); + const keywords: Node[] = []; + const modifierFlag: NodeFlags = getFlagFromModifier(modifier); let nodes: Node[]; switch (container.kind) { @@ -5035,7 +5034,7 @@ namespace ts { // If we're an accessibility modifier, we're in an instance member and should search // the constructor's parameter list for instance members as well. if (modifierFlag & NodeFlags.AccessibilityModifier) { - let constructor = forEach((container).members, member => { + const constructor = forEach((container).members, member => { return member.kind === SyntaxKind.Constructor && member; }); @@ -5048,7 +5047,7 @@ namespace ts { } break; default: - Debug.fail("Invalid container kind.") + Debug.fail("Invalid container kind."); } forEach(nodes, node => { @@ -5091,7 +5090,7 @@ namespace ts { } function getGetAndSetOccurrences(accessorDeclaration: AccessorDeclaration): HighlightSpan[] { - let keywords: Node[] = []; + const keywords: Node[] = []; tryPushAccessorKeyword(accessorDeclaration.symbol, SyntaxKind.GetAccessor); tryPushAccessorKeyword(accessorDeclaration.symbol, SyntaxKind.SetAccessor); @@ -5099,7 +5098,7 @@ namespace ts { return map(keywords, getHighlightSpanForNode); function tryPushAccessorKeyword(accessorSymbol: Symbol, accessorKind: SyntaxKind): void { - let accessor = getDeclarationOfKind(accessorSymbol, accessorKind); + const accessor = getDeclarationOfKind(accessorSymbol, accessorKind); if (accessor) { forEach(accessor.getChildren(), child => pushKeywordIf(keywords, child, SyntaxKind.GetKeyword, SyntaxKind.SetKeyword)); @@ -5108,9 +5107,9 @@ namespace ts { } function getConstructorOccurrences(constructorDeclaration: ConstructorDeclaration): HighlightSpan[] { - let declarations = constructorDeclaration.symbol.getDeclarations() + const declarations = constructorDeclaration.symbol.getDeclarations(); - let keywords: Node[] = []; + const keywords: Node[] = []; forEach(declarations, declaration => { forEach(declaration.getChildren(), token => { @@ -5122,12 +5121,12 @@ namespace ts { } function getLoopBreakContinueOccurrences(loopNode: IterationStatement): HighlightSpan[] { - let keywords: Node[] = []; + const keywords: Node[] = []; if (pushKeywordIf(keywords, loopNode.getFirstToken(), SyntaxKind.ForKeyword, SyntaxKind.WhileKeyword, SyntaxKind.DoKeyword)) { // If we succeeded and got a do-while loop, then start looking for a 'while' keyword. if (loopNode.kind === SyntaxKind.DoStatement) { - let loopTokens = loopNode.getChildren(); + const loopTokens = loopNode.getChildren(); for (let i = loopTokens.length - 1; i >= 0; i--) { if (pushKeywordIf(keywords, loopTokens[i], SyntaxKind.WhileKeyword)) { @@ -5137,7 +5136,7 @@ namespace ts { } } - let breaksAndContinues = aggregateAllBreakAndContinueStatements(loopNode.statement); + const breaksAndContinues = aggregateAllBreakAndContinueStatements(loopNode.statement); forEach(breaksAndContinues, statement => { if (ownsBreakOrContinueStatement(loopNode, statement)) { @@ -5149,7 +5148,7 @@ namespace ts { } function getBreakOrContinueStatementOccurrences(breakOrContinueStatement: BreakOrContinueStatement): HighlightSpan[] { - let owner = getBreakOrContinueOwner(breakOrContinueStatement); + const owner = getBreakOrContinueOwner(breakOrContinueStatement); if (owner) { switch (owner.kind) { @@ -5158,7 +5157,7 @@ namespace ts { case SyntaxKind.ForOfStatement: case SyntaxKind.DoStatement: case SyntaxKind.WhileStatement: - return getLoopBreakContinueOccurrences(owner) + return getLoopBreakContinueOccurrences(owner); case SyntaxKind.SwitchStatement: return getSwitchCaseDefaultOccurrences(owner); @@ -5169,7 +5168,7 @@ namespace ts { } function getSwitchCaseDefaultOccurrences(switchStatement: SwitchStatement): HighlightSpan[] { - let keywords: Node[] = []; + const keywords: Node[] = []; pushKeywordIf(keywords, switchStatement.getFirstToken(), SyntaxKind.SwitchKeyword); @@ -5177,7 +5176,7 @@ namespace ts { forEach(switchStatement.caseBlock.clauses, clause => { pushKeywordIf(keywords, clause.getFirstToken(), SyntaxKind.CaseKeyword, SyntaxKind.DefaultKeyword); - let breaksAndContinues = aggregateAllBreakAndContinueStatements(clause); + const breaksAndContinues = aggregateAllBreakAndContinueStatements(clause); forEach(breaksAndContinues, statement => { if (ownsBreakOrContinueStatement(switchStatement, statement)) { @@ -5190,7 +5189,7 @@ namespace ts { } function getTryCatchFinallyOccurrences(tryStatement: TryStatement): HighlightSpan[] { - let keywords: Node[] = []; + const keywords: Node[] = []; pushKeywordIf(keywords, tryStatement.getFirstToken(), SyntaxKind.TryKeyword); @@ -5199,7 +5198,7 @@ namespace ts { } if (tryStatement.finallyBlock) { - let finallyKeyword = findChildOfKind(tryStatement, SyntaxKind.FinallyKeyword, sourceFile); + const finallyKeyword = findChildOfKind(tryStatement, SyntaxKind.FinallyKeyword, sourceFile); pushKeywordIf(keywords, finallyKeyword, SyntaxKind.FinallyKeyword); } @@ -5207,13 +5206,13 @@ namespace ts { } function getThrowOccurrences(throwStatement: ThrowStatement): HighlightSpan[] { - let owner = getThrowStatementOwner(throwStatement); + const owner = getThrowStatementOwner(throwStatement); if (!owner) { return undefined; } - let keywords: Node[] = []; + const keywords: Node[] = []; forEach(aggregateOwnedThrowStatements(owner), throwStatement => { pushKeywordIf(keywords, throwStatement.getFirstToken(), SyntaxKind.ThrowKeyword); @@ -5231,14 +5230,14 @@ namespace ts { } function getReturnOccurrences(returnStatement: ReturnStatement): HighlightSpan[] { - let func = getContainingFunction(returnStatement); + const func = getContainingFunction(returnStatement); // If we didn't find a containing function with a block body, bail out. if (!(func && hasKind(func.body, SyntaxKind.Block))) { return undefined; } - let keywords: Node[] = [] + const keywords: Node[] = []; forEachReturnStatement(func.body, returnStatement => { pushKeywordIf(keywords, returnStatement.getFirstToken(), SyntaxKind.ReturnKeyword); }); @@ -5252,7 +5251,7 @@ namespace ts { } function getIfElseOccurrences(ifStatement: IfStatement): HighlightSpan[] { - let keywords: Node[] = []; + const keywords: Node[] = []; // Traverse upwards through all parent if-statements linked by their else-branches. while (hasKind(ifStatement.parent, SyntaxKind.IfStatement) && (ifStatement.parent).elseStatement === ifStatement) { @@ -5261,7 +5260,7 @@ namespace ts { // Now traverse back down through the else branches, aggregating if/else keywords of if-statements. while (ifStatement) { - let children = ifStatement.getChildren(); + const children = ifStatement.getChildren(); pushKeywordIf(keywords, children[0], SyntaxKind.IfKeyword); // Generally the 'else' keyword is second-to-last, so we traverse backwards. @@ -5272,20 +5271,20 @@ namespace ts { } if (!hasKind(ifStatement.elseStatement, SyntaxKind.IfStatement)) { - break + break; } ifStatement = ifStatement.elseStatement; } - let result: HighlightSpan[] = []; + const result: HighlightSpan[] = []; // We'd like to highlight else/ifs together if they are only separated by whitespace // (i.e. the keywords are separated by no comments, no newlines). for (let i = 0; i < keywords.length; i++) { if (keywords[i].kind === SyntaxKind.ElseKeyword && i < keywords.length - 1) { - let elseKeyword = keywords[i]; - let ifKeyword = keywords[i + 1]; // this *should* always be an 'if' keyword. + const elseKeyword = keywords[i]; + const ifKeyword = keywords[i + 1]; // this *should* always be an 'if' keyword. let shouldCombindElseAndIf = true; @@ -5328,9 +5327,9 @@ namespace ts { return undefined; } - let result: ReferenceEntry[] = []; - for (let entry of documentHighlights) { - for (let highlightSpan of entry.highlightSpans) { + const result: ReferenceEntry[] = []; + for (const entry of documentHighlights) { + for (const highlightSpan of entry.highlightSpans) { result.push({ fileName: entry.fileName, textSpan: highlightSpan.textSpan, @@ -5348,9 +5347,9 @@ namespace ts { return undefined; } - let referenceEntries: ReferenceEntry[] = []; + const referenceEntries: ReferenceEntry[] = []; - for (let referenceSymbol of referenceSymbols) { + for (const referenceSymbol of referenceSymbols) { addRange(referenceEntries, referenceSymbol.references); } @@ -5358,17 +5357,17 @@ namespace ts { } function findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): RenameLocation[] { - let referencedSymbols = findReferencedSymbols(fileName, position, findInStrings, findInComments); + const referencedSymbols = findReferencedSymbols(fileName, position, findInStrings, findInComments); return convertReferences(referencedSymbols); } function getReferencesAtPosition(fileName: string, position: number): ReferenceEntry[] { - let referencedSymbols = findReferencedSymbols(fileName, position, /*findInStrings:*/ false, /*findInComments:*/ false); + const referencedSymbols = findReferencedSymbols(fileName, position, /*findInStrings*/ false, /*findInComments*/ false); return convertReferences(referencedSymbols); } - function findReferences(fileName: string, position: number): ReferencedSymbol[]{ - let referencedSymbols = findReferencedSymbols(fileName, position, /*findInStrings:*/ false, /*findInComments:*/ false); + function findReferences(fileName: string, position: number): ReferencedSymbol[] { + const referencedSymbols = findReferencedSymbols(fileName, position, /*findInStrings*/ false, /*findInComments*/ false); // Only include referenced symbols that have a valid definition. return filter(referencedSymbols, rs => !!rs.definition); @@ -5377,17 +5376,17 @@ namespace ts { function findReferencedSymbols(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): ReferencedSymbol[] { synchronizeHostData(); - let sourceFile = getValidSourceFile(fileName); + const sourceFile = getValidSourceFile(fileName); - let node = getTouchingPropertyName(sourceFile, position); + const node = getTouchingPropertyName(sourceFile, position); if (!node) { return undefined; } if (node.kind !== SyntaxKind.Identifier && // TODO (drosen): This should be enabled in a later release - currently breaks rename. - //node.kind !== SyntaxKind.ThisKeyword && - //node.kind !== SyntaxKind.SuperKeyword && + // node.kind !== SyntaxKind.ThisKeyword && + // node.kind !== SyntaxKind.SuperKeyword && !isLiteralNameOfPropertyDeclarationOrIndexAccess(node) && !isNameOfExternalModuleImportOrDeclaration(node)) { return undefined; @@ -5398,12 +5397,12 @@ namespace ts { } function getReferencedSymbolsForNode(node: Node, sourceFiles: SourceFile[], findInStrings: boolean, findInComments: boolean): ReferencedSymbol[] { - let typeChecker = program.getTypeChecker(); + const typeChecker = program.getTypeChecker(); // Labels if (isLabelName(node)) { if (isJumpStatementTarget(node)) { - let labelDefinition = getTargetLabel((node.parent), (node).text); + const labelDefinition = getTargetLabel((node.parent), (node).text); // if we have a label definition, look within its statement for references, if not, then // the label is undefined and we have no results.. return labelDefinition ? getLabelReferencesInNode(labelDefinition.parent, labelDefinition) : undefined; @@ -5422,7 +5421,7 @@ namespace ts { return getReferencesForSuperKeyword(node); } - let symbol = typeChecker.getSymbolAtLocation(node); + const symbol = typeChecker.getSymbolAtLocation(node); // Could not find a symbol e.g. unknown identifier if (!symbol) { @@ -5430,7 +5429,7 @@ namespace ts { return undefined; } - let declarations = symbol.declarations; + const declarations = symbol.declarations; // The symbol was an internal symbol and does not have a declaration e.g. undefined symbol if (!declarations || !declarations.length) { @@ -5440,29 +5439,29 @@ namespace ts { let result: ReferencedSymbol[]; // Compute the meaning from the location and the symbol it references - let searchMeaning = getIntersectingMeaningFromDeclarations(getMeaningFromLocation(node), declarations); + const searchMeaning = getIntersectingMeaningFromDeclarations(getMeaningFromLocation(node), declarations); // Get the text to search for. // Note: if this is an external module symbol, the name doesn't include quotes. - let declaredName = stripQuotes(getDeclaredName(typeChecker, symbol, node)); + const declaredName = stripQuotes(getDeclaredName(typeChecker, symbol, node)); // Try to get the smallest valid scope that we can limit our search to; // otherwise we'll need to search globally (i.e. include each file). - let scope = getSymbolScope(symbol); + const scope = getSymbolScope(symbol); // Maps from a symbol ID to the ReferencedSymbol entry in 'result'. - let symbolToIndex: number[] = []; + const symbolToIndex: number[] = []; if (scope) { result = []; getReferencesInNode(scope, symbol, declaredName, node, searchMeaning, findInStrings, findInComments, result, symbolToIndex); } else { - let internedName = getInternedName(symbol, node, declarations) - for (let sourceFile of sourceFiles) { + const internedName = getInternedName(symbol, node, declarations); + for (const sourceFile of sourceFiles) { cancellationToken.throwIfCancellationRequested(); - let nameTable = getNameTable(sourceFile); + const nameTable = getNameTable(sourceFile); if (lookUp(nameTable, internedName)) { result = result || []; @@ -5474,9 +5473,9 @@ namespace ts { return result; function getDefinition(symbol: Symbol): DefinitionInfo { - let info = getSymbolDisplayPartsDocumentationAndSymbolKind(symbol, node.getSourceFile(), getContainerNode(node), node); - let name = map(info.displayParts, p => p.text).join(""); - let declarations = symbol.declarations; + const info = getSymbolDisplayPartsDocumentationAndSymbolKind(symbol, node.getSourceFile(), getContainerNode(node), node); + const name = map(info.displayParts, p => p.text).join(""); + const declarations = symbol.declarations; if (!declarations || declarations.length === 0) { return undefined; } @@ -5506,7 +5505,7 @@ namespace ts { // Try to get the local symbol if we're dealing with an 'export default' // since that symbol has the "true" name. - let localExportDefaultSymbol = getLocalSymbolForExportDefault(symbol); + const localExportDefaultSymbol = getLocalSymbolForExportDefault(symbol); symbol = localExportDefaultSymbol || symbol; return stripQuotes(symbol.name); @@ -5523,14 +5522,14 @@ namespace ts { function getSymbolScope(symbol: Symbol): Node { // If this is the symbol of a named function expression or named class expression, // then named references are limited to its own scope. - let valueDeclaration = symbol.valueDeclaration; + const valueDeclaration = symbol.valueDeclaration; if (valueDeclaration && (valueDeclaration.kind === SyntaxKind.FunctionExpression || valueDeclaration.kind === SyntaxKind.ClassExpression)) { return valueDeclaration; } // If this is private property or method, the scope is the containing class if (symbol.flags & (SymbolFlags.Property | SymbolFlags.Method)) { - let privateDeclaration = forEach(symbol.getDeclarations(), d => (d.flags & NodeFlags.Private) ? d : undefined); + const privateDeclaration = forEach(symbol.getDeclarations(), d => (d.flags & NodeFlags.Private) ? d : undefined); if (privateDeclaration) { return getAncestor(privateDeclaration, SyntaxKind.ClassDeclaration); } @@ -5548,12 +5547,12 @@ namespace ts { return undefined; } - let scope: Node = undefined; + let scope: Node; - let declarations = symbol.getDeclarations(); + const declarations = symbol.getDeclarations(); if (declarations) { - for (let declaration of declarations) { - let container = getContainerNode(declaration); + for (const declaration of declarations) { + const container = getContainerNode(declaration); if (!container) { return undefined; @@ -5579,7 +5578,7 @@ namespace ts { } function getPossibleSymbolReferencePositions(sourceFile: SourceFile, symbolName: string, start: number, end: number): number[] { - let positions: number[] = []; + const positions: number[] = []; /// TODO: Cache symbol existence for files to save text search // Also, need to make this work for unicode escapes. @@ -5589,9 +5588,9 @@ namespace ts { return positions; } - let text = sourceFile.text; - let sourceLength = text.length; - let symbolNameLength = symbolName.length; + const text = sourceFile.text; + const sourceLength = text.length; + const symbolNameLength = symbolName.length; let position = text.indexOf(symbolName, start); while (position >= 0) { @@ -5602,7 +5601,7 @@ namespace ts { // We found a match. Make sure it's not part of a larger word (i.e. the char // before and after it have to be a non-identifier char). - let endPosition = position + symbolNameLength; + const endPosition = position + symbolNameLength; if ((position === 0 || !isIdentifierPart(text.charCodeAt(position - 1), ScriptTarget.Latest)) && (endPosition === sourceLength || !isIdentifierPart(text.charCodeAt(endPosition), ScriptTarget.Latest))) { @@ -5616,14 +5615,14 @@ namespace ts { } function getLabelReferencesInNode(container: Node, targetLabel: Identifier): ReferencedSymbol[] { - let references: ReferenceEntry[] = []; - let sourceFile = container.getSourceFile(); - let labelName = targetLabel.text; - let possiblePositions = getPossibleSymbolReferencePositions(sourceFile, labelName, container.getStart(), container.getEnd()); + const references: ReferenceEntry[] = []; + const sourceFile = container.getSourceFile(); + const labelName = targetLabel.text; + const possiblePositions = getPossibleSymbolReferencePositions(sourceFile, labelName, container.getStart(), container.getEnd()); forEach(possiblePositions, position => { cancellationToken.throwIfCancellationRequested(); - let node = getTouchingWord(sourceFile, position); + const node = getTouchingWord(sourceFile, position); if (!node || node.getWidth() !== labelName.length) { return; } @@ -5635,14 +5634,14 @@ namespace ts { } }); - let definition: DefinitionInfo = { + const definition: DefinitionInfo = { containerKind: "", containerName: "", fileName: targetLabel.getSourceFile().fileName, kind: ScriptElementKind.label, name: labelName, textSpan: createTextSpanFromBounds(targetLabel.getStart(), targetLabel.getEnd()) - } + }; return [{ definition, references }]; } @@ -5687,19 +5686,19 @@ namespace ts { result: ReferencedSymbol[], symbolToIndex: number[]): void { - let sourceFile = container.getSourceFile(); - let tripleSlashDirectivePrefixRegex = /^\/\/\/\s* { cancellationToken.throwIfCancellationRequested(); - let referenceLocation = getTouchingPropertyName(sourceFile, position); + const referenceLocation = getTouchingPropertyName(sourceFile, position); if (!isValidReferencePosition(referenceLocation, searchText)) { // This wasn't the start of a token. Check to see if it might be a // match in a comment or string if that's what the caller is asking @@ -5727,14 +5726,14 @@ namespace ts { return; } - let referenceSymbol = typeChecker.getSymbolAtLocation(referenceLocation); + const referenceSymbol = typeChecker.getSymbolAtLocation(referenceLocation); if (referenceSymbol) { - let referenceSymbolDeclaration = referenceSymbol.valueDeclaration; - let shorthandValueSymbol = typeChecker.getShorthandAssignmentValueSymbol(referenceSymbolDeclaration); - let relatedSymbol = getRelatedSymbol(searchSymbols, referenceSymbol, referenceLocation); + const referenceSymbolDeclaration = referenceSymbol.valueDeclaration; + const shorthandValueSymbol = typeChecker.getShorthandAssignmentValueSymbol(referenceSymbolDeclaration); + const relatedSymbol = getRelatedSymbol(searchSymbols, referenceSymbol, referenceLocation); if (relatedSymbol) { - let referencedSymbol = getReferencedSymbol(relatedSymbol); + const referencedSymbol = getReferencedSymbol(relatedSymbol); referencedSymbol.references.push(getReferenceEntryFromNode(referenceLocation)); } /* Because in short-hand property assignment, an identifier which stored as name of the short-hand property assignment @@ -5744,7 +5743,7 @@ namespace ts { * position of property accessing, the referenceEntry of such position will be handled in the first case. */ else if (!(referenceSymbol.flags & SymbolFlags.Transient) && searchSymbols.indexOf(shorthandValueSymbol) >= 0) { - let referencedSymbol = getReferencedSymbol(shorthandValueSymbol); + const referencedSymbol = getReferencedSymbol(shorthandValueSymbol); referencedSymbol.references.push(getReferenceEntryFromNode(referenceSymbolDeclaration.name)); } } @@ -5754,7 +5753,7 @@ namespace ts { return; function getReferencedSymbol(symbol: Symbol): ReferencedSymbol { - let symbolId = getSymbolId(symbol); + const symbolId = getSymbolId(symbol); let index = symbolToIndex[symbolId]; if (index === undefined) { index = result.length; @@ -5773,7 +5772,7 @@ namespace ts { return isInCommentHelper(sourceFile, position, isNonReferenceComment); function isNonReferenceComment(c: CommentRange): boolean { - let commentText = sourceFile.text.substring(c.pos, c.end); + const commentText = sourceFile.text.substring(c.pos, c.end); return !tripleSlashDirectivePrefixRegex.test(commentText); } } @@ -5802,20 +5801,20 @@ namespace ts { return undefined; } - let references: ReferenceEntry[] = []; + const references: ReferenceEntry[] = []; - let sourceFile = searchSpaceNode.getSourceFile(); - let possiblePositions = getPossibleSymbolReferencePositions(sourceFile, "super", searchSpaceNode.getStart(), searchSpaceNode.getEnd()); + const sourceFile = searchSpaceNode.getSourceFile(); + const possiblePositions = getPossibleSymbolReferencePositions(sourceFile, "super", searchSpaceNode.getStart(), searchSpaceNode.getEnd()); forEach(possiblePositions, position => { cancellationToken.throwIfCancellationRequested(); - let node = getTouchingWord(sourceFile, position); + const node = getTouchingWord(sourceFile, position); if (!node || node.kind !== SyntaxKind.SuperKeyword) { return; } - let container = getSuperContainer(node, /*includeFunctions*/ false); + const container = getSuperContainer(node, /*includeFunctions*/ false); // If we have a 'super' container, we must have an enclosing class. // Now make sure the owning class is the same as the search-space @@ -5825,7 +5824,7 @@ namespace ts { } }); - let definition = getDefinition(searchSpaceNode.symbol); + const definition = getDefinition(searchSpaceNode.symbol); return [{ definition, references }]; } @@ -5847,7 +5846,7 @@ namespace ts { case SyntaxKind.Constructor: case SyntaxKind.GetAccessor: case SyntaxKind.SetAccessor: - staticFlag &= searchSpaceNode.flags + staticFlag &= searchSpaceNode.flags; searchSpaceNode = searchSpaceNode.parent; // re-assign to be the owning class break; case SyntaxKind.SourceFile: @@ -5864,7 +5863,7 @@ namespace ts { return undefined; } - let references: ReferenceEntry[] = []; + const references: ReferenceEntry[] = []; let possiblePositions: number[]; if (searchSpaceNode.kind === SyntaxKind.SourceFile) { @@ -5874,7 +5873,7 @@ namespace ts { }); } else { - let sourceFile = searchSpaceNode.getSourceFile(); + const sourceFile = searchSpaceNode.getSourceFile(); possiblePositions = getPossibleSymbolReferencePositions(sourceFile, "this", searchSpaceNode.getStart(), searchSpaceNode.getEnd()); getThisReferencesInFile(sourceFile, searchSpaceNode, possiblePositions, references); } @@ -5895,12 +5894,12 @@ namespace ts { forEach(possiblePositions, position => { cancellationToken.throwIfCancellationRequested(); - let node = getTouchingWord(sourceFile, position); + const node = getTouchingWord(sourceFile, position); if (!node || (node.kind !== SyntaxKind.ThisKeyword && node.kind !== SyntaxKind.ThisType)) { return; } - let container = getThisContainer(node, /* includeArrowFunctions */ false); + const container = getThisContainer(node, /* includeArrowFunctions */ false); switch (searchSpaceNode.kind) { case SyntaxKind.FunctionExpression: @@ -5955,13 +5954,13 @@ namespace ts { * property name and variable declaration of the identifier. * Like in below example, when querying for all references for an identifier 'name', of the property assignment, the language service * should show both 'name' in 'obj' and 'name' in variable declaration - * let name = "Foo"; - * let obj = { name }; + * const name = "Foo"; + * const obj = { name }; * In order to do that, we will populate the search set with the value symbol of the identifier as a value of the property assignment * so that when matching with potential reference symbol, both symbols from property declaration and variable declaration * will be included correctly. */ - let shorthandValueSymbol = typeChecker.getShorthandAssignmentValueSymbol(location.parent); + const shorthandValueSymbol = typeChecker.getShorthandAssignmentValueSymbol(location.parent); if (shorthandValueSymbol) { result.push(shorthandValueSymbol); } @@ -6008,9 +6007,9 @@ namespace ts { function getPropertySymbolFromTypeReference(typeReference: ExpressionWithTypeArguments) { if (typeReference) { - let type = typeChecker.getTypeAtLocation(typeReference); + const type = typeChecker.getTypeAtLocation(typeReference); if (type) { - let propertySymbol = typeChecker.getPropertyOfType(type, propertyName); + const propertySymbol = typeChecker.getPropertyOfType(type, propertyName); if (propertySymbol) { result.push(propertySymbol); } @@ -6030,7 +6029,7 @@ namespace ts { // If the reference symbol is an alias, check if what it is aliasing is one of the search // symbols. if (isImportOrExportSpecifierImportSymbol(referenceSymbol)) { - let aliasedSymbol = typeChecker.getAliasedSymbol(referenceSymbol); + const aliasedSymbol = typeChecker.getAliasedSymbol(referenceSymbol); if (searchSymbols.indexOf(aliasedSymbol) >= 0) { return aliasedSymbol; } @@ -6056,7 +6055,7 @@ namespace ts { // Finally, try all properties with the same name in any type the containing type extended or implemented, and // see if any is in the list if (rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { - let result: Symbol[] = []; + const result: Symbol[] = []; getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getName(), result); return forEach(result, s => searchSymbols.indexOf(s) >= 0 ? s : undefined); } @@ -6067,21 +6066,21 @@ namespace ts { function getPropertySymbolsFromContextualType(node: Node): Symbol[] { if (isNameOfPropertyAssignment(node)) { - let objectLiteral = node.parent.parent; - let contextualType = typeChecker.getContextualType(objectLiteral); - let name = (node).text; + const objectLiteral = node.parent.parent; + const contextualType = typeChecker.getContextualType(objectLiteral); + const name = (node).text; if (contextualType) { if (contextualType.flags & TypeFlags.Union) { // This is a union type, first see if the property we are looking for is a union property (i.e. exists in all types) // if not, search the constituent types for the property - let unionProperty = contextualType.getProperty(name) + const unionProperty = contextualType.getProperty(name); if (unionProperty) { return [unionProperty]; } else { - let result: Symbol[] = []; + const result: Symbol[] = []; forEach((contextualType).types, t => { - let symbol = t.getProperty(name); + const symbol = t.getProperty(name); if (symbol) { result.push(symbol); } @@ -6090,7 +6089,7 @@ namespace ts { } } else { - let symbol = contextualType.getProperty(name); + const symbol = contextualType.getProperty(name); if (symbol) { return [symbol]; } @@ -6119,8 +6118,8 @@ namespace ts { // Remember the last meaning lastIterationMeaning = meaning; - for (let declaration of declarations) { - let declarationMeaning = getMeaningFromDeclaration(declaration); + for (const declaration of declarations) { + const declarationMeaning = getMeaningFromDeclaration(declaration); if (declarationMeaning & meaning) { meaning |= declarationMeaning; @@ -6155,13 +6154,13 @@ namespace ts { return true; } - let parent = node.parent; + const parent = node.parent; if (parent) { if (parent.kind === SyntaxKind.PostfixUnaryExpression || parent.kind === SyntaxKind.PrefixUnaryExpression) { return true; } else if (parent.kind === SyntaxKind.BinaryExpression && (parent).left === node) { - let operator = (parent).operatorToken.kind; + const operator = (parent).operatorToken.kind; return SyntaxKind.FirstAssignment <= operator && operator <= SyntaxKind.LastAssignment; } } @@ -6183,8 +6182,8 @@ namespace ts { function getEmitOutput(fileName: string): EmitOutput { synchronizeHostData(); - let sourceFile = getValidSourceFile(fileName); - let outputFiles: OutputFile[] = []; + const sourceFile = getValidSourceFile(fileName); + const outputFiles: OutputFile[] = []; function writeFile(fileName: string, data: string, writeByteOrderMark: boolean) { outputFiles.push({ @@ -6194,7 +6193,7 @@ namespace ts { }); } - let emitOutput = program.emit(sourceFile, writeFile, cancellationToken); + const emitOutput = program.emit(sourceFile, writeFile, cancellationToken); return { outputFiles, @@ -6287,7 +6286,7 @@ namespace ts { } if (!isLastClause && root.parent.kind === SyntaxKind.ExpressionWithTypeArguments && root.parent.parent.kind === SyntaxKind.HeritageClause) { - let decl = root.parent.parent.parent; + const decl = root.parent.parent.parent; return (decl.kind === SyntaxKind.ClassDeclaration && (root.parent.parent).token === SyntaxKind.ImplementsKeyword) || (decl.kind === SyntaxKind.InterfaceDeclaration && (root.parent.parent).token === SyntaxKind.ExtendsKeyword); } @@ -6359,7 +6358,7 @@ namespace ts { function getSignatureHelpItems(fileName: string, position: number): SignatureHelpItems { synchronizeHostData(); - let sourceFile = getValidSourceFile(fileName); + const sourceFile = getValidSourceFile(fileName); return SignatureHelp.getSignatureHelpItems(program, sourceFile, position, cancellationToken); } @@ -6370,10 +6369,10 @@ namespace ts { } function getNameOrDottedNameSpan(fileName: string, startPos: number, endPos: number): TextSpan { - let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); // Get node at the location - let node = getTouchingPropertyName(sourceFile, startPos); + const node = getTouchingPropertyName(sourceFile, startPos); if (!node) { return; @@ -6429,13 +6428,13 @@ namespace ts { function getBreakpointStatementAtPosition(fileName: string, position: number) { // doesn't use compiler - no need to synchronize with host - let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); return BreakpointResolver.spanInSourceFileAtLocation(sourceFile, position); } function getNavigationBarItems(fileName: string): NavigationBarItem[] { - let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); return NavigationBar.getNavigationBarItems(sourceFile, host.getCompilationSettings()); } @@ -6467,11 +6466,11 @@ namespace ts { function getEncodedSemanticClassifications(fileName: string, span: TextSpan): Classifications { synchronizeHostData(); - let sourceFile = getValidSourceFile(fileName); - let typeChecker = program.getTypeChecker(); + const sourceFile = getValidSourceFile(fileName); + const typeChecker = program.getTypeChecker(); - let result: number[] = []; - let classifiableNames = program.getClassifiableNames(); + const result: number[] = []; + const classifiableNames = program.getClassifiableNames(); processNode(sourceFile); return { spans: result, endOfLineState: EndOfLineState.None }; @@ -6483,7 +6482,7 @@ namespace ts { } function classifySymbol(symbol: Symbol, meaningAtPosition: SemanticMeaning): ClassificationType { - let flags = symbol.getFlags(); + const flags = symbol.getFlags(); if ((flags & SymbolFlags.Classifiable) === SymbolFlags.None) { return; } @@ -6531,19 +6530,19 @@ namespace ts { function processNode(node: Node) { // Only walk into nodes that intersect the requested span. if (node && textSpanIntersectsWith(span, node.getFullStart(), node.getFullWidth())) { - let kind = node.kind; + const kind = node.kind; checkForClassificationCancellation(kind); if (kind === SyntaxKind.Identifier && !nodeIsMissing(node)) { - let identifier = node; + const identifier = node; // Only bother calling into the typechecker if this is an identifier that // could possibly resolve to a type name. This makes classification run // in a third of the time it would normally take. if (classifiableNames[identifier.text]) { - let symbol = typeChecker.getSymbolAtLocation(node); + const symbol = typeChecker.getSymbolAtLocation(node); if (symbol) { - let type = classifySymbol(symbol, getMeaningFromLocation(node)); + const type = classifySymbol(symbol, getMeaningFromLocation(node)); if (type) { pushClassification(node.getStart(), node.getWidth(), type); } @@ -6583,8 +6582,8 @@ namespace ts { function convertClassifications(classifications: Classifications): ClassifiedSpan[] { Debug.assert(classifications.spans.length % 3 === 0); - let dense = classifications.spans; - let result: ClassifiedSpan[] = []; + const dense = classifications.spans; + const result: ClassifiedSpan[] = []; for (let i = 0, n = dense.length; i < n; i += 3) { result.push({ textSpan: createTextSpan(dense[i], dense[i + 1]), @@ -6601,15 +6600,15 @@ namespace ts { function getEncodedSyntacticClassifications(fileName: string, span: TextSpan): Classifications { // doesn't use compiler - no need to synchronize with host - let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); - let spanStart = span.start; - let spanLength = span.length; + const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + const spanStart = span.start; + const spanLength = span.length; // Make a scanner we can get trivia from. - let triviaScanner = createScanner(ScriptTarget.Latest, /*skipTrivia:*/ false, sourceFile.languageVariant, sourceFile.text); - let mergeConflictScanner = createScanner(ScriptTarget.Latest, /*skipTrivia:*/ false, sourceFile.languageVariant, sourceFile.text); + const triviaScanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ false, sourceFile.languageVariant, sourceFile.text); + const mergeConflictScanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ false, sourceFile.languageVariant, sourceFile.text); - let result: number[] = []; + const result: number[] = []; processElement(sourceFile); return { spans: result, endOfLineState: EndOfLineState.None }; @@ -6623,15 +6622,15 @@ namespace ts { function classifyLeadingTriviaAndGetTokenStart(token: Node): number { triviaScanner.setTextPos(token.pos); while (true) { - let start = triviaScanner.getTextPos(); + const start = triviaScanner.getTextPos(); // only bother scanning if we have something that could be trivia. if (!couldStartTrivia(sourceFile.text, start)) { return start; } - let kind = triviaScanner.scan(); - let end = triviaScanner.getTextPos(); - let width = end - start; + const kind = triviaScanner.scan(); + const end = triviaScanner.getTextPos(); + const width = end - start; // The moment we get something that isn't trivia, then stop processing. if (!isTrivia(kind)) { @@ -6655,8 +6654,8 @@ namespace ts { } if (kind === SyntaxKind.ConflictMarkerTrivia) { - let text = sourceFile.text; - let ch = text.charCodeAt(start); + const text = sourceFile.text; + const ch = text.charCodeAt(start); // for the <<<<<<< and >>>>>>> markers, we just add them in as comments // in the classification stream. @@ -6677,7 +6676,7 @@ namespace ts { if (kind === SyntaxKind.MultiLineCommentTrivia) { // See if this is a doc comment. If so, we'll classify certain portions of it // specially. - let docCommentAndDiagnostics = parseIsolatedJSDocComment(sourceFile.text, start, width); + const docCommentAndDiagnostics = parseIsolatedJSDocComment(sourceFile.text, start, width); if (docCommentAndDiagnostics && docCommentAndDiagnostics.jsDocComment) { docCommentAndDiagnostics.jsDocComment.parent = token; classifyJSDocComment(docCommentAndDiagnostics.jsDocComment); @@ -6696,7 +6695,7 @@ namespace ts { function classifyJSDocComment(docComment: JSDocComment) { let pos = docComment.pos; - for (let tag of docComment.tags) { + for (const tag of docComment.tags) { // As we walk through each tag, classify the portion of text from the end of // the last tag (or the start of the entire doc comment) as 'comment'. if (tag.pos !== pos) { @@ -6754,7 +6753,7 @@ namespace ts { } function processJSDocTemplateTag(tag: JSDocTemplateTag) { - for (let child of tag.getChildren()) { + for (const child of tag.getChildren()) { processElement(child); } } @@ -6776,11 +6775,11 @@ namespace ts { } function classifyDisabledCodeToken() { - let start = mergeConflictScanner.getTextPos(); - let tokenKind = mergeConflictScanner.scan(); - let end = mergeConflictScanner.getTextPos(); + const start = mergeConflictScanner.getTextPos(); + const tokenKind = mergeConflictScanner.scan(); + const end = mergeConflictScanner.getTextPos(); - let type = classifyTokenType(tokenKind); + const type = classifyTokenType(tokenKind); if (type) { pushClassification(start, end - start, type); } @@ -6791,12 +6790,12 @@ namespace ts { return; } - let tokenStart = classifyLeadingTriviaAndGetTokenStart(token); + const tokenStart = classifyLeadingTriviaAndGetTokenStart(token); - let tokenWidth = token.end - tokenStart; + const tokenWidth = token.end - tokenStart; Debug.assert(tokenWidth >= 0); if (tokenWidth > 0) { - let type = classifyTokenType(token.kind, token); + const type = classifyTokenType(token.kind, token); if (type) { pushClassification(tokenStart, tokenWidth, type); } @@ -6923,9 +6922,9 @@ namespace ts { if (decodedTextSpanIntersectsWith(spanStart, spanLength, element.pos, element.getFullWidth())) { checkForClassificationCancellation(element.kind); - let children = element.getChildren(sourceFile); + const children = element.getChildren(sourceFile); for (let i = 0, n = children.length; i < n; i++) { - let child = children[i]; + const child = children[i]; if (isToken(child)) { classifyToken(child); } @@ -6940,28 +6939,28 @@ namespace ts { function getOutliningSpans(fileName: string): OutliningSpan[] { // doesn't use compiler - no need to synchronize with host - let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); return OutliningElementsCollector.collectElements(sourceFile); } function getBraceMatchingAtPosition(fileName: string, position: number) { - let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); - let result: TextSpan[] = []; + const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + const result: TextSpan[] = []; - let token = getTouchingToken(sourceFile, position); + const token = getTouchingToken(sourceFile, position); if (token.getStart(sourceFile) === position) { - let matchKind = getMatchingTokenKind(token); + const matchKind = getMatchingTokenKind(token); // Ensure that there is a corresponding token to match ours. if (matchKind) { - let parentElement = token.parent; + const parentElement = token.parent; - let childNodes = parentElement.getChildren(sourceFile); - for (let current of childNodes) { + const childNodes = parentElement.getChildren(sourceFile); + for (const current of childNodes) { if (current.kind === matchKind) { - let range1 = createTextSpan(token.getStart(sourceFile), token.getWidth(sourceFile)); - let range2 = createTextSpan(current.getStart(sourceFile), current.getWidth(sourceFile)); + const range1 = createTextSpan(token.getStart(sourceFile), token.getWidth(sourceFile)); + const range2 = createTextSpan(current.getStart(sourceFile), current.getWidth(sourceFile)); // We want to order the braces when we return the result. if (range1.start < range2.start) { @@ -6981,11 +6980,11 @@ namespace ts { function getMatchingTokenKind(token: Node): ts.SyntaxKind { switch (token.kind) { - case ts.SyntaxKind.OpenBraceToken: return ts.SyntaxKind.CloseBraceToken + case ts.SyntaxKind.OpenBraceToken: return ts.SyntaxKind.CloseBraceToken; case ts.SyntaxKind.OpenParenToken: return ts.SyntaxKind.CloseParenToken; case ts.SyntaxKind.OpenBracketToken: return ts.SyntaxKind.CloseBracketToken; case ts.SyntaxKind.LessThanToken: return ts.SyntaxKind.GreaterThanToken; - case ts.SyntaxKind.CloseBraceToken: return ts.SyntaxKind.OpenBraceToken + case ts.SyntaxKind.CloseBraceToken: return ts.SyntaxKind.OpenBraceToken; case ts.SyntaxKind.CloseParenToken: return ts.SyntaxKind.OpenParenToken; case ts.SyntaxKind.CloseBracketToken: return ts.SyntaxKind.OpenBracketToken; case ts.SyntaxKind.GreaterThanToken: return ts.SyntaxKind.LessThanToken; @@ -6997,29 +6996,29 @@ namespace ts { function getIndentationAtPosition(fileName: string, position: number, editorOptions: EditorOptions) { let start = new Date().getTime(); - let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); log("getIndentationAtPosition: getCurrentSourceFile: " + (new Date().getTime() - start)); start = new Date().getTime(); - let result = formatting.SmartIndenter.getIndentation(position, sourceFile, editorOptions); + const result = formatting.SmartIndenter.getIndentation(position, sourceFile, editorOptions); log("getIndentationAtPosition: computeIndentation : " + (new Date().getTime() - start)); return result; } function getFormattingEditsForRange(fileName: string, start: number, end: number, options: FormatCodeOptions): TextChange[] { - let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); return formatting.formatSelection(start, end, sourceFile, getRuleProvider(options), options); } function getFormattingEditsForDocument(fileName: string, options: FormatCodeOptions): TextChange[] { - let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); return formatting.formatDocument(sourceFile, getRuleProvider(options), options); } function getFormattingEditsAfterKeystroke(fileName: string, position: number, key: string, options: FormatCodeOptions): TextChange[] { - let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); if (key === "}") { return formatting.formatOnClosingCurly(position, sourceFile, getRuleProvider(options), options); @@ -7055,16 +7054,16 @@ namespace ts { * be performed. */ function getDocCommentTemplateAtPosition(fileName: string, position: number): TextInsertion { - let start = new Date().getTime(); - let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + const start = new Date().getTime(); + const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); // Check if in a context where we don't want to perform any insertion if (isInString(sourceFile, position) || isInComment(sourceFile, position) || hasDocComment(sourceFile, position)) { return undefined; } - let tokenAtPos = getTokenAtPosition(sourceFile, position); - let tokenStart = tokenAtPos.getStart() + const tokenAtPos = getTokenAtPosition(sourceFile, position); + const tokenStart = tokenAtPos.getStart(); if (!tokenAtPos || tokenStart < position) { return undefined; } @@ -7100,11 +7099,11 @@ namespace ts { return undefined; } - let parameters = getParametersForJsDocOwningNode(commentOwner); - let posLineAndChar = sourceFile.getLineAndCharacterOfPosition(position); - let lineStart = sourceFile.getLineStarts()[posLineAndChar.line]; + const parameters = getParametersForJsDocOwningNode(commentOwner); + const posLineAndChar = sourceFile.getLineAndCharacterOfPosition(position); + const lineStart = sourceFile.getLineStarts()[posLineAndChar.line]; - let indentationStr = sourceFile.text.substr(lineStart, posLineAndChar.character); + const indentationStr = sourceFile.text.substr(lineStart, posLineAndChar.character); // TODO: call a helper method instead once PR #4133 gets merged in. const newLine = host.getNewLine ? host.getNewLine() : "\r\n"; @@ -7128,7 +7127,7 @@ namespace ts { // * if the caret was directly in front of the object, then we add an extra line and indentation. const preamble = "/**" + newLine + indentationStr + " * "; - let result = + const result = preamble + newLine + docParams + indentationStr + " */" + @@ -7172,7 +7171,7 @@ namespace ts { case SyntaxKind.ArrowFunction: return (rightHandSide).parameters; case SyntaxKind.ClassExpression: - for (let member of (rightHandSide).members) { + for (const member of (rightHandSide).members) { if (member.kind === SyntaxKind.Constructor) { return (member).parameters; } @@ -7192,15 +7191,15 @@ namespace ts { // anything away. synchronizeHostData(); - let sourceFile = getValidSourceFile(fileName); + const sourceFile = getValidSourceFile(fileName); cancellationToken.throwIfCancellationRequested(); - let fileContents = sourceFile.text; - let result: TodoComment[] = []; + const fileContents = sourceFile.text; + const result: TodoComment[] = []; if (descriptors.length > 0) { - let regExp = getTodoCommentsRegExp(); + const regExp = getTodoCommentsRegExp(); let matchArray: RegExpExecArray; while (matchArray = regExp.exec(fileContents)) { @@ -7223,15 +7222,15 @@ namespace ts { // // i.e. 'undefined' in position 3 above means TODO(jason) didn't match. // "hack" in position 4 means HACK did match. - let firstDescriptorCaptureIndex = 3; + const firstDescriptorCaptureIndex = 3; Debug.assert(matchArray.length === descriptors.length + firstDescriptorCaptureIndex); - let preamble = matchArray[1]; - let matchPosition = matchArray.index + preamble.length; + const preamble = matchArray[1]; + const matchPosition = matchArray.index + preamble.length; // OK, we have found a match in the file. This is only an acceptable match if // it is contained within a comment. - let token = getTokenAtPosition(sourceFile, matchPosition); + const token = getTokenAtPosition(sourceFile, matchPosition); if (!isInsideComment(sourceFile, token, matchPosition)) { continue; } @@ -7250,7 +7249,7 @@ namespace ts { continue; } - let message = matchArray[2]; + const message = matchArray[2]; result.push({ descriptor: descriptor, message: message, @@ -7281,14 +7280,14 @@ namespace ts { // // The following three regexps are used to match the start of the text up to the TODO // comment portion. - let singleLineCommentStart = /(?:\/\/+\s*)/.source; - let multiLineCommentStart = /(?:\/\*+\s*)/.source; - let anyNumberOfSpacesAndAsterixesAtStartOfLine = /(?:^(?:\s|\*)*)/.source; + const singleLineCommentStart = /(?:\/\/+\s*)/.source; + const multiLineCommentStart = /(?:\/\*+\s*)/.source; + const anyNumberOfSpacesAndAsterixesAtStartOfLine = /(?:^(?:\s|\*)*)/.source; // Match any of the above three TODO comment start regexps. // Note that the outermost group *is* a capture group. We want to capture the preamble // so that we can determine the starting position of the TODO comment match. - let preamble = "(" + anyNumberOfSpacesAndAsterixesAtStartOfLine + "|" + singleLineCommentStart + "|" + multiLineCommentStart + ")"; + const preamble = "(" + anyNumberOfSpacesAndAsterixesAtStartOfLine + "|" + singleLineCommentStart + "|" + multiLineCommentStart + ")"; // Takes the descriptors and forms a regexp that matches them as if they were literals. // For example, if the descriptors are "TODO(jason)" and "HACK", then this will be: @@ -7298,17 +7297,17 @@ namespace ts { // Note that the outermost group is *not* a capture group, but the innermost groups // *are* capture groups. By capturing the inner literals we can determine after // matching which descriptor we are dealing with. - let literals = "(?:" + map(descriptors, d => "(" + escapeRegExp(d.text) + ")").join("|") + ")"; + const literals = "(?:" + map(descriptors, d => "(" + escapeRegExp(d.text) + ")").join("|") + ")"; // After matching a descriptor literal, the following regexp matches the rest of the // text up to the end of the line (or */). - let endOfLineOrEndOfComment = /(?:$|\*\/)/.source - let messageRemainder = /(?:.*?)/.source + const endOfLineOrEndOfComment = /(?:$|\*\/)/.source; + const messageRemainder = /(?:.*?)/.source; // This is the portion of the match we'll return as part of the TODO comment result. We // match the literal portion up to the end of the line or end of comment. - let messagePortion = "(" + literals + messageRemainder + ")"; - let regExpString = preamble + messagePortion + endOfLineOrEndOfComment; + const messagePortion = "(" + literals + messageRemainder + ")"; + const regExpString = preamble + messagePortion + endOfLineOrEndOfComment; // The final regexp will look like this: // /((?:\/\/+\s*)|(?:\/\*+\s*)|(?:^(?:\s|\*)*))((?:(TODO\(jason\))|(HACK))(?:.*?))(?:$|\*\/)/gim @@ -7334,40 +7333,40 @@ namespace ts { function getRenameInfo(fileName: string, position: number): RenameInfo { synchronizeHostData(); - let sourceFile = getValidSourceFile(fileName); - let typeChecker = program.getTypeChecker(); + const sourceFile = getValidSourceFile(fileName); + const typeChecker = program.getTypeChecker(); - let node = getTouchingWord(sourceFile, position); + const node = getTouchingWord(sourceFile, position); // Can only rename an identifier. if (node && node.kind === SyntaxKind.Identifier) { - let symbol = typeChecker.getSymbolAtLocation(node); + const symbol = typeChecker.getSymbolAtLocation(node); // Only allow a symbol to be renamed if it actually has at least one declaration. if (symbol) { - let declarations = symbol.getDeclarations(); + const declarations = symbol.getDeclarations(); if (declarations && declarations.length > 0) { // Disallow rename for elements that are defined in the standard TypeScript library. - let defaultLibFileName = host.getDefaultLibFileName(host.getCompilationSettings()); + const defaultLibFileName = host.getDefaultLibFileName(host.getCompilationSettings()); if (defaultLibFileName) { - for (let current of declarations) { - let sourceFile = current.getSourceFile(); - var canonicalName = getCanonicalFileName(ts.normalizePath(sourceFile.fileName)); + for (const current of declarations) { + const sourceFile = current.getSourceFile(); + const canonicalName = getCanonicalFileName(ts.normalizePath(sourceFile.fileName)); if (sourceFile && getCanonicalFileName(ts.normalizePath(sourceFile.fileName)) === getCanonicalFileName(ts.normalizePath(defaultLibFileName))) { return getRenameInfoError(getLocaleSpecificMessage(Diagnostics.You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library)); } } } - let displayName = stripQuotes(getDeclaredName(typeChecker, symbol, node)); - let kind = getSymbolKind(symbol, node); + const displayName = stripQuotes(getDeclaredName(typeChecker, symbol, node)); + const kind = getSymbolKind(symbol, node); if (kind) { return { canRename: true, - localizedErrorMessage: undefined, + kind, displayName, + localizedErrorMessage: undefined, fullDisplayName: typeChecker.getFullyQualifiedName(symbol), - kind: kind, kindModifiers: getSymbolModifiers(symbol), triggerSpan: createTextSpan(node.getStart(), node.getWidth()) }; @@ -7434,14 +7433,14 @@ namespace ts { /* @internal */ export function getNameTable(sourceFile: SourceFile): Map { if (!sourceFile.nameTable) { - initializeNameTable(sourceFile) + initializeNameTable(sourceFile); } return sourceFile.nameTable; } function initializeNameTable(sourceFile: SourceFile): void { - let nameTable: Map = {}; + const nameTable: Map = {}; walk(sourceFile); sourceFile.nameTable = nameTable; @@ -7479,13 +7478,13 @@ namespace ts { /// Classifier export function createClassifier(): Classifier { - let scanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ false); + const scanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ false); /// We do not have a full parser support to know when we should parse a regex or not /// If we consider every slash token to be a regex, we could be missing cases like "1/2/3", where /// we have a series of divide operator. this list allows us to be more accurate by ruling out /// locations where a regexp cannot exist. - let noRegexTable: boolean[] = []; + const noRegexTable: boolean[] = []; noRegexTable[SyntaxKind.Identifier] = true; noRegexTable[SyntaxKind.StringLiteral] = true; noRegexTable[SyntaxKind.NumericLiteral] = true; @@ -7519,7 +7518,7 @@ namespace ts { // // Where on the second line, you will get the 'return' keyword, // a string literal, and a template end consisting of '} } `'. - let templateStack: SyntaxKind[] = []; + const templateStack: SyntaxKind[] = []; /** Returns true if 'keyword2' can legally follow 'keyword1' in any language construct. */ function canFollow(keyword1: SyntaxKind, keyword2: SyntaxKind) { @@ -7545,18 +7544,18 @@ namespace ts { } function convertClassifications(classifications: Classifications, text: string): ClassificationResult { - let entries: ClassificationInfo[] = []; - let dense = classifications.spans; + const entries: ClassificationInfo[] = []; + const dense = classifications.spans; let lastEnd = 0; for (let i = 0, n = dense.length; i < n; i += 3) { - let start = dense[i]; - let length = dense[i + 1]; - let type = dense[i + 2]; + const start = dense[i]; + const length = dense[i + 1]; + const type = dense[i + 2]; // Make a whitespace entry between the last item and this one. if (lastEnd >= 0) { - let whitespaceLength = start - lastEnd; + const whitespaceLength = start - lastEnd; if (whitespaceLength > 0) { entries.push({ length: whitespaceLength, classification: TokenClass.Whitespace }); } @@ -7566,7 +7565,7 @@ namespace ts { lastEnd = start + length; } - let whitespaceLength = text.length - lastEnd; + const whitespaceLength = text.length - lastEnd; if (whitespaceLength > 0) { entries.push({ length: whitespaceLength, classification: TokenClass.Whitespace }); } @@ -7620,7 +7619,7 @@ namespace ts { // (and a newline). That way when we lex we'll think we're still in a multiline comment. switch (lexState) { case EndOfLineState.InDoubleQuoteStringLiteral: - text = '"\\\n' + text; + text = "\"\\\n" + text; offset = 3; break; case EndOfLineState.InSingleQuoteStringLiteral: @@ -7646,7 +7645,7 @@ namespace ts { scanner.setText(text); - let result: Classifications = { + const result: Classifications = { endOfLineState: EndOfLineState.None, spans: [] }; @@ -7728,7 +7727,7 @@ namespace ts { // If we don't have anything on the template stack, // then we aren't trying to keep track of a previously scanned template head. if (templateStack.length > 0) { - let lastTemplateStackToken = lastOrUndefined(templateStack); + const lastTemplateStackToken = lastOrUndefined(templateStack); if (lastTemplateStackToken === SyntaxKind.TemplateHead) { token = scanner.reScanTemplateToken(); @@ -7758,17 +7757,17 @@ namespace ts { return result; function processToken(): void { - let start = scanner.getTokenPos(); - let end = scanner.getTextPos(); + const start = scanner.getTokenPos(); + const end = scanner.getTextPos(); addResult(start, end, classFromKind(token)); if (end >= text.length) { if (token === SyntaxKind.StringLiteral || token === SyntaxKind.StringLiteralType) { // Check to see if we finished up on a multiline string literal. - let tokenText = scanner.getTokenText(); + const tokenText = scanner.getTokenText(); if (scanner.isUnterminated()) { - let lastCharIndex = tokenText.length - 1; + const lastCharIndex = tokenText.length - 1; let numBackslashes = 0; while (tokenText.charCodeAt(lastCharIndex - numBackslashes) === CharacterCodes.backslash) { @@ -7777,7 +7776,7 @@ namespace ts { // If we have an odd number of backslashes, then the multiline string is unclosed if (numBackslashes & 1) { - let quoteChar = tokenText.charCodeAt(0); + const quoteChar = tokenText.charCodeAt(0); result.endOfLineState = quoteChar === CharacterCodes.doubleQuote ? EndOfLineState.InDoubleQuoteStringLiteral : EndOfLineState.InSingleQuoteStringLiteral; @@ -7826,7 +7825,7 @@ namespace ts { // relative to the original text. start -= offset; end -= offset; - let length = end - start; + const length = end - start; if (length > 0) { result.spans.push(start); @@ -7941,7 +7940,7 @@ namespace ts { } /// getDefaultLibraryFilePath - declare let __dirname: string; + declare const __dirname: string; /** * Get the path of the default library files (lib.d.ts) as distributed with the typescript From c0b0bebaa79d055bf23bde9e2a4c4eb5c7c97766 Mon Sep 17 00:00:00 2001 From: Yui T Date: Mon, 14 Dec 2015 14:04:14 -0800 Subject: [PATCH 38/79] Fix linting issue --- Jakefile.js | 3 +- src/services/services.ts | 1071 +++++++++++++++++++------------------- 2 files changed, 537 insertions(+), 537 deletions(-) diff --git a/Jakefile.js b/Jakefile.js index beb16d2886f..91bd805a27b 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -924,7 +924,8 @@ function lintFileAsync(options, path, cb) { var lintTargets = compilerSources .concat(harnessCoreSources) .concat(serverCoreSources) - .concat(scriptSources); + .concat(scriptSources) + .concat([path.join(servicesDirectory,"services.ts")]); desc("Runs tslint on the compiler sources"); task("lint", ["build-rules"], function() { diff --git a/src/services/services.ts b/src/services/services.ts index 8e2e4913edd..4109a4eb345 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -12,7 +12,7 @@ namespace ts { /** The version of the language service API */ - export let servicesVersion = "0.4" + export const servicesVersion = "0.4"; export interface Node { getSourceFile(): SourceFile; @@ -48,7 +48,7 @@ namespace ts { getConstructSignatures(): Signature[]; getStringIndexType(): Type; getNumberIndexType(): Type; - getBaseTypes(): ObjectType[] + getBaseTypes(): ObjectType[]; } export interface Signature { @@ -97,7 +97,7 @@ namespace ts { dispose?(): void; } - export module ScriptSnapshot { + export namespace ScriptSnapshot { class StringScriptSnapshot implements IScriptSnapshot { constructor(private text: string) { @@ -126,12 +126,12 @@ namespace ts { referencedFiles: FileReference[]; importedFiles: FileReference[]; ambientExternalModules: string[]; - isLibFile: boolean + isLibFile: boolean; } - let scanner: Scanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ true); + const scanner: Scanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ true); - let emptyArray: any[] = []; + const emptyArray: any[] = []; const jsDocTagNames = [ "augments", @@ -174,7 +174,7 @@ namespace ts { let jsDocCompletionEntries: CompletionEntry[]; function createNode(kind: SyntaxKind, pos: number, end: number, flags: NodeFlags, parent?: Node): NodeObject { - let node = new NodeObject(kind, pos, end); + const node = new NodeObject(kind, pos, end); node.flags = flags; node.parent = parent; return node; @@ -235,8 +235,8 @@ namespace ts { private addSyntheticNodes(nodes: Node[], pos: number, end: number): number { scanner.setTextPos(pos); while (pos < end) { - let token = scanner.scan(); - let textPos = scanner.getTextPos(); + const token = scanner.scan(); + const textPos = scanner.getTextPos(); nodes.push(createNode(token, pos, textPos, NodeFlags.Synthetic, this)); pos = textPos; } @@ -244,13 +244,11 @@ namespace ts { } private createSyntaxList(nodes: NodeArray): Node { - let list = createNode(SyntaxKind.SyntaxList, nodes.pos, nodes.end, NodeFlags.Synthetic, this); + const list = createNode(SyntaxKind.SyntaxList, nodes.pos, nodes.end, NodeFlags.Synthetic, this); list._children = []; let pos = nodes.pos; - - - for (let node of nodes) { + for (const node of nodes) { if (pos < node.pos) { pos = this.addSyntheticNodes(list._children, pos, node.pos); } @@ -269,14 +267,14 @@ namespace ts { scanner.setText((sourceFile || this.getSourceFile()).text); children = []; let pos = this.pos; - let processNode = (node: Node) => { + const processNode = (node: Node) => { if (pos < node.pos) { pos = this.addSyntheticNodes(children, pos, node.pos); } children.push(node); pos = node.end; }; - let processNodes = (nodes: NodeArray) => { + const processNodes = (nodes: NodeArray) => { if (pos < nodes.pos) { pos = this.addSyntheticNodes(children, pos, nodes.pos); } @@ -308,20 +306,20 @@ namespace ts { } public getFirstToken(sourceFile?: SourceFile): Node { - let children = this.getChildren(sourceFile); + const children = this.getChildren(sourceFile); if (!children.length) { return undefined; } - let child = children[0]; + const child = children[0]; return child.kind < SyntaxKind.FirstNode ? child : child.getFirstToken(sourceFile); } public getLastToken(sourceFile?: SourceFile): Node { - let children = this.getChildren(sourceFile); + const children = this.getChildren(sourceFile); - let child = lastOrUndefined(children); + const child = lastOrUndefined(children); if (!child) { return undefined; } @@ -366,8 +364,8 @@ namespace ts { } function getJsDocCommentsFromDeclarations(declarations: Declaration[], name: string, canUseParsedParamTagComments: boolean) { - let documentationComment = []; - let docComments = getJsDocCommentsSeparatedByNewLines(); + const documentationComment = []; + const docComments = getJsDocCommentsSeparatedByNewLines(); ts.forEach(docComments, docComment => { if (documentationComment.length) { documentationComment.push(lineBreakPart()); @@ -378,22 +376,22 @@ namespace ts { return documentationComment; function getJsDocCommentsSeparatedByNewLines() { - let paramTag = "@param"; - let jsDocCommentParts: SymbolDisplayPart[] = []; + const paramTag = "@param"; + const jsDocCommentParts: SymbolDisplayPart[] = []; ts.forEach(declarations, (declaration, indexOfDeclaration) => { // Make sure we are collecting doc comment from declaration once, // In case of union property there might be same declaration multiple times // which only varies in type parameter - // Eg. let a: Array | Array; a.length + // Eg. const a: Array | Array; a.length // The property length will have two declarations of property length coming // from Array - Array and Array if (indexOf(declarations, declaration) === indexOfDeclaration) { - let sourceFileOfDeclaration = getSourceFileOfNode(declaration); + const sourceFileOfDeclaration = getSourceFileOfNode(declaration); // If it is parameter - try and get the jsDoc comment with @param tag from function declaration's jsDoc comments if (canUseParsedParamTagComments && declaration.kind === SyntaxKind.Parameter) { ts.forEach(getJsDocCommentTextRange(declaration.parent, sourceFileOfDeclaration), jsDocCommentTextRange => { - let cleanedParamJsDocComment = getCleanedParamJsDocComment(jsDocCommentTextRange.pos, jsDocCommentTextRange.end, sourceFileOfDeclaration); + const cleanedParamJsDocComment = getCleanedParamJsDocComment(jsDocCommentTextRange.pos, jsDocCommentTextRange.end, sourceFileOfDeclaration); if (cleanedParamJsDocComment) { addRange(jsDocCommentParts, cleanedParamJsDocComment); } @@ -413,7 +411,7 @@ namespace ts { // Get the cleaned js doc comment text from the declaration ts.forEach(getJsDocCommentTextRange( declaration.kind === SyntaxKind.VariableDeclaration ? declaration.parent.parent : declaration, sourceFileOfDeclaration), jsDocCommentTextRange => { - let cleanedJsDocComment = getCleanedJsDocComment(jsDocCommentTextRange.pos, jsDocCommentTextRange.end, sourceFileOfDeclaration); + const cleanedJsDocComment = getCleanedJsDocComment(jsDocCommentTextRange.pos, jsDocCommentTextRange.end, sourceFileOfDeclaration); if (cleanedJsDocComment) { addRange(jsDocCommentParts, cleanedJsDocComment); } @@ -439,7 +437,7 @@ namespace ts { } for (; pos < end; pos++) { - let ch = sourceFile.text.charCodeAt(pos); + const ch = sourceFile.text.charCodeAt(pos); if (!isWhiteSpace(ch) || isLineBreak(ch)) { // Either found lineBreak or non whiteSpace return pos; @@ -480,7 +478,7 @@ namespace ts { function getCleanedJsDocComment(pos: number, end: number, sourceFile: SourceFile) { let spacesToRemoveAfterAsterisk: number; - let docComments: SymbolDisplayPart[] = []; + const docComments: SymbolDisplayPart[] = []; let blankLineCount = 0; let isInParamTag = false; @@ -491,7 +489,7 @@ namespace ts { // If the comment starts with '*' consume the spaces on this line if (pos < end && sourceFile.text.charCodeAt(pos) === CharacterCodes.asterisk) { - let lineStartPos = pos + 1; + const lineStartPos = pos + 1; pos = consumeWhiteSpacesOnTheLine(pos + 1, end, sourceFile, spacesToRemoveAfterAsterisk); // Set the spaces to remove after asterisk as margin if not already set @@ -505,7 +503,7 @@ namespace ts { // Analyse text on this line while (pos < end && !isLineBreak(sourceFile.text.charCodeAt(pos))) { - let ch = sourceFile.text.charAt(pos); + const ch = sourceFile.text.charAt(pos); if (ch === "@") { // If it is @param tag if (isParamTag(pos, end, sourceFile)) { @@ -544,7 +542,7 @@ namespace ts { function getCleanedParamJsDocComment(pos: number, end: number, sourceFile: SourceFile) { let paramHelpStringMargin: number; - let paramDocComments: SymbolDisplayPart[] = []; + const paramDocComments: SymbolDisplayPart[] = []; while (pos < end) { if (isParamTag(pos, end, sourceFile)) { let blankLineCount = 0; @@ -559,7 +557,7 @@ namespace ts { if (sourceFile.text.charCodeAt(pos) === CharacterCodes.openBrace) { pos++; for (let curlies = 1; pos < end; pos++) { - let charCode = sourceFile.text.charCodeAt(pos); + const charCode = sourceFile.text.charCodeAt(pos); // { character means we need to find another } to match the found one if (charCode === CharacterCodes.openBrace) { @@ -603,9 +601,9 @@ namespace ts { } let paramHelpString = ""; - let firstLineParamHelpStringPos = pos; + const firstLineParamHelpStringPos = pos; while (pos < end) { - let ch = sourceFile.text.charCodeAt(pos); + const ch = sourceFile.text.charCodeAt(pos); // at line break, set this comment line text and go to next line if (isLineBreak(ch)) { @@ -674,15 +672,15 @@ namespace ts { } // Now consume white spaces max - let startOfLinePos = pos; + const startOfLinePos = pos; pos = consumeWhiteSpacesOnTheLine(pos, end, sourceFile, paramHelpStringMargin); if (pos >= end) { return; } - let consumedSpaces = pos - startOfLinePos; + const consumedSpaces = pos - startOfLinePos; if (consumedSpaces < paramHelpStringMargin) { - let ch = sourceFile.text.charCodeAt(pos); + const ch = sourceFile.text.charCodeAt(pos); if (ch === CharacterCodes.asterisk) { // Consume more spaces after asterisk pos = consumeWhiteSpacesOnTheLine(pos + 1, end, sourceFile, paramHelpStringMargin - consumedSpaces - 1); @@ -815,7 +813,7 @@ namespace ts { private namedDeclarations: Map; constructor(kind: SyntaxKind, pos: number, end: number) { - super(kind, pos, end) + super(kind, pos, end); } public update(newText: string, textChangeRange: TextChangeRange): SourceFile { @@ -843,16 +841,16 @@ namespace ts { } private computeNamedDeclarations(): Map { - let result: Map = {}; + const result: Map = {}; forEachChild(this, visit); return result; function addDeclaration(declaration: Declaration) { - let name = getDeclarationName(declaration); + const name = getDeclarationName(declaration); if (name) { - let declarations = getDeclarations(name); + const declarations = getDeclarations(name); declarations.push(declaration); } } @@ -863,13 +861,13 @@ namespace ts { function getDeclarationName(declaration: Declaration) { if (declaration.name) { - let result = getTextOfIdentifierOrLiteral(declaration.name); + const result = getTextOfIdentifierOrLiteral(declaration.name); if (result !== undefined) { return result; } if (declaration.name.kind === SyntaxKind.ComputedPropertyName) { - let expr = (declaration.name).expression; + const expr = (declaration.name).expression; if (expr.kind === SyntaxKind.PropertyAccessExpression) { return (expr).name.text; } @@ -899,12 +897,12 @@ namespace ts { case SyntaxKind.FunctionDeclaration: case SyntaxKind.MethodDeclaration: case SyntaxKind.MethodSignature: - let functionDeclaration = node; - let declarationName = getDeclarationName(functionDeclaration); + const functionDeclaration = node; + const declarationName = getDeclarationName(functionDeclaration); if (declarationName) { - let declarations = getDeclarations(declarationName); - let lastDeclaration = lastOrUndefined(declarations); + const declarations = getDeclarations(declarationName); + const lastDeclaration = lastOrUndefined(declarations); // Check whether this declaration belongs to an "overload group". if (lastDeclaration && functionDeclaration.parent === lastDeclaration.parent && functionDeclaration.symbol === lastDeclaration.symbol) { @@ -980,7 +978,7 @@ namespace ts { break; case SyntaxKind.ImportDeclaration: - let importClause = (node).importClause; + const importClause = (node).importClause; if (importClause) { // Handle default import case e.g.: // import d from "mod"; @@ -1113,8 +1111,8 @@ namespace ts { } export interface Classifications { - spans: number[], - endOfLineState: EndOfLineState + spans: number[]; + endOfLineState: EndOfLineState; } export interface ClassifiedSpan { @@ -1171,7 +1169,7 @@ namespace ts { highlightSpans: HighlightSpan[]; } - export module HighlightSpanKind { + export namespace HighlightSpanKind { export const none = "none"; export const definition = "definition"; export const reference = "reference"; @@ -1220,7 +1218,7 @@ namespace ts { InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: boolean; PlaceOpenBraceOnNewLineForFunctions: boolean; PlaceOpenBraceOnNewLineForControlBlocks: boolean; - [s: string]: boolean | number| string; + [s: string]: boolean | number | string; } export interface DefinitionInfo { @@ -1500,7 +1498,7 @@ namespace ts { } // TODO: move these to enums - export module ScriptElementKind { + export namespace ScriptElementKind { export const unknown = ""; export const warning = "warning"; @@ -1529,7 +1527,7 @@ namespace ts { export const enumElement = "enum"; // Inside module and script only - // let v = .. + // const v = .. export const variableElement = "var"; // Inside function @@ -1581,7 +1579,7 @@ namespace ts { export const letElement = "let"; } - export module ScriptElementKindModifier { + export namespace ScriptElementKindModifier { export const none = ""; export const publicMemberModifier = "public"; export const privateMemberModifier = "private"; @@ -1723,8 +1721,8 @@ namespace ts { this.fileNameToEntry = createFileMap(); // Initialize the list with the root file names - let rootFileNames = host.getScriptFileNames(); - for (let fileName of rootFileNames) { + const rootFileNames = host.getScriptFileNames(); + for (const fileName of rootFileNames) { this.createEntry(fileName, toPath(fileName, this.currentDirectory, getCanonicalFileName)); } @@ -1738,7 +1736,7 @@ namespace ts { private createEntry(fileName: string, path: Path) { let entry: HostFileInformation; - let scriptSnapshot = this.host.getScriptSnapshot(fileName); + const scriptSnapshot = this.host.getScriptSnapshot(fileName); if (scriptSnapshot) { entry = { hostFileName: fileName, @@ -1760,7 +1758,7 @@ namespace ts { } public getOrCreateEntry(fileName: string): HostFileInformation { - let path = toPath(fileName, this.currentDirectory, this.getCanonicalFileName) + const path = toPath(fileName, this.currentDirectory, this.getCanonicalFileName); if (this.contains(path)) { return this.getEntry(path); } @@ -1769,7 +1767,7 @@ namespace ts { } public getRootFileNames(): string[] { - let fileNames: string[] = []; + const fileNames: string[] = []; this.fileNameToEntry.forEachValue((path, value) => { if (value) { @@ -1781,12 +1779,12 @@ namespace ts { } public getVersion(path: Path): string { - let file = this.getEntry(path); + const file = this.getEntry(path); return file && file.version; } public getScriptSnapshot(path: Path): IScriptSnapshot { - let file = this.getEntry(path); + const file = this.getEntry(path); return file && file.scriptSnapshot; } } @@ -1803,22 +1801,22 @@ namespace ts { } public getCurrentSourceFile(fileName: string): SourceFile { - let scriptSnapshot = this.host.getScriptSnapshot(fileName); + const scriptSnapshot = this.host.getScriptSnapshot(fileName); if (!scriptSnapshot) { // The host does not know about this file. throw new Error("Could not find file: '" + fileName + "'."); } - let version = this.host.getScriptVersion(fileName); + const version = this.host.getScriptVersion(fileName); let sourceFile: SourceFile; if (this.currentFileName !== fileName) { // This is a new file, just parse it - sourceFile = createLanguageServiceSourceFile(fileName, scriptSnapshot, ScriptTarget.Latest, version, /*setNodeParents:*/ true); + sourceFile = createLanguageServiceSourceFile(fileName, scriptSnapshot, ScriptTarget.Latest, version, /*setNodeParents*/ true); } else if (this.currentFileVersion !== version) { // This is the same file, just a newer version. Incrementally parse the file. - let editRange = scriptSnapshot.getChangeRange(this.currentFileScriptSnapshot); + const editRange = scriptSnapshot.getChangeRange(this.currentFileScriptSnapshot); sourceFile = updateLanguageServiceSourceFile(this.currentSourceFile, scriptSnapshot, version, editRange); } @@ -1863,7 +1861,7 @@ namespace ts { * - noResolve = true */ export function transpileModule(input: string, transpileOptions: TranspileOptions): TranspileOutput { - let options = transpileOptions.compilerOptions ? clone(transpileOptions.compilerOptions) : getDefaultCompilerOptions(); + const options = transpileOptions.compilerOptions ? clone(transpileOptions.compilerOptions) : getDefaultCompilerOptions(); options.isolatedModules = true; @@ -1879,21 +1877,22 @@ namespace ts { options.noResolve = true; // if jsx is specified then treat file as .tsx - let inputFileName = transpileOptions.fileName || (options.jsx ? "module.tsx" : "module.ts"); - let sourceFile = createSourceFile(inputFileName, input, options.target); + const inputFileName = transpileOptions.fileName || (options.jsx ? "module.tsx" : "module.ts"); + const sourceFile = createSourceFile(inputFileName, input, options.target); if (transpileOptions.moduleName) { sourceFile.moduleName = transpileOptions.moduleName; } sourceFile.renamedDependencies = transpileOptions.renamedDependencies; - let newLine = getNewLineCharacter(options); + const newLine = getNewLineCharacter(options); // Output let outputText: string; let sourceMapText: string; + // Create a compilerHost object to allow the compiler to read and write files - let compilerHost: CompilerHost = { + const compilerHost: CompilerHost = { getSourceFile: (fileName, target) => fileName === normalizeSlashes(inputFileName) ? sourceFile : undefined, writeFile: (name, text, writeByteOrderMark) => { if (fileExtensionIs(name, ".map")) { @@ -1914,7 +1913,7 @@ namespace ts { readFile: (fileName): string => "" }; - let program = createProgram([inputFileName], options, compilerHost); + const program = createProgram([inputFileName], options, compilerHost); let diagnostics: Diagnostic[]; if (transpileOptions.reportDiagnostics) { @@ -1934,15 +1933,15 @@ namespace ts { * This is a shortcut function for transpileModule - it accepts transpileOptions as parameters and returns only outputText part of the result. */ export function transpile(input: string, compilerOptions?: CompilerOptions, fileName?: string, diagnostics?: Diagnostic[], moduleName?: string): string { - let output = transpileModule(input, { compilerOptions, fileName, reportDiagnostics: !!diagnostics, moduleName }); + const output = transpileModule(input, { compilerOptions, fileName, reportDiagnostics: !!diagnostics, moduleName }); // addRange correctly handles cases when wither 'from' or 'to' argument is missing addRange(diagnostics, output.diagnostics); return output.outputText; } export function createLanguageServiceSourceFile(fileName: string, scriptSnapshot: IScriptSnapshot, scriptTarget: ScriptTarget, version: string, setNodeParents: boolean): SourceFile { - let text = scriptSnapshot.getText(0, scriptSnapshot.getLength()); - let sourceFile = createSourceFile(fileName, text, scriptTarget, setNodeParents); + const text = scriptSnapshot.getText(0, scriptSnapshot.getLength()); + const sourceFile = createSourceFile(fileName, text, scriptTarget, setNodeParents); setSourceFileFields(sourceFile, scriptSnapshot, version); // after full parsing we can use table with interned strings as name table sourceFile.nameTable = sourceFile.identifiers; @@ -1961,12 +1960,12 @@ namespace ts { let newText: string; // grab the fragment from the beginning of the original text to the beginning of the span - let prefix = textChangeRange.span.start !== 0 + const prefix = textChangeRange.span.start !== 0 ? sourceFile.text.substr(0, textChangeRange.span.start) : ""; // grab the fragment from the end of the span till the end of the original text - let suffix = textSpanEnd(textChangeRange.span) !== sourceFile.text.length + const suffix = textSpanEnd(textChangeRange.span) !== sourceFile.text.length ? sourceFile.text.substr(textSpanEnd(textChangeRange.span)) : ""; @@ -1976,7 +1975,7 @@ namespace ts { } else { // it was actual edit, fetch the fragment of new text that correspond to new span - let changedText = scriptSnapshot.getText(textChangeRange.span.start, textChangeRange.span.start + textChangeRange.newLength); + const changedText = scriptSnapshot.getText(textChangeRange.span.start, textChangeRange.span.start + textChangeRange.newLength); // combine prefix, changed text and suffix newText = prefix && suffix ? prefix + changedText + suffix @@ -1985,7 +1984,7 @@ namespace ts { : (changedText + suffix); } - let newSourceFile = updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks); + const newSourceFile = updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks); setSourceFileFields(newSourceFile, scriptSnapshot, version); // after incremental parsing nameTable might not be up-to-date // drop it so it can be lazily recreated later @@ -2006,7 +2005,7 @@ namespace ts { } // Otherwise, just create a new source file. - return createLanguageServiceSourceFile(sourceFile.fileName, scriptSnapshot, sourceFile.languageVersion, version, /*setNodeParents:*/ true); + return createLanguageServiceSourceFile(sourceFile.fileName, scriptSnapshot, sourceFile.languageVersion, version, /*setNodeParents*/ true); } export function createGetCanonicalFileName(useCaseSensitivefileNames: boolean): (fileName: string) => string { @@ -2019,15 +2018,15 @@ namespace ts { export function createDocumentRegistry(useCaseSensitiveFileNames?: boolean, currentDirectory = ""): DocumentRegistry { // Maps from compiler setting target (ES3, ES5, etc.) to all the cached documents we have // for those settings. - let buckets: Map> = {}; - let getCanonicalFileName = createGetCanonicalFileName(!!useCaseSensitiveFileNames); + const buckets: Map> = {}; + const getCanonicalFileName = createGetCanonicalFileName(!!useCaseSensitiveFileNames); function getKeyFromCompilationSettings(settings: CompilerOptions): string { return "_" + settings.target + "|" + settings.module + "|" + settings.noResolve + "|" + settings.jsx + +"|" + settings.allowJs; } function getBucketForCompilationSettings(settings: CompilerOptions, createIfMissing: boolean): FileMap { - let key = getKeyFromCompilationSettings(settings); + const key = getKeyFromCompilationSettings(settings); let bucket = lookUp(buckets, key); if (!bucket && createIfMissing) { buckets[key] = bucket = createFileMap(); @@ -2036,9 +2035,9 @@ namespace ts { } function reportStats() { - let bucketInfoArray = Object.keys(buckets).filter(name => name && name.charAt(0) === '_').map(name => { - let entries = lookUp(buckets, name); - let sourceFiles: { name: string; refCount: number; references: string[]; }[] = []; + const bucketInfoArray = Object.keys(buckets).filter(name => name && name.charAt(0) === "_").map(name => { + const entries = lookUp(buckets, name); + const sourceFiles: { name: string; refCount: number; references: string[]; }[] = []; entries.forEachValue((key, entry) => { sourceFiles.push({ name: key, @@ -2052,15 +2051,15 @@ namespace ts { sourceFiles }; }); - return JSON.stringify(bucketInfoArray, null, 2); + return JSON.stringify(bucketInfoArray, undefined, 2); } function acquireDocument(fileName: string, compilationSettings: CompilerOptions, scriptSnapshot: IScriptSnapshot, version: string): SourceFile { - return acquireOrUpdateDocument(fileName, compilationSettings, scriptSnapshot, version, /*acquiring:*/ true); + return acquireOrUpdateDocument(fileName, compilationSettings, scriptSnapshot, version, /*acquiring*/ true); } function updateDocument(fileName: string, compilationSettings: CompilerOptions, scriptSnapshot: IScriptSnapshot, version: string): SourceFile { - return acquireOrUpdateDocument(fileName, compilationSettings, scriptSnapshot, version, /*acquiring:*/ false); + return acquireOrUpdateDocument(fileName, compilationSettings, scriptSnapshot, version, /*acquiring*/ false); } function acquireOrUpdateDocument( @@ -2070,14 +2069,14 @@ namespace ts { version: string, acquiring: boolean): SourceFile { - let bucket = getBucketForCompilationSettings(compilationSettings, /*createIfMissing*/ true); - let path = toPath(fileName, currentDirectory, getCanonicalFileName); + const bucket = getBucketForCompilationSettings(compilationSettings, /*createIfMissing*/ true); + const path = toPath(fileName, currentDirectory, getCanonicalFileName); let entry = bucket.get(path); if (!entry) { Debug.assert(acquiring, "How could we be trying to update a document that the registry doesn't have?"); // Have never seen this file with these settings. Create a new source file for it. - let sourceFile = createLanguageServiceSourceFile(fileName, scriptSnapshot, compilationSettings.target, version, /*setNodeParents:*/ false); + const sourceFile = createLanguageServiceSourceFile(fileName, scriptSnapshot, compilationSettings.target, version, /*setNodeParents*/ false); entry = { sourceFile: sourceFile, @@ -2109,12 +2108,12 @@ namespace ts { } function releaseDocument(fileName: string, compilationSettings: CompilerOptions): void { - let bucket = getBucketForCompilationSettings(compilationSettings, false); + const bucket = getBucketForCompilationSettings(compilationSettings, /*createIfMissing*/false); Debug.assert(bucket !== undefined); - let path = toPath(fileName, currentDirectory, getCanonicalFileName); + const path = toPath(fileName, currentDirectory, getCanonicalFileName); - let entry = bucket.get(path); + const entry = bucket.get(path); entry.languageServiceRefCount--; Debug.assert(entry.languageServiceRefCount >= 0); @@ -2132,19 +2131,19 @@ namespace ts { } export function preProcessFile(sourceText: string, readImportFiles = true, detectJavaScriptImports = false): PreProcessedFileInfo { - let referencedFiles: FileReference[] = []; - let importedFiles: FileReference[] = []; + const referencedFiles: FileReference[] = []; + const importedFiles: FileReference[] = []; let ambientExternalModules: string[]; let isNoDefaultLib = false; function processTripleSlashDirectives(): void { - let commentRanges = getLeadingCommentRanges(sourceText, 0); + const commentRanges = getLeadingCommentRanges(sourceText, 0); forEach(commentRanges, commentRange => { - let comment = sourceText.substring(commentRange.pos, commentRange.end); - let referencePathMatchResult = getFileReferenceFromReferencePath(comment, commentRange); + const comment = sourceText.substring(commentRange.pos, commentRange.end); + const referencePathMatchResult = getFileReferenceFromReferencePath(comment, commentRange); if (referencePathMatchResult) { isNoDefaultLib = referencePathMatchResult.isNoDefaultLib; - let fileReference = referencePathMatchResult.fileReference; + const fileReference = referencePathMatchResult.fileReference; if (fileReference) { referencedFiles.push(fileReference); } @@ -2160,8 +2159,8 @@ namespace ts { } function recordModuleName() { - let importPath = scanner.getTokenValue(); - let pos = scanner.getTokenPos(); + const importPath = scanner.getTokenValue(); + const pos = scanner.getTokenPos(); importedFiles.push({ fileName: importPath, pos: pos, @@ -2213,7 +2212,7 @@ namespace ts { } } else if (token === SyntaxKind.EqualsToken) { - if (tryConsumeRequireCall(/* skipCurrentToken */ true)) { + if (tryConsumeRequireCall(/*skipCurrentToken*/ true)) { return true; } } @@ -2311,7 +2310,7 @@ namespace ts { if (token === SyntaxKind.Identifier || isKeyword(token)) { token = scanner.scan(); if (token === SyntaxKind.EqualsToken) { - if (tryConsumeRequireCall(/* skipCurrentToken */ true)) { + if (tryConsumeRequireCall(/*skipCurrentToken*/ true)) { return true; } } @@ -2410,7 +2409,7 @@ namespace ts { if (tryConsumeDeclare() || tryConsumeImport() || tryConsumeExport() || - (detectJavaScriptImports && (tryConsumeRequireCall(/* skipCurrentToken */ false) || tryConsumeDefine()))) { + (detectJavaScriptImports && (tryConsumeRequireCall(/*skipCurrentToken*/ false) || tryConsumeDefine()))) { continue; } else { @@ -2550,8 +2549,8 @@ namespace ts { return true; } else if (position === comment.end) { - let text = sourceFile.text; - let width = comment.end - comment.pos; + const text = sourceFile.text; + const width = comment.end - comment.pos; // is single line comment or just /* if (width <= 2 || text.charCodeAt(comment.pos + 1) === CharacterCodes.slash) { return true; @@ -2583,7 +2582,7 @@ namespace ts { } // A cache of completion entries for keywords, these do not change between sessions - let keywordCompletions: CompletionEntry[] = []; + const keywordCompletions: CompletionEntry[] = []; for (let i = SyntaxKind.FirstKeyword; i <= SyntaxKind.LastKeyword; i++) { keywordCompletions.push({ name: tokenToString(i), @@ -2673,15 +2672,15 @@ namespace ts { export function createLanguageService(host: LanguageServiceHost, documentRegistry: DocumentRegistry = createDocumentRegistry(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames(), host.getCurrentDirectory())): LanguageService { - let syntaxTreeCache: SyntaxTreeCache = new SyntaxTreeCache(host); + const syntaxTreeCache: SyntaxTreeCache = new SyntaxTreeCache(host); let ruleProvider: formatting.RulesProvider; let program: Program; let lastProjectVersion: string; - let useCaseSensitivefileNames = false; - let cancellationToken = new CancellationTokenObject(host.getCancellationToken && host.getCancellationToken()); + const useCaseSensitivefileNames = false; + const cancellationToken = new CancellationTokenObject(host.getCancellationToken && host.getCancellationToken()); - let currentDirectory = host.getCurrentDirectory(); + const currentDirectory = host.getCurrentDirectory(); // Check if the localized messages json is set, otherwise query the host for it if (!localizedDiagnosticMessages && host.getLocalizedDiagnosticMessages) { localizedDiagnosticMessages = host.getLocalizedDiagnosticMessages(); @@ -2693,10 +2692,10 @@ namespace ts { } } - let getCanonicalFileName = createGetCanonicalFileName(useCaseSensitivefileNames); + const getCanonicalFileName = createGetCanonicalFileName(useCaseSensitivefileNames); function getValidSourceFile(fileName: string): SourceFile { - let sourceFile = program.getSourceFile(fileName); + const sourceFile = program.getSourceFile(fileName); if (!sourceFile) { throw new Error("Could not find file: '" + fileName + "'."); } @@ -2716,7 +2715,7 @@ namespace ts { function synchronizeHostData(): void { // perform fast check if host supports it if (host.getProjectVersion) { - let hostProjectVersion = host.getProjectVersion(); + const hostProjectVersion = host.getProjectVersion(); if (hostProjectVersion) { if (lastProjectVersion === hostProjectVersion) { return; @@ -2740,17 +2739,17 @@ namespace ts { // the program points to old source files that have been invalidated because of // incremental parsing. - let oldSettings = program && program.getCompilerOptions(); - let newSettings = hostCache.compilationSettings(); - let changesInCompilationSettingsAffectSyntax = oldSettings && + const oldSettings = program && program.getCompilerOptions(); + const newSettings = hostCache.compilationSettings(); + const changesInCompilationSettingsAffectSyntax = oldSettings && (oldSettings.target !== newSettings.target || oldSettings.module !== newSettings.module || oldSettings.noResolve !== newSettings.noResolve || - oldSettings.jsx !== newSettings.jsx || + oldSettings.jsx !== newSettings.jsx || oldSettings.allowJs !== newSettings.allowJs); // Now create a new compiler - let compilerHost: CompilerHost = { + const compilerHost: CompilerHost = { getSourceFile: getOrCreateSourceFile, getCancellationToken: () => cancellationToken, getCanonicalFileName, @@ -2766,22 +2765,22 @@ namespace ts { }, readFile: (fileName): string => { // stub missing host functionality - let entry = hostCache.getOrCreateEntry(fileName); + const entry = hostCache.getOrCreateEntry(fileName); return entry && entry.scriptSnapshot.getText(0, entry.scriptSnapshot.getLength()); } }; if (host.resolveModuleNames) { - compilerHost.resolveModuleNames = (moduleNames, containingFile) => host.resolveModuleNames(moduleNames, containingFile) + compilerHost.resolveModuleNames = (moduleNames, containingFile) => host.resolveModuleNames(moduleNames, containingFile); } - let newProgram = createProgram(hostCache.getRootFileNames(), newSettings, compilerHost, program); + const newProgram = createProgram(hostCache.getRootFileNames(), newSettings, compilerHost, program); // Release any files we have acquired in the old program but are // not part of the new program. if (program) { - let oldSourceFiles = program.getSourceFiles(); - for (let oldSourceFile of oldSourceFiles) { + const oldSourceFiles = program.getSourceFiles(); + for (const oldSourceFile of oldSourceFiles) { if (!newProgram.getSourceFile(oldSourceFile.fileName) || changesInCompilationSettingsAffectSyntax) { documentRegistry.releaseDocument(oldSourceFile.fileName, oldSettings); } @@ -2804,7 +2803,7 @@ namespace ts { // The program is asking for this file, check first if the host can locate it. // If the host can not locate the file, then it does not exist. return undefined // to the program to allow reporting of errors for missing files. - let hostFileInformation = hostCache.getOrCreateEntry(fileName); + const hostFileInformation = hostCache.getOrCreateEntry(fileName); if (!hostFileInformation) { return undefined; } @@ -2814,7 +2813,7 @@ namespace ts { // can not be reused. we have to dump all syntax trees and create new ones. if (!changesInCompilationSettingsAffectSyntax) { // Check if the old program had this file already - let oldSourceFile = program && program.getSourceFile(fileName); + const oldSourceFile = program && program.getSourceFile(fileName); if (oldSourceFile) { // We already had a source file for this file name. Go to the registry to // ensure that we get the right up to date version of it. We need this to @@ -2851,7 +2850,7 @@ namespace ts { if (!sourceFile) { return false; } - let path = sourceFile.path || toPath(sourceFile.fileName, currentDirectory, getCanonicalFileName); + const path = sourceFile.path || toPath(sourceFile.fileName, currentDirectory, getCanonicalFileName); return sourceFile.version === hostCache.getVersion(path); } @@ -2862,13 +2861,13 @@ namespace ts { } // If number of files in the program do not match, it is not up-to-date - let rootFileNames = hostCache.getRootFileNames(); + const rootFileNames = hostCache.getRootFileNames(); if (program.getSourceFiles().length !== rootFileNames.length) { return false; } // If any file is not up-to-date, then the whole program is not up-to-date - for (let fileName of rootFileNames) { + for (const fileName of rootFileNames) { if (!sourceFileUpToDate(program.getSourceFile(fileName))) { return false; } @@ -2910,18 +2909,18 @@ namespace ts { function getSemanticDiagnostics(fileName: string): Diagnostic[] { synchronizeHostData(); - let targetSourceFile = getValidSourceFile(fileName); + const targetSourceFile = getValidSourceFile(fileName); // Only perform the action per file regardless of '-out' flag as LanguageServiceHost is expected to call this function per file. // Therefore only get diagnostics for given file. - let semanticDiagnostics = program.getSemanticDiagnostics(targetSourceFile, cancellationToken); + const semanticDiagnostics = program.getSemanticDiagnostics(targetSourceFile, cancellationToken); if (!program.getCompilerOptions().declaration) { return semanticDiagnostics; } // If '-d' is enabled, check for emitter error. One example of emitter error is export class implements non-export interface - let declarationDiagnostics = program.getDeclarationDiagnostics(targetSourceFile, cancellationToken); + const declarationDiagnostics = program.getDeclarationDiagnostics(targetSourceFile, cancellationToken); return concatenate(semanticDiagnostics, declarationDiagnostics); } @@ -2937,14 +2936,14 @@ namespace ts { * @return undefined if the name is of external module otherwise a name with striped of any quote */ function getCompletionEntryDisplayNameForSymbol(symbol: Symbol, target: ScriptTarget, performCharacterChecks: boolean, location: Node): string { - let displayName: string = getDeclaredName(program.getTypeChecker(), symbol, location); + const displayName: string = getDeclaredName(program.getTypeChecker(), symbol, location); if (displayName) { - let firstCharCode = displayName.charCodeAt(0); + const firstCharCode = displayName.charCodeAt(0); // First check of the displayName is not external module; if it is an external module, it is not valid entry if ((symbol.flags & SymbolFlags.Namespace) && (firstCharCode === CharacterCodes.singleQuote || firstCharCode === CharacterCodes.doubleQuote)) { // If the symbol is external module, don't show it in the completion list - // (i.e declare module "http" { let x; } | // <= request completion here, "http" should not be there) + // (i.e declare module "http" { const x; } | // <= request completion here, "http" should not be there) return undefined; } } @@ -2987,20 +2986,20 @@ namespace ts { } function getCompletionData(fileName: string, position: number) { - let typeChecker = program.getTypeChecker(); - let syntacticStart = new Date().getTime(); - let sourceFile = getValidSourceFile(fileName); - let isJavaScriptFile = isSourceFileJavaScript(sourceFile); + const typeChecker = program.getTypeChecker(); + const syntacticStart = new Date().getTime(); + const sourceFile = getValidSourceFile(fileName); + const isJavaScriptFile = isSourceFileJavaScript(sourceFile); let isJsDocTagName = false; let start = new Date().getTime(); - let currentToken = getTokenAtPosition(sourceFile, position); + const currentToken = getTokenAtPosition(sourceFile, position); log("getCompletionData: Get current token: " + (new Date().getTime() - start)); start = new Date().getTime(); // Completion not allowed inside comments, bail out if this is the case - let insideComment = isInsideComment(sourceFile, currentToken, position); + const insideComment = isInsideComment(sourceFile, currentToken, position); log("getCompletionData: Is inside comment: " + (new Date().getTime() - start)); if (insideComment) { @@ -3014,7 +3013,7 @@ namespace ts { // /** @type {number | string} */ // Completion should work in the brackets let insideJsDocTagExpression = false; - let tag = getJsDocTagAtPosition(sourceFile, position); + const tag = getJsDocTagAtPosition(sourceFile, position); if (tag) { if (tag.tagName.pos <= position && position <= tag.tagName.end) { isJsDocTagName = true; @@ -3024,7 +3023,7 @@ namespace ts { case SyntaxKind.JSDocTypeTag: case SyntaxKind.JSDocParameterTag: case SyntaxKind.JSDocReturnTag: - let tagWithExpression = tag; + const tagWithExpression = tag; if (tagWithExpression.typeExpression) { insideJsDocTagExpression = tagWithExpression.typeExpression.pos < position && position < tagWithExpression.typeExpression.end; } @@ -3045,7 +3044,7 @@ namespace ts { } start = new Date().getTime(); - let previousToken = findPrecedingToken(position, sourceFile); + const previousToken = findPrecedingToken(position, sourceFile); log("getCompletionData: Get previous token 1: " + (new Date().getTime() - start)); // The decision to provide completion depends on the contextToken, which is determined through the previousToken. @@ -3055,7 +3054,7 @@ namespace ts { // Check if the caret is at the end of an identifier; this is a partial identifier that we want to complete: e.g. a.toS| // Skip this partial identifier and adjust the contextToken to the token that precedes it. if (contextToken && position <= contextToken.end && isWord(contextToken.kind)) { - let start = new Date().getTime(); + const start = new Date().getTime(); contextToken = findPrecedingToken(contextToken.getFullStart(), sourceFile); log("getCompletionData: Get previous token 2: " + (new Date().getTime() - start)); } @@ -3076,7 +3075,7 @@ namespace ts { return undefined; } - let { parent, kind } = contextToken; + const { parent, kind } = contextToken; if (kind === SyntaxKind.DotToken) { if (parent.kind === SyntaxKind.PropertyAccessExpression) { node = (contextToken.parent).expression; @@ -3103,7 +3102,7 @@ namespace ts { } } - let semanticStart = new Date().getTime(); + const semanticStart = new Date().getTime(); let isMemberCompletion: boolean; let isNewIdentifierLocation: boolean; let symbols: Symbol[] = []; @@ -3112,7 +3111,7 @@ namespace ts { getTypeScriptMemberSymbols(); } else if (isRightOfOpenTag) { - let tagSymbols = typeChecker.getJsxIntrinsicTagNames(); + const tagSymbols = typeChecker.getJsxIntrinsicTagNames(); if (tryGetGlobalSymbols()) { symbols = tagSymbols.concat(symbols.filter(s => !!(s.flags & SymbolFlags.Value))); } @@ -3123,7 +3122,7 @@ namespace ts { isNewIdentifierLocation = false; } else if (isStartingCloseTag) { - let tagName = (contextToken.parent.parent).openingElement.tagName; + const tagName = (contextToken.parent.parent).openingElement.tagName; symbols = [typeChecker.getSymbolAtLocation(tagName)]; isMemberCompletion = true; @@ -3157,7 +3156,7 @@ namespace ts { if (symbol && symbol.flags & SymbolFlags.HasExports) { // Extract module or enum members - let exportedSymbols = typeChecker.getExportsOfModule(symbol); + const exportedSymbols = typeChecker.getExportsOfModule(symbol); forEach(exportedSymbols, symbol => { if (typeChecker.isValidPropertyAccess((node.parent), symbol.name)) { symbols.push(symbol); @@ -3166,14 +3165,14 @@ namespace ts { } } - let type = typeChecker.getTypeAtLocation(node); + const type = typeChecker.getTypeAtLocation(node); addTypeProperties(type); } function addTypeProperties(type: Type) { if (type) { // Filter private properties - for (let symbol of type.getApparentProperties()) { + for (const symbol of type.getApparentProperties()) { if (typeChecker.isValidPropertyAccess((node.parent), symbol.name)) { symbols.push(symbol); } @@ -3185,8 +3184,8 @@ namespace ts { // each individual type has. This is because we're going to add all identifiers // anyways. So we might as well elevate the members that were at least part // of the individual types to a higher status since we know what they are. - let unionType = type; - for (let elementType of unionType.types) { + const unionType = type; + for (const elementType of unionType.types) { addTypeProperties(elementType); } } @@ -3256,14 +3255,14 @@ namespace ts { // - 'contextToken' was adjusted to the token prior to 'previousToken' // because we were at the end of an identifier. // - 'previousToken' is defined. - let adjustedPosition = previousToken !== contextToken ? + const adjustedPosition = previousToken !== contextToken ? previousToken.getStart() : position; - let scopeNode = getScopeNode(contextToken, adjustedPosition, sourceFile) || sourceFile; + const scopeNode = getScopeNode(contextToken, adjustedPosition, sourceFile) || sourceFile; /// TODO filter meaning based on the current context - let symbolMeanings = SymbolFlags.Type | SymbolFlags.Value | SymbolFlags.Namespace | SymbolFlags.Alias; + const symbolMeanings = SymbolFlags.Type | SymbolFlags.Value | SymbolFlags.Namespace | SymbolFlags.Alias; symbols = typeChecker.getSymbolsInScope(scopeNode, symbolMeanings); return true; @@ -3282,8 +3281,8 @@ namespace ts { } function isCompletionListBlocker(contextToken: Node): boolean { - let start = new Date().getTime(); - let result = isInStringOrRegularExpressionOrTemplateLiteral(contextToken) || + const start = new Date().getTime(); + const result = isInStringOrRegularExpressionOrTemplateLiteral(contextToken) || isSolelyIdentifierDefinitionLocation(contextToken) || isDotOfNumericLiteral(contextToken) || isInJsxText(contextToken); @@ -3310,27 +3309,27 @@ namespace ts { function isNewIdentifierDefinitionLocation(previousToken: Node): boolean { if (previousToken) { - let containingNodeKind = previousToken.parent.kind; + const containingNodeKind = previousToken.parent.kind; switch (previousToken.kind) { case SyntaxKind.CommaToken: return containingNodeKind === SyntaxKind.CallExpression // func( a, | || containingNodeKind === SyntaxKind.Constructor // constructor( a, | /* public, protected, private keywords are allowed here, so show completion */ || containingNodeKind === SyntaxKind.NewExpression // new C(a, | || containingNodeKind === SyntaxKind.ArrayLiteralExpression // [a, | - || containingNodeKind === SyntaxKind.BinaryExpression // let x = (a, | + || containingNodeKind === SyntaxKind.BinaryExpression // const x = (a, | || containingNodeKind === SyntaxKind.FunctionType; // var x: (s: string, list| case SyntaxKind.OpenParenToken: return containingNodeKind === SyntaxKind.CallExpression // func( | || containingNodeKind === SyntaxKind.Constructor // constructor( | || containingNodeKind === SyntaxKind.NewExpression // new C(a| - || containingNodeKind === SyntaxKind.ParenthesizedExpression // let x = (a| + || containingNodeKind === SyntaxKind.ParenthesizedExpression // const x = (a| || containingNodeKind === SyntaxKind.ParenthesizedType; // function F(pred: (a| /* this can become an arrow function, where 'a' is the argument */ case SyntaxKind.OpenBracketToken: return containingNodeKind === SyntaxKind.ArrayLiteralExpression // [ | || containingNodeKind === SyntaxKind.IndexSignature // [ | : string ] - || containingNodeKind === SyntaxKind.ComputedPropertyName // [ | /* this can become an index signature */ + || containingNodeKind === SyntaxKind.ComputedPropertyName; // [ | /* this can become an index signature */ case SyntaxKind.ModuleKeyword: // module | case SyntaxKind.NamespaceKeyword: // namespace | @@ -3343,7 +3342,7 @@ namespace ts { return containingNodeKind === SyntaxKind.ClassDeclaration; // class A{ | case SyntaxKind.EqualsToken: - return containingNodeKind === SyntaxKind.VariableDeclaration // let x = a| + return containingNodeKind === SyntaxKind.VariableDeclaration // const x = a| || containingNodeKind === SyntaxKind.BinaryExpression; // x = a| case SyntaxKind.TemplateHead: @@ -3375,8 +3374,8 @@ namespace ts { || contextToken.kind === SyntaxKind.StringLiteralType || contextToken.kind === SyntaxKind.RegularExpressionLiteral || isTemplateLiteralKind(contextToken.kind)) { - let start = contextToken.getStart(); - let end = contextToken.getEnd(); + const start = contextToken.getStart(); + const end = contextToken.getEnd(); // To be "in" one of these literals, the position has to be: // 1. entirely within the token text. @@ -3420,7 +3419,7 @@ namespace ts { // We are *only* completing on properties from the type being destructured. isNewIdentifierLocation = false; - let rootDeclaration = getRootDeclaration(objectLikeContainer.parent); + const rootDeclaration = getRootDeclaration(objectLikeContainer.parent); if (isVariableLike(rootDeclaration)) { // We don't want to complete using the type acquired by the shape // of the binding pattern; we are only interested in types acquired @@ -3431,7 +3430,7 @@ namespace ts { } } else { - Debug.fail("Root declaration is not variable-like.") + Debug.fail("Root declaration is not variable-like."); } } else { @@ -3442,7 +3441,7 @@ namespace ts { return false; } - let typeMembers = typeChecker.getPropertiesOfType(typeForObject); + const typeMembers = typeChecker.getPropertiesOfType(typeForObject); if (typeMembers && typeMembers.length > 0) { // Add filtered items to the completion list symbols = filterObjectMembersList(typeMembers, existingMembers); @@ -3466,11 +3465,11 @@ namespace ts { * @returns true if 'symbols' was successfully populated; false otherwise. */ function tryGetImportOrExportClauseCompletionSymbols(namedImportsOrExports: NamedImportsOrExports): boolean { - let declarationKind = namedImportsOrExports.kind === SyntaxKind.NamedImports ? + const declarationKind = namedImportsOrExports.kind === SyntaxKind.NamedImports ? SyntaxKind.ImportDeclaration : SyntaxKind.ExportDeclaration; - let importOrExportDeclaration = getAncestor(namedImportsOrExports, declarationKind); - let moduleSpecifier = importOrExportDeclaration.moduleSpecifier; + const importOrExportDeclaration = getAncestor(namedImportsOrExports, declarationKind); + const moduleSpecifier = importOrExportDeclaration.moduleSpecifier; if (!moduleSpecifier) { return false; @@ -3480,7 +3479,7 @@ namespace ts { isNewIdentifierLocation = false; let exports: Symbol[]; - let moduleSpecifierSymbol = typeChecker.getSymbolAtLocation(importOrExportDeclaration.moduleSpecifier); + const moduleSpecifierSymbol = typeChecker.getSymbolAtLocation(importOrExportDeclaration.moduleSpecifier); if (moduleSpecifierSymbol) { exports = typeChecker.getExportsOfModule(moduleSpecifierSymbol); } @@ -3497,9 +3496,9 @@ namespace ts { function tryGetObjectLikeCompletionContainer(contextToken: Node): ObjectLiteralExpression | BindingPattern { if (contextToken) { switch (contextToken.kind) { - case SyntaxKind.OpenBraceToken: // let x = { | - case SyntaxKind.CommaToken: // let x = { a: 0, | - let parent = contextToken.parent; + case SyntaxKind.OpenBraceToken: // const x = { | + case SyntaxKind.CommaToken: // const x = { a: 0, | + const parent = contextToken.parent; if (parent && (parent.kind === SyntaxKind.ObjectLiteralExpression || parent.kind === SyntaxKind.ObjectBindingPattern)) { return parent; } @@ -3532,8 +3531,8 @@ namespace ts { function tryGetContainingJsxElement(contextToken: Node): JsxOpeningLikeElement { if (contextToken) { - let parent = contextToken.parent; - switch(contextToken.kind) { + const parent = contextToken.parent; + switch (contextToken.kind) { case SyntaxKind.LessThanSlashToken: case SyntaxKind.SlashToken: case SyntaxKind.Identifier: @@ -3596,7 +3595,7 @@ namespace ts { * @returns true if we are certain that the currently edited location must define a new location; false otherwise. */ function isSolelyIdentifierDefinitionLocation(contextToken: Node): boolean { - let containingNodeKind = contextToken.parent.kind; + const containingNodeKind = contextToken.parent.kind; switch (contextToken.kind) { case SyntaxKind.CommaToken: return containingNodeKind === SyntaxKind.VariableDeclaration || @@ -3626,13 +3625,13 @@ namespace ts { case SyntaxKind.OpenBraceToken: return containingNodeKind === SyntaxKind.EnumDeclaration || // enum a { | containingNodeKind === SyntaxKind.InterfaceDeclaration || // interface a { | - containingNodeKind === SyntaxKind.TypeLiteral; // let x : { | + containingNodeKind === SyntaxKind.TypeLiteral; // const x : { | case SyntaxKind.SemicolonToken: return containingNodeKind === SyntaxKind.PropertySignature && contextToken.parent && contextToken.parent.parent && (contextToken.parent.parent.kind === SyntaxKind.InterfaceDeclaration || // interface a { f; | - contextToken.parent.parent.kind === SyntaxKind.TypeLiteral); // let x : { a; | + contextToken.parent.parent.kind === SyntaxKind.TypeLiteral); // const x : { a; | case SyntaxKind.LessThanToken: return containingNodeKind === SyntaxKind.ClassDeclaration || // class A< | @@ -3699,7 +3698,7 @@ namespace ts { function isDotOfNumericLiteral(contextToken: Node): boolean { if (contextToken.kind === SyntaxKind.NumericLiteral) { - let text = contextToken.getFullText(); + const text = contextToken.getFullText(); return text.charAt(text.length - 1) === "."; } @@ -3716,15 +3715,15 @@ namespace ts { * do not occur at the current position and have not otherwise been typed. */ function filterNamedImportOrExportCompletionItems(exportsOfModule: Symbol[], namedImportsOrExports: ImportOrExportSpecifier[]): Symbol[] { - let exisingImportsOrExports: Map = {}; + const exisingImportsOrExports: Map = {}; - for (let element of namedImportsOrExports) { + for (const element of namedImportsOrExports) { // If this is the current item we are editing right now, do not filter it out if (element.getStart() <= position && position <= element.getEnd()) { continue; } - let name = element.propertyName || element.name; + const name = element.propertyName || element.name; exisingImportsOrExports[name.text] = true; } @@ -3746,8 +3745,8 @@ namespace ts { return contextualMemberSymbols; } - let existingMemberNames: Map = {}; - for (let m of existingMembers) { + const existingMemberNames: Map = {}; + for (const m of existingMembers) { // Ignore omitted expressions for missing members if (m.kind !== SyntaxKind.PropertyAssignment && m.kind !== SyntaxKind.ShorthandPropertyAssignment && @@ -3766,7 +3765,7 @@ namespace ts { if (m.kind === SyntaxKind.BindingElement && (m).propertyName) { // include only identifiers in completion list if ((m).propertyName.kind === SyntaxKind.Identifier) { - existingName = ((m).propertyName).text + existingName = ((m).propertyName).text; } } else { @@ -3789,8 +3788,8 @@ namespace ts { * do not occur at the current position and have not otherwise been typed. */ function filterJsxAttributes(symbols: Symbol[], attributes: NodeArray): Symbol[] { - let seenNames: Map = {}; - for (let attr of attributes) { + const seenNames: Map = {}; + for (const attr of attributes) { // If this is the current item we are editing right now, do not filter it out if (attr.getStart() <= position && position <= attr.getEnd()) { continue; @@ -3809,21 +3808,21 @@ namespace ts { function getCompletionsAtPosition(fileName: string, position: number): CompletionInfo { synchronizeHostData(); - let completionData = getCompletionData(fileName, position); + const completionData = getCompletionData(fileName, position); if (!completionData) { return undefined; } - let { symbols, isMemberCompletion, isNewIdentifierLocation, location, isRightOfDot, isJsDocTagName } = completionData; + const { symbols, isMemberCompletion, isNewIdentifierLocation, location, isRightOfDot, isJsDocTagName } = completionData; if (isJsDocTagName) { // If the current position is a jsDoc tag name, only tag names should be provided for completion return { isMemberCompletion: false, isNewIdentifierLocation: false, entries: getAllJsDocCompletionEntries() }; } - let sourceFile = getValidSourceFile(fileName); + const sourceFile = getValidSourceFile(fileName); - let entries: CompletionEntry[] = []; + const entries: CompletionEntry[] = []; if (isRightOfDot && isSourceFileJavaScript(sourceFile)) { const uniqueNames = getCompletionEntriesFromSymbols(symbols, entries); @@ -3845,16 +3844,16 @@ namespace ts { return { isMemberCompletion, isNewIdentifierLocation, entries }; function getJavaScriptCompletionEntries(sourceFile: SourceFile, uniqueNames: Map): CompletionEntry[] { - let entries: CompletionEntry[] = []; - let target = program.getCompilerOptions().target; + const entries: CompletionEntry[] = []; + const target = program.getCompilerOptions().target; - let nameTable = getNameTable(sourceFile); - for (let name in nameTable) { + const nameTable = getNameTable(sourceFile); + for (const name in nameTable) { if (!uniqueNames[name]) { uniqueNames[name] = name; - let displayName = getCompletionEntryDisplayName(name, target, /*performCharacterChecks:*/ true); + const displayName = getCompletionEntryDisplayName(name, target, /*performCharacterChecks*/ true); if (displayName) { - let entry = { + const entry = { name: displayName, kind: ScriptElementKind.warning, kindModifiers: "", @@ -3875,7 +3874,7 @@ namespace ts { kind: ScriptElementKind.keyword, kindModifiers: "", sortText: "0", - } + }; })); } @@ -3883,7 +3882,7 @@ namespace ts { // Try to get a valid display name for this symbol, if we could not find one, then ignore it. // We would like to only show things that can be added after a dot, so for instance numeric properties can // not be accessed with a dot (a.1 <- invalid) - let displayName = getCompletionEntryDisplayNameForSymbol(symbol, program.getCompilerOptions().target, /*performCharacterChecks:*/ true, location); + const displayName = getCompletionEntryDisplayNameForSymbol(symbol, program.getCompilerOptions().target, /*performCharacterChecks*/ true, location); if (!displayName) { return undefined; } @@ -3905,13 +3904,13 @@ namespace ts { } function getCompletionEntriesFromSymbols(symbols: Symbol[], entries: CompletionEntry[]): Map { - let start = new Date().getTime(); - let uniqueNames: Map = {}; + const start = new Date().getTime(); + const uniqueNames: Map = {}; if (symbols) { - for (let symbol of symbols) { - let entry = createCompletionEntry(symbol, location); + for (const symbol of symbols) { + const entry = createCompletionEntry(symbol, location); if (entry) { - let id = escapeIdentifier(entry.name); + const id = escapeIdentifier(entry.name); if (!lookUp(uniqueNames, id)) { entries.push(entry); uniqueNames[id] = id; @@ -3929,19 +3928,19 @@ namespace ts { synchronizeHostData(); // Compute all the completion symbols again. - let completionData = getCompletionData(fileName, position); + const completionData = getCompletionData(fileName, position); if (completionData) { - let { symbols, location } = completionData; + const { symbols, location } = completionData; // Find the symbol with the matching entry name. - let target = program.getCompilerOptions().target; + const target = program.getCompilerOptions().target; // We don't need to perform character checks here because we're only comparing the // name against 'entryName' (which is known to be good), not building a new // completion entry. - let symbol = forEach(symbols, s => getCompletionEntryDisplayNameForSymbol(s, target, /*performCharacterChecks:*/ false, location) === entryName ? s : undefined); + const symbol = forEach(symbols, s => getCompletionEntryDisplayNameForSymbol(s, target, /*performCharacterChecks*/ false, location) === entryName ? s : undefined); if (symbol) { - let { displayParts, documentation, symbolKind } = getSymbolDisplayPartsDocumentationAndSymbolKind(symbol, getValidSourceFile(fileName), location, location, SemanticMeaning.All); + const { displayParts, documentation, symbolKind } = getSymbolDisplayPartsDocumentationAndSymbolKind(symbol, getValidSourceFile(fileName), location, location, SemanticMeaning.All); return { name: entryName, kindModifiers: getSymbolModifiers(symbol), @@ -3953,7 +3952,7 @@ namespace ts { } // Didn't find a symbol with this name. See if we can find a keyword instead. - let keywordCompletion = forEach(keywordCompletions, c => c.name === entryName); + const keywordCompletion = forEach(keywordCompletions, c => c.name === entryName); if (keywordCompletion) { return { name: entryName, @@ -3969,7 +3968,7 @@ namespace ts { // TODO(drosen): use contextual SemanticMeaning. function getSymbolKind(symbol: Symbol, location: Node): string { - let flags = symbol.getFlags(); + const flags = symbol.getFlags(); if (flags & SymbolFlags.Class) return getDeclarationOfKind(symbol, SyntaxKind.ClassExpression) ? ScriptElementKind.localClassElement : ScriptElementKind.classElement; @@ -3978,7 +3977,7 @@ namespace ts { if (flags & SymbolFlags.Interface) return ScriptElementKind.interfaceElement; if (flags & SymbolFlags.TypeParameter) return ScriptElementKind.typeParameterElement; - let result = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(symbol, flags, location); + const result = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(symbol, flags, location); if (result === ScriptElementKind.unknown) { if (flags & SymbolFlags.TypeParameter) return ScriptElementKind.typeParameterElement; if (flags & SymbolFlags.EnumMember) return ScriptElementKind.variableElement; @@ -3990,7 +3989,7 @@ namespace ts { } function getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(symbol: Symbol, flags: SymbolFlags, location: Node) { - let typeChecker = program.getTypeChecker(); + const typeChecker = program.getTypeChecker(); if (typeChecker.isUndefinedSymbol(symbol)) { return ScriptElementKind.variableElement; @@ -4019,8 +4018,8 @@ namespace ts { if (flags & SymbolFlags.Property) { if (flags & SymbolFlags.SyntheticProperty) { // If union property is result of union of non method (property/accessors/variables), it is labeled as property - let unionPropertyKind = forEach(typeChecker.getRootSymbols(symbol), rootSymbol => { - let rootSymbolFlags = rootSymbol.getFlags(); + const unionPropertyKind = forEach(typeChecker.getRootSymbols(symbol), rootSymbol => { + const rootSymbolFlags = rootSymbol.getFlags(); if (rootSymbolFlags & (SymbolFlags.PropertyOrAccessor | SymbolFlags.Variable)) { return ScriptElementKind.memberVariableElement; } @@ -4028,8 +4027,8 @@ namespace ts { }); if (!unionPropertyKind) { // If this was union of all methods, - //make sure it has call signatures before we can label it as method - let typeOfUnionProperty = typeChecker.getTypeOfSymbolAtLocation(symbol, location); + // make sure it has call signatures before we can label it as method + const typeOfUnionProperty = typeChecker.getTypeOfSymbolAtLocation(symbol, location); if (typeOfUnionProperty.getCallSignatures().length) { return ScriptElementKind.memberFunctionElement; } @@ -4053,11 +4052,11 @@ namespace ts { function getSymbolDisplayPartsDocumentationAndSymbolKind(symbol: Symbol, sourceFile: SourceFile, enclosingDeclaration: Node, location: Node, semanticMeaning = getMeaningFromLocation(location)) { - let typeChecker = program.getTypeChecker(); + const typeChecker = program.getTypeChecker(); - let displayParts: SymbolDisplayPart[] = []; + const displayParts: SymbolDisplayPart[] = []; let documentation: SymbolDisplayPart[]; - let symbolFlags = symbol.flags; + const symbolFlags = symbol.flags; let symbolKind = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(symbol, symbolFlags, location); let hasAddedSymbolInfo: boolean; let type: Type; @@ -4073,7 +4072,7 @@ namespace ts { type = typeChecker.getTypeOfSymbolAtLocation(symbol, location); if (type) { if (location.parent && location.parent.kind === SyntaxKind.PropertyAccessExpression) { - let right = (location.parent).name; + const right = (location.parent).name; // Either the location is on the right of a property access, or on the left and the right is missing if (right === location || (right && right.getFullWidth() === 0)) { location = location.parent; @@ -4090,15 +4089,15 @@ namespace ts { } if (callExpression) { - let candidateSignatures: Signature[] = []; + const candidateSignatures: Signature[] = []; signature = typeChecker.getResolvedSignature(callExpression, candidateSignatures); if (!signature && candidateSignatures.length) { // Use the first candidate: signature = candidateSignatures[0]; } - let useConstructSignatures = callExpression.kind === SyntaxKind.NewExpression || callExpression.expression.kind === SyntaxKind.SuperKeyword; - let allSignatures = useConstructSignatures ? type.getConstructSignatures() : type.getCallSignatures(); + const useConstructSignatures = callExpression.kind === SyntaxKind.NewExpression || callExpression.expression.kind === SyntaxKind.SuperKeyword; + const allSignatures = useConstructSignatures ? type.getConstructSignatures() : type.getCallSignatures(); if (!contains(allSignatures, signature.target) && !contains(allSignatures, signature)) { // Get the first signature if there is one -- allSignatures may contain @@ -4156,8 +4155,8 @@ namespace ts { else if ((isNameOfFunctionDeclaration(location) && !(symbol.flags & SymbolFlags.Accessor)) || // name of function declaration (location.kind === SyntaxKind.ConstructorKeyword && location.parent.kind === SyntaxKind.Constructor)) { // At constructor keyword of constructor declaration // get the signature from the declaration and write it - let functionDeclaration = location.parent; - let allSignatures = functionDeclaration.kind === SyntaxKind.Constructor ? type.getConstructSignatures() : type.getCallSignatures(); + const functionDeclaration = location.parent; + const allSignatures = functionDeclaration.kind === SyntaxKind.Constructor ? type.getConstructSignatures() : type.getCallSignatures(); if (!typeChecker.isImplementationOfOverload(functionDeclaration)) { signature = typeChecker.getSignatureFromDeclaration(functionDeclaration); } @@ -4226,8 +4225,8 @@ namespace ts { } if (symbolFlags & SymbolFlags.Module) { addNewLineIfDisplayPartsExist(); - let declaration = getDeclarationOfKind(symbol, SyntaxKind.ModuleDeclaration); - let isNamespace = declaration && declaration.name && declaration.name.kind === SyntaxKind.Identifier; + const declaration = getDeclarationOfKind(symbol, SyntaxKind.ModuleDeclaration); + const isNamespace = declaration && declaration.name && declaration.name.kind === SyntaxKind.Identifier; displayParts.push(keywordPart(isNamespace ? SyntaxKind.NamespaceKeyword : SyntaxKind.ModuleKeyword)); displayParts.push(spacePart()); addFullSymbolName(symbol); @@ -4279,9 +4278,9 @@ namespace ts { } if (symbolFlags & SymbolFlags.EnumMember) { addPrefixForAnyFunctionOrVar(symbol, "enum member"); - let declaration = symbol.declarations[0]; + const declaration = symbol.declarations[0]; if (declaration.kind === SyntaxKind.EnumMember) { - let constantValue = typeChecker.getConstantValue(declaration); + const constantValue = typeChecker.getConstantValue(declaration); if (constantValue !== undefined) { displayParts.push(spacePart()); displayParts.push(operatorPart(SyntaxKind.EqualsToken)); @@ -4297,7 +4296,7 @@ namespace ts { addFullSymbolName(symbol); ts.forEach(symbol.declarations, declaration => { if (declaration.kind === SyntaxKind.ImportEqualsDeclaration) { - let importEqualsDeclaration = declaration; + const importEqualsDeclaration = declaration; if (isExternalModuleImportEqualsDeclaration(importEqualsDeclaration)) { displayParts.push(spacePart()); displayParts.push(operatorPart(SyntaxKind.EqualsToken)); @@ -4308,7 +4307,7 @@ namespace ts { displayParts.push(punctuationPart(SyntaxKind.CloseParenToken)); } else { - let internalAliasSymbol = typeChecker.getSymbolAtLocation(importEqualsDeclaration.moduleReference); + const internalAliasSymbol = typeChecker.getSymbolAtLocation(importEqualsDeclaration.moduleReference); if (internalAliasSymbol) { displayParts.push(spacePart()); displayParts.push(operatorPart(SyntaxKind.EqualsToken)); @@ -4332,7 +4331,7 @@ namespace ts { displayParts.push(spacePart()); // If the type is type parameter, format it specially if (type.symbol && type.symbol.flags & SymbolFlags.TypeParameter) { - let typeParameterParts = mapToDisplayParts(writer => { + const typeParameterParts = mapToDisplayParts(writer => { typeChecker.getSymbolDisplayBuilder().buildTypeParameterDisplay(type, writer, enclosingDeclaration); }); addRange(displayParts, typeParameterParts); @@ -4347,7 +4346,7 @@ namespace ts { symbolFlags & SymbolFlags.Signature || symbolFlags & SymbolFlags.Accessor || symbolKind === ScriptElementKind.memberFunctionElement) { - let allSignatures = type.getCallSignatures(); + const allSignatures = type.getCallSignatures(); addSignatureDisplayParts(allSignatures[0], allSignatures); } } @@ -4370,7 +4369,7 @@ namespace ts { } function addFullSymbolName(symbol: Symbol, enclosingDeclaration?: Node) { - let fullSymbolDisplayParts = symbolToDisplayParts(typeChecker, symbol, enclosingDeclaration || sourceFile, /*meaning*/ undefined, + const fullSymbolDisplayParts = symbolToDisplayParts(typeChecker, symbol, enclosingDeclaration || sourceFile, /*meaning*/ undefined, SymbolFormatFlags.WriteTypeParametersOrArguments | SymbolFormatFlags.UseOnlyExternalAliasing); addRange(displayParts, fullSymbolDisplayParts); } @@ -4416,7 +4415,7 @@ namespace ts { } function writeTypeParametersOfSymbol(symbol: Symbol, enclosingDeclaration: Node) { - let typeParameterParts = mapToDisplayParts(writer => { + const typeParameterParts = mapToDisplayParts(writer => { typeChecker.getSymbolDisplayBuilder().buildTypeParameterDisplayFromSymbol(symbol, writer, enclosingDeclaration); }); addRange(displayParts, typeParameterParts); @@ -4426,8 +4425,8 @@ namespace ts { function getQuickInfoAtPosition(fileName: string, position: number): QuickInfo { synchronizeHostData(); - let sourceFile = getValidSourceFile(fileName); - let node = getTouchingPropertyName(sourceFile, position); + const sourceFile = getValidSourceFile(fileName); + const node = getTouchingPropertyName(sourceFile, position); if (!node) { return undefined; } @@ -4436,8 +4435,8 @@ namespace ts { return undefined; } - let typeChecker = program.getTypeChecker(); - let symbol = typeChecker.getSymbolAtLocation(node); + const typeChecker = program.getTypeChecker(); + const symbol = typeChecker.getSymbolAtLocation(node); if (!symbol) { // Try getting just type at this position and show @@ -4449,7 +4448,7 @@ namespace ts { case SyntaxKind.ThisType: case SyntaxKind.SuperKeyword: // For the identifiers/this/super etc get the type at position - let type = typeChecker.getTypeAtLocation(node); + const type = typeChecker.getTypeAtLocation(node); if (type) { return { kind: ScriptElementKind.unknown, @@ -4464,7 +4463,7 @@ namespace ts { return undefined; } - let displayPartsDocumentationsAndKind = getSymbolDisplayPartsDocumentationAndSymbolKind(symbol, sourceFile, getContainerNode(node), node); + const displayPartsDocumentationsAndKind = getSymbolDisplayPartsDocumentationAndSymbolKind(symbol, sourceFile, getContainerNode(node), node); return { kind: displayPartsDocumentationsAndKind.symbolKind, kindModifiers: getSymbolModifiers(symbol), @@ -4486,13 +4485,13 @@ namespace ts { } function getDefinitionFromSymbol(symbol: Symbol, node: Node): DefinitionInfo[] { - let typeChecker = program.getTypeChecker(); - let result: DefinitionInfo[] = []; - let declarations = symbol.getDeclarations(); - let symbolName = typeChecker.symbolToString(symbol); // Do not get scoped name, just the name of the symbol - let symbolKind = getSymbolKind(symbol, node); - let containerSymbol = symbol.parent; - let containerName = containerSymbol ? typeChecker.symbolToString(containerSymbol, node) : ""; + const typeChecker = program.getTypeChecker(); + const result: DefinitionInfo[] = []; + const declarations = symbol.getDeclarations(); + const symbolName = typeChecker.symbolToString(symbol); // Do not get scoped name, just the name of the symbol + const symbolKind = getSymbolKind(symbol, node); + const containerSymbol = symbol.parent; + const containerName = containerSymbol ? typeChecker.symbolToString(containerSymbol, node) : ""; if (!tryAddConstructSignature(symbol, node, symbolKind, symbolName, containerName, result) && !tryAddCallSignature(symbol, node, symbolKind, symbolName, containerName, result)) { @@ -4510,7 +4509,7 @@ namespace ts { if (isNewExpressionTarget(location) || location.kind === SyntaxKind.ConstructorKeyword) { if (symbol.flags & SymbolFlags.Class) { // Find the first class-like declaration and try to get the construct signature. - for (let declaration of symbol.getDeclarations()) { + for (const declaration of symbol.getDeclarations()) { if (isClassLike(declaration)) { return tryAddSignature(declaration.members, /*selectConstructors*/ true, @@ -4535,7 +4534,7 @@ namespace ts { } function tryAddSignature(signatureDeclarations: Declaration[], selectConstructors: boolean, symbolKind: string, symbolName: string, containerName: string, result: DefinitionInfo[]) { - let declarations: Declaration[] = []; + const declarations: Declaration[] = []; let definition: Declaration; forEach(signatureDeclarations, d => { @@ -4563,24 +4562,24 @@ namespace ts { function getDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[] { synchronizeHostData(); - let sourceFile = getValidSourceFile(fileName); + const sourceFile = getValidSourceFile(fileName); - let node = getTouchingPropertyName(sourceFile, position); + const node = getTouchingPropertyName(sourceFile, position); if (!node) { return undefined; } // Labels if (isJumpStatementTarget(node)) { - let labelName = (node).text; - let label = getTargetLabel((node.parent), (node).text); + const labelName = (node).text; + const label = getTargetLabel((node.parent), (node).text); return label ? [createDefinitionInfo(label, ScriptElementKind.label, labelName, /*containerName*/ undefined)] : undefined; } /// Triple slash reference comments - let comment = forEach(sourceFile.referencedFiles, r => (r.pos <= position && position < r.end) ? r : undefined); + const comment = forEach(sourceFile.referencedFiles, r => (r.pos <= position && position < r.end) ? r : undefined); if (comment) { - let referenceFile = tryResolveScriptReference(program, sourceFile, comment); + const referenceFile = tryResolveScriptReference(program, sourceFile, comment); if (referenceFile) { return [{ fileName: referenceFile.fileName, @@ -4594,7 +4593,7 @@ namespace ts { return undefined; } - let typeChecker = program.getTypeChecker(); + const typeChecker = program.getTypeChecker(); let symbol = typeChecker.getSymbolAtLocation(node); // Could not find a symbol e.g. node is string or number keyword, @@ -4608,7 +4607,7 @@ namespace ts { // import {A, B} from "mod"; // to jump to the implementation directly. if (symbol.flags & SymbolFlags.Alias) { - let declaration = symbol.declarations[0]; + const declaration = symbol.declarations[0]; if (node.kind === SyntaxKind.Identifier && node.parent === declaration) { symbol = typeChecker.getAliasedSymbol(symbol); } @@ -4620,15 +4619,15 @@ namespace ts { // is performed at the location of property access, we would like to go to definition of the property in the short-hand // assignment. This case and others are handled by the following code. if (node.parent.kind === SyntaxKind.ShorthandPropertyAssignment) { - let shorthandSymbol = typeChecker.getShorthandAssignmentValueSymbol(symbol.valueDeclaration); + const shorthandSymbol = typeChecker.getShorthandAssignmentValueSymbol(symbol.valueDeclaration); if (!shorthandSymbol) { return []; } - let shorthandDeclarations = shorthandSymbol.getDeclarations(); - let shorthandSymbolKind = getSymbolKind(shorthandSymbol, node); - let shorthandSymbolName = typeChecker.symbolToString(shorthandSymbol); - let shorthandContainerName = typeChecker.symbolToString(symbol.parent, node); + const shorthandDeclarations = shorthandSymbol.getDeclarations(); + const shorthandSymbolKind = getSymbolKind(shorthandSymbol, node); + const shorthandSymbolName = typeChecker.symbolToString(shorthandSymbol); + const shorthandContainerName = typeChecker.symbolToString(symbol.parent, node); return map(shorthandDeclarations, declaration => createDefinitionInfo(declaration, shorthandSymbolKind, shorthandSymbolName, shorthandContainerName)); } @@ -4640,27 +4639,27 @@ namespace ts { function getTypeDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[] { synchronizeHostData(); - let sourceFile = getValidSourceFile(fileName); + const sourceFile = getValidSourceFile(fileName); - let node = getTouchingPropertyName(sourceFile, position); + const node = getTouchingPropertyName(sourceFile, position); if (!node) { return undefined; } - let typeChecker = program.getTypeChecker(); + const typeChecker = program.getTypeChecker(); - let symbol = typeChecker.getSymbolAtLocation(node); + const symbol = typeChecker.getSymbolAtLocation(node); if (!symbol) { return undefined; } - let type = typeChecker.getTypeOfSymbolAtLocation(symbol, node); + const type = typeChecker.getTypeOfSymbolAtLocation(symbol, node); if (!type) { return undefined; } if (type.flags & TypeFlags.Union) { - let result: DefinitionInfo[] = []; + const result: DefinitionInfo[] = []; forEach((type).types, t => { if (t.symbol) { addRange(/*to*/ result, /*from*/ getDefinitionFromSymbol(t.symbol, node)); @@ -4680,7 +4679,7 @@ namespace ts { let results = getOccurrencesAtPositionCore(fileName, position); if (results) { - let sourceFile = getCanonicalFileName(normalizeSlashes(fileName)); + const sourceFile = getCanonicalFileName(normalizeSlashes(fileName)); // Get occurrences only supports reporting occurrences for the file queried. So // filter down to that list. @@ -4694,10 +4693,10 @@ namespace ts { synchronizeHostData(); filesToSearch = map(filesToSearch, normalizeSlashes); - let sourceFilesToSearch = filter(program.getSourceFiles(), f => contains(filesToSearch, f.fileName)); - let sourceFile = getValidSourceFile(fileName); + const sourceFilesToSearch = filter(program.getSourceFiles(), f => contains(filesToSearch, f.fileName)); + const sourceFile = getValidSourceFile(fileName); - let node = getTouchingWord(sourceFile, position); + const node = getTouchingWord(sourceFile, position); if (!node) { return undefined; } @@ -4705,8 +4704,8 @@ namespace ts { return getSemanticDocumentHighlights(node) || getSyntacticDocumentHighlights(node); function getHighlightSpanForNode(node: Node): HighlightSpan { - let start = node.getStart(); - let end = node.getEnd(); + const start = node.getStart(); + const end = node.getEnd(); return { fileName: sourceFile.fileName, @@ -4723,7 +4722,7 @@ namespace ts { isLiteralNameOfPropertyDeclarationOrIndexAccess(node) || isNameOfExternalModuleImportOrDeclaration(node)) { - let referencedSymbols = getReferencedSymbolsForNode(node, sourceFilesToSearch, /*findInStrings:*/ false, /*findInComments:*/ false); + const referencedSymbols = getReferencedSymbolsForNode(node, sourceFilesToSearch, /*findInStrings*/ false, /*findInComments*/ false); return convertReferencedSymbols(referencedSymbols); } @@ -4734,11 +4733,11 @@ namespace ts { return undefined; } - let fileNameToDocumentHighlights: Map = {}; - let result: DocumentHighlights[] = []; - for (let referencedSymbol of referencedSymbols) { - for (let referenceEntry of referencedSymbol.references) { - let fileName = referenceEntry.fileName; + const fileNameToDocumentHighlights: Map = {}; + const result: DocumentHighlights[] = []; + for (const referencedSymbol of referencedSymbols) { + for (const referenceEntry of referencedSymbol.references) { + const fileName = referenceEntry.fileName; let documentHighlights = getProperty(fileNameToDocumentHighlights, fileName); if (!documentHighlights) { documentHighlights = { fileName, highlightSpans: [] }; @@ -4759,9 +4758,9 @@ namespace ts { } function getSyntacticDocumentHighlights(node: Node): DocumentHighlights[] { - let fileName = sourceFile.fileName; + const fileName = sourceFile.fileName; - let highlightSpans = getHighlightSpans(node); + const highlightSpans = getHighlightSpans(node); if (!highlightSpans || highlightSpans.length === 0) { return undefined; } @@ -4865,7 +4864,7 @@ namespace ts { * into function boundaries and try-blocks with catch-clauses. */ function aggregateOwnedThrowStatements(node: Node): ThrowStatement[] { - let statementAccumulator: ThrowStatement[] = [] + const statementAccumulator: ThrowStatement[] = []; aggregate(node); return statementAccumulator; @@ -4874,7 +4873,7 @@ namespace ts { statementAccumulator.push(node); } else if (node.kind === SyntaxKind.TryStatement) { - let tryStatement = node; + const tryStatement = node; if (tryStatement.catchClause) { aggregate(tryStatement.catchClause); @@ -4905,7 +4904,7 @@ namespace ts { let child: Node = throwStatement; while (child.parent) { - let parent = child.parent; + const parent = child.parent; if (isFunctionBlock(parent) || parent.kind === SyntaxKind.SourceFile) { return parent; @@ -4914,7 +4913,7 @@ namespace ts { // A throw-statement is only owned by a try-statement if the try-statement has // a catch clause, and if the throw-statement occurs within the try block. if (parent.kind === SyntaxKind.TryStatement) { - let tryStatement = parent; + const tryStatement = parent; if (tryStatement.tryBlock === child && tryStatement.catchClause) { return child; @@ -4928,7 +4927,7 @@ namespace ts { } function aggregateAllBreakAndContinueStatements(node: Node): BreakOrContinueStatement[] { - let statementAccumulator: BreakOrContinueStatement[] = [] + const statementAccumulator: BreakOrContinueStatement[] = []; aggregate(node); return statementAccumulator; @@ -4944,7 +4943,7 @@ namespace ts { } function ownsBreakOrContinueStatement(owner: Node, statement: BreakOrContinueStatement): boolean { - let actualOwner = getBreakOrContinueOwner(statement); + const actualOwner = getBreakOrContinueOwner(statement); return actualOwner && actualOwner === owner; } @@ -4979,7 +4978,7 @@ namespace ts { } function getModifierOccurrences(modifier: SyntaxKind, declaration: Node): HighlightSpan[] { - let container = declaration.parent; + const container = declaration.parent; // Make sure we only highlight the keyword when it makes sense to do so. if (isAccessibilityModifier(modifier)) { @@ -5009,8 +5008,8 @@ namespace ts { return undefined; } - let keywords: Node[] = []; - let modifierFlag: NodeFlags = getFlagFromModifier(modifier); + const keywords: Node[] = []; + const modifierFlag: NodeFlags = getFlagFromModifier(modifier); let nodes: Node[]; switch (container.kind) { @@ -5035,7 +5034,7 @@ namespace ts { // If we're an accessibility modifier, we're in an instance member and should search // the constructor's parameter list for instance members as well. if (modifierFlag & NodeFlags.AccessibilityModifier) { - let constructor = forEach((container).members, member => { + const constructor = forEach((container).members, member => { return member.kind === SyntaxKind.Constructor && member; }); @@ -5048,7 +5047,7 @@ namespace ts { } break; default: - Debug.fail("Invalid container kind.") + Debug.fail("Invalid container kind."); } forEach(nodes, node => { @@ -5091,7 +5090,7 @@ namespace ts { } function getGetAndSetOccurrences(accessorDeclaration: AccessorDeclaration): HighlightSpan[] { - let keywords: Node[] = []; + const keywords: Node[] = []; tryPushAccessorKeyword(accessorDeclaration.symbol, SyntaxKind.GetAccessor); tryPushAccessorKeyword(accessorDeclaration.symbol, SyntaxKind.SetAccessor); @@ -5099,7 +5098,7 @@ namespace ts { return map(keywords, getHighlightSpanForNode); function tryPushAccessorKeyword(accessorSymbol: Symbol, accessorKind: SyntaxKind): void { - let accessor = getDeclarationOfKind(accessorSymbol, accessorKind); + const accessor = getDeclarationOfKind(accessorSymbol, accessorKind); if (accessor) { forEach(accessor.getChildren(), child => pushKeywordIf(keywords, child, SyntaxKind.GetKeyword, SyntaxKind.SetKeyword)); @@ -5108,9 +5107,9 @@ namespace ts { } function getConstructorOccurrences(constructorDeclaration: ConstructorDeclaration): HighlightSpan[] { - let declarations = constructorDeclaration.symbol.getDeclarations() + const declarations = constructorDeclaration.symbol.getDeclarations(); - let keywords: Node[] = []; + const keywords: Node[] = []; forEach(declarations, declaration => { forEach(declaration.getChildren(), token => { @@ -5122,12 +5121,12 @@ namespace ts { } function getLoopBreakContinueOccurrences(loopNode: IterationStatement): HighlightSpan[] { - let keywords: Node[] = []; + const keywords: Node[] = []; if (pushKeywordIf(keywords, loopNode.getFirstToken(), SyntaxKind.ForKeyword, SyntaxKind.WhileKeyword, SyntaxKind.DoKeyword)) { // If we succeeded and got a do-while loop, then start looking for a 'while' keyword. if (loopNode.kind === SyntaxKind.DoStatement) { - let loopTokens = loopNode.getChildren(); + const loopTokens = loopNode.getChildren(); for (let i = loopTokens.length - 1; i >= 0; i--) { if (pushKeywordIf(keywords, loopTokens[i], SyntaxKind.WhileKeyword)) { @@ -5137,7 +5136,7 @@ namespace ts { } } - let breaksAndContinues = aggregateAllBreakAndContinueStatements(loopNode.statement); + const breaksAndContinues = aggregateAllBreakAndContinueStatements(loopNode.statement); forEach(breaksAndContinues, statement => { if (ownsBreakOrContinueStatement(loopNode, statement)) { @@ -5149,7 +5148,7 @@ namespace ts { } function getBreakOrContinueStatementOccurrences(breakOrContinueStatement: BreakOrContinueStatement): HighlightSpan[] { - let owner = getBreakOrContinueOwner(breakOrContinueStatement); + const owner = getBreakOrContinueOwner(breakOrContinueStatement); if (owner) { switch (owner.kind) { @@ -5158,7 +5157,7 @@ namespace ts { case SyntaxKind.ForOfStatement: case SyntaxKind.DoStatement: case SyntaxKind.WhileStatement: - return getLoopBreakContinueOccurrences(owner) + return getLoopBreakContinueOccurrences(owner); case SyntaxKind.SwitchStatement: return getSwitchCaseDefaultOccurrences(owner); @@ -5169,7 +5168,7 @@ namespace ts { } function getSwitchCaseDefaultOccurrences(switchStatement: SwitchStatement): HighlightSpan[] { - let keywords: Node[] = []; + const keywords: Node[] = []; pushKeywordIf(keywords, switchStatement.getFirstToken(), SyntaxKind.SwitchKeyword); @@ -5177,7 +5176,7 @@ namespace ts { forEach(switchStatement.caseBlock.clauses, clause => { pushKeywordIf(keywords, clause.getFirstToken(), SyntaxKind.CaseKeyword, SyntaxKind.DefaultKeyword); - let breaksAndContinues = aggregateAllBreakAndContinueStatements(clause); + const breaksAndContinues = aggregateAllBreakAndContinueStatements(clause); forEach(breaksAndContinues, statement => { if (ownsBreakOrContinueStatement(switchStatement, statement)) { @@ -5190,7 +5189,7 @@ namespace ts { } function getTryCatchFinallyOccurrences(tryStatement: TryStatement): HighlightSpan[] { - let keywords: Node[] = []; + const keywords: Node[] = []; pushKeywordIf(keywords, tryStatement.getFirstToken(), SyntaxKind.TryKeyword); @@ -5199,7 +5198,7 @@ namespace ts { } if (tryStatement.finallyBlock) { - let finallyKeyword = findChildOfKind(tryStatement, SyntaxKind.FinallyKeyword, sourceFile); + const finallyKeyword = findChildOfKind(tryStatement, SyntaxKind.FinallyKeyword, sourceFile); pushKeywordIf(keywords, finallyKeyword, SyntaxKind.FinallyKeyword); } @@ -5207,13 +5206,13 @@ namespace ts { } function getThrowOccurrences(throwStatement: ThrowStatement): HighlightSpan[] { - let owner = getThrowStatementOwner(throwStatement); + const owner = getThrowStatementOwner(throwStatement); if (!owner) { return undefined; } - let keywords: Node[] = []; + const keywords: Node[] = []; forEach(aggregateOwnedThrowStatements(owner), throwStatement => { pushKeywordIf(keywords, throwStatement.getFirstToken(), SyntaxKind.ThrowKeyword); @@ -5231,14 +5230,14 @@ namespace ts { } function getReturnOccurrences(returnStatement: ReturnStatement): HighlightSpan[] { - let func = getContainingFunction(returnStatement); + const func = getContainingFunction(returnStatement); // If we didn't find a containing function with a block body, bail out. if (!(func && hasKind(func.body, SyntaxKind.Block))) { return undefined; } - let keywords: Node[] = [] + const keywords: Node[] = []; forEachReturnStatement(func.body, returnStatement => { pushKeywordIf(keywords, returnStatement.getFirstToken(), SyntaxKind.ReturnKeyword); }); @@ -5252,7 +5251,7 @@ namespace ts { } function getIfElseOccurrences(ifStatement: IfStatement): HighlightSpan[] { - let keywords: Node[] = []; + const keywords: Node[] = []; // Traverse upwards through all parent if-statements linked by their else-branches. while (hasKind(ifStatement.parent, SyntaxKind.IfStatement) && (ifStatement.parent).elseStatement === ifStatement) { @@ -5261,7 +5260,7 @@ namespace ts { // Now traverse back down through the else branches, aggregating if/else keywords of if-statements. while (ifStatement) { - let children = ifStatement.getChildren(); + const children = ifStatement.getChildren(); pushKeywordIf(keywords, children[0], SyntaxKind.IfKeyword); // Generally the 'else' keyword is second-to-last, so we traverse backwards. @@ -5272,20 +5271,20 @@ namespace ts { } if (!hasKind(ifStatement.elseStatement, SyntaxKind.IfStatement)) { - break + break; } ifStatement = ifStatement.elseStatement; } - let result: HighlightSpan[] = []; + const result: HighlightSpan[] = []; // We'd like to highlight else/ifs together if they are only separated by whitespace // (i.e. the keywords are separated by no comments, no newlines). for (let i = 0; i < keywords.length; i++) { if (keywords[i].kind === SyntaxKind.ElseKeyword && i < keywords.length - 1) { - let elseKeyword = keywords[i]; - let ifKeyword = keywords[i + 1]; // this *should* always be an 'if' keyword. + const elseKeyword = keywords[i]; + const ifKeyword = keywords[i + 1]; // this *should* always be an 'if' keyword. let shouldCombindElseAndIf = true; @@ -5328,9 +5327,9 @@ namespace ts { return undefined; } - let result: ReferenceEntry[] = []; - for (let entry of documentHighlights) { - for (let highlightSpan of entry.highlightSpans) { + const result: ReferenceEntry[] = []; + for (const entry of documentHighlights) { + for (const highlightSpan of entry.highlightSpans) { result.push({ fileName: entry.fileName, textSpan: highlightSpan.textSpan, @@ -5348,9 +5347,9 @@ namespace ts { return undefined; } - let referenceEntries: ReferenceEntry[] = []; + const referenceEntries: ReferenceEntry[] = []; - for (let referenceSymbol of referenceSymbols) { + for (const referenceSymbol of referenceSymbols) { addRange(referenceEntries, referenceSymbol.references); } @@ -5358,17 +5357,17 @@ namespace ts { } function findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): RenameLocation[] { - let referencedSymbols = findReferencedSymbols(fileName, position, findInStrings, findInComments); + const referencedSymbols = findReferencedSymbols(fileName, position, findInStrings, findInComments); return convertReferences(referencedSymbols); } function getReferencesAtPosition(fileName: string, position: number): ReferenceEntry[] { - let referencedSymbols = findReferencedSymbols(fileName, position, /*findInStrings:*/ false, /*findInComments:*/ false); + const referencedSymbols = findReferencedSymbols(fileName, position, /*findInStrings*/ false, /*findInComments*/ false); return convertReferences(referencedSymbols); } - function findReferences(fileName: string, position: number): ReferencedSymbol[]{ - let referencedSymbols = findReferencedSymbols(fileName, position, /*findInStrings:*/ false, /*findInComments:*/ false); + function findReferences(fileName: string, position: number): ReferencedSymbol[] { + const referencedSymbols = findReferencedSymbols(fileName, position, /*findInStrings*/ false, /*findInComments*/ false); // Only include referenced symbols that have a valid definition. return filter(referencedSymbols, rs => !!rs.definition); @@ -5377,17 +5376,17 @@ namespace ts { function findReferencedSymbols(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): ReferencedSymbol[] { synchronizeHostData(); - let sourceFile = getValidSourceFile(fileName); + const sourceFile = getValidSourceFile(fileName); - let node = getTouchingPropertyName(sourceFile, position); + const node = getTouchingPropertyName(sourceFile, position); if (!node) { return undefined; } if (node.kind !== SyntaxKind.Identifier && // TODO (drosen): This should be enabled in a later release - currently breaks rename. - //node.kind !== SyntaxKind.ThisKeyword && - //node.kind !== SyntaxKind.SuperKeyword && + // node.kind !== SyntaxKind.ThisKeyword && + // node.kind !== SyntaxKind.SuperKeyword && !isLiteralNameOfPropertyDeclarationOrIndexAccess(node) && !isNameOfExternalModuleImportOrDeclaration(node)) { return undefined; @@ -5398,12 +5397,12 @@ namespace ts { } function getReferencedSymbolsForNode(node: Node, sourceFiles: SourceFile[], findInStrings: boolean, findInComments: boolean): ReferencedSymbol[] { - let typeChecker = program.getTypeChecker(); + const typeChecker = program.getTypeChecker(); // Labels if (isLabelName(node)) { if (isJumpStatementTarget(node)) { - let labelDefinition = getTargetLabel((node.parent), (node).text); + const labelDefinition = getTargetLabel((node.parent), (node).text); // if we have a label definition, look within its statement for references, if not, then // the label is undefined and we have no results.. return labelDefinition ? getLabelReferencesInNode(labelDefinition.parent, labelDefinition) : undefined; @@ -5422,7 +5421,7 @@ namespace ts { return getReferencesForSuperKeyword(node); } - let symbol = typeChecker.getSymbolAtLocation(node); + const symbol = typeChecker.getSymbolAtLocation(node); // Could not find a symbol e.g. unknown identifier if (!symbol) { @@ -5430,7 +5429,7 @@ namespace ts { return undefined; } - let declarations = symbol.declarations; + const declarations = symbol.declarations; // The symbol was an internal symbol and does not have a declaration e.g. undefined symbol if (!declarations || !declarations.length) { @@ -5440,29 +5439,29 @@ namespace ts { let result: ReferencedSymbol[]; // Compute the meaning from the location and the symbol it references - let searchMeaning = getIntersectingMeaningFromDeclarations(getMeaningFromLocation(node), declarations); + const searchMeaning = getIntersectingMeaningFromDeclarations(getMeaningFromLocation(node), declarations); // Get the text to search for. // Note: if this is an external module symbol, the name doesn't include quotes. - let declaredName = stripQuotes(getDeclaredName(typeChecker, symbol, node)); + const declaredName = stripQuotes(getDeclaredName(typeChecker, symbol, node)); // Try to get the smallest valid scope that we can limit our search to; // otherwise we'll need to search globally (i.e. include each file). - let scope = getSymbolScope(symbol); + const scope = getSymbolScope(symbol); // Maps from a symbol ID to the ReferencedSymbol entry in 'result'. - let symbolToIndex: number[] = []; + const symbolToIndex: number[] = []; if (scope) { result = []; getReferencesInNode(scope, symbol, declaredName, node, searchMeaning, findInStrings, findInComments, result, symbolToIndex); } else { - let internedName = getInternedName(symbol, node, declarations) - for (let sourceFile of sourceFiles) { + const internedName = getInternedName(symbol, node, declarations); + for (const sourceFile of sourceFiles) { cancellationToken.throwIfCancellationRequested(); - let nameTable = getNameTable(sourceFile); + const nameTable = getNameTable(sourceFile); if (lookUp(nameTable, internedName)) { result = result || []; @@ -5474,9 +5473,9 @@ namespace ts { return result; function getDefinition(symbol: Symbol): DefinitionInfo { - let info = getSymbolDisplayPartsDocumentationAndSymbolKind(symbol, node.getSourceFile(), getContainerNode(node), node); - let name = map(info.displayParts, p => p.text).join(""); - let declarations = symbol.declarations; + const info = getSymbolDisplayPartsDocumentationAndSymbolKind(symbol, node.getSourceFile(), getContainerNode(node), node); + const name = map(info.displayParts, p => p.text).join(""); + const declarations = symbol.declarations; if (!declarations || declarations.length === 0) { return undefined; } @@ -5506,7 +5505,7 @@ namespace ts { // Try to get the local symbol if we're dealing with an 'export default' // since that symbol has the "true" name. - let localExportDefaultSymbol = getLocalSymbolForExportDefault(symbol); + const localExportDefaultSymbol = getLocalSymbolForExportDefault(symbol); symbol = localExportDefaultSymbol || symbol; return stripQuotes(symbol.name); @@ -5523,14 +5522,14 @@ namespace ts { function getSymbolScope(symbol: Symbol): Node { // If this is the symbol of a named function expression or named class expression, // then named references are limited to its own scope. - let valueDeclaration = symbol.valueDeclaration; + const valueDeclaration = symbol.valueDeclaration; if (valueDeclaration && (valueDeclaration.kind === SyntaxKind.FunctionExpression || valueDeclaration.kind === SyntaxKind.ClassExpression)) { return valueDeclaration; } // If this is private property or method, the scope is the containing class if (symbol.flags & (SymbolFlags.Property | SymbolFlags.Method)) { - let privateDeclaration = forEach(symbol.getDeclarations(), d => (d.flags & NodeFlags.Private) ? d : undefined); + const privateDeclaration = forEach(symbol.getDeclarations(), d => (d.flags & NodeFlags.Private) ? d : undefined); if (privateDeclaration) { return getAncestor(privateDeclaration, SyntaxKind.ClassDeclaration); } @@ -5548,12 +5547,12 @@ namespace ts { return undefined; } - let scope: Node = undefined; + let scope: Node; - let declarations = symbol.getDeclarations(); + const declarations = symbol.getDeclarations(); if (declarations) { - for (let declaration of declarations) { - let container = getContainerNode(declaration); + for (const declaration of declarations) { + const container = getContainerNode(declaration); if (!container) { return undefined; @@ -5579,7 +5578,7 @@ namespace ts { } function getPossibleSymbolReferencePositions(sourceFile: SourceFile, symbolName: string, start: number, end: number): number[] { - let positions: number[] = []; + const positions: number[] = []; /// TODO: Cache symbol existence for files to save text search // Also, need to make this work for unicode escapes. @@ -5589,9 +5588,9 @@ namespace ts { return positions; } - let text = sourceFile.text; - let sourceLength = text.length; - let symbolNameLength = symbolName.length; + const text = sourceFile.text; + const sourceLength = text.length; + const symbolNameLength = symbolName.length; let position = text.indexOf(symbolName, start); while (position >= 0) { @@ -5602,7 +5601,7 @@ namespace ts { // We found a match. Make sure it's not part of a larger word (i.e. the char // before and after it have to be a non-identifier char). - let endPosition = position + symbolNameLength; + const endPosition = position + symbolNameLength; if ((position === 0 || !isIdentifierPart(text.charCodeAt(position - 1), ScriptTarget.Latest)) && (endPosition === sourceLength || !isIdentifierPart(text.charCodeAt(endPosition), ScriptTarget.Latest))) { @@ -5616,14 +5615,14 @@ namespace ts { } function getLabelReferencesInNode(container: Node, targetLabel: Identifier): ReferencedSymbol[] { - let references: ReferenceEntry[] = []; - let sourceFile = container.getSourceFile(); - let labelName = targetLabel.text; - let possiblePositions = getPossibleSymbolReferencePositions(sourceFile, labelName, container.getStart(), container.getEnd()); + const references: ReferenceEntry[] = []; + const sourceFile = container.getSourceFile(); + const labelName = targetLabel.text; + const possiblePositions = getPossibleSymbolReferencePositions(sourceFile, labelName, container.getStart(), container.getEnd()); forEach(possiblePositions, position => { cancellationToken.throwIfCancellationRequested(); - let node = getTouchingWord(sourceFile, position); + const node = getTouchingWord(sourceFile, position); if (!node || node.getWidth() !== labelName.length) { return; } @@ -5635,14 +5634,14 @@ namespace ts { } }); - let definition: DefinitionInfo = { + const definition: DefinitionInfo = { containerKind: "", containerName: "", fileName: targetLabel.getSourceFile().fileName, kind: ScriptElementKind.label, name: labelName, textSpan: createTextSpanFromBounds(targetLabel.getStart(), targetLabel.getEnd()) - } + }; return [{ definition, references }]; } @@ -5687,19 +5686,19 @@ namespace ts { result: ReferencedSymbol[], symbolToIndex: number[]): void { - let sourceFile = container.getSourceFile(); - let tripleSlashDirectivePrefixRegex = /^\/\/\/\s* { cancellationToken.throwIfCancellationRequested(); - let referenceLocation = getTouchingPropertyName(sourceFile, position); + const referenceLocation = getTouchingPropertyName(sourceFile, position); if (!isValidReferencePosition(referenceLocation, searchText)) { // This wasn't the start of a token. Check to see if it might be a // match in a comment or string if that's what the caller is asking @@ -5727,14 +5726,14 @@ namespace ts { return; } - let referenceSymbol = typeChecker.getSymbolAtLocation(referenceLocation); + const referenceSymbol = typeChecker.getSymbolAtLocation(referenceLocation); if (referenceSymbol) { - let referenceSymbolDeclaration = referenceSymbol.valueDeclaration; - let shorthandValueSymbol = typeChecker.getShorthandAssignmentValueSymbol(referenceSymbolDeclaration); - let relatedSymbol = getRelatedSymbol(searchSymbols, referenceSymbol, referenceLocation); + const referenceSymbolDeclaration = referenceSymbol.valueDeclaration; + const shorthandValueSymbol = typeChecker.getShorthandAssignmentValueSymbol(referenceSymbolDeclaration); + const relatedSymbol = getRelatedSymbol(searchSymbols, referenceSymbol, referenceLocation); if (relatedSymbol) { - let referencedSymbol = getReferencedSymbol(relatedSymbol); + const referencedSymbol = getReferencedSymbol(relatedSymbol); referencedSymbol.references.push(getReferenceEntryFromNode(referenceLocation)); } /* Because in short-hand property assignment, an identifier which stored as name of the short-hand property assignment @@ -5744,7 +5743,7 @@ namespace ts { * position of property accessing, the referenceEntry of such position will be handled in the first case. */ else if (!(referenceSymbol.flags & SymbolFlags.Transient) && searchSymbols.indexOf(shorthandValueSymbol) >= 0) { - let referencedSymbol = getReferencedSymbol(shorthandValueSymbol); + const referencedSymbol = getReferencedSymbol(shorthandValueSymbol); referencedSymbol.references.push(getReferenceEntryFromNode(referenceSymbolDeclaration.name)); } } @@ -5754,7 +5753,7 @@ namespace ts { return; function getReferencedSymbol(symbol: Symbol): ReferencedSymbol { - let symbolId = getSymbolId(symbol); + const symbolId = getSymbolId(symbol); let index = symbolToIndex[symbolId]; if (index === undefined) { index = result.length; @@ -5773,7 +5772,7 @@ namespace ts { return isInCommentHelper(sourceFile, position, isNonReferenceComment); function isNonReferenceComment(c: CommentRange): boolean { - let commentText = sourceFile.text.substring(c.pos, c.end); + const commentText = sourceFile.text.substring(c.pos, c.end); return !tripleSlashDirectivePrefixRegex.test(commentText); } } @@ -5802,20 +5801,20 @@ namespace ts { return undefined; } - let references: ReferenceEntry[] = []; + const references: ReferenceEntry[] = []; - let sourceFile = searchSpaceNode.getSourceFile(); - let possiblePositions = getPossibleSymbolReferencePositions(sourceFile, "super", searchSpaceNode.getStart(), searchSpaceNode.getEnd()); + const sourceFile = searchSpaceNode.getSourceFile(); + const possiblePositions = getPossibleSymbolReferencePositions(sourceFile, "super", searchSpaceNode.getStart(), searchSpaceNode.getEnd()); forEach(possiblePositions, position => { cancellationToken.throwIfCancellationRequested(); - let node = getTouchingWord(sourceFile, position); + const node = getTouchingWord(sourceFile, position); if (!node || node.kind !== SyntaxKind.SuperKeyword) { return; } - let container = getSuperContainer(node, /*includeFunctions*/ false); + const container = getSuperContainer(node, /*includeFunctions*/ false); // If we have a 'super' container, we must have an enclosing class. // Now make sure the owning class is the same as the search-space @@ -5825,7 +5824,7 @@ namespace ts { } }); - let definition = getDefinition(searchSpaceNode.symbol); + const definition = getDefinition(searchSpaceNode.symbol); return [{ definition, references }]; } @@ -5847,7 +5846,7 @@ namespace ts { case SyntaxKind.Constructor: case SyntaxKind.GetAccessor: case SyntaxKind.SetAccessor: - staticFlag &= searchSpaceNode.flags + staticFlag &= searchSpaceNode.flags; searchSpaceNode = searchSpaceNode.parent; // re-assign to be the owning class break; case SyntaxKind.SourceFile: @@ -5864,7 +5863,7 @@ namespace ts { return undefined; } - let references: ReferenceEntry[] = []; + const references: ReferenceEntry[] = []; let possiblePositions: number[]; if (searchSpaceNode.kind === SyntaxKind.SourceFile) { @@ -5874,7 +5873,7 @@ namespace ts { }); } else { - let sourceFile = searchSpaceNode.getSourceFile(); + const sourceFile = searchSpaceNode.getSourceFile(); possiblePositions = getPossibleSymbolReferencePositions(sourceFile, "this", searchSpaceNode.getStart(), searchSpaceNode.getEnd()); getThisReferencesInFile(sourceFile, searchSpaceNode, possiblePositions, references); } @@ -5895,12 +5894,12 @@ namespace ts { forEach(possiblePositions, position => { cancellationToken.throwIfCancellationRequested(); - let node = getTouchingWord(sourceFile, position); + const node = getTouchingWord(sourceFile, position); if (!node || (node.kind !== SyntaxKind.ThisKeyword && node.kind !== SyntaxKind.ThisType)) { return; } - let container = getThisContainer(node, /* includeArrowFunctions */ false); + const container = getThisContainer(node, /* includeArrowFunctions */ false); switch (searchSpaceNode.kind) { case SyntaxKind.FunctionExpression: @@ -5955,13 +5954,13 @@ namespace ts { * property name and variable declaration of the identifier. * Like in below example, when querying for all references for an identifier 'name', of the property assignment, the language service * should show both 'name' in 'obj' and 'name' in variable declaration - * let name = "Foo"; - * let obj = { name }; + * const name = "Foo"; + * const obj = { name }; * In order to do that, we will populate the search set with the value symbol of the identifier as a value of the property assignment * so that when matching with potential reference symbol, both symbols from property declaration and variable declaration * will be included correctly. */ - let shorthandValueSymbol = typeChecker.getShorthandAssignmentValueSymbol(location.parent); + const shorthandValueSymbol = typeChecker.getShorthandAssignmentValueSymbol(location.parent); if (shorthandValueSymbol) { result.push(shorthandValueSymbol); } @@ -6008,9 +6007,9 @@ namespace ts { function getPropertySymbolFromTypeReference(typeReference: ExpressionWithTypeArguments) { if (typeReference) { - let type = typeChecker.getTypeAtLocation(typeReference); + const type = typeChecker.getTypeAtLocation(typeReference); if (type) { - let propertySymbol = typeChecker.getPropertyOfType(type, propertyName); + const propertySymbol = typeChecker.getPropertyOfType(type, propertyName); if (propertySymbol) { result.push(propertySymbol); } @@ -6030,7 +6029,7 @@ namespace ts { // If the reference symbol is an alias, check if what it is aliasing is one of the search // symbols. if (isImportOrExportSpecifierImportSymbol(referenceSymbol)) { - let aliasedSymbol = typeChecker.getAliasedSymbol(referenceSymbol); + const aliasedSymbol = typeChecker.getAliasedSymbol(referenceSymbol); if (searchSymbols.indexOf(aliasedSymbol) >= 0) { return aliasedSymbol; } @@ -6056,7 +6055,7 @@ namespace ts { // Finally, try all properties with the same name in any type the containing type extended or implemented, and // see if any is in the list if (rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { - let result: Symbol[] = []; + const result: Symbol[] = []; getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getName(), result); return forEach(result, s => searchSymbols.indexOf(s) >= 0 ? s : undefined); } @@ -6067,21 +6066,21 @@ namespace ts { function getPropertySymbolsFromContextualType(node: Node): Symbol[] { if (isNameOfPropertyAssignment(node)) { - let objectLiteral = node.parent.parent; - let contextualType = typeChecker.getContextualType(objectLiteral); - let name = (node).text; + const objectLiteral = node.parent.parent; + const contextualType = typeChecker.getContextualType(objectLiteral); + const name = (node).text; if (contextualType) { if (contextualType.flags & TypeFlags.Union) { // This is a union type, first see if the property we are looking for is a union property (i.e. exists in all types) // if not, search the constituent types for the property - let unionProperty = contextualType.getProperty(name) + const unionProperty = contextualType.getProperty(name); if (unionProperty) { return [unionProperty]; } else { - let result: Symbol[] = []; + const result: Symbol[] = []; forEach((contextualType).types, t => { - let symbol = t.getProperty(name); + const symbol = t.getProperty(name); if (symbol) { result.push(symbol); } @@ -6090,7 +6089,7 @@ namespace ts { } } else { - let symbol = contextualType.getProperty(name); + const symbol = contextualType.getProperty(name); if (symbol) { return [symbol]; } @@ -6119,8 +6118,8 @@ namespace ts { // Remember the last meaning lastIterationMeaning = meaning; - for (let declaration of declarations) { - let declarationMeaning = getMeaningFromDeclaration(declaration); + for (const declaration of declarations) { + const declarationMeaning = getMeaningFromDeclaration(declaration); if (declarationMeaning & meaning) { meaning |= declarationMeaning; @@ -6155,13 +6154,13 @@ namespace ts { return true; } - let parent = node.parent; + const parent = node.parent; if (parent) { if (parent.kind === SyntaxKind.PostfixUnaryExpression || parent.kind === SyntaxKind.PrefixUnaryExpression) { return true; } else if (parent.kind === SyntaxKind.BinaryExpression && (parent).left === node) { - let operator = (parent).operatorToken.kind; + const operator = (parent).operatorToken.kind; return SyntaxKind.FirstAssignment <= operator && operator <= SyntaxKind.LastAssignment; } } @@ -6183,8 +6182,8 @@ namespace ts { function getEmitOutput(fileName: string): EmitOutput { synchronizeHostData(); - let sourceFile = getValidSourceFile(fileName); - let outputFiles: OutputFile[] = []; + const sourceFile = getValidSourceFile(fileName); + const outputFiles: OutputFile[] = []; function writeFile(fileName: string, data: string, writeByteOrderMark: boolean) { outputFiles.push({ @@ -6194,7 +6193,7 @@ namespace ts { }); } - let emitOutput = program.emit(sourceFile, writeFile, cancellationToken); + const emitOutput = program.emit(sourceFile, writeFile, cancellationToken); return { outputFiles, @@ -6287,7 +6286,7 @@ namespace ts { } if (!isLastClause && root.parent.kind === SyntaxKind.ExpressionWithTypeArguments && root.parent.parent.kind === SyntaxKind.HeritageClause) { - let decl = root.parent.parent.parent; + const decl = root.parent.parent.parent; return (decl.kind === SyntaxKind.ClassDeclaration && (root.parent.parent).token === SyntaxKind.ImplementsKeyword) || (decl.kind === SyntaxKind.InterfaceDeclaration && (root.parent.parent).token === SyntaxKind.ExtendsKeyword); } @@ -6359,7 +6358,7 @@ namespace ts { function getSignatureHelpItems(fileName: string, position: number): SignatureHelpItems { synchronizeHostData(); - let sourceFile = getValidSourceFile(fileName); + const sourceFile = getValidSourceFile(fileName); return SignatureHelp.getSignatureHelpItems(program, sourceFile, position, cancellationToken); } @@ -6370,10 +6369,10 @@ namespace ts { } function getNameOrDottedNameSpan(fileName: string, startPos: number, endPos: number): TextSpan { - let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); // Get node at the location - let node = getTouchingPropertyName(sourceFile, startPos); + const node = getTouchingPropertyName(sourceFile, startPos); if (!node) { return; @@ -6429,13 +6428,13 @@ namespace ts { function getBreakpointStatementAtPosition(fileName: string, position: number) { // doesn't use compiler - no need to synchronize with host - let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); return BreakpointResolver.spanInSourceFileAtLocation(sourceFile, position); } function getNavigationBarItems(fileName: string): NavigationBarItem[] { - let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); return NavigationBar.getNavigationBarItems(sourceFile, host.getCompilationSettings()); } @@ -6467,11 +6466,11 @@ namespace ts { function getEncodedSemanticClassifications(fileName: string, span: TextSpan): Classifications { synchronizeHostData(); - let sourceFile = getValidSourceFile(fileName); - let typeChecker = program.getTypeChecker(); + const sourceFile = getValidSourceFile(fileName); + const typeChecker = program.getTypeChecker(); - let result: number[] = []; - let classifiableNames = program.getClassifiableNames(); + const result: number[] = []; + const classifiableNames = program.getClassifiableNames(); processNode(sourceFile); return { spans: result, endOfLineState: EndOfLineState.None }; @@ -6483,7 +6482,7 @@ namespace ts { } function classifySymbol(symbol: Symbol, meaningAtPosition: SemanticMeaning): ClassificationType { - let flags = symbol.getFlags(); + const flags = symbol.getFlags(); if ((flags & SymbolFlags.Classifiable) === SymbolFlags.None) { return; } @@ -6531,19 +6530,19 @@ namespace ts { function processNode(node: Node) { // Only walk into nodes that intersect the requested span. if (node && textSpanIntersectsWith(span, node.getFullStart(), node.getFullWidth())) { - let kind = node.kind; + const kind = node.kind; checkForClassificationCancellation(kind); if (kind === SyntaxKind.Identifier && !nodeIsMissing(node)) { - let identifier = node; + const identifier = node; // Only bother calling into the typechecker if this is an identifier that // could possibly resolve to a type name. This makes classification run // in a third of the time it would normally take. if (classifiableNames[identifier.text]) { - let symbol = typeChecker.getSymbolAtLocation(node); + const symbol = typeChecker.getSymbolAtLocation(node); if (symbol) { - let type = classifySymbol(symbol, getMeaningFromLocation(node)); + const type = classifySymbol(symbol, getMeaningFromLocation(node)); if (type) { pushClassification(node.getStart(), node.getWidth(), type); } @@ -6583,8 +6582,8 @@ namespace ts { function convertClassifications(classifications: Classifications): ClassifiedSpan[] { Debug.assert(classifications.spans.length % 3 === 0); - let dense = classifications.spans; - let result: ClassifiedSpan[] = []; + const dense = classifications.spans; + const result: ClassifiedSpan[] = []; for (let i = 0, n = dense.length; i < n; i += 3) { result.push({ textSpan: createTextSpan(dense[i], dense[i + 1]), @@ -6601,15 +6600,15 @@ namespace ts { function getEncodedSyntacticClassifications(fileName: string, span: TextSpan): Classifications { // doesn't use compiler - no need to synchronize with host - let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); - let spanStart = span.start; - let spanLength = span.length; + const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + const spanStart = span.start; + const spanLength = span.length; // Make a scanner we can get trivia from. - let triviaScanner = createScanner(ScriptTarget.Latest, /*skipTrivia:*/ false, sourceFile.languageVariant, sourceFile.text); - let mergeConflictScanner = createScanner(ScriptTarget.Latest, /*skipTrivia:*/ false, sourceFile.languageVariant, sourceFile.text); + const triviaScanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ false, sourceFile.languageVariant, sourceFile.text); + const mergeConflictScanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ false, sourceFile.languageVariant, sourceFile.text); - let result: number[] = []; + const result: number[] = []; processElement(sourceFile); return { spans: result, endOfLineState: EndOfLineState.None }; @@ -6623,15 +6622,15 @@ namespace ts { function classifyLeadingTriviaAndGetTokenStart(token: Node): number { triviaScanner.setTextPos(token.pos); while (true) { - let start = triviaScanner.getTextPos(); + const start = triviaScanner.getTextPos(); // only bother scanning if we have something that could be trivia. if (!couldStartTrivia(sourceFile.text, start)) { return start; } - let kind = triviaScanner.scan(); - let end = triviaScanner.getTextPos(); - let width = end - start; + const kind = triviaScanner.scan(); + const end = triviaScanner.getTextPos(); + const width = end - start; // The moment we get something that isn't trivia, then stop processing. if (!isTrivia(kind)) { @@ -6655,8 +6654,8 @@ namespace ts { } if (kind === SyntaxKind.ConflictMarkerTrivia) { - let text = sourceFile.text; - let ch = text.charCodeAt(start); + const text = sourceFile.text; + const ch = text.charCodeAt(start); // for the <<<<<<< and >>>>>>> markers, we just add them in as comments // in the classification stream. @@ -6677,7 +6676,7 @@ namespace ts { if (kind === SyntaxKind.MultiLineCommentTrivia) { // See if this is a doc comment. If so, we'll classify certain portions of it // specially. - let docCommentAndDiagnostics = parseIsolatedJSDocComment(sourceFile.text, start, width); + const docCommentAndDiagnostics = parseIsolatedJSDocComment(sourceFile.text, start, width); if (docCommentAndDiagnostics && docCommentAndDiagnostics.jsDocComment) { docCommentAndDiagnostics.jsDocComment.parent = token; classifyJSDocComment(docCommentAndDiagnostics.jsDocComment); @@ -6696,7 +6695,7 @@ namespace ts { function classifyJSDocComment(docComment: JSDocComment) { let pos = docComment.pos; - for (let tag of docComment.tags) { + for (const tag of docComment.tags) { // As we walk through each tag, classify the portion of text from the end of // the last tag (or the start of the entire doc comment) as 'comment'. if (tag.pos !== pos) { @@ -6754,7 +6753,7 @@ namespace ts { } function processJSDocTemplateTag(tag: JSDocTemplateTag) { - for (let child of tag.getChildren()) { + for (const child of tag.getChildren()) { processElement(child); } } @@ -6776,11 +6775,11 @@ namespace ts { } function classifyDisabledCodeToken() { - let start = mergeConflictScanner.getTextPos(); - let tokenKind = mergeConflictScanner.scan(); - let end = mergeConflictScanner.getTextPos(); + const start = mergeConflictScanner.getTextPos(); + const tokenKind = mergeConflictScanner.scan(); + const end = mergeConflictScanner.getTextPos(); - let type = classifyTokenType(tokenKind); + const type = classifyTokenType(tokenKind); if (type) { pushClassification(start, end - start, type); } @@ -6791,12 +6790,12 @@ namespace ts { return; } - let tokenStart = classifyLeadingTriviaAndGetTokenStart(token); + const tokenStart = classifyLeadingTriviaAndGetTokenStart(token); - let tokenWidth = token.end - tokenStart; + const tokenWidth = token.end - tokenStart; Debug.assert(tokenWidth >= 0); if (tokenWidth > 0) { - let type = classifyTokenType(token.kind, token); + const type = classifyTokenType(token.kind, token); if (type) { pushClassification(tokenStart, tokenWidth, type); } @@ -6923,9 +6922,9 @@ namespace ts { if (decodedTextSpanIntersectsWith(spanStart, spanLength, element.pos, element.getFullWidth())) { checkForClassificationCancellation(element.kind); - let children = element.getChildren(sourceFile); + const children = element.getChildren(sourceFile); for (let i = 0, n = children.length; i < n; i++) { - let child = children[i]; + const child = children[i]; if (isToken(child)) { classifyToken(child); } @@ -6940,28 +6939,28 @@ namespace ts { function getOutliningSpans(fileName: string): OutliningSpan[] { // doesn't use compiler - no need to synchronize with host - let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); return OutliningElementsCollector.collectElements(sourceFile); } function getBraceMatchingAtPosition(fileName: string, position: number) { - let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); - let result: TextSpan[] = []; + const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + const result: TextSpan[] = []; - let token = getTouchingToken(sourceFile, position); + const token = getTouchingToken(sourceFile, position); if (token.getStart(sourceFile) === position) { - let matchKind = getMatchingTokenKind(token); + const matchKind = getMatchingTokenKind(token); // Ensure that there is a corresponding token to match ours. if (matchKind) { - let parentElement = token.parent; + const parentElement = token.parent; - let childNodes = parentElement.getChildren(sourceFile); - for (let current of childNodes) { + const childNodes = parentElement.getChildren(sourceFile); + for (const current of childNodes) { if (current.kind === matchKind) { - let range1 = createTextSpan(token.getStart(sourceFile), token.getWidth(sourceFile)); - let range2 = createTextSpan(current.getStart(sourceFile), current.getWidth(sourceFile)); + const range1 = createTextSpan(token.getStart(sourceFile), token.getWidth(sourceFile)); + const range2 = createTextSpan(current.getStart(sourceFile), current.getWidth(sourceFile)); // We want to order the braces when we return the result. if (range1.start < range2.start) { @@ -6981,11 +6980,11 @@ namespace ts { function getMatchingTokenKind(token: Node): ts.SyntaxKind { switch (token.kind) { - case ts.SyntaxKind.OpenBraceToken: return ts.SyntaxKind.CloseBraceToken + case ts.SyntaxKind.OpenBraceToken: return ts.SyntaxKind.CloseBraceToken; case ts.SyntaxKind.OpenParenToken: return ts.SyntaxKind.CloseParenToken; case ts.SyntaxKind.OpenBracketToken: return ts.SyntaxKind.CloseBracketToken; case ts.SyntaxKind.LessThanToken: return ts.SyntaxKind.GreaterThanToken; - case ts.SyntaxKind.CloseBraceToken: return ts.SyntaxKind.OpenBraceToken + case ts.SyntaxKind.CloseBraceToken: return ts.SyntaxKind.OpenBraceToken; case ts.SyntaxKind.CloseParenToken: return ts.SyntaxKind.OpenParenToken; case ts.SyntaxKind.CloseBracketToken: return ts.SyntaxKind.OpenBracketToken; case ts.SyntaxKind.GreaterThanToken: return ts.SyntaxKind.LessThanToken; @@ -6997,29 +6996,29 @@ namespace ts { function getIndentationAtPosition(fileName: string, position: number, editorOptions: EditorOptions) { let start = new Date().getTime(); - let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); log("getIndentationAtPosition: getCurrentSourceFile: " + (new Date().getTime() - start)); start = new Date().getTime(); - let result = formatting.SmartIndenter.getIndentation(position, sourceFile, editorOptions); + const result = formatting.SmartIndenter.getIndentation(position, sourceFile, editorOptions); log("getIndentationAtPosition: computeIndentation : " + (new Date().getTime() - start)); return result; } function getFormattingEditsForRange(fileName: string, start: number, end: number, options: FormatCodeOptions): TextChange[] { - let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); return formatting.formatSelection(start, end, sourceFile, getRuleProvider(options), options); } function getFormattingEditsForDocument(fileName: string, options: FormatCodeOptions): TextChange[] { - let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); return formatting.formatDocument(sourceFile, getRuleProvider(options), options); } function getFormattingEditsAfterKeystroke(fileName: string, position: number, key: string, options: FormatCodeOptions): TextChange[] { - let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); if (key === "}") { return formatting.formatOnClosingCurly(position, sourceFile, getRuleProvider(options), options); @@ -7055,16 +7054,16 @@ namespace ts { * be performed. */ function getDocCommentTemplateAtPosition(fileName: string, position: number): TextInsertion { - let start = new Date().getTime(); - let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + const start = new Date().getTime(); + const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); // Check if in a context where we don't want to perform any insertion if (isInString(sourceFile, position) || isInComment(sourceFile, position) || hasDocComment(sourceFile, position)) { return undefined; } - let tokenAtPos = getTokenAtPosition(sourceFile, position); - let tokenStart = tokenAtPos.getStart() + const tokenAtPos = getTokenAtPosition(sourceFile, position); + const tokenStart = tokenAtPos.getStart(); if (!tokenAtPos || tokenStart < position) { return undefined; } @@ -7100,11 +7099,11 @@ namespace ts { return undefined; } - let parameters = getParametersForJsDocOwningNode(commentOwner); - let posLineAndChar = sourceFile.getLineAndCharacterOfPosition(position); - let lineStart = sourceFile.getLineStarts()[posLineAndChar.line]; + const parameters = getParametersForJsDocOwningNode(commentOwner); + const posLineAndChar = sourceFile.getLineAndCharacterOfPosition(position); + const lineStart = sourceFile.getLineStarts()[posLineAndChar.line]; - let indentationStr = sourceFile.text.substr(lineStart, posLineAndChar.character); + const indentationStr = sourceFile.text.substr(lineStart, posLineAndChar.character); // TODO: call a helper method instead once PR #4133 gets merged in. const newLine = host.getNewLine ? host.getNewLine() : "\r\n"; @@ -7128,7 +7127,7 @@ namespace ts { // * if the caret was directly in front of the object, then we add an extra line and indentation. const preamble = "/**" + newLine + indentationStr + " * "; - let result = + const result = preamble + newLine + docParams + indentationStr + " */" + @@ -7172,7 +7171,7 @@ namespace ts { case SyntaxKind.ArrowFunction: return (rightHandSide).parameters; case SyntaxKind.ClassExpression: - for (let member of (rightHandSide).members) { + for (const member of (rightHandSide).members) { if (member.kind === SyntaxKind.Constructor) { return (member).parameters; } @@ -7192,15 +7191,15 @@ namespace ts { // anything away. synchronizeHostData(); - let sourceFile = getValidSourceFile(fileName); + const sourceFile = getValidSourceFile(fileName); cancellationToken.throwIfCancellationRequested(); - let fileContents = sourceFile.text; - let result: TodoComment[] = []; + const fileContents = sourceFile.text; + const result: TodoComment[] = []; if (descriptors.length > 0) { - let regExp = getTodoCommentsRegExp(); + const regExp = getTodoCommentsRegExp(); let matchArray: RegExpExecArray; while (matchArray = regExp.exec(fileContents)) { @@ -7223,15 +7222,15 @@ namespace ts { // // i.e. 'undefined' in position 3 above means TODO(jason) didn't match. // "hack" in position 4 means HACK did match. - let firstDescriptorCaptureIndex = 3; + const firstDescriptorCaptureIndex = 3; Debug.assert(matchArray.length === descriptors.length + firstDescriptorCaptureIndex); - let preamble = matchArray[1]; - let matchPosition = matchArray.index + preamble.length; + const preamble = matchArray[1]; + const matchPosition = matchArray.index + preamble.length; // OK, we have found a match in the file. This is only an acceptable match if // it is contained within a comment. - let token = getTokenAtPosition(sourceFile, matchPosition); + const token = getTokenAtPosition(sourceFile, matchPosition); if (!isInsideComment(sourceFile, token, matchPosition)) { continue; } @@ -7250,7 +7249,7 @@ namespace ts { continue; } - let message = matchArray[2]; + const message = matchArray[2]; result.push({ descriptor: descriptor, message: message, @@ -7281,14 +7280,14 @@ namespace ts { // // The following three regexps are used to match the start of the text up to the TODO // comment portion. - let singleLineCommentStart = /(?:\/\/+\s*)/.source; - let multiLineCommentStart = /(?:\/\*+\s*)/.source; - let anyNumberOfSpacesAndAsterixesAtStartOfLine = /(?:^(?:\s|\*)*)/.source; + const singleLineCommentStart = /(?:\/\/+\s*)/.source; + const multiLineCommentStart = /(?:\/\*+\s*)/.source; + const anyNumberOfSpacesAndAsterixesAtStartOfLine = /(?:^(?:\s|\*)*)/.source; // Match any of the above three TODO comment start regexps. // Note that the outermost group *is* a capture group. We want to capture the preamble // so that we can determine the starting position of the TODO comment match. - let preamble = "(" + anyNumberOfSpacesAndAsterixesAtStartOfLine + "|" + singleLineCommentStart + "|" + multiLineCommentStart + ")"; + const preamble = "(" + anyNumberOfSpacesAndAsterixesAtStartOfLine + "|" + singleLineCommentStart + "|" + multiLineCommentStart + ")"; // Takes the descriptors and forms a regexp that matches them as if they were literals. // For example, if the descriptors are "TODO(jason)" and "HACK", then this will be: @@ -7298,17 +7297,17 @@ namespace ts { // Note that the outermost group is *not* a capture group, but the innermost groups // *are* capture groups. By capturing the inner literals we can determine after // matching which descriptor we are dealing with. - let literals = "(?:" + map(descriptors, d => "(" + escapeRegExp(d.text) + ")").join("|") + ")"; + const literals = "(?:" + map(descriptors, d => "(" + escapeRegExp(d.text) + ")").join("|") + ")"; // After matching a descriptor literal, the following regexp matches the rest of the // text up to the end of the line (or */). - let endOfLineOrEndOfComment = /(?:$|\*\/)/.source - let messageRemainder = /(?:.*?)/.source + const endOfLineOrEndOfComment = /(?:$|\*\/)/.source; + const messageRemainder = /(?:.*?)/.source; // This is the portion of the match we'll return as part of the TODO comment result. We // match the literal portion up to the end of the line or end of comment. - let messagePortion = "(" + literals + messageRemainder + ")"; - let regExpString = preamble + messagePortion + endOfLineOrEndOfComment; + const messagePortion = "(" + literals + messageRemainder + ")"; + const regExpString = preamble + messagePortion + endOfLineOrEndOfComment; // The final regexp will look like this: // /((?:\/\/+\s*)|(?:\/\*+\s*)|(?:^(?:\s|\*)*))((?:(TODO\(jason\))|(HACK))(?:.*?))(?:$|\*\/)/gim @@ -7334,40 +7333,40 @@ namespace ts { function getRenameInfo(fileName: string, position: number): RenameInfo { synchronizeHostData(); - let sourceFile = getValidSourceFile(fileName); - let typeChecker = program.getTypeChecker(); + const sourceFile = getValidSourceFile(fileName); + const typeChecker = program.getTypeChecker(); - let node = getTouchingWord(sourceFile, position); + const node = getTouchingWord(sourceFile, position); // Can only rename an identifier. if (node && node.kind === SyntaxKind.Identifier) { - let symbol = typeChecker.getSymbolAtLocation(node); + const symbol = typeChecker.getSymbolAtLocation(node); // Only allow a symbol to be renamed if it actually has at least one declaration. if (symbol) { - let declarations = symbol.getDeclarations(); + const declarations = symbol.getDeclarations(); if (declarations && declarations.length > 0) { // Disallow rename for elements that are defined in the standard TypeScript library. - let defaultLibFileName = host.getDefaultLibFileName(host.getCompilationSettings()); + const defaultLibFileName = host.getDefaultLibFileName(host.getCompilationSettings()); if (defaultLibFileName) { - for (let current of declarations) { - let sourceFile = current.getSourceFile(); - var canonicalName = getCanonicalFileName(ts.normalizePath(sourceFile.fileName)); + for (const current of declarations) { + const sourceFile = current.getSourceFile(); + const canonicalName = getCanonicalFileName(ts.normalizePath(sourceFile.fileName)); if (sourceFile && getCanonicalFileName(ts.normalizePath(sourceFile.fileName)) === getCanonicalFileName(ts.normalizePath(defaultLibFileName))) { return getRenameInfoError(getLocaleSpecificMessage(Diagnostics.You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library)); } } } - let displayName = stripQuotes(getDeclaredName(typeChecker, symbol, node)); - let kind = getSymbolKind(symbol, node); + const displayName = stripQuotes(getDeclaredName(typeChecker, symbol, node)); + const kind = getSymbolKind(symbol, node); if (kind) { return { canRename: true, - localizedErrorMessage: undefined, + kind, displayName, + localizedErrorMessage: undefined, fullDisplayName: typeChecker.getFullyQualifiedName(symbol), - kind: kind, kindModifiers: getSymbolModifiers(symbol), triggerSpan: createTextSpan(node.getStart(), node.getWidth()) }; @@ -7434,14 +7433,14 @@ namespace ts { /* @internal */ export function getNameTable(sourceFile: SourceFile): Map { if (!sourceFile.nameTable) { - initializeNameTable(sourceFile) + initializeNameTable(sourceFile); } return sourceFile.nameTable; } function initializeNameTable(sourceFile: SourceFile): void { - let nameTable: Map = {}; + const nameTable: Map = {}; walk(sourceFile); sourceFile.nameTable = nameTable; @@ -7479,13 +7478,13 @@ namespace ts { /// Classifier export function createClassifier(): Classifier { - let scanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ false); + const scanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ false); /// We do not have a full parser support to know when we should parse a regex or not /// If we consider every slash token to be a regex, we could be missing cases like "1/2/3", where /// we have a series of divide operator. this list allows us to be more accurate by ruling out /// locations where a regexp cannot exist. - let noRegexTable: boolean[] = []; + const noRegexTable: boolean[] = []; noRegexTable[SyntaxKind.Identifier] = true; noRegexTable[SyntaxKind.StringLiteral] = true; noRegexTable[SyntaxKind.NumericLiteral] = true; @@ -7519,7 +7518,7 @@ namespace ts { // // Where on the second line, you will get the 'return' keyword, // a string literal, and a template end consisting of '} } `'. - let templateStack: SyntaxKind[] = []; + const templateStack: SyntaxKind[] = []; /** Returns true if 'keyword2' can legally follow 'keyword1' in any language construct. */ function canFollow(keyword1: SyntaxKind, keyword2: SyntaxKind) { @@ -7545,18 +7544,18 @@ namespace ts { } function convertClassifications(classifications: Classifications, text: string): ClassificationResult { - let entries: ClassificationInfo[] = []; - let dense = classifications.spans; + const entries: ClassificationInfo[] = []; + const dense = classifications.spans; let lastEnd = 0; for (let i = 0, n = dense.length; i < n; i += 3) { - let start = dense[i]; - let length = dense[i + 1]; - let type = dense[i + 2]; + const start = dense[i]; + const length = dense[i + 1]; + const type = dense[i + 2]; // Make a whitespace entry between the last item and this one. if (lastEnd >= 0) { - let whitespaceLength = start - lastEnd; + const whitespaceLength = start - lastEnd; if (whitespaceLength > 0) { entries.push({ length: whitespaceLength, classification: TokenClass.Whitespace }); } @@ -7566,7 +7565,7 @@ namespace ts { lastEnd = start + length; } - let whitespaceLength = text.length - lastEnd; + const whitespaceLength = text.length - lastEnd; if (whitespaceLength > 0) { entries.push({ length: whitespaceLength, classification: TokenClass.Whitespace }); } @@ -7620,7 +7619,7 @@ namespace ts { // (and a newline). That way when we lex we'll think we're still in a multiline comment. switch (lexState) { case EndOfLineState.InDoubleQuoteStringLiteral: - text = '"\\\n' + text; + text = "\"\\\n" + text; offset = 3; break; case EndOfLineState.InSingleQuoteStringLiteral: @@ -7646,7 +7645,7 @@ namespace ts { scanner.setText(text); - let result: Classifications = { + const result: Classifications = { endOfLineState: EndOfLineState.None, spans: [] }; @@ -7728,7 +7727,7 @@ namespace ts { // If we don't have anything on the template stack, // then we aren't trying to keep track of a previously scanned template head. if (templateStack.length > 0) { - let lastTemplateStackToken = lastOrUndefined(templateStack); + const lastTemplateStackToken = lastOrUndefined(templateStack); if (lastTemplateStackToken === SyntaxKind.TemplateHead) { token = scanner.reScanTemplateToken(); @@ -7758,17 +7757,17 @@ namespace ts { return result; function processToken(): void { - let start = scanner.getTokenPos(); - let end = scanner.getTextPos(); + const start = scanner.getTokenPos(); + const end = scanner.getTextPos(); addResult(start, end, classFromKind(token)); if (end >= text.length) { if (token === SyntaxKind.StringLiteral || token === SyntaxKind.StringLiteralType) { // Check to see if we finished up on a multiline string literal. - let tokenText = scanner.getTokenText(); + const tokenText = scanner.getTokenText(); if (scanner.isUnterminated()) { - let lastCharIndex = tokenText.length - 1; + const lastCharIndex = tokenText.length - 1; let numBackslashes = 0; while (tokenText.charCodeAt(lastCharIndex - numBackslashes) === CharacterCodes.backslash) { @@ -7777,7 +7776,7 @@ namespace ts { // If we have an odd number of backslashes, then the multiline string is unclosed if (numBackslashes & 1) { - let quoteChar = tokenText.charCodeAt(0); + const quoteChar = tokenText.charCodeAt(0); result.endOfLineState = quoteChar === CharacterCodes.doubleQuote ? EndOfLineState.InDoubleQuoteStringLiteral : EndOfLineState.InSingleQuoteStringLiteral; @@ -7826,7 +7825,7 @@ namespace ts { // relative to the original text. start -= offset; end -= offset; - let length = end - start; + const length = end - start; if (length > 0) { result.spans.push(start); @@ -7941,7 +7940,7 @@ namespace ts { } /// getDefaultLibraryFilePath - declare let __dirname: string; + declare const __dirname: string; /** * Get the path of the default library files (lib.d.ts) as distributed with the typescript From 5cbf17d989d6f746de480631fa6b05d43d1afd8f Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Mon, 14 Dec 2015 14:16:31 -0800 Subject: [PATCH 39/79] Added tests. --- .../stringLiteralTypesAsTags02.ts | 42 +++++++++++++++++ .../stringLiteralTypesAsTags03.ts | 46 +++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 tests/cases/conformance/types/stringLiteral/stringLiteralTypesAsTags02.ts create mode 100644 tests/cases/conformance/types/stringLiteral/stringLiteralTypesAsTags03.ts diff --git a/tests/cases/conformance/types/stringLiteral/stringLiteralTypesAsTags02.ts b/tests/cases/conformance/types/stringLiteral/stringLiteralTypesAsTags02.ts new file mode 100644 index 00000000000..9fdc942a3f2 --- /dev/null +++ b/tests/cases/conformance/types/stringLiteral/stringLiteralTypesAsTags02.ts @@ -0,0 +1,42 @@ +// @declaration: true + +type Kind = "A" | "B" + +interface Entity { + kind: Kind; +} + +interface A extends Entity { + kind: "A"; + a: number; +} + +interface B extends Entity { + kind: "B"; + b: string; +} + +function hasKind(entity: Entity, kind: "A"): entity is A; +function hasKind(entity: Entity, kind: "B"): entity is B; +function hasKind(entity: Entity, kind: Kind): entity is (A | B) { + return entity.kind === kind; +} + +let x: A = { + kind: "A", + a: 100, +} + +if (hasKind(x, "A")) { + let a = x; +} +else { + let b = x; +} + +if (!hasKind(x, "B")) { + let c = x; +} +else { + let d = x; +} \ No newline at end of file diff --git a/tests/cases/conformance/types/stringLiteral/stringLiteralTypesAsTags03.ts b/tests/cases/conformance/types/stringLiteral/stringLiteralTypesAsTags03.ts new file mode 100644 index 00000000000..96011d27255 --- /dev/null +++ b/tests/cases/conformance/types/stringLiteral/stringLiteralTypesAsTags03.ts @@ -0,0 +1,46 @@ +// @declaration: true + +type Kind = "A" | "B" + +interface Entity { + kind: Kind; +} + +interface A extends Entity { + kind: "A"; + a: number; +} + +interface B extends Entity { + kind: "B"; + b: string; +} + +// Currently (2015-12-14), we write '"A" | "A"' and '"B" | "B"' to avoid +// interpreting respective overloads as "specialized" signatures. +// That way, we can avoid the need to look for a compatible overload +// signature and simply check compatibility with the implementation. +function hasKind(entity: Entity, kind: "A" | "A"): entity is A; +function hasKind(entity: Entity, kind: "B" | "B"): entity is B; +function hasKind(entity: Entity, kind: Kind): entity is Entity { + return entity.kind === kind; +} + +let x: A = { + kind: "A", + a: 100, +} + +if (hasKind(x, "A")) { + let a = x; +} +else { + let b = x; +} + +if (!hasKind(x, "B")) { + let c = x; +} +else { + let d = x; +} \ No newline at end of file From 2efa69773d5e7fb208e2a03e52758189e058d266 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Mon, 14 Dec 2015 14:24:55 -0800 Subject: [PATCH 40/79] Accepted baselines. --- .../stringLiteralTypesAsTags02.errors.txt | 50 ++++++++ .../reference/stringLiteralTypesAsTags02.js | 81 ++++++++++++ .../reference/stringLiteralTypesAsTags03.js | 85 +++++++++++++ .../stringLiteralTypesAsTags03.symbols | 109 ++++++++++++++++ .../stringLiteralTypesAsTags03.types | 118 ++++++++++++++++++ 5 files changed, 443 insertions(+) create mode 100644 tests/baselines/reference/stringLiteralTypesAsTags02.errors.txt create mode 100644 tests/baselines/reference/stringLiteralTypesAsTags02.js create mode 100644 tests/baselines/reference/stringLiteralTypesAsTags03.js create mode 100644 tests/baselines/reference/stringLiteralTypesAsTags03.symbols create mode 100644 tests/baselines/reference/stringLiteralTypesAsTags03.types diff --git a/tests/baselines/reference/stringLiteralTypesAsTags02.errors.txt b/tests/baselines/reference/stringLiteralTypesAsTags02.errors.txt new file mode 100644 index 00000000000..077113632d0 --- /dev/null +++ b/tests/baselines/reference/stringLiteralTypesAsTags02.errors.txt @@ -0,0 +1,50 @@ +tests/cases/conformance/types/stringLiteral/stringLiteralTypesAsTags02.ts(18,10): error TS2382: Specialized overload signature is not assignable to any non-specialized signature. +tests/cases/conformance/types/stringLiteral/stringLiteralTypesAsTags02.ts(19,10): error TS2382: Specialized overload signature is not assignable to any non-specialized signature. + + +==== tests/cases/conformance/types/stringLiteral/stringLiteralTypesAsTags02.ts (2 errors) ==== + + type Kind = "A" | "B" + + interface Entity { + kind: Kind; + } + + interface A extends Entity { + kind: "A"; + a: number; + } + + interface B extends Entity { + kind: "B"; + b: string; + } + + function hasKind(entity: Entity, kind: "A"): entity is A; + ~~~~~~~ +!!! error TS2382: Specialized overload signature is not assignable to any non-specialized signature. + function hasKind(entity: Entity, kind: "B"): entity is B; + ~~~~~~~ +!!! error TS2382: Specialized overload signature is not assignable to any non-specialized signature. + function hasKind(entity: Entity, kind: Kind): entity is (A | B) { + return entity.kind === kind; + } + + let x: A = { + kind: "A", + a: 100, + } + + if (hasKind(x, "A")) { + let a = x; + } + else { + let b = x; + } + + if (!hasKind(x, "B")) { + let c = x; + } + else { + let d = x; + } \ No newline at end of file diff --git a/tests/baselines/reference/stringLiteralTypesAsTags02.js b/tests/baselines/reference/stringLiteralTypesAsTags02.js new file mode 100644 index 00000000000..e83f1ad46ee --- /dev/null +++ b/tests/baselines/reference/stringLiteralTypesAsTags02.js @@ -0,0 +1,81 @@ +//// [stringLiteralTypesAsTags02.ts] + +type Kind = "A" | "B" + +interface Entity { + kind: Kind; +} + +interface A extends Entity { + kind: "A"; + a: number; +} + +interface B extends Entity { + kind: "B"; + b: string; +} + +function hasKind(entity: Entity, kind: "A"): entity is A; +function hasKind(entity: Entity, kind: "B"): entity is B; +function hasKind(entity: Entity, kind: Kind): entity is (A | B) { + return entity.kind === kind; +} + +let x: A = { + kind: "A", + a: 100, +} + +if (hasKind(x, "A")) { + let a = x; +} +else { + let b = x; +} + +if (!hasKind(x, "B")) { + let c = x; +} +else { + let d = x; +} + +//// [stringLiteralTypesAsTags02.js] +function hasKind(entity, kind) { + return entity.kind === kind; +} +var x = { + kind: "A", + a: 100 +}; +if (hasKind(x, "A")) { + var a = x; +} +else { + var b = x; +} +if (!hasKind(x, "B")) { + var c = x; +} +else { + var d = x; +} + + +//// [stringLiteralTypesAsTags02.d.ts] +declare type Kind = "A" | "B"; +interface Entity { + kind: Kind; +} +interface A extends Entity { + kind: "A"; + a: number; +} +interface B extends Entity { + kind: "B"; + b: string; +} +declare function hasKind(entity: Entity, kind: "A"): entity is A; +declare function hasKind(entity: Entity, kind: "B"): entity is B; +declare let x: A; diff --git a/tests/baselines/reference/stringLiteralTypesAsTags03.js b/tests/baselines/reference/stringLiteralTypesAsTags03.js new file mode 100644 index 00000000000..bb2ed56040e --- /dev/null +++ b/tests/baselines/reference/stringLiteralTypesAsTags03.js @@ -0,0 +1,85 @@ +//// [stringLiteralTypesAsTags03.ts] + +type Kind = "A" | "B" + +interface Entity { + kind: Kind; +} + +interface A extends Entity { + kind: "A"; + a: number; +} + +interface B extends Entity { + kind: "B"; + b: string; +} + +// Currently (2015-12-14), we write '"A" | "A"' and '"B" | "B"' to avoid +// interpreting respective overloads as "specialized" signatures. +// That way, we can avoid the need to look for a compatible overload +// signature and simply check compatibility with the implementation. +function hasKind(entity: Entity, kind: "A" | "A"): entity is A; +function hasKind(entity: Entity, kind: "B" | "B"): entity is B; +function hasKind(entity: Entity, kind: Kind): entity is Entity { + return entity.kind === kind; +} + +let x: A = { + kind: "A", + a: 100, +} + +if (hasKind(x, "A")) { + let a = x; +} +else { + let b = x; +} + +if (!hasKind(x, "B")) { + let c = x; +} +else { + let d = x; +} + +//// [stringLiteralTypesAsTags03.js] +function hasKind(entity, kind) { + return entity.kind === kind; +} +var x = { + kind: "A", + a: 100 +}; +if (hasKind(x, "A")) { + var a = x; +} +else { + var b = x; +} +if (!hasKind(x, "B")) { + var c = x; +} +else { + var d = x; +} + + +//// [stringLiteralTypesAsTags03.d.ts] +declare type Kind = "A" | "B"; +interface Entity { + kind: Kind; +} +interface A extends Entity { + kind: "A"; + a: number; +} +interface B extends Entity { + kind: "B"; + b: string; +} +declare function hasKind(entity: Entity, kind: "A" | "A"): entity is A; +declare function hasKind(entity: Entity, kind: "B" | "B"): entity is B; +declare let x: A; diff --git a/tests/baselines/reference/stringLiteralTypesAsTags03.symbols b/tests/baselines/reference/stringLiteralTypesAsTags03.symbols new file mode 100644 index 00000000000..3694daf8e00 --- /dev/null +++ b/tests/baselines/reference/stringLiteralTypesAsTags03.symbols @@ -0,0 +1,109 @@ +=== tests/cases/conformance/types/stringLiteral/stringLiteralTypesAsTags03.ts === + +type Kind = "A" | "B" +>Kind : Symbol(Kind, Decl(stringLiteralTypesAsTags03.ts, 0, 0)) + +interface Entity { +>Entity : Symbol(Entity, Decl(stringLiteralTypesAsTags03.ts, 1, 21)) + + kind: Kind; +>kind : Symbol(kind, Decl(stringLiteralTypesAsTags03.ts, 3, 18)) +>Kind : Symbol(Kind, Decl(stringLiteralTypesAsTags03.ts, 0, 0)) +} + +interface A extends Entity { +>A : Symbol(A, Decl(stringLiteralTypesAsTags03.ts, 5, 1)) +>Entity : Symbol(Entity, Decl(stringLiteralTypesAsTags03.ts, 1, 21)) + + kind: "A"; +>kind : Symbol(kind, Decl(stringLiteralTypesAsTags03.ts, 7, 28)) + + a: number; +>a : Symbol(a, Decl(stringLiteralTypesAsTags03.ts, 8, 14)) +} + +interface B extends Entity { +>B : Symbol(B, Decl(stringLiteralTypesAsTags03.ts, 10, 1)) +>Entity : Symbol(Entity, Decl(stringLiteralTypesAsTags03.ts, 1, 21)) + + kind: "B"; +>kind : Symbol(kind, Decl(stringLiteralTypesAsTags03.ts, 12, 28)) + + b: string; +>b : Symbol(b, Decl(stringLiteralTypesAsTags03.ts, 13, 14)) +} + +// Currently (2015-12-14), we write '"A" | "A"' and '"B" | "B"' to avoid +// interpreting respective overloads as "specialized" signatures. +// That way, we can avoid the need to look for a compatible overload +// signature and simply check compatibility with the implementation. +function hasKind(entity: Entity, kind: "A" | "A"): entity is A; +>hasKind : Symbol(hasKind, Decl(stringLiteralTypesAsTags03.ts, 15, 1), Decl(stringLiteralTypesAsTags03.ts, 21, 63), Decl(stringLiteralTypesAsTags03.ts, 22, 63)) +>entity : Symbol(entity, Decl(stringLiteralTypesAsTags03.ts, 21, 17)) +>Entity : Symbol(Entity, Decl(stringLiteralTypesAsTags03.ts, 1, 21)) +>kind : Symbol(kind, Decl(stringLiteralTypesAsTags03.ts, 21, 32)) +>entity : Symbol(entity, Decl(stringLiteralTypesAsTags03.ts, 21, 17)) +>A : Symbol(A, Decl(stringLiteralTypesAsTags03.ts, 5, 1)) + +function hasKind(entity: Entity, kind: "B" | "B"): entity is B; +>hasKind : Symbol(hasKind, Decl(stringLiteralTypesAsTags03.ts, 15, 1), Decl(stringLiteralTypesAsTags03.ts, 21, 63), Decl(stringLiteralTypesAsTags03.ts, 22, 63)) +>entity : Symbol(entity, Decl(stringLiteralTypesAsTags03.ts, 22, 17)) +>Entity : Symbol(Entity, Decl(stringLiteralTypesAsTags03.ts, 1, 21)) +>kind : Symbol(kind, Decl(stringLiteralTypesAsTags03.ts, 22, 32)) +>entity : Symbol(entity, Decl(stringLiteralTypesAsTags03.ts, 22, 17)) +>B : Symbol(B, Decl(stringLiteralTypesAsTags03.ts, 10, 1)) + +function hasKind(entity: Entity, kind: Kind): entity is Entity { +>hasKind : Symbol(hasKind, Decl(stringLiteralTypesAsTags03.ts, 15, 1), Decl(stringLiteralTypesAsTags03.ts, 21, 63), Decl(stringLiteralTypesAsTags03.ts, 22, 63)) +>entity : Symbol(entity, Decl(stringLiteralTypesAsTags03.ts, 23, 17)) +>Entity : Symbol(Entity, Decl(stringLiteralTypesAsTags03.ts, 1, 21)) +>kind : Symbol(kind, Decl(stringLiteralTypesAsTags03.ts, 23, 32)) +>Kind : Symbol(Kind, Decl(stringLiteralTypesAsTags03.ts, 0, 0)) +>entity : Symbol(entity, Decl(stringLiteralTypesAsTags03.ts, 23, 17)) +>Entity : Symbol(Entity, Decl(stringLiteralTypesAsTags03.ts, 1, 21)) + + return entity.kind === kind; +>entity.kind : Symbol(Entity.kind, Decl(stringLiteralTypesAsTags03.ts, 3, 18)) +>entity : Symbol(entity, Decl(stringLiteralTypesAsTags03.ts, 23, 17)) +>kind : Symbol(Entity.kind, Decl(stringLiteralTypesAsTags03.ts, 3, 18)) +>kind : Symbol(kind, Decl(stringLiteralTypesAsTags03.ts, 23, 32)) +} + +let x: A = { +>x : Symbol(x, Decl(stringLiteralTypesAsTags03.ts, 27, 3)) +>A : Symbol(A, Decl(stringLiteralTypesAsTags03.ts, 5, 1)) + + kind: "A", +>kind : Symbol(kind, Decl(stringLiteralTypesAsTags03.ts, 27, 12)) + + a: 100, +>a : Symbol(a, Decl(stringLiteralTypesAsTags03.ts, 28, 14)) +} + +if (hasKind(x, "A")) { +>hasKind : Symbol(hasKind, Decl(stringLiteralTypesAsTags03.ts, 15, 1), Decl(stringLiteralTypesAsTags03.ts, 21, 63), Decl(stringLiteralTypesAsTags03.ts, 22, 63)) +>x : Symbol(x, Decl(stringLiteralTypesAsTags03.ts, 27, 3)) + + let a = x; +>a : Symbol(a, Decl(stringLiteralTypesAsTags03.ts, 33, 7)) +>x : Symbol(x, Decl(stringLiteralTypesAsTags03.ts, 27, 3)) +} +else { + let b = x; +>b : Symbol(b, Decl(stringLiteralTypesAsTags03.ts, 36, 7)) +>x : Symbol(x, Decl(stringLiteralTypesAsTags03.ts, 27, 3)) +} + +if (!hasKind(x, "B")) { +>hasKind : Symbol(hasKind, Decl(stringLiteralTypesAsTags03.ts, 15, 1), Decl(stringLiteralTypesAsTags03.ts, 21, 63), Decl(stringLiteralTypesAsTags03.ts, 22, 63)) +>x : Symbol(x, Decl(stringLiteralTypesAsTags03.ts, 27, 3)) + + let c = x; +>c : Symbol(c, Decl(stringLiteralTypesAsTags03.ts, 40, 7)) +>x : Symbol(x, Decl(stringLiteralTypesAsTags03.ts, 27, 3)) +} +else { + let d = x; +>d : Symbol(d, Decl(stringLiteralTypesAsTags03.ts, 43, 7)) +>x : Symbol(x, Decl(stringLiteralTypesAsTags03.ts, 27, 3)) +} diff --git a/tests/baselines/reference/stringLiteralTypesAsTags03.types b/tests/baselines/reference/stringLiteralTypesAsTags03.types new file mode 100644 index 00000000000..a1d83a1c058 --- /dev/null +++ b/tests/baselines/reference/stringLiteralTypesAsTags03.types @@ -0,0 +1,118 @@ +=== tests/cases/conformance/types/stringLiteral/stringLiteralTypesAsTags03.ts === + +type Kind = "A" | "B" +>Kind : "A" | "B" + +interface Entity { +>Entity : Entity + + kind: Kind; +>kind : "A" | "B" +>Kind : "A" | "B" +} + +interface A extends Entity { +>A : A +>Entity : Entity + + kind: "A"; +>kind : "A" + + a: number; +>a : number +} + +interface B extends Entity { +>B : B +>Entity : Entity + + kind: "B"; +>kind : "B" + + b: string; +>b : string +} + +// Currently (2015-12-14), we write '"A" | "A"' and '"B" | "B"' to avoid +// interpreting respective overloads as "specialized" signatures. +// That way, we can avoid the need to look for a compatible overload +// signature and simply check compatibility with the implementation. +function hasKind(entity: Entity, kind: "A" | "A"): entity is A; +>hasKind : { (entity: Entity, kind: "A"): entity is A; (entity: Entity, kind: "B"): entity is B; } +>entity : Entity +>Entity : Entity +>kind : "A" +>entity : any +>A : A + +function hasKind(entity: Entity, kind: "B" | "B"): entity is B; +>hasKind : { (entity: Entity, kind: "A"): entity is A; (entity: Entity, kind: "B"): entity is B; } +>entity : Entity +>Entity : Entity +>kind : "B" +>entity : any +>B : B + +function hasKind(entity: Entity, kind: Kind): entity is Entity { +>hasKind : { (entity: Entity, kind: "A"): entity is A; (entity: Entity, kind: "B"): entity is B; } +>entity : Entity +>Entity : Entity +>kind : "A" | "B" +>Kind : "A" | "B" +>entity : any +>Entity : Entity + + return entity.kind === kind; +>entity.kind === kind : boolean +>entity.kind : "A" | "B" +>entity : Entity +>kind : "A" | "B" +>kind : "A" | "B" +} + +let x: A = { +>x : A +>A : A +>{ kind: "A", a: 100,} : { kind: "A"; a: number; } + + kind: "A", +>kind : "A" +>"A" : "A" + + a: 100, +>a : number +>100 : number +} + +if (hasKind(x, "A")) { +>hasKind(x, "A") : entity is A +>hasKind : { (entity: Entity, kind: "A"): entity is A; (entity: Entity, kind: "B"): entity is B; } +>x : A +>"A" : "A" + + let a = x; +>a : A +>x : A +} +else { + let b = x; +>b : A +>x : A +} + +if (!hasKind(x, "B")) { +>!hasKind(x, "B") : boolean +>hasKind(x, "B") : entity is B +>hasKind : { (entity: Entity, kind: "A"): entity is A; (entity: Entity, kind: "B"): entity is B; } +>x : A +>"B" : "B" + + let c = x; +>c : A +>x : A +} +else { + let d = x; +>d : A +>x : A +} From c0ff7f77a250e41a744dc56f7133c5808af1875e Mon Sep 17 00:00:00 2001 From: Yui T Date: Mon, 14 Dec 2015 14:35:27 -0800 Subject: [PATCH 41/79] Fix build error --- src/services/services.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/services.ts b/src/services/services.ts index 092f987eb5a..4109a4eb345 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1948,7 +1948,7 @@ namespace ts { return sourceFile; } - export const disableIncrementalParsing = false; + export let disableIncrementalParsing = false; export function updateLanguageServiceSourceFile(sourceFile: SourceFile, scriptSnapshot: IScriptSnapshot, version: string, textChangeRange: TextChangeRange, aggressiveChecks?: boolean): SourceFile { // If we were given a text change range, and our version or open-ness changed, then From 023e375835886c77278328663c79bf010f8f836e Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Mon, 14 Dec 2015 16:44:26 -0800 Subject: [PATCH 42/79] Properly handle multiply-declared optional properties in JSX attr. type Fixes #6029 --- src/compiler/checker.ts | 15 +++++-- src/compiler/diagnosticMessages.json | 2 +- .../tsxAttributeResolution11.errors.txt | 33 +++++++++++++++ .../reference/tsxAttributeResolution11.js | 41 +++++++++++++++++++ .../jsx/tsxAttributeResolution11.tsx | 29 +++++++++++++ 5 files changed, 115 insertions(+), 5 deletions(-) create mode 100644 tests/baselines/reference/tsxAttributeResolution11.errors.txt create mode 100644 tests/baselines/reference/tsxAttributeResolution11.js create mode 100644 tests/cases/conformance/jsx/tsxAttributeResolution11.tsx diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 78a7ccffbdd..09760b6b1e5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3766,11 +3766,13 @@ namespace ts { function createUnionOrIntersectionProperty(containingType: UnionOrIntersectionType, name: string): Symbol { const types = containingType.types; let props: Symbol[]; + let isOptional = !!(containingType.flags & TypeFlags.Intersection); for (const current of types) { const type = getApparentType(current); if (type !== unknownType) { const prop = getPropertyOfType(type, name); if (prop && !(getDeclarationFlagsFromSymbol(prop) & (NodeFlags.Private | NodeFlags.Protected))) { + isOptional = isOptional && !!(prop.flags & SymbolFlags.Optional); if (!props) { props = [prop]; } @@ -3798,7 +3800,12 @@ namespace ts { } propTypes.push(getTypeOfSymbol(prop)); } - const result = createSymbol(SymbolFlags.Property | SymbolFlags.Transient | SymbolFlags.SyntheticProperty, name); + const result = createSymbol( + SymbolFlags.Property | + SymbolFlags.Transient | + SymbolFlags.SyntheticProperty | + (isOptional ? SymbolFlags.Optional : SymbolFlags.None), + name); result.containingType = containingType; result.declarations = declarations; result.type = containingType.flags & TypeFlags.Union ? getUnionType(propTypes) : getIntersectionType(propTypes); @@ -8232,9 +8239,9 @@ namespace ts { // Props is of type 'any' or unknown return links.resolvedJsxType = attributesType; } - else if (!(attributesType.flags & TypeFlags.ObjectType)) { - // Props is not an object type - error(node.tagName, Diagnostics.JSX_element_attributes_type_0_must_be_an_object_type, typeToString(attributesType)); + else if (attributesType.flags & TypeFlags.Union) { + // Props cannot be a union type + error(node.tagName, Diagnostics.JSX_element_attributes_type_0_may_not_be_a_union_type, typeToString(attributesType)); return links.resolvedJsxType = anyType; } else { diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 54123808932..1a2575e9da6 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1691,7 +1691,7 @@ "category": "Error", "code": 2528 }, - "JSX element attributes type '{0}' must be an object type.": { + "JSX element attributes type '{0}' may not be a union type.": { "category": "Error", "code": 2600 }, diff --git a/tests/baselines/reference/tsxAttributeResolution11.errors.txt b/tests/baselines/reference/tsxAttributeResolution11.errors.txt new file mode 100644 index 00000000000..b043897d50d --- /dev/null +++ b/tests/baselines/reference/tsxAttributeResolution11.errors.txt @@ -0,0 +1,33 @@ +tests/cases/conformance/jsx/file.tsx(11,22): error TS2339: Property 'bar' does not exist on type 'IntrinsicAttributes & { ref?: string; }'. + + +==== tests/cases/conformance/jsx/react.d.ts (0 errors) ==== + + declare module JSX { + interface Element { } + interface IntrinsicElements { + } + interface ElementAttributesProperty { + props; + } + interface IntrinsicAttributes { + ref?: string; + } + } + +==== tests/cases/conformance/jsx/file.tsx (1 errors) ==== + class MyComponent { + render() { + } + + props: { + ref?: string; + } + } + + // Should be an OK + var x = ; + ~~~ +!!! error TS2339: Property 'bar' does not exist on type 'IntrinsicAttributes & { ref?: string; }'. + + \ No newline at end of file diff --git a/tests/baselines/reference/tsxAttributeResolution11.js b/tests/baselines/reference/tsxAttributeResolution11.js new file mode 100644 index 00000000000..03b843c209a --- /dev/null +++ b/tests/baselines/reference/tsxAttributeResolution11.js @@ -0,0 +1,41 @@ +//// [tests/cases/conformance/jsx/tsxAttributeResolution11.tsx] //// + +//// [react.d.ts] + +declare module JSX { + interface Element { } + interface IntrinsicElements { + } + interface ElementAttributesProperty { + props; + } + interface IntrinsicAttributes { + ref?: string; + } +} + +//// [file.tsx] +class MyComponent { + render() { + } + + props: { + ref?: string; + } +} + +// Should be an OK +var x = ; + + + +//// [file.jsx] +var MyComponent = (function () { + function MyComponent() { + } + MyComponent.prototype.render = function () { + }; + return MyComponent; +}()); +// Should be an OK +var x = ; diff --git a/tests/cases/conformance/jsx/tsxAttributeResolution11.tsx b/tests/cases/conformance/jsx/tsxAttributeResolution11.tsx new file mode 100644 index 00000000000..fdff3c36fc7 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxAttributeResolution11.tsx @@ -0,0 +1,29 @@ +//@jsx: preserve +//@module: amd + +//@filename: react.d.ts +declare module JSX { + interface Element { } + interface IntrinsicElements { + } + interface ElementAttributesProperty { + props; + } + interface IntrinsicAttributes { + ref?: string; + } +} + +//@filename: file.tsx +class MyComponent { + render() { + } + + props: { + ref?: string; + } +} + +// Should be an OK +var x = ; + From ec95f9955af6507bba7b572ce913e48fd9639c94 Mon Sep 17 00:00:00 2001 From: Yui T Date: Tue, 15 Dec 2015 10:04:30 -0800 Subject: [PATCH 43/79] Fix linting issue --- Jakefile.js | 3 +- src/services/services.ts | 1073 +++++++++++++++++++------------------- 2 files changed, 538 insertions(+), 538 deletions(-) diff --git a/Jakefile.js b/Jakefile.js index beb16d2886f..91bd805a27b 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -924,7 +924,8 @@ function lintFileAsync(options, path, cb) { var lintTargets = compilerSources .concat(harnessCoreSources) .concat(serverCoreSources) - .concat(scriptSources); + .concat(scriptSources) + .concat([path.join(servicesDirectory,"services.ts")]); desc("Runs tslint on the compiler sources"); task("lint", ["build-rules"], function() { diff --git a/src/services/services.ts b/src/services/services.ts index a9dda549ead..8f9028486aa 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -12,7 +12,7 @@ namespace ts { /** The version of the language service API */ - export let servicesVersion = "0.4" + export const servicesVersion = "0.4"; export interface Node { getSourceFile(): SourceFile; @@ -48,7 +48,7 @@ namespace ts { getConstructSignatures(): Signature[]; getStringIndexType(): Type; getNumberIndexType(): Type; - getBaseTypes(): ObjectType[] + getBaseTypes(): ObjectType[]; } export interface Signature { @@ -97,7 +97,7 @@ namespace ts { dispose?(): void; } - export module ScriptSnapshot { + export namespace ScriptSnapshot { class StringScriptSnapshot implements IScriptSnapshot { constructor(private text: string) { @@ -126,12 +126,12 @@ namespace ts { referencedFiles: FileReference[]; importedFiles: FileReference[]; ambientExternalModules: string[]; - isLibFile: boolean + isLibFile: boolean; } - let scanner: Scanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ true); + const scanner: Scanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ true); - let emptyArray: any[] = []; + const emptyArray: any[] = []; const jsDocTagNames = [ "augments", @@ -174,7 +174,7 @@ namespace ts { let jsDocCompletionEntries: CompletionEntry[]; function createNode(kind: SyntaxKind, pos: number, end: number, flags: NodeFlags, parent?: Node): NodeObject { - let node = new NodeObject(kind, pos, end); + const node = new NodeObject(kind, pos, end); node.flags = flags; node.parent = parent; return node; @@ -235,8 +235,8 @@ namespace ts { private addSyntheticNodes(nodes: Node[], pos: number, end: number): number { scanner.setTextPos(pos); while (pos < end) { - let token = scanner.scan(); - let textPos = scanner.getTextPos(); + const token = scanner.scan(); + const textPos = scanner.getTextPos(); nodes.push(createNode(token, pos, textPos, NodeFlags.Synthetic, this)); pos = textPos; } @@ -244,13 +244,11 @@ namespace ts { } private createSyntaxList(nodes: NodeArray): Node { - let list = createNode(SyntaxKind.SyntaxList, nodes.pos, nodes.end, NodeFlags.Synthetic, this); + const list = createNode(SyntaxKind.SyntaxList, nodes.pos, nodes.end, NodeFlags.Synthetic, this); list._children = []; let pos = nodes.pos; - - - for (let node of nodes) { + for (const node of nodes) { if (pos < node.pos) { pos = this.addSyntheticNodes(list._children, pos, node.pos); } @@ -269,14 +267,14 @@ namespace ts { scanner.setText((sourceFile || this.getSourceFile()).text); children = []; let pos = this.pos; - let processNode = (node: Node) => { + const processNode = (node: Node) => { if (pos < node.pos) { pos = this.addSyntheticNodes(children, pos, node.pos); } children.push(node); pos = node.end; }; - let processNodes = (nodes: NodeArray) => { + const processNodes = (nodes: NodeArray) => { if (pos < nodes.pos) { pos = this.addSyntheticNodes(children, pos, nodes.pos); } @@ -308,20 +306,20 @@ namespace ts { } public getFirstToken(sourceFile?: SourceFile): Node { - let children = this.getChildren(sourceFile); + const children = this.getChildren(sourceFile); if (!children.length) { return undefined; } - let child = children[0]; + const child = children[0]; return child.kind < SyntaxKind.FirstNode ? child : child.getFirstToken(sourceFile); } public getLastToken(sourceFile?: SourceFile): Node { - let children = this.getChildren(sourceFile); + const children = this.getChildren(sourceFile); - let child = lastOrUndefined(children); + const child = lastOrUndefined(children); if (!child) { return undefined; } @@ -366,8 +364,8 @@ namespace ts { } function getJsDocCommentsFromDeclarations(declarations: Declaration[], name: string, canUseParsedParamTagComments: boolean) { - let documentationComment = []; - let docComments = getJsDocCommentsSeparatedByNewLines(); + const documentationComment = []; + const docComments = getJsDocCommentsSeparatedByNewLines(); ts.forEach(docComments, docComment => { if (documentationComment.length) { documentationComment.push(lineBreakPart()); @@ -378,22 +376,22 @@ namespace ts { return documentationComment; function getJsDocCommentsSeparatedByNewLines() { - let paramTag = "@param"; - let jsDocCommentParts: SymbolDisplayPart[] = []; + const paramTag = "@param"; + const jsDocCommentParts: SymbolDisplayPart[] = []; ts.forEach(declarations, (declaration, indexOfDeclaration) => { // Make sure we are collecting doc comment from declaration once, // In case of union property there might be same declaration multiple times // which only varies in type parameter - // Eg. let a: Array | Array; a.length + // Eg. const a: Array | Array; a.length // The property length will have two declarations of property length coming // from Array - Array and Array if (indexOf(declarations, declaration) === indexOfDeclaration) { - let sourceFileOfDeclaration = getSourceFileOfNode(declaration); + const sourceFileOfDeclaration = getSourceFileOfNode(declaration); // If it is parameter - try and get the jsDoc comment with @param tag from function declaration's jsDoc comments if (canUseParsedParamTagComments && declaration.kind === SyntaxKind.Parameter) { ts.forEach(getJsDocCommentTextRange(declaration.parent, sourceFileOfDeclaration), jsDocCommentTextRange => { - let cleanedParamJsDocComment = getCleanedParamJsDocComment(jsDocCommentTextRange.pos, jsDocCommentTextRange.end, sourceFileOfDeclaration); + const cleanedParamJsDocComment = getCleanedParamJsDocComment(jsDocCommentTextRange.pos, jsDocCommentTextRange.end, sourceFileOfDeclaration); if (cleanedParamJsDocComment) { addRange(jsDocCommentParts, cleanedParamJsDocComment); } @@ -413,7 +411,7 @@ namespace ts { // Get the cleaned js doc comment text from the declaration ts.forEach(getJsDocCommentTextRange( declaration.kind === SyntaxKind.VariableDeclaration ? declaration.parent.parent : declaration, sourceFileOfDeclaration), jsDocCommentTextRange => { - let cleanedJsDocComment = getCleanedJsDocComment(jsDocCommentTextRange.pos, jsDocCommentTextRange.end, sourceFileOfDeclaration); + const cleanedJsDocComment = getCleanedJsDocComment(jsDocCommentTextRange.pos, jsDocCommentTextRange.end, sourceFileOfDeclaration); if (cleanedJsDocComment) { addRange(jsDocCommentParts, cleanedJsDocComment); } @@ -439,7 +437,7 @@ namespace ts { } for (; pos < end; pos++) { - let ch = sourceFile.text.charCodeAt(pos); + const ch = sourceFile.text.charCodeAt(pos); if (!isWhiteSpace(ch) || isLineBreak(ch)) { // Either found lineBreak or non whiteSpace return pos; @@ -480,7 +478,7 @@ namespace ts { function getCleanedJsDocComment(pos: number, end: number, sourceFile: SourceFile) { let spacesToRemoveAfterAsterisk: number; - let docComments: SymbolDisplayPart[] = []; + const docComments: SymbolDisplayPart[] = []; let blankLineCount = 0; let isInParamTag = false; @@ -491,7 +489,7 @@ namespace ts { // If the comment starts with '*' consume the spaces on this line if (pos < end && sourceFile.text.charCodeAt(pos) === CharacterCodes.asterisk) { - let lineStartPos = pos + 1; + const lineStartPos = pos + 1; pos = consumeWhiteSpacesOnTheLine(pos + 1, end, sourceFile, spacesToRemoveAfterAsterisk); // Set the spaces to remove after asterisk as margin if not already set @@ -505,7 +503,7 @@ namespace ts { // Analyse text on this line while (pos < end && !isLineBreak(sourceFile.text.charCodeAt(pos))) { - let ch = sourceFile.text.charAt(pos); + const ch = sourceFile.text.charAt(pos); if (ch === "@") { // If it is @param tag if (isParamTag(pos, end, sourceFile)) { @@ -544,7 +542,7 @@ namespace ts { function getCleanedParamJsDocComment(pos: number, end: number, sourceFile: SourceFile) { let paramHelpStringMargin: number; - let paramDocComments: SymbolDisplayPart[] = []; + const paramDocComments: SymbolDisplayPart[] = []; while (pos < end) { if (isParamTag(pos, end, sourceFile)) { let blankLineCount = 0; @@ -559,7 +557,7 @@ namespace ts { if (sourceFile.text.charCodeAt(pos) === CharacterCodes.openBrace) { pos++; for (let curlies = 1; pos < end; pos++) { - let charCode = sourceFile.text.charCodeAt(pos); + const charCode = sourceFile.text.charCodeAt(pos); // { character means we need to find another } to match the found one if (charCode === CharacterCodes.openBrace) { @@ -603,9 +601,9 @@ namespace ts { } let paramHelpString = ""; - let firstLineParamHelpStringPos = pos; + const firstLineParamHelpStringPos = pos; while (pos < end) { - let ch = sourceFile.text.charCodeAt(pos); + const ch = sourceFile.text.charCodeAt(pos); // at line break, set this comment line text and go to next line if (isLineBreak(ch)) { @@ -674,15 +672,15 @@ namespace ts { } // Now consume white spaces max - let startOfLinePos = pos; + const startOfLinePos = pos; pos = consumeWhiteSpacesOnTheLine(pos, end, sourceFile, paramHelpStringMargin); if (pos >= end) { return; } - let consumedSpaces = pos - startOfLinePos; + const consumedSpaces = pos - startOfLinePos; if (consumedSpaces < paramHelpStringMargin) { - let ch = sourceFile.text.charCodeAt(pos); + const ch = sourceFile.text.charCodeAt(pos); if (ch === CharacterCodes.asterisk) { // Consume more spaces after asterisk pos = consumeWhiteSpacesOnTheLine(pos + 1, end, sourceFile, paramHelpStringMargin - consumedSpaces - 1); @@ -815,7 +813,7 @@ namespace ts { private namedDeclarations: Map; constructor(kind: SyntaxKind, pos: number, end: number) { - super(kind, pos, end) + super(kind, pos, end); } public update(newText: string, textChangeRange: TextChangeRange): SourceFile { @@ -843,16 +841,16 @@ namespace ts { } private computeNamedDeclarations(): Map { - let result: Map = {}; + const result: Map = {}; forEachChild(this, visit); return result; function addDeclaration(declaration: Declaration) { - let name = getDeclarationName(declaration); + const name = getDeclarationName(declaration); if (name) { - let declarations = getDeclarations(name); + const declarations = getDeclarations(name); declarations.push(declaration); } } @@ -863,13 +861,13 @@ namespace ts { function getDeclarationName(declaration: Declaration) { if (declaration.name) { - let result = getTextOfIdentifierOrLiteral(declaration.name); + const result = getTextOfIdentifierOrLiteral(declaration.name); if (result !== undefined) { return result; } if (declaration.name.kind === SyntaxKind.ComputedPropertyName) { - let expr = (declaration.name).expression; + const expr = (declaration.name).expression; if (expr.kind === SyntaxKind.PropertyAccessExpression) { return (expr).name.text; } @@ -899,12 +897,12 @@ namespace ts { case SyntaxKind.FunctionDeclaration: case SyntaxKind.MethodDeclaration: case SyntaxKind.MethodSignature: - let functionDeclaration = node; - let declarationName = getDeclarationName(functionDeclaration); + const functionDeclaration = node; + const declarationName = getDeclarationName(functionDeclaration); if (declarationName) { - let declarations = getDeclarations(declarationName); - let lastDeclaration = lastOrUndefined(declarations); + const declarations = getDeclarations(declarationName); + const lastDeclaration = lastOrUndefined(declarations); // Check whether this declaration belongs to an "overload group". if (lastDeclaration && functionDeclaration.parent === lastDeclaration.parent && functionDeclaration.symbol === lastDeclaration.symbol) { @@ -980,7 +978,7 @@ namespace ts { break; case SyntaxKind.ImportDeclaration: - let importClause = (node).importClause; + const importClause = (node).importClause; if (importClause) { // Handle default import case e.g.: // import d from "mod"; @@ -1113,8 +1111,8 @@ namespace ts { } export interface Classifications { - spans: number[], - endOfLineState: EndOfLineState + spans: number[]; + endOfLineState: EndOfLineState; } export interface ClassifiedSpan { @@ -1171,7 +1169,7 @@ namespace ts { highlightSpans: HighlightSpan[]; } - export module HighlightSpanKind { + export namespace HighlightSpanKind { export const none = "none"; export const definition = "definition"; export const reference = "reference"; @@ -1220,7 +1218,7 @@ namespace ts { InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: boolean; PlaceOpenBraceOnNewLineForFunctions: boolean; PlaceOpenBraceOnNewLineForControlBlocks: boolean; - [s: string]: boolean | number| string; + [s: string]: boolean | number | string; } export interface DefinitionInfo { @@ -1500,7 +1498,7 @@ namespace ts { } // TODO: move these to enums - export module ScriptElementKind { + export namespace ScriptElementKind { export const unknown = ""; export const warning = "warning"; @@ -1529,7 +1527,7 @@ namespace ts { export const enumElement = "enum"; // Inside module and script only - // let v = .. + // const v = .. export const variableElement = "var"; // Inside function @@ -1581,7 +1579,7 @@ namespace ts { export const letElement = "let"; } - export module ScriptElementKindModifier { + export namespace ScriptElementKindModifier { export const none = ""; export const publicMemberModifier = "public"; export const privateMemberModifier = "private"; @@ -1723,8 +1721,8 @@ namespace ts { this.fileNameToEntry = createFileMap(); // Initialize the list with the root file names - let rootFileNames = host.getScriptFileNames(); - for (let fileName of rootFileNames) { + const rootFileNames = host.getScriptFileNames(); + for (const fileName of rootFileNames) { this.createEntry(fileName, toPath(fileName, this.currentDirectory, getCanonicalFileName)); } @@ -1738,7 +1736,7 @@ namespace ts { private createEntry(fileName: string, path: Path) { let entry: HostFileInformation; - let scriptSnapshot = this.host.getScriptSnapshot(fileName); + const scriptSnapshot = this.host.getScriptSnapshot(fileName); if (scriptSnapshot) { entry = { hostFileName: fileName, @@ -1760,7 +1758,7 @@ namespace ts { } public getOrCreateEntry(fileName: string): HostFileInformation { - let path = toPath(fileName, this.currentDirectory, this.getCanonicalFileName) + const path = toPath(fileName, this.currentDirectory, this.getCanonicalFileName); if (this.contains(path)) { return this.getEntry(path); } @@ -1769,7 +1767,7 @@ namespace ts { } public getRootFileNames(): string[] { - let fileNames: string[] = []; + const fileNames: string[] = []; this.fileNameToEntry.forEachValue((path, value) => { if (value) { @@ -1781,12 +1779,12 @@ namespace ts { } public getVersion(path: Path): string { - let file = this.getEntry(path); + const file = this.getEntry(path); return file && file.version; } public getScriptSnapshot(path: Path): IScriptSnapshot { - let file = this.getEntry(path); + const file = this.getEntry(path); return file && file.scriptSnapshot; } } @@ -1803,22 +1801,22 @@ namespace ts { } public getCurrentSourceFile(fileName: string): SourceFile { - let scriptSnapshot = this.host.getScriptSnapshot(fileName); + const scriptSnapshot = this.host.getScriptSnapshot(fileName); if (!scriptSnapshot) { // The host does not know about this file. throw new Error("Could not find file: '" + fileName + "'."); } - let version = this.host.getScriptVersion(fileName); + const version = this.host.getScriptVersion(fileName); let sourceFile: SourceFile; if (this.currentFileName !== fileName) { // This is a new file, just parse it - sourceFile = createLanguageServiceSourceFile(fileName, scriptSnapshot, ScriptTarget.Latest, version, /*setNodeParents:*/ true); + sourceFile = createLanguageServiceSourceFile(fileName, scriptSnapshot, ScriptTarget.Latest, version, /*setNodeParents*/ true); } else if (this.currentFileVersion !== version) { // This is the same file, just a newer version. Incrementally parse the file. - let editRange = scriptSnapshot.getChangeRange(this.currentFileScriptSnapshot); + const editRange = scriptSnapshot.getChangeRange(this.currentFileScriptSnapshot); sourceFile = updateLanguageServiceSourceFile(this.currentSourceFile, scriptSnapshot, version, editRange); } @@ -1863,7 +1861,7 @@ namespace ts { * - noResolve = true */ export function transpileModule(input: string, transpileOptions: TranspileOptions): TranspileOutput { - let options = transpileOptions.compilerOptions ? clone(transpileOptions.compilerOptions) : getDefaultCompilerOptions(); + const options = transpileOptions.compilerOptions ? clone(transpileOptions.compilerOptions) : getDefaultCompilerOptions(); options.isolatedModules = true; @@ -1879,21 +1877,22 @@ namespace ts { options.noResolve = true; // if jsx is specified then treat file as .tsx - let inputFileName = transpileOptions.fileName || (options.jsx ? "module.tsx" : "module.ts"); - let sourceFile = createSourceFile(inputFileName, input, options.target); + const inputFileName = transpileOptions.fileName || (options.jsx ? "module.tsx" : "module.ts"); + const sourceFile = createSourceFile(inputFileName, input, options.target); if (transpileOptions.moduleName) { sourceFile.moduleName = transpileOptions.moduleName; } sourceFile.renamedDependencies = transpileOptions.renamedDependencies; - let newLine = getNewLineCharacter(options); + const newLine = getNewLineCharacter(options); // Output let outputText: string; let sourceMapText: string; + // Create a compilerHost object to allow the compiler to read and write files - let compilerHost: CompilerHost = { + const compilerHost: CompilerHost = { getSourceFile: (fileName, target) => fileName === normalizeSlashes(inputFileName) ? sourceFile : undefined, writeFile: (name, text, writeByteOrderMark) => { if (fileExtensionIs(name, ".map")) { @@ -1914,7 +1913,7 @@ namespace ts { readFile: (fileName): string => "" }; - let program = createProgram([inputFileName], options, compilerHost); + const program = createProgram([inputFileName], options, compilerHost); let diagnostics: Diagnostic[]; if (transpileOptions.reportDiagnostics) { @@ -1934,15 +1933,15 @@ namespace ts { * This is a shortcut function for transpileModule - it accepts transpileOptions as parameters and returns only outputText part of the result. */ export function transpile(input: string, compilerOptions?: CompilerOptions, fileName?: string, diagnostics?: Diagnostic[], moduleName?: string): string { - let output = transpileModule(input, { compilerOptions, fileName, reportDiagnostics: !!diagnostics, moduleName }); + const output = transpileModule(input, { compilerOptions, fileName, reportDiagnostics: !!diagnostics, moduleName }); // addRange correctly handles cases when wither 'from' or 'to' argument is missing addRange(diagnostics, output.diagnostics); return output.outputText; } export function createLanguageServiceSourceFile(fileName: string, scriptSnapshot: IScriptSnapshot, scriptTarget: ScriptTarget, version: string, setNodeParents: boolean): SourceFile { - let text = scriptSnapshot.getText(0, scriptSnapshot.getLength()); - let sourceFile = createSourceFile(fileName, text, scriptTarget, setNodeParents); + const text = scriptSnapshot.getText(0, scriptSnapshot.getLength()); + const sourceFile = createSourceFile(fileName, text, scriptTarget, setNodeParents); setSourceFileFields(sourceFile, scriptSnapshot, version); // after full parsing we can use table with interned strings as name table sourceFile.nameTable = sourceFile.identifiers; @@ -1961,12 +1960,12 @@ namespace ts { let newText: string; // grab the fragment from the beginning of the original text to the beginning of the span - let prefix = textChangeRange.span.start !== 0 + const prefix = textChangeRange.span.start !== 0 ? sourceFile.text.substr(0, textChangeRange.span.start) : ""; // grab the fragment from the end of the span till the end of the original text - let suffix = textSpanEnd(textChangeRange.span) !== sourceFile.text.length + const suffix = textSpanEnd(textChangeRange.span) !== sourceFile.text.length ? sourceFile.text.substr(textSpanEnd(textChangeRange.span)) : ""; @@ -1976,7 +1975,7 @@ namespace ts { } else { // it was actual edit, fetch the fragment of new text that correspond to new span - let changedText = scriptSnapshot.getText(textChangeRange.span.start, textChangeRange.span.start + textChangeRange.newLength); + const changedText = scriptSnapshot.getText(textChangeRange.span.start, textChangeRange.span.start + textChangeRange.newLength); // combine prefix, changed text and suffix newText = prefix && suffix ? prefix + changedText + suffix @@ -1985,7 +1984,7 @@ namespace ts { : (changedText + suffix); } - let newSourceFile = updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks); + const newSourceFile = updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks); setSourceFileFields(newSourceFile, scriptSnapshot, version); // after incremental parsing nameTable might not be up-to-date // drop it so it can be lazily recreated later @@ -2006,7 +2005,7 @@ namespace ts { } // Otherwise, just create a new source file. - return createLanguageServiceSourceFile(sourceFile.fileName, scriptSnapshot, sourceFile.languageVersion, version, /*setNodeParents:*/ true); + return createLanguageServiceSourceFile(sourceFile.fileName, scriptSnapshot, sourceFile.languageVersion, version, /*setNodeParents*/ true); } export function createGetCanonicalFileName(useCaseSensitivefileNames: boolean): (fileName: string) => string { @@ -2019,15 +2018,15 @@ namespace ts { export function createDocumentRegistry(useCaseSensitiveFileNames?: boolean, currentDirectory = ""): DocumentRegistry { // Maps from compiler setting target (ES3, ES5, etc.) to all the cached documents we have // for those settings. - let buckets: Map> = {}; - let getCanonicalFileName = createGetCanonicalFileName(!!useCaseSensitiveFileNames); + const buckets: Map> = {}; + const getCanonicalFileName = createGetCanonicalFileName(!!useCaseSensitiveFileNames); function getKeyFromCompilationSettings(settings: CompilerOptions): string { return "_" + settings.target + "|" + settings.module + "|" + settings.noResolve + "|" + settings.jsx + +"|" + settings.allowJs; } function getBucketForCompilationSettings(settings: CompilerOptions, createIfMissing: boolean): FileMap { - let key = getKeyFromCompilationSettings(settings); + const key = getKeyFromCompilationSettings(settings); let bucket = lookUp(buckets, key); if (!bucket && createIfMissing) { buckets[key] = bucket = createFileMap(); @@ -2036,9 +2035,9 @@ namespace ts { } function reportStats() { - let bucketInfoArray = Object.keys(buckets).filter(name => name && name.charAt(0) === '_').map(name => { - let entries = lookUp(buckets, name); - let sourceFiles: { name: string; refCount: number; references: string[]; }[] = []; + const bucketInfoArray = Object.keys(buckets).filter(name => name && name.charAt(0) === "_").map(name => { + const entries = lookUp(buckets, name); + const sourceFiles: { name: string; refCount: number; references: string[]; }[] = []; entries.forEachValue((key, entry) => { sourceFiles.push({ name: key, @@ -2052,15 +2051,15 @@ namespace ts { sourceFiles }; }); - return JSON.stringify(bucketInfoArray, null, 2); + return JSON.stringify(bucketInfoArray, undefined, 2); } function acquireDocument(fileName: string, compilationSettings: CompilerOptions, scriptSnapshot: IScriptSnapshot, version: string): SourceFile { - return acquireOrUpdateDocument(fileName, compilationSettings, scriptSnapshot, version, /*acquiring:*/ true); + return acquireOrUpdateDocument(fileName, compilationSettings, scriptSnapshot, version, /*acquiring*/ true); } function updateDocument(fileName: string, compilationSettings: CompilerOptions, scriptSnapshot: IScriptSnapshot, version: string): SourceFile { - return acquireOrUpdateDocument(fileName, compilationSettings, scriptSnapshot, version, /*acquiring:*/ false); + return acquireOrUpdateDocument(fileName, compilationSettings, scriptSnapshot, version, /*acquiring*/ false); } function acquireOrUpdateDocument( @@ -2070,14 +2069,14 @@ namespace ts { version: string, acquiring: boolean): SourceFile { - let bucket = getBucketForCompilationSettings(compilationSettings, /*createIfMissing*/ true); - let path = toPath(fileName, currentDirectory, getCanonicalFileName); + const bucket = getBucketForCompilationSettings(compilationSettings, /*createIfMissing*/ true); + const path = toPath(fileName, currentDirectory, getCanonicalFileName); let entry = bucket.get(path); if (!entry) { Debug.assert(acquiring, "How could we be trying to update a document that the registry doesn't have?"); // Have never seen this file with these settings. Create a new source file for it. - let sourceFile = createLanguageServiceSourceFile(fileName, scriptSnapshot, compilationSettings.target, version, /*setNodeParents:*/ false); + const sourceFile = createLanguageServiceSourceFile(fileName, scriptSnapshot, compilationSettings.target, version, /*setNodeParents*/ false); entry = { sourceFile: sourceFile, @@ -2109,12 +2108,12 @@ namespace ts { } function releaseDocument(fileName: string, compilationSettings: CompilerOptions): void { - let bucket = getBucketForCompilationSettings(compilationSettings, false); + const bucket = getBucketForCompilationSettings(compilationSettings, /*createIfMissing*/false); Debug.assert(bucket !== undefined); - let path = toPath(fileName, currentDirectory, getCanonicalFileName); + const path = toPath(fileName, currentDirectory, getCanonicalFileName); - let entry = bucket.get(path); + const entry = bucket.get(path); entry.languageServiceRefCount--; Debug.assert(entry.languageServiceRefCount >= 0); @@ -2132,19 +2131,19 @@ namespace ts { } export function preProcessFile(sourceText: string, readImportFiles = true, detectJavaScriptImports = false): PreProcessedFileInfo { - let referencedFiles: FileReference[] = []; - let importedFiles: FileReference[] = []; + const referencedFiles: FileReference[] = []; + const importedFiles: FileReference[] = []; let ambientExternalModules: string[]; let isNoDefaultLib = false; function processTripleSlashDirectives(): void { - let commentRanges = getLeadingCommentRanges(sourceText, 0); + const commentRanges = getLeadingCommentRanges(sourceText, 0); forEach(commentRanges, commentRange => { - let comment = sourceText.substring(commentRange.pos, commentRange.end); - let referencePathMatchResult = getFileReferenceFromReferencePath(comment, commentRange); + const comment = sourceText.substring(commentRange.pos, commentRange.end); + const referencePathMatchResult = getFileReferenceFromReferencePath(comment, commentRange); if (referencePathMatchResult) { isNoDefaultLib = referencePathMatchResult.isNoDefaultLib; - let fileReference = referencePathMatchResult.fileReference; + const fileReference = referencePathMatchResult.fileReference; if (fileReference) { referencedFiles.push(fileReference); } @@ -2160,8 +2159,8 @@ namespace ts { } function recordModuleName() { - let importPath = scanner.getTokenValue(); - let pos = scanner.getTokenPos(); + const importPath = scanner.getTokenValue(); + const pos = scanner.getTokenPos(); importedFiles.push({ fileName: importPath, pos: pos, @@ -2213,7 +2212,7 @@ namespace ts { } } else if (token === SyntaxKind.EqualsToken) { - if (tryConsumeRequireCall(/* skipCurrentToken */ true)) { + if (tryConsumeRequireCall(/*skipCurrentToken*/ true)) { return true; } } @@ -2311,7 +2310,7 @@ namespace ts { if (token === SyntaxKind.Identifier || isKeyword(token)) { token = scanner.scan(); if (token === SyntaxKind.EqualsToken) { - if (tryConsumeRequireCall(/* skipCurrentToken */ true)) { + if (tryConsumeRequireCall(/*skipCurrentToken*/ true)) { return true; } } @@ -2410,7 +2409,7 @@ namespace ts { if (tryConsumeDeclare() || tryConsumeImport() || tryConsumeExport() || - (detectJavaScriptImports && (tryConsumeRequireCall(/* skipCurrentToken */ false) || tryConsumeDefine()))) { + (detectJavaScriptImports && (tryConsumeRequireCall(/*skipCurrentToken*/ false) || tryConsumeDefine()))) { continue; } else { @@ -2550,8 +2549,8 @@ namespace ts { return true; } else if (position === comment.end) { - let text = sourceFile.text; - let width = comment.end - comment.pos; + const text = sourceFile.text; + const width = comment.end - comment.pos; // is single line comment or just /* if (width <= 2 || text.charCodeAt(comment.pos + 1) === CharacterCodes.slash) { return true; @@ -2583,7 +2582,7 @@ namespace ts { } // A cache of completion entries for keywords, these do not change between sessions - let keywordCompletions: CompletionEntry[] = []; + const keywordCompletions: CompletionEntry[] = []; for (let i = SyntaxKind.FirstKeyword; i <= SyntaxKind.LastKeyword; i++) { keywordCompletions.push({ name: tokenToString(i), @@ -2673,15 +2672,15 @@ namespace ts { export function createLanguageService(host: LanguageServiceHost, documentRegistry: DocumentRegistry = createDocumentRegistry(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames(), host.getCurrentDirectory())): LanguageService { - let syntaxTreeCache: SyntaxTreeCache = new SyntaxTreeCache(host); + const syntaxTreeCache: SyntaxTreeCache = new SyntaxTreeCache(host); let ruleProvider: formatting.RulesProvider; let program: Program; let lastProjectVersion: string; - let useCaseSensitivefileNames = false; - let cancellationToken = new CancellationTokenObject(host.getCancellationToken && host.getCancellationToken()); + const useCaseSensitivefileNames = false; + const cancellationToken = new CancellationTokenObject(host.getCancellationToken && host.getCancellationToken()); - let currentDirectory = host.getCurrentDirectory(); + const currentDirectory = host.getCurrentDirectory(); // Check if the localized messages json is set, otherwise query the host for it if (!localizedDiagnosticMessages && host.getLocalizedDiagnosticMessages) { localizedDiagnosticMessages = host.getLocalizedDiagnosticMessages(); @@ -2693,10 +2692,10 @@ namespace ts { } } - let getCanonicalFileName = createGetCanonicalFileName(useCaseSensitivefileNames); + const getCanonicalFileName = createGetCanonicalFileName(useCaseSensitivefileNames); function getValidSourceFile(fileName: string): SourceFile { - let sourceFile = program.getSourceFile(fileName); + const sourceFile = program.getSourceFile(fileName); if (!sourceFile) { throw new Error("Could not find file: '" + fileName + "'."); } @@ -2716,7 +2715,7 @@ namespace ts { function synchronizeHostData(): void { // perform fast check if host supports it if (host.getProjectVersion) { - let hostProjectVersion = host.getProjectVersion(); + const hostProjectVersion = host.getProjectVersion(); if (hostProjectVersion) { if (lastProjectVersion === hostProjectVersion) { return; @@ -2740,17 +2739,17 @@ namespace ts { // the program points to old source files that have been invalidated because of // incremental parsing. - let oldSettings = program && program.getCompilerOptions(); - let newSettings = hostCache.compilationSettings(); - let changesInCompilationSettingsAffectSyntax = oldSettings && + const oldSettings = program && program.getCompilerOptions(); + const newSettings = hostCache.compilationSettings(); + const changesInCompilationSettingsAffectSyntax = oldSettings && (oldSettings.target !== newSettings.target || oldSettings.module !== newSettings.module || oldSettings.noResolve !== newSettings.noResolve || - oldSettings.jsx !== newSettings.jsx || + oldSettings.jsx !== newSettings.jsx || oldSettings.allowJs !== newSettings.allowJs); // Now create a new compiler - let compilerHost: CompilerHost = { + const compilerHost: CompilerHost = { getSourceFile: getOrCreateSourceFile, getCancellationToken: () => cancellationToken, getCanonicalFileName, @@ -2766,22 +2765,22 @@ namespace ts { }, readFile: (fileName): string => { // stub missing host functionality - let entry = hostCache.getOrCreateEntry(fileName); + const entry = hostCache.getOrCreateEntry(fileName); return entry && entry.scriptSnapshot.getText(0, entry.scriptSnapshot.getLength()); } }; if (host.resolveModuleNames) { - compilerHost.resolveModuleNames = (moduleNames, containingFile) => host.resolveModuleNames(moduleNames, containingFile) + compilerHost.resolveModuleNames = (moduleNames, containingFile) => host.resolveModuleNames(moduleNames, containingFile); } - let newProgram = createProgram(hostCache.getRootFileNames(), newSettings, compilerHost, program); + const newProgram = createProgram(hostCache.getRootFileNames(), newSettings, compilerHost, program); // Release any files we have acquired in the old program but are // not part of the new program. if (program) { - let oldSourceFiles = program.getSourceFiles(); - for (let oldSourceFile of oldSourceFiles) { + const oldSourceFiles = program.getSourceFiles(); + for (const oldSourceFile of oldSourceFiles) { if (!newProgram.getSourceFile(oldSourceFile.fileName) || changesInCompilationSettingsAffectSyntax) { documentRegistry.releaseDocument(oldSourceFile.fileName, oldSettings); } @@ -2804,7 +2803,7 @@ namespace ts { // The program is asking for this file, check first if the host can locate it. // If the host can not locate the file, then it does not exist. return undefined // to the program to allow reporting of errors for missing files. - let hostFileInformation = hostCache.getOrCreateEntry(fileName); + const hostFileInformation = hostCache.getOrCreateEntry(fileName); if (!hostFileInformation) { return undefined; } @@ -2814,7 +2813,7 @@ namespace ts { // can not be reused. we have to dump all syntax trees and create new ones. if (!changesInCompilationSettingsAffectSyntax) { // Check if the old program had this file already - let oldSourceFile = program && program.getSourceFile(fileName); + const oldSourceFile = program && program.getSourceFile(fileName); if (oldSourceFile) { // We already had a source file for this file name. Go to the registry to // ensure that we get the right up to date version of it. We need this to @@ -2851,7 +2850,7 @@ namespace ts { if (!sourceFile) { return false; } - let path = sourceFile.path || toPath(sourceFile.fileName, currentDirectory, getCanonicalFileName); + const path = sourceFile.path || toPath(sourceFile.fileName, currentDirectory, getCanonicalFileName); return sourceFile.version === hostCache.getVersion(path); } @@ -2862,13 +2861,13 @@ namespace ts { } // If number of files in the program do not match, it is not up-to-date - let rootFileNames = hostCache.getRootFileNames(); + const rootFileNames = hostCache.getRootFileNames(); if (program.getSourceFiles().length !== rootFileNames.length) { return false; } // If any file is not up-to-date, then the whole program is not up-to-date - for (let fileName of rootFileNames) { + for (const fileName of rootFileNames) { if (!sourceFileUpToDate(program.getSourceFile(fileName))) { return false; } @@ -2910,18 +2909,18 @@ namespace ts { function getSemanticDiagnostics(fileName: string): Diagnostic[] { synchronizeHostData(); - let targetSourceFile = getValidSourceFile(fileName); + const targetSourceFile = getValidSourceFile(fileName); // Only perform the action per file regardless of '-out' flag as LanguageServiceHost is expected to call this function per file. // Therefore only get diagnostics for given file. - let semanticDiagnostics = program.getSemanticDiagnostics(targetSourceFile, cancellationToken); + const semanticDiagnostics = program.getSemanticDiagnostics(targetSourceFile, cancellationToken); if (!program.getCompilerOptions().declaration) { return semanticDiagnostics; } // If '-d' is enabled, check for emitter error. One example of emitter error is export class implements non-export interface - let declarationDiagnostics = program.getDeclarationDiagnostics(targetSourceFile, cancellationToken); + const declarationDiagnostics = program.getDeclarationDiagnostics(targetSourceFile, cancellationToken); return concatenate(semanticDiagnostics, declarationDiagnostics); } @@ -2937,14 +2936,14 @@ namespace ts { * @return undefined if the name is of external module otherwise a name with striped of any quote */ function getCompletionEntryDisplayNameForSymbol(symbol: Symbol, target: ScriptTarget, performCharacterChecks: boolean, location: Node): string { - let displayName: string = getDeclaredName(program.getTypeChecker(), symbol, location); + const displayName: string = getDeclaredName(program.getTypeChecker(), symbol, location); if (displayName) { - let firstCharCode = displayName.charCodeAt(0); + const firstCharCode = displayName.charCodeAt(0); // First check of the displayName is not external module; if it is an external module, it is not valid entry if ((symbol.flags & SymbolFlags.Namespace) && (firstCharCode === CharacterCodes.singleQuote || firstCharCode === CharacterCodes.doubleQuote)) { // If the symbol is external module, don't show it in the completion list - // (i.e declare module "http" { let x; } | // <= request completion here, "http" should not be there) + // (i.e declare module "http" { const x; } | // <= request completion here, "http" should not be there) return undefined; } } @@ -2987,20 +2986,20 @@ namespace ts { } function getCompletionData(fileName: string, position: number) { - let typeChecker = program.getTypeChecker(); - let syntacticStart = new Date().getTime(); - let sourceFile = getValidSourceFile(fileName); - let isJavaScriptFile = isSourceFileJavaScript(sourceFile); + const typeChecker = program.getTypeChecker(); + const syntacticStart = new Date().getTime(); + const sourceFile = getValidSourceFile(fileName); + const isJavaScriptFile = isSourceFileJavaScript(sourceFile); let isJsDocTagName = false; let start = new Date().getTime(); - let currentToken = getTokenAtPosition(sourceFile, position); + const currentToken = getTokenAtPosition(sourceFile, position); log("getCompletionData: Get current token: " + (new Date().getTime() - start)); start = new Date().getTime(); // Completion not allowed inside comments, bail out if this is the case - let insideComment = isInsideComment(sourceFile, currentToken, position); + const insideComment = isInsideComment(sourceFile, currentToken, position); log("getCompletionData: Is inside comment: " + (new Date().getTime() - start)); if (insideComment) { @@ -3014,7 +3013,7 @@ namespace ts { // /** @type {number | string} */ // Completion should work in the brackets let insideJsDocTagExpression = false; - let tag = getJsDocTagAtPosition(sourceFile, position); + const tag = getJsDocTagAtPosition(sourceFile, position); if (tag) { if (tag.tagName.pos <= position && position <= tag.tagName.end) { isJsDocTagName = true; @@ -3024,7 +3023,7 @@ namespace ts { case SyntaxKind.JSDocTypeTag: case SyntaxKind.JSDocParameterTag: case SyntaxKind.JSDocReturnTag: - let tagWithExpression = tag; + const tagWithExpression = tag; if (tagWithExpression.typeExpression) { insideJsDocTagExpression = tagWithExpression.typeExpression.pos < position && position < tagWithExpression.typeExpression.end; } @@ -3045,7 +3044,7 @@ namespace ts { } start = new Date().getTime(); - let previousToken = findPrecedingToken(position, sourceFile); + const previousToken = findPrecedingToken(position, sourceFile); log("getCompletionData: Get previous token 1: " + (new Date().getTime() - start)); // The decision to provide completion depends on the contextToken, which is determined through the previousToken. @@ -3055,7 +3054,7 @@ namespace ts { // Check if the caret is at the end of an identifier; this is a partial identifier that we want to complete: e.g. a.toS| // Skip this partial identifier and adjust the contextToken to the token that precedes it. if (contextToken && position <= contextToken.end && isWord(contextToken.kind)) { - let start = new Date().getTime(); + const start = new Date().getTime(); contextToken = findPrecedingToken(contextToken.getFullStart(), sourceFile); log("getCompletionData: Get previous token 2: " + (new Date().getTime() - start)); } @@ -3076,7 +3075,7 @@ namespace ts { return undefined; } - let { parent, kind } = contextToken; + const { parent, kind } = contextToken; if (kind === SyntaxKind.DotToken) { if (parent.kind === SyntaxKind.PropertyAccessExpression) { node = (contextToken.parent).expression; @@ -3103,7 +3102,7 @@ namespace ts { } } - let semanticStart = new Date().getTime(); + const semanticStart = new Date().getTime(); let isMemberCompletion: boolean; let isNewIdentifierLocation: boolean; let symbols: Symbol[] = []; @@ -3112,7 +3111,7 @@ namespace ts { getTypeScriptMemberSymbols(); } else if (isRightOfOpenTag) { - let tagSymbols = typeChecker.getJsxIntrinsicTagNames(); + const tagSymbols = typeChecker.getJsxIntrinsicTagNames(); if (tryGetGlobalSymbols()) { symbols = tagSymbols.concat(symbols.filter(s => !!(s.flags & SymbolFlags.Value))); } @@ -3123,7 +3122,7 @@ namespace ts { isNewIdentifierLocation = false; } else if (isStartingCloseTag) { - let tagName = (contextToken.parent.parent).openingElement.tagName; + const tagName = (contextToken.parent.parent).openingElement.tagName; symbols = [typeChecker.getSymbolAtLocation(tagName)]; isMemberCompletion = true; @@ -3157,7 +3156,7 @@ namespace ts { if (symbol && symbol.flags & SymbolFlags.HasExports) { // Extract module or enum members - let exportedSymbols = typeChecker.getExportsOfModule(symbol); + const exportedSymbols = typeChecker.getExportsOfModule(symbol); forEach(exportedSymbols, symbol => { if (typeChecker.isValidPropertyAccess((node.parent), symbol.name)) { symbols.push(symbol); @@ -3166,14 +3165,14 @@ namespace ts { } } - let type = typeChecker.getTypeAtLocation(node); + const type = typeChecker.getTypeAtLocation(node); addTypeProperties(type); } function addTypeProperties(type: Type) { if (type) { // Filter private properties - for (let symbol of type.getApparentProperties()) { + for (const symbol of type.getApparentProperties()) { if (typeChecker.isValidPropertyAccess((node.parent), symbol.name)) { symbols.push(symbol); } @@ -3185,8 +3184,8 @@ namespace ts { // each individual type has. This is because we're going to add all identifiers // anyways. So we might as well elevate the members that were at least part // of the individual types to a higher status since we know what they are. - let unionType = type; - for (let elementType of unionType.types) { + const unionType = type; + for (const elementType of unionType.types) { addTypeProperties(elementType); } } @@ -3256,14 +3255,14 @@ namespace ts { // - 'contextToken' was adjusted to the token prior to 'previousToken' // because we were at the end of an identifier. // - 'previousToken' is defined. - let adjustedPosition = previousToken !== contextToken ? + const adjustedPosition = previousToken !== contextToken ? previousToken.getStart() : position; - let scopeNode = getScopeNode(contextToken, adjustedPosition, sourceFile) || sourceFile; + const scopeNode = getScopeNode(contextToken, adjustedPosition, sourceFile) || sourceFile; /// TODO filter meaning based on the current context - let symbolMeanings = SymbolFlags.Type | SymbolFlags.Value | SymbolFlags.Namespace | SymbolFlags.Alias; + const symbolMeanings = SymbolFlags.Type | SymbolFlags.Value | SymbolFlags.Namespace | SymbolFlags.Alias; symbols = typeChecker.getSymbolsInScope(scopeNode, symbolMeanings); return true; @@ -3282,8 +3281,8 @@ namespace ts { } function isCompletionListBlocker(contextToken: Node): boolean { - let start = new Date().getTime(); - let result = isInStringOrRegularExpressionOrTemplateLiteral(contextToken) || + const start = new Date().getTime(); + const result = isInStringOrRegularExpressionOrTemplateLiteral(contextToken) || isSolelyIdentifierDefinitionLocation(contextToken) || isDotOfNumericLiteral(contextToken) || isInJsxText(contextToken); @@ -3310,27 +3309,27 @@ namespace ts { function isNewIdentifierDefinitionLocation(previousToken: Node): boolean { if (previousToken) { - let containingNodeKind = previousToken.parent.kind; + const containingNodeKind = previousToken.parent.kind; switch (previousToken.kind) { case SyntaxKind.CommaToken: return containingNodeKind === SyntaxKind.CallExpression // func( a, | || containingNodeKind === SyntaxKind.Constructor // constructor( a, | /* public, protected, private keywords are allowed here, so show completion */ || containingNodeKind === SyntaxKind.NewExpression // new C(a, | || containingNodeKind === SyntaxKind.ArrayLiteralExpression // [a, | - || containingNodeKind === SyntaxKind.BinaryExpression // let x = (a, | + || containingNodeKind === SyntaxKind.BinaryExpression // const x = (a, | || containingNodeKind === SyntaxKind.FunctionType; // var x: (s: string, list| case SyntaxKind.OpenParenToken: return containingNodeKind === SyntaxKind.CallExpression // func( | || containingNodeKind === SyntaxKind.Constructor // constructor( | || containingNodeKind === SyntaxKind.NewExpression // new C(a| - || containingNodeKind === SyntaxKind.ParenthesizedExpression // let x = (a| + || containingNodeKind === SyntaxKind.ParenthesizedExpression // const x = (a| || containingNodeKind === SyntaxKind.ParenthesizedType; // function F(pred: (a| /* this can become an arrow function, where 'a' is the argument */ case SyntaxKind.OpenBracketToken: return containingNodeKind === SyntaxKind.ArrayLiteralExpression // [ | || containingNodeKind === SyntaxKind.IndexSignature // [ | : string ] - || containingNodeKind === SyntaxKind.ComputedPropertyName // [ | /* this can become an index signature */ + || containingNodeKind === SyntaxKind.ComputedPropertyName; // [ | /* this can become an index signature */ case SyntaxKind.ModuleKeyword: // module | case SyntaxKind.NamespaceKeyword: // namespace | @@ -3343,7 +3342,7 @@ namespace ts { return containingNodeKind === SyntaxKind.ClassDeclaration; // class A{ | case SyntaxKind.EqualsToken: - return containingNodeKind === SyntaxKind.VariableDeclaration // let x = a| + return containingNodeKind === SyntaxKind.VariableDeclaration // const x = a| || containingNodeKind === SyntaxKind.BinaryExpression; // x = a| case SyntaxKind.TemplateHead: @@ -3375,8 +3374,8 @@ namespace ts { || contextToken.kind === SyntaxKind.StringLiteralType || contextToken.kind === SyntaxKind.RegularExpressionLiteral || isTemplateLiteralKind(contextToken.kind)) { - let start = contextToken.getStart(); - let end = contextToken.getEnd(); + const start = contextToken.getStart(); + const end = contextToken.getEnd(); // To be "in" one of these literals, the position has to be: // 1. entirely within the token text. @@ -3420,7 +3419,7 @@ namespace ts { // We are *only* completing on properties from the type being destructured. isNewIdentifierLocation = false; - let rootDeclaration = getRootDeclaration(objectLikeContainer.parent); + const rootDeclaration = getRootDeclaration(objectLikeContainer.parent); if (isVariableLike(rootDeclaration)) { // We don't want to complete using the type acquired by the shape // of the binding pattern; we are only interested in types acquired @@ -3431,7 +3430,7 @@ namespace ts { } } else { - Debug.fail("Root declaration is not variable-like.") + Debug.fail("Root declaration is not variable-like."); } } else { @@ -3442,7 +3441,7 @@ namespace ts { return false; } - let typeMembers = typeChecker.getPropertiesOfType(typeForObject); + const typeMembers = typeChecker.getPropertiesOfType(typeForObject); if (typeMembers && typeMembers.length > 0) { // Add filtered items to the completion list symbols = filterObjectMembersList(typeMembers, existingMembers); @@ -3466,11 +3465,11 @@ namespace ts { * @returns true if 'symbols' was successfully populated; false otherwise. */ function tryGetImportOrExportClauseCompletionSymbols(namedImportsOrExports: NamedImportsOrExports): boolean { - let declarationKind = namedImportsOrExports.kind === SyntaxKind.NamedImports ? + const declarationKind = namedImportsOrExports.kind === SyntaxKind.NamedImports ? SyntaxKind.ImportDeclaration : SyntaxKind.ExportDeclaration; - let importOrExportDeclaration = getAncestor(namedImportsOrExports, declarationKind); - let moduleSpecifier = importOrExportDeclaration.moduleSpecifier; + const importOrExportDeclaration = getAncestor(namedImportsOrExports, declarationKind); + const moduleSpecifier = importOrExportDeclaration.moduleSpecifier; if (!moduleSpecifier) { return false; @@ -3480,7 +3479,7 @@ namespace ts { isNewIdentifierLocation = false; let exports: Symbol[]; - let moduleSpecifierSymbol = typeChecker.getSymbolAtLocation(importOrExportDeclaration.moduleSpecifier); + const moduleSpecifierSymbol = typeChecker.getSymbolAtLocation(importOrExportDeclaration.moduleSpecifier); if (moduleSpecifierSymbol) { exports = typeChecker.getExportsOfModule(moduleSpecifierSymbol); } @@ -3497,9 +3496,9 @@ namespace ts { function tryGetObjectLikeCompletionContainer(contextToken: Node): ObjectLiteralExpression | BindingPattern { if (contextToken) { switch (contextToken.kind) { - case SyntaxKind.OpenBraceToken: // let x = { | - case SyntaxKind.CommaToken: // let x = { a: 0, | - let parent = contextToken.parent; + case SyntaxKind.OpenBraceToken: // const x = { | + case SyntaxKind.CommaToken: // const x = { a: 0, | + const parent = contextToken.parent; if (parent && (parent.kind === SyntaxKind.ObjectLiteralExpression || parent.kind === SyntaxKind.ObjectBindingPattern)) { return parent; } @@ -3532,8 +3531,8 @@ namespace ts { function tryGetContainingJsxElement(contextToken: Node): JsxOpeningLikeElement { if (contextToken) { - let parent = contextToken.parent; - switch(contextToken.kind) { + const parent = contextToken.parent; + switch (contextToken.kind) { case SyntaxKind.LessThanSlashToken: case SyntaxKind.SlashToken: case SyntaxKind.Identifier: @@ -3596,7 +3595,7 @@ namespace ts { * @returns true if we are certain that the currently edited location must define a new location; false otherwise. */ function isSolelyIdentifierDefinitionLocation(contextToken: Node): boolean { - let containingNodeKind = contextToken.parent.kind; + const containingNodeKind = contextToken.parent.kind; switch (contextToken.kind) { case SyntaxKind.CommaToken: return containingNodeKind === SyntaxKind.VariableDeclaration || @@ -3626,13 +3625,13 @@ namespace ts { case SyntaxKind.OpenBraceToken: return containingNodeKind === SyntaxKind.EnumDeclaration || // enum a { | containingNodeKind === SyntaxKind.InterfaceDeclaration || // interface a { | - containingNodeKind === SyntaxKind.TypeLiteral; // let x : { | + containingNodeKind === SyntaxKind.TypeLiteral; // const x : { | case SyntaxKind.SemicolonToken: return containingNodeKind === SyntaxKind.PropertySignature && contextToken.parent && contextToken.parent.parent && (contextToken.parent.parent.kind === SyntaxKind.InterfaceDeclaration || // interface a { f; | - contextToken.parent.parent.kind === SyntaxKind.TypeLiteral); // let x : { a; | + contextToken.parent.parent.kind === SyntaxKind.TypeLiteral); // const x : { a; | case SyntaxKind.LessThanToken: return containingNodeKind === SyntaxKind.ClassDeclaration || // class A< | @@ -3699,7 +3698,7 @@ namespace ts { function isDotOfNumericLiteral(contextToken: Node): boolean { if (contextToken.kind === SyntaxKind.NumericLiteral) { - let text = contextToken.getFullText(); + const text = contextToken.getFullText(); return text.charAt(text.length - 1) === "."; } @@ -3716,15 +3715,15 @@ namespace ts { * do not occur at the current position and have not otherwise been typed. */ function filterNamedImportOrExportCompletionItems(exportsOfModule: Symbol[], namedImportsOrExports: ImportOrExportSpecifier[]): Symbol[] { - let exisingImportsOrExports: Map = {}; + const exisingImportsOrExports: Map = {}; - for (let element of namedImportsOrExports) { + for (const element of namedImportsOrExports) { // If this is the current item we are editing right now, do not filter it out if (element.getStart() <= position && position <= element.getEnd()) { continue; } - let name = element.propertyName || element.name; + const name = element.propertyName || element.name; exisingImportsOrExports[name.text] = true; } @@ -3746,8 +3745,8 @@ namespace ts { return contextualMemberSymbols; } - let existingMemberNames: Map = {}; - for (let m of existingMembers) { + const existingMemberNames: Map = {}; + for (const m of existingMembers) { // Ignore omitted expressions for missing members if (m.kind !== SyntaxKind.PropertyAssignment && m.kind !== SyntaxKind.ShorthandPropertyAssignment && @@ -3766,7 +3765,7 @@ namespace ts { if (m.kind === SyntaxKind.BindingElement && (m).propertyName) { // include only identifiers in completion list if ((m).propertyName.kind === SyntaxKind.Identifier) { - existingName = ((m).propertyName).text + existingName = ((m).propertyName).text; } } else { @@ -3789,8 +3788,8 @@ namespace ts { * do not occur at the current position and have not otherwise been typed. */ function filterJsxAttributes(symbols: Symbol[], attributes: NodeArray): Symbol[] { - let seenNames: Map = {}; - for (let attr of attributes) { + const seenNames: Map = {}; + for (const attr of attributes) { // If this is the current item we are editing right now, do not filter it out if (attr.getStart() <= position && position <= attr.getEnd()) { continue; @@ -3809,21 +3808,21 @@ namespace ts { function getCompletionsAtPosition(fileName: string, position: number): CompletionInfo { synchronizeHostData(); - let completionData = getCompletionData(fileName, position); + const completionData = getCompletionData(fileName, position); if (!completionData) { return undefined; } - let { symbols, isMemberCompletion, isNewIdentifierLocation, location, isRightOfDot, isJsDocTagName } = completionData; + const { symbols, isMemberCompletion, isNewIdentifierLocation, location, isRightOfDot, isJsDocTagName } = completionData; if (isJsDocTagName) { // If the current position is a jsDoc tag name, only tag names should be provided for completion return { isMemberCompletion: false, isNewIdentifierLocation: false, entries: getAllJsDocCompletionEntries() }; } - let sourceFile = getValidSourceFile(fileName); + const sourceFile = getValidSourceFile(fileName); - let entries: CompletionEntry[] = []; + const entries: CompletionEntry[] = []; if (isRightOfDot && isSourceFileJavaScript(sourceFile)) { const uniqueNames = getCompletionEntriesFromSymbols(symbols, entries); @@ -3845,16 +3844,16 @@ namespace ts { return { isMemberCompletion, isNewIdentifierLocation, entries }; function getJavaScriptCompletionEntries(sourceFile: SourceFile, uniqueNames: Map): CompletionEntry[] { - let entries: CompletionEntry[] = []; - let target = program.getCompilerOptions().target; + const entries: CompletionEntry[] = []; + const target = program.getCompilerOptions().target; - let nameTable = getNameTable(sourceFile); - for (let name in nameTable) { + const nameTable = getNameTable(sourceFile); + for (const name in nameTable) { if (!uniqueNames[name]) { uniqueNames[name] = name; - let displayName = getCompletionEntryDisplayName(name, target, /*performCharacterChecks:*/ true); + const displayName = getCompletionEntryDisplayName(name, target, /*performCharacterChecks*/ true); if (displayName) { - let entry = { + const entry = { name: displayName, kind: ScriptElementKind.warning, kindModifiers: "", @@ -3875,7 +3874,7 @@ namespace ts { kind: ScriptElementKind.keyword, kindModifiers: "", sortText: "0", - } + }; })); } @@ -3883,7 +3882,7 @@ namespace ts { // Try to get a valid display name for this symbol, if we could not find one, then ignore it. // We would like to only show things that can be added after a dot, so for instance numeric properties can // not be accessed with a dot (a.1 <- invalid) - let displayName = getCompletionEntryDisplayNameForSymbol(symbol, program.getCompilerOptions().target, /*performCharacterChecks:*/ true, location); + const displayName = getCompletionEntryDisplayNameForSymbol(symbol, program.getCompilerOptions().target, /*performCharacterChecks*/ true, location); if (!displayName) { return undefined; } @@ -3905,13 +3904,13 @@ namespace ts { } function getCompletionEntriesFromSymbols(symbols: Symbol[], entries: CompletionEntry[]): Map { - let start = new Date().getTime(); - let uniqueNames: Map = {}; + const start = new Date().getTime(); + const uniqueNames: Map = {}; if (symbols) { - for (let symbol of symbols) { - let entry = createCompletionEntry(symbol, location); + for (const symbol of symbols) { + const entry = createCompletionEntry(symbol, location); if (entry) { - let id = escapeIdentifier(entry.name); + const id = escapeIdentifier(entry.name); if (!lookUp(uniqueNames, id)) { entries.push(entry); uniqueNames[id] = id; @@ -3929,19 +3928,19 @@ namespace ts { synchronizeHostData(); // Compute all the completion symbols again. - let completionData = getCompletionData(fileName, position); + const completionData = getCompletionData(fileName, position); if (completionData) { - let { symbols, location } = completionData; + const { symbols, location } = completionData; // Find the symbol with the matching entry name. - let target = program.getCompilerOptions().target; + const target = program.getCompilerOptions().target; // We don't need to perform character checks here because we're only comparing the // name against 'entryName' (which is known to be good), not building a new // completion entry. - let symbol = forEach(symbols, s => getCompletionEntryDisplayNameForSymbol(s, target, /*performCharacterChecks:*/ false, location) === entryName ? s : undefined); + const symbol = forEach(symbols, s => getCompletionEntryDisplayNameForSymbol(s, target, /*performCharacterChecks*/ false, location) === entryName ? s : undefined); if (symbol) { - let { displayParts, documentation, symbolKind } = getSymbolDisplayPartsDocumentationAndSymbolKind(symbol, getValidSourceFile(fileName), location, location, SemanticMeaning.All); + const { displayParts, documentation, symbolKind } = getSymbolDisplayPartsDocumentationAndSymbolKind(symbol, getValidSourceFile(fileName), location, location, SemanticMeaning.All); return { name: entryName, kindModifiers: getSymbolModifiers(symbol), @@ -3953,7 +3952,7 @@ namespace ts { } // Didn't find a symbol with this name. See if we can find a keyword instead. - let keywordCompletion = forEach(keywordCompletions, c => c.name === entryName); + const keywordCompletion = forEach(keywordCompletions, c => c.name === entryName); if (keywordCompletion) { return { name: entryName, @@ -3969,7 +3968,7 @@ namespace ts { // TODO(drosen): use contextual SemanticMeaning. function getSymbolKind(symbol: Symbol, location: Node): string { - let flags = symbol.getFlags(); + const flags = symbol.getFlags(); if (flags & SymbolFlags.Class) return getDeclarationOfKind(symbol, SyntaxKind.ClassExpression) ? ScriptElementKind.localClassElement : ScriptElementKind.classElement; @@ -3978,7 +3977,7 @@ namespace ts { if (flags & SymbolFlags.Interface) return ScriptElementKind.interfaceElement; if (flags & SymbolFlags.TypeParameter) return ScriptElementKind.typeParameterElement; - let result = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(symbol, flags, location); + const result = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(symbol, flags, location); if (result === ScriptElementKind.unknown) { if (flags & SymbolFlags.TypeParameter) return ScriptElementKind.typeParameterElement; if (flags & SymbolFlags.EnumMember) return ScriptElementKind.variableElement; @@ -3990,7 +3989,7 @@ namespace ts { } function getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(symbol: Symbol, flags: SymbolFlags, location: Node) { - let typeChecker = program.getTypeChecker(); + const typeChecker = program.getTypeChecker(); if (typeChecker.isUndefinedSymbol(symbol)) { return ScriptElementKind.variableElement; @@ -4019,8 +4018,8 @@ namespace ts { if (flags & SymbolFlags.Property) { if (flags & SymbolFlags.SyntheticProperty) { // If union property is result of union of non method (property/accessors/variables), it is labeled as property - let unionPropertyKind = forEach(typeChecker.getRootSymbols(symbol), rootSymbol => { - let rootSymbolFlags = rootSymbol.getFlags(); + const unionPropertyKind = forEach(typeChecker.getRootSymbols(symbol), rootSymbol => { + const rootSymbolFlags = rootSymbol.getFlags(); if (rootSymbolFlags & (SymbolFlags.PropertyOrAccessor | SymbolFlags.Variable)) { return ScriptElementKind.memberVariableElement; } @@ -4028,8 +4027,8 @@ namespace ts { }); if (!unionPropertyKind) { // If this was union of all methods, - //make sure it has call signatures before we can label it as method - let typeOfUnionProperty = typeChecker.getTypeOfSymbolAtLocation(symbol, location); + // make sure it has call signatures before we can label it as method + const typeOfUnionProperty = typeChecker.getTypeOfSymbolAtLocation(symbol, location); if (typeOfUnionProperty.getCallSignatures().length) { return ScriptElementKind.memberFunctionElement; } @@ -4053,11 +4052,11 @@ namespace ts { function getSymbolDisplayPartsDocumentationAndSymbolKind(symbol: Symbol, sourceFile: SourceFile, enclosingDeclaration: Node, location: Node, semanticMeaning = getMeaningFromLocation(location)) { - let typeChecker = program.getTypeChecker(); + const typeChecker = program.getTypeChecker(); - let displayParts: SymbolDisplayPart[] = []; + const displayParts: SymbolDisplayPart[] = []; let documentation: SymbolDisplayPart[]; - let symbolFlags = symbol.flags; + const symbolFlags = symbol.flags; let symbolKind = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(symbol, symbolFlags, location); let hasAddedSymbolInfo: boolean; let type: Type; @@ -4073,7 +4072,7 @@ namespace ts { type = typeChecker.getTypeOfSymbolAtLocation(symbol, location); if (type) { if (location.parent && location.parent.kind === SyntaxKind.PropertyAccessExpression) { - let right = (location.parent).name; + const right = (location.parent).name; // Either the location is on the right of a property access, or on the left and the right is missing if (right === location || (right && right.getFullWidth() === 0)) { location = location.parent; @@ -4090,15 +4089,15 @@ namespace ts { } if (callExpression) { - let candidateSignatures: Signature[] = []; + const candidateSignatures: Signature[] = []; signature = typeChecker.getResolvedSignature(callExpression, candidateSignatures); if (!signature && candidateSignatures.length) { // Use the first candidate: signature = candidateSignatures[0]; } - let useConstructSignatures = callExpression.kind === SyntaxKind.NewExpression || callExpression.expression.kind === SyntaxKind.SuperKeyword; - let allSignatures = useConstructSignatures ? type.getConstructSignatures() : type.getCallSignatures(); + const useConstructSignatures = callExpression.kind === SyntaxKind.NewExpression || callExpression.expression.kind === SyntaxKind.SuperKeyword; + const allSignatures = useConstructSignatures ? type.getConstructSignatures() : type.getCallSignatures(); if (!contains(allSignatures, signature.target) && !contains(allSignatures, signature)) { // Get the first signature if there is one -- allSignatures may contain @@ -4156,8 +4155,8 @@ namespace ts { else if ((isNameOfFunctionDeclaration(location) && !(symbol.flags & SymbolFlags.Accessor)) || // name of function declaration (location.kind === SyntaxKind.ConstructorKeyword && location.parent.kind === SyntaxKind.Constructor)) { // At constructor keyword of constructor declaration // get the signature from the declaration and write it - let functionDeclaration = location.parent; - let allSignatures = functionDeclaration.kind === SyntaxKind.Constructor ? type.getConstructSignatures() : type.getCallSignatures(); + const functionDeclaration = location.parent; + const allSignatures = functionDeclaration.kind === SyntaxKind.Constructor ? type.getConstructSignatures() : type.getCallSignatures(); if (!typeChecker.isImplementationOfOverload(functionDeclaration)) { signature = typeChecker.getSignatureFromDeclaration(functionDeclaration); } @@ -4226,8 +4225,8 @@ namespace ts { } if (symbolFlags & SymbolFlags.Module) { addNewLineIfDisplayPartsExist(); - let declaration = getDeclarationOfKind(symbol, SyntaxKind.ModuleDeclaration); - let isNamespace = declaration && declaration.name && declaration.name.kind === SyntaxKind.Identifier; + const declaration = getDeclarationOfKind(symbol, SyntaxKind.ModuleDeclaration); + const isNamespace = declaration && declaration.name && declaration.name.kind === SyntaxKind.Identifier; displayParts.push(keywordPart(isNamespace ? SyntaxKind.NamespaceKeyword : SyntaxKind.ModuleKeyword)); displayParts.push(spacePart()); addFullSymbolName(symbol); @@ -4279,9 +4278,9 @@ namespace ts { } if (symbolFlags & SymbolFlags.EnumMember) { addPrefixForAnyFunctionOrVar(symbol, "enum member"); - let declaration = symbol.declarations[0]; + const declaration = symbol.declarations[0]; if (declaration.kind === SyntaxKind.EnumMember) { - let constantValue = typeChecker.getConstantValue(declaration); + const constantValue = typeChecker.getConstantValue(declaration); if (constantValue !== undefined) { displayParts.push(spacePart()); displayParts.push(operatorPart(SyntaxKind.EqualsToken)); @@ -4297,7 +4296,7 @@ namespace ts { addFullSymbolName(symbol); ts.forEach(symbol.declarations, declaration => { if (declaration.kind === SyntaxKind.ImportEqualsDeclaration) { - let importEqualsDeclaration = declaration; + const importEqualsDeclaration = declaration; if (isExternalModuleImportEqualsDeclaration(importEqualsDeclaration)) { displayParts.push(spacePart()); displayParts.push(operatorPart(SyntaxKind.EqualsToken)); @@ -4308,7 +4307,7 @@ namespace ts { displayParts.push(punctuationPart(SyntaxKind.CloseParenToken)); } else { - let internalAliasSymbol = typeChecker.getSymbolAtLocation(importEqualsDeclaration.moduleReference); + const internalAliasSymbol = typeChecker.getSymbolAtLocation(importEqualsDeclaration.moduleReference); if (internalAliasSymbol) { displayParts.push(spacePart()); displayParts.push(operatorPart(SyntaxKind.EqualsToken)); @@ -4332,7 +4331,7 @@ namespace ts { displayParts.push(spacePart()); // If the type is type parameter, format it specially if (type.symbol && type.symbol.flags & SymbolFlags.TypeParameter) { - let typeParameterParts = mapToDisplayParts(writer => { + const typeParameterParts = mapToDisplayParts(writer => { typeChecker.getSymbolDisplayBuilder().buildTypeParameterDisplay(type, writer, enclosingDeclaration); }); addRange(displayParts, typeParameterParts); @@ -4347,7 +4346,7 @@ namespace ts { symbolFlags & SymbolFlags.Signature || symbolFlags & SymbolFlags.Accessor || symbolKind === ScriptElementKind.memberFunctionElement) { - let allSignatures = type.getCallSignatures(); + const allSignatures = type.getCallSignatures(); addSignatureDisplayParts(allSignatures[0], allSignatures); } } @@ -4370,7 +4369,7 @@ namespace ts { } function addFullSymbolName(symbol: Symbol, enclosingDeclaration?: Node) { - let fullSymbolDisplayParts = symbolToDisplayParts(typeChecker, symbol, enclosingDeclaration || sourceFile, /*meaning*/ undefined, + const fullSymbolDisplayParts = symbolToDisplayParts(typeChecker, symbol, enclosingDeclaration || sourceFile, /*meaning*/ undefined, SymbolFormatFlags.WriteTypeParametersOrArguments | SymbolFormatFlags.UseOnlyExternalAliasing); addRange(displayParts, fullSymbolDisplayParts); } @@ -4416,7 +4415,7 @@ namespace ts { } function writeTypeParametersOfSymbol(symbol: Symbol, enclosingDeclaration: Node) { - let typeParameterParts = mapToDisplayParts(writer => { + const typeParameterParts = mapToDisplayParts(writer => { typeChecker.getSymbolDisplayBuilder().buildTypeParameterDisplayFromSymbol(symbol, writer, enclosingDeclaration); }); addRange(displayParts, typeParameterParts); @@ -4426,8 +4425,8 @@ namespace ts { function getQuickInfoAtPosition(fileName: string, position: number): QuickInfo { synchronizeHostData(); - let sourceFile = getValidSourceFile(fileName); - let node = getTouchingPropertyName(sourceFile, position); + const sourceFile = getValidSourceFile(fileName); + const node = getTouchingPropertyName(sourceFile, position); if (!node) { return undefined; } @@ -4436,8 +4435,8 @@ namespace ts { return undefined; } - let typeChecker = program.getTypeChecker(); - let symbol = typeChecker.getSymbolAtLocation(node); + const typeChecker = program.getTypeChecker(); + const symbol = typeChecker.getSymbolAtLocation(node); if (!symbol) { // Try getting just type at this position and show @@ -4449,7 +4448,7 @@ namespace ts { case SyntaxKind.ThisType: case SyntaxKind.SuperKeyword: // For the identifiers/this/super etc get the type at position - let type = typeChecker.getTypeAtLocation(node); + const type = typeChecker.getTypeAtLocation(node); if (type) { return { kind: ScriptElementKind.unknown, @@ -4464,7 +4463,7 @@ namespace ts { return undefined; } - let displayPartsDocumentationsAndKind = getSymbolDisplayPartsDocumentationAndSymbolKind(symbol, sourceFile, getContainerNode(node), node); + const displayPartsDocumentationsAndKind = getSymbolDisplayPartsDocumentationAndSymbolKind(symbol, sourceFile, getContainerNode(node), node); return { kind: displayPartsDocumentationsAndKind.symbolKind, kindModifiers: getSymbolModifiers(symbol), @@ -4486,13 +4485,13 @@ namespace ts { } function getDefinitionFromSymbol(symbol: Symbol, node: Node): DefinitionInfo[] { - let typeChecker = program.getTypeChecker(); - let result: DefinitionInfo[] = []; - let declarations = symbol.getDeclarations(); - let symbolName = typeChecker.symbolToString(symbol); // Do not get scoped name, just the name of the symbol - let symbolKind = getSymbolKind(symbol, node); - let containerSymbol = symbol.parent; - let containerName = containerSymbol ? typeChecker.symbolToString(containerSymbol, node) : ""; + const typeChecker = program.getTypeChecker(); + const result: DefinitionInfo[] = []; + const declarations = symbol.getDeclarations(); + const symbolName = typeChecker.symbolToString(symbol); // Do not get scoped name, just the name of the symbol + const symbolKind = getSymbolKind(symbol, node); + const containerSymbol = symbol.parent; + const containerName = containerSymbol ? typeChecker.symbolToString(containerSymbol, node) : ""; if (!tryAddConstructSignature(symbol, node, symbolKind, symbolName, containerName, result) && !tryAddCallSignature(symbol, node, symbolKind, symbolName, containerName, result)) { @@ -4510,7 +4509,7 @@ namespace ts { if (isNewExpressionTarget(location) || location.kind === SyntaxKind.ConstructorKeyword) { if (symbol.flags & SymbolFlags.Class) { // Find the first class-like declaration and try to get the construct signature. - for (let declaration of symbol.getDeclarations()) { + for (const declaration of symbol.getDeclarations()) { if (isClassLike(declaration)) { return tryAddSignature(declaration.members, /*selectConstructors*/ true, @@ -4535,7 +4534,7 @@ namespace ts { } function tryAddSignature(signatureDeclarations: Declaration[], selectConstructors: boolean, symbolKind: string, symbolName: string, containerName: string, result: DefinitionInfo[]) { - let declarations: Declaration[] = []; + const declarations: Declaration[] = []; let definition: Declaration; forEach(signatureDeclarations, d => { @@ -4563,24 +4562,24 @@ namespace ts { function getDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[] { synchronizeHostData(); - let sourceFile = getValidSourceFile(fileName); + const sourceFile = getValidSourceFile(fileName); - let node = getTouchingPropertyName(sourceFile, position); + const node = getTouchingPropertyName(sourceFile, position); if (!node) { return undefined; } // Labels if (isJumpStatementTarget(node)) { - let labelName = (node).text; - let label = getTargetLabel((node.parent), (node).text); + const labelName = (node).text; + const label = getTargetLabel((node.parent), (node).text); return label ? [createDefinitionInfo(label, ScriptElementKind.label, labelName, /*containerName*/ undefined)] : undefined; } /// Triple slash reference comments - let comment = forEach(sourceFile.referencedFiles, r => (r.pos <= position && position < r.end) ? r : undefined); + const comment = forEach(sourceFile.referencedFiles, r => (r.pos <= position && position < r.end) ? r : undefined); if (comment) { - let referenceFile = tryResolveScriptReference(program, sourceFile, comment); + const referenceFile = tryResolveScriptReference(program, sourceFile, comment); if (referenceFile) { return [{ fileName: referenceFile.fileName, @@ -4594,7 +4593,7 @@ namespace ts { return undefined; } - let typeChecker = program.getTypeChecker(); + const typeChecker = program.getTypeChecker(); let symbol = typeChecker.getSymbolAtLocation(node); // Could not find a symbol e.g. node is string or number keyword, @@ -4608,7 +4607,7 @@ namespace ts { // import {A, B} from "mod"; // to jump to the implementation directly. if (symbol.flags & SymbolFlags.Alias) { - let declaration = symbol.declarations[0]; + const declaration = symbol.declarations[0]; if (node.kind === SyntaxKind.Identifier && node.parent === declaration) { symbol = typeChecker.getAliasedSymbol(symbol); } @@ -4620,15 +4619,15 @@ namespace ts { // is performed at the location of property access, we would like to go to definition of the property in the short-hand // assignment. This case and others are handled by the following code. if (node.parent.kind === SyntaxKind.ShorthandPropertyAssignment) { - let shorthandSymbol = typeChecker.getShorthandAssignmentValueSymbol(symbol.valueDeclaration); + const shorthandSymbol = typeChecker.getShorthandAssignmentValueSymbol(symbol.valueDeclaration); if (!shorthandSymbol) { return []; } - let shorthandDeclarations = shorthandSymbol.getDeclarations(); - let shorthandSymbolKind = getSymbolKind(shorthandSymbol, node); - let shorthandSymbolName = typeChecker.symbolToString(shorthandSymbol); - let shorthandContainerName = typeChecker.symbolToString(symbol.parent, node); + const shorthandDeclarations = shorthandSymbol.getDeclarations(); + const shorthandSymbolKind = getSymbolKind(shorthandSymbol, node); + const shorthandSymbolName = typeChecker.symbolToString(shorthandSymbol); + const shorthandContainerName = typeChecker.symbolToString(symbol.parent, node); return map(shorthandDeclarations, declaration => createDefinitionInfo(declaration, shorthandSymbolKind, shorthandSymbolName, shorthandContainerName)); } @@ -4640,27 +4639,27 @@ namespace ts { function getTypeDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[] { synchronizeHostData(); - let sourceFile = getValidSourceFile(fileName); + const sourceFile = getValidSourceFile(fileName); - let node = getTouchingPropertyName(sourceFile, position); + const node = getTouchingPropertyName(sourceFile, position); if (!node) { return undefined; } - let typeChecker = program.getTypeChecker(); + const typeChecker = program.getTypeChecker(); - let symbol = typeChecker.getSymbolAtLocation(node); + const symbol = typeChecker.getSymbolAtLocation(node); if (!symbol) { return undefined; } - let type = typeChecker.getTypeOfSymbolAtLocation(symbol, node); + const type = typeChecker.getTypeOfSymbolAtLocation(symbol, node); if (!type) { return undefined; } if (type.flags & TypeFlags.Union) { - let result: DefinitionInfo[] = []; + const result: DefinitionInfo[] = []; forEach((type).types, t => { if (t.symbol) { addRange(/*to*/ result, /*from*/ getDefinitionFromSymbol(t.symbol, node)); @@ -4680,7 +4679,7 @@ namespace ts { let results = getOccurrencesAtPositionCore(fileName, position); if (results) { - let sourceFile = getCanonicalFileName(normalizeSlashes(fileName)); + const sourceFile = getCanonicalFileName(normalizeSlashes(fileName)); // Get occurrences only supports reporting occurrences for the file queried. So // filter down to that list. @@ -4694,10 +4693,10 @@ namespace ts { synchronizeHostData(); filesToSearch = map(filesToSearch, normalizeSlashes); - let sourceFilesToSearch = filter(program.getSourceFiles(), f => contains(filesToSearch, f.fileName)); - let sourceFile = getValidSourceFile(fileName); + const sourceFilesToSearch = filter(program.getSourceFiles(), f => contains(filesToSearch, f.fileName)); + const sourceFile = getValidSourceFile(fileName); - let node = getTouchingWord(sourceFile, position); + const node = getTouchingWord(sourceFile, position); if (!node) { return undefined; } @@ -4705,8 +4704,8 @@ namespace ts { return getSemanticDocumentHighlights(node) || getSyntacticDocumentHighlights(node); function getHighlightSpanForNode(node: Node): HighlightSpan { - let start = node.getStart(); - let end = node.getEnd(); + const start = node.getStart(); + const end = node.getEnd(); return { fileName: sourceFile.fileName, @@ -4723,7 +4722,7 @@ namespace ts { isLiteralNameOfPropertyDeclarationOrIndexAccess(node) || isNameOfExternalModuleImportOrDeclaration(node)) { - let referencedSymbols = getReferencedSymbolsForNode(node, sourceFilesToSearch, /*findInStrings:*/ false, /*findInComments:*/ false); + const referencedSymbols = getReferencedSymbolsForNode(node, sourceFilesToSearch, /*findInStrings*/ false, /*findInComments*/ false); return convertReferencedSymbols(referencedSymbols); } @@ -4734,11 +4733,11 @@ namespace ts { return undefined; } - let fileNameToDocumentHighlights: Map = {}; - let result: DocumentHighlights[] = []; - for (let referencedSymbol of referencedSymbols) { - for (let referenceEntry of referencedSymbol.references) { - let fileName = referenceEntry.fileName; + const fileNameToDocumentHighlights: Map = {}; + const result: DocumentHighlights[] = []; + for (const referencedSymbol of referencedSymbols) { + for (const referenceEntry of referencedSymbol.references) { + const fileName = referenceEntry.fileName; let documentHighlights = getProperty(fileNameToDocumentHighlights, fileName); if (!documentHighlights) { documentHighlights = { fileName, highlightSpans: [] }; @@ -4759,9 +4758,9 @@ namespace ts { } function getSyntacticDocumentHighlights(node: Node): DocumentHighlights[] { - let fileName = sourceFile.fileName; + const fileName = sourceFile.fileName; - let highlightSpans = getHighlightSpans(node); + const highlightSpans = getHighlightSpans(node); if (!highlightSpans || highlightSpans.length === 0) { return undefined; } @@ -4865,7 +4864,7 @@ namespace ts { * into function boundaries and try-blocks with catch-clauses. */ function aggregateOwnedThrowStatements(node: Node): ThrowStatement[] { - let statementAccumulator: ThrowStatement[] = [] + const statementAccumulator: ThrowStatement[] = []; aggregate(node); return statementAccumulator; @@ -4874,7 +4873,7 @@ namespace ts { statementAccumulator.push(node); } else if (node.kind === SyntaxKind.TryStatement) { - let tryStatement = node; + const tryStatement = node; if (tryStatement.catchClause) { aggregate(tryStatement.catchClause); @@ -4905,7 +4904,7 @@ namespace ts { let child: Node = throwStatement; while (child.parent) { - let parent = child.parent; + const parent = child.parent; if (isFunctionBlock(parent) || parent.kind === SyntaxKind.SourceFile) { return parent; @@ -4914,7 +4913,7 @@ namespace ts { // A throw-statement is only owned by a try-statement if the try-statement has // a catch clause, and if the throw-statement occurs within the try block. if (parent.kind === SyntaxKind.TryStatement) { - let tryStatement = parent; + const tryStatement = parent; if (tryStatement.tryBlock === child && tryStatement.catchClause) { return child; @@ -4928,7 +4927,7 @@ namespace ts { } function aggregateAllBreakAndContinueStatements(node: Node): BreakOrContinueStatement[] { - let statementAccumulator: BreakOrContinueStatement[] = [] + const statementAccumulator: BreakOrContinueStatement[] = []; aggregate(node); return statementAccumulator; @@ -4944,7 +4943,7 @@ namespace ts { } function ownsBreakOrContinueStatement(owner: Node, statement: BreakOrContinueStatement): boolean { - let actualOwner = getBreakOrContinueOwner(statement); + const actualOwner = getBreakOrContinueOwner(statement); return actualOwner && actualOwner === owner; } @@ -4979,7 +4978,7 @@ namespace ts { } function getModifierOccurrences(modifier: SyntaxKind, declaration: Node): HighlightSpan[] { - let container = declaration.parent; + const container = declaration.parent; // Make sure we only highlight the keyword when it makes sense to do so. if (isAccessibilityModifier(modifier)) { @@ -5009,8 +5008,8 @@ namespace ts { return undefined; } - let keywords: Node[] = []; - let modifierFlag: NodeFlags = getFlagFromModifier(modifier); + const keywords: Node[] = []; + const modifierFlag: NodeFlags = getFlagFromModifier(modifier); let nodes: Node[]; switch (container.kind) { @@ -5035,7 +5034,7 @@ namespace ts { // If we're an accessibility modifier, we're in an instance member and should search // the constructor's parameter list for instance members as well. if (modifierFlag & NodeFlags.AccessibilityModifier) { - let constructor = forEach((container).members, member => { + const constructor = forEach((container).members, member => { return member.kind === SyntaxKind.Constructor && member; }); @@ -5048,7 +5047,7 @@ namespace ts { } break; default: - Debug.fail("Invalid container kind.") + Debug.fail("Invalid container kind."); } forEach(nodes, node => { @@ -5091,7 +5090,7 @@ namespace ts { } function getGetAndSetOccurrences(accessorDeclaration: AccessorDeclaration): HighlightSpan[] { - let keywords: Node[] = []; + const keywords: Node[] = []; tryPushAccessorKeyword(accessorDeclaration.symbol, SyntaxKind.GetAccessor); tryPushAccessorKeyword(accessorDeclaration.symbol, SyntaxKind.SetAccessor); @@ -5099,7 +5098,7 @@ namespace ts { return map(keywords, getHighlightSpanForNode); function tryPushAccessorKeyword(accessorSymbol: Symbol, accessorKind: SyntaxKind): void { - let accessor = getDeclarationOfKind(accessorSymbol, accessorKind); + const accessor = getDeclarationOfKind(accessorSymbol, accessorKind); if (accessor) { forEach(accessor.getChildren(), child => pushKeywordIf(keywords, child, SyntaxKind.GetKeyword, SyntaxKind.SetKeyword)); @@ -5108,9 +5107,9 @@ namespace ts { } function getConstructorOccurrences(constructorDeclaration: ConstructorDeclaration): HighlightSpan[] { - let declarations = constructorDeclaration.symbol.getDeclarations() + const declarations = constructorDeclaration.symbol.getDeclarations(); - let keywords: Node[] = []; + const keywords: Node[] = []; forEach(declarations, declaration => { forEach(declaration.getChildren(), token => { @@ -5122,12 +5121,12 @@ namespace ts { } function getLoopBreakContinueOccurrences(loopNode: IterationStatement): HighlightSpan[] { - let keywords: Node[] = []; + const keywords: Node[] = []; if (pushKeywordIf(keywords, loopNode.getFirstToken(), SyntaxKind.ForKeyword, SyntaxKind.WhileKeyword, SyntaxKind.DoKeyword)) { // If we succeeded and got a do-while loop, then start looking for a 'while' keyword. if (loopNode.kind === SyntaxKind.DoStatement) { - let loopTokens = loopNode.getChildren(); + const loopTokens = loopNode.getChildren(); for (let i = loopTokens.length - 1; i >= 0; i--) { if (pushKeywordIf(keywords, loopTokens[i], SyntaxKind.WhileKeyword)) { @@ -5137,7 +5136,7 @@ namespace ts { } } - let breaksAndContinues = aggregateAllBreakAndContinueStatements(loopNode.statement); + const breaksAndContinues = aggregateAllBreakAndContinueStatements(loopNode.statement); forEach(breaksAndContinues, statement => { if (ownsBreakOrContinueStatement(loopNode, statement)) { @@ -5149,7 +5148,7 @@ namespace ts { } function getBreakOrContinueStatementOccurrences(breakOrContinueStatement: BreakOrContinueStatement): HighlightSpan[] { - let owner = getBreakOrContinueOwner(breakOrContinueStatement); + const owner = getBreakOrContinueOwner(breakOrContinueStatement); if (owner) { switch (owner.kind) { @@ -5158,7 +5157,7 @@ namespace ts { case SyntaxKind.ForOfStatement: case SyntaxKind.DoStatement: case SyntaxKind.WhileStatement: - return getLoopBreakContinueOccurrences(owner) + return getLoopBreakContinueOccurrences(owner); case SyntaxKind.SwitchStatement: return getSwitchCaseDefaultOccurrences(owner); @@ -5169,7 +5168,7 @@ namespace ts { } function getSwitchCaseDefaultOccurrences(switchStatement: SwitchStatement): HighlightSpan[] { - let keywords: Node[] = []; + const keywords: Node[] = []; pushKeywordIf(keywords, switchStatement.getFirstToken(), SyntaxKind.SwitchKeyword); @@ -5177,7 +5176,7 @@ namespace ts { forEach(switchStatement.caseBlock.clauses, clause => { pushKeywordIf(keywords, clause.getFirstToken(), SyntaxKind.CaseKeyword, SyntaxKind.DefaultKeyword); - let breaksAndContinues = aggregateAllBreakAndContinueStatements(clause); + const breaksAndContinues = aggregateAllBreakAndContinueStatements(clause); forEach(breaksAndContinues, statement => { if (ownsBreakOrContinueStatement(switchStatement, statement)) { @@ -5190,7 +5189,7 @@ namespace ts { } function getTryCatchFinallyOccurrences(tryStatement: TryStatement): HighlightSpan[] { - let keywords: Node[] = []; + const keywords: Node[] = []; pushKeywordIf(keywords, tryStatement.getFirstToken(), SyntaxKind.TryKeyword); @@ -5199,7 +5198,7 @@ namespace ts { } if (tryStatement.finallyBlock) { - let finallyKeyword = findChildOfKind(tryStatement, SyntaxKind.FinallyKeyword, sourceFile); + const finallyKeyword = findChildOfKind(tryStatement, SyntaxKind.FinallyKeyword, sourceFile); pushKeywordIf(keywords, finallyKeyword, SyntaxKind.FinallyKeyword); } @@ -5207,13 +5206,13 @@ namespace ts { } function getThrowOccurrences(throwStatement: ThrowStatement): HighlightSpan[] { - let owner = getThrowStatementOwner(throwStatement); + const owner = getThrowStatementOwner(throwStatement); if (!owner) { return undefined; } - let keywords: Node[] = []; + const keywords: Node[] = []; forEach(aggregateOwnedThrowStatements(owner), throwStatement => { pushKeywordIf(keywords, throwStatement.getFirstToken(), SyntaxKind.ThrowKeyword); @@ -5231,14 +5230,14 @@ namespace ts { } function getReturnOccurrences(returnStatement: ReturnStatement): HighlightSpan[] { - let func = getContainingFunction(returnStatement); + const func = getContainingFunction(returnStatement); // If we didn't find a containing function with a block body, bail out. if (!(func && hasKind(func.body, SyntaxKind.Block))) { return undefined; } - let keywords: Node[] = [] + const keywords: Node[] = []; forEachReturnStatement(func.body, returnStatement => { pushKeywordIf(keywords, returnStatement.getFirstToken(), SyntaxKind.ReturnKeyword); }); @@ -5252,7 +5251,7 @@ namespace ts { } function getIfElseOccurrences(ifStatement: IfStatement): HighlightSpan[] { - let keywords: Node[] = []; + const keywords: Node[] = []; // Traverse upwards through all parent if-statements linked by their else-branches. while (hasKind(ifStatement.parent, SyntaxKind.IfStatement) && (ifStatement.parent).elseStatement === ifStatement) { @@ -5261,7 +5260,7 @@ namespace ts { // Now traverse back down through the else branches, aggregating if/else keywords of if-statements. while (ifStatement) { - let children = ifStatement.getChildren(); + const children = ifStatement.getChildren(); pushKeywordIf(keywords, children[0], SyntaxKind.IfKeyword); // Generally the 'else' keyword is second-to-last, so we traverse backwards. @@ -5272,20 +5271,20 @@ namespace ts { } if (!hasKind(ifStatement.elseStatement, SyntaxKind.IfStatement)) { - break + break; } ifStatement = ifStatement.elseStatement; } - let result: HighlightSpan[] = []; + const result: HighlightSpan[] = []; // We'd like to highlight else/ifs together if they are only separated by whitespace // (i.e. the keywords are separated by no comments, no newlines). for (let i = 0; i < keywords.length; i++) { if (keywords[i].kind === SyntaxKind.ElseKeyword && i < keywords.length - 1) { - let elseKeyword = keywords[i]; - let ifKeyword = keywords[i + 1]; // this *should* always be an 'if' keyword. + const elseKeyword = keywords[i]; + const ifKeyword = keywords[i + 1]; // this *should* always be an 'if' keyword. let shouldCombindElseAndIf = true; @@ -5328,9 +5327,9 @@ namespace ts { return undefined; } - let result: ReferenceEntry[] = []; - for (let entry of documentHighlights) { - for (let highlightSpan of entry.highlightSpans) { + const result: ReferenceEntry[] = []; + for (const entry of documentHighlights) { + for (const highlightSpan of entry.highlightSpans) { result.push({ fileName: entry.fileName, textSpan: highlightSpan.textSpan, @@ -5348,9 +5347,9 @@ namespace ts { return undefined; } - let referenceEntries: ReferenceEntry[] = []; + const referenceEntries: ReferenceEntry[] = []; - for (let referenceSymbol of referenceSymbols) { + for (const referenceSymbol of referenceSymbols) { addRange(referenceEntries, referenceSymbol.references); } @@ -5358,17 +5357,17 @@ namespace ts { } function findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): RenameLocation[] { - let referencedSymbols = findReferencedSymbols(fileName, position, findInStrings, findInComments); + const referencedSymbols = findReferencedSymbols(fileName, position, findInStrings, findInComments); return convertReferences(referencedSymbols); } function getReferencesAtPosition(fileName: string, position: number): ReferenceEntry[] { - let referencedSymbols = findReferencedSymbols(fileName, position, /*findInStrings:*/ false, /*findInComments:*/ false); + const referencedSymbols = findReferencedSymbols(fileName, position, /*findInStrings*/ false, /*findInComments*/ false); return convertReferences(referencedSymbols); } - function findReferences(fileName: string, position: number): ReferencedSymbol[]{ - let referencedSymbols = findReferencedSymbols(fileName, position, /*findInStrings:*/ false, /*findInComments:*/ false); + function findReferences(fileName: string, position: number): ReferencedSymbol[] { + const referencedSymbols = findReferencedSymbols(fileName, position, /*findInStrings*/ false, /*findInComments*/ false); // Only include referenced symbols that have a valid definition. return filter(referencedSymbols, rs => !!rs.definition); @@ -5377,17 +5376,17 @@ namespace ts { function findReferencedSymbols(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): ReferencedSymbol[] { synchronizeHostData(); - let sourceFile = getValidSourceFile(fileName); + const sourceFile = getValidSourceFile(fileName); - let node = getTouchingPropertyName(sourceFile, position); + const node = getTouchingPropertyName(sourceFile, position); if (!node) { return undefined; } if (node.kind !== SyntaxKind.Identifier && // TODO (drosen): This should be enabled in a later release - currently breaks rename. - //node.kind !== SyntaxKind.ThisKeyword && - //node.kind !== SyntaxKind.SuperKeyword && + // node.kind !== SyntaxKind.ThisKeyword && + // node.kind !== SyntaxKind.SuperKeyword && !isLiteralNameOfPropertyDeclarationOrIndexAccess(node) && !isNameOfExternalModuleImportOrDeclaration(node)) { return undefined; @@ -5398,12 +5397,12 @@ namespace ts { } function getReferencedSymbolsForNode(node: Node, sourceFiles: SourceFile[], findInStrings: boolean, findInComments: boolean): ReferencedSymbol[] { - let typeChecker = program.getTypeChecker(); + const typeChecker = program.getTypeChecker(); // Labels if (isLabelName(node)) { if (isJumpStatementTarget(node)) { - let labelDefinition = getTargetLabel((node.parent), (node).text); + const labelDefinition = getTargetLabel((node.parent), (node).text); // if we have a label definition, look within its statement for references, if not, then // the label is undefined and we have no results.. return labelDefinition ? getLabelReferencesInNode(labelDefinition.parent, labelDefinition) : undefined; @@ -5422,7 +5421,7 @@ namespace ts { return getReferencesForSuperKeyword(node); } - let symbol = typeChecker.getSymbolAtLocation(node); + const symbol = typeChecker.getSymbolAtLocation(node); // Could not find a symbol e.g. unknown identifier if (!symbol) { @@ -5430,7 +5429,7 @@ namespace ts { return undefined; } - let declarations = symbol.declarations; + const declarations = symbol.declarations; // The symbol was an internal symbol and does not have a declaration e.g. undefined symbol if (!declarations || !declarations.length) { @@ -5440,29 +5439,29 @@ namespace ts { let result: ReferencedSymbol[]; // Compute the meaning from the location and the symbol it references - let searchMeaning = getIntersectingMeaningFromDeclarations(getMeaningFromLocation(node), declarations); + const searchMeaning = getIntersectingMeaningFromDeclarations(getMeaningFromLocation(node), declarations); // Get the text to search for. // Note: if this is an external module symbol, the name doesn't include quotes. - let declaredName = stripQuotes(getDeclaredName(typeChecker, symbol, node)); + const declaredName = stripQuotes(getDeclaredName(typeChecker, symbol, node)); // Try to get the smallest valid scope that we can limit our search to; // otherwise we'll need to search globally (i.e. include each file). - let scope = getSymbolScope(symbol); + const scope = getSymbolScope(symbol); // Maps from a symbol ID to the ReferencedSymbol entry in 'result'. - let symbolToIndex: number[] = []; + const symbolToIndex: number[] = []; if (scope) { result = []; getReferencesInNode(scope, symbol, declaredName, node, searchMeaning, findInStrings, findInComments, result, symbolToIndex); } else { - let internedName = getInternedName(symbol, node, declarations) - for (let sourceFile of sourceFiles) { + const internedName = getInternedName(symbol, node, declarations); + for (const sourceFile of sourceFiles) { cancellationToken.throwIfCancellationRequested(); - let nameTable = getNameTable(sourceFile); + const nameTable = getNameTable(sourceFile); if (lookUp(nameTable, internedName)) { result = result || []; @@ -5474,9 +5473,9 @@ namespace ts { return result; function getDefinition(symbol: Symbol): DefinitionInfo { - let info = getSymbolDisplayPartsDocumentationAndSymbolKind(symbol, node.getSourceFile(), getContainerNode(node), node); - let name = map(info.displayParts, p => p.text).join(""); - let declarations = symbol.declarations; + const info = getSymbolDisplayPartsDocumentationAndSymbolKind(symbol, node.getSourceFile(), getContainerNode(node), node); + const name = map(info.displayParts, p => p.text).join(""); + const declarations = symbol.declarations; if (!declarations || declarations.length === 0) { return undefined; } @@ -5506,7 +5505,7 @@ namespace ts { // Try to get the local symbol if we're dealing with an 'export default' // since that symbol has the "true" name. - let localExportDefaultSymbol = getLocalSymbolForExportDefault(symbol); + const localExportDefaultSymbol = getLocalSymbolForExportDefault(symbol); symbol = localExportDefaultSymbol || symbol; return stripQuotes(symbol.name); @@ -5523,14 +5522,14 @@ namespace ts { function getSymbolScope(symbol: Symbol): Node { // If this is the symbol of a named function expression or named class expression, // then named references are limited to its own scope. - let valueDeclaration = symbol.valueDeclaration; + const valueDeclaration = symbol.valueDeclaration; if (valueDeclaration && (valueDeclaration.kind === SyntaxKind.FunctionExpression || valueDeclaration.kind === SyntaxKind.ClassExpression)) { return valueDeclaration; } // If this is private property or method, the scope is the containing class if (symbol.flags & (SymbolFlags.Property | SymbolFlags.Method)) { - let privateDeclaration = forEach(symbol.getDeclarations(), d => (d.flags & NodeFlags.Private) ? d : undefined); + const privateDeclaration = forEach(symbol.getDeclarations(), d => (d.flags & NodeFlags.Private) ? d : undefined); if (privateDeclaration) { return getAncestor(privateDeclaration, SyntaxKind.ClassDeclaration); } @@ -5548,12 +5547,12 @@ namespace ts { return undefined; } - let scope: Node = undefined; + let scope: Node; - let declarations = symbol.getDeclarations(); + const declarations = symbol.getDeclarations(); if (declarations) { - for (let declaration of declarations) { - let container = getContainerNode(declaration); + for (const declaration of declarations) { + const container = getContainerNode(declaration); if (!container) { return undefined; @@ -5579,7 +5578,7 @@ namespace ts { } function getPossibleSymbolReferencePositions(sourceFile: SourceFile, symbolName: string, start: number, end: number): number[] { - let positions: number[] = []; + const positions: number[] = []; /// TODO: Cache symbol existence for files to save text search // Also, need to make this work for unicode escapes. @@ -5589,9 +5588,9 @@ namespace ts { return positions; } - let text = sourceFile.text; - let sourceLength = text.length; - let symbolNameLength = symbolName.length; + const text = sourceFile.text; + const sourceLength = text.length; + const symbolNameLength = symbolName.length; let position = text.indexOf(symbolName, start); while (position >= 0) { @@ -5602,7 +5601,7 @@ namespace ts { // We found a match. Make sure it's not part of a larger word (i.e. the char // before and after it have to be a non-identifier char). - let endPosition = position + symbolNameLength; + const endPosition = position + symbolNameLength; if ((position === 0 || !isIdentifierPart(text.charCodeAt(position - 1), ScriptTarget.Latest)) && (endPosition === sourceLength || !isIdentifierPart(text.charCodeAt(endPosition), ScriptTarget.Latest))) { @@ -5616,14 +5615,14 @@ namespace ts { } function getLabelReferencesInNode(container: Node, targetLabel: Identifier): ReferencedSymbol[] { - let references: ReferenceEntry[] = []; - let sourceFile = container.getSourceFile(); - let labelName = targetLabel.text; - let possiblePositions = getPossibleSymbolReferencePositions(sourceFile, labelName, container.getStart(), container.getEnd()); + const references: ReferenceEntry[] = []; + const sourceFile = container.getSourceFile(); + const labelName = targetLabel.text; + const possiblePositions = getPossibleSymbolReferencePositions(sourceFile, labelName, container.getStart(), container.getEnd()); forEach(possiblePositions, position => { cancellationToken.throwIfCancellationRequested(); - let node = getTouchingWord(sourceFile, position); + const node = getTouchingWord(sourceFile, position); if (!node || node.getWidth() !== labelName.length) { return; } @@ -5635,14 +5634,14 @@ namespace ts { } }); - let definition: DefinitionInfo = { + const definition: DefinitionInfo = { containerKind: "", containerName: "", fileName: targetLabel.getSourceFile().fileName, kind: ScriptElementKind.label, name: labelName, textSpan: createTextSpanFromBounds(targetLabel.getStart(), targetLabel.getEnd()) - } + }; return [{ definition, references }]; } @@ -5687,19 +5686,19 @@ namespace ts { result: ReferencedSymbol[], symbolToIndex: number[]): void { - let sourceFile = container.getSourceFile(); - let tripleSlashDirectivePrefixRegex = /^\/\/\/\s* { cancellationToken.throwIfCancellationRequested(); - let referenceLocation = getTouchingPropertyName(sourceFile, position); + const referenceLocation = getTouchingPropertyName(sourceFile, position); if (!isValidReferencePosition(referenceLocation, searchText)) { // This wasn't the start of a token. Check to see if it might be a // match in a comment or string if that's what the caller is asking @@ -5727,14 +5726,14 @@ namespace ts { return; } - let referenceSymbol = typeChecker.getSymbolAtLocation(referenceLocation); + const referenceSymbol = typeChecker.getSymbolAtLocation(referenceLocation); if (referenceSymbol) { - let referenceSymbolDeclaration = referenceSymbol.valueDeclaration; - let shorthandValueSymbol = typeChecker.getShorthandAssignmentValueSymbol(referenceSymbolDeclaration); - let relatedSymbol = getRelatedSymbol(searchSymbols, referenceSymbol, referenceLocation); + const referenceSymbolDeclaration = referenceSymbol.valueDeclaration; + const shorthandValueSymbol = typeChecker.getShorthandAssignmentValueSymbol(referenceSymbolDeclaration); + const relatedSymbol = getRelatedSymbol(searchSymbols, referenceSymbol, referenceLocation); if (relatedSymbol) { - let referencedSymbol = getReferencedSymbol(relatedSymbol); + const referencedSymbol = getReferencedSymbol(relatedSymbol); referencedSymbol.references.push(getReferenceEntryFromNode(referenceLocation)); } /* Because in short-hand property assignment, an identifier which stored as name of the short-hand property assignment @@ -5744,7 +5743,7 @@ namespace ts { * position of property accessing, the referenceEntry of such position will be handled in the first case. */ else if (!(referenceSymbol.flags & SymbolFlags.Transient) && searchSymbols.indexOf(shorthandValueSymbol) >= 0) { - let referencedSymbol = getReferencedSymbol(shorthandValueSymbol); + const referencedSymbol = getReferencedSymbol(shorthandValueSymbol); referencedSymbol.references.push(getReferenceEntryFromNode(referenceSymbolDeclaration.name)); } } @@ -5754,7 +5753,7 @@ namespace ts { return; function getReferencedSymbol(symbol: Symbol): ReferencedSymbol { - let symbolId = getSymbolId(symbol); + const symbolId = getSymbolId(symbol); let index = symbolToIndex[symbolId]; if (index === undefined) { index = result.length; @@ -5773,7 +5772,7 @@ namespace ts { return isInCommentHelper(sourceFile, position, isNonReferenceComment); function isNonReferenceComment(c: CommentRange): boolean { - let commentText = sourceFile.text.substring(c.pos, c.end); + const commentText = sourceFile.text.substring(c.pos, c.end); return !tripleSlashDirectivePrefixRegex.test(commentText); } } @@ -5802,20 +5801,20 @@ namespace ts { return undefined; } - let references: ReferenceEntry[] = []; + const references: ReferenceEntry[] = []; - let sourceFile = searchSpaceNode.getSourceFile(); - let possiblePositions = getPossibleSymbolReferencePositions(sourceFile, "super", searchSpaceNode.getStart(), searchSpaceNode.getEnd()); + const sourceFile = searchSpaceNode.getSourceFile(); + const possiblePositions = getPossibleSymbolReferencePositions(sourceFile, "super", searchSpaceNode.getStart(), searchSpaceNode.getEnd()); forEach(possiblePositions, position => { cancellationToken.throwIfCancellationRequested(); - let node = getTouchingWord(sourceFile, position); + const node = getTouchingWord(sourceFile, position); if (!node || node.kind !== SyntaxKind.SuperKeyword) { return; } - let container = getSuperContainer(node, /*includeFunctions*/ false); + const container = getSuperContainer(node, /*includeFunctions*/ false); // If we have a 'super' container, we must have an enclosing class. // Now make sure the owning class is the same as the search-space @@ -5825,7 +5824,7 @@ namespace ts { } }); - let definition = getDefinition(searchSpaceNode.symbol); + const definition = getDefinition(searchSpaceNode.symbol); return [{ definition, references }]; } @@ -5847,7 +5846,7 @@ namespace ts { case SyntaxKind.Constructor: case SyntaxKind.GetAccessor: case SyntaxKind.SetAccessor: - staticFlag &= searchSpaceNode.flags + staticFlag &= searchSpaceNode.flags; searchSpaceNode = searchSpaceNode.parent; // re-assign to be the owning class break; case SyntaxKind.SourceFile: @@ -5864,7 +5863,7 @@ namespace ts { return undefined; } - let references: ReferenceEntry[] = []; + const references: ReferenceEntry[] = []; let possiblePositions: number[]; if (searchSpaceNode.kind === SyntaxKind.SourceFile) { @@ -5874,7 +5873,7 @@ namespace ts { }); } else { - let sourceFile = searchSpaceNode.getSourceFile(); + const sourceFile = searchSpaceNode.getSourceFile(); possiblePositions = getPossibleSymbolReferencePositions(sourceFile, "this", searchSpaceNode.getStart(), searchSpaceNode.getEnd()); getThisReferencesInFile(sourceFile, searchSpaceNode, possiblePositions, references); } @@ -5895,12 +5894,12 @@ namespace ts { forEach(possiblePositions, position => { cancellationToken.throwIfCancellationRequested(); - let node = getTouchingWord(sourceFile, position); + const node = getTouchingWord(sourceFile, position); if (!node || (node.kind !== SyntaxKind.ThisKeyword && node.kind !== SyntaxKind.ThisType)) { return; } - let container = getThisContainer(node, /* includeArrowFunctions */ false); + const container = getThisContainer(node, /* includeArrowFunctions */ false); switch (searchSpaceNode.kind) { case SyntaxKind.FunctionExpression: @@ -5935,7 +5934,7 @@ namespace ts { function populateSearchSymbolSet(symbol: Symbol, location: Node): Symbol[] { // The search set contains at least the current symbol - let result = [symbol]; + const result = [symbol]; // If the symbol is an alias, add what it alaises to the list if (isImportOrExportSpecifierImportSymbol(symbol)) { @@ -5955,13 +5954,13 @@ namespace ts { * property name and variable declaration of the identifier. * Like in below example, when querying for all references for an identifier 'name', of the property assignment, the language service * should show both 'name' in 'obj' and 'name' in variable declaration - * let name = "Foo"; - * let obj = { name }; + * const name = "Foo"; + * const obj = { name }; * In order to do that, we will populate the search set with the value symbol of the identifier as a value of the property assignment * so that when matching with potential reference symbol, both symbols from property declaration and variable declaration * will be included correctly. */ - let shorthandValueSymbol = typeChecker.getShorthandAssignmentValueSymbol(location.parent); + const shorthandValueSymbol = typeChecker.getShorthandAssignmentValueSymbol(location.parent); if (shorthandValueSymbol) { result.push(shorthandValueSymbol); } @@ -5999,9 +5998,9 @@ namespace ts { function getPropertySymbolFromTypeReference(typeReference: ExpressionWithTypeArguments) { if (typeReference) { - let type = typeChecker.getTypeAtLocation(typeReference); + const type = typeChecker.getTypeAtLocation(typeReference); if (type) { - let propertySymbol = typeChecker.getPropertyOfType(type, propertyName); + const propertySymbol = typeChecker.getPropertyOfType(type, propertyName); if (propertySymbol) { result.push(propertySymbol); } @@ -6021,7 +6020,7 @@ namespace ts { // If the reference symbol is an alias, check if what it is aliasing is one of the search // symbols. if (isImportOrExportSpecifierImportSymbol(referenceSymbol)) { - let aliasedSymbol = typeChecker.getAliasedSymbol(referenceSymbol); + const aliasedSymbol = typeChecker.getAliasedSymbol(referenceSymbol); if (searchSymbols.indexOf(aliasedSymbol) >= 0) { return aliasedSymbol; } @@ -6047,7 +6046,7 @@ namespace ts { // Finally, try all properties with the same name in any type the containing type extended or implemented, and // see if any is in the list if (rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { - let result: Symbol[] = []; + const result: Symbol[] = []; getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getName(), result); return forEach(result, s => searchSymbols.indexOf(s) >= 0 ? s : undefined); } @@ -6058,21 +6057,21 @@ namespace ts { function getPropertySymbolsFromContextualType(node: Node): Symbol[] { if (isNameOfPropertyAssignment(node)) { - let objectLiteral = node.parent.parent; - let contextualType = typeChecker.getContextualType(objectLiteral); - let name = (node).text; + const objectLiteral = node.parent.parent; + const contextualType = typeChecker.getContextualType(objectLiteral); + const name = (node).text; if (contextualType) { if (contextualType.flags & TypeFlags.Union) { // This is a union type, first see if the property we are looking for is a union property (i.e. exists in all types) // if not, search the constituent types for the property - let unionProperty = contextualType.getProperty(name) + const unionProperty = contextualType.getProperty(name); if (unionProperty) { return [unionProperty]; } else { - let result: Symbol[] = []; + const result: Symbol[] = []; forEach((contextualType).types, t => { - let symbol = t.getProperty(name); + const symbol = t.getProperty(name); if (symbol) { result.push(symbol); } @@ -6081,7 +6080,7 @@ namespace ts { } } else { - let symbol = contextualType.getProperty(name); + const symbol = contextualType.getProperty(name); if (symbol) { return [symbol]; } @@ -6110,8 +6109,8 @@ namespace ts { // Remember the last meaning lastIterationMeaning = meaning; - for (let declaration of declarations) { - let declarationMeaning = getMeaningFromDeclaration(declaration); + for (const declaration of declarations) { + const declarationMeaning = getMeaningFromDeclaration(declaration); if (declarationMeaning & meaning) { meaning |= declarationMeaning; @@ -6146,13 +6145,13 @@ namespace ts { return true; } - let parent = node.parent; + const parent = node.parent; if (parent) { if (parent.kind === SyntaxKind.PostfixUnaryExpression || parent.kind === SyntaxKind.PrefixUnaryExpression) { return true; } else if (parent.kind === SyntaxKind.BinaryExpression && (parent).left === node) { - let operator = (parent).operatorToken.kind; + const operator = (parent).operatorToken.kind; return SyntaxKind.FirstAssignment <= operator && operator <= SyntaxKind.LastAssignment; } } @@ -6174,8 +6173,8 @@ namespace ts { function getEmitOutput(fileName: string): EmitOutput { synchronizeHostData(); - let sourceFile = getValidSourceFile(fileName); - let outputFiles: OutputFile[] = []; + const sourceFile = getValidSourceFile(fileName); + const outputFiles: OutputFile[] = []; function writeFile(fileName: string, data: string, writeByteOrderMark: boolean) { outputFiles.push({ @@ -6185,7 +6184,7 @@ namespace ts { }); } - let emitOutput = program.emit(sourceFile, writeFile, cancellationToken); + const emitOutput = program.emit(sourceFile, writeFile, cancellationToken); return { outputFiles, @@ -6278,7 +6277,7 @@ namespace ts { } if (!isLastClause && root.parent.kind === SyntaxKind.ExpressionWithTypeArguments && root.parent.parent.kind === SyntaxKind.HeritageClause) { - let decl = root.parent.parent.parent; + const decl = root.parent.parent.parent; return (decl.kind === SyntaxKind.ClassDeclaration && (root.parent.parent).token === SyntaxKind.ImplementsKeyword) || (decl.kind === SyntaxKind.InterfaceDeclaration && (root.parent.parent).token === SyntaxKind.ExtendsKeyword); } @@ -6350,7 +6349,7 @@ namespace ts { function getSignatureHelpItems(fileName: string, position: number): SignatureHelpItems { synchronizeHostData(); - let sourceFile = getValidSourceFile(fileName); + const sourceFile = getValidSourceFile(fileName); return SignatureHelp.getSignatureHelpItems(program, sourceFile, position, cancellationToken); } @@ -6361,10 +6360,10 @@ namespace ts { } function getNameOrDottedNameSpan(fileName: string, startPos: number, endPos: number): TextSpan { - let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); // Get node at the location - let node = getTouchingPropertyName(sourceFile, startPos); + const node = getTouchingPropertyName(sourceFile, startPos); if (!node) { return; @@ -6420,13 +6419,13 @@ namespace ts { function getBreakpointStatementAtPosition(fileName: string, position: number) { // doesn't use compiler - no need to synchronize with host - let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); return BreakpointResolver.spanInSourceFileAtLocation(sourceFile, position); } function getNavigationBarItems(fileName: string): NavigationBarItem[] { - let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); return NavigationBar.getNavigationBarItems(sourceFile, host.getCompilationSettings()); } @@ -6458,11 +6457,11 @@ namespace ts { function getEncodedSemanticClassifications(fileName: string, span: TextSpan): Classifications { synchronizeHostData(); - let sourceFile = getValidSourceFile(fileName); - let typeChecker = program.getTypeChecker(); + const sourceFile = getValidSourceFile(fileName); + const typeChecker = program.getTypeChecker(); - let result: number[] = []; - let classifiableNames = program.getClassifiableNames(); + const result: number[] = []; + const classifiableNames = program.getClassifiableNames(); processNode(sourceFile); return { spans: result, endOfLineState: EndOfLineState.None }; @@ -6474,7 +6473,7 @@ namespace ts { } function classifySymbol(symbol: Symbol, meaningAtPosition: SemanticMeaning): ClassificationType { - let flags = symbol.getFlags(); + const flags = symbol.getFlags(); if ((flags & SymbolFlags.Classifiable) === SymbolFlags.None) { return; } @@ -6522,19 +6521,19 @@ namespace ts { function processNode(node: Node) { // Only walk into nodes that intersect the requested span. if (node && textSpanIntersectsWith(span, node.getFullStart(), node.getFullWidth())) { - let kind = node.kind; + const kind = node.kind; checkForClassificationCancellation(kind); if (kind === SyntaxKind.Identifier && !nodeIsMissing(node)) { - let identifier = node; + const identifier = node; // Only bother calling into the typechecker if this is an identifier that // could possibly resolve to a type name. This makes classification run // in a third of the time it would normally take. if (classifiableNames[identifier.text]) { - let symbol = typeChecker.getSymbolAtLocation(node); + const symbol = typeChecker.getSymbolAtLocation(node); if (symbol) { - let type = classifySymbol(symbol, getMeaningFromLocation(node)); + const type = classifySymbol(symbol, getMeaningFromLocation(node)); if (type) { pushClassification(node.getStart(), node.getWidth(), type); } @@ -6574,8 +6573,8 @@ namespace ts { function convertClassifications(classifications: Classifications): ClassifiedSpan[] { Debug.assert(classifications.spans.length % 3 === 0); - let dense = classifications.spans; - let result: ClassifiedSpan[] = []; + const dense = classifications.spans; + const result: ClassifiedSpan[] = []; for (let i = 0, n = dense.length; i < n; i += 3) { result.push({ textSpan: createTextSpan(dense[i], dense[i + 1]), @@ -6592,15 +6591,15 @@ namespace ts { function getEncodedSyntacticClassifications(fileName: string, span: TextSpan): Classifications { // doesn't use compiler - no need to synchronize with host - let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); - let spanStart = span.start; - let spanLength = span.length; + const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + const spanStart = span.start; + const spanLength = span.length; // Make a scanner we can get trivia from. - let triviaScanner = createScanner(ScriptTarget.Latest, /*skipTrivia:*/ false, sourceFile.languageVariant, sourceFile.text); - let mergeConflictScanner = createScanner(ScriptTarget.Latest, /*skipTrivia:*/ false, sourceFile.languageVariant, sourceFile.text); + const triviaScanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ false, sourceFile.languageVariant, sourceFile.text); + const mergeConflictScanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ false, sourceFile.languageVariant, sourceFile.text); - let result: number[] = []; + const result: number[] = []; processElement(sourceFile); return { spans: result, endOfLineState: EndOfLineState.None }; @@ -6614,15 +6613,15 @@ namespace ts { function classifyLeadingTriviaAndGetTokenStart(token: Node): number { triviaScanner.setTextPos(token.pos); while (true) { - let start = triviaScanner.getTextPos(); + const start = triviaScanner.getTextPos(); // only bother scanning if we have something that could be trivia. if (!couldStartTrivia(sourceFile.text, start)) { return start; } - let kind = triviaScanner.scan(); - let end = triviaScanner.getTextPos(); - let width = end - start; + const kind = triviaScanner.scan(); + const end = triviaScanner.getTextPos(); + const width = end - start; // The moment we get something that isn't trivia, then stop processing. if (!isTrivia(kind)) { @@ -6646,8 +6645,8 @@ namespace ts { } if (kind === SyntaxKind.ConflictMarkerTrivia) { - let text = sourceFile.text; - let ch = text.charCodeAt(start); + const text = sourceFile.text; + const ch = text.charCodeAt(start); // for the <<<<<<< and >>>>>>> markers, we just add them in as comments // in the classification stream. @@ -6668,7 +6667,7 @@ namespace ts { if (kind === SyntaxKind.MultiLineCommentTrivia) { // See if this is a doc comment. If so, we'll classify certain portions of it // specially. - let docCommentAndDiagnostics = parseIsolatedJSDocComment(sourceFile.text, start, width); + const docCommentAndDiagnostics = parseIsolatedJSDocComment(sourceFile.text, start, width); if (docCommentAndDiagnostics && docCommentAndDiagnostics.jsDocComment) { docCommentAndDiagnostics.jsDocComment.parent = token; classifyJSDocComment(docCommentAndDiagnostics.jsDocComment); @@ -6687,7 +6686,7 @@ namespace ts { function classifyJSDocComment(docComment: JSDocComment) { let pos = docComment.pos; - for (let tag of docComment.tags) { + for (const tag of docComment.tags) { // As we walk through each tag, classify the portion of text from the end of // the last tag (or the start of the entire doc comment) as 'comment'. if (tag.pos !== pos) { @@ -6745,7 +6744,7 @@ namespace ts { } function processJSDocTemplateTag(tag: JSDocTemplateTag) { - for (let child of tag.getChildren()) { + for (const child of tag.getChildren()) { processElement(child); } } @@ -6767,11 +6766,11 @@ namespace ts { } function classifyDisabledCodeToken() { - let start = mergeConflictScanner.getTextPos(); - let tokenKind = mergeConflictScanner.scan(); - let end = mergeConflictScanner.getTextPos(); + const start = mergeConflictScanner.getTextPos(); + const tokenKind = mergeConflictScanner.scan(); + const end = mergeConflictScanner.getTextPos(); - let type = classifyTokenType(tokenKind); + const type = classifyTokenType(tokenKind); if (type) { pushClassification(start, end - start, type); } @@ -6782,12 +6781,12 @@ namespace ts { return; } - let tokenStart = classifyLeadingTriviaAndGetTokenStart(token); + const tokenStart = classifyLeadingTriviaAndGetTokenStart(token); - let tokenWidth = token.end - tokenStart; + const tokenWidth = token.end - tokenStart; Debug.assert(tokenWidth >= 0); if (tokenWidth > 0) { - let type = classifyTokenType(token.kind, token); + const type = classifyTokenType(token.kind, token); if (type) { pushClassification(tokenStart, tokenWidth, type); } @@ -6914,9 +6913,9 @@ namespace ts { if (decodedTextSpanIntersectsWith(spanStart, spanLength, element.pos, element.getFullWidth())) { checkForClassificationCancellation(element.kind); - let children = element.getChildren(sourceFile); + const children = element.getChildren(sourceFile); for (let i = 0, n = children.length; i < n; i++) { - let child = children[i]; + const child = children[i]; if (isToken(child)) { classifyToken(child); } @@ -6931,28 +6930,28 @@ namespace ts { function getOutliningSpans(fileName: string): OutliningSpan[] { // doesn't use compiler - no need to synchronize with host - let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); return OutliningElementsCollector.collectElements(sourceFile); } function getBraceMatchingAtPosition(fileName: string, position: number) { - let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); - let result: TextSpan[] = []; + const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + const result: TextSpan[] = []; - let token = getTouchingToken(sourceFile, position); + const token = getTouchingToken(sourceFile, position); if (token.getStart(sourceFile) === position) { - let matchKind = getMatchingTokenKind(token); + const matchKind = getMatchingTokenKind(token); // Ensure that there is a corresponding token to match ours. if (matchKind) { - let parentElement = token.parent; + const parentElement = token.parent; - let childNodes = parentElement.getChildren(sourceFile); - for (let current of childNodes) { + const childNodes = parentElement.getChildren(sourceFile); + for (const current of childNodes) { if (current.kind === matchKind) { - let range1 = createTextSpan(token.getStart(sourceFile), token.getWidth(sourceFile)); - let range2 = createTextSpan(current.getStart(sourceFile), current.getWidth(sourceFile)); + const range1 = createTextSpan(token.getStart(sourceFile), token.getWidth(sourceFile)); + const range2 = createTextSpan(current.getStart(sourceFile), current.getWidth(sourceFile)); // We want to order the braces when we return the result. if (range1.start < range2.start) { @@ -6972,11 +6971,11 @@ namespace ts { function getMatchingTokenKind(token: Node): ts.SyntaxKind { switch (token.kind) { - case ts.SyntaxKind.OpenBraceToken: return ts.SyntaxKind.CloseBraceToken + case ts.SyntaxKind.OpenBraceToken: return ts.SyntaxKind.CloseBraceToken; case ts.SyntaxKind.OpenParenToken: return ts.SyntaxKind.CloseParenToken; case ts.SyntaxKind.OpenBracketToken: return ts.SyntaxKind.CloseBracketToken; case ts.SyntaxKind.LessThanToken: return ts.SyntaxKind.GreaterThanToken; - case ts.SyntaxKind.CloseBraceToken: return ts.SyntaxKind.OpenBraceToken + case ts.SyntaxKind.CloseBraceToken: return ts.SyntaxKind.OpenBraceToken; case ts.SyntaxKind.CloseParenToken: return ts.SyntaxKind.OpenParenToken; case ts.SyntaxKind.CloseBracketToken: return ts.SyntaxKind.OpenBracketToken; case ts.SyntaxKind.GreaterThanToken: return ts.SyntaxKind.LessThanToken; @@ -6988,29 +6987,29 @@ namespace ts { function getIndentationAtPosition(fileName: string, position: number, editorOptions: EditorOptions) { let start = new Date().getTime(); - let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); log("getIndentationAtPosition: getCurrentSourceFile: " + (new Date().getTime() - start)); start = new Date().getTime(); - let result = formatting.SmartIndenter.getIndentation(position, sourceFile, editorOptions); + const result = formatting.SmartIndenter.getIndentation(position, sourceFile, editorOptions); log("getIndentationAtPosition: computeIndentation : " + (new Date().getTime() - start)); return result; } function getFormattingEditsForRange(fileName: string, start: number, end: number, options: FormatCodeOptions): TextChange[] { - let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); return formatting.formatSelection(start, end, sourceFile, getRuleProvider(options), options); } function getFormattingEditsForDocument(fileName: string, options: FormatCodeOptions): TextChange[] { - let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); return formatting.formatDocument(sourceFile, getRuleProvider(options), options); } function getFormattingEditsAfterKeystroke(fileName: string, position: number, key: string, options: FormatCodeOptions): TextChange[] { - let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); if (key === "}") { return formatting.formatOnClosingCurly(position, sourceFile, getRuleProvider(options), options); @@ -7046,16 +7045,16 @@ namespace ts { * be performed. */ function getDocCommentTemplateAtPosition(fileName: string, position: number): TextInsertion { - let start = new Date().getTime(); - let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + const start = new Date().getTime(); + const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); // Check if in a context where we don't want to perform any insertion if (isInString(sourceFile, position) || isInComment(sourceFile, position) || hasDocComment(sourceFile, position)) { return undefined; } - let tokenAtPos = getTokenAtPosition(sourceFile, position); - let tokenStart = tokenAtPos.getStart() + const tokenAtPos = getTokenAtPosition(sourceFile, position); + const tokenStart = tokenAtPos.getStart(); if (!tokenAtPos || tokenStart < position) { return undefined; } @@ -7091,11 +7090,11 @@ namespace ts { return undefined; } - let parameters = getParametersForJsDocOwningNode(commentOwner); - let posLineAndChar = sourceFile.getLineAndCharacterOfPosition(position); - let lineStart = sourceFile.getLineStarts()[posLineAndChar.line]; + const parameters = getParametersForJsDocOwningNode(commentOwner); + const posLineAndChar = sourceFile.getLineAndCharacterOfPosition(position); + const lineStart = sourceFile.getLineStarts()[posLineAndChar.line]; - let indentationStr = sourceFile.text.substr(lineStart, posLineAndChar.character); + const indentationStr = sourceFile.text.substr(lineStart, posLineAndChar.character); // TODO: call a helper method instead once PR #4133 gets merged in. const newLine = host.getNewLine ? host.getNewLine() : "\r\n"; @@ -7119,7 +7118,7 @@ namespace ts { // * if the caret was directly in front of the object, then we add an extra line and indentation. const preamble = "/**" + newLine + indentationStr + " * "; - let result = + const result = preamble + newLine + docParams + indentationStr + " */" + @@ -7163,7 +7162,7 @@ namespace ts { case SyntaxKind.ArrowFunction: return (rightHandSide).parameters; case SyntaxKind.ClassExpression: - for (let member of (rightHandSide).members) { + for (const member of (rightHandSide).members) { if (member.kind === SyntaxKind.Constructor) { return (member).parameters; } @@ -7183,15 +7182,15 @@ namespace ts { // anything away. synchronizeHostData(); - let sourceFile = getValidSourceFile(fileName); + const sourceFile = getValidSourceFile(fileName); cancellationToken.throwIfCancellationRequested(); - let fileContents = sourceFile.text; - let result: TodoComment[] = []; + const fileContents = sourceFile.text; + const result: TodoComment[] = []; if (descriptors.length > 0) { - let regExp = getTodoCommentsRegExp(); + const regExp = getTodoCommentsRegExp(); let matchArray: RegExpExecArray; while (matchArray = regExp.exec(fileContents)) { @@ -7214,15 +7213,15 @@ namespace ts { // // i.e. 'undefined' in position 3 above means TODO(jason) didn't match. // "hack" in position 4 means HACK did match. - let firstDescriptorCaptureIndex = 3; + const firstDescriptorCaptureIndex = 3; Debug.assert(matchArray.length === descriptors.length + firstDescriptorCaptureIndex); - let preamble = matchArray[1]; - let matchPosition = matchArray.index + preamble.length; + const preamble = matchArray[1]; + const matchPosition = matchArray.index + preamble.length; // OK, we have found a match in the file. This is only an acceptable match if // it is contained within a comment. - let token = getTokenAtPosition(sourceFile, matchPosition); + const token = getTokenAtPosition(sourceFile, matchPosition); if (!isInsideComment(sourceFile, token, matchPosition)) { continue; } @@ -7241,7 +7240,7 @@ namespace ts { continue; } - let message = matchArray[2]; + const message = matchArray[2]; result.push({ descriptor: descriptor, message: message, @@ -7272,14 +7271,14 @@ namespace ts { // // The following three regexps are used to match the start of the text up to the TODO // comment portion. - let singleLineCommentStart = /(?:\/\/+\s*)/.source; - let multiLineCommentStart = /(?:\/\*+\s*)/.source; - let anyNumberOfSpacesAndAsterixesAtStartOfLine = /(?:^(?:\s|\*)*)/.source; + const singleLineCommentStart = /(?:\/\/+\s*)/.source; + const multiLineCommentStart = /(?:\/\*+\s*)/.source; + const anyNumberOfSpacesAndAsterixesAtStartOfLine = /(?:^(?:\s|\*)*)/.source; // Match any of the above three TODO comment start regexps. // Note that the outermost group *is* a capture group. We want to capture the preamble // so that we can determine the starting position of the TODO comment match. - let preamble = "(" + anyNumberOfSpacesAndAsterixesAtStartOfLine + "|" + singleLineCommentStart + "|" + multiLineCommentStart + ")"; + const preamble = "(" + anyNumberOfSpacesAndAsterixesAtStartOfLine + "|" + singleLineCommentStart + "|" + multiLineCommentStart + ")"; // Takes the descriptors and forms a regexp that matches them as if they were literals. // For example, if the descriptors are "TODO(jason)" and "HACK", then this will be: @@ -7289,17 +7288,17 @@ namespace ts { // Note that the outermost group is *not* a capture group, but the innermost groups // *are* capture groups. By capturing the inner literals we can determine after // matching which descriptor we are dealing with. - let literals = "(?:" + map(descriptors, d => "(" + escapeRegExp(d.text) + ")").join("|") + ")"; + const literals = "(?:" + map(descriptors, d => "(" + escapeRegExp(d.text) + ")").join("|") + ")"; // After matching a descriptor literal, the following regexp matches the rest of the // text up to the end of the line (or */). - let endOfLineOrEndOfComment = /(?:$|\*\/)/.source - let messageRemainder = /(?:.*?)/.source + const endOfLineOrEndOfComment = /(?:$|\*\/)/.source; + const messageRemainder = /(?:.*?)/.source; // This is the portion of the match we'll return as part of the TODO comment result. We // match the literal portion up to the end of the line or end of comment. - let messagePortion = "(" + literals + messageRemainder + ")"; - let regExpString = preamble + messagePortion + endOfLineOrEndOfComment; + const messagePortion = "(" + literals + messageRemainder + ")"; + const regExpString = preamble + messagePortion + endOfLineOrEndOfComment; // The final regexp will look like this: // /((?:\/\/+\s*)|(?:\/\*+\s*)|(?:^(?:\s|\*)*))((?:(TODO\(jason\))|(HACK))(?:.*?))(?:$|\*\/)/gim @@ -7325,40 +7324,40 @@ namespace ts { function getRenameInfo(fileName: string, position: number): RenameInfo { synchronizeHostData(); - let sourceFile = getValidSourceFile(fileName); - let typeChecker = program.getTypeChecker(); + const sourceFile = getValidSourceFile(fileName); + const typeChecker = program.getTypeChecker(); - let node = getTouchingWord(sourceFile, position); + const node = getTouchingWord(sourceFile, position); // Can only rename an identifier. if (node && node.kind === SyntaxKind.Identifier) { - let symbol = typeChecker.getSymbolAtLocation(node); + const symbol = typeChecker.getSymbolAtLocation(node); // Only allow a symbol to be renamed if it actually has at least one declaration. if (symbol) { - let declarations = symbol.getDeclarations(); + const declarations = symbol.getDeclarations(); if (declarations && declarations.length > 0) { // Disallow rename for elements that are defined in the standard TypeScript library. - let defaultLibFileName = host.getDefaultLibFileName(host.getCompilationSettings()); + const defaultLibFileName = host.getDefaultLibFileName(host.getCompilationSettings()); if (defaultLibFileName) { - for (let current of declarations) { - let sourceFile = current.getSourceFile(); - var canonicalName = getCanonicalFileName(ts.normalizePath(sourceFile.fileName)); + for (const current of declarations) { + const sourceFile = current.getSourceFile(); + const canonicalName = getCanonicalFileName(ts.normalizePath(sourceFile.fileName)); if (sourceFile && getCanonicalFileName(ts.normalizePath(sourceFile.fileName)) === getCanonicalFileName(ts.normalizePath(defaultLibFileName))) { return getRenameInfoError(getLocaleSpecificMessage(Diagnostics.You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library)); } } } - let displayName = stripQuotes(getDeclaredName(typeChecker, symbol, node)); - let kind = getSymbolKind(symbol, node); + const displayName = stripQuotes(getDeclaredName(typeChecker, symbol, node)); + const kind = getSymbolKind(symbol, node); if (kind) { return { canRename: true, - localizedErrorMessage: undefined, + kind, displayName, + localizedErrorMessage: undefined, fullDisplayName: typeChecker.getFullyQualifiedName(symbol), - kind: kind, kindModifiers: getSymbolModifiers(symbol), triggerSpan: createTextSpan(node.getStart(), node.getWidth()) }; @@ -7425,14 +7424,14 @@ namespace ts { /* @internal */ export function getNameTable(sourceFile: SourceFile): Map { if (!sourceFile.nameTable) { - initializeNameTable(sourceFile) + initializeNameTable(sourceFile); } return sourceFile.nameTable; } function initializeNameTable(sourceFile: SourceFile): void { - let nameTable: Map = {}; + const nameTable: Map = {}; walk(sourceFile); sourceFile.nameTable = nameTable; @@ -7470,13 +7469,13 @@ namespace ts { /// Classifier export function createClassifier(): Classifier { - let scanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ false); + const scanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ false); /// We do not have a full parser support to know when we should parse a regex or not /// If we consider every slash token to be a regex, we could be missing cases like "1/2/3", where /// we have a series of divide operator. this list allows us to be more accurate by ruling out /// locations where a regexp cannot exist. - let noRegexTable: boolean[] = []; + const noRegexTable: boolean[] = []; noRegexTable[SyntaxKind.Identifier] = true; noRegexTable[SyntaxKind.StringLiteral] = true; noRegexTable[SyntaxKind.NumericLiteral] = true; @@ -7510,7 +7509,7 @@ namespace ts { // // Where on the second line, you will get the 'return' keyword, // a string literal, and a template end consisting of '} } `'. - let templateStack: SyntaxKind[] = []; + const templateStack: SyntaxKind[] = []; /** Returns true if 'keyword2' can legally follow 'keyword1' in any language construct. */ function canFollow(keyword1: SyntaxKind, keyword2: SyntaxKind) { @@ -7536,18 +7535,18 @@ namespace ts { } function convertClassifications(classifications: Classifications, text: string): ClassificationResult { - let entries: ClassificationInfo[] = []; - let dense = classifications.spans; + const entries: ClassificationInfo[] = []; + const dense = classifications.spans; let lastEnd = 0; for (let i = 0, n = dense.length; i < n; i += 3) { - let start = dense[i]; - let length = dense[i + 1]; - let type = dense[i + 2]; + const start = dense[i]; + const length = dense[i + 1]; + const type = dense[i + 2]; // Make a whitespace entry between the last item and this one. if (lastEnd >= 0) { - let whitespaceLength = start - lastEnd; + const whitespaceLength = start - lastEnd; if (whitespaceLength > 0) { entries.push({ length: whitespaceLength, classification: TokenClass.Whitespace }); } @@ -7557,7 +7556,7 @@ namespace ts { lastEnd = start + length; } - let whitespaceLength = text.length - lastEnd; + const whitespaceLength = text.length - lastEnd; if (whitespaceLength > 0) { entries.push({ length: whitespaceLength, classification: TokenClass.Whitespace }); } @@ -7611,7 +7610,7 @@ namespace ts { // (and a newline). That way when we lex we'll think we're still in a multiline comment. switch (lexState) { case EndOfLineState.InDoubleQuoteStringLiteral: - text = '"\\\n' + text; + text = "\"\\\n" + text; offset = 3; break; case EndOfLineState.InSingleQuoteStringLiteral: @@ -7637,7 +7636,7 @@ namespace ts { scanner.setText(text); - let result: Classifications = { + const result: Classifications = { endOfLineState: EndOfLineState.None, spans: [] }; @@ -7719,7 +7718,7 @@ namespace ts { // If we don't have anything on the template stack, // then we aren't trying to keep track of a previously scanned template head. if (templateStack.length > 0) { - let lastTemplateStackToken = lastOrUndefined(templateStack); + const lastTemplateStackToken = lastOrUndefined(templateStack); if (lastTemplateStackToken === SyntaxKind.TemplateHead) { token = scanner.reScanTemplateToken(); @@ -7749,17 +7748,17 @@ namespace ts { return result; function processToken(): void { - let start = scanner.getTokenPos(); - let end = scanner.getTextPos(); + const start = scanner.getTokenPos(); + const end = scanner.getTextPos(); addResult(start, end, classFromKind(token)); if (end >= text.length) { if (token === SyntaxKind.StringLiteral || token === SyntaxKind.StringLiteralType) { // Check to see if we finished up on a multiline string literal. - let tokenText = scanner.getTokenText(); + const tokenText = scanner.getTokenText(); if (scanner.isUnterminated()) { - let lastCharIndex = tokenText.length - 1; + const lastCharIndex = tokenText.length - 1; let numBackslashes = 0; while (tokenText.charCodeAt(lastCharIndex - numBackslashes) === CharacterCodes.backslash) { @@ -7768,7 +7767,7 @@ namespace ts { // If we have an odd number of backslashes, then the multiline string is unclosed if (numBackslashes & 1) { - let quoteChar = tokenText.charCodeAt(0); + const quoteChar = tokenText.charCodeAt(0); result.endOfLineState = quoteChar === CharacterCodes.doubleQuote ? EndOfLineState.InDoubleQuoteStringLiteral : EndOfLineState.InSingleQuoteStringLiteral; @@ -7817,7 +7816,7 @@ namespace ts { // relative to the original text. start -= offset; end -= offset; - let length = end - start; + const length = end - start; if (length > 0) { result.spans.push(start); @@ -7932,7 +7931,7 @@ namespace ts { } /// getDefaultLibraryFilePath - declare let __dirname: string; + declare const __dirname: string; /** * Get the path of the default library files (lib.d.ts) as distributed with the typescript From e3075bab784a6577e354cb96e84f8d061e15a91b Mon Sep 17 00:00:00 2001 From: Yui T Date: Tue, 15 Dec 2015 10:57:56 -0800 Subject: [PATCH 44/79] Revert linting services --- Jakefile.js | 3 +- src/services/services.ts | 1071 +++++++++++++++++++------------------- 2 files changed, 537 insertions(+), 537 deletions(-) diff --git a/Jakefile.js b/Jakefile.js index 91bd805a27b..beb16d2886f 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -924,8 +924,7 @@ function lintFileAsync(options, path, cb) { var lintTargets = compilerSources .concat(harnessCoreSources) .concat(serverCoreSources) - .concat(scriptSources) - .concat([path.join(servicesDirectory,"services.ts")]); + .concat(scriptSources); desc("Runs tslint on the compiler sources"); task("lint", ["build-rules"], function() { diff --git a/src/services/services.ts b/src/services/services.ts index 4109a4eb345..8e2e4913edd 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -12,7 +12,7 @@ namespace ts { /** The version of the language service API */ - export const servicesVersion = "0.4"; + export let servicesVersion = "0.4" export interface Node { getSourceFile(): SourceFile; @@ -48,7 +48,7 @@ namespace ts { getConstructSignatures(): Signature[]; getStringIndexType(): Type; getNumberIndexType(): Type; - getBaseTypes(): ObjectType[]; + getBaseTypes(): ObjectType[] } export interface Signature { @@ -97,7 +97,7 @@ namespace ts { dispose?(): void; } - export namespace ScriptSnapshot { + export module ScriptSnapshot { class StringScriptSnapshot implements IScriptSnapshot { constructor(private text: string) { @@ -126,12 +126,12 @@ namespace ts { referencedFiles: FileReference[]; importedFiles: FileReference[]; ambientExternalModules: string[]; - isLibFile: boolean; + isLibFile: boolean } - const scanner: Scanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ true); + let scanner: Scanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ true); - const emptyArray: any[] = []; + let emptyArray: any[] = []; const jsDocTagNames = [ "augments", @@ -174,7 +174,7 @@ namespace ts { let jsDocCompletionEntries: CompletionEntry[]; function createNode(kind: SyntaxKind, pos: number, end: number, flags: NodeFlags, parent?: Node): NodeObject { - const node = new NodeObject(kind, pos, end); + let node = new NodeObject(kind, pos, end); node.flags = flags; node.parent = parent; return node; @@ -235,8 +235,8 @@ namespace ts { private addSyntheticNodes(nodes: Node[], pos: number, end: number): number { scanner.setTextPos(pos); while (pos < end) { - const token = scanner.scan(); - const textPos = scanner.getTextPos(); + let token = scanner.scan(); + let textPos = scanner.getTextPos(); nodes.push(createNode(token, pos, textPos, NodeFlags.Synthetic, this)); pos = textPos; } @@ -244,11 +244,13 @@ namespace ts { } private createSyntaxList(nodes: NodeArray): Node { - const list = createNode(SyntaxKind.SyntaxList, nodes.pos, nodes.end, NodeFlags.Synthetic, this); + let list = createNode(SyntaxKind.SyntaxList, nodes.pos, nodes.end, NodeFlags.Synthetic, this); list._children = []; let pos = nodes.pos; - for (const node of nodes) { + + + for (let node of nodes) { if (pos < node.pos) { pos = this.addSyntheticNodes(list._children, pos, node.pos); } @@ -267,14 +269,14 @@ namespace ts { scanner.setText((sourceFile || this.getSourceFile()).text); children = []; let pos = this.pos; - const processNode = (node: Node) => { + let processNode = (node: Node) => { if (pos < node.pos) { pos = this.addSyntheticNodes(children, pos, node.pos); } children.push(node); pos = node.end; }; - const processNodes = (nodes: NodeArray) => { + let processNodes = (nodes: NodeArray) => { if (pos < nodes.pos) { pos = this.addSyntheticNodes(children, pos, nodes.pos); } @@ -306,20 +308,20 @@ namespace ts { } public getFirstToken(sourceFile?: SourceFile): Node { - const children = this.getChildren(sourceFile); + let children = this.getChildren(sourceFile); if (!children.length) { return undefined; } - const child = children[0]; + let child = children[0]; return child.kind < SyntaxKind.FirstNode ? child : child.getFirstToken(sourceFile); } public getLastToken(sourceFile?: SourceFile): Node { - const children = this.getChildren(sourceFile); + let children = this.getChildren(sourceFile); - const child = lastOrUndefined(children); + let child = lastOrUndefined(children); if (!child) { return undefined; } @@ -364,8 +366,8 @@ namespace ts { } function getJsDocCommentsFromDeclarations(declarations: Declaration[], name: string, canUseParsedParamTagComments: boolean) { - const documentationComment = []; - const docComments = getJsDocCommentsSeparatedByNewLines(); + let documentationComment = []; + let docComments = getJsDocCommentsSeparatedByNewLines(); ts.forEach(docComments, docComment => { if (documentationComment.length) { documentationComment.push(lineBreakPart()); @@ -376,22 +378,22 @@ namespace ts { return documentationComment; function getJsDocCommentsSeparatedByNewLines() { - const paramTag = "@param"; - const jsDocCommentParts: SymbolDisplayPart[] = []; + let paramTag = "@param"; + let jsDocCommentParts: SymbolDisplayPart[] = []; ts.forEach(declarations, (declaration, indexOfDeclaration) => { // Make sure we are collecting doc comment from declaration once, // In case of union property there might be same declaration multiple times // which only varies in type parameter - // Eg. const a: Array | Array; a.length + // Eg. let a: Array | Array; a.length // The property length will have two declarations of property length coming // from Array - Array and Array if (indexOf(declarations, declaration) === indexOfDeclaration) { - const sourceFileOfDeclaration = getSourceFileOfNode(declaration); + let sourceFileOfDeclaration = getSourceFileOfNode(declaration); // If it is parameter - try and get the jsDoc comment with @param tag from function declaration's jsDoc comments if (canUseParsedParamTagComments && declaration.kind === SyntaxKind.Parameter) { ts.forEach(getJsDocCommentTextRange(declaration.parent, sourceFileOfDeclaration), jsDocCommentTextRange => { - const cleanedParamJsDocComment = getCleanedParamJsDocComment(jsDocCommentTextRange.pos, jsDocCommentTextRange.end, sourceFileOfDeclaration); + let cleanedParamJsDocComment = getCleanedParamJsDocComment(jsDocCommentTextRange.pos, jsDocCommentTextRange.end, sourceFileOfDeclaration); if (cleanedParamJsDocComment) { addRange(jsDocCommentParts, cleanedParamJsDocComment); } @@ -411,7 +413,7 @@ namespace ts { // Get the cleaned js doc comment text from the declaration ts.forEach(getJsDocCommentTextRange( declaration.kind === SyntaxKind.VariableDeclaration ? declaration.parent.parent : declaration, sourceFileOfDeclaration), jsDocCommentTextRange => { - const cleanedJsDocComment = getCleanedJsDocComment(jsDocCommentTextRange.pos, jsDocCommentTextRange.end, sourceFileOfDeclaration); + let cleanedJsDocComment = getCleanedJsDocComment(jsDocCommentTextRange.pos, jsDocCommentTextRange.end, sourceFileOfDeclaration); if (cleanedJsDocComment) { addRange(jsDocCommentParts, cleanedJsDocComment); } @@ -437,7 +439,7 @@ namespace ts { } for (; pos < end; pos++) { - const ch = sourceFile.text.charCodeAt(pos); + let ch = sourceFile.text.charCodeAt(pos); if (!isWhiteSpace(ch) || isLineBreak(ch)) { // Either found lineBreak or non whiteSpace return pos; @@ -478,7 +480,7 @@ namespace ts { function getCleanedJsDocComment(pos: number, end: number, sourceFile: SourceFile) { let spacesToRemoveAfterAsterisk: number; - const docComments: SymbolDisplayPart[] = []; + let docComments: SymbolDisplayPart[] = []; let blankLineCount = 0; let isInParamTag = false; @@ -489,7 +491,7 @@ namespace ts { // If the comment starts with '*' consume the spaces on this line if (pos < end && sourceFile.text.charCodeAt(pos) === CharacterCodes.asterisk) { - const lineStartPos = pos + 1; + let lineStartPos = pos + 1; pos = consumeWhiteSpacesOnTheLine(pos + 1, end, sourceFile, spacesToRemoveAfterAsterisk); // Set the spaces to remove after asterisk as margin if not already set @@ -503,7 +505,7 @@ namespace ts { // Analyse text on this line while (pos < end && !isLineBreak(sourceFile.text.charCodeAt(pos))) { - const ch = sourceFile.text.charAt(pos); + let ch = sourceFile.text.charAt(pos); if (ch === "@") { // If it is @param tag if (isParamTag(pos, end, sourceFile)) { @@ -542,7 +544,7 @@ namespace ts { function getCleanedParamJsDocComment(pos: number, end: number, sourceFile: SourceFile) { let paramHelpStringMargin: number; - const paramDocComments: SymbolDisplayPart[] = []; + let paramDocComments: SymbolDisplayPart[] = []; while (pos < end) { if (isParamTag(pos, end, sourceFile)) { let blankLineCount = 0; @@ -557,7 +559,7 @@ namespace ts { if (sourceFile.text.charCodeAt(pos) === CharacterCodes.openBrace) { pos++; for (let curlies = 1; pos < end; pos++) { - const charCode = sourceFile.text.charCodeAt(pos); + let charCode = sourceFile.text.charCodeAt(pos); // { character means we need to find another } to match the found one if (charCode === CharacterCodes.openBrace) { @@ -601,9 +603,9 @@ namespace ts { } let paramHelpString = ""; - const firstLineParamHelpStringPos = pos; + let firstLineParamHelpStringPos = pos; while (pos < end) { - const ch = sourceFile.text.charCodeAt(pos); + let ch = sourceFile.text.charCodeAt(pos); // at line break, set this comment line text and go to next line if (isLineBreak(ch)) { @@ -672,15 +674,15 @@ namespace ts { } // Now consume white spaces max - const startOfLinePos = pos; + let startOfLinePos = pos; pos = consumeWhiteSpacesOnTheLine(pos, end, sourceFile, paramHelpStringMargin); if (pos >= end) { return; } - const consumedSpaces = pos - startOfLinePos; + let consumedSpaces = pos - startOfLinePos; if (consumedSpaces < paramHelpStringMargin) { - const ch = sourceFile.text.charCodeAt(pos); + let ch = sourceFile.text.charCodeAt(pos); if (ch === CharacterCodes.asterisk) { // Consume more spaces after asterisk pos = consumeWhiteSpacesOnTheLine(pos + 1, end, sourceFile, paramHelpStringMargin - consumedSpaces - 1); @@ -813,7 +815,7 @@ namespace ts { private namedDeclarations: Map; constructor(kind: SyntaxKind, pos: number, end: number) { - super(kind, pos, end); + super(kind, pos, end) } public update(newText: string, textChangeRange: TextChangeRange): SourceFile { @@ -841,16 +843,16 @@ namespace ts { } private computeNamedDeclarations(): Map { - const result: Map = {}; + let result: Map = {}; forEachChild(this, visit); return result; function addDeclaration(declaration: Declaration) { - const name = getDeclarationName(declaration); + let name = getDeclarationName(declaration); if (name) { - const declarations = getDeclarations(name); + let declarations = getDeclarations(name); declarations.push(declaration); } } @@ -861,13 +863,13 @@ namespace ts { function getDeclarationName(declaration: Declaration) { if (declaration.name) { - const result = getTextOfIdentifierOrLiteral(declaration.name); + let result = getTextOfIdentifierOrLiteral(declaration.name); if (result !== undefined) { return result; } if (declaration.name.kind === SyntaxKind.ComputedPropertyName) { - const expr = (declaration.name).expression; + let expr = (declaration.name).expression; if (expr.kind === SyntaxKind.PropertyAccessExpression) { return (expr).name.text; } @@ -897,12 +899,12 @@ namespace ts { case SyntaxKind.FunctionDeclaration: case SyntaxKind.MethodDeclaration: case SyntaxKind.MethodSignature: - const functionDeclaration = node; - const declarationName = getDeclarationName(functionDeclaration); + let functionDeclaration = node; + let declarationName = getDeclarationName(functionDeclaration); if (declarationName) { - const declarations = getDeclarations(declarationName); - const lastDeclaration = lastOrUndefined(declarations); + let declarations = getDeclarations(declarationName); + let lastDeclaration = lastOrUndefined(declarations); // Check whether this declaration belongs to an "overload group". if (lastDeclaration && functionDeclaration.parent === lastDeclaration.parent && functionDeclaration.symbol === lastDeclaration.symbol) { @@ -978,7 +980,7 @@ namespace ts { break; case SyntaxKind.ImportDeclaration: - const importClause = (node).importClause; + let importClause = (node).importClause; if (importClause) { // Handle default import case e.g.: // import d from "mod"; @@ -1111,8 +1113,8 @@ namespace ts { } export interface Classifications { - spans: number[]; - endOfLineState: EndOfLineState; + spans: number[], + endOfLineState: EndOfLineState } export interface ClassifiedSpan { @@ -1169,7 +1171,7 @@ namespace ts { highlightSpans: HighlightSpan[]; } - export namespace HighlightSpanKind { + export module HighlightSpanKind { export const none = "none"; export const definition = "definition"; export const reference = "reference"; @@ -1218,7 +1220,7 @@ namespace ts { InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: boolean; PlaceOpenBraceOnNewLineForFunctions: boolean; PlaceOpenBraceOnNewLineForControlBlocks: boolean; - [s: string]: boolean | number | string; + [s: string]: boolean | number| string; } export interface DefinitionInfo { @@ -1498,7 +1500,7 @@ namespace ts { } // TODO: move these to enums - export namespace ScriptElementKind { + export module ScriptElementKind { export const unknown = ""; export const warning = "warning"; @@ -1527,7 +1529,7 @@ namespace ts { export const enumElement = "enum"; // Inside module and script only - // const v = .. + // let v = .. export const variableElement = "var"; // Inside function @@ -1579,7 +1581,7 @@ namespace ts { export const letElement = "let"; } - export namespace ScriptElementKindModifier { + export module ScriptElementKindModifier { export const none = ""; export const publicMemberModifier = "public"; export const privateMemberModifier = "private"; @@ -1721,8 +1723,8 @@ namespace ts { this.fileNameToEntry = createFileMap(); // Initialize the list with the root file names - const rootFileNames = host.getScriptFileNames(); - for (const fileName of rootFileNames) { + let rootFileNames = host.getScriptFileNames(); + for (let fileName of rootFileNames) { this.createEntry(fileName, toPath(fileName, this.currentDirectory, getCanonicalFileName)); } @@ -1736,7 +1738,7 @@ namespace ts { private createEntry(fileName: string, path: Path) { let entry: HostFileInformation; - const scriptSnapshot = this.host.getScriptSnapshot(fileName); + let scriptSnapshot = this.host.getScriptSnapshot(fileName); if (scriptSnapshot) { entry = { hostFileName: fileName, @@ -1758,7 +1760,7 @@ namespace ts { } public getOrCreateEntry(fileName: string): HostFileInformation { - const path = toPath(fileName, this.currentDirectory, this.getCanonicalFileName); + let path = toPath(fileName, this.currentDirectory, this.getCanonicalFileName) if (this.contains(path)) { return this.getEntry(path); } @@ -1767,7 +1769,7 @@ namespace ts { } public getRootFileNames(): string[] { - const fileNames: string[] = []; + let fileNames: string[] = []; this.fileNameToEntry.forEachValue((path, value) => { if (value) { @@ -1779,12 +1781,12 @@ namespace ts { } public getVersion(path: Path): string { - const file = this.getEntry(path); + let file = this.getEntry(path); return file && file.version; } public getScriptSnapshot(path: Path): IScriptSnapshot { - const file = this.getEntry(path); + let file = this.getEntry(path); return file && file.scriptSnapshot; } } @@ -1801,22 +1803,22 @@ namespace ts { } public getCurrentSourceFile(fileName: string): SourceFile { - const scriptSnapshot = this.host.getScriptSnapshot(fileName); + let scriptSnapshot = this.host.getScriptSnapshot(fileName); if (!scriptSnapshot) { // The host does not know about this file. throw new Error("Could not find file: '" + fileName + "'."); } - const version = this.host.getScriptVersion(fileName); + let version = this.host.getScriptVersion(fileName); let sourceFile: SourceFile; if (this.currentFileName !== fileName) { // This is a new file, just parse it - sourceFile = createLanguageServiceSourceFile(fileName, scriptSnapshot, ScriptTarget.Latest, version, /*setNodeParents*/ true); + sourceFile = createLanguageServiceSourceFile(fileName, scriptSnapshot, ScriptTarget.Latest, version, /*setNodeParents:*/ true); } else if (this.currentFileVersion !== version) { // This is the same file, just a newer version. Incrementally parse the file. - const editRange = scriptSnapshot.getChangeRange(this.currentFileScriptSnapshot); + let editRange = scriptSnapshot.getChangeRange(this.currentFileScriptSnapshot); sourceFile = updateLanguageServiceSourceFile(this.currentSourceFile, scriptSnapshot, version, editRange); } @@ -1861,7 +1863,7 @@ namespace ts { * - noResolve = true */ export function transpileModule(input: string, transpileOptions: TranspileOptions): TranspileOutput { - const options = transpileOptions.compilerOptions ? clone(transpileOptions.compilerOptions) : getDefaultCompilerOptions(); + let options = transpileOptions.compilerOptions ? clone(transpileOptions.compilerOptions) : getDefaultCompilerOptions(); options.isolatedModules = true; @@ -1877,22 +1879,21 @@ namespace ts { options.noResolve = true; // if jsx is specified then treat file as .tsx - const inputFileName = transpileOptions.fileName || (options.jsx ? "module.tsx" : "module.ts"); - const sourceFile = createSourceFile(inputFileName, input, options.target); + let inputFileName = transpileOptions.fileName || (options.jsx ? "module.tsx" : "module.ts"); + let sourceFile = createSourceFile(inputFileName, input, options.target); if (transpileOptions.moduleName) { sourceFile.moduleName = transpileOptions.moduleName; } sourceFile.renamedDependencies = transpileOptions.renamedDependencies; - const newLine = getNewLineCharacter(options); + let newLine = getNewLineCharacter(options); // Output let outputText: string; let sourceMapText: string; - // Create a compilerHost object to allow the compiler to read and write files - const compilerHost: CompilerHost = { + let compilerHost: CompilerHost = { getSourceFile: (fileName, target) => fileName === normalizeSlashes(inputFileName) ? sourceFile : undefined, writeFile: (name, text, writeByteOrderMark) => { if (fileExtensionIs(name, ".map")) { @@ -1913,7 +1914,7 @@ namespace ts { readFile: (fileName): string => "" }; - const program = createProgram([inputFileName], options, compilerHost); + let program = createProgram([inputFileName], options, compilerHost); let diagnostics: Diagnostic[]; if (transpileOptions.reportDiagnostics) { @@ -1933,15 +1934,15 @@ namespace ts { * This is a shortcut function for transpileModule - it accepts transpileOptions as parameters and returns only outputText part of the result. */ export function transpile(input: string, compilerOptions?: CompilerOptions, fileName?: string, diagnostics?: Diagnostic[], moduleName?: string): string { - const output = transpileModule(input, { compilerOptions, fileName, reportDiagnostics: !!diagnostics, moduleName }); + let output = transpileModule(input, { compilerOptions, fileName, reportDiagnostics: !!diagnostics, moduleName }); // addRange correctly handles cases when wither 'from' or 'to' argument is missing addRange(diagnostics, output.diagnostics); return output.outputText; } export function createLanguageServiceSourceFile(fileName: string, scriptSnapshot: IScriptSnapshot, scriptTarget: ScriptTarget, version: string, setNodeParents: boolean): SourceFile { - const text = scriptSnapshot.getText(0, scriptSnapshot.getLength()); - const sourceFile = createSourceFile(fileName, text, scriptTarget, setNodeParents); + let text = scriptSnapshot.getText(0, scriptSnapshot.getLength()); + let sourceFile = createSourceFile(fileName, text, scriptTarget, setNodeParents); setSourceFileFields(sourceFile, scriptSnapshot, version); // after full parsing we can use table with interned strings as name table sourceFile.nameTable = sourceFile.identifiers; @@ -1960,12 +1961,12 @@ namespace ts { let newText: string; // grab the fragment from the beginning of the original text to the beginning of the span - const prefix = textChangeRange.span.start !== 0 + let prefix = textChangeRange.span.start !== 0 ? sourceFile.text.substr(0, textChangeRange.span.start) : ""; // grab the fragment from the end of the span till the end of the original text - const suffix = textSpanEnd(textChangeRange.span) !== sourceFile.text.length + let suffix = textSpanEnd(textChangeRange.span) !== sourceFile.text.length ? sourceFile.text.substr(textSpanEnd(textChangeRange.span)) : ""; @@ -1975,7 +1976,7 @@ namespace ts { } else { // it was actual edit, fetch the fragment of new text that correspond to new span - const changedText = scriptSnapshot.getText(textChangeRange.span.start, textChangeRange.span.start + textChangeRange.newLength); + let changedText = scriptSnapshot.getText(textChangeRange.span.start, textChangeRange.span.start + textChangeRange.newLength); // combine prefix, changed text and suffix newText = prefix && suffix ? prefix + changedText + suffix @@ -1984,7 +1985,7 @@ namespace ts { : (changedText + suffix); } - const newSourceFile = updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks); + let newSourceFile = updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks); setSourceFileFields(newSourceFile, scriptSnapshot, version); // after incremental parsing nameTable might not be up-to-date // drop it so it can be lazily recreated later @@ -2005,7 +2006,7 @@ namespace ts { } // Otherwise, just create a new source file. - return createLanguageServiceSourceFile(sourceFile.fileName, scriptSnapshot, sourceFile.languageVersion, version, /*setNodeParents*/ true); + return createLanguageServiceSourceFile(sourceFile.fileName, scriptSnapshot, sourceFile.languageVersion, version, /*setNodeParents:*/ true); } export function createGetCanonicalFileName(useCaseSensitivefileNames: boolean): (fileName: string) => string { @@ -2018,15 +2019,15 @@ namespace ts { export function createDocumentRegistry(useCaseSensitiveFileNames?: boolean, currentDirectory = ""): DocumentRegistry { // Maps from compiler setting target (ES3, ES5, etc.) to all the cached documents we have // for those settings. - const buckets: Map> = {}; - const getCanonicalFileName = createGetCanonicalFileName(!!useCaseSensitiveFileNames); + let buckets: Map> = {}; + let getCanonicalFileName = createGetCanonicalFileName(!!useCaseSensitiveFileNames); function getKeyFromCompilationSettings(settings: CompilerOptions): string { return "_" + settings.target + "|" + settings.module + "|" + settings.noResolve + "|" + settings.jsx + +"|" + settings.allowJs; } function getBucketForCompilationSettings(settings: CompilerOptions, createIfMissing: boolean): FileMap { - const key = getKeyFromCompilationSettings(settings); + let key = getKeyFromCompilationSettings(settings); let bucket = lookUp(buckets, key); if (!bucket && createIfMissing) { buckets[key] = bucket = createFileMap(); @@ -2035,9 +2036,9 @@ namespace ts { } function reportStats() { - const bucketInfoArray = Object.keys(buckets).filter(name => name && name.charAt(0) === "_").map(name => { - const entries = lookUp(buckets, name); - const sourceFiles: { name: string; refCount: number; references: string[]; }[] = []; + let bucketInfoArray = Object.keys(buckets).filter(name => name && name.charAt(0) === '_').map(name => { + let entries = lookUp(buckets, name); + let sourceFiles: { name: string; refCount: number; references: string[]; }[] = []; entries.forEachValue((key, entry) => { sourceFiles.push({ name: key, @@ -2051,15 +2052,15 @@ namespace ts { sourceFiles }; }); - return JSON.stringify(bucketInfoArray, undefined, 2); + return JSON.stringify(bucketInfoArray, null, 2); } function acquireDocument(fileName: string, compilationSettings: CompilerOptions, scriptSnapshot: IScriptSnapshot, version: string): SourceFile { - return acquireOrUpdateDocument(fileName, compilationSettings, scriptSnapshot, version, /*acquiring*/ true); + return acquireOrUpdateDocument(fileName, compilationSettings, scriptSnapshot, version, /*acquiring:*/ true); } function updateDocument(fileName: string, compilationSettings: CompilerOptions, scriptSnapshot: IScriptSnapshot, version: string): SourceFile { - return acquireOrUpdateDocument(fileName, compilationSettings, scriptSnapshot, version, /*acquiring*/ false); + return acquireOrUpdateDocument(fileName, compilationSettings, scriptSnapshot, version, /*acquiring:*/ false); } function acquireOrUpdateDocument( @@ -2069,14 +2070,14 @@ namespace ts { version: string, acquiring: boolean): SourceFile { - const bucket = getBucketForCompilationSettings(compilationSettings, /*createIfMissing*/ true); - const path = toPath(fileName, currentDirectory, getCanonicalFileName); + let bucket = getBucketForCompilationSettings(compilationSettings, /*createIfMissing*/ true); + let path = toPath(fileName, currentDirectory, getCanonicalFileName); let entry = bucket.get(path); if (!entry) { Debug.assert(acquiring, "How could we be trying to update a document that the registry doesn't have?"); // Have never seen this file with these settings. Create a new source file for it. - const sourceFile = createLanguageServiceSourceFile(fileName, scriptSnapshot, compilationSettings.target, version, /*setNodeParents*/ false); + let sourceFile = createLanguageServiceSourceFile(fileName, scriptSnapshot, compilationSettings.target, version, /*setNodeParents:*/ false); entry = { sourceFile: sourceFile, @@ -2108,12 +2109,12 @@ namespace ts { } function releaseDocument(fileName: string, compilationSettings: CompilerOptions): void { - const bucket = getBucketForCompilationSettings(compilationSettings, /*createIfMissing*/false); + let bucket = getBucketForCompilationSettings(compilationSettings, false); Debug.assert(bucket !== undefined); - const path = toPath(fileName, currentDirectory, getCanonicalFileName); + let path = toPath(fileName, currentDirectory, getCanonicalFileName); - const entry = bucket.get(path); + let entry = bucket.get(path); entry.languageServiceRefCount--; Debug.assert(entry.languageServiceRefCount >= 0); @@ -2131,19 +2132,19 @@ namespace ts { } export function preProcessFile(sourceText: string, readImportFiles = true, detectJavaScriptImports = false): PreProcessedFileInfo { - const referencedFiles: FileReference[] = []; - const importedFiles: FileReference[] = []; + let referencedFiles: FileReference[] = []; + let importedFiles: FileReference[] = []; let ambientExternalModules: string[]; let isNoDefaultLib = false; function processTripleSlashDirectives(): void { - const commentRanges = getLeadingCommentRanges(sourceText, 0); + let commentRanges = getLeadingCommentRanges(sourceText, 0); forEach(commentRanges, commentRange => { - const comment = sourceText.substring(commentRange.pos, commentRange.end); - const referencePathMatchResult = getFileReferenceFromReferencePath(comment, commentRange); + let comment = sourceText.substring(commentRange.pos, commentRange.end); + let referencePathMatchResult = getFileReferenceFromReferencePath(comment, commentRange); if (referencePathMatchResult) { isNoDefaultLib = referencePathMatchResult.isNoDefaultLib; - const fileReference = referencePathMatchResult.fileReference; + let fileReference = referencePathMatchResult.fileReference; if (fileReference) { referencedFiles.push(fileReference); } @@ -2159,8 +2160,8 @@ namespace ts { } function recordModuleName() { - const importPath = scanner.getTokenValue(); - const pos = scanner.getTokenPos(); + let importPath = scanner.getTokenValue(); + let pos = scanner.getTokenPos(); importedFiles.push({ fileName: importPath, pos: pos, @@ -2212,7 +2213,7 @@ namespace ts { } } else if (token === SyntaxKind.EqualsToken) { - if (tryConsumeRequireCall(/*skipCurrentToken*/ true)) { + if (tryConsumeRequireCall(/* skipCurrentToken */ true)) { return true; } } @@ -2310,7 +2311,7 @@ namespace ts { if (token === SyntaxKind.Identifier || isKeyword(token)) { token = scanner.scan(); if (token === SyntaxKind.EqualsToken) { - if (tryConsumeRequireCall(/*skipCurrentToken*/ true)) { + if (tryConsumeRequireCall(/* skipCurrentToken */ true)) { return true; } } @@ -2409,7 +2410,7 @@ namespace ts { if (tryConsumeDeclare() || tryConsumeImport() || tryConsumeExport() || - (detectJavaScriptImports && (tryConsumeRequireCall(/*skipCurrentToken*/ false) || tryConsumeDefine()))) { + (detectJavaScriptImports && (tryConsumeRequireCall(/* skipCurrentToken */ false) || tryConsumeDefine()))) { continue; } else { @@ -2549,8 +2550,8 @@ namespace ts { return true; } else if (position === comment.end) { - const text = sourceFile.text; - const width = comment.end - comment.pos; + let text = sourceFile.text; + let width = comment.end - comment.pos; // is single line comment or just /* if (width <= 2 || text.charCodeAt(comment.pos + 1) === CharacterCodes.slash) { return true; @@ -2582,7 +2583,7 @@ namespace ts { } // A cache of completion entries for keywords, these do not change between sessions - const keywordCompletions: CompletionEntry[] = []; + let keywordCompletions: CompletionEntry[] = []; for (let i = SyntaxKind.FirstKeyword; i <= SyntaxKind.LastKeyword; i++) { keywordCompletions.push({ name: tokenToString(i), @@ -2672,15 +2673,15 @@ namespace ts { export function createLanguageService(host: LanguageServiceHost, documentRegistry: DocumentRegistry = createDocumentRegistry(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames(), host.getCurrentDirectory())): LanguageService { - const syntaxTreeCache: SyntaxTreeCache = new SyntaxTreeCache(host); + let syntaxTreeCache: SyntaxTreeCache = new SyntaxTreeCache(host); let ruleProvider: formatting.RulesProvider; let program: Program; let lastProjectVersion: string; - const useCaseSensitivefileNames = false; - const cancellationToken = new CancellationTokenObject(host.getCancellationToken && host.getCancellationToken()); + let useCaseSensitivefileNames = false; + let cancellationToken = new CancellationTokenObject(host.getCancellationToken && host.getCancellationToken()); - const currentDirectory = host.getCurrentDirectory(); + let currentDirectory = host.getCurrentDirectory(); // Check if the localized messages json is set, otherwise query the host for it if (!localizedDiagnosticMessages && host.getLocalizedDiagnosticMessages) { localizedDiagnosticMessages = host.getLocalizedDiagnosticMessages(); @@ -2692,10 +2693,10 @@ namespace ts { } } - const getCanonicalFileName = createGetCanonicalFileName(useCaseSensitivefileNames); + let getCanonicalFileName = createGetCanonicalFileName(useCaseSensitivefileNames); function getValidSourceFile(fileName: string): SourceFile { - const sourceFile = program.getSourceFile(fileName); + let sourceFile = program.getSourceFile(fileName); if (!sourceFile) { throw new Error("Could not find file: '" + fileName + "'."); } @@ -2715,7 +2716,7 @@ namespace ts { function synchronizeHostData(): void { // perform fast check if host supports it if (host.getProjectVersion) { - const hostProjectVersion = host.getProjectVersion(); + let hostProjectVersion = host.getProjectVersion(); if (hostProjectVersion) { if (lastProjectVersion === hostProjectVersion) { return; @@ -2739,17 +2740,17 @@ namespace ts { // the program points to old source files that have been invalidated because of // incremental parsing. - const oldSettings = program && program.getCompilerOptions(); - const newSettings = hostCache.compilationSettings(); - const changesInCompilationSettingsAffectSyntax = oldSettings && + let oldSettings = program && program.getCompilerOptions(); + let newSettings = hostCache.compilationSettings(); + let changesInCompilationSettingsAffectSyntax = oldSettings && (oldSettings.target !== newSettings.target || oldSettings.module !== newSettings.module || oldSettings.noResolve !== newSettings.noResolve || - oldSettings.jsx !== newSettings.jsx || + oldSettings.jsx !== newSettings.jsx || oldSettings.allowJs !== newSettings.allowJs); // Now create a new compiler - const compilerHost: CompilerHost = { + let compilerHost: CompilerHost = { getSourceFile: getOrCreateSourceFile, getCancellationToken: () => cancellationToken, getCanonicalFileName, @@ -2765,22 +2766,22 @@ namespace ts { }, readFile: (fileName): string => { // stub missing host functionality - const entry = hostCache.getOrCreateEntry(fileName); + let entry = hostCache.getOrCreateEntry(fileName); return entry && entry.scriptSnapshot.getText(0, entry.scriptSnapshot.getLength()); } }; if (host.resolveModuleNames) { - compilerHost.resolveModuleNames = (moduleNames, containingFile) => host.resolveModuleNames(moduleNames, containingFile); + compilerHost.resolveModuleNames = (moduleNames, containingFile) => host.resolveModuleNames(moduleNames, containingFile) } - const newProgram = createProgram(hostCache.getRootFileNames(), newSettings, compilerHost, program); + let newProgram = createProgram(hostCache.getRootFileNames(), newSettings, compilerHost, program); // Release any files we have acquired in the old program but are // not part of the new program. if (program) { - const oldSourceFiles = program.getSourceFiles(); - for (const oldSourceFile of oldSourceFiles) { + let oldSourceFiles = program.getSourceFiles(); + for (let oldSourceFile of oldSourceFiles) { if (!newProgram.getSourceFile(oldSourceFile.fileName) || changesInCompilationSettingsAffectSyntax) { documentRegistry.releaseDocument(oldSourceFile.fileName, oldSettings); } @@ -2803,7 +2804,7 @@ namespace ts { // The program is asking for this file, check first if the host can locate it. // If the host can not locate the file, then it does not exist. return undefined // to the program to allow reporting of errors for missing files. - const hostFileInformation = hostCache.getOrCreateEntry(fileName); + let hostFileInformation = hostCache.getOrCreateEntry(fileName); if (!hostFileInformation) { return undefined; } @@ -2813,7 +2814,7 @@ namespace ts { // can not be reused. we have to dump all syntax trees and create new ones. if (!changesInCompilationSettingsAffectSyntax) { // Check if the old program had this file already - const oldSourceFile = program && program.getSourceFile(fileName); + let oldSourceFile = program && program.getSourceFile(fileName); if (oldSourceFile) { // We already had a source file for this file name. Go to the registry to // ensure that we get the right up to date version of it. We need this to @@ -2850,7 +2851,7 @@ namespace ts { if (!sourceFile) { return false; } - const path = sourceFile.path || toPath(sourceFile.fileName, currentDirectory, getCanonicalFileName); + let path = sourceFile.path || toPath(sourceFile.fileName, currentDirectory, getCanonicalFileName); return sourceFile.version === hostCache.getVersion(path); } @@ -2861,13 +2862,13 @@ namespace ts { } // If number of files in the program do not match, it is not up-to-date - const rootFileNames = hostCache.getRootFileNames(); + let rootFileNames = hostCache.getRootFileNames(); if (program.getSourceFiles().length !== rootFileNames.length) { return false; } // If any file is not up-to-date, then the whole program is not up-to-date - for (const fileName of rootFileNames) { + for (let fileName of rootFileNames) { if (!sourceFileUpToDate(program.getSourceFile(fileName))) { return false; } @@ -2909,18 +2910,18 @@ namespace ts { function getSemanticDiagnostics(fileName: string): Diagnostic[] { synchronizeHostData(); - const targetSourceFile = getValidSourceFile(fileName); + let targetSourceFile = getValidSourceFile(fileName); // Only perform the action per file regardless of '-out' flag as LanguageServiceHost is expected to call this function per file. // Therefore only get diagnostics for given file. - const semanticDiagnostics = program.getSemanticDiagnostics(targetSourceFile, cancellationToken); + let semanticDiagnostics = program.getSemanticDiagnostics(targetSourceFile, cancellationToken); if (!program.getCompilerOptions().declaration) { return semanticDiagnostics; } // If '-d' is enabled, check for emitter error. One example of emitter error is export class implements non-export interface - const declarationDiagnostics = program.getDeclarationDiagnostics(targetSourceFile, cancellationToken); + let declarationDiagnostics = program.getDeclarationDiagnostics(targetSourceFile, cancellationToken); return concatenate(semanticDiagnostics, declarationDiagnostics); } @@ -2936,14 +2937,14 @@ namespace ts { * @return undefined if the name is of external module otherwise a name with striped of any quote */ function getCompletionEntryDisplayNameForSymbol(symbol: Symbol, target: ScriptTarget, performCharacterChecks: boolean, location: Node): string { - const displayName: string = getDeclaredName(program.getTypeChecker(), symbol, location); + let displayName: string = getDeclaredName(program.getTypeChecker(), symbol, location); if (displayName) { - const firstCharCode = displayName.charCodeAt(0); + let firstCharCode = displayName.charCodeAt(0); // First check of the displayName is not external module; if it is an external module, it is not valid entry if ((symbol.flags & SymbolFlags.Namespace) && (firstCharCode === CharacterCodes.singleQuote || firstCharCode === CharacterCodes.doubleQuote)) { // If the symbol is external module, don't show it in the completion list - // (i.e declare module "http" { const x; } | // <= request completion here, "http" should not be there) + // (i.e declare module "http" { let x; } | // <= request completion here, "http" should not be there) return undefined; } } @@ -2986,20 +2987,20 @@ namespace ts { } function getCompletionData(fileName: string, position: number) { - const typeChecker = program.getTypeChecker(); - const syntacticStart = new Date().getTime(); - const sourceFile = getValidSourceFile(fileName); - const isJavaScriptFile = isSourceFileJavaScript(sourceFile); + let typeChecker = program.getTypeChecker(); + let syntacticStart = new Date().getTime(); + let sourceFile = getValidSourceFile(fileName); + let isJavaScriptFile = isSourceFileJavaScript(sourceFile); let isJsDocTagName = false; let start = new Date().getTime(); - const currentToken = getTokenAtPosition(sourceFile, position); + let currentToken = getTokenAtPosition(sourceFile, position); log("getCompletionData: Get current token: " + (new Date().getTime() - start)); start = new Date().getTime(); // Completion not allowed inside comments, bail out if this is the case - const insideComment = isInsideComment(sourceFile, currentToken, position); + let insideComment = isInsideComment(sourceFile, currentToken, position); log("getCompletionData: Is inside comment: " + (new Date().getTime() - start)); if (insideComment) { @@ -3013,7 +3014,7 @@ namespace ts { // /** @type {number | string} */ // Completion should work in the brackets let insideJsDocTagExpression = false; - const tag = getJsDocTagAtPosition(sourceFile, position); + let tag = getJsDocTagAtPosition(sourceFile, position); if (tag) { if (tag.tagName.pos <= position && position <= tag.tagName.end) { isJsDocTagName = true; @@ -3023,7 +3024,7 @@ namespace ts { case SyntaxKind.JSDocTypeTag: case SyntaxKind.JSDocParameterTag: case SyntaxKind.JSDocReturnTag: - const tagWithExpression = tag; + let tagWithExpression = tag; if (tagWithExpression.typeExpression) { insideJsDocTagExpression = tagWithExpression.typeExpression.pos < position && position < tagWithExpression.typeExpression.end; } @@ -3044,7 +3045,7 @@ namespace ts { } start = new Date().getTime(); - const previousToken = findPrecedingToken(position, sourceFile); + let previousToken = findPrecedingToken(position, sourceFile); log("getCompletionData: Get previous token 1: " + (new Date().getTime() - start)); // The decision to provide completion depends on the contextToken, which is determined through the previousToken. @@ -3054,7 +3055,7 @@ namespace ts { // Check if the caret is at the end of an identifier; this is a partial identifier that we want to complete: e.g. a.toS| // Skip this partial identifier and adjust the contextToken to the token that precedes it. if (contextToken && position <= contextToken.end && isWord(contextToken.kind)) { - const start = new Date().getTime(); + let start = new Date().getTime(); contextToken = findPrecedingToken(contextToken.getFullStart(), sourceFile); log("getCompletionData: Get previous token 2: " + (new Date().getTime() - start)); } @@ -3075,7 +3076,7 @@ namespace ts { return undefined; } - const { parent, kind } = contextToken; + let { parent, kind } = contextToken; if (kind === SyntaxKind.DotToken) { if (parent.kind === SyntaxKind.PropertyAccessExpression) { node = (contextToken.parent).expression; @@ -3102,7 +3103,7 @@ namespace ts { } } - const semanticStart = new Date().getTime(); + let semanticStart = new Date().getTime(); let isMemberCompletion: boolean; let isNewIdentifierLocation: boolean; let symbols: Symbol[] = []; @@ -3111,7 +3112,7 @@ namespace ts { getTypeScriptMemberSymbols(); } else if (isRightOfOpenTag) { - const tagSymbols = typeChecker.getJsxIntrinsicTagNames(); + let tagSymbols = typeChecker.getJsxIntrinsicTagNames(); if (tryGetGlobalSymbols()) { symbols = tagSymbols.concat(symbols.filter(s => !!(s.flags & SymbolFlags.Value))); } @@ -3122,7 +3123,7 @@ namespace ts { isNewIdentifierLocation = false; } else if (isStartingCloseTag) { - const tagName = (contextToken.parent.parent).openingElement.tagName; + let tagName = (contextToken.parent.parent).openingElement.tagName; symbols = [typeChecker.getSymbolAtLocation(tagName)]; isMemberCompletion = true; @@ -3156,7 +3157,7 @@ namespace ts { if (symbol && symbol.flags & SymbolFlags.HasExports) { // Extract module or enum members - const exportedSymbols = typeChecker.getExportsOfModule(symbol); + let exportedSymbols = typeChecker.getExportsOfModule(symbol); forEach(exportedSymbols, symbol => { if (typeChecker.isValidPropertyAccess((node.parent), symbol.name)) { symbols.push(symbol); @@ -3165,14 +3166,14 @@ namespace ts { } } - const type = typeChecker.getTypeAtLocation(node); + let type = typeChecker.getTypeAtLocation(node); addTypeProperties(type); } function addTypeProperties(type: Type) { if (type) { // Filter private properties - for (const symbol of type.getApparentProperties()) { + for (let symbol of type.getApparentProperties()) { if (typeChecker.isValidPropertyAccess((node.parent), symbol.name)) { symbols.push(symbol); } @@ -3184,8 +3185,8 @@ namespace ts { // each individual type has. This is because we're going to add all identifiers // anyways. So we might as well elevate the members that were at least part // of the individual types to a higher status since we know what they are. - const unionType = type; - for (const elementType of unionType.types) { + let unionType = type; + for (let elementType of unionType.types) { addTypeProperties(elementType); } } @@ -3255,14 +3256,14 @@ namespace ts { // - 'contextToken' was adjusted to the token prior to 'previousToken' // because we were at the end of an identifier. // - 'previousToken' is defined. - const adjustedPosition = previousToken !== contextToken ? + let adjustedPosition = previousToken !== contextToken ? previousToken.getStart() : position; - const scopeNode = getScopeNode(contextToken, adjustedPosition, sourceFile) || sourceFile; + let scopeNode = getScopeNode(contextToken, adjustedPosition, sourceFile) || sourceFile; /// TODO filter meaning based on the current context - const symbolMeanings = SymbolFlags.Type | SymbolFlags.Value | SymbolFlags.Namespace | SymbolFlags.Alias; + let symbolMeanings = SymbolFlags.Type | SymbolFlags.Value | SymbolFlags.Namespace | SymbolFlags.Alias; symbols = typeChecker.getSymbolsInScope(scopeNode, symbolMeanings); return true; @@ -3281,8 +3282,8 @@ namespace ts { } function isCompletionListBlocker(contextToken: Node): boolean { - const start = new Date().getTime(); - const result = isInStringOrRegularExpressionOrTemplateLiteral(contextToken) || + let start = new Date().getTime(); + let result = isInStringOrRegularExpressionOrTemplateLiteral(contextToken) || isSolelyIdentifierDefinitionLocation(contextToken) || isDotOfNumericLiteral(contextToken) || isInJsxText(contextToken); @@ -3309,27 +3310,27 @@ namespace ts { function isNewIdentifierDefinitionLocation(previousToken: Node): boolean { if (previousToken) { - const containingNodeKind = previousToken.parent.kind; + let containingNodeKind = previousToken.parent.kind; switch (previousToken.kind) { case SyntaxKind.CommaToken: return containingNodeKind === SyntaxKind.CallExpression // func( a, | || containingNodeKind === SyntaxKind.Constructor // constructor( a, | /* public, protected, private keywords are allowed here, so show completion */ || containingNodeKind === SyntaxKind.NewExpression // new C(a, | || containingNodeKind === SyntaxKind.ArrayLiteralExpression // [a, | - || containingNodeKind === SyntaxKind.BinaryExpression // const x = (a, | + || containingNodeKind === SyntaxKind.BinaryExpression // let x = (a, | || containingNodeKind === SyntaxKind.FunctionType; // var x: (s: string, list| case SyntaxKind.OpenParenToken: return containingNodeKind === SyntaxKind.CallExpression // func( | || containingNodeKind === SyntaxKind.Constructor // constructor( | || containingNodeKind === SyntaxKind.NewExpression // new C(a| - || containingNodeKind === SyntaxKind.ParenthesizedExpression // const x = (a| + || containingNodeKind === SyntaxKind.ParenthesizedExpression // let x = (a| || containingNodeKind === SyntaxKind.ParenthesizedType; // function F(pred: (a| /* this can become an arrow function, where 'a' is the argument */ case SyntaxKind.OpenBracketToken: return containingNodeKind === SyntaxKind.ArrayLiteralExpression // [ | || containingNodeKind === SyntaxKind.IndexSignature // [ | : string ] - || containingNodeKind === SyntaxKind.ComputedPropertyName; // [ | /* this can become an index signature */ + || containingNodeKind === SyntaxKind.ComputedPropertyName // [ | /* this can become an index signature */ case SyntaxKind.ModuleKeyword: // module | case SyntaxKind.NamespaceKeyword: // namespace | @@ -3342,7 +3343,7 @@ namespace ts { return containingNodeKind === SyntaxKind.ClassDeclaration; // class A{ | case SyntaxKind.EqualsToken: - return containingNodeKind === SyntaxKind.VariableDeclaration // const x = a| + return containingNodeKind === SyntaxKind.VariableDeclaration // let x = a| || containingNodeKind === SyntaxKind.BinaryExpression; // x = a| case SyntaxKind.TemplateHead: @@ -3374,8 +3375,8 @@ namespace ts { || contextToken.kind === SyntaxKind.StringLiteralType || contextToken.kind === SyntaxKind.RegularExpressionLiteral || isTemplateLiteralKind(contextToken.kind)) { - const start = contextToken.getStart(); - const end = contextToken.getEnd(); + let start = contextToken.getStart(); + let end = contextToken.getEnd(); // To be "in" one of these literals, the position has to be: // 1. entirely within the token text. @@ -3419,7 +3420,7 @@ namespace ts { // We are *only* completing on properties from the type being destructured. isNewIdentifierLocation = false; - const rootDeclaration = getRootDeclaration(objectLikeContainer.parent); + let rootDeclaration = getRootDeclaration(objectLikeContainer.parent); if (isVariableLike(rootDeclaration)) { // We don't want to complete using the type acquired by the shape // of the binding pattern; we are only interested in types acquired @@ -3430,7 +3431,7 @@ namespace ts { } } else { - Debug.fail("Root declaration is not variable-like."); + Debug.fail("Root declaration is not variable-like.") } } else { @@ -3441,7 +3442,7 @@ namespace ts { return false; } - const typeMembers = typeChecker.getPropertiesOfType(typeForObject); + let typeMembers = typeChecker.getPropertiesOfType(typeForObject); if (typeMembers && typeMembers.length > 0) { // Add filtered items to the completion list symbols = filterObjectMembersList(typeMembers, existingMembers); @@ -3465,11 +3466,11 @@ namespace ts { * @returns true if 'symbols' was successfully populated; false otherwise. */ function tryGetImportOrExportClauseCompletionSymbols(namedImportsOrExports: NamedImportsOrExports): boolean { - const declarationKind = namedImportsOrExports.kind === SyntaxKind.NamedImports ? + let declarationKind = namedImportsOrExports.kind === SyntaxKind.NamedImports ? SyntaxKind.ImportDeclaration : SyntaxKind.ExportDeclaration; - const importOrExportDeclaration = getAncestor(namedImportsOrExports, declarationKind); - const moduleSpecifier = importOrExportDeclaration.moduleSpecifier; + let importOrExportDeclaration = getAncestor(namedImportsOrExports, declarationKind); + let moduleSpecifier = importOrExportDeclaration.moduleSpecifier; if (!moduleSpecifier) { return false; @@ -3479,7 +3480,7 @@ namespace ts { isNewIdentifierLocation = false; let exports: Symbol[]; - const moduleSpecifierSymbol = typeChecker.getSymbolAtLocation(importOrExportDeclaration.moduleSpecifier); + let moduleSpecifierSymbol = typeChecker.getSymbolAtLocation(importOrExportDeclaration.moduleSpecifier); if (moduleSpecifierSymbol) { exports = typeChecker.getExportsOfModule(moduleSpecifierSymbol); } @@ -3496,9 +3497,9 @@ namespace ts { function tryGetObjectLikeCompletionContainer(contextToken: Node): ObjectLiteralExpression | BindingPattern { if (contextToken) { switch (contextToken.kind) { - case SyntaxKind.OpenBraceToken: // const x = { | - case SyntaxKind.CommaToken: // const x = { a: 0, | - const parent = contextToken.parent; + case SyntaxKind.OpenBraceToken: // let x = { | + case SyntaxKind.CommaToken: // let x = { a: 0, | + let parent = contextToken.parent; if (parent && (parent.kind === SyntaxKind.ObjectLiteralExpression || parent.kind === SyntaxKind.ObjectBindingPattern)) { return parent; } @@ -3531,8 +3532,8 @@ namespace ts { function tryGetContainingJsxElement(contextToken: Node): JsxOpeningLikeElement { if (contextToken) { - const parent = contextToken.parent; - switch (contextToken.kind) { + let parent = contextToken.parent; + switch(contextToken.kind) { case SyntaxKind.LessThanSlashToken: case SyntaxKind.SlashToken: case SyntaxKind.Identifier: @@ -3595,7 +3596,7 @@ namespace ts { * @returns true if we are certain that the currently edited location must define a new location; false otherwise. */ function isSolelyIdentifierDefinitionLocation(contextToken: Node): boolean { - const containingNodeKind = contextToken.parent.kind; + let containingNodeKind = contextToken.parent.kind; switch (contextToken.kind) { case SyntaxKind.CommaToken: return containingNodeKind === SyntaxKind.VariableDeclaration || @@ -3625,13 +3626,13 @@ namespace ts { case SyntaxKind.OpenBraceToken: return containingNodeKind === SyntaxKind.EnumDeclaration || // enum a { | containingNodeKind === SyntaxKind.InterfaceDeclaration || // interface a { | - containingNodeKind === SyntaxKind.TypeLiteral; // const x : { | + containingNodeKind === SyntaxKind.TypeLiteral; // let x : { | case SyntaxKind.SemicolonToken: return containingNodeKind === SyntaxKind.PropertySignature && contextToken.parent && contextToken.parent.parent && (contextToken.parent.parent.kind === SyntaxKind.InterfaceDeclaration || // interface a { f; | - contextToken.parent.parent.kind === SyntaxKind.TypeLiteral); // const x : { a; | + contextToken.parent.parent.kind === SyntaxKind.TypeLiteral); // let x : { a; | case SyntaxKind.LessThanToken: return containingNodeKind === SyntaxKind.ClassDeclaration || // class A< | @@ -3698,7 +3699,7 @@ namespace ts { function isDotOfNumericLiteral(contextToken: Node): boolean { if (contextToken.kind === SyntaxKind.NumericLiteral) { - const text = contextToken.getFullText(); + let text = contextToken.getFullText(); return text.charAt(text.length - 1) === "."; } @@ -3715,15 +3716,15 @@ namespace ts { * do not occur at the current position and have not otherwise been typed. */ function filterNamedImportOrExportCompletionItems(exportsOfModule: Symbol[], namedImportsOrExports: ImportOrExportSpecifier[]): Symbol[] { - const exisingImportsOrExports: Map = {}; + let exisingImportsOrExports: Map = {}; - for (const element of namedImportsOrExports) { + for (let element of namedImportsOrExports) { // If this is the current item we are editing right now, do not filter it out if (element.getStart() <= position && position <= element.getEnd()) { continue; } - const name = element.propertyName || element.name; + let name = element.propertyName || element.name; exisingImportsOrExports[name.text] = true; } @@ -3745,8 +3746,8 @@ namespace ts { return contextualMemberSymbols; } - const existingMemberNames: Map = {}; - for (const m of existingMembers) { + let existingMemberNames: Map = {}; + for (let m of existingMembers) { // Ignore omitted expressions for missing members if (m.kind !== SyntaxKind.PropertyAssignment && m.kind !== SyntaxKind.ShorthandPropertyAssignment && @@ -3765,7 +3766,7 @@ namespace ts { if (m.kind === SyntaxKind.BindingElement && (m).propertyName) { // include only identifiers in completion list if ((m).propertyName.kind === SyntaxKind.Identifier) { - existingName = ((m).propertyName).text; + existingName = ((m).propertyName).text } } else { @@ -3788,8 +3789,8 @@ namespace ts { * do not occur at the current position and have not otherwise been typed. */ function filterJsxAttributes(symbols: Symbol[], attributes: NodeArray): Symbol[] { - const seenNames: Map = {}; - for (const attr of attributes) { + let seenNames: Map = {}; + for (let attr of attributes) { // If this is the current item we are editing right now, do not filter it out if (attr.getStart() <= position && position <= attr.getEnd()) { continue; @@ -3808,21 +3809,21 @@ namespace ts { function getCompletionsAtPosition(fileName: string, position: number): CompletionInfo { synchronizeHostData(); - const completionData = getCompletionData(fileName, position); + let completionData = getCompletionData(fileName, position); if (!completionData) { return undefined; } - const { symbols, isMemberCompletion, isNewIdentifierLocation, location, isRightOfDot, isJsDocTagName } = completionData; + let { symbols, isMemberCompletion, isNewIdentifierLocation, location, isRightOfDot, isJsDocTagName } = completionData; if (isJsDocTagName) { // If the current position is a jsDoc tag name, only tag names should be provided for completion return { isMemberCompletion: false, isNewIdentifierLocation: false, entries: getAllJsDocCompletionEntries() }; } - const sourceFile = getValidSourceFile(fileName); + let sourceFile = getValidSourceFile(fileName); - const entries: CompletionEntry[] = []; + let entries: CompletionEntry[] = []; if (isRightOfDot && isSourceFileJavaScript(sourceFile)) { const uniqueNames = getCompletionEntriesFromSymbols(symbols, entries); @@ -3844,16 +3845,16 @@ namespace ts { return { isMemberCompletion, isNewIdentifierLocation, entries }; function getJavaScriptCompletionEntries(sourceFile: SourceFile, uniqueNames: Map): CompletionEntry[] { - const entries: CompletionEntry[] = []; - const target = program.getCompilerOptions().target; + let entries: CompletionEntry[] = []; + let target = program.getCompilerOptions().target; - const nameTable = getNameTable(sourceFile); - for (const name in nameTable) { + let nameTable = getNameTable(sourceFile); + for (let name in nameTable) { if (!uniqueNames[name]) { uniqueNames[name] = name; - const displayName = getCompletionEntryDisplayName(name, target, /*performCharacterChecks*/ true); + let displayName = getCompletionEntryDisplayName(name, target, /*performCharacterChecks:*/ true); if (displayName) { - const entry = { + let entry = { name: displayName, kind: ScriptElementKind.warning, kindModifiers: "", @@ -3874,7 +3875,7 @@ namespace ts { kind: ScriptElementKind.keyword, kindModifiers: "", sortText: "0", - }; + } })); } @@ -3882,7 +3883,7 @@ namespace ts { // Try to get a valid display name for this symbol, if we could not find one, then ignore it. // We would like to only show things that can be added after a dot, so for instance numeric properties can // not be accessed with a dot (a.1 <- invalid) - const displayName = getCompletionEntryDisplayNameForSymbol(symbol, program.getCompilerOptions().target, /*performCharacterChecks*/ true, location); + let displayName = getCompletionEntryDisplayNameForSymbol(symbol, program.getCompilerOptions().target, /*performCharacterChecks:*/ true, location); if (!displayName) { return undefined; } @@ -3904,13 +3905,13 @@ namespace ts { } function getCompletionEntriesFromSymbols(symbols: Symbol[], entries: CompletionEntry[]): Map { - const start = new Date().getTime(); - const uniqueNames: Map = {}; + let start = new Date().getTime(); + let uniqueNames: Map = {}; if (symbols) { - for (const symbol of symbols) { - const entry = createCompletionEntry(symbol, location); + for (let symbol of symbols) { + let entry = createCompletionEntry(symbol, location); if (entry) { - const id = escapeIdentifier(entry.name); + let id = escapeIdentifier(entry.name); if (!lookUp(uniqueNames, id)) { entries.push(entry); uniqueNames[id] = id; @@ -3928,19 +3929,19 @@ namespace ts { synchronizeHostData(); // Compute all the completion symbols again. - const completionData = getCompletionData(fileName, position); + let completionData = getCompletionData(fileName, position); if (completionData) { - const { symbols, location } = completionData; + let { symbols, location } = completionData; // Find the symbol with the matching entry name. - const target = program.getCompilerOptions().target; + let target = program.getCompilerOptions().target; // We don't need to perform character checks here because we're only comparing the // name against 'entryName' (which is known to be good), not building a new // completion entry. - const symbol = forEach(symbols, s => getCompletionEntryDisplayNameForSymbol(s, target, /*performCharacterChecks*/ false, location) === entryName ? s : undefined); + let symbol = forEach(symbols, s => getCompletionEntryDisplayNameForSymbol(s, target, /*performCharacterChecks:*/ false, location) === entryName ? s : undefined); if (symbol) { - const { displayParts, documentation, symbolKind } = getSymbolDisplayPartsDocumentationAndSymbolKind(symbol, getValidSourceFile(fileName), location, location, SemanticMeaning.All); + let { displayParts, documentation, symbolKind } = getSymbolDisplayPartsDocumentationAndSymbolKind(symbol, getValidSourceFile(fileName), location, location, SemanticMeaning.All); return { name: entryName, kindModifiers: getSymbolModifiers(symbol), @@ -3952,7 +3953,7 @@ namespace ts { } // Didn't find a symbol with this name. See if we can find a keyword instead. - const keywordCompletion = forEach(keywordCompletions, c => c.name === entryName); + let keywordCompletion = forEach(keywordCompletions, c => c.name === entryName); if (keywordCompletion) { return { name: entryName, @@ -3968,7 +3969,7 @@ namespace ts { // TODO(drosen): use contextual SemanticMeaning. function getSymbolKind(symbol: Symbol, location: Node): string { - const flags = symbol.getFlags(); + let flags = symbol.getFlags(); if (flags & SymbolFlags.Class) return getDeclarationOfKind(symbol, SyntaxKind.ClassExpression) ? ScriptElementKind.localClassElement : ScriptElementKind.classElement; @@ -3977,7 +3978,7 @@ namespace ts { if (flags & SymbolFlags.Interface) return ScriptElementKind.interfaceElement; if (flags & SymbolFlags.TypeParameter) return ScriptElementKind.typeParameterElement; - const result = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(symbol, flags, location); + let result = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(symbol, flags, location); if (result === ScriptElementKind.unknown) { if (flags & SymbolFlags.TypeParameter) return ScriptElementKind.typeParameterElement; if (flags & SymbolFlags.EnumMember) return ScriptElementKind.variableElement; @@ -3989,7 +3990,7 @@ namespace ts { } function getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(symbol: Symbol, flags: SymbolFlags, location: Node) { - const typeChecker = program.getTypeChecker(); + let typeChecker = program.getTypeChecker(); if (typeChecker.isUndefinedSymbol(symbol)) { return ScriptElementKind.variableElement; @@ -4018,8 +4019,8 @@ namespace ts { if (flags & SymbolFlags.Property) { if (flags & SymbolFlags.SyntheticProperty) { // If union property is result of union of non method (property/accessors/variables), it is labeled as property - const unionPropertyKind = forEach(typeChecker.getRootSymbols(symbol), rootSymbol => { - const rootSymbolFlags = rootSymbol.getFlags(); + let unionPropertyKind = forEach(typeChecker.getRootSymbols(symbol), rootSymbol => { + let rootSymbolFlags = rootSymbol.getFlags(); if (rootSymbolFlags & (SymbolFlags.PropertyOrAccessor | SymbolFlags.Variable)) { return ScriptElementKind.memberVariableElement; } @@ -4027,8 +4028,8 @@ namespace ts { }); if (!unionPropertyKind) { // If this was union of all methods, - // make sure it has call signatures before we can label it as method - const typeOfUnionProperty = typeChecker.getTypeOfSymbolAtLocation(symbol, location); + //make sure it has call signatures before we can label it as method + let typeOfUnionProperty = typeChecker.getTypeOfSymbolAtLocation(symbol, location); if (typeOfUnionProperty.getCallSignatures().length) { return ScriptElementKind.memberFunctionElement; } @@ -4052,11 +4053,11 @@ namespace ts { function getSymbolDisplayPartsDocumentationAndSymbolKind(symbol: Symbol, sourceFile: SourceFile, enclosingDeclaration: Node, location: Node, semanticMeaning = getMeaningFromLocation(location)) { - const typeChecker = program.getTypeChecker(); + let typeChecker = program.getTypeChecker(); - const displayParts: SymbolDisplayPart[] = []; + let displayParts: SymbolDisplayPart[] = []; let documentation: SymbolDisplayPart[]; - const symbolFlags = symbol.flags; + let symbolFlags = symbol.flags; let symbolKind = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(symbol, symbolFlags, location); let hasAddedSymbolInfo: boolean; let type: Type; @@ -4072,7 +4073,7 @@ namespace ts { type = typeChecker.getTypeOfSymbolAtLocation(symbol, location); if (type) { if (location.parent && location.parent.kind === SyntaxKind.PropertyAccessExpression) { - const right = (location.parent).name; + let right = (location.parent).name; // Either the location is on the right of a property access, or on the left and the right is missing if (right === location || (right && right.getFullWidth() === 0)) { location = location.parent; @@ -4089,15 +4090,15 @@ namespace ts { } if (callExpression) { - const candidateSignatures: Signature[] = []; + let candidateSignatures: Signature[] = []; signature = typeChecker.getResolvedSignature(callExpression, candidateSignatures); if (!signature && candidateSignatures.length) { // Use the first candidate: signature = candidateSignatures[0]; } - const useConstructSignatures = callExpression.kind === SyntaxKind.NewExpression || callExpression.expression.kind === SyntaxKind.SuperKeyword; - const allSignatures = useConstructSignatures ? type.getConstructSignatures() : type.getCallSignatures(); + let useConstructSignatures = callExpression.kind === SyntaxKind.NewExpression || callExpression.expression.kind === SyntaxKind.SuperKeyword; + let allSignatures = useConstructSignatures ? type.getConstructSignatures() : type.getCallSignatures(); if (!contains(allSignatures, signature.target) && !contains(allSignatures, signature)) { // Get the first signature if there is one -- allSignatures may contain @@ -4155,8 +4156,8 @@ namespace ts { else if ((isNameOfFunctionDeclaration(location) && !(symbol.flags & SymbolFlags.Accessor)) || // name of function declaration (location.kind === SyntaxKind.ConstructorKeyword && location.parent.kind === SyntaxKind.Constructor)) { // At constructor keyword of constructor declaration // get the signature from the declaration and write it - const functionDeclaration = location.parent; - const allSignatures = functionDeclaration.kind === SyntaxKind.Constructor ? type.getConstructSignatures() : type.getCallSignatures(); + let functionDeclaration = location.parent; + let allSignatures = functionDeclaration.kind === SyntaxKind.Constructor ? type.getConstructSignatures() : type.getCallSignatures(); if (!typeChecker.isImplementationOfOverload(functionDeclaration)) { signature = typeChecker.getSignatureFromDeclaration(functionDeclaration); } @@ -4225,8 +4226,8 @@ namespace ts { } if (symbolFlags & SymbolFlags.Module) { addNewLineIfDisplayPartsExist(); - const declaration = getDeclarationOfKind(symbol, SyntaxKind.ModuleDeclaration); - const isNamespace = declaration && declaration.name && declaration.name.kind === SyntaxKind.Identifier; + let declaration = getDeclarationOfKind(symbol, SyntaxKind.ModuleDeclaration); + let isNamespace = declaration && declaration.name && declaration.name.kind === SyntaxKind.Identifier; displayParts.push(keywordPart(isNamespace ? SyntaxKind.NamespaceKeyword : SyntaxKind.ModuleKeyword)); displayParts.push(spacePart()); addFullSymbolName(symbol); @@ -4278,9 +4279,9 @@ namespace ts { } if (symbolFlags & SymbolFlags.EnumMember) { addPrefixForAnyFunctionOrVar(symbol, "enum member"); - const declaration = symbol.declarations[0]; + let declaration = symbol.declarations[0]; if (declaration.kind === SyntaxKind.EnumMember) { - const constantValue = typeChecker.getConstantValue(declaration); + let constantValue = typeChecker.getConstantValue(declaration); if (constantValue !== undefined) { displayParts.push(spacePart()); displayParts.push(operatorPart(SyntaxKind.EqualsToken)); @@ -4296,7 +4297,7 @@ namespace ts { addFullSymbolName(symbol); ts.forEach(symbol.declarations, declaration => { if (declaration.kind === SyntaxKind.ImportEqualsDeclaration) { - const importEqualsDeclaration = declaration; + let importEqualsDeclaration = declaration; if (isExternalModuleImportEqualsDeclaration(importEqualsDeclaration)) { displayParts.push(spacePart()); displayParts.push(operatorPart(SyntaxKind.EqualsToken)); @@ -4307,7 +4308,7 @@ namespace ts { displayParts.push(punctuationPart(SyntaxKind.CloseParenToken)); } else { - const internalAliasSymbol = typeChecker.getSymbolAtLocation(importEqualsDeclaration.moduleReference); + let internalAliasSymbol = typeChecker.getSymbolAtLocation(importEqualsDeclaration.moduleReference); if (internalAliasSymbol) { displayParts.push(spacePart()); displayParts.push(operatorPart(SyntaxKind.EqualsToken)); @@ -4331,7 +4332,7 @@ namespace ts { displayParts.push(spacePart()); // If the type is type parameter, format it specially if (type.symbol && type.symbol.flags & SymbolFlags.TypeParameter) { - const typeParameterParts = mapToDisplayParts(writer => { + let typeParameterParts = mapToDisplayParts(writer => { typeChecker.getSymbolDisplayBuilder().buildTypeParameterDisplay(type, writer, enclosingDeclaration); }); addRange(displayParts, typeParameterParts); @@ -4346,7 +4347,7 @@ namespace ts { symbolFlags & SymbolFlags.Signature || symbolFlags & SymbolFlags.Accessor || symbolKind === ScriptElementKind.memberFunctionElement) { - const allSignatures = type.getCallSignatures(); + let allSignatures = type.getCallSignatures(); addSignatureDisplayParts(allSignatures[0], allSignatures); } } @@ -4369,7 +4370,7 @@ namespace ts { } function addFullSymbolName(symbol: Symbol, enclosingDeclaration?: Node) { - const fullSymbolDisplayParts = symbolToDisplayParts(typeChecker, symbol, enclosingDeclaration || sourceFile, /*meaning*/ undefined, + let fullSymbolDisplayParts = symbolToDisplayParts(typeChecker, symbol, enclosingDeclaration || sourceFile, /*meaning*/ undefined, SymbolFormatFlags.WriteTypeParametersOrArguments | SymbolFormatFlags.UseOnlyExternalAliasing); addRange(displayParts, fullSymbolDisplayParts); } @@ -4415,7 +4416,7 @@ namespace ts { } function writeTypeParametersOfSymbol(symbol: Symbol, enclosingDeclaration: Node) { - const typeParameterParts = mapToDisplayParts(writer => { + let typeParameterParts = mapToDisplayParts(writer => { typeChecker.getSymbolDisplayBuilder().buildTypeParameterDisplayFromSymbol(symbol, writer, enclosingDeclaration); }); addRange(displayParts, typeParameterParts); @@ -4425,8 +4426,8 @@ namespace ts { function getQuickInfoAtPosition(fileName: string, position: number): QuickInfo { synchronizeHostData(); - const sourceFile = getValidSourceFile(fileName); - const node = getTouchingPropertyName(sourceFile, position); + let sourceFile = getValidSourceFile(fileName); + let node = getTouchingPropertyName(sourceFile, position); if (!node) { return undefined; } @@ -4435,8 +4436,8 @@ namespace ts { return undefined; } - const typeChecker = program.getTypeChecker(); - const symbol = typeChecker.getSymbolAtLocation(node); + let typeChecker = program.getTypeChecker(); + let symbol = typeChecker.getSymbolAtLocation(node); if (!symbol) { // Try getting just type at this position and show @@ -4448,7 +4449,7 @@ namespace ts { case SyntaxKind.ThisType: case SyntaxKind.SuperKeyword: // For the identifiers/this/super etc get the type at position - const type = typeChecker.getTypeAtLocation(node); + let type = typeChecker.getTypeAtLocation(node); if (type) { return { kind: ScriptElementKind.unknown, @@ -4463,7 +4464,7 @@ namespace ts { return undefined; } - const displayPartsDocumentationsAndKind = getSymbolDisplayPartsDocumentationAndSymbolKind(symbol, sourceFile, getContainerNode(node), node); + let displayPartsDocumentationsAndKind = getSymbolDisplayPartsDocumentationAndSymbolKind(symbol, sourceFile, getContainerNode(node), node); return { kind: displayPartsDocumentationsAndKind.symbolKind, kindModifiers: getSymbolModifiers(symbol), @@ -4485,13 +4486,13 @@ namespace ts { } function getDefinitionFromSymbol(symbol: Symbol, node: Node): DefinitionInfo[] { - const typeChecker = program.getTypeChecker(); - const result: DefinitionInfo[] = []; - const declarations = symbol.getDeclarations(); - const symbolName = typeChecker.symbolToString(symbol); // Do not get scoped name, just the name of the symbol - const symbolKind = getSymbolKind(symbol, node); - const containerSymbol = symbol.parent; - const containerName = containerSymbol ? typeChecker.symbolToString(containerSymbol, node) : ""; + let typeChecker = program.getTypeChecker(); + let result: DefinitionInfo[] = []; + let declarations = symbol.getDeclarations(); + let symbolName = typeChecker.symbolToString(symbol); // Do not get scoped name, just the name of the symbol + let symbolKind = getSymbolKind(symbol, node); + let containerSymbol = symbol.parent; + let containerName = containerSymbol ? typeChecker.symbolToString(containerSymbol, node) : ""; if (!tryAddConstructSignature(symbol, node, symbolKind, symbolName, containerName, result) && !tryAddCallSignature(symbol, node, symbolKind, symbolName, containerName, result)) { @@ -4509,7 +4510,7 @@ namespace ts { if (isNewExpressionTarget(location) || location.kind === SyntaxKind.ConstructorKeyword) { if (symbol.flags & SymbolFlags.Class) { // Find the first class-like declaration and try to get the construct signature. - for (const declaration of symbol.getDeclarations()) { + for (let declaration of symbol.getDeclarations()) { if (isClassLike(declaration)) { return tryAddSignature(declaration.members, /*selectConstructors*/ true, @@ -4534,7 +4535,7 @@ namespace ts { } function tryAddSignature(signatureDeclarations: Declaration[], selectConstructors: boolean, symbolKind: string, symbolName: string, containerName: string, result: DefinitionInfo[]) { - const declarations: Declaration[] = []; + let declarations: Declaration[] = []; let definition: Declaration; forEach(signatureDeclarations, d => { @@ -4562,24 +4563,24 @@ namespace ts { function getDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[] { synchronizeHostData(); - const sourceFile = getValidSourceFile(fileName); + let sourceFile = getValidSourceFile(fileName); - const node = getTouchingPropertyName(sourceFile, position); + let node = getTouchingPropertyName(sourceFile, position); if (!node) { return undefined; } // Labels if (isJumpStatementTarget(node)) { - const labelName = (node).text; - const label = getTargetLabel((node.parent), (node).text); + let labelName = (node).text; + let label = getTargetLabel((node.parent), (node).text); return label ? [createDefinitionInfo(label, ScriptElementKind.label, labelName, /*containerName*/ undefined)] : undefined; } /// Triple slash reference comments - const comment = forEach(sourceFile.referencedFiles, r => (r.pos <= position && position < r.end) ? r : undefined); + let comment = forEach(sourceFile.referencedFiles, r => (r.pos <= position && position < r.end) ? r : undefined); if (comment) { - const referenceFile = tryResolveScriptReference(program, sourceFile, comment); + let referenceFile = tryResolveScriptReference(program, sourceFile, comment); if (referenceFile) { return [{ fileName: referenceFile.fileName, @@ -4593,7 +4594,7 @@ namespace ts { return undefined; } - const typeChecker = program.getTypeChecker(); + let typeChecker = program.getTypeChecker(); let symbol = typeChecker.getSymbolAtLocation(node); // Could not find a symbol e.g. node is string or number keyword, @@ -4607,7 +4608,7 @@ namespace ts { // import {A, B} from "mod"; // to jump to the implementation directly. if (symbol.flags & SymbolFlags.Alias) { - const declaration = symbol.declarations[0]; + let declaration = symbol.declarations[0]; if (node.kind === SyntaxKind.Identifier && node.parent === declaration) { symbol = typeChecker.getAliasedSymbol(symbol); } @@ -4619,15 +4620,15 @@ namespace ts { // is performed at the location of property access, we would like to go to definition of the property in the short-hand // assignment. This case and others are handled by the following code. if (node.parent.kind === SyntaxKind.ShorthandPropertyAssignment) { - const shorthandSymbol = typeChecker.getShorthandAssignmentValueSymbol(symbol.valueDeclaration); + let shorthandSymbol = typeChecker.getShorthandAssignmentValueSymbol(symbol.valueDeclaration); if (!shorthandSymbol) { return []; } - const shorthandDeclarations = shorthandSymbol.getDeclarations(); - const shorthandSymbolKind = getSymbolKind(shorthandSymbol, node); - const shorthandSymbolName = typeChecker.symbolToString(shorthandSymbol); - const shorthandContainerName = typeChecker.symbolToString(symbol.parent, node); + let shorthandDeclarations = shorthandSymbol.getDeclarations(); + let shorthandSymbolKind = getSymbolKind(shorthandSymbol, node); + let shorthandSymbolName = typeChecker.symbolToString(shorthandSymbol); + let shorthandContainerName = typeChecker.symbolToString(symbol.parent, node); return map(shorthandDeclarations, declaration => createDefinitionInfo(declaration, shorthandSymbolKind, shorthandSymbolName, shorthandContainerName)); } @@ -4639,27 +4640,27 @@ namespace ts { function getTypeDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[] { synchronizeHostData(); - const sourceFile = getValidSourceFile(fileName); + let sourceFile = getValidSourceFile(fileName); - const node = getTouchingPropertyName(sourceFile, position); + let node = getTouchingPropertyName(sourceFile, position); if (!node) { return undefined; } - const typeChecker = program.getTypeChecker(); + let typeChecker = program.getTypeChecker(); - const symbol = typeChecker.getSymbolAtLocation(node); + let symbol = typeChecker.getSymbolAtLocation(node); if (!symbol) { return undefined; } - const type = typeChecker.getTypeOfSymbolAtLocation(symbol, node); + let type = typeChecker.getTypeOfSymbolAtLocation(symbol, node); if (!type) { return undefined; } if (type.flags & TypeFlags.Union) { - const result: DefinitionInfo[] = []; + let result: DefinitionInfo[] = []; forEach((type).types, t => { if (t.symbol) { addRange(/*to*/ result, /*from*/ getDefinitionFromSymbol(t.symbol, node)); @@ -4679,7 +4680,7 @@ namespace ts { let results = getOccurrencesAtPositionCore(fileName, position); if (results) { - const sourceFile = getCanonicalFileName(normalizeSlashes(fileName)); + let sourceFile = getCanonicalFileName(normalizeSlashes(fileName)); // Get occurrences only supports reporting occurrences for the file queried. So // filter down to that list. @@ -4693,10 +4694,10 @@ namespace ts { synchronizeHostData(); filesToSearch = map(filesToSearch, normalizeSlashes); - const sourceFilesToSearch = filter(program.getSourceFiles(), f => contains(filesToSearch, f.fileName)); - const sourceFile = getValidSourceFile(fileName); + let sourceFilesToSearch = filter(program.getSourceFiles(), f => contains(filesToSearch, f.fileName)); + let sourceFile = getValidSourceFile(fileName); - const node = getTouchingWord(sourceFile, position); + let node = getTouchingWord(sourceFile, position); if (!node) { return undefined; } @@ -4704,8 +4705,8 @@ namespace ts { return getSemanticDocumentHighlights(node) || getSyntacticDocumentHighlights(node); function getHighlightSpanForNode(node: Node): HighlightSpan { - const start = node.getStart(); - const end = node.getEnd(); + let start = node.getStart(); + let end = node.getEnd(); return { fileName: sourceFile.fileName, @@ -4722,7 +4723,7 @@ namespace ts { isLiteralNameOfPropertyDeclarationOrIndexAccess(node) || isNameOfExternalModuleImportOrDeclaration(node)) { - const referencedSymbols = getReferencedSymbolsForNode(node, sourceFilesToSearch, /*findInStrings*/ false, /*findInComments*/ false); + let referencedSymbols = getReferencedSymbolsForNode(node, sourceFilesToSearch, /*findInStrings:*/ false, /*findInComments:*/ false); return convertReferencedSymbols(referencedSymbols); } @@ -4733,11 +4734,11 @@ namespace ts { return undefined; } - const fileNameToDocumentHighlights: Map = {}; - const result: DocumentHighlights[] = []; - for (const referencedSymbol of referencedSymbols) { - for (const referenceEntry of referencedSymbol.references) { - const fileName = referenceEntry.fileName; + let fileNameToDocumentHighlights: Map = {}; + let result: DocumentHighlights[] = []; + for (let referencedSymbol of referencedSymbols) { + for (let referenceEntry of referencedSymbol.references) { + let fileName = referenceEntry.fileName; let documentHighlights = getProperty(fileNameToDocumentHighlights, fileName); if (!documentHighlights) { documentHighlights = { fileName, highlightSpans: [] }; @@ -4758,9 +4759,9 @@ namespace ts { } function getSyntacticDocumentHighlights(node: Node): DocumentHighlights[] { - const fileName = sourceFile.fileName; + let fileName = sourceFile.fileName; - const highlightSpans = getHighlightSpans(node); + let highlightSpans = getHighlightSpans(node); if (!highlightSpans || highlightSpans.length === 0) { return undefined; } @@ -4864,7 +4865,7 @@ namespace ts { * into function boundaries and try-blocks with catch-clauses. */ function aggregateOwnedThrowStatements(node: Node): ThrowStatement[] { - const statementAccumulator: ThrowStatement[] = []; + let statementAccumulator: ThrowStatement[] = [] aggregate(node); return statementAccumulator; @@ -4873,7 +4874,7 @@ namespace ts { statementAccumulator.push(node); } else if (node.kind === SyntaxKind.TryStatement) { - const tryStatement = node; + let tryStatement = node; if (tryStatement.catchClause) { aggregate(tryStatement.catchClause); @@ -4904,7 +4905,7 @@ namespace ts { let child: Node = throwStatement; while (child.parent) { - const parent = child.parent; + let parent = child.parent; if (isFunctionBlock(parent) || parent.kind === SyntaxKind.SourceFile) { return parent; @@ -4913,7 +4914,7 @@ namespace ts { // A throw-statement is only owned by a try-statement if the try-statement has // a catch clause, and if the throw-statement occurs within the try block. if (parent.kind === SyntaxKind.TryStatement) { - const tryStatement = parent; + let tryStatement = parent; if (tryStatement.tryBlock === child && tryStatement.catchClause) { return child; @@ -4927,7 +4928,7 @@ namespace ts { } function aggregateAllBreakAndContinueStatements(node: Node): BreakOrContinueStatement[] { - const statementAccumulator: BreakOrContinueStatement[] = []; + let statementAccumulator: BreakOrContinueStatement[] = [] aggregate(node); return statementAccumulator; @@ -4943,7 +4944,7 @@ namespace ts { } function ownsBreakOrContinueStatement(owner: Node, statement: BreakOrContinueStatement): boolean { - const actualOwner = getBreakOrContinueOwner(statement); + let actualOwner = getBreakOrContinueOwner(statement); return actualOwner && actualOwner === owner; } @@ -4978,7 +4979,7 @@ namespace ts { } function getModifierOccurrences(modifier: SyntaxKind, declaration: Node): HighlightSpan[] { - const container = declaration.parent; + let container = declaration.parent; // Make sure we only highlight the keyword when it makes sense to do so. if (isAccessibilityModifier(modifier)) { @@ -5008,8 +5009,8 @@ namespace ts { return undefined; } - const keywords: Node[] = []; - const modifierFlag: NodeFlags = getFlagFromModifier(modifier); + let keywords: Node[] = []; + let modifierFlag: NodeFlags = getFlagFromModifier(modifier); let nodes: Node[]; switch (container.kind) { @@ -5034,7 +5035,7 @@ namespace ts { // If we're an accessibility modifier, we're in an instance member and should search // the constructor's parameter list for instance members as well. if (modifierFlag & NodeFlags.AccessibilityModifier) { - const constructor = forEach((container).members, member => { + let constructor = forEach((container).members, member => { return member.kind === SyntaxKind.Constructor && member; }); @@ -5047,7 +5048,7 @@ namespace ts { } break; default: - Debug.fail("Invalid container kind."); + Debug.fail("Invalid container kind.") } forEach(nodes, node => { @@ -5090,7 +5091,7 @@ namespace ts { } function getGetAndSetOccurrences(accessorDeclaration: AccessorDeclaration): HighlightSpan[] { - const keywords: Node[] = []; + let keywords: Node[] = []; tryPushAccessorKeyword(accessorDeclaration.symbol, SyntaxKind.GetAccessor); tryPushAccessorKeyword(accessorDeclaration.symbol, SyntaxKind.SetAccessor); @@ -5098,7 +5099,7 @@ namespace ts { return map(keywords, getHighlightSpanForNode); function tryPushAccessorKeyword(accessorSymbol: Symbol, accessorKind: SyntaxKind): void { - const accessor = getDeclarationOfKind(accessorSymbol, accessorKind); + let accessor = getDeclarationOfKind(accessorSymbol, accessorKind); if (accessor) { forEach(accessor.getChildren(), child => pushKeywordIf(keywords, child, SyntaxKind.GetKeyword, SyntaxKind.SetKeyword)); @@ -5107,9 +5108,9 @@ namespace ts { } function getConstructorOccurrences(constructorDeclaration: ConstructorDeclaration): HighlightSpan[] { - const declarations = constructorDeclaration.symbol.getDeclarations(); + let declarations = constructorDeclaration.symbol.getDeclarations() - const keywords: Node[] = []; + let keywords: Node[] = []; forEach(declarations, declaration => { forEach(declaration.getChildren(), token => { @@ -5121,12 +5122,12 @@ namespace ts { } function getLoopBreakContinueOccurrences(loopNode: IterationStatement): HighlightSpan[] { - const keywords: Node[] = []; + let keywords: Node[] = []; if (pushKeywordIf(keywords, loopNode.getFirstToken(), SyntaxKind.ForKeyword, SyntaxKind.WhileKeyword, SyntaxKind.DoKeyword)) { // If we succeeded and got a do-while loop, then start looking for a 'while' keyword. if (loopNode.kind === SyntaxKind.DoStatement) { - const loopTokens = loopNode.getChildren(); + let loopTokens = loopNode.getChildren(); for (let i = loopTokens.length - 1; i >= 0; i--) { if (pushKeywordIf(keywords, loopTokens[i], SyntaxKind.WhileKeyword)) { @@ -5136,7 +5137,7 @@ namespace ts { } } - const breaksAndContinues = aggregateAllBreakAndContinueStatements(loopNode.statement); + let breaksAndContinues = aggregateAllBreakAndContinueStatements(loopNode.statement); forEach(breaksAndContinues, statement => { if (ownsBreakOrContinueStatement(loopNode, statement)) { @@ -5148,7 +5149,7 @@ namespace ts { } function getBreakOrContinueStatementOccurrences(breakOrContinueStatement: BreakOrContinueStatement): HighlightSpan[] { - const owner = getBreakOrContinueOwner(breakOrContinueStatement); + let owner = getBreakOrContinueOwner(breakOrContinueStatement); if (owner) { switch (owner.kind) { @@ -5157,7 +5158,7 @@ namespace ts { case SyntaxKind.ForOfStatement: case SyntaxKind.DoStatement: case SyntaxKind.WhileStatement: - return getLoopBreakContinueOccurrences(owner); + return getLoopBreakContinueOccurrences(owner) case SyntaxKind.SwitchStatement: return getSwitchCaseDefaultOccurrences(owner); @@ -5168,7 +5169,7 @@ namespace ts { } function getSwitchCaseDefaultOccurrences(switchStatement: SwitchStatement): HighlightSpan[] { - const keywords: Node[] = []; + let keywords: Node[] = []; pushKeywordIf(keywords, switchStatement.getFirstToken(), SyntaxKind.SwitchKeyword); @@ -5176,7 +5177,7 @@ namespace ts { forEach(switchStatement.caseBlock.clauses, clause => { pushKeywordIf(keywords, clause.getFirstToken(), SyntaxKind.CaseKeyword, SyntaxKind.DefaultKeyword); - const breaksAndContinues = aggregateAllBreakAndContinueStatements(clause); + let breaksAndContinues = aggregateAllBreakAndContinueStatements(clause); forEach(breaksAndContinues, statement => { if (ownsBreakOrContinueStatement(switchStatement, statement)) { @@ -5189,7 +5190,7 @@ namespace ts { } function getTryCatchFinallyOccurrences(tryStatement: TryStatement): HighlightSpan[] { - const keywords: Node[] = []; + let keywords: Node[] = []; pushKeywordIf(keywords, tryStatement.getFirstToken(), SyntaxKind.TryKeyword); @@ -5198,7 +5199,7 @@ namespace ts { } if (tryStatement.finallyBlock) { - const finallyKeyword = findChildOfKind(tryStatement, SyntaxKind.FinallyKeyword, sourceFile); + let finallyKeyword = findChildOfKind(tryStatement, SyntaxKind.FinallyKeyword, sourceFile); pushKeywordIf(keywords, finallyKeyword, SyntaxKind.FinallyKeyword); } @@ -5206,13 +5207,13 @@ namespace ts { } function getThrowOccurrences(throwStatement: ThrowStatement): HighlightSpan[] { - const owner = getThrowStatementOwner(throwStatement); + let owner = getThrowStatementOwner(throwStatement); if (!owner) { return undefined; } - const keywords: Node[] = []; + let keywords: Node[] = []; forEach(aggregateOwnedThrowStatements(owner), throwStatement => { pushKeywordIf(keywords, throwStatement.getFirstToken(), SyntaxKind.ThrowKeyword); @@ -5230,14 +5231,14 @@ namespace ts { } function getReturnOccurrences(returnStatement: ReturnStatement): HighlightSpan[] { - const func = getContainingFunction(returnStatement); + let func = getContainingFunction(returnStatement); // If we didn't find a containing function with a block body, bail out. if (!(func && hasKind(func.body, SyntaxKind.Block))) { return undefined; } - const keywords: Node[] = []; + let keywords: Node[] = [] forEachReturnStatement(func.body, returnStatement => { pushKeywordIf(keywords, returnStatement.getFirstToken(), SyntaxKind.ReturnKeyword); }); @@ -5251,7 +5252,7 @@ namespace ts { } function getIfElseOccurrences(ifStatement: IfStatement): HighlightSpan[] { - const keywords: Node[] = []; + let keywords: Node[] = []; // Traverse upwards through all parent if-statements linked by their else-branches. while (hasKind(ifStatement.parent, SyntaxKind.IfStatement) && (ifStatement.parent).elseStatement === ifStatement) { @@ -5260,7 +5261,7 @@ namespace ts { // Now traverse back down through the else branches, aggregating if/else keywords of if-statements. while (ifStatement) { - const children = ifStatement.getChildren(); + let children = ifStatement.getChildren(); pushKeywordIf(keywords, children[0], SyntaxKind.IfKeyword); // Generally the 'else' keyword is second-to-last, so we traverse backwards. @@ -5271,20 +5272,20 @@ namespace ts { } if (!hasKind(ifStatement.elseStatement, SyntaxKind.IfStatement)) { - break; + break } ifStatement = ifStatement.elseStatement; } - const result: HighlightSpan[] = []; + let result: HighlightSpan[] = []; // We'd like to highlight else/ifs together if they are only separated by whitespace // (i.e. the keywords are separated by no comments, no newlines). for (let i = 0; i < keywords.length; i++) { if (keywords[i].kind === SyntaxKind.ElseKeyword && i < keywords.length - 1) { - const elseKeyword = keywords[i]; - const ifKeyword = keywords[i + 1]; // this *should* always be an 'if' keyword. + let elseKeyword = keywords[i]; + let ifKeyword = keywords[i + 1]; // this *should* always be an 'if' keyword. let shouldCombindElseAndIf = true; @@ -5327,9 +5328,9 @@ namespace ts { return undefined; } - const result: ReferenceEntry[] = []; - for (const entry of documentHighlights) { - for (const highlightSpan of entry.highlightSpans) { + let result: ReferenceEntry[] = []; + for (let entry of documentHighlights) { + for (let highlightSpan of entry.highlightSpans) { result.push({ fileName: entry.fileName, textSpan: highlightSpan.textSpan, @@ -5347,9 +5348,9 @@ namespace ts { return undefined; } - const referenceEntries: ReferenceEntry[] = []; + let referenceEntries: ReferenceEntry[] = []; - for (const referenceSymbol of referenceSymbols) { + for (let referenceSymbol of referenceSymbols) { addRange(referenceEntries, referenceSymbol.references); } @@ -5357,17 +5358,17 @@ namespace ts { } function findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): RenameLocation[] { - const referencedSymbols = findReferencedSymbols(fileName, position, findInStrings, findInComments); + let referencedSymbols = findReferencedSymbols(fileName, position, findInStrings, findInComments); return convertReferences(referencedSymbols); } function getReferencesAtPosition(fileName: string, position: number): ReferenceEntry[] { - const referencedSymbols = findReferencedSymbols(fileName, position, /*findInStrings*/ false, /*findInComments*/ false); + let referencedSymbols = findReferencedSymbols(fileName, position, /*findInStrings:*/ false, /*findInComments:*/ false); return convertReferences(referencedSymbols); } - function findReferences(fileName: string, position: number): ReferencedSymbol[] { - const referencedSymbols = findReferencedSymbols(fileName, position, /*findInStrings*/ false, /*findInComments*/ false); + function findReferences(fileName: string, position: number): ReferencedSymbol[]{ + let referencedSymbols = findReferencedSymbols(fileName, position, /*findInStrings:*/ false, /*findInComments:*/ false); // Only include referenced symbols that have a valid definition. return filter(referencedSymbols, rs => !!rs.definition); @@ -5376,17 +5377,17 @@ namespace ts { function findReferencedSymbols(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): ReferencedSymbol[] { synchronizeHostData(); - const sourceFile = getValidSourceFile(fileName); + let sourceFile = getValidSourceFile(fileName); - const node = getTouchingPropertyName(sourceFile, position); + let node = getTouchingPropertyName(sourceFile, position); if (!node) { return undefined; } if (node.kind !== SyntaxKind.Identifier && // TODO (drosen): This should be enabled in a later release - currently breaks rename. - // node.kind !== SyntaxKind.ThisKeyword && - // node.kind !== SyntaxKind.SuperKeyword && + //node.kind !== SyntaxKind.ThisKeyword && + //node.kind !== SyntaxKind.SuperKeyword && !isLiteralNameOfPropertyDeclarationOrIndexAccess(node) && !isNameOfExternalModuleImportOrDeclaration(node)) { return undefined; @@ -5397,12 +5398,12 @@ namespace ts { } function getReferencedSymbolsForNode(node: Node, sourceFiles: SourceFile[], findInStrings: boolean, findInComments: boolean): ReferencedSymbol[] { - const typeChecker = program.getTypeChecker(); + let typeChecker = program.getTypeChecker(); // Labels if (isLabelName(node)) { if (isJumpStatementTarget(node)) { - const labelDefinition = getTargetLabel((node.parent), (node).text); + let labelDefinition = getTargetLabel((node.parent), (node).text); // if we have a label definition, look within its statement for references, if not, then // the label is undefined and we have no results.. return labelDefinition ? getLabelReferencesInNode(labelDefinition.parent, labelDefinition) : undefined; @@ -5421,7 +5422,7 @@ namespace ts { return getReferencesForSuperKeyword(node); } - const symbol = typeChecker.getSymbolAtLocation(node); + let symbol = typeChecker.getSymbolAtLocation(node); // Could not find a symbol e.g. unknown identifier if (!symbol) { @@ -5429,7 +5430,7 @@ namespace ts { return undefined; } - const declarations = symbol.declarations; + let declarations = symbol.declarations; // The symbol was an internal symbol and does not have a declaration e.g. undefined symbol if (!declarations || !declarations.length) { @@ -5439,29 +5440,29 @@ namespace ts { let result: ReferencedSymbol[]; // Compute the meaning from the location and the symbol it references - const searchMeaning = getIntersectingMeaningFromDeclarations(getMeaningFromLocation(node), declarations); + let searchMeaning = getIntersectingMeaningFromDeclarations(getMeaningFromLocation(node), declarations); // Get the text to search for. // Note: if this is an external module symbol, the name doesn't include quotes. - const declaredName = stripQuotes(getDeclaredName(typeChecker, symbol, node)); + let declaredName = stripQuotes(getDeclaredName(typeChecker, symbol, node)); // Try to get the smallest valid scope that we can limit our search to; // otherwise we'll need to search globally (i.e. include each file). - const scope = getSymbolScope(symbol); + let scope = getSymbolScope(symbol); // Maps from a symbol ID to the ReferencedSymbol entry in 'result'. - const symbolToIndex: number[] = []; + let symbolToIndex: number[] = []; if (scope) { result = []; getReferencesInNode(scope, symbol, declaredName, node, searchMeaning, findInStrings, findInComments, result, symbolToIndex); } else { - const internedName = getInternedName(symbol, node, declarations); - for (const sourceFile of sourceFiles) { + let internedName = getInternedName(symbol, node, declarations) + for (let sourceFile of sourceFiles) { cancellationToken.throwIfCancellationRequested(); - const nameTable = getNameTable(sourceFile); + let nameTable = getNameTable(sourceFile); if (lookUp(nameTable, internedName)) { result = result || []; @@ -5473,9 +5474,9 @@ namespace ts { return result; function getDefinition(symbol: Symbol): DefinitionInfo { - const info = getSymbolDisplayPartsDocumentationAndSymbolKind(symbol, node.getSourceFile(), getContainerNode(node), node); - const name = map(info.displayParts, p => p.text).join(""); - const declarations = symbol.declarations; + let info = getSymbolDisplayPartsDocumentationAndSymbolKind(symbol, node.getSourceFile(), getContainerNode(node), node); + let name = map(info.displayParts, p => p.text).join(""); + let declarations = symbol.declarations; if (!declarations || declarations.length === 0) { return undefined; } @@ -5505,7 +5506,7 @@ namespace ts { // Try to get the local symbol if we're dealing with an 'export default' // since that symbol has the "true" name. - const localExportDefaultSymbol = getLocalSymbolForExportDefault(symbol); + let localExportDefaultSymbol = getLocalSymbolForExportDefault(symbol); symbol = localExportDefaultSymbol || symbol; return stripQuotes(symbol.name); @@ -5522,14 +5523,14 @@ namespace ts { function getSymbolScope(symbol: Symbol): Node { // If this is the symbol of a named function expression or named class expression, // then named references are limited to its own scope. - const valueDeclaration = symbol.valueDeclaration; + let valueDeclaration = symbol.valueDeclaration; if (valueDeclaration && (valueDeclaration.kind === SyntaxKind.FunctionExpression || valueDeclaration.kind === SyntaxKind.ClassExpression)) { return valueDeclaration; } // If this is private property or method, the scope is the containing class if (symbol.flags & (SymbolFlags.Property | SymbolFlags.Method)) { - const privateDeclaration = forEach(symbol.getDeclarations(), d => (d.flags & NodeFlags.Private) ? d : undefined); + let privateDeclaration = forEach(symbol.getDeclarations(), d => (d.flags & NodeFlags.Private) ? d : undefined); if (privateDeclaration) { return getAncestor(privateDeclaration, SyntaxKind.ClassDeclaration); } @@ -5547,12 +5548,12 @@ namespace ts { return undefined; } - let scope: Node; + let scope: Node = undefined; - const declarations = symbol.getDeclarations(); + let declarations = symbol.getDeclarations(); if (declarations) { - for (const declaration of declarations) { - const container = getContainerNode(declaration); + for (let declaration of declarations) { + let container = getContainerNode(declaration); if (!container) { return undefined; @@ -5578,7 +5579,7 @@ namespace ts { } function getPossibleSymbolReferencePositions(sourceFile: SourceFile, symbolName: string, start: number, end: number): number[] { - const positions: number[] = []; + let positions: number[] = []; /// TODO: Cache symbol existence for files to save text search // Also, need to make this work for unicode escapes. @@ -5588,9 +5589,9 @@ namespace ts { return positions; } - const text = sourceFile.text; - const sourceLength = text.length; - const symbolNameLength = symbolName.length; + let text = sourceFile.text; + let sourceLength = text.length; + let symbolNameLength = symbolName.length; let position = text.indexOf(symbolName, start); while (position >= 0) { @@ -5601,7 +5602,7 @@ namespace ts { // We found a match. Make sure it's not part of a larger word (i.e. the char // before and after it have to be a non-identifier char). - const endPosition = position + symbolNameLength; + let endPosition = position + symbolNameLength; if ((position === 0 || !isIdentifierPart(text.charCodeAt(position - 1), ScriptTarget.Latest)) && (endPosition === sourceLength || !isIdentifierPart(text.charCodeAt(endPosition), ScriptTarget.Latest))) { @@ -5615,14 +5616,14 @@ namespace ts { } function getLabelReferencesInNode(container: Node, targetLabel: Identifier): ReferencedSymbol[] { - const references: ReferenceEntry[] = []; - const sourceFile = container.getSourceFile(); - const labelName = targetLabel.text; - const possiblePositions = getPossibleSymbolReferencePositions(sourceFile, labelName, container.getStart(), container.getEnd()); + let references: ReferenceEntry[] = []; + let sourceFile = container.getSourceFile(); + let labelName = targetLabel.text; + let possiblePositions = getPossibleSymbolReferencePositions(sourceFile, labelName, container.getStart(), container.getEnd()); forEach(possiblePositions, position => { cancellationToken.throwIfCancellationRequested(); - const node = getTouchingWord(sourceFile, position); + let node = getTouchingWord(sourceFile, position); if (!node || node.getWidth() !== labelName.length) { return; } @@ -5634,14 +5635,14 @@ namespace ts { } }); - const definition: DefinitionInfo = { + let definition: DefinitionInfo = { containerKind: "", containerName: "", fileName: targetLabel.getSourceFile().fileName, kind: ScriptElementKind.label, name: labelName, textSpan: createTextSpanFromBounds(targetLabel.getStart(), targetLabel.getEnd()) - }; + } return [{ definition, references }]; } @@ -5686,19 +5687,19 @@ namespace ts { result: ReferencedSymbol[], symbolToIndex: number[]): void { - const sourceFile = container.getSourceFile(); - const tripleSlashDirectivePrefixRegex = /^\/\/\/\s* { cancellationToken.throwIfCancellationRequested(); - const referenceLocation = getTouchingPropertyName(sourceFile, position); + let referenceLocation = getTouchingPropertyName(sourceFile, position); if (!isValidReferencePosition(referenceLocation, searchText)) { // This wasn't the start of a token. Check to see if it might be a // match in a comment or string if that's what the caller is asking @@ -5726,14 +5727,14 @@ namespace ts { return; } - const referenceSymbol = typeChecker.getSymbolAtLocation(referenceLocation); + let referenceSymbol = typeChecker.getSymbolAtLocation(referenceLocation); if (referenceSymbol) { - const referenceSymbolDeclaration = referenceSymbol.valueDeclaration; - const shorthandValueSymbol = typeChecker.getShorthandAssignmentValueSymbol(referenceSymbolDeclaration); - const relatedSymbol = getRelatedSymbol(searchSymbols, referenceSymbol, referenceLocation); + let referenceSymbolDeclaration = referenceSymbol.valueDeclaration; + let shorthandValueSymbol = typeChecker.getShorthandAssignmentValueSymbol(referenceSymbolDeclaration); + let relatedSymbol = getRelatedSymbol(searchSymbols, referenceSymbol, referenceLocation); if (relatedSymbol) { - const referencedSymbol = getReferencedSymbol(relatedSymbol); + let referencedSymbol = getReferencedSymbol(relatedSymbol); referencedSymbol.references.push(getReferenceEntryFromNode(referenceLocation)); } /* Because in short-hand property assignment, an identifier which stored as name of the short-hand property assignment @@ -5743,7 +5744,7 @@ namespace ts { * position of property accessing, the referenceEntry of such position will be handled in the first case. */ else if (!(referenceSymbol.flags & SymbolFlags.Transient) && searchSymbols.indexOf(shorthandValueSymbol) >= 0) { - const referencedSymbol = getReferencedSymbol(shorthandValueSymbol); + let referencedSymbol = getReferencedSymbol(shorthandValueSymbol); referencedSymbol.references.push(getReferenceEntryFromNode(referenceSymbolDeclaration.name)); } } @@ -5753,7 +5754,7 @@ namespace ts { return; function getReferencedSymbol(symbol: Symbol): ReferencedSymbol { - const symbolId = getSymbolId(symbol); + let symbolId = getSymbolId(symbol); let index = symbolToIndex[symbolId]; if (index === undefined) { index = result.length; @@ -5772,7 +5773,7 @@ namespace ts { return isInCommentHelper(sourceFile, position, isNonReferenceComment); function isNonReferenceComment(c: CommentRange): boolean { - const commentText = sourceFile.text.substring(c.pos, c.end); + let commentText = sourceFile.text.substring(c.pos, c.end); return !tripleSlashDirectivePrefixRegex.test(commentText); } } @@ -5801,20 +5802,20 @@ namespace ts { return undefined; } - const references: ReferenceEntry[] = []; + let references: ReferenceEntry[] = []; - const sourceFile = searchSpaceNode.getSourceFile(); - const possiblePositions = getPossibleSymbolReferencePositions(sourceFile, "super", searchSpaceNode.getStart(), searchSpaceNode.getEnd()); + let sourceFile = searchSpaceNode.getSourceFile(); + let possiblePositions = getPossibleSymbolReferencePositions(sourceFile, "super", searchSpaceNode.getStart(), searchSpaceNode.getEnd()); forEach(possiblePositions, position => { cancellationToken.throwIfCancellationRequested(); - const node = getTouchingWord(sourceFile, position); + let node = getTouchingWord(sourceFile, position); if (!node || node.kind !== SyntaxKind.SuperKeyword) { return; } - const container = getSuperContainer(node, /*includeFunctions*/ false); + let container = getSuperContainer(node, /*includeFunctions*/ false); // If we have a 'super' container, we must have an enclosing class. // Now make sure the owning class is the same as the search-space @@ -5824,7 +5825,7 @@ namespace ts { } }); - const definition = getDefinition(searchSpaceNode.symbol); + let definition = getDefinition(searchSpaceNode.symbol); return [{ definition, references }]; } @@ -5846,7 +5847,7 @@ namespace ts { case SyntaxKind.Constructor: case SyntaxKind.GetAccessor: case SyntaxKind.SetAccessor: - staticFlag &= searchSpaceNode.flags; + staticFlag &= searchSpaceNode.flags searchSpaceNode = searchSpaceNode.parent; // re-assign to be the owning class break; case SyntaxKind.SourceFile: @@ -5863,7 +5864,7 @@ namespace ts { return undefined; } - const references: ReferenceEntry[] = []; + let references: ReferenceEntry[] = []; let possiblePositions: number[]; if (searchSpaceNode.kind === SyntaxKind.SourceFile) { @@ -5873,7 +5874,7 @@ namespace ts { }); } else { - const sourceFile = searchSpaceNode.getSourceFile(); + let sourceFile = searchSpaceNode.getSourceFile(); possiblePositions = getPossibleSymbolReferencePositions(sourceFile, "this", searchSpaceNode.getStart(), searchSpaceNode.getEnd()); getThisReferencesInFile(sourceFile, searchSpaceNode, possiblePositions, references); } @@ -5894,12 +5895,12 @@ namespace ts { forEach(possiblePositions, position => { cancellationToken.throwIfCancellationRequested(); - const node = getTouchingWord(sourceFile, position); + let node = getTouchingWord(sourceFile, position); if (!node || (node.kind !== SyntaxKind.ThisKeyword && node.kind !== SyntaxKind.ThisType)) { return; } - const container = getThisContainer(node, /* includeArrowFunctions */ false); + let container = getThisContainer(node, /* includeArrowFunctions */ false); switch (searchSpaceNode.kind) { case SyntaxKind.FunctionExpression: @@ -5954,13 +5955,13 @@ namespace ts { * property name and variable declaration of the identifier. * Like in below example, when querying for all references for an identifier 'name', of the property assignment, the language service * should show both 'name' in 'obj' and 'name' in variable declaration - * const name = "Foo"; - * const obj = { name }; + * let name = "Foo"; + * let obj = { name }; * In order to do that, we will populate the search set with the value symbol of the identifier as a value of the property assignment * so that when matching with potential reference symbol, both symbols from property declaration and variable declaration * will be included correctly. */ - const shorthandValueSymbol = typeChecker.getShorthandAssignmentValueSymbol(location.parent); + let shorthandValueSymbol = typeChecker.getShorthandAssignmentValueSymbol(location.parent); if (shorthandValueSymbol) { result.push(shorthandValueSymbol); } @@ -6007,9 +6008,9 @@ namespace ts { function getPropertySymbolFromTypeReference(typeReference: ExpressionWithTypeArguments) { if (typeReference) { - const type = typeChecker.getTypeAtLocation(typeReference); + let type = typeChecker.getTypeAtLocation(typeReference); if (type) { - const propertySymbol = typeChecker.getPropertyOfType(type, propertyName); + let propertySymbol = typeChecker.getPropertyOfType(type, propertyName); if (propertySymbol) { result.push(propertySymbol); } @@ -6029,7 +6030,7 @@ namespace ts { // If the reference symbol is an alias, check if what it is aliasing is one of the search // symbols. if (isImportOrExportSpecifierImportSymbol(referenceSymbol)) { - const aliasedSymbol = typeChecker.getAliasedSymbol(referenceSymbol); + let aliasedSymbol = typeChecker.getAliasedSymbol(referenceSymbol); if (searchSymbols.indexOf(aliasedSymbol) >= 0) { return aliasedSymbol; } @@ -6055,7 +6056,7 @@ namespace ts { // Finally, try all properties with the same name in any type the containing type extended or implemented, and // see if any is in the list if (rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { - const result: Symbol[] = []; + let result: Symbol[] = []; getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getName(), result); return forEach(result, s => searchSymbols.indexOf(s) >= 0 ? s : undefined); } @@ -6066,21 +6067,21 @@ namespace ts { function getPropertySymbolsFromContextualType(node: Node): Symbol[] { if (isNameOfPropertyAssignment(node)) { - const objectLiteral = node.parent.parent; - const contextualType = typeChecker.getContextualType(objectLiteral); - const name = (node).text; + let objectLiteral = node.parent.parent; + let contextualType = typeChecker.getContextualType(objectLiteral); + let name = (node).text; if (contextualType) { if (contextualType.flags & TypeFlags.Union) { // This is a union type, first see if the property we are looking for is a union property (i.e. exists in all types) // if not, search the constituent types for the property - const unionProperty = contextualType.getProperty(name); + let unionProperty = contextualType.getProperty(name) if (unionProperty) { return [unionProperty]; } else { - const result: Symbol[] = []; + let result: Symbol[] = []; forEach((contextualType).types, t => { - const symbol = t.getProperty(name); + let symbol = t.getProperty(name); if (symbol) { result.push(symbol); } @@ -6089,7 +6090,7 @@ namespace ts { } } else { - const symbol = contextualType.getProperty(name); + let symbol = contextualType.getProperty(name); if (symbol) { return [symbol]; } @@ -6118,8 +6119,8 @@ namespace ts { // Remember the last meaning lastIterationMeaning = meaning; - for (const declaration of declarations) { - const declarationMeaning = getMeaningFromDeclaration(declaration); + for (let declaration of declarations) { + let declarationMeaning = getMeaningFromDeclaration(declaration); if (declarationMeaning & meaning) { meaning |= declarationMeaning; @@ -6154,13 +6155,13 @@ namespace ts { return true; } - const parent = node.parent; + let parent = node.parent; if (parent) { if (parent.kind === SyntaxKind.PostfixUnaryExpression || parent.kind === SyntaxKind.PrefixUnaryExpression) { return true; } else if (parent.kind === SyntaxKind.BinaryExpression && (parent).left === node) { - const operator = (parent).operatorToken.kind; + let operator = (parent).operatorToken.kind; return SyntaxKind.FirstAssignment <= operator && operator <= SyntaxKind.LastAssignment; } } @@ -6182,8 +6183,8 @@ namespace ts { function getEmitOutput(fileName: string): EmitOutput { synchronizeHostData(); - const sourceFile = getValidSourceFile(fileName); - const outputFiles: OutputFile[] = []; + let sourceFile = getValidSourceFile(fileName); + let outputFiles: OutputFile[] = []; function writeFile(fileName: string, data: string, writeByteOrderMark: boolean) { outputFiles.push({ @@ -6193,7 +6194,7 @@ namespace ts { }); } - const emitOutput = program.emit(sourceFile, writeFile, cancellationToken); + let emitOutput = program.emit(sourceFile, writeFile, cancellationToken); return { outputFiles, @@ -6286,7 +6287,7 @@ namespace ts { } if (!isLastClause && root.parent.kind === SyntaxKind.ExpressionWithTypeArguments && root.parent.parent.kind === SyntaxKind.HeritageClause) { - const decl = root.parent.parent.parent; + let decl = root.parent.parent.parent; return (decl.kind === SyntaxKind.ClassDeclaration && (root.parent.parent).token === SyntaxKind.ImplementsKeyword) || (decl.kind === SyntaxKind.InterfaceDeclaration && (root.parent.parent).token === SyntaxKind.ExtendsKeyword); } @@ -6358,7 +6359,7 @@ namespace ts { function getSignatureHelpItems(fileName: string, position: number): SignatureHelpItems { synchronizeHostData(); - const sourceFile = getValidSourceFile(fileName); + let sourceFile = getValidSourceFile(fileName); return SignatureHelp.getSignatureHelpItems(program, sourceFile, position, cancellationToken); } @@ -6369,10 +6370,10 @@ namespace ts { } function getNameOrDottedNameSpan(fileName: string, startPos: number, endPos: number): TextSpan { - const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); // Get node at the location - const node = getTouchingPropertyName(sourceFile, startPos); + let node = getTouchingPropertyName(sourceFile, startPos); if (!node) { return; @@ -6428,13 +6429,13 @@ namespace ts { function getBreakpointStatementAtPosition(fileName: string, position: number) { // doesn't use compiler - no need to synchronize with host - const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); return BreakpointResolver.spanInSourceFileAtLocation(sourceFile, position); } function getNavigationBarItems(fileName: string): NavigationBarItem[] { - const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); return NavigationBar.getNavigationBarItems(sourceFile, host.getCompilationSettings()); } @@ -6466,11 +6467,11 @@ namespace ts { function getEncodedSemanticClassifications(fileName: string, span: TextSpan): Classifications { synchronizeHostData(); - const sourceFile = getValidSourceFile(fileName); - const typeChecker = program.getTypeChecker(); + let sourceFile = getValidSourceFile(fileName); + let typeChecker = program.getTypeChecker(); - const result: number[] = []; - const classifiableNames = program.getClassifiableNames(); + let result: number[] = []; + let classifiableNames = program.getClassifiableNames(); processNode(sourceFile); return { spans: result, endOfLineState: EndOfLineState.None }; @@ -6482,7 +6483,7 @@ namespace ts { } function classifySymbol(symbol: Symbol, meaningAtPosition: SemanticMeaning): ClassificationType { - const flags = symbol.getFlags(); + let flags = symbol.getFlags(); if ((flags & SymbolFlags.Classifiable) === SymbolFlags.None) { return; } @@ -6530,19 +6531,19 @@ namespace ts { function processNode(node: Node) { // Only walk into nodes that intersect the requested span. if (node && textSpanIntersectsWith(span, node.getFullStart(), node.getFullWidth())) { - const kind = node.kind; + let kind = node.kind; checkForClassificationCancellation(kind); if (kind === SyntaxKind.Identifier && !nodeIsMissing(node)) { - const identifier = node; + let identifier = node; // Only bother calling into the typechecker if this is an identifier that // could possibly resolve to a type name. This makes classification run // in a third of the time it would normally take. if (classifiableNames[identifier.text]) { - const symbol = typeChecker.getSymbolAtLocation(node); + let symbol = typeChecker.getSymbolAtLocation(node); if (symbol) { - const type = classifySymbol(symbol, getMeaningFromLocation(node)); + let type = classifySymbol(symbol, getMeaningFromLocation(node)); if (type) { pushClassification(node.getStart(), node.getWidth(), type); } @@ -6582,8 +6583,8 @@ namespace ts { function convertClassifications(classifications: Classifications): ClassifiedSpan[] { Debug.assert(classifications.spans.length % 3 === 0); - const dense = classifications.spans; - const result: ClassifiedSpan[] = []; + let dense = classifications.spans; + let result: ClassifiedSpan[] = []; for (let i = 0, n = dense.length; i < n; i += 3) { result.push({ textSpan: createTextSpan(dense[i], dense[i + 1]), @@ -6600,15 +6601,15 @@ namespace ts { function getEncodedSyntacticClassifications(fileName: string, span: TextSpan): Classifications { // doesn't use compiler - no need to synchronize with host - const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); - const spanStart = span.start; - const spanLength = span.length; + let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + let spanStart = span.start; + let spanLength = span.length; // Make a scanner we can get trivia from. - const triviaScanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ false, sourceFile.languageVariant, sourceFile.text); - const mergeConflictScanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ false, sourceFile.languageVariant, sourceFile.text); + let triviaScanner = createScanner(ScriptTarget.Latest, /*skipTrivia:*/ false, sourceFile.languageVariant, sourceFile.text); + let mergeConflictScanner = createScanner(ScriptTarget.Latest, /*skipTrivia:*/ false, sourceFile.languageVariant, sourceFile.text); - const result: number[] = []; + let result: number[] = []; processElement(sourceFile); return { spans: result, endOfLineState: EndOfLineState.None }; @@ -6622,15 +6623,15 @@ namespace ts { function classifyLeadingTriviaAndGetTokenStart(token: Node): number { triviaScanner.setTextPos(token.pos); while (true) { - const start = triviaScanner.getTextPos(); + let start = triviaScanner.getTextPos(); // only bother scanning if we have something that could be trivia. if (!couldStartTrivia(sourceFile.text, start)) { return start; } - const kind = triviaScanner.scan(); - const end = triviaScanner.getTextPos(); - const width = end - start; + let kind = triviaScanner.scan(); + let end = triviaScanner.getTextPos(); + let width = end - start; // The moment we get something that isn't trivia, then stop processing. if (!isTrivia(kind)) { @@ -6654,8 +6655,8 @@ namespace ts { } if (kind === SyntaxKind.ConflictMarkerTrivia) { - const text = sourceFile.text; - const ch = text.charCodeAt(start); + let text = sourceFile.text; + let ch = text.charCodeAt(start); // for the <<<<<<< and >>>>>>> markers, we just add them in as comments // in the classification stream. @@ -6676,7 +6677,7 @@ namespace ts { if (kind === SyntaxKind.MultiLineCommentTrivia) { // See if this is a doc comment. If so, we'll classify certain portions of it // specially. - const docCommentAndDiagnostics = parseIsolatedJSDocComment(sourceFile.text, start, width); + let docCommentAndDiagnostics = parseIsolatedJSDocComment(sourceFile.text, start, width); if (docCommentAndDiagnostics && docCommentAndDiagnostics.jsDocComment) { docCommentAndDiagnostics.jsDocComment.parent = token; classifyJSDocComment(docCommentAndDiagnostics.jsDocComment); @@ -6695,7 +6696,7 @@ namespace ts { function classifyJSDocComment(docComment: JSDocComment) { let pos = docComment.pos; - for (const tag of docComment.tags) { + for (let tag of docComment.tags) { // As we walk through each tag, classify the portion of text from the end of // the last tag (or the start of the entire doc comment) as 'comment'. if (tag.pos !== pos) { @@ -6753,7 +6754,7 @@ namespace ts { } function processJSDocTemplateTag(tag: JSDocTemplateTag) { - for (const child of tag.getChildren()) { + for (let child of tag.getChildren()) { processElement(child); } } @@ -6775,11 +6776,11 @@ namespace ts { } function classifyDisabledCodeToken() { - const start = mergeConflictScanner.getTextPos(); - const tokenKind = mergeConflictScanner.scan(); - const end = mergeConflictScanner.getTextPos(); + let start = mergeConflictScanner.getTextPos(); + let tokenKind = mergeConflictScanner.scan(); + let end = mergeConflictScanner.getTextPos(); - const type = classifyTokenType(tokenKind); + let type = classifyTokenType(tokenKind); if (type) { pushClassification(start, end - start, type); } @@ -6790,12 +6791,12 @@ namespace ts { return; } - const tokenStart = classifyLeadingTriviaAndGetTokenStart(token); + let tokenStart = classifyLeadingTriviaAndGetTokenStart(token); - const tokenWidth = token.end - tokenStart; + let tokenWidth = token.end - tokenStart; Debug.assert(tokenWidth >= 0); if (tokenWidth > 0) { - const type = classifyTokenType(token.kind, token); + let type = classifyTokenType(token.kind, token); if (type) { pushClassification(tokenStart, tokenWidth, type); } @@ -6922,9 +6923,9 @@ namespace ts { if (decodedTextSpanIntersectsWith(spanStart, spanLength, element.pos, element.getFullWidth())) { checkForClassificationCancellation(element.kind); - const children = element.getChildren(sourceFile); + let children = element.getChildren(sourceFile); for (let i = 0, n = children.length; i < n; i++) { - const child = children[i]; + let child = children[i]; if (isToken(child)) { classifyToken(child); } @@ -6939,28 +6940,28 @@ namespace ts { function getOutliningSpans(fileName: string): OutliningSpan[] { // doesn't use compiler - no need to synchronize with host - const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); return OutliningElementsCollector.collectElements(sourceFile); } function getBraceMatchingAtPosition(fileName: string, position: number) { - const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); - const result: TextSpan[] = []; + let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + let result: TextSpan[] = []; - const token = getTouchingToken(sourceFile, position); + let token = getTouchingToken(sourceFile, position); if (token.getStart(sourceFile) === position) { - const matchKind = getMatchingTokenKind(token); + let matchKind = getMatchingTokenKind(token); // Ensure that there is a corresponding token to match ours. if (matchKind) { - const parentElement = token.parent; + let parentElement = token.parent; - const childNodes = parentElement.getChildren(sourceFile); - for (const current of childNodes) { + let childNodes = parentElement.getChildren(sourceFile); + for (let current of childNodes) { if (current.kind === matchKind) { - const range1 = createTextSpan(token.getStart(sourceFile), token.getWidth(sourceFile)); - const range2 = createTextSpan(current.getStart(sourceFile), current.getWidth(sourceFile)); + let range1 = createTextSpan(token.getStart(sourceFile), token.getWidth(sourceFile)); + let range2 = createTextSpan(current.getStart(sourceFile), current.getWidth(sourceFile)); // We want to order the braces when we return the result. if (range1.start < range2.start) { @@ -6980,11 +6981,11 @@ namespace ts { function getMatchingTokenKind(token: Node): ts.SyntaxKind { switch (token.kind) { - case ts.SyntaxKind.OpenBraceToken: return ts.SyntaxKind.CloseBraceToken; + case ts.SyntaxKind.OpenBraceToken: return ts.SyntaxKind.CloseBraceToken case ts.SyntaxKind.OpenParenToken: return ts.SyntaxKind.CloseParenToken; case ts.SyntaxKind.OpenBracketToken: return ts.SyntaxKind.CloseBracketToken; case ts.SyntaxKind.LessThanToken: return ts.SyntaxKind.GreaterThanToken; - case ts.SyntaxKind.CloseBraceToken: return ts.SyntaxKind.OpenBraceToken; + case ts.SyntaxKind.CloseBraceToken: return ts.SyntaxKind.OpenBraceToken case ts.SyntaxKind.CloseParenToken: return ts.SyntaxKind.OpenParenToken; case ts.SyntaxKind.CloseBracketToken: return ts.SyntaxKind.OpenBracketToken; case ts.SyntaxKind.GreaterThanToken: return ts.SyntaxKind.LessThanToken; @@ -6996,29 +6997,29 @@ namespace ts { function getIndentationAtPosition(fileName: string, position: number, editorOptions: EditorOptions) { let start = new Date().getTime(); - const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); log("getIndentationAtPosition: getCurrentSourceFile: " + (new Date().getTime() - start)); start = new Date().getTime(); - const result = formatting.SmartIndenter.getIndentation(position, sourceFile, editorOptions); + let result = formatting.SmartIndenter.getIndentation(position, sourceFile, editorOptions); log("getIndentationAtPosition: computeIndentation : " + (new Date().getTime() - start)); return result; } function getFormattingEditsForRange(fileName: string, start: number, end: number, options: FormatCodeOptions): TextChange[] { - const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); return formatting.formatSelection(start, end, sourceFile, getRuleProvider(options), options); } function getFormattingEditsForDocument(fileName: string, options: FormatCodeOptions): TextChange[] { - const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); return formatting.formatDocument(sourceFile, getRuleProvider(options), options); } function getFormattingEditsAfterKeystroke(fileName: string, position: number, key: string, options: FormatCodeOptions): TextChange[] { - const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); if (key === "}") { return formatting.formatOnClosingCurly(position, sourceFile, getRuleProvider(options), options); @@ -7054,16 +7055,16 @@ namespace ts { * be performed. */ function getDocCommentTemplateAtPosition(fileName: string, position: number): TextInsertion { - const start = new Date().getTime(); - const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + let start = new Date().getTime(); + let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); // Check if in a context where we don't want to perform any insertion if (isInString(sourceFile, position) || isInComment(sourceFile, position) || hasDocComment(sourceFile, position)) { return undefined; } - const tokenAtPos = getTokenAtPosition(sourceFile, position); - const tokenStart = tokenAtPos.getStart(); + let tokenAtPos = getTokenAtPosition(sourceFile, position); + let tokenStart = tokenAtPos.getStart() if (!tokenAtPos || tokenStart < position) { return undefined; } @@ -7099,11 +7100,11 @@ namespace ts { return undefined; } - const parameters = getParametersForJsDocOwningNode(commentOwner); - const posLineAndChar = sourceFile.getLineAndCharacterOfPosition(position); - const lineStart = sourceFile.getLineStarts()[posLineAndChar.line]; + let parameters = getParametersForJsDocOwningNode(commentOwner); + let posLineAndChar = sourceFile.getLineAndCharacterOfPosition(position); + let lineStart = sourceFile.getLineStarts()[posLineAndChar.line]; - const indentationStr = sourceFile.text.substr(lineStart, posLineAndChar.character); + let indentationStr = sourceFile.text.substr(lineStart, posLineAndChar.character); // TODO: call a helper method instead once PR #4133 gets merged in. const newLine = host.getNewLine ? host.getNewLine() : "\r\n"; @@ -7127,7 +7128,7 @@ namespace ts { // * if the caret was directly in front of the object, then we add an extra line and indentation. const preamble = "/**" + newLine + indentationStr + " * "; - const result = + let result = preamble + newLine + docParams + indentationStr + " */" + @@ -7171,7 +7172,7 @@ namespace ts { case SyntaxKind.ArrowFunction: return (rightHandSide).parameters; case SyntaxKind.ClassExpression: - for (const member of (rightHandSide).members) { + for (let member of (rightHandSide).members) { if (member.kind === SyntaxKind.Constructor) { return (member).parameters; } @@ -7191,15 +7192,15 @@ namespace ts { // anything away. synchronizeHostData(); - const sourceFile = getValidSourceFile(fileName); + let sourceFile = getValidSourceFile(fileName); cancellationToken.throwIfCancellationRequested(); - const fileContents = sourceFile.text; - const result: TodoComment[] = []; + let fileContents = sourceFile.text; + let result: TodoComment[] = []; if (descriptors.length > 0) { - const regExp = getTodoCommentsRegExp(); + let regExp = getTodoCommentsRegExp(); let matchArray: RegExpExecArray; while (matchArray = regExp.exec(fileContents)) { @@ -7222,15 +7223,15 @@ namespace ts { // // i.e. 'undefined' in position 3 above means TODO(jason) didn't match. // "hack" in position 4 means HACK did match. - const firstDescriptorCaptureIndex = 3; + let firstDescriptorCaptureIndex = 3; Debug.assert(matchArray.length === descriptors.length + firstDescriptorCaptureIndex); - const preamble = matchArray[1]; - const matchPosition = matchArray.index + preamble.length; + let preamble = matchArray[1]; + let matchPosition = matchArray.index + preamble.length; // OK, we have found a match in the file. This is only an acceptable match if // it is contained within a comment. - const token = getTokenAtPosition(sourceFile, matchPosition); + let token = getTokenAtPosition(sourceFile, matchPosition); if (!isInsideComment(sourceFile, token, matchPosition)) { continue; } @@ -7249,7 +7250,7 @@ namespace ts { continue; } - const message = matchArray[2]; + let message = matchArray[2]; result.push({ descriptor: descriptor, message: message, @@ -7280,14 +7281,14 @@ namespace ts { // // The following three regexps are used to match the start of the text up to the TODO // comment portion. - const singleLineCommentStart = /(?:\/\/+\s*)/.source; - const multiLineCommentStart = /(?:\/\*+\s*)/.source; - const anyNumberOfSpacesAndAsterixesAtStartOfLine = /(?:^(?:\s|\*)*)/.source; + let singleLineCommentStart = /(?:\/\/+\s*)/.source; + let multiLineCommentStart = /(?:\/\*+\s*)/.source; + let anyNumberOfSpacesAndAsterixesAtStartOfLine = /(?:^(?:\s|\*)*)/.source; // Match any of the above three TODO comment start regexps. // Note that the outermost group *is* a capture group. We want to capture the preamble // so that we can determine the starting position of the TODO comment match. - const preamble = "(" + anyNumberOfSpacesAndAsterixesAtStartOfLine + "|" + singleLineCommentStart + "|" + multiLineCommentStart + ")"; + let preamble = "(" + anyNumberOfSpacesAndAsterixesAtStartOfLine + "|" + singleLineCommentStart + "|" + multiLineCommentStart + ")"; // Takes the descriptors and forms a regexp that matches them as if they were literals. // For example, if the descriptors are "TODO(jason)" and "HACK", then this will be: @@ -7297,17 +7298,17 @@ namespace ts { // Note that the outermost group is *not* a capture group, but the innermost groups // *are* capture groups. By capturing the inner literals we can determine after // matching which descriptor we are dealing with. - const literals = "(?:" + map(descriptors, d => "(" + escapeRegExp(d.text) + ")").join("|") + ")"; + let literals = "(?:" + map(descriptors, d => "(" + escapeRegExp(d.text) + ")").join("|") + ")"; // After matching a descriptor literal, the following regexp matches the rest of the // text up to the end of the line (or */). - const endOfLineOrEndOfComment = /(?:$|\*\/)/.source; - const messageRemainder = /(?:.*?)/.source; + let endOfLineOrEndOfComment = /(?:$|\*\/)/.source + let messageRemainder = /(?:.*?)/.source // This is the portion of the match we'll return as part of the TODO comment result. We // match the literal portion up to the end of the line or end of comment. - const messagePortion = "(" + literals + messageRemainder + ")"; - const regExpString = preamble + messagePortion + endOfLineOrEndOfComment; + let messagePortion = "(" + literals + messageRemainder + ")"; + let regExpString = preamble + messagePortion + endOfLineOrEndOfComment; // The final regexp will look like this: // /((?:\/\/+\s*)|(?:\/\*+\s*)|(?:^(?:\s|\*)*))((?:(TODO\(jason\))|(HACK))(?:.*?))(?:$|\*\/)/gim @@ -7333,40 +7334,40 @@ namespace ts { function getRenameInfo(fileName: string, position: number): RenameInfo { synchronizeHostData(); - const sourceFile = getValidSourceFile(fileName); - const typeChecker = program.getTypeChecker(); + let sourceFile = getValidSourceFile(fileName); + let typeChecker = program.getTypeChecker(); - const node = getTouchingWord(sourceFile, position); + let node = getTouchingWord(sourceFile, position); // Can only rename an identifier. if (node && node.kind === SyntaxKind.Identifier) { - const symbol = typeChecker.getSymbolAtLocation(node); + let symbol = typeChecker.getSymbolAtLocation(node); // Only allow a symbol to be renamed if it actually has at least one declaration. if (symbol) { - const declarations = symbol.getDeclarations(); + let declarations = symbol.getDeclarations(); if (declarations && declarations.length > 0) { // Disallow rename for elements that are defined in the standard TypeScript library. - const defaultLibFileName = host.getDefaultLibFileName(host.getCompilationSettings()); + let defaultLibFileName = host.getDefaultLibFileName(host.getCompilationSettings()); if (defaultLibFileName) { - for (const current of declarations) { - const sourceFile = current.getSourceFile(); - const canonicalName = getCanonicalFileName(ts.normalizePath(sourceFile.fileName)); + for (let current of declarations) { + let sourceFile = current.getSourceFile(); + var canonicalName = getCanonicalFileName(ts.normalizePath(sourceFile.fileName)); if (sourceFile && getCanonicalFileName(ts.normalizePath(sourceFile.fileName)) === getCanonicalFileName(ts.normalizePath(defaultLibFileName))) { return getRenameInfoError(getLocaleSpecificMessage(Diagnostics.You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library)); } } } - const displayName = stripQuotes(getDeclaredName(typeChecker, symbol, node)); - const kind = getSymbolKind(symbol, node); + let displayName = stripQuotes(getDeclaredName(typeChecker, symbol, node)); + let kind = getSymbolKind(symbol, node); if (kind) { return { canRename: true, - kind, - displayName, localizedErrorMessage: undefined, + displayName, fullDisplayName: typeChecker.getFullyQualifiedName(symbol), + kind: kind, kindModifiers: getSymbolModifiers(symbol), triggerSpan: createTextSpan(node.getStart(), node.getWidth()) }; @@ -7433,14 +7434,14 @@ namespace ts { /* @internal */ export function getNameTable(sourceFile: SourceFile): Map { if (!sourceFile.nameTable) { - initializeNameTable(sourceFile); + initializeNameTable(sourceFile) } return sourceFile.nameTable; } function initializeNameTable(sourceFile: SourceFile): void { - const nameTable: Map = {}; + let nameTable: Map = {}; walk(sourceFile); sourceFile.nameTable = nameTable; @@ -7478,13 +7479,13 @@ namespace ts { /// Classifier export function createClassifier(): Classifier { - const scanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ false); + let scanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ false); /// We do not have a full parser support to know when we should parse a regex or not /// If we consider every slash token to be a regex, we could be missing cases like "1/2/3", where /// we have a series of divide operator. this list allows us to be more accurate by ruling out /// locations where a regexp cannot exist. - const noRegexTable: boolean[] = []; + let noRegexTable: boolean[] = []; noRegexTable[SyntaxKind.Identifier] = true; noRegexTable[SyntaxKind.StringLiteral] = true; noRegexTable[SyntaxKind.NumericLiteral] = true; @@ -7518,7 +7519,7 @@ namespace ts { // // Where on the second line, you will get the 'return' keyword, // a string literal, and a template end consisting of '} } `'. - const templateStack: SyntaxKind[] = []; + let templateStack: SyntaxKind[] = []; /** Returns true if 'keyword2' can legally follow 'keyword1' in any language construct. */ function canFollow(keyword1: SyntaxKind, keyword2: SyntaxKind) { @@ -7544,18 +7545,18 @@ namespace ts { } function convertClassifications(classifications: Classifications, text: string): ClassificationResult { - const entries: ClassificationInfo[] = []; - const dense = classifications.spans; + let entries: ClassificationInfo[] = []; + let dense = classifications.spans; let lastEnd = 0; for (let i = 0, n = dense.length; i < n; i += 3) { - const start = dense[i]; - const length = dense[i + 1]; - const type = dense[i + 2]; + let start = dense[i]; + let length = dense[i + 1]; + let type = dense[i + 2]; // Make a whitespace entry between the last item and this one. if (lastEnd >= 0) { - const whitespaceLength = start - lastEnd; + let whitespaceLength = start - lastEnd; if (whitespaceLength > 0) { entries.push({ length: whitespaceLength, classification: TokenClass.Whitespace }); } @@ -7565,7 +7566,7 @@ namespace ts { lastEnd = start + length; } - const whitespaceLength = text.length - lastEnd; + let whitespaceLength = text.length - lastEnd; if (whitespaceLength > 0) { entries.push({ length: whitespaceLength, classification: TokenClass.Whitespace }); } @@ -7619,7 +7620,7 @@ namespace ts { // (and a newline). That way when we lex we'll think we're still in a multiline comment. switch (lexState) { case EndOfLineState.InDoubleQuoteStringLiteral: - text = "\"\\\n" + text; + text = '"\\\n' + text; offset = 3; break; case EndOfLineState.InSingleQuoteStringLiteral: @@ -7645,7 +7646,7 @@ namespace ts { scanner.setText(text); - const result: Classifications = { + let result: Classifications = { endOfLineState: EndOfLineState.None, spans: [] }; @@ -7727,7 +7728,7 @@ namespace ts { // If we don't have anything on the template stack, // then we aren't trying to keep track of a previously scanned template head. if (templateStack.length > 0) { - const lastTemplateStackToken = lastOrUndefined(templateStack); + let lastTemplateStackToken = lastOrUndefined(templateStack); if (lastTemplateStackToken === SyntaxKind.TemplateHead) { token = scanner.reScanTemplateToken(); @@ -7757,17 +7758,17 @@ namespace ts { return result; function processToken(): void { - const start = scanner.getTokenPos(); - const end = scanner.getTextPos(); + let start = scanner.getTokenPos(); + let end = scanner.getTextPos(); addResult(start, end, classFromKind(token)); if (end >= text.length) { if (token === SyntaxKind.StringLiteral || token === SyntaxKind.StringLiteralType) { // Check to see if we finished up on a multiline string literal. - const tokenText = scanner.getTokenText(); + let tokenText = scanner.getTokenText(); if (scanner.isUnterminated()) { - const lastCharIndex = tokenText.length - 1; + let lastCharIndex = tokenText.length - 1; let numBackslashes = 0; while (tokenText.charCodeAt(lastCharIndex - numBackslashes) === CharacterCodes.backslash) { @@ -7776,7 +7777,7 @@ namespace ts { // If we have an odd number of backslashes, then the multiline string is unclosed if (numBackslashes & 1) { - const quoteChar = tokenText.charCodeAt(0); + let quoteChar = tokenText.charCodeAt(0); result.endOfLineState = quoteChar === CharacterCodes.doubleQuote ? EndOfLineState.InDoubleQuoteStringLiteral : EndOfLineState.InSingleQuoteStringLiteral; @@ -7825,7 +7826,7 @@ namespace ts { // relative to the original text. start -= offset; end -= offset; - const length = end - start; + let length = end - start; if (length > 0) { result.spans.push(start); @@ -7940,7 +7941,7 @@ namespace ts { } /// getDefaultLibraryFilePath - declare const __dirname: string; + declare let __dirname: string; /** * Get the path of the default library files (lib.d.ts) as distributed with the typescript From a2b6e8c2c0f6e5bf9ac259c16b399791e3f1ca13 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 15 Dec 2015 11:39:54 -0800 Subject: [PATCH 45/79] Use nicer flag collection method --- src/compiler/checker.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 09760b6b1e5..0700a82a6b8 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3766,13 +3766,14 @@ namespace ts { function createUnionOrIntersectionProperty(containingType: UnionOrIntersectionType, name: string): Symbol { const types = containingType.types; let props: Symbol[]; - let isOptional = !!(containingType.flags & TypeFlags.Intersection); + // Flags we want to propagate to the result if they exist in all source symbols + let commonFlags = (containingType.flags & TypeFlags.Intersection) ? SymbolFlags.Optional : SymbolFlags.None; for (const current of types) { const type = getApparentType(current); if (type !== unknownType) { const prop = getPropertyOfType(type, name); if (prop && !(getDeclarationFlagsFromSymbol(prop) & (NodeFlags.Private | NodeFlags.Protected))) { - isOptional = isOptional && !!(prop.flags & SymbolFlags.Optional); + commonFlags &= prop.flags; if (!props) { props = [prop]; } @@ -3804,7 +3805,7 @@ namespace ts { SymbolFlags.Property | SymbolFlags.Transient | SymbolFlags.SyntheticProperty | - (isOptional ? SymbolFlags.Optional : SymbolFlags.None), + commonFlags, name); result.containingType = containingType; result.declarations = declarations; From d8db60a9a2be9c4ca82170bc6bb457b70b20f7b5 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 15 Dec 2015 17:52:26 -0800 Subject: [PATCH 46/79] Use a comparison function instead of creating a new type for each signature. --- src/compiler/checker.ts | 125 ++++++++++++++++++++++++++++++---------- src/compiler/types.ts | 2 - 2 files changed, 94 insertions(+), 33 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index fac21177aae..e1b400310b5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3501,7 +3501,7 @@ namespace ts { function findMatchingSignature(signatureList: Signature[], signature: Signature, partialMatch: boolean, ignoreReturnTypes: boolean): Signature { for (const s of signatureList) { - if (compareSignatures(s, signature, partialMatch, ignoreReturnTypes, compareTypes)) { + if (compareSignaturesIdentical(s, signature, partialMatch, ignoreReturnTypes, compareTypesIdentical)) { return s; } } @@ -4115,16 +4115,6 @@ namespace ts { return signature.erasedSignatureCache; } - function getAnyReturningErasedSignature(signature: Signature): Signature { - if (!signature.anyReturningErasedSignatureCache) { - const erasedSignature = getErasedSignature(signature); - const anyReturningErasedSignature = cloneSignature(erasedSignature); - anyReturningErasedSignature.resolvedReturnType = anyType; - signature.anyReturningErasedSignatureCache = anyReturningErasedSignature; - } - return signature.anyReturningErasedSignatureCache; - } - function getOrCreateTypeFromSignature(signature: Signature): ObjectType { // There are two ways to declare a construct signature, one is by declaring a class constructor // using the constructor keyword, and the other is declaring a bare construct signature in an @@ -4965,7 +4955,7 @@ namespace ts { return checkTypeRelatedTo(source, target, identityRelation, /*errorNode*/ undefined); } - function compareTypes(source: Type, target: Type): Ternary { + function compareTypesIdentical(source: Type, target: Type): Ternary { return checkTypeRelatedTo(source, target, identityRelation, /*errorNode*/ undefined) ? Ternary.True : Ternary.False; } @@ -4985,10 +4975,53 @@ namespace ts { return checkTypeRelatedTo(source, target, assignableRelation, errorNode, headMessage, containingMessageChain); } - function isSignatureAssignableTo(source: Signature, target: Signature): boolean { - const sourceType = getOrCreateTypeFromSignature(source); - const targetType = getOrCreateTypeFromSignature(target); - return checkTypeRelatedTo(sourceType, targetType, assignableRelation, /*errorNode*/ undefined); + /** + * See signatureRelatedTo, compareSignaturesIdentical + */ + function isSignatureAssignableTo(source: Signature, target: Signature, ignoreReturnTypes: boolean): boolean { + // TODO (drosen): De-duplicate code between related functions. + if (source === target) { + return true; + } + if (!target.hasRestParameter && source.minArgumentCount > target.parameters.length) { + return false; + } + + // Spec 1.0 Section 3.8.3 & 3.8.4: + // M and N (the signatures) are instantiated using type Any as the type argument for all type parameters declared by M and N + source = getErasedSignature(source); + target = getErasedSignature(target); + + const sourceMax = getNumNonRestParameters(source); + const targetMax = getNumNonRestParameters(target); + const checkCount = getNumParametersToCheckForSignatureRelatability(source, sourceMax, target, targetMax); + for (let i = 0; i < checkCount; i++) { + const s = i < sourceMax ? getTypeOfSymbol(source.parameters[i]) : getRestTypeOfSignature(source); + const t = i < targetMax ? getTypeOfSymbol(target.parameters[i]) : getRestTypeOfSignature(target); + const related = isTypeAssignableTo(t, s) || isTypeAssignableTo(s, t); + if (!related) { + return false; + } + } + + if (!ignoreReturnTypes) { + const targetReturnType = getReturnTypeOfSignature(target); + if (targetReturnType === voidType) { + return true; + } + const sourceReturnType = getReturnTypeOfSignature(source); + + // The following block preserves behavior forbidding boolean returning functions from being assignable to type guard returning functions + if (targetReturnType.flags & TypeFlags.PredicateType && (targetReturnType as PredicateType).predicate.kind === TypePredicateKind.Identifier) { + if (!(sourceReturnType.flags & TypeFlags.PredicateType)) { + return false; + } + } + + return isTypeAssignableTo(sourceReturnType, targetReturnType); + } + + return true; } function isImplementationCompatibleWithOverload(implementation: Signature, overload: Signature): boolean { @@ -5002,15 +5035,35 @@ namespace ts { || checkTypeRelatedTo(targetReturnType, sourceReturnType, assignableRelation, /*errorNode*/ undefined) || checkTypeRelatedTo(sourceReturnType, targetReturnType, assignableRelation, /*errorNode*/ undefined)) { - // The return types are compatible, so create versions of the signature with 'any' as the return type. - // We need to do this so that we can check assignability while disregarding the return type. - const anyReturningSource = getAnyReturningErasedSignature(implementation); - const anyReturningTarget = getAnyReturningErasedSignature(overload); + return isSignatureAssignableTo(erasedSource, erasedTarget, /*ignoreReturnTypes*/ true); + } - // Create object types to actually perform relation checks. - const anyReturningSourceType = getOrCreateTypeFromSignature(anyReturningSource); - const anyReturningTargetType = getOrCreateTypeFromSignature(anyReturningTarget); - return checkTypeRelatedTo(anyReturningSourceType, anyReturningTargetType, assignableRelation, /*errorNode*/ undefined); + return false; + } + + function getNumNonRestParameters(signature: Signature) { + const numParams = signature.parameters.length; + return signature.hasRestParameter ? + numParams - 1 : + numParams; + } + + function getNumParametersToCheckForSignatureRelatability(source: Signature, sourceNonRestParamCount: number, target: Signature, targetNonRestParamCount: number) { + if (source.hasRestParameter === target.hasRestParameter) { + if (source.hasRestParameter) { + // If both have rest parameters, get the max and add 1 to + // compensate for the rest parameter. + return Math.max(sourceNonRestParamCount, targetNonRestParamCount) + 1; + } + else { + return Math.min(sourceNonRestParamCount, targetNonRestParamCount); + } + } + else { + // Return the count for whichever signature doesn't have rest parameters. + return source.hasRestParameter ? + targetNonRestParamCount : + sourceNonRestParamCount; } } @@ -5645,7 +5698,11 @@ namespace ts { } } + /** + * See signatureAssignableTo, signatureAssignableTo + */ function signatureRelatedTo(source: Signature, target: Signature, reportErrors: boolean): Ternary { + // TODO (drosen): De-duplicate code between related functions. if (source === target) { return Ternary.True; } @@ -5697,10 +5754,12 @@ namespace ts { } const targetReturnType = getReturnTypeOfSignature(target); - if (targetReturnType === voidType) return result; + if (targetReturnType === voidType) { + return result; + } const sourceReturnType = getReturnTypeOfSignature(source); - // The follow block preserves old behavior forbidding boolean returning functions from being assignable to type guard returning functions + // The following block preserves behavior forbidding boolean returning functions from being assignable to type guard returning functions if (targetReturnType.flags & TypeFlags.PredicateType && (targetReturnType as PredicateType).predicate.kind === TypePredicateKind.Identifier) { if (!(sourceReturnType.flags & TypeFlags.PredicateType)) { if (reportErrors) { @@ -5721,7 +5780,7 @@ namespace ts { } let result = Ternary.True; for (let i = 0, len = sourceSignatures.length; i < len; ++i) { - const related = compareSignatures(sourceSignatures[i], targetSignatures[i], /*partialMatch*/ false, /*ignoreReturnTypes*/ false, isRelatedTo); + const related = compareSignaturesIdentical(sourceSignatures[i], targetSignatures[i], /*partialMatch*/ false, /*ignoreReturnTypes*/ false, isRelatedTo); if (!related) { return Ternary.False; } @@ -5833,7 +5892,7 @@ namespace ts { } function isPropertyIdenticalTo(sourceProp: Symbol, targetProp: Symbol): boolean { - return compareProperties(sourceProp, targetProp, compareTypes) !== Ternary.False; + return compareProperties(sourceProp, targetProp, compareTypesIdentical) !== Ternary.False; } function compareProperties(sourceProp: Symbol, targetProp: Symbol, compareTypes: (source: Type, target: Type) => Ternary): Ternary { @@ -5880,7 +5939,11 @@ namespace ts { return false; } - function compareSignatures(source: Signature, target: Signature, partialMatch: boolean, ignoreReturnTypes: boolean, compareTypes: (s: Type, t: Type) => Ternary): Ternary { + /** + * See signatureRelatedTo, compareSignaturesIdentical + */ + function compareSignaturesIdentical(source: Signature, target: Signature, partialMatch: boolean, ignoreReturnTypes: boolean, compareTypes: (s: Type, t: Type) => Ternary): Ternary { + // TODO (drosen): De-duplicate code between related functions. if (source === target) { return Ternary.True; } @@ -7571,7 +7634,7 @@ namespace ts { // This signature will contribute to contextual union signature signatureList = [signature]; } - else if (!compareSignatures(signatureList[0], signature, /*partialMatch*/ false, /*ignoreReturnTypes*/ true, compareTypes)) { + else if (!compareSignaturesIdentical(signatureList[0], signature, /*partialMatch*/ false, /*ignoreReturnTypes*/ true, compareTypesIdentical)) { // Signatures aren't identical, do not use return undefined; } @@ -11564,7 +11627,7 @@ namespace ts { } for (const otherSignature of signaturesToCheck) { - if (!otherSignature.hasStringLiterals && isSignatureAssignableTo(signature, otherSignature)) { + if (!otherSignature.hasStringLiterals && isSignatureAssignableTo(signature, otherSignature, /*ignoreReturnTypes*/ false)) { return; } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index c6c78709300..ff8ffa4ebd2 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2280,8 +2280,6 @@ namespace ts { /* @internal */ erasedSignatureCache?: Signature; // Erased version of signature (deferred) /* @internal */ - anyReturningErasedSignatureCache?: Signature; // A version of the erased signature whose type returns 'any' - /* @internal */ isolatedSignatureType?: ObjectType; // A manufactured type that just contains the signature for purposes of signature comparison } From 731925bffeb356e3ee18628bc8d8997d6c79c83f Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 15 Dec 2015 20:55:54 -0800 Subject: [PATCH 47/79] Fix linter nits. --- src/compiler/checker.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e1b400310b5..c017f9e7921 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5040,7 +5040,7 @@ namespace ts { return false; } - + function getNumNonRestParameters(signature: Signature) { const numParams = signature.parameters.length; return signature.hasRestParameter ? @@ -5651,7 +5651,7 @@ namespace ts { shouldElaborateErrors = false; } } - // don't elaborate the primitive apparent types (like Number) + // don't elaborate the primitive apparent types (like Number) // because the actual primitives will have already been reported. if (shouldElaborateErrors && !isPrimitiveApparentType(source)) { reportError(Diagnostics.Type_0_provides_no_match_for_the_signature_1, From aa1a7664e73c444a5c9ecf147d85b856f94eee79 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Wed, 16 Dec 2015 12:11:24 -0800 Subject: [PATCH 48/79] Add enum/module merge test --- .../enumAssignmentCompat3.errors.txt | 32 +++++++++++++------ .../reference/enumAssignmentCompat3.js | 30 ++++++++++++++++- tests/cases/compiler/enumAssignmentCompat3.ts | 14 +++++++- 3 files changed, 64 insertions(+), 12 deletions(-) diff --git a/tests/baselines/reference/enumAssignmentCompat3.errors.txt b/tests/baselines/reference/enumAssignmentCompat3.errors.txt index c34ad434347..02cb4314777 100644 --- a/tests/baselines/reference/enumAssignmentCompat3.errors.txt +++ b/tests/baselines/reference/enumAssignmentCompat3.errors.txt @@ -1,16 +1,16 @@ -tests/cases/compiler/enumAssignmentCompat3.ts(58,1): error TS2322: Type 'Abcd.E' is not assignable to type 'First.E'. +tests/cases/compiler/enumAssignmentCompat3.ts(68,1): error TS2322: Type 'Abcd.E' is not assignable to type 'First.E'. Property 'd' is missing in type 'First.E'. -tests/cases/compiler/enumAssignmentCompat3.ts(60,1): error TS2322: Type 'Cd.E' is not assignable to type 'First.E'. +tests/cases/compiler/enumAssignmentCompat3.ts(70,1): error TS2322: Type 'Cd.E' is not assignable to type 'First.E'. Property 'd' is missing in type 'First.E'. -tests/cases/compiler/enumAssignmentCompat3.ts(61,1): error TS2322: Type 'Nope' is not assignable to type 'E'. -tests/cases/compiler/enumAssignmentCompat3.ts(65,1): error TS2322: Type 'First.E' is not assignable to type 'Ab.E'. +tests/cases/compiler/enumAssignmentCompat3.ts(71,1): error TS2322: Type 'Nope' is not assignable to type 'E'. +tests/cases/compiler/enumAssignmentCompat3.ts(75,1): error TS2322: Type 'First.E' is not assignable to type 'Ab.E'. Property 'c' is missing in type 'Ab.E'. -tests/cases/compiler/enumAssignmentCompat3.ts(66,1): error TS2322: Type 'First.E' is not assignable to type 'Cd.E'. +tests/cases/compiler/enumAssignmentCompat3.ts(76,1): error TS2322: Type 'First.E' is not assignable to type 'Cd.E'. Property 'a' is missing in type 'Cd.E'. -tests/cases/compiler/enumAssignmentCompat3.ts(67,1): error TS2322: Type 'E' is not assignable to type 'Nope'. -tests/cases/compiler/enumAssignmentCompat3.ts(72,1): error TS2322: Type 'Const.E' is not assignable to type 'First.E'. -tests/cases/compiler/enumAssignmentCompat3.ts(73,1): error TS2322: Type 'First.E' is not assignable to type 'Const.E'. -tests/cases/compiler/enumAssignmentCompat3.ts(76,1): error TS2322: Type 'Merged.E' is not assignable to type 'First.E'. +tests/cases/compiler/enumAssignmentCompat3.ts(77,1): error TS2322: Type 'E' is not assignable to type 'Nope'. +tests/cases/compiler/enumAssignmentCompat3.ts(82,1): error TS2322: Type 'Const.E' is not assignable to type 'First.E'. +tests/cases/compiler/enumAssignmentCompat3.ts(83,1): error TS2322: Type 'First.E' is not assignable to type 'Const.E'. +tests/cases/compiler/enumAssignmentCompat3.ts(86,1): error TS2322: Type 'Merged.E' is not assignable to type 'First.E'. Property 'd' is missing in type 'First.E'. @@ -62,6 +62,15 @@ tests/cases/compiler/enumAssignmentCompat3.ts(76,1): error TS2322: Type 'Merged. } } + namespace Merged2 { + export enum E { + a, b, c + } + export module E { + export let d = 5; + } + } + var abc: First.E; var secondAbc: Abc.E; var secondAbcd: Abcd.E; @@ -71,6 +80,7 @@ tests/cases/compiler/enumAssignmentCompat3.ts(76,1): error TS2322: Type 'Merged. var k: Const.E; var decl: Decl.E; var merged: Merged.E; + var merged2: Merged2.E; abc = secondAbc; // ok abc = secondAbcd; // missing 'd' ~~~ @@ -114,4 +124,6 @@ tests/cases/compiler/enumAssignmentCompat3.ts(76,1): error TS2322: Type 'Merged. ~~~ !!! error TS2322: Type 'Merged.E' is not assignable to type 'First.E'. !!! error TS2322: Property 'd' is missing in type 'First.E'. - merged = abc; // ok \ No newline at end of file + merged = abc; // ok + abc = merged2; // ok + merged2 = abc; // ok \ No newline at end of file diff --git a/tests/baselines/reference/enumAssignmentCompat3.js b/tests/baselines/reference/enumAssignmentCompat3.js index e43874911ce..74f74ab1652 100644 --- a/tests/baselines/reference/enumAssignmentCompat3.js +++ b/tests/baselines/reference/enumAssignmentCompat3.js @@ -46,6 +46,15 @@ namespace Merged { } } +namespace Merged2 { + export enum E { + a, b, c + } + export module E { + export let d = 5; + } +} + var abc: First.E; var secondAbc: Abc.E; var secondAbcd: Abcd.E; @@ -55,6 +64,7 @@ var nope: Abc.Nope; var k: Const.E; var decl: Decl.E; var merged: Merged.E; +var merged2: Merged2.E; abc = secondAbc; // ok abc = secondAbcd; // missing 'd' abc = secondAb; // ok @@ -75,7 +85,9 @@ k = abc; // merged enums compare all their members abc = merged; // missing 'd' -merged = abc; // ok +merged = abc; // ok +abc = merged2; // ok +merged2 = abc; // ok //// [enumAssignmentCompat3.js] var First; @@ -144,6 +156,19 @@ var Merged; })(Merged.E || (Merged.E = {})); var E = Merged.E; })(Merged || (Merged = {})); +var Merged2; +(function (Merged2) { + (function (E) { + E[E["a"] = 0] = "a"; + E[E["b"] = 1] = "b"; + E[E["c"] = 2] = "c"; + })(Merged2.E || (Merged2.E = {})); + var E = Merged2.E; + var E; + (function (E) { + E.d = 5; + })(E = Merged2.E || (Merged2.E = {})); +})(Merged2 || (Merged2 = {})); var abc; var secondAbc; var secondAbcd; @@ -153,6 +178,7 @@ var nope; var k; var decl; var merged; +var merged2; abc = secondAbc; // ok abc = secondAbcd; // missing 'd' abc = secondAb; // ok @@ -172,3 +198,5 @@ k = abc; // merged enums compare all their members abc = merged; // missing 'd' merged = abc; // ok +abc = merged2; // ok +merged2 = abc; // ok diff --git a/tests/cases/compiler/enumAssignmentCompat3.ts b/tests/cases/compiler/enumAssignmentCompat3.ts index 33070572661..97a136468e3 100644 --- a/tests/cases/compiler/enumAssignmentCompat3.ts +++ b/tests/cases/compiler/enumAssignmentCompat3.ts @@ -45,6 +45,15 @@ namespace Merged { } } +namespace Merged2 { + export enum E { + a, b, c + } + export module E { + export let d = 5; + } +} + var abc: First.E; var secondAbc: Abc.E; var secondAbcd: Abcd.E; @@ -54,6 +63,7 @@ var nope: Abc.Nope; var k: Const.E; var decl: Decl.E; var merged: Merged.E; +var merged2: Merged2.E; abc = secondAbc; // ok abc = secondAbcd; // missing 'd' abc = secondAb; // ok @@ -74,4 +84,6 @@ k = abc; // merged enums compare all their members abc = merged; // missing 'd' -merged = abc; // ok \ No newline at end of file +merged = abc; // ok +abc = merged2; // ok +merged2 = abc; // ok \ No newline at end of file From a3cce3868b7e7e92eab3ed7cd3b1637087ef137b Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Wed, 16 Dec 2015 13:19:57 -0800 Subject: [PATCH 49/79] addressed PR feedback --- src/compiler/checker.ts | 2 +- src/compiler/diagnosticMessages.json | 2 +- .../superInObjectLiterals_ES5.errors.txt | 24 ++++++------- ...ect-literal-getters-and-setters.errors.txt | 12 +++---- tests/cases/fourslash/getOccurrencesSuper3.ts | 34 +++++++++++++++++++ 5 files changed, 54 insertions(+), 20 deletions(-) create mode 100644 tests/cases/fourslash/getOccurrencesSuper3.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2dd567cbe90..8a81ac167b0 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7095,7 +7095,7 @@ namespace ts { if (container.parent.kind === SyntaxKind.ObjectLiteralExpression) { if (languageVersion < ScriptTarget.ES6) { - error(node, Diagnostics.super_in_members_of_object_literal_expressions_is_only_allowed_when_option_target_is_ES2015_or_higher); + error(node, Diagnostics.super_is_only_allowed_in_members_of_object_literal_expressions_when_option_target_is_ES2015_or_higher); return unknownType; } else { diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 30b46e5cde2..34552a26b20 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1759,7 +1759,7 @@ "category": "Error", "code": 2658 }, - "'super' in members of object literal expressions is only allowed when option 'target' is 'ES2015' or higher.": { + "'super' is only allowed in members of object literal expressions when option 'target' is 'ES2015' or higher.": { "category": "Error", "code": 2659 }, diff --git a/tests/baselines/reference/superInObjectLiterals_ES5.errors.txt b/tests/baselines/reference/superInObjectLiterals_ES5.errors.txt index 944766cb5ae..a3149ce8cd5 100644 --- a/tests/baselines/reference/superInObjectLiterals_ES5.errors.txt +++ b/tests/baselines/reference/superInObjectLiterals_ES5.errors.txt @@ -1,12 +1,12 @@ -tests/cases/compiler/superInObjectLiterals_ES5.ts(7,9): error TS2659: 'super' in members of object literal expressions is only allowed when option 'target' is 'ES2015' or higher. -tests/cases/compiler/superInObjectLiterals_ES5.ts(10,9): error TS2659: 'super' in members of object literal expressions is only allowed when option 'target' is 'ES2015' or higher. -tests/cases/compiler/superInObjectLiterals_ES5.ts(14,9): error TS2659: 'super' in members of object literal expressions is only allowed when option 'target' is 'ES2015' or higher. +tests/cases/compiler/superInObjectLiterals_ES5.ts(7,9): error TS2659: 'super' is only allowed in members of object literal expressions when option 'target' is 'ES2015' or higher. +tests/cases/compiler/superInObjectLiterals_ES5.ts(10,9): error TS2659: 'super' is only allowed in members of object literal expressions when option 'target' is 'ES2015' or higher. +tests/cases/compiler/superInObjectLiterals_ES5.ts(14,9): error TS2659: 'super' is only allowed in members of object literal expressions when option 'target' is 'ES2015' or higher. tests/cases/compiler/superInObjectLiterals_ES5.ts(17,9): error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. tests/cases/compiler/superInObjectLiterals_ES5.ts(20,9): error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. tests/cases/compiler/superInObjectLiterals_ES5.ts(23,9): error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. -tests/cases/compiler/superInObjectLiterals_ES5.ts(39,17): error TS2659: 'super' in members of object literal expressions is only allowed when option 'target' is 'ES2015' or higher. -tests/cases/compiler/superInObjectLiterals_ES5.ts(42,17): error TS2659: 'super' in members of object literal expressions is only allowed when option 'target' is 'ES2015' or higher. -tests/cases/compiler/superInObjectLiterals_ES5.ts(46,17): error TS2659: 'super' in members of object literal expressions is only allowed when option 'target' is 'ES2015' or higher. +tests/cases/compiler/superInObjectLiterals_ES5.ts(39,17): error TS2659: 'super' is only allowed in members of object literal expressions when option 'target' is 'ES2015' or higher. +tests/cases/compiler/superInObjectLiterals_ES5.ts(42,17): error TS2659: 'super' is only allowed in members of object literal expressions when option 'target' is 'ES2015' or higher. +tests/cases/compiler/superInObjectLiterals_ES5.ts(46,17): error TS2659: 'super' is only allowed in members of object literal expressions when option 'target' is 'ES2015' or higher. tests/cases/compiler/superInObjectLiterals_ES5.ts(49,17): error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. tests/cases/compiler/superInObjectLiterals_ES5.ts(52,17): error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. @@ -20,18 +20,18 @@ tests/cases/compiler/superInObjectLiterals_ES5.ts(52,17): error TS2660: 'super' method() { super.method(); ~~~~~ -!!! error TS2659: 'super' in members of object literal expressions is only allowed when option 'target' is 'ES2015' or higher. +!!! error TS2659: 'super' is only allowed in members of object literal expressions when option 'target' is 'ES2015' or higher. }, get prop() { super.method(); ~~~~~ -!!! error TS2659: 'super' in members of object literal expressions is only allowed when option 'target' is 'ES2015' or higher. +!!! error TS2659: 'super' is only allowed in members of object literal expressions when option 'target' is 'ES2015' or higher. return 10; }, set prop(value) { super.method(); ~~~~~ -!!! error TS2659: 'super' in members of object literal expressions is only allowed when option 'target' is 'ES2015' or higher. +!!! error TS2659: 'super' is only allowed in members of object literal expressions when option 'target' is 'ES2015' or higher. }, p1: function () { super.method(); @@ -64,18 +64,18 @@ tests/cases/compiler/superInObjectLiterals_ES5.ts(52,17): error TS2660: 'super' method() { super.method(); ~~~~~ -!!! error TS2659: 'super' in members of object literal expressions is only allowed when option 'target' is 'ES2015' or higher. +!!! error TS2659: 'super' is only allowed in members of object literal expressions when option 'target' is 'ES2015' or higher. }, get prop() { super.method(); ~~~~~ -!!! error TS2659: 'super' in members of object literal expressions is only allowed when option 'target' is 'ES2015' or higher. +!!! error TS2659: 'super' is only allowed in members of object literal expressions when option 'target' is 'ES2015' or higher. return 10; }, set prop(value) { super.method(); ~~~~~ -!!! error TS2659: 'super' in members of object literal expressions is only allowed when option 'target' is 'ES2015' or higher. +!!! error TS2659: 'super' is only allowed in members of object literal expressions when option 'target' is 'ES2015' or higher. }, p1: function () { super.method(); diff --git a/tests/baselines/reference/super_inside-object-literal-getters-and-setters.errors.txt b/tests/baselines/reference/super_inside-object-literal-getters-and-setters.errors.txt index 16a66bf6fa4..5fe7fa59ff6 100644 --- a/tests/baselines/reference/super_inside-object-literal-getters-and-setters.errors.txt +++ b/tests/baselines/reference/super_inside-object-literal-getters-and-setters.errors.txt @@ -1,10 +1,10 @@ tests/cases/compiler/super_inside-object-literal-getters-and-setters.ts(4,13): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. -tests/cases/compiler/super_inside-object-literal-getters-and-setters.ts(5,20): error TS2659: 'super' in members of object literal expressions is only allowed when option 'target' is 'ES2015' or higher. +tests/cases/compiler/super_inside-object-literal-getters-and-setters.ts(5,20): error TS2659: 'super' is only allowed in members of object literal expressions when option 'target' is 'ES2015' or higher. tests/cases/compiler/super_inside-object-literal-getters-and-setters.ts(7,13): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. -tests/cases/compiler/super_inside-object-literal-getters-and-setters.ts(8,13): error TS2659: 'super' in members of object literal expressions is only allowed when option 'target' is 'ES2015' or higher. +tests/cases/compiler/super_inside-object-literal-getters-and-setters.ts(8,13): error TS2659: 'super' is only allowed in members of object literal expressions when option 'target' is 'ES2015' or higher. tests/cases/compiler/super_inside-object-literal-getters-and-setters.ts(11,20): error TS2660: 'super' can only be referenced in members of derived classes or object literal expressions. tests/cases/compiler/super_inside-object-literal-getters-and-setters.ts(20,17): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. -tests/cases/compiler/super_inside-object-literal-getters-and-setters.ts(21,24): error TS2659: 'super' in members of object literal expressions is only allowed when option 'target' is 'ES2015' or higher. +tests/cases/compiler/super_inside-object-literal-getters-and-setters.ts(21,24): error TS2659: 'super' is only allowed in members of object literal expressions when option 'target' is 'ES2015' or higher. ==== tests/cases/compiler/super_inside-object-literal-getters-and-setters.ts (7 errors) ==== @@ -16,14 +16,14 @@ tests/cases/compiler/super_inside-object-literal-getters-and-setters.ts(21,24): !!! error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. return super._foo; ~~~~~ -!!! error TS2659: 'super' in members of object literal expressions is only allowed when option 'target' is 'ES2015' or higher. +!!! error TS2659: 'super' is only allowed in members of object literal expressions when option 'target' is 'ES2015' or higher. }, set foo(value: string) { ~~~ !!! error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. super._foo = value; ~~~~~ -!!! error TS2659: 'super' in members of object literal expressions is only allowed when option 'target' is 'ES2015' or higher. +!!! error TS2659: 'super' is only allowed in members of object literal expressions when option 'target' is 'ES2015' or higher. }, test: function () { return super._foo; @@ -42,7 +42,7 @@ tests/cases/compiler/super_inside-object-literal-getters-and-setters.ts(21,24): !!! error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. return super.test(); ~~~~~ -!!! error TS2659: 'super' in members of object literal expressions is only allowed when option 'target' is 'ES2015' or higher. +!!! error TS2659: 'super' is only allowed in members of object literal expressions when option 'target' is 'ES2015' or higher. } }; } diff --git a/tests/cases/fourslash/getOccurrencesSuper3.ts b/tests/cases/fourslash/getOccurrencesSuper3.ts new file mode 100644 index 00000000000..bceac02a392 --- /dev/null +++ b/tests/cases/fourslash/getOccurrencesSuper3.ts @@ -0,0 +1,34 @@ +/// + +////let x = { +//// a() { +//// return [|s/**/uper|].b(); +//// }, +//// b() { +//// return [|super|].a(); +//// }, +//// c: function () { +//// return [|super|].a(); +//// } +//// d: () => [|super|].b(); +////} + +function checkRange(r: FourSlashInterface.Range, expectedOccurences: FourSlashInterface.Range[]): void { + goTo.position(r.start); + if (expectedOccurences.length) { + for (const expected of expectedOccurences) { + verify.occurrencesAtPositionContains(expected); + } + } + else { + verify.occurrencesAtPositionCount(0); + } +} + +let [r0, r1, r2, r3] = test.ranges(); + +checkRange(r0, [r0, r1]); +checkRange(r1, [r0, r1]); +checkRange(r0, [r0, r1]); +checkRange(r2, []); +checkRange(r3, []); \ No newline at end of file From ddbf1030ff5a0b4c0a1c568959c1297663ce9af0 Mon Sep 17 00:00:00 2001 From: Yui T Date: Wed, 16 Dec 2015 16:06:55 -0800 Subject: [PATCH 50/79] Fix fourslash range annotation --- .../fourslash/findAllRefsParameterPropertyDeclaration1.ts | 6 +++--- .../fourslash/findAllRefsParameterPropertyDeclaration2.ts | 6 +++--- .../fourslash/findAllRefsParameterPropertyDeclaration3.ts | 6 +++--- .../cases/fourslash/renameParameterPropertyDeclaration1.ts | 6 +++--- .../cases/fourslash/renameParameterPropertyDeclaration2.ts | 6 +++--- .../cases/fourslash/renameParameterPropertyDeclaration3.ts | 6 +++--- .../cases/fourslash/renameParameterPropertyDeclaration4.ts | 4 ++-- .../cases/fourslash/renameParameterPropertyDeclaration5.ts | 4 ++-- 8 files changed, 22 insertions(+), 22 deletions(-) diff --git a/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration1.ts b/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration1.ts index d0854262828..5034a57ae1d 100644 --- a/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration1.ts +++ b/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration1.ts @@ -1,9 +1,9 @@ /// //// class Foo { -//// constructor(private |privateParam|: number) { -//// let localPrivate = |privateParam|; -//// this.|privateParam| += 10; +//// constructor(private [|privateParam|]: number) { +//// let localPrivate = [|privateParam|]; +//// this.[|privateParam|] += 10; //// } //// } diff --git a/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration2.ts b/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration2.ts index 7e59567364a..7db5ba13585 100644 --- a/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration2.ts +++ b/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration2.ts @@ -1,9 +1,9 @@ /// //// class Foo { -//// constructor(public |publicParam|: number) { -//// let localPublic = |publicParam|; -//// this.|publicParam| += 10; +//// constructor(public [|publicParam|]: number) { +//// let localPublic = [|publicParam|]; +//// this.[|publicParam|] += 10; //// } //// } diff --git a/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration3.ts b/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration3.ts index 2d78e9793f7..c2d8a06f658 100644 --- a/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration3.ts +++ b/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration3.ts @@ -1,9 +1,9 @@ /// //// class Foo { -//// constructor(protected |protectedParam|: number) { -//// let localProtected = |protectedParam|; -//// this.|protectedParam| += 10; +//// constructor(protected [|protectedParam|]: number) { +//// let localProtected = [|protectedParam|]; +//// this.[|protectedParam|] += 10; //// } //// } diff --git a/tests/cases/fourslash/renameParameterPropertyDeclaration1.ts b/tests/cases/fourslash/renameParameterPropertyDeclaration1.ts index 1faed546d91..4ca09b71e4b 100644 --- a/tests/cases/fourslash/renameParameterPropertyDeclaration1.ts +++ b/tests/cases/fourslash/renameParameterPropertyDeclaration1.ts @@ -1,9 +1,9 @@ /// //// class Foo { -//// constructor(private |privateParam|: number) { -//// let localPrivate = |privateParam|; -//// this.|privateParam| += 10; +//// constructor(private [|privateParam|]: number) { +//// let localPrivate = [|privateParam|]; +//// this.[|privateParam|] += 10; //// } //// } diff --git a/tests/cases/fourslash/renameParameterPropertyDeclaration2.ts b/tests/cases/fourslash/renameParameterPropertyDeclaration2.ts index e8eec5d3a0a..695e3729f94 100644 --- a/tests/cases/fourslash/renameParameterPropertyDeclaration2.ts +++ b/tests/cases/fourslash/renameParameterPropertyDeclaration2.ts @@ -1,9 +1,9 @@ /// //// class Foo { -//// constructor(public |publicParam|: number) { -//// let publicParam = |publicParam|; -//// this.|publicParam| += 10; +//// constructor(public [|publicParam|]: number) { +//// let publicParam = [|publicParam|]; +//// this.[|publicParam|] += 10; //// } //// } diff --git a/tests/cases/fourslash/renameParameterPropertyDeclaration3.ts b/tests/cases/fourslash/renameParameterPropertyDeclaration3.ts index 44f4cf68858..23971f0be27 100644 --- a/tests/cases/fourslash/renameParameterPropertyDeclaration3.ts +++ b/tests/cases/fourslash/renameParameterPropertyDeclaration3.ts @@ -1,9 +1,9 @@ /// //// class Foo { -//// constructor(protected |protectedParam|: number) { -//// let protectedParam = |protectedParam|; -//// this.|protectedParam| += 10; +//// constructor(protected [|protectedParam|]: number) { +//// let protectedParam = [|protectedParam|]; +//// this.[|protectedParam|] += 10; //// } //// } diff --git a/tests/cases/fourslash/renameParameterPropertyDeclaration4.ts b/tests/cases/fourslash/renameParameterPropertyDeclaration4.ts index 21ba7da4141..4646de6123c 100644 --- a/tests/cases/fourslash/renameParameterPropertyDeclaration4.ts +++ b/tests/cases/fourslash/renameParameterPropertyDeclaration4.ts @@ -1,8 +1,8 @@ /// //// class Foo { -//// constructor(protected { |protectedParam| }) { -//// let myProtectedParam = |protectedParam|; +//// constructor(protected { [|protectedParam|] }) { +//// let myProtectedParam = [|protectedParam|]; //// } //// } diff --git a/tests/cases/fourslash/renameParameterPropertyDeclaration5.ts b/tests/cases/fourslash/renameParameterPropertyDeclaration5.ts index a4bc00b697b..6d73c7af072 100644 --- a/tests/cases/fourslash/renameParameterPropertyDeclaration5.ts +++ b/tests/cases/fourslash/renameParameterPropertyDeclaration5.ts @@ -1,8 +1,8 @@ /// //// class Foo { -//// constructor(protected [ |protectedParam| ]) { -//// let myProtectedParam = |protectedParam|; +//// constructor(protected [ [|protectedParam|] ]) { +//// let myProtectedParam = [|protectedParam|]; //// } //// } From 479f7af4df24491ce766f1471c30bd19dab8d86e Mon Sep 17 00:00:00 2001 From: Yui T Date: Wed, 16 Dec 2015 16:24:18 -0800 Subject: [PATCH 51/79] Add debug fail when getting parameter-property declaration --- src/compiler/checker.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9d14bb39206..b6f03cd77d1 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -442,7 +442,11 @@ namespace ts { const parameterSymbol = getSymbol(constructoDeclaration.locals, parameterName, SymbolFlags.Value); const propertySymbol = getSymbol(classDeclaration.symbol.members, parameterName, SymbolFlags.Value); - return parameterSymbol && propertySymbol ? [parameterSymbol, propertySymbol] : undefined; + if (parameterSymbol && propertySymbol) { + return [parameterSymbol, propertySymbol]; + } + + Debug.fail("There should exist two symbols, one as property declaration and one as parameter declaration"); } function isBlockScopedNameDeclaredBeforeUse(declaration: Declaration, usage: Node): boolean { From 3558d7d423c6d7837c5a0e7a304ec7edcf100eb0 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 17 Dec 2015 11:34:54 -0800 Subject: [PATCH 52/79] Added README.md to 'doc' folder. --- doc/README.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 doc/README.md diff --git a/doc/README.md b/doc/README.md new file mode 100644 index 00000000000..164fb69ee20 --- /dev/null +++ b/doc/README.md @@ -0,0 +1,7 @@ +This directory contains miscellaneous documentation such as the TypeScript language specification and logo. +If you are looking for more introductory material, you might want to take a look at the [TypeScript Handbook](https://github.com/Microsoft/TypeScript-Handbook). + +# Spec Contributions + +The specification is first authored as a Microsoft Word (docx) file and then generated into Markdown and PDF formats. +Due to the binary format of docx files, and the merging difficulties that may come with it, it is preferred that any suggestions or problems found in the spec should be [filed as issues](https://github.com/Microsoft/TypeScript/issues/new) rather than sent as pull requests. \ No newline at end of file From cf621399a49745d693b6874eab9b792d1055d6ab Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 17 Dec 2015 14:32:02 -0800 Subject: [PATCH 53/79] Add 'no-unused-variable' to 'tslint.json'. --- tslint.json | 1 + 1 file changed, 1 insertion(+) diff --git a/tslint.json b/tslint.json index 9b010d9a896..71efb21ad7b 100644 --- a/tslint.json +++ b/tslint.json @@ -38,6 +38,7 @@ "no-trailing-whitespace": true, "no-inferrable-types": true, "no-null": true, + "no-unused-variable": true, "boolean-trivia": true, "type-operator-spacing": true, "prefer-const": true, From 0a470add811a0c8edcb69fe977daad6451c9836b Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 17 Dec 2015 14:33:55 -0800 Subject: [PATCH 54/79] Removed unused declarations from 'sys.ts'. --- src/compiler/sys.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts index 836b2daeab2..c99c28bc0dd 100644 --- a/src/compiler/sys.ts +++ b/src/compiler/sys.ts @@ -218,7 +218,6 @@ namespace ts { const _fs = require("fs"); const _path = require("path"); const _os = require("os"); - const _tty = require("tty"); // average async stat takes about 30 microseconds // set chunk size to do 30 files in < 1 millisecond @@ -313,10 +312,6 @@ namespace ts { // time dynamically to match the large reference set? const watchedFileSet = createWatchedFileSet(); - function isNode4OrLater(): Boolean { - return parseInt(process.version.charAt(1)) >= 4; - } - const platform: string = _os.platform(); // win32\win64 are case insensitive platforms, MacOS (darwin) by default is also case insensitive const useCaseSensitiveFileNames = platform !== "win32" && platform !== "win64" && platform !== "darwin"; From 0843c82543da7552de929c5ef576ae6989f1d6fe Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 17 Dec 2015 14:37:54 -0800 Subject: [PATCH 55/79] Removed unused declarations from 'core.ts'. --- src/compiler/core.ts | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index cae7bd82103..ad434d4cfad 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -794,23 +794,6 @@ namespace ts { return path; } - const backslashOrDoubleQuote = /[\"\\]/g; - const escapedCharsRegExp = /[\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g; - const escapedCharsMap: Map = { - "\0": "\\0", - "\t": "\\t", - "\v": "\\v", - "\f": "\\f", - "\b": "\\b", - "\r": "\\r", - "\n": "\\n", - "\\": "\\\\", - "\"": "\\\"", - "\u2028": "\\u2028", // lineSeparator - "\u2029": "\\u2029", // paragraphSeparator - "\u0085": "\\u0085" // nextLine - }; - export interface ObjectAllocator { getNodeConstructor(): new (kind: SyntaxKind, pos?: number, end?: number) => Node; getSourceFileConstructor(): new (kind: SyntaxKind, pos?: number, end?: number) => SourceFile; From 80c7f3a529baffdfb2eee060a497a879a711d6bd Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 17 Dec 2015 14:39:15 -0800 Subject: [PATCH 56/79] Removed unused declarations from 'declarationEmitter.ts'. --- src/compiler/declarationEmitter.ts | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 3348b51dff7..d0c5cbff48b 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -1534,14 +1534,6 @@ namespace ts { } function emitBindingElement(bindingElement: BindingElement) { - function getBindingElementTypeVisibilityError(symbolAccesibilityResult: SymbolAccessiblityResult): SymbolAccessibilityDiagnostic { - const diagnosticMessage = getParameterDeclarationTypeVisibilityDiagnosticMessage(symbolAccesibilityResult); - return diagnosticMessage !== undefined ? { - diagnosticMessage, - errorNode: bindingElement, - typeName: bindingElement.name - } : undefined; - } if (bindingElement.kind === SyntaxKind.OmittedExpression) { // If bindingElement is an omittedExpression (i.e. containing elision), From b1ccf69d34c9fa20f96321793400048ffdde1fc1 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 17 Dec 2015 14:50:27 -0800 Subject: [PATCH 57/79] Removed unused declarations in 'checker.ts'. --- src/compiler/checker.ts | 180 ++++------------------------------------ 1 file changed, 16 insertions(+), 164 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1fdac127c50..96852d25efb 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -819,15 +819,6 @@ namespace ts { return resolveESModuleSymbol(resolveExternalModuleName(node, moduleSpecifier), moduleSpecifier); } - function getMemberOfModuleVariable(moduleSymbol: Symbol, name: string): Symbol { - if (moduleSymbol.flags & SymbolFlags.Variable) { - const typeAnnotation = (moduleSymbol.valueDeclaration).type; - if (typeAnnotation) { - return getPropertyOfType(getTypeFromTypeNode(typeAnnotation), name); - } - } - } - // This function creates a synthetic symbol that combines the value side of one symbol with the // type/namespace side of another symbol. Consider this example: // @@ -1063,7 +1054,6 @@ namespace ts { } const moduleReferenceLiteral = moduleReferenceExpression; - const searchPath = getDirectoryPath(getSourceFile(location).fileName); // Module names are escaped in our symbol table. However, string literal values aren't. // Escape the name in the "require(...)" clause to ensure we find the right symbol. @@ -2183,65 +2173,15 @@ namespace ts { } function isDeclarationVisible(node: Declaration): boolean { - function getContainingExternalModule(node: Node) { - for (; node; node = node.parent) { - if (node.kind === SyntaxKind.ModuleDeclaration) { - if ((node).name.kind === SyntaxKind.StringLiteral) { - return node; - } - } - else if (node.kind === SyntaxKind.SourceFile) { - return isExternalOrCommonJsModule(node) ? node : undefined; - } + if (node) { + const links = getNodeLinks(node); + if (links.isVisible === undefined) { + links.isVisible = !!determineIfDeclarationIsVisible(); } - Debug.fail("getContainingModule cant reach here"); + return links.isVisible; } - function isUsedInExportAssignment(node: Node) { - // Get source File and see if it is external module and has export assigned symbol - const externalModule = getContainingExternalModule(node); - let exportAssignmentSymbol: Symbol; - let resolvedExportSymbol: Symbol; - if (externalModule) { - // This is export assigned symbol node - const externalModuleSymbol = getSymbolOfNode(externalModule); - exportAssignmentSymbol = getExportAssignmentSymbol(externalModuleSymbol); - const symbolOfNode = getSymbolOfNode(node); - if (isSymbolUsedInExportAssignment(symbolOfNode)) { - return true; - } - - // if symbolOfNode is alias declaration, resolve the symbol declaration and check - if (symbolOfNode.flags & SymbolFlags.Alias) { - return isSymbolUsedInExportAssignment(resolveAlias(symbolOfNode)); - } - } - - // Check if the symbol is used in export assignment - function isSymbolUsedInExportAssignment(symbol: Symbol) { - if (exportAssignmentSymbol === symbol) { - return true; - } - - if (exportAssignmentSymbol && !!(exportAssignmentSymbol.flags & SymbolFlags.Alias)) { - // if export assigned symbol is alias declaration, resolve the alias - resolvedExportSymbol = resolvedExportSymbol || resolveAlias(exportAssignmentSymbol); - if (resolvedExportSymbol === symbol) { - return true; - } - - // Container of resolvedExportSymbol is visible - return forEach(resolvedExportSymbol.declarations, (current: Node) => { - while (current) { - if (current === node) { - return true; - } - current = current.parent; - } - }); - } - } - } + return false; function determineIfDeclarationIsVisible() { switch (node.kind) { @@ -2320,14 +2260,6 @@ namespace ts { Debug.fail("isDeclarationVisible unknown: SyntaxKind: " + node.kind); } } - - if (node) { - const links = getNodeLinks(node); - if (links.isVisible === undefined) { - links.isVisible = !!determineIfDeclarationIsVisible(); - } - return links.isVisible; - } } function collectLinkedAliases(node: Identifier): Node[] { @@ -3373,14 +3305,6 @@ namespace ts { } } - function addInheritedSignatures(signatures: Signature[], baseSignatures: Signature[]) { - if (baseSignatures) { - for (const signature of baseSignatures) { - signatures.push(signature); - } - } - } - function resolveDeclaredMembers(type: InterfaceType): InterfaceTypeWithDeclaredMembers { if (!(type).declaredProperties) { const symbol = type.symbol; @@ -3861,25 +3785,6 @@ namespace ts { function getSignaturesOfType(type: Type, kind: SignatureKind): Signature[] { return getSignaturesOfStructuredType(getApparentType(type), kind); } - - function typeHasConstructSignatures(type: Type): boolean { - const apparentType = getApparentType(type); - if (apparentType.flags & (TypeFlags.ObjectType | TypeFlags.Union)) { - const resolved = resolveStructuredTypeMembers(type); - return resolved.constructSignatures.length > 0; - } - return false; - } - - function typeHasCallOrConstructSignatures(type: Type): boolean { - const apparentType = getApparentType(type); - if (apparentType.flags & TypeFlags.StructuredType) { - const resolved = resolveStructuredTypeMembers(type); - return resolved.callSignatures.length > 0 || resolved.constructSignatures.length > 0; - } - return false; - } - function getIndexTypeOfStructuredType(type: Type, kind: IndexKind): Type { if (type.flags & TypeFlags.StructuredType) { const resolved = resolveStructuredTypeMembers(type); @@ -4381,10 +4286,6 @@ namespace ts { return getTypeOfGlobalSymbol(getGlobalTypeSymbol(name), arity); } - function tryGetGlobalType(name: string, arity = 0): ObjectType { - return getTypeOfGlobalSymbol(getGlobalSymbol(name, SymbolFlags.Type, /*diagnostic*/ undefined), arity); - } - /** * Returns a type that is inside a namespace at the global scope, e.g. * getExportedTypeFromNamespace('JSX', 'Element') returns the JSX.Element type @@ -6148,12 +6049,8 @@ namespace ts { } function createInferenceContext(typeParameters: TypeParameter[], inferUnionTypes: boolean): InferenceContext { - const inferences: TypeInferences[] = []; - for (const unused of typeParameters) { - inferences.push({ - primary: undefined, secondary: undefined, isFixed: false - }); - } + const inferences = map(typeParameters, createTypeInferencesObject); + return { typeParameters, inferUnionTypes, @@ -6162,6 +6059,14 @@ namespace ts { }; } + function createTypeInferencesObject(): TypeInferences { + return { + primary: undefined, + secondary: undefined, + isFixed: false, + }; + } + function inferTypes(context: InferenceContext, source: Type, target: Type) { let sourceStack: Type[]; let targetStack: Type[]; @@ -6432,10 +6337,6 @@ namespace ts { return context.inferredTypes; } - function hasAncestor(node: Node, kind: SyntaxKind): boolean { - return getAncestor(node, kind) !== undefined; - } - // EXPRESSION TYPE CHECKING function getResolvedSymbol(node: Identifier): Symbol { @@ -8035,7 +7936,6 @@ namespace ts { /// type or factory function. /// Otherwise, returns unknownSymbol. function getJsxElementTagSymbol(node: JsxOpeningLikeElement | JsxClosingElement): Symbol { - const flags: JsxFlags = JsxFlags.UnknownElement; const links = getNodeLinks(node); if (!links.resolvedSymbol) { if (isJsxIntrinsicIdentifier(node.tagName)) { @@ -14308,16 +14208,6 @@ namespace ts { } } - function getModuleStatements(node: Declaration): Statement[] { - if (node.kind === SyntaxKind.SourceFile) { - return (node).statements; - } - if (node.kind === SyntaxKind.ModuleDeclaration && (node).body.kind === SyntaxKind.ModuleBlock) { - return ((node).body).statements; - } - return emptyArray; - } - function hasExportedMembers(moduleSymbol: Symbol) { for (var id in moduleSymbol.exports) { if (id !== "export=") { @@ -15396,20 +15286,6 @@ namespace ts { return symbol && getExportSymbolOfValueSymbolIfExported(symbol).valueDeclaration; } - function instantiateSingleCallFunctionType(functionType: Type, typeArguments: Type[]): Type { - if (functionType === unknownType) { - return unknownType; - } - - const signature = getSingleCallSignature(functionType); - if (!signature) { - return unknownType; - } - - const instantiatedSignature = getSignatureInstantiation(signature, typeArguments); - return getOrCreateTypeFromSignature(instantiatedSignature); - } - function createResolver(): EmitResolver { return { getReferencedExportContainer, @@ -16458,25 +16334,6 @@ namespace ts { } } - function isIntegerLiteral(expression: Expression): boolean { - if (expression.kind === SyntaxKind.PrefixUnaryExpression) { - const unaryExpression = expression; - if (unaryExpression.operator === SyntaxKind.PlusToken || unaryExpression.operator === SyntaxKind.MinusToken) { - expression = unaryExpression.operand; - } - } - if (expression.kind === SyntaxKind.NumericLiteral) { - // Allows for scientific notation since literalExpression.text was formed by - // coercing a number to a string. Sometimes this coercion can yield a string - // in scientific notation. - // We also don't need special logic for hex because a hex integer is converted - // to decimal when it is coerced. - return /^[0-9]+([eE]\+?[0-9]+)?$/.test((expression).text); - } - - return false; - } - function hasParseDiagnostics(sourceFile: SourceFile): boolean { return sourceFile.parseDiagnostics.length > 0; } @@ -16505,11 +16362,6 @@ namespace ts { } } - function isEvalOrArgumentsIdentifier(node: Node): boolean { - return node.kind === SyntaxKind.Identifier && - ((node).text === "eval" || (node).text === "arguments"); - } - function checkGrammarConstructorTypeParameters(node: ConstructorDeclaration) { if (node.typeParameters) { return grammarErrorAtPos(getSourceFileOfNode(node), node.typeParameters.pos, node.typeParameters.end - node.typeParameters.pos, Diagnostics.Type_parameters_cannot_appear_on_a_constructor_declaration); From d7c5e18cb3439c3d5a07b721239615536429f1f5 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 17 Dec 2015 14:53:46 -0800 Subject: [PATCH 58/79] Removed unused declarations in 'parser.ts'. --- src/compiler/parser.ts | 34 ---------------------------------- 1 file changed, 34 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 62d98337102..7f5d052a7e7 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -771,10 +771,6 @@ namespace ts { return doInsideOfContext(ParserContextFlags.Yield, func); } - function doOutsideOfYieldContext(func: () => T): T { - return doOutsideOfContext(ParserContextFlags.Yield, func); - } - function doInDecoratorContext(func: () => T): T { return doInsideOfContext(ParserContextFlags.Decorator, func); } @@ -791,10 +787,6 @@ namespace ts { return doInsideOfContext(ParserContextFlags.Yield | ParserContextFlags.Await, func); } - function doOutsideOfYieldAndAwaitContext(func: () => T): T { - return doOutsideOfContext(ParserContextFlags.Yield | ParserContextFlags.Await, func); - } - function inContext(flags: ParserContextFlags) { return (contextFlags & flags) !== 0; } @@ -851,10 +843,6 @@ namespace ts { return token = scanner.scan(); } - function getTokenPos(pos: number): number { - return skipTrivia(sourceText, pos); - } - function reScanGreaterToken(): SyntaxKind { return token = scanner.reScanGreaterToken(); } @@ -2644,10 +2632,6 @@ namespace ts { isStartOfExpression(); } - function allowInAndParseExpression(): Expression { - return allowInAnd(parseExpression); - } - function parseExpression(): Expression { // Expression[in]: // AssignmentExpression[in] @@ -3962,7 +3946,6 @@ namespace ts { const asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken); const tokenIsIdentifier = isIdentifier(); - const nameToken = token; const propertyName = parsePropertyName(); // Disallowing of optional property assignments happens in the grammar checker. @@ -5104,10 +5087,6 @@ namespace ts { return undefined; } - function parseHeritageClausesWorker() { - return parseList(ParsingContext.HeritageClauses, parseHeritageClause); - } - function parseHeritageClause() { if (token === SyntaxKind.ExtendsKeyword || token === SyntaxKind.ImplementsKeyword) { const node = createNode(SyntaxKind.HeritageClause); @@ -5253,12 +5232,6 @@ namespace ts { return nextToken() === SyntaxKind.SlashToken; } - function nextTokenIsCommaOrFromKeyword() { - nextToken(); - return token === SyntaxKind.CommaToken || - token === SyntaxKind.FromKeyword; - } - function parseImportDeclarationOrImportEqualsDeclaration(fullStart: number, decorators: NodeArray, modifiers: ModifiersArray): ImportEqualsDeclaration | ImportDeclaration { parseExpected(SyntaxKind.ImportKeyword); const afterImportPos = scanner.getStartPos(); @@ -5751,13 +5724,6 @@ namespace ts { return finishNode(parameter); } - function parseJSDocOptionalType(type: JSDocType): JSDocOptionalType { - const result = createNode(SyntaxKind.JSDocOptionalType, type.pos); - nextToken(); - result.type = type; - return finishNode(result); - } - function parseJSDocTypeReference(): JSDocTypeReference { const result = createNode(SyntaxKind.JSDocTypeReference); result.name = parseSimplePropertyName(); From 11acb7bf16b123841dc256002c9bbb6848f1139c Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 17 Dec 2015 14:54:19 -0800 Subject: [PATCH 59/79] Removed unused declarations in 'sourcemap.ts'. --- src/compiler/sourcemap.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/compiler/sourcemap.ts b/src/compiler/sourcemap.ts index d98dc233c16..50644201544 100644 --- a/src/compiler/sourcemap.ts +++ b/src/compiler/sourcemap.ts @@ -14,7 +14,6 @@ namespace ts { reset(): void; } - const nop = <(...args: any[]) => any>Function.prototype; let nullSourceMapWriter: SourceMapWriter; export function getNullSourceMapWriter(): SourceMapWriter { From 66cf6be6d84cb79d4433723d71d73dca72542e92 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 17 Dec 2015 14:55:08 -0800 Subject: [PATCH 60/79] Removed unused declarations in 'emitter.ts'. --- src/compiler/emitter.ts | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index f0b49854734..622ec14caa8 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -779,12 +779,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi } } - function emitTrailingCommaIfPresent(nodeList: NodeArray): void { - if (nodeList.hasTrailingComma) { - write(","); - } - } - function emitLinePreservingList(parent: Node, nodes: NodeArray, allowTrailingComma: boolean, spacesBetweenBraces: boolean) { Debug.assert(nodes.length > 0); @@ -3248,10 +3242,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi } } - function emitDownLevelForOfStatement(node: ForOfStatement) { - emitLoop(node, emitDownLevelForOfStatementWorker); - } - function emitDownLevelForOfStatementWorker(node: ForOfStatement, loop: ConvertedLoop) { // The following ES6 code: // From 9e801c21ae368658ca5df9bcfcf2db890badb294 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 17 Dec 2015 15:01:05 -0800 Subject: [PATCH 61/79] Removed unused declarations in 'harness.ts'. --- src/harness/harness.ts | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 15f3813e54d..117be8a9afb 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -31,7 +31,6 @@ // this will work in the browser via browserify var _chai: typeof chai = require("chai"); var assert: typeof _chai.assert = _chai.assert; -var expect: typeof _chai.expect = _chai.expect; declare var __dirname: string; // Node-specific var global = Function("return this").call(null); /* tslint:enable:no-var-keyword */ @@ -513,7 +512,6 @@ namespace Harness { } const folder: any = fso.GetFolder(path); - const paths: string[] = []; return filesInFolder(folder, path); }; @@ -627,18 +625,6 @@ namespace Harness { } /// Ask the server to use node's path.resolve to resolve the given path - function getResolvedPathFromServer(path: string) { - const xhr = new XMLHttpRequest(); - try { - xhr.open("GET", path + "?resolve", /*async*/ false); - xhr.send(); - } - catch (e) { - return { status: 404, responseText: null }; - } - - return waitForXHR(xhr); - } export interface XHRResponse { status: number; From 3dee60f6ef219860202622d8560d9a883c12e4b3 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 17 Dec 2015 15:01:48 -0800 Subject: [PATCH 62/79] Removed unused declarations in 'harnessLanguageService.ts'. --- src/harness/harnessLanguageService.ts | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index 3c7814df562..fb5b6ce92aa 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -315,13 +315,6 @@ namespace Harness.LanguageService { class LanguageServiceShimProxy implements ts.LanguageService { constructor(private shim: ts.LanguageServiceShim) { } - private unwrappJSONCallResult(result: string): any { - const parsedResult = JSON.parse(result); - if (parsedResult.error) { - throw new Error("Language Service Shim Error: " + JSON.stringify(parsedResult.error)); - } - return parsedResult.result; - } cleanupSemanticCache(): void { this.shim.cleanupSemanticCache(); } From 4a07ee730adc0ca75242325e84ef0513985fbec4 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 17 Dec 2015 15:02:20 -0800 Subject: [PATCH 63/79] Removed unused declarations in 'compilerRunner.ts'. --- src/harness/compilerRunner.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/harness/compilerRunner.ts b/src/harness/compilerRunner.ts index 8ee287b2637..d1566c05d4e 100644 --- a/src/harness/compilerRunner.ts +++ b/src/harness/compilerRunner.ts @@ -251,7 +251,6 @@ class CompilerBaselineRunner extends RunnerBase { const allFiles = toBeCompiled.concat(otherFiles).filter(file => !!program.getSourceFile(file.unitName)); const fullWalker = new TypeWriterWalker(program, /*fullTypeCheck*/ true); - const pullWalker = new TypeWriterWalker(program, /*fullTypeCheck*/ false); const fullResults: ts.Map = {}; const pullResults: ts.Map = {}; From 125f0a1a232c4ffa879590775e62346cd47b59aa Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 17 Dec 2015 15:03:38 -0800 Subject: [PATCH 64/79] Removed unused declarations in 'loggedIO.ts'. --- src/harness/loggedIO.ts | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/src/harness/loggedIO.ts b/src/harness/loggedIO.ts index 0bae91f7976..3d51682f745 100644 --- a/src/harness/loggedIO.ts +++ b/src/harness/loggedIO.ts @@ -305,25 +305,6 @@ namespace Playback { } } - const pathEquivCache: any = {}; - function pathsAreEquivalent(left: string, right: string, wrapper: { resolvePath(s: string): string }) { - const key = left + "-~~-" + right; - function areSame(a: string, b: string) { - return ts.normalizeSlashes(a).toLowerCase() === ts.normalizeSlashes(b).toLowerCase(); - } - function check() { - if (Harness.Path.getFileName(left).toLowerCase() === Harness.Path.getFileName(right).toLowerCase()) { - return areSame(left, right) || areSame(wrapper.resolvePath(left), right) || areSame(left, wrapper.resolvePath(right)) || areSame(wrapper.resolvePath(left), wrapper.resolvePath(right)); - } - } - if (pathEquivCache.hasOwnProperty(key)) { - return pathEquivCache[key]; - } - else { - return pathEquivCache[key] = check(); - } - } - function noOpReplay(name: string) { // console.log("Swallowed write operation during replay: " + name); } From 7fd6aa4318db062346ebea005364efca0b868498 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 17 Dec 2015 15:07:37 -0800 Subject: [PATCH 65/79] Removed unused declarations in 'editorServices.ts'. --- src/server/editorServices.ts | 36 ++++++------------------------------ 1 file changed, 6 insertions(+), 30 deletions(-) diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 0305b7595c2..d023a9827ee 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -263,13 +263,11 @@ namespace ts.server { } resolvePath(path: string): string { - const start = new Date().getTime(); const result = this.host.resolvePath(path); return result; } fileExists(path: string): boolean { - const start = new Date().getTime(); const result = this.host.fileExists(path); return result; } @@ -325,32 +323,6 @@ namespace ts.server { } } - // assumes normalized paths - function getAbsolutePath(filename: string, directory: string) { - const rootLength = ts.getRootLength(filename); - if (rootLength > 0) { - return filename; - } - else { - const splitFilename = filename.split("/"); - const splitDir = directory.split("/"); - let i = 0; - let dirTail = 0; - const sflen = splitFilename.length; - while ((i < sflen) && (splitFilename[i].charAt(0) == ".")) { - const dots = splitFilename[i]; - if (dots == "..") { - dirTail++; - } - else if (dots != ".") { - return undefined; - } - i++; - } - return splitDir.slice(0, splitDir.length - dirTail).concat(splitFilename.slice(i)).join("/"); - } - } - export interface ProjectOptions { // these fields can be present in the project file files?: string[]; @@ -583,7 +555,9 @@ namespace ts.server { } handleProjectFilelistChanges(project: Project) { - const { succeeded, projectOptions, error } = this.configFileToProjectOptions(project.projectFilename); + // TODO: Ignoring potentially returned 'error' and 'succeeded' condition + const { projectOptions } = this.configFileToProjectOptions(project.projectFilename); + const newRootFiles = projectOptions.files.map((f => this.getCanonicalFileName(f))); const currentRootFiles = project.getRootFiles().map((f => this.getCanonicalFileName(f))); @@ -611,7 +585,9 @@ namespace ts.server { this.log("Detected newly added tsconfig file: " + fileName); - const { succeeded, projectOptions, error } = this.configFileToProjectOptions(fileName); + // TODO: Ignoring potentially returned 'error' and 'succeeded' condition + const { projectOptions } = this.configFileToProjectOptions(fileName); + const rootFilesInTsconfig = projectOptions.files.map(f => this.getCanonicalFileName(f)); const openFileRoots = this.openFileRoots.map(s => this.getCanonicalFileName(s.fileName)); From 172d509c74e4376d840eb64a48254f738a638a8a Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 17 Dec 2015 15:09:12 -0800 Subject: [PATCH 66/79] Removed unused declarations in 'session.ts'. --- src/server/session.ts | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/server/session.ts b/src/server/session.ts index dae2384ce54..78686b79118 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -129,9 +129,6 @@ namespace ts.server { export class Session { protected projectService: ProjectService; - private pendingOperation = false; - private fileHash: ts.Map = {}; - private nextFileId = 1; private errorTimer: any; /*NodeJS.Timer | number*/ private immediateId: any; private changeSeq = 0; @@ -239,11 +236,6 @@ namespace ts.server { } } - private errorCheck(file: string, project: Project) { - this.syntacticCheck(file, project); - this.semanticCheck(file, project); - } - private reloadProjects() { this.projectService.reloadProjects(); } @@ -901,7 +893,7 @@ namespace ts.server { } getDiagnosticsForProject(delay: number, fileName: string) { - const { configFileName, fileNames } = this.getProjectInfo(fileName, /*needFileNameList*/ true); + const { fileNames } = this.getProjectInfo(fileName, /*needFileNameList*/ true); // No need to analyze lib.d.ts let fileNamesInProject = fileNames.filter((value, index, array) => value.indexOf("lib.d.ts") < 0); From 7637f4d2a0d6fccbb200a8411359ad6b034e8237 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 17 Dec 2015 15:09:39 -0800 Subject: [PATCH 67/79] Removed unused declarations in 'server.ts'. --- src/server/server.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/server/server.ts b/src/server/server.ts index e29e79ac6ed..d9f078ac0eb 100644 --- a/src/server/server.ts +++ b/src/server/server.ts @@ -4,9 +4,7 @@ /* tslint:disable:no-null */ namespace ts.server { - const nodeproto: typeof NodeJS._debugger = require("_debugger"); const readline: NodeJS.ReadLine = require("readline"); - const path: NodeJS.Path = require("path"); const fs: typeof NodeJS.fs = require("fs"); const rl = readline.createInterface({ From 50542946f7051726bd9b8b26c566c0abdfdd18c9 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 17 Dec 2015 15:12:25 -0800 Subject: [PATCH 68/79] Removed unused declarations in 'harness/fourslash.ts'. --- src/harness/fourslash.ts | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 24f3319285b..e8d985d40a6 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -321,11 +321,6 @@ namespace FourSlash { PlaceOpenBraceOnNewLineForControlBlocks: false, }; - this.testData.files.forEach(file => { - const fileName = file.fileName.replace(Harness.IO.directoryName(file.fileName), "").substr(1); - const fileNameWithoutExtension = fileName.substr(0, fileName.lastIndexOf(".")); - }); - // Open the first file by default this.openFile(0); } @@ -762,10 +757,6 @@ namespace FourSlash { return this.languageService.getReferencesAtPosition(this.activeFile.fileName, this.currentCaretPosition); } - private assertionMessage(name: string, actualValue: any, expectedValue: any) { - return "\nActual " + name + ":\n\t" + actualValue + "\nExpected value:\n\t" + expectedValue; - } - public getSyntacticDiagnostics(expected: string) { const diagnostics = this.languageService.getSyntacticDiagnostics(this.activeFile.fileName); this.testDiagnostics(expected, diagnostics); @@ -910,7 +901,6 @@ namespace FourSlash { } public verifyCurrentParameterSpanIs(parameter: string) { - const activeSignature = this.getActiveSignatureHelpItem(); const activeParameter = this.getActiveParameter(); assert.equal(ts.displayPartsToString(activeParameter.displayParts), parameter); } @@ -2189,9 +2179,6 @@ namespace FourSlash { } } - // TOOD: should these just use the Harness's stdout/stderr? - const fsOutput = new Harness.Compiler.WriterAggregator(); - const fsErrors = new Harness.Compiler.WriterAggregator(); export function runFourSlashTest(basePath: string, testType: FourSlashTestType, fileName: string) { const content = Harness.IO.readFile(fileName); runFourSlashTestContent(basePath, testType, content, fileName); From d59831b4e86b102a28ca045ee0a61778873df1c8 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 17 Dec 2015 15:38:02 -0800 Subject: [PATCH 69/79] Get rid of list and map abstractions to reduce GC pressure --- src/compiler/checker.ts | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 8d9fe1f7ba5..488549cb180 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5762,22 +5762,19 @@ namespace ts { target.symbol.flags & SymbolFlags.ConstEnum) { return Ternary.False; } - const targetNames = arrayToMap(getEnumMembersOfEnumType(target), member => member.name); - for (const member of getEnumMembersOfEnumType(source)) { - if (!hasProperty(targetNames, member.name)) { - reportError(Diagnostics.Property_0_is_missing_in_type_1, - member.name, - typeToString(target, /*enclosingDeclaration*/ undefined, TypeFormatFlags.UseFullyQualifiedType)); - return Ternary.False; + for (const property of getPropertiesOfType(getTypeOfSymbol(source.symbol))) { + if (property.flags & SymbolFlags.EnumMember) { + const targetProperty = getPropertyOfType(getTypeOfSymbol(target.symbol), property.name); + if (!targetProperty || !(targetProperty.flags & SymbolFlags.EnumMember)) { + reportError(Diagnostics.Property_0_is_missing_in_type_1, + property.name, + typeToString(target, /*enclosingDeclaration*/ undefined, TypeFormatFlags.UseFullyQualifiedType)); + return Ternary.False; + } } } return Ternary.True; } - - function getEnumMembersOfEnumType(type: Type) { - return filter(resolveStructuredTypeMembers(getTypeOfSymbol(type.symbol)).properties, - property => !!(property.flags & SymbolFlags.EnumMember)); - } } // Return true if the given type is part of a deeply nested chain of generic instantiations. We consider this to be the case From 5a53c613e4322d28a9931aca67a10735843cbf16 Mon Sep 17 00:00:00 2001 From: Yui T Date: Thu, 17 Dec 2015 15:51:00 -0800 Subject: [PATCH 70/79] Add assertion to check that ranges-array is not empty so it doesn't silently fail --- src/harness/fourslash.ts | 4 ++++ .../findAllRefsParameterPropertyDeclaration1.ts | 13 ++++++++----- .../findAllRefsParameterPropertyDeclaration2.ts | 1 + .../findAllRefsParameterPropertyDeclaration3.ts | 7 ++++--- tests/cases/fourslash/fourslash.ts | 1 + .../renameParameterPropertyDeclaration1.ts | 3 ++- .../renameParameterPropertyDeclaration2.ts | 3 ++- .../renameParameterPropertyDeclaration3.ts | 3 ++- .../renameParameterPropertyDeclaration4.ts | 3 ++- .../renameParameterPropertyDeclaration5.ts | 3 ++- 10 files changed, 28 insertions(+), 13 deletions(-) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 9d729345781..729d2052a92 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -2768,6 +2768,10 @@ namespace FourSlashInterface { this.state.verifyCompletionListItemsCountIsGreaterThan(count, this.negative); } + public assertRangesEmpty(ranges: FourSlash.Range[]) { + assert(ranges.length !== 0, "Ranges array is expected to be non-empty"); + } + public completionListIsEmpty() { this.state.verifyCompletionListIsEmpty(this.negative); } diff --git a/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration1.ts b/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration1.ts index 5034a57ae1d..828b143a4ce 100644 --- a/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration1.ts +++ b/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration1.ts @@ -7,12 +7,15 @@ //// } //// } -let ranges = test.ranges(); -for (let range of ranges) { +const ranges = test.ranges(); +verify.assertRangesEmpty(ranges); +for (const range of ranges) { goTo.position(range.start); - verify.referencesCountIs(ranges.length); - for (let expectedRange of ranges) { - verify.referencesAtPositionContains(expectedRange); + if (ranges.length) { + verify.referencesCountIs(ranges.length); + for (const expectedRange of ranges) { + verify.referencesAtPositionContains(expectedRange); + } } } \ No newline at end of file diff --git a/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration2.ts b/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration2.ts index 7db5ba13585..6b15b334c28 100644 --- a/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration2.ts +++ b/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration2.ts @@ -8,6 +8,7 @@ //// } let ranges = test.ranges(); +verify.assertRangesEmpty(ranges); for (let range of ranges) { goTo.position(range.start); diff --git a/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration3.ts b/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration3.ts index c2d8a06f658..1310841eed4 100644 --- a/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration3.ts +++ b/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration3.ts @@ -7,12 +7,13 @@ //// } //// } -let ranges = test.ranges(); -for (let range of ranges) { +const ranges = test.ranges(); +verify.assertRangesEmpty(ranges); +for (const range of ranges) { goTo.position(range.start); verify.referencesCountIs(ranges.length); - for (let expectedRange of ranges) { + for (const expectedRange of ranges) { verify.referencesAtPositionContains(expectedRange); } } \ No newline at end of file diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index b9b379bd465..fcb221e8233 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -137,6 +137,7 @@ declare namespace FourSlashInterface { verifyDefinitionsName(name: string, containerName: string): void; } class verify extends verifyNegatable { + assertRangesEmpty(ranges: FourSlash.Range[]): void; caretAtMarker(markerName?: string): void; indentationIs(numberOfSpaces: number): void; indentationAtPositionIs(fileName: string, position: number, numberOfSpaces: number, indentStyle?: ts.IndentStyle): void; diff --git a/tests/cases/fourslash/renameParameterPropertyDeclaration1.ts b/tests/cases/fourslash/renameParameterPropertyDeclaration1.ts index 4ca09b71e4b..37db51447ca 100644 --- a/tests/cases/fourslash/renameParameterPropertyDeclaration1.ts +++ b/tests/cases/fourslash/renameParameterPropertyDeclaration1.ts @@ -7,7 +7,8 @@ //// } //// } -let ranges = test.ranges() +let ranges = test.ranges(); +verify.assertRangesEmpty(ranges); for (let range of ranges) { goTo.position(range.start); verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); diff --git a/tests/cases/fourslash/renameParameterPropertyDeclaration2.ts b/tests/cases/fourslash/renameParameterPropertyDeclaration2.ts index 695e3729f94..c5e44438ee3 100644 --- a/tests/cases/fourslash/renameParameterPropertyDeclaration2.ts +++ b/tests/cases/fourslash/renameParameterPropertyDeclaration2.ts @@ -7,7 +7,8 @@ //// } //// } -let ranges = test.ranges() +let ranges = test.ranges(); +verify.assertRangesEmpty(ranges); for (let range of ranges) { goTo.position(range.start); verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); diff --git a/tests/cases/fourslash/renameParameterPropertyDeclaration3.ts b/tests/cases/fourslash/renameParameterPropertyDeclaration3.ts index 23971f0be27..2ca284f38d9 100644 --- a/tests/cases/fourslash/renameParameterPropertyDeclaration3.ts +++ b/tests/cases/fourslash/renameParameterPropertyDeclaration3.ts @@ -7,7 +7,8 @@ //// } //// } -let ranges = test.ranges() +let ranges = test.ranges(); +verify.assertRangesEmpty(ranges); for (let range of ranges) { goTo.position(range.start); verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); diff --git a/tests/cases/fourslash/renameParameterPropertyDeclaration4.ts b/tests/cases/fourslash/renameParameterPropertyDeclaration4.ts index 4646de6123c..35d268532b9 100644 --- a/tests/cases/fourslash/renameParameterPropertyDeclaration4.ts +++ b/tests/cases/fourslash/renameParameterPropertyDeclaration4.ts @@ -6,7 +6,8 @@ //// } //// } -let ranges = test.ranges() +let ranges = test.ranges(); +verify.assertRangesEmpty(ranges); for (let range of ranges) { goTo.position(range.start); verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); diff --git a/tests/cases/fourslash/renameParameterPropertyDeclaration5.ts b/tests/cases/fourslash/renameParameterPropertyDeclaration5.ts index 6d73c7af072..d32e69ad0c5 100644 --- a/tests/cases/fourslash/renameParameterPropertyDeclaration5.ts +++ b/tests/cases/fourslash/renameParameterPropertyDeclaration5.ts @@ -6,7 +6,8 @@ //// } //// } -let ranges = test.ranges() +let ranges = test.ranges(); +verify.assertRangesEmpty(ranges); for (let range of ranges) { goTo.position(range.start); verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); From b04bd66bb2a11ddfe7a7c17d35ea87ea4e9160cb Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 17 Dec 2015 16:18:55 -0800 Subject: [PATCH 71/79] Get type of target enum outside the lookup loop --- src/compiler/checker.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 488549cb180..f65a10b266a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5762,9 +5762,10 @@ namespace ts { target.symbol.flags & SymbolFlags.ConstEnum) { return Ternary.False; } + const targetEnumType = getTypeOfSymbol(target.symbol); for (const property of getPropertiesOfType(getTypeOfSymbol(source.symbol))) { if (property.flags & SymbolFlags.EnumMember) { - const targetProperty = getPropertyOfType(getTypeOfSymbol(target.symbol), property.name); + const targetProperty = getPropertyOfType(targetEnumType, property.name); if (!targetProperty || !(targetProperty.flags & SymbolFlags.EnumMember)) { reportError(Diagnostics.Property_0_is_missing_in_type_1, property.name, From 65571426bf9e47b1d364060b72cdd48039f77d74 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 17 Dec 2015 16:47:00 -0800 Subject: [PATCH 72/79] Remove missed unused declaration from 'harness.ts'. --- src/harness/harness.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 117be8a9afb..7fd81973172 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -615,7 +615,6 @@ namespace Harness { export const getExecutingFilePath = () => ""; export const exit = (exitCode: number) => {}; - const supportsCodePage = () => false; export let log = (s: string) => console.log(s); namespace Http { From f6253177094cb2fb1e32c1572a7227d96269bf36 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 17 Dec 2015 17:04:45 -0800 Subject: [PATCH 73/79] Added missing require for 'session' tests that relied on 'harness.ts'. --- tests/cases/unittests/session.ts | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/tests/cases/unittests/session.ts b/tests/cases/unittests/session.ts index c1dfd508942..1251fb7215f 100644 --- a/tests/cases/unittests/session.ts +++ b/tests/cases/unittests/session.ts @@ -1,5 +1,7 @@ /// +var expect: typeof _chai.expect = _chai.expect; + namespace ts.server { let lastWrittenToHost: string; const mockHost: ServerHost = { @@ -28,7 +30,7 @@ namespace ts.server { endGroup(): void {}, msg(s: string, type?: string): void {}, }; - + describe("the Session class", () => { let session: Session; let lastSent: protocol.Message; @@ -204,7 +206,7 @@ namespace ts.server { .to.throw(`Protocol handler already exists for command "${command}"`); }); }); - + describe("event", () => { it("can format event responses and send them", () => { const evt = "notify-test"; @@ -315,7 +317,7 @@ namespace ts.server { responseRequired: true })); } - + send(msg: protocol.Message) { this.client.handle(msg); } @@ -323,7 +325,7 @@ namespace ts.server { enqueue(msg: protocol.Request) { this.queue.unshift(msg); } - + handleRequest(msg: protocol.Request) { let response: protocol.Response; try { @@ -345,7 +347,7 @@ namespace ts.server { } } } - + class InProcClient { private server: InProcSession; private seq = 0; @@ -379,7 +381,7 @@ namespace ts.server { connect(session: InProcSession): void { this.server = session; } - + execute(command: string, args: any, callback: (resp: protocol.Response) => void): void { if (!this.server) { return; @@ -394,7 +396,7 @@ namespace ts.server { this.callbacks[this.seq] = callback; } }; - + it("can be constructed and respond to commands", (done) => { const cli = new InProcClient(); const session = new InProcSession(cli); @@ -402,23 +404,23 @@ namespace ts.server { data: true }; const toEvent = { - data: false + data: false }; let responses = 0; // Connect the client cli.connect(session); - + // Add an event handler cli.on("testevent", (eventinfo) => { expect(eventinfo).to.equal(toEvent); responses++; expect(responses).to.equal(1); }); - + // Trigger said event from the server session.event(toEvent, "testevent"); - + // Queue an echo command cli.execute("echo", toEcho, (resp) => { assert(resp.success, resp.message); @@ -426,7 +428,7 @@ namespace ts.server { expect(responses).to.equal(2); expect(resp.body).to.deep.equal(toEcho); }); - + // Queue a configure command cli.execute("configure", { hostInfo: "unit test", @@ -436,10 +438,10 @@ namespace ts.server { }, (resp) => { assert(resp.success, resp.message); responses++; - expect(responses).to.equal(3); + expect(responses).to.equal(3); done(); }); - + // Consume the queue and trigger the callbacks session.consumeQueue(); }); From e4e6f7072d798c593a0f59eeb2a8d4d9453c3dd1 Mon Sep 17 00:00:00 2001 From: Yui T Date: Thu, 17 Dec 2015 17:27:00 -0800 Subject: [PATCH 74/79] Update assert msg --- src/harness/fourslash.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 729d2052a92..796dc1134a1 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -2769,7 +2769,7 @@ namespace FourSlashInterface { } public assertRangesEmpty(ranges: FourSlash.Range[]) { - assert(ranges.length !== 0, "Ranges array is expected to be non-empty"); + assert(ranges.length !== 0, "Array of ranges is expected to be non-empty"); } public completionListIsEmpty() { @@ -3291,4 +3291,4 @@ namespace FourSlashInterface { }; } } -} +} From 2ec97a2d2e5ba40483f2e466ce414cb25e18314c Mon Sep 17 00:00:00 2001 From: Yui T Date: Thu, 17 Dec 2015 18:00:53 -0800 Subject: [PATCH 75/79] Address PR feed back --- Jakefile.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jakefile.js b/Jakefile.js index 91bd805a27b..288472a697b 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -925,7 +925,7 @@ var lintTargets = compilerSources .concat(harnessCoreSources) .concat(serverCoreSources) .concat(scriptSources) - .concat([path.join(servicesDirectory,"services.ts")]); + .concat([path.join(servicesDirectory, "services.ts")]); desc("Runs tslint on the compiler sources"); task("lint", ["build-rules"], function() { From 03be649b1c086801c17a84f74a714188c8ae92e7 Mon Sep 17 00:00:00 2001 From: Yui T Date: Thu, 17 Dec 2015 18:14:04 -0800 Subject: [PATCH 76/79] Address feedback --- src/harness/fourslash.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 796dc1134a1..d5e1687b305 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -2768,7 +2768,7 @@ namespace FourSlashInterface { this.state.verifyCompletionListItemsCountIsGreaterThan(count, this.negative); } - public assertRangesEmpty(ranges: FourSlash.Range[]) { + public assertHasRanges(ranges: FourSlash.Range[]) { assert(ranges.length !== 0, "Array of ranges is expected to be non-empty"); } From 7499c7c279933ac2fd35aa5ce11e82d319ec1a59 Mon Sep 17 00:00:00 2001 From: Yui T Date: Thu, 17 Dec 2015 18:34:21 -0800 Subject: [PATCH 77/79] Address feedback --- src/harness/fourslash.ts | 2 +- .../cases/fourslash/findAllRefsParameterPropertyDeclaration1.ts | 2 +- .../cases/fourslash/findAllRefsParameterPropertyDeclaration2.ts | 2 +- .../cases/fourslash/findAllRefsParameterPropertyDeclaration3.ts | 2 +- tests/cases/fourslash/fourslash.ts | 2 +- tests/cases/fourslash/renameParameterPropertyDeclaration1.ts | 2 +- tests/cases/fourslash/renameParameterPropertyDeclaration2.ts | 2 +- tests/cases/fourslash/renameParameterPropertyDeclaration3.ts | 2 +- tests/cases/fourslash/renameParameterPropertyDeclaration4.ts | 2 +- tests/cases/fourslash/renameParameterPropertyDeclaration5.ts | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 796dc1134a1..d5e1687b305 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -2768,7 +2768,7 @@ namespace FourSlashInterface { this.state.verifyCompletionListItemsCountIsGreaterThan(count, this.negative); } - public assertRangesEmpty(ranges: FourSlash.Range[]) { + public assertHasRanges(ranges: FourSlash.Range[]) { assert(ranges.length !== 0, "Array of ranges is expected to be non-empty"); } diff --git a/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration1.ts b/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration1.ts index 828b143a4ce..4018698f4ef 100644 --- a/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration1.ts +++ b/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration1.ts @@ -8,7 +8,7 @@ //// } const ranges = test.ranges(); -verify.assertRangesEmpty(ranges); +verify.assertHasRanges(ranges); for (const range of ranges) { goTo.position(range.start); diff --git a/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration2.ts b/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration2.ts index 6b15b334c28..a450a77e2dc 100644 --- a/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration2.ts +++ b/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration2.ts @@ -8,7 +8,7 @@ //// } let ranges = test.ranges(); -verify.assertRangesEmpty(ranges); +verify.assertHasRanges(ranges); for (let range of ranges) { goTo.position(range.start); diff --git a/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration3.ts b/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration3.ts index 1310841eed4..82fd67dfc9b 100644 --- a/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration3.ts +++ b/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration3.ts @@ -8,7 +8,7 @@ //// } const ranges = test.ranges(); -verify.assertRangesEmpty(ranges); +verify.assertHasRanges(ranges); for (const range of ranges) { goTo.position(range.start); diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index fcb221e8233..dd443e942cf 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -137,7 +137,7 @@ declare namespace FourSlashInterface { verifyDefinitionsName(name: string, containerName: string): void; } class verify extends verifyNegatable { - assertRangesEmpty(ranges: FourSlash.Range[]): void; + assertHasRanges(ranges: FourSlash.Range[]): void; caretAtMarker(markerName?: string): void; indentationIs(numberOfSpaces: number): void; indentationAtPositionIs(fileName: string, position: number, numberOfSpaces: number, indentStyle?: ts.IndentStyle): void; diff --git a/tests/cases/fourslash/renameParameterPropertyDeclaration1.ts b/tests/cases/fourslash/renameParameterPropertyDeclaration1.ts index 37db51447ca..42bfbf63a47 100644 --- a/tests/cases/fourslash/renameParameterPropertyDeclaration1.ts +++ b/tests/cases/fourslash/renameParameterPropertyDeclaration1.ts @@ -8,7 +8,7 @@ //// } let ranges = test.ranges(); -verify.assertRangesEmpty(ranges); +verify.assertHasRanges(ranges); for (let range of ranges) { goTo.position(range.start); verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); diff --git a/tests/cases/fourslash/renameParameterPropertyDeclaration2.ts b/tests/cases/fourslash/renameParameterPropertyDeclaration2.ts index c5e44438ee3..e7ef9d1c1a2 100644 --- a/tests/cases/fourslash/renameParameterPropertyDeclaration2.ts +++ b/tests/cases/fourslash/renameParameterPropertyDeclaration2.ts @@ -8,7 +8,7 @@ //// } let ranges = test.ranges(); -verify.assertRangesEmpty(ranges); +verify.assertHasRanges(ranges); for (let range of ranges) { goTo.position(range.start); verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); diff --git a/tests/cases/fourslash/renameParameterPropertyDeclaration3.ts b/tests/cases/fourslash/renameParameterPropertyDeclaration3.ts index 2ca284f38d9..9446e2aeb75 100644 --- a/tests/cases/fourslash/renameParameterPropertyDeclaration3.ts +++ b/tests/cases/fourslash/renameParameterPropertyDeclaration3.ts @@ -8,7 +8,7 @@ //// } let ranges = test.ranges(); -verify.assertRangesEmpty(ranges); +verify.assertHasRanges(ranges); for (let range of ranges) { goTo.position(range.start); verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); diff --git a/tests/cases/fourslash/renameParameterPropertyDeclaration4.ts b/tests/cases/fourslash/renameParameterPropertyDeclaration4.ts index 35d268532b9..7fb4b8c757d 100644 --- a/tests/cases/fourslash/renameParameterPropertyDeclaration4.ts +++ b/tests/cases/fourslash/renameParameterPropertyDeclaration4.ts @@ -7,7 +7,7 @@ //// } let ranges = test.ranges(); -verify.assertRangesEmpty(ranges); +verify.assertHasRanges(ranges); for (let range of ranges) { goTo.position(range.start); verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); diff --git a/tests/cases/fourslash/renameParameterPropertyDeclaration5.ts b/tests/cases/fourslash/renameParameterPropertyDeclaration5.ts index d32e69ad0c5..b7c47a4c0d7 100644 --- a/tests/cases/fourslash/renameParameterPropertyDeclaration5.ts +++ b/tests/cases/fourslash/renameParameterPropertyDeclaration5.ts @@ -7,7 +7,7 @@ //// } let ranges = test.ranges(); -verify.assertRangesEmpty(ranges); +verify.assertHasRanges(ranges); for (let range of ranges) { goTo.position(range.start); verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); From 75678de6d99ecffec583804fd6ce52cc83c46618 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 17 Dec 2015 19:47:01 -0800 Subject: [PATCH 78/79] Removed unused declarations from 'services.ts'. --- src/services/services.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/services/services.ts b/src/services/services.ts index 8f9028486aa..10f404dbcad 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -2987,7 +2987,6 @@ namespace ts { function getCompletionData(fileName: string, position: number) { const typeChecker = program.getTypeChecker(); - const syntacticStart = new Date().getTime(); const sourceFile = getValidSourceFile(fileName); const isJavaScriptFile = isSourceFileJavaScript(sourceFile); @@ -6166,10 +6165,6 @@ namespace ts { return ts.NavigateTo.getNavigateToItems(program, cancellationToken, searchValue, maxResultCount); } - function containErrors(diagnostics: Diagnostic[]): boolean { - return forEach(diagnostics, diagnostic => diagnostic.category === DiagnosticCategory.Error); - } - function getEmitOutput(fileName: string): EmitOutput { synchronizeHostData(); @@ -7045,7 +7040,6 @@ namespace ts { * be performed. */ function getDocCommentTemplateAtPosition(fileName: string, position: number): TextInsertion { - const start = new Date().getTime(); const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); // Check if in a context where we don't want to perform any insertion @@ -7339,11 +7333,17 @@ namespace ts { if (declarations && declarations.length > 0) { // Disallow rename for elements that are defined in the standard TypeScript library. const defaultLibFileName = host.getDefaultLibFileName(host.getCompilationSettings()); + const canonicalDefaultLibName = getCanonicalFileName(ts.normalizePath(defaultLibFileName)); if (defaultLibFileName) { for (const current of declarations) { const sourceFile = current.getSourceFile(); + // TODO (drosen): When is there no source file? + if (!sourceFile) { + continue; + } + const canonicalName = getCanonicalFileName(ts.normalizePath(sourceFile.fileName)); - if (sourceFile && getCanonicalFileName(ts.normalizePath(sourceFile.fileName)) === getCanonicalFileName(ts.normalizePath(defaultLibFileName))) { + if (canonicalName === canonicalDefaultLibName) { return getRenameInfoError(getLocaleSpecificMessage(Diagnostics.You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library)); } } From a5c632cd5a104935a737b58eb41adb79e57cbc84 Mon Sep 17 00:00:00 2001 From: Yui T Date: Thu, 17 Dec 2015 21:08:11 -0800 Subject: [PATCH 79/79] Fix merge error --- src/services/services.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/services.ts b/src/services/services.ts index d171724d7ff..4109a4eb345 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -5934,7 +5934,7 @@ namespace ts { function populateSearchSymbolSet(symbol: Symbol, location: Node): Symbol[] { // The search set contains at least the current symbol - const result = [symbol]; + let result = [symbol]; // If the symbol is an alias, add what it alaises to the list if (isImportOrExportSpecifierImportSymbol(symbol)) {