From 6afb15c19e51d2bf9cf9c6b644234af532d2af42 Mon Sep 17 00:00:00 2001 From: Jason Ramsay Date: Wed, 17 Jun 2015 21:22:16 -0700 Subject: [PATCH 01/78] CoreServicesShimHost and CoreServicesShimHostAdapter changes to support TSConfig exclude from the language service --- src/services/shims.ts | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/services/shims.ts b/src/services/shims.ts index 2e8b3eb774d..611d1dc8d29 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -61,8 +61,12 @@ namespace ts { /** Public interface of the the of a config service shim instance.*/ export interface CoreServicesShimHost extends Logger { - /** Returns a JSON-encoded value of the type: string[] */ - readDirectory(rootDir: string, extension: string): string; + /** Returns a JSON-encoded value of the type: string[] + * + * @param exclude A JSON encoded string[] containing the paths to exclude + * when enumerating the directory. + */ + readDirectory(rootDir: string, extension: string, exclude?: string): string; } /// @@ -351,8 +355,18 @@ namespace ts { constructor(private shimHost: CoreServicesShimHost) { } - public readDirectory(rootDir: string, extension: string): string[] { - var encoded = this.shimHost.readDirectory(rootDir, extension); + public readDirectory(rootDir: string, extension: string, exclude: string[]): string[] { + // Wrap the API changes for 1.5 release. This try/catch + // should be removed once TypeScript 1.5 has shipped. + // Also consider removing the optional designation for + // the exclude param at this time. + var encoded: string; + try { + encoded = this.shimHost.readDirectory(rootDir, extension, JSON.stringify(exclude)); + } + catch (e) { + encoded = this.shimHost.readDirectory(rootDir, extension); + } return JSON.parse(encoded); } } From f848087db0082493458c9a1406d718cf802de7c5 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 25 Jun 2015 11:59:45 -0400 Subject: [PATCH 02/78] Added failing tests. --- ...lRefsObjectBindingElementPropertyName01.ts | 19 +++++++++++++++++++ ...itionObjectBindingElementPropertyName01.ts | 14 ++++++++++++++ ...foForObjectBindingElementPropertyName01.ts | 12 ++++++++++++ ...enameObjectBindingElementPropertyName01.ts | 15 +++++++++++++++ 4 files changed, 60 insertions(+) create mode 100644 tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName01.ts create mode 100644 tests/cases/fourslash/goToDefinitionObjectBindingElementPropertyName01.ts create mode 100644 tests/cases/fourslash/quickInfoForObjectBindingElementPropertyName01.ts create mode 100644 tests/cases/fourslash/renameObjectBindingElementPropertyName01.ts diff --git a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName01.ts b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName01.ts new file mode 100644 index 00000000000..0d03561515d --- /dev/null +++ b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName01.ts @@ -0,0 +1,19 @@ +/// + +////interface I { +//// [|property1|]: number; +//// property2: string; +////} +//// +////var foo: I; +////var { [|property1|]: prop1 } = foo; + +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/goToDefinitionObjectBindingElementPropertyName01.ts b/tests/cases/fourslash/goToDefinitionObjectBindingElementPropertyName01.ts new file mode 100644 index 00000000000..9348ba05678 --- /dev/null +++ b/tests/cases/fourslash/goToDefinitionObjectBindingElementPropertyName01.ts @@ -0,0 +1,14 @@ +/// + +////interface I { +//// /*def*/property1: number; +//// property2: string; +////} +//// +////var foo: I; +////var { /*use*/property1: prop1 } = foo; + +goTo.marker("use"); +verify.definitionLocationExists(); +goTo.definition(); +verify.caretAtMarker("def"); \ No newline at end of file diff --git a/tests/cases/fourslash/quickInfoForObjectBindingElementPropertyName01.ts b/tests/cases/fourslash/quickInfoForObjectBindingElementPropertyName01.ts new file mode 100644 index 00000000000..72e742ba7af --- /dev/null +++ b/tests/cases/fourslash/quickInfoForObjectBindingElementPropertyName01.ts @@ -0,0 +1,12 @@ +/// + +////interface I { +//// property1: number; +//// property2: string; +////} +//// +////var foo: I; +////var { /*use*/property1: prop1 } = foo; + +goTo.marker(); +verify.quickInfoIs("(property) I.property1: number"); \ No newline at end of file diff --git a/tests/cases/fourslash/renameObjectBindingElementPropertyName01.ts b/tests/cases/fourslash/renameObjectBindingElementPropertyName01.ts new file mode 100644 index 00000000000..34dcc1353d0 --- /dev/null +++ b/tests/cases/fourslash/renameObjectBindingElementPropertyName01.ts @@ -0,0 +1,15 @@ +/// + +////interface I { +//// /*1*/[|property1|]: number; +//// property2: string; +////} +//// +////var foo: I; +////var { /*2*/[|property1|]: prop1 } = foo; + +for (let m of test.markers()) { + goTo.position(m.position); + verify.renameInfoSucceeded("property1", "I.property1", "property"); + verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); +} \ No newline at end of file From cb48c041874bebbfbf78a46ed5d2aa5e0979cdf9 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 25 Jun 2015 12:18:06 -0400 Subject: [PATCH 03/78] Added failing tests for when RHS is a destructuring. --- ...lRefsObjectBindingElementPropertyName02.ts | 19 +++++++++++++++++++ ...foForObjectBindingElementPropertyName02.ts | 12 ++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName02.ts create mode 100644 tests/cases/fourslash/quickInfoForObjectBindingElementPropertyName02.ts diff --git a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName02.ts b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName02.ts new file mode 100644 index 00000000000..86514051557 --- /dev/null +++ b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName02.ts @@ -0,0 +1,19 @@ +/// + +////interface I { +//// [|property1|]: number; +//// property2: string; +////} +//// +////var foo: I; +////var { [|property1|]: {} } = foo; + +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/quickInfoForObjectBindingElementPropertyName02.ts b/tests/cases/fourslash/quickInfoForObjectBindingElementPropertyName02.ts new file mode 100644 index 00000000000..5a166037f1c --- /dev/null +++ b/tests/cases/fourslash/quickInfoForObjectBindingElementPropertyName02.ts @@ -0,0 +1,12 @@ +/// + +////interface I { +//// property1: number; +//// property2: string; +////} +//// +////var foo: I; +////var { /**/property1: {} } = foo; + +goTo.marker(); +verify.quickInfoIs("(property) I.property1: number"); \ No newline at end of file From 70758e2920f6142d8dbcc02250129fa0f19a1d80 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 25 Jun 2015 14:24:13 -0400 Subject: [PATCH 04/78] Add two new tests to test for regression. --- .../quickInfoForObjectBindingElementName01.ts | 12 ++++++++++++ .../quickInfoForObjectBindingElementName02.ts | 12 ++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 tests/cases/fourslash/quickInfoForObjectBindingElementName01.ts create mode 100644 tests/cases/fourslash/quickInfoForObjectBindingElementName02.ts diff --git a/tests/cases/fourslash/quickInfoForObjectBindingElementName01.ts b/tests/cases/fourslash/quickInfoForObjectBindingElementName01.ts new file mode 100644 index 00000000000..5cba9554b80 --- /dev/null +++ b/tests/cases/fourslash/quickInfoForObjectBindingElementName01.ts @@ -0,0 +1,12 @@ +/// + +////interface I { +//// property1: number; +//// property2: string; +////} +//// +////var foo: I; +////var { /**/property1 } = foo; + +goTo.marker(); +verify.quickInfoIs("var property1: number"); \ No newline at end of file diff --git a/tests/cases/fourslash/quickInfoForObjectBindingElementName02.ts b/tests/cases/fourslash/quickInfoForObjectBindingElementName02.ts new file mode 100644 index 00000000000..e861d3db8fb --- /dev/null +++ b/tests/cases/fourslash/quickInfoForObjectBindingElementName02.ts @@ -0,0 +1,12 @@ +/// + +////interface I { +//// property1: number; +//// property2: string; +////} +//// +////var foo: I; +////var { property1: /**/prop1 } = foo; + +goTo.marker(); +verify.quickInfoIs("var prop1: number"); \ No newline at end of file From 341ba747d0d62bb9ca21830e1491d4e2790822c3 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 25 Jun 2015 14:25:51 -0400 Subject: [PATCH 05/78] Fix marker name. --- .../fourslash/quickInfoForObjectBindingElementPropertyName01.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cases/fourslash/quickInfoForObjectBindingElementPropertyName01.ts b/tests/cases/fourslash/quickInfoForObjectBindingElementPropertyName01.ts index 72e742ba7af..52a9af258b3 100644 --- a/tests/cases/fourslash/quickInfoForObjectBindingElementPropertyName01.ts +++ b/tests/cases/fourslash/quickInfoForObjectBindingElementPropertyName01.ts @@ -6,7 +6,7 @@ ////} //// ////var foo: I; -////var { /*use*/property1: prop1 } = foo; +////var { /**/property1: prop1 } = foo; goTo.marker(); verify.quickInfoIs("(property) I.property1: number"); \ No newline at end of file From 8ec4af546aad35e023a83e978ec5c833e74f2aa1 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 25 Jun 2015 15:50:25 -0400 Subject: [PATCH 06/78] Just use ranges, don't bother iwth renameInfoSucceeded. --- .../renameObjectBindingElementPropertyName01.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tests/cases/fourslash/renameObjectBindingElementPropertyName01.ts b/tests/cases/fourslash/renameObjectBindingElementPropertyName01.ts index 34dcc1353d0..535dbd3d5a3 100644 --- a/tests/cases/fourslash/renameObjectBindingElementPropertyName01.ts +++ b/tests/cases/fourslash/renameObjectBindingElementPropertyName01.ts @@ -1,15 +1,14 @@ /// ////interface I { -//// /*1*/[|property1|]: number; +//// [|property1|]: number; //// property2: string; ////} //// ////var foo: I; -////var { /*2*/[|property1|]: prop1 } = foo; +////var { [|property1|]: prop1 } = foo; -for (let m of test.markers()) { - goTo.position(m.position); - verify.renameInfoSucceeded("property1", "I.property1", "property"); +for (let range of test.ranges()) { + goTo.position(range.start); verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); } \ No newline at end of file From d7a4ac25f495d5ba78ff27b90fd4f23caf09abac Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 25 Jun 2015 15:52:10 -0400 Subject: [PATCH 07/78] Allow semantic operations to be performed on property names. Provide the property symbol of the type being destructured when referring to the property name. --- src/compiler/checker.ts | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index efee668a24b..763e4173287 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12352,10 +12352,21 @@ namespace ts { return getSymbolOfNode(node.parent); } - if (node.kind === SyntaxKind.Identifier && isInRightSideOfImportOrExportAssignment(node)) { - return node.parent.kind === SyntaxKind.ExportAssignment - ? getSymbolOfEntityNameOrPropertyAccessExpression(node) - : getSymbolOfPartOfRightHandSideOfImportEquals(node); + if (node.kind === SyntaxKind.Identifier) { + if (isInRightSideOfImportOrExportAssignment(node)) { + return node.parent.kind === SyntaxKind.ExportAssignment + ? getSymbolOfEntityNameOrPropertyAccessExpression(node) + : getSymbolOfPartOfRightHandSideOfImportEquals(node); + } + else if (node.parent.kind === SyntaxKind.BindingElement && + node.parent.parent.kind === SyntaxKind.ObjectBindingPattern && + node === (node.parent).propertyName) { + let typeOfPattern = getTypeAtLocation(node.parent.parent); + let propertyDeclaration = getPropertyOfType(typeOfPattern, (node).text); + if (propertyDeclaration) { + return propertyDeclaration; + } + } } switch (node.kind) { From a769e6747a0ead53cc8ca77c446de6cea5bc7c92 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 25 Jun 2015 15:57:30 -0400 Subject: [PATCH 08/78] Added one more test. --- ...lRefsObjectBindingElementPropertyName03.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName03.ts diff --git a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName03.ts b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName03.ts new file mode 100644 index 00000000000..304fa9e42e9 --- /dev/null +++ b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName03.ts @@ -0,0 +1,19 @@ +/// + +////interface I { +//// [|property1|]: number; +//// property2: string; +////} +//// +////var foo: I; +////var [{ [|property1|]: prop1 }, { property1, property2 } ] = [foo, foo]; + +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 From 5ee5ae11f99a8830af6fb4a94aca7f8ef2f68b94 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 25 Jun 2015 16:09:59 -0400 Subject: [PATCH 09/78] Check for definedness on the pattern's type. --- 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 763e4173287..64155fe7737 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12362,7 +12362,8 @@ namespace ts { node.parent.parent.kind === SyntaxKind.ObjectBindingPattern && node === (node.parent).propertyName) { let typeOfPattern = getTypeAtLocation(node.parent.parent); - let propertyDeclaration = getPropertyOfType(typeOfPattern, (node).text); + let propertyDeclaration = typeOfPattern && getPropertyOfType(typeOfPattern, (node).text); + if (propertyDeclaration) { return propertyDeclaration; } From 475819e27cb84e007fae02e82a4dbaa7d6fa6e05 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 25 Jun 2015 16:18:51 -0400 Subject: [PATCH 10/78] Accepted new baselines. --- .../reference/declarationEmitDestructuring1.symbols | 1 + .../declarationEmitDestructuringArrayPattern2.symbols | 1 + ...larationEmitDestructuringObjectLiteralPattern.symbols | 9 +++++++++ ...arationEmitDestructuringObjectLiteralPattern1.symbols | 4 ++++ ...arationEmitDestructuringObjectLiteralPattern2.symbols | 5 +++++ ...ucturingObjectBindingPatternAndAssignment1ES5.symbols | 2 ++ ...ucturingObjectBindingPatternAndAssignment1ES6.symbols | 2 ++ .../destructuringVariableDeclaration1ES5.symbols | 6 ++++++ .../destructuringVariableDeclaration1ES6.symbols | 6 ++++++ tests/baselines/reference/downlevelLetConst12.symbols | 2 ++ tests/baselines/reference/downlevelLetConst13.symbols | 4 ++++ tests/baselines/reference/downlevelLetConst14.symbols | 4 ++++ tests/baselines/reference/downlevelLetConst15.symbols | 6 ++++++ .../emitArrowFunctionWhenUsingArguments18_ES6.symbols | 1 + tests/baselines/reference/for-of41.symbols | 2 ++ tests/baselines/reference/for-of42.symbols | 2 ++ .../reference/initializePropertiesWithRenamedLet.symbols | 1 + tests/baselines/reference/letInNonStrictMode.symbols | 1 + .../objectBindingPatternKeywordIdentifiers06.symbols | 1 + tests/baselines/reference/systemModule13.symbols | 3 +++ tests/baselines/reference/systemModule8.symbols | 3 +++ 21 files changed, 66 insertions(+) diff --git a/tests/baselines/reference/declarationEmitDestructuring1.symbols b/tests/baselines/reference/declarationEmitDestructuring1.symbols index 10920128eee..32755fdef35 100644 --- a/tests/baselines/reference/declarationEmitDestructuring1.symbols +++ b/tests/baselines/reference/declarationEmitDestructuring1.symbols @@ -23,6 +23,7 @@ function bar({a1, b1, c1}: { a1: number, b1: boolean, c1: string }): void { } function baz({a2, b2: {b1, c1}}: { a2: number, b2: { b1: boolean, c1: string } }): void { } >baz : Symbol(baz, Decl(declarationEmitDestructuring1.ts, 2, 77)) >a2 : Symbol(a2, Decl(declarationEmitDestructuring1.ts, 3, 14)) +>b2 : Symbol(b2, Decl(declarationEmitDestructuring1.ts, 3, 46)) >b1 : Symbol(b1, Decl(declarationEmitDestructuring1.ts, 3, 23)) >c1 : Symbol(c1, Decl(declarationEmitDestructuring1.ts, 3, 26)) >a2 : Symbol(a2, Decl(declarationEmitDestructuring1.ts, 3, 34)) diff --git a/tests/baselines/reference/declarationEmitDestructuringArrayPattern2.symbols b/tests/baselines/reference/declarationEmitDestructuringArrayPattern2.symbols index 9e0e48f89e8..0a3c6f4044d 100644 --- a/tests/baselines/reference/declarationEmitDestructuringArrayPattern2.symbols +++ b/tests/baselines/reference/declarationEmitDestructuringArrayPattern2.symbols @@ -17,6 +17,7 @@ var [a2, [b2, { x12, y12: c2 }]=["abc", { x12: 10, y12: false }]] = [1, ["hello" >a2 : Symbol(a2, Decl(declarationEmitDestructuringArrayPattern2.ts, 5, 5)) >b2 : Symbol(b2, Decl(declarationEmitDestructuringArrayPattern2.ts, 5, 10)) >x12 : Symbol(x12, Decl(declarationEmitDestructuringArrayPattern2.ts, 5, 15)) +>y12 : Symbol(y12, Decl(declarationEmitDestructuringArrayPattern2.ts, 5, 91)) >c2 : Symbol(c2, Decl(declarationEmitDestructuringArrayPattern2.ts, 5, 20)) >x12 : Symbol(x12, Decl(declarationEmitDestructuringArrayPattern2.ts, 5, 41)) >y12 : Symbol(y12, Decl(declarationEmitDestructuringArrayPattern2.ts, 5, 50)) diff --git a/tests/baselines/reference/declarationEmitDestructuringObjectLiteralPattern.symbols b/tests/baselines/reference/declarationEmitDestructuringObjectLiteralPattern.symbols index 3cb4ef28c2b..0a57a93f3d0 100644 --- a/tests/baselines/reference/declarationEmitDestructuringObjectLiteralPattern.symbols +++ b/tests/baselines/reference/declarationEmitDestructuringObjectLiteralPattern.symbols @@ -21,24 +21,33 @@ var { x6, y6 } = { x6: 5, y6: "hello" }; >y6 : Symbol(y6, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 4, 25)) var { x7: a1 } = { x7: 5, y7: "hello" }; +>x7 : Symbol(x7, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 5, 18)) >a1 : Symbol(a1, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 5, 5)) >x7 : Symbol(x7, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 5, 18)) >y7 : Symbol(y7, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 5, 25)) var { y8: b1 } = { x8: 5, y8: "hello" }; +>y8 : Symbol(y8, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 6, 25)) >b1 : Symbol(b1, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 6, 5)) >x8 : Symbol(x8, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 6, 18)) >y8 : Symbol(y8, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 6, 25)) var { x9: a2, y9: b2 } = { x9: 5, y9: "hello" }; +>x9 : Symbol(x9, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 7, 26)) >a2 : Symbol(a2, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 7, 5)) +>y9 : Symbol(y9, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 7, 33)) >b2 : Symbol(b2, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 7, 13)) >x9 : Symbol(x9, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 7, 26)) >y9 : Symbol(y9, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 7, 33)) var { a: x11, b: { a: y11, b: { a: z11 }}} = { a: 1, b: { a: "hello", b: { a: true } } }; +>a : Symbol(a, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 9, 46)) >x11 : Symbol(x11, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 9, 5)) +>b : Symbol(b, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 9, 52)) +>a : Symbol(a, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 9, 57)) >y11 : Symbol(y11, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 9, 18)) +>b : Symbol(b, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 9, 69)) +>a : Symbol(a, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 9, 74)) >z11 : Symbol(z11, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 9, 31)) >a : Symbol(a, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 9, 46)) >b : Symbol(b, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 9, 52)) diff --git a/tests/baselines/reference/declarationEmitDestructuringObjectLiteralPattern1.symbols b/tests/baselines/reference/declarationEmitDestructuringObjectLiteralPattern1.symbols index a4c43a07bc8..cac2431411e 100644 --- a/tests/baselines/reference/declarationEmitDestructuringObjectLiteralPattern1.symbols +++ b/tests/baselines/reference/declarationEmitDestructuringObjectLiteralPattern1.symbols @@ -21,17 +21,21 @@ var { x6, y6 } = { x6: 5, y6: "hello" }; >y6 : Symbol(y6, Decl(declarationEmitDestructuringObjectLiteralPattern1.ts, 4, 25)) var { x7: a1 } = { x7: 5, y7: "hello" }; +>x7 : Symbol(x7, Decl(declarationEmitDestructuringObjectLiteralPattern1.ts, 5, 18)) >a1 : Symbol(a1, Decl(declarationEmitDestructuringObjectLiteralPattern1.ts, 5, 5)) >x7 : Symbol(x7, Decl(declarationEmitDestructuringObjectLiteralPattern1.ts, 5, 18)) >y7 : Symbol(y7, Decl(declarationEmitDestructuringObjectLiteralPattern1.ts, 5, 25)) var { y8: b1 } = { x8: 5, y8: "hello" }; +>y8 : Symbol(y8, Decl(declarationEmitDestructuringObjectLiteralPattern1.ts, 6, 25)) >b1 : Symbol(b1, Decl(declarationEmitDestructuringObjectLiteralPattern1.ts, 6, 5)) >x8 : Symbol(x8, Decl(declarationEmitDestructuringObjectLiteralPattern1.ts, 6, 18)) >y8 : Symbol(y8, Decl(declarationEmitDestructuringObjectLiteralPattern1.ts, 6, 25)) var { x9: a2, y9: b2 } = { x9: 5, y9: "hello" }; +>x9 : Symbol(x9, Decl(declarationEmitDestructuringObjectLiteralPattern1.ts, 7, 26)) >a2 : Symbol(a2, Decl(declarationEmitDestructuringObjectLiteralPattern1.ts, 7, 5)) +>y9 : Symbol(y9, Decl(declarationEmitDestructuringObjectLiteralPattern1.ts, 7, 33)) >b2 : Symbol(b2, Decl(declarationEmitDestructuringObjectLiteralPattern1.ts, 7, 13)) >x9 : Symbol(x9, Decl(declarationEmitDestructuringObjectLiteralPattern1.ts, 7, 26)) >y9 : Symbol(y9, Decl(declarationEmitDestructuringObjectLiteralPattern1.ts, 7, 33)) diff --git a/tests/baselines/reference/declarationEmitDestructuringObjectLiteralPattern2.symbols b/tests/baselines/reference/declarationEmitDestructuringObjectLiteralPattern2.symbols index 76440b60038..77e26e2c9b7 100644 --- a/tests/baselines/reference/declarationEmitDestructuringObjectLiteralPattern2.symbols +++ b/tests/baselines/reference/declarationEmitDestructuringObjectLiteralPattern2.symbols @@ -1,8 +1,13 @@ === tests/cases/compiler/declarationEmitDestructuringObjectLiteralPattern2.ts === var { a: x11, b: { a: y11, b: { a: z11 }}} = { a: 1, b: { a: "hello", b: { a: true } } }; +>a : Symbol(a, Decl(declarationEmitDestructuringObjectLiteralPattern2.ts, 1, 46)) >x11 : Symbol(x11, Decl(declarationEmitDestructuringObjectLiteralPattern2.ts, 1, 5)) +>b : Symbol(b, Decl(declarationEmitDestructuringObjectLiteralPattern2.ts, 1, 52)) +>a : Symbol(a, Decl(declarationEmitDestructuringObjectLiteralPattern2.ts, 1, 57)) >y11 : Symbol(y11, Decl(declarationEmitDestructuringObjectLiteralPattern2.ts, 1, 18)) +>b : Symbol(b, Decl(declarationEmitDestructuringObjectLiteralPattern2.ts, 1, 69)) +>a : Symbol(a, Decl(declarationEmitDestructuringObjectLiteralPattern2.ts, 1, 74)) >z11 : Symbol(z11, Decl(declarationEmitDestructuringObjectLiteralPattern2.ts, 1, 31)) >a : Symbol(a, Decl(declarationEmitDestructuringObjectLiteralPattern2.ts, 1, 46)) >b : Symbol(b, Decl(declarationEmitDestructuringObjectLiteralPattern2.ts, 1, 52)) diff --git a/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment1ES5.symbols b/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment1ES5.symbols index 017a7f71e61..718af66047d 100644 --- a/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment1ES5.symbols +++ b/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment1ES5.symbols @@ -19,6 +19,7 @@ var { b1, } = { b1:1, }; >b1 : Symbol(b1, Decl(destructuringObjectBindingPatternAndAssignment1ES5.ts, 11, 15)) var { b2: { b21 } = { b21: "string" } } = { b2: { b21: "world" } }; +>b2 : Symbol(b2, Decl(destructuringObjectBindingPatternAndAssignment1ES5.ts, 12, 44)) >b21 : Symbol(b21, Decl(destructuringObjectBindingPatternAndAssignment1ES5.ts, 12, 11)) >b21 : Symbol(b21, Decl(destructuringObjectBindingPatternAndAssignment1ES5.ts, 12, 21)) >b2 : Symbol(b2, Decl(destructuringObjectBindingPatternAndAssignment1ES5.ts, 12, 44)) @@ -32,6 +33,7 @@ var {b4 = 1}: any = { b4: 100000 }; >b4 : Symbol(b4, Decl(destructuringObjectBindingPatternAndAssignment1ES5.ts, 14, 21)) var {b5: { b52 } } = { b5: { b52 } }; +>b5 : Symbol(b5, Decl(destructuringObjectBindingPatternAndAssignment1ES5.ts, 15, 23)) >b52 : Symbol(b52, Decl(destructuringObjectBindingPatternAndAssignment1ES5.ts, 15, 10)) >b5 : Symbol(b5, Decl(destructuringObjectBindingPatternAndAssignment1ES5.ts, 15, 23)) >b52 : Symbol(b52, Decl(destructuringObjectBindingPatternAndAssignment1ES5.ts, 15, 29)) diff --git a/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment1ES6.symbols b/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment1ES6.symbols index 11289210ee4..57d739cbbfc 100644 --- a/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment1ES6.symbols +++ b/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment1ES6.symbols @@ -19,6 +19,7 @@ var { b1, } = { b1:1, }; >b1 : Symbol(b1, Decl(destructuringObjectBindingPatternAndAssignment1ES6.ts, 11, 15)) var { b2: { b21 } = { b21: "string" } } = { b2: { b21: "world" } }; +>b2 : Symbol(b2, Decl(destructuringObjectBindingPatternAndAssignment1ES6.ts, 12, 44)) >b21 : Symbol(b21, Decl(destructuringObjectBindingPatternAndAssignment1ES6.ts, 12, 11)) >b21 : Symbol(b21, Decl(destructuringObjectBindingPatternAndAssignment1ES6.ts, 12, 21)) >b2 : Symbol(b2, Decl(destructuringObjectBindingPatternAndAssignment1ES6.ts, 12, 44)) @@ -32,6 +33,7 @@ var {b4 = 1}: any = { b4: 100000 }; >b4 : Symbol(b4, Decl(destructuringObjectBindingPatternAndAssignment1ES6.ts, 14, 21)) var {b5: { b52 } } = { b5: { b52 } }; +>b5 : Symbol(b5, Decl(destructuringObjectBindingPatternAndAssignment1ES6.ts, 15, 23)) >b52 : Symbol(b52, Decl(destructuringObjectBindingPatternAndAssignment1ES6.ts, 15, 10)) >b5 : Symbol(b5, Decl(destructuringObjectBindingPatternAndAssignment1ES6.ts, 15, 23)) >b52 : Symbol(b52, Decl(destructuringObjectBindingPatternAndAssignment1ES6.ts, 15, 29)) diff --git a/tests/baselines/reference/destructuringVariableDeclaration1ES5.symbols b/tests/baselines/reference/destructuringVariableDeclaration1ES5.symbols index 2a2f2a358ca..924527bf1b4 100644 --- a/tests/baselines/reference/destructuringVariableDeclaration1ES5.symbols +++ b/tests/baselines/reference/destructuringVariableDeclaration1ES5.symbols @@ -17,6 +17,7 @@ var [a3, [[a4]], a5]: [number, [[string]], boolean] = [1, [["hello"]], true]; // The type T associated with a destructuring variable declaration is determined as follows: // Otherwise, if the declaration includes an initializer expression, T is the type of that initializer expression. var { b1: { b11 } = { b11: "string" } } = { b1: { b11: "world" } }; +>b1 : Symbol(b1, Decl(destructuringVariableDeclaration1ES5.ts, 7, 44)) >b11 : Symbol(b11, Decl(destructuringVariableDeclaration1ES5.ts, 7, 11)) >b11 : Symbol(b11, Decl(destructuringVariableDeclaration1ES5.ts, 7, 21)) >b1 : Symbol(b1, Decl(destructuringVariableDeclaration1ES5.ts, 7, 44)) @@ -74,6 +75,7 @@ var [d3, d4] = [1, "string", ...temp1]; // Combining both forms of destructuring, var {e: [e1, e2, e3 = { b1: 1000, b4: 200 }]} = { e: [1, 2, { b1: 4, b4: 0 }] }; +>e : Symbol(e, Decl(destructuringVariableDeclaration1ES5.ts, 31, 49)) >e1 : Symbol(e1, Decl(destructuringVariableDeclaration1ES5.ts, 31, 9)) >e2 : Symbol(e2, Decl(destructuringVariableDeclaration1ES5.ts, 31, 12)) >e3 : Symbol(e3, Decl(destructuringVariableDeclaration1ES5.ts, 31, 16)) @@ -84,8 +86,10 @@ var {e: [e1, e2, e3 = { b1: 1000, b4: 200 }]} = { e: [1, 2, { b1: 4, b4: 0 }] }; >b4 : Symbol(b4, Decl(destructuringVariableDeclaration1ES5.ts, 31, 68)) var {f: [f1, f2, { f3: f4, f5 }, , ]} = { f: [1, 2, { f3: 4, f5: 0 }] }; +>f : Symbol(f, Decl(destructuringVariableDeclaration1ES5.ts, 32, 41)) >f1 : Symbol(f1, Decl(destructuringVariableDeclaration1ES5.ts, 32, 9)) >f2 : Symbol(f2, Decl(destructuringVariableDeclaration1ES5.ts, 32, 12)) +>f3 : Symbol(f3, Decl(destructuringVariableDeclaration1ES5.ts, 32, 53)) >f4 : Symbol(f4, Decl(destructuringVariableDeclaration1ES5.ts, 32, 18)) >f5 : Symbol(f5, Decl(destructuringVariableDeclaration1ES5.ts, 32, 26)) >f : Symbol(f, Decl(destructuringVariableDeclaration1ES5.ts, 32, 41)) @@ -96,6 +100,7 @@ var {f: [f1, f2, { f3: f4, f5 }, , ]} = { f: [1, 2, { f3: 4, f5: 0 }] }; // an initializer expression, the type of the initializer expression is required to be assignable // to the widened form of the type associated with the destructuring variable declaration, binding property, or binding element. var {g: {g1 = [undefined, null]}}: { g: { g1: any[] } } = { g: { g1: [1, 2] } }; +>g : Symbol(g, Decl(destructuringVariableDeclaration1ES5.ts, 37, 36)) >g1 : Symbol(g1, Decl(destructuringVariableDeclaration1ES5.ts, 37, 9)) >undefined : Symbol(undefined) >g : Symbol(g, Decl(destructuringVariableDeclaration1ES5.ts, 37, 36)) @@ -104,6 +109,7 @@ var {g: {g1 = [undefined, null]}}: { g: { g1: any[] } } = { g: { g1: [1, 2] } }; >g1 : Symbol(g1, Decl(destructuringVariableDeclaration1ES5.ts, 37, 64)) var {h: {h1 = [undefined, null]}}: { h: { h1: number[] } } = { h: { h1: [1, 2] } }; +>h : Symbol(h, Decl(destructuringVariableDeclaration1ES5.ts, 38, 36)) >h1 : Symbol(h1, Decl(destructuringVariableDeclaration1ES5.ts, 38, 9)) >undefined : Symbol(undefined) >h : Symbol(h, Decl(destructuringVariableDeclaration1ES5.ts, 38, 36)) diff --git a/tests/baselines/reference/destructuringVariableDeclaration1ES6.symbols b/tests/baselines/reference/destructuringVariableDeclaration1ES6.symbols index 0350ff35251..ee4f391eb7a 100644 --- a/tests/baselines/reference/destructuringVariableDeclaration1ES6.symbols +++ b/tests/baselines/reference/destructuringVariableDeclaration1ES6.symbols @@ -17,6 +17,7 @@ var [a3, [[a4]], a5]: [number, [[string]], boolean] = [1, [["hello"]], true]; // The type T associated with a destructuring variable declaration is determined as follows: // Otherwise, if the declaration includes an initializer expression, T is the type of that initializer expression. var { b1: { b11 } = { b11: "string" } } = { b1: { b11: "world" } }; +>b1 : Symbol(b1, Decl(destructuringVariableDeclaration1ES6.ts, 7, 44)) >b11 : Symbol(b11, Decl(destructuringVariableDeclaration1ES6.ts, 7, 11)) >b11 : Symbol(b11, Decl(destructuringVariableDeclaration1ES6.ts, 7, 21)) >b1 : Symbol(b1, Decl(destructuringVariableDeclaration1ES6.ts, 7, 44)) @@ -74,6 +75,7 @@ var [d3, d4] = [1, "string", ...temp1]; // Combining both forms of destructuring, var {e: [e1, e2, e3 = { b1: 1000, b4: 200 }]} = { e: [1, 2, { b1: 4, b4: 0 }] }; +>e : Symbol(e, Decl(destructuringVariableDeclaration1ES6.ts, 31, 49)) >e1 : Symbol(e1, Decl(destructuringVariableDeclaration1ES6.ts, 31, 9)) >e2 : Symbol(e2, Decl(destructuringVariableDeclaration1ES6.ts, 31, 12)) >e3 : Symbol(e3, Decl(destructuringVariableDeclaration1ES6.ts, 31, 16)) @@ -84,8 +86,10 @@ var {e: [e1, e2, e3 = { b1: 1000, b4: 200 }]} = { e: [1, 2, { b1: 4, b4: 0 }] }; >b4 : Symbol(b4, Decl(destructuringVariableDeclaration1ES6.ts, 31, 68)) var {f: [f1, f2, { f3: f4, f5 }, , ]} = { f: [1, 2, { f3: 4, f5: 0 }] }; +>f : Symbol(f, Decl(destructuringVariableDeclaration1ES6.ts, 32, 41)) >f1 : Symbol(f1, Decl(destructuringVariableDeclaration1ES6.ts, 32, 9)) >f2 : Symbol(f2, Decl(destructuringVariableDeclaration1ES6.ts, 32, 12)) +>f3 : Symbol(f3, Decl(destructuringVariableDeclaration1ES6.ts, 32, 53)) >f4 : Symbol(f4, Decl(destructuringVariableDeclaration1ES6.ts, 32, 18)) >f5 : Symbol(f5, Decl(destructuringVariableDeclaration1ES6.ts, 32, 26)) >f : Symbol(f, Decl(destructuringVariableDeclaration1ES6.ts, 32, 41)) @@ -96,6 +100,7 @@ var {f: [f1, f2, { f3: f4, f5 }, , ]} = { f: [1, 2, { f3: 4, f5: 0 }] }; // an initializer expression, the type of the initializer expression is required to be assignable // to the widened form of the type associated with the destructuring variable declaration, binding property, or binding element. var {g: {g1 = [undefined, null]}}: { g: { g1: any[] } } = { g: { g1: [1, 2] } }; +>g : Symbol(g, Decl(destructuringVariableDeclaration1ES6.ts, 37, 36)) >g1 : Symbol(g1, Decl(destructuringVariableDeclaration1ES6.ts, 37, 9)) >undefined : Symbol(undefined) >g : Symbol(g, Decl(destructuringVariableDeclaration1ES6.ts, 37, 36)) @@ -104,6 +109,7 @@ var {g: {g1 = [undefined, null]}}: { g: { g1: any[] } } = { g: { g1: [1, 2] } }; >g1 : Symbol(g1, Decl(destructuringVariableDeclaration1ES6.ts, 37, 64)) var {h: {h1 = [undefined, null]}}: { h: { h1: number[] } } = { h: { h1: [1, 2] } }; +>h : Symbol(h, Decl(destructuringVariableDeclaration1ES6.ts, 38, 36)) >h1 : Symbol(h1, Decl(destructuringVariableDeclaration1ES6.ts, 38, 9)) >undefined : Symbol(undefined) >h : Symbol(h, Decl(destructuringVariableDeclaration1ES6.ts, 38, 36)) diff --git a/tests/baselines/reference/downlevelLetConst12.symbols b/tests/baselines/reference/downlevelLetConst12.symbols index d1c7fe3ea5b..97d6d5eebf8 100644 --- a/tests/baselines/reference/downlevelLetConst12.symbols +++ b/tests/baselines/reference/downlevelLetConst12.symbols @@ -12,6 +12,7 @@ let [baz] = []; >baz : Symbol(baz, Decl(downlevelLetConst12.ts, 6, 5)) let {a: baz2} = { a: 1 }; +>a : Symbol(a, Decl(downlevelLetConst12.ts, 7, 17)) >baz2 : Symbol(baz2, Decl(downlevelLetConst12.ts, 7, 5)) >a : Symbol(a, Decl(downlevelLetConst12.ts, 7, 17)) @@ -19,6 +20,7 @@ const [baz3] = [] >baz3 : Symbol(baz3, Decl(downlevelLetConst12.ts, 9, 7)) const {a: baz4} = { a: 1 }; +>a : Symbol(a, Decl(downlevelLetConst12.ts, 10, 19)) >baz4 : Symbol(baz4, Decl(downlevelLetConst12.ts, 10, 7)) >a : Symbol(a, Decl(downlevelLetConst12.ts, 10, 19)) diff --git a/tests/baselines/reference/downlevelLetConst13.symbols b/tests/baselines/reference/downlevelLetConst13.symbols index 1b06184f2b3..f8cd2e548a9 100644 --- a/tests/baselines/reference/downlevelLetConst13.symbols +++ b/tests/baselines/reference/downlevelLetConst13.symbols @@ -16,10 +16,12 @@ export const [bar2] = [2]; >bar2 : Symbol(bar2, Decl(downlevelLetConst13.ts, 7, 14)) export let {a: bar3} = { a: 1 }; +>a : Symbol(a, Decl(downlevelLetConst13.ts, 8, 24)) >bar3 : Symbol(bar3, Decl(downlevelLetConst13.ts, 8, 12)) >a : Symbol(a, Decl(downlevelLetConst13.ts, 8, 24)) export const {a: bar4} = { a: 1 }; +>a : Symbol(a, Decl(downlevelLetConst13.ts, 9, 26)) >bar4 : Symbol(bar4, Decl(downlevelLetConst13.ts, 9, 14)) >a : Symbol(a, Decl(downlevelLetConst13.ts, 9, 26)) @@ -39,10 +41,12 @@ export module M { >bar6 : Symbol(bar6, Decl(downlevelLetConst13.ts, 15, 18)) export let {a: bar7} = { a: 1 }; +>a : Symbol(a, Decl(downlevelLetConst13.ts, 16, 28)) >bar7 : Symbol(bar7, Decl(downlevelLetConst13.ts, 16, 16)) >a : Symbol(a, Decl(downlevelLetConst13.ts, 16, 28)) export const {a: bar8} = { a: 1 }; +>a : Symbol(a, Decl(downlevelLetConst13.ts, 17, 30)) >bar8 : Symbol(bar8, Decl(downlevelLetConst13.ts, 17, 18)) >a : Symbol(a, Decl(downlevelLetConst13.ts, 17, 30)) } diff --git a/tests/baselines/reference/downlevelLetConst14.symbols b/tests/baselines/reference/downlevelLetConst14.symbols index bf3450af71c..135f3c1417d 100644 --- a/tests/baselines/reference/downlevelLetConst14.symbols +++ b/tests/baselines/reference/downlevelLetConst14.symbols @@ -35,6 +35,7 @@ var z0, z1, z2, z3; >z1 : Symbol(z1, Decl(downlevelLetConst14.ts, 11, 9)) let {a: z2} = { a: 1 }; +>a : Symbol(a, Decl(downlevelLetConst14.ts, 13, 19)) >z2 : Symbol(z2, Decl(downlevelLetConst14.ts, 13, 9)) >a : Symbol(a, Decl(downlevelLetConst14.ts, 13, 19)) @@ -43,6 +44,7 @@ var z0, z1, z2, z3; >z2 : Symbol(z2, Decl(downlevelLetConst14.ts, 13, 9)) let {a: z3} = { a: 1 }; +>a : Symbol(a, Decl(downlevelLetConst14.ts, 15, 19)) >z3 : Symbol(z3, Decl(downlevelLetConst14.ts, 15, 9)) >a : Symbol(a, Decl(downlevelLetConst14.ts, 15, 19)) @@ -86,6 +88,7 @@ var y = true; >y : Symbol(y, Decl(downlevelLetConst14.ts, 29, 11)) let {a: z6} = {a: 1} +>a : Symbol(a, Decl(downlevelLetConst14.ts, 30, 23)) >z6 : Symbol(z6, Decl(downlevelLetConst14.ts, 30, 13)) >a : Symbol(a, Decl(downlevelLetConst14.ts, 30, 23)) @@ -129,6 +132,7 @@ var z5 = 1; >_z : Symbol(_z, Decl(downlevelLetConst14.ts, 46, 11)) let {a: _z5} = { a: 1 }; +>a : Symbol(a, Decl(downlevelLetConst14.ts, 47, 24)) >_z5 : Symbol(_z5, Decl(downlevelLetConst14.ts, 47, 13)) >a : Symbol(a, Decl(downlevelLetConst14.ts, 47, 24)) diff --git a/tests/baselines/reference/downlevelLetConst15.symbols b/tests/baselines/reference/downlevelLetConst15.symbols index 159e5a6d676..00c7e122eb2 100644 --- a/tests/baselines/reference/downlevelLetConst15.symbols +++ b/tests/baselines/reference/downlevelLetConst15.symbols @@ -28,6 +28,7 @@ var z0, z1, z2, z3; >z0 : Symbol(z0, Decl(downlevelLetConst15.ts, 9, 11)) const [{a: z1}] = [{a: 1}] +>a : Symbol(a, Decl(downlevelLetConst15.ts, 11, 24)) >z1 : Symbol(z1, Decl(downlevelLetConst15.ts, 11, 12)) >a : Symbol(a, Decl(downlevelLetConst15.ts, 11, 24)) @@ -36,6 +37,7 @@ var z0, z1, z2, z3; >z1 : Symbol(z1, Decl(downlevelLetConst15.ts, 11, 12)) const {a: z2} = { a: 1 }; +>a : Symbol(a, Decl(downlevelLetConst15.ts, 13, 21)) >z2 : Symbol(z2, Decl(downlevelLetConst15.ts, 13, 11)) >a : Symbol(a, Decl(downlevelLetConst15.ts, 13, 21)) @@ -44,6 +46,8 @@ var z0, z1, z2, z3; >z2 : Symbol(z2, Decl(downlevelLetConst15.ts, 13, 11)) const {a: {b: z3}} = { a: {b: 1} }; +>a : Symbol(a, Decl(downlevelLetConst15.ts, 15, 26)) +>b : Symbol(b, Decl(downlevelLetConst15.ts, 15, 31)) >z3 : Symbol(z3, Decl(downlevelLetConst15.ts, 15, 15)) >a : Symbol(a, Decl(downlevelLetConst15.ts, 15, 26)) >b : Symbol(b, Decl(downlevelLetConst15.ts, 15, 31)) @@ -88,6 +92,7 @@ var y = true; >y : Symbol(y, Decl(downlevelLetConst15.ts, 29, 13)) const {a: z6} = { a: 1 } +>a : Symbol(a, Decl(downlevelLetConst15.ts, 30, 25)) >z6 : Symbol(z6, Decl(downlevelLetConst15.ts, 30, 15)) >a : Symbol(a, Decl(downlevelLetConst15.ts, 30, 25)) @@ -131,6 +136,7 @@ var z5 = 1; >_z : Symbol(_z, Decl(downlevelLetConst15.ts, 46, 13)) const {a: _z5} = { a: 1 }; +>a : Symbol(a, Decl(downlevelLetConst15.ts, 47, 26)) >_z5 : Symbol(_z5, Decl(downlevelLetConst15.ts, 47, 15)) >a : Symbol(a, Decl(downlevelLetConst15.ts, 47, 26)) diff --git a/tests/baselines/reference/emitArrowFunctionWhenUsingArguments18_ES6.symbols b/tests/baselines/reference/emitArrowFunctionWhenUsingArguments18_ES6.symbols index 4d0887c1ff8..eb24f638884 100644 --- a/tests/baselines/reference/emitArrowFunctionWhenUsingArguments18_ES6.symbols +++ b/tests/baselines/reference/emitArrowFunctionWhenUsingArguments18_ES6.symbols @@ -4,6 +4,7 @@ function f() { >f : Symbol(f, Decl(emitArrowFunctionWhenUsingArguments18_ES6.ts, 0, 0)) var { arguments: args } = { arguments }; +>arguments : Symbol(arguments, Decl(emitArrowFunctionWhenUsingArguments18_ES6.ts, 2, 31)) >args : Symbol(args, Decl(emitArrowFunctionWhenUsingArguments18_ES6.ts, 2, 9)) >arguments : Symbol(arguments, Decl(emitArrowFunctionWhenUsingArguments18_ES6.ts, 2, 31)) diff --git a/tests/baselines/reference/for-of41.symbols b/tests/baselines/reference/for-of41.symbols index cf8db913919..046361653bb 100644 --- a/tests/baselines/reference/for-of41.symbols +++ b/tests/baselines/reference/for-of41.symbols @@ -6,7 +6,9 @@ var array = [{x: [0], y: {p: ""}}] >p : Symbol(p, Decl(for-of41.ts, 0, 26)) for (var {x: [a], y: {p}} of array) { +>x : Symbol(x, Decl(for-of41.ts, 0, 14)) >a : Symbol(a, Decl(for-of41.ts, 1, 14)) +>y : Symbol(y, Decl(for-of41.ts, 0, 21)) >p : Symbol(p, Decl(for-of41.ts, 1, 22)) >array : Symbol(array, Decl(for-of41.ts, 0, 3)) diff --git a/tests/baselines/reference/for-of42.symbols b/tests/baselines/reference/for-of42.symbols index b310fb1044f..5310f4970b9 100644 --- a/tests/baselines/reference/for-of42.symbols +++ b/tests/baselines/reference/for-of42.symbols @@ -5,7 +5,9 @@ var array = [{ x: "", y: 0 }] >y : Symbol(y, Decl(for-of42.ts, 0, 21)) for (var {x: a, y: b} of array) { +>x : Symbol(x, Decl(for-of42.ts, 0, 14)) >a : Symbol(a, Decl(for-of42.ts, 1, 10)) +>y : Symbol(y, Decl(for-of42.ts, 0, 21)) >b : Symbol(b, Decl(for-of42.ts, 1, 15)) >array : Symbol(array, Decl(for-of42.ts, 0, 3)) diff --git a/tests/baselines/reference/initializePropertiesWithRenamedLet.symbols b/tests/baselines/reference/initializePropertiesWithRenamedLet.symbols index 203508ddf98..f16d8cfc9e0 100644 --- a/tests/baselines/reference/initializePropertiesWithRenamedLet.symbols +++ b/tests/baselines/reference/initializePropertiesWithRenamedLet.symbols @@ -24,6 +24,7 @@ var x, y, z; if (true) { let { x: x } = { x: 0 }; +>x : Symbol(x, Decl(initializePropertiesWithRenamedLet.ts, 10, 20)) >x : Symbol(x, Decl(initializePropertiesWithRenamedLet.ts, 10, 9)) >x : Symbol(x, Decl(initializePropertiesWithRenamedLet.ts, 10, 20)) diff --git a/tests/baselines/reference/letInNonStrictMode.symbols b/tests/baselines/reference/letInNonStrictMode.symbols index 2b854a8c03f..47ba4465d1b 100644 --- a/tests/baselines/reference/letInNonStrictMode.symbols +++ b/tests/baselines/reference/letInNonStrictMode.symbols @@ -3,6 +3,7 @@ let [x] = [1]; >x : Symbol(x, Decl(letInNonStrictMode.ts, 0, 5)) let {a: y} = {a: 1}; +>a : Symbol(a, Decl(letInNonStrictMode.ts, 1, 14)) >y : Symbol(y, Decl(letInNonStrictMode.ts, 1, 5)) >a : Symbol(a, Decl(letInNonStrictMode.ts, 1, 14)) diff --git a/tests/baselines/reference/objectBindingPatternKeywordIdentifiers06.symbols b/tests/baselines/reference/objectBindingPatternKeywordIdentifiers06.symbols index 7cee5f3009b..f0546012498 100644 --- a/tests/baselines/reference/objectBindingPatternKeywordIdentifiers06.symbols +++ b/tests/baselines/reference/objectBindingPatternKeywordIdentifiers06.symbols @@ -1,6 +1,7 @@ === tests/cases/conformance/es6/destructuring/objectBindingPatternKeywordIdentifiers06.ts === var { as: as } = { as: 1 } +>as : Symbol(as, Decl(objectBindingPatternKeywordIdentifiers06.ts, 1, 18)) >as : Symbol(as, Decl(objectBindingPatternKeywordIdentifiers06.ts, 1, 5)) >as : Symbol(as, Decl(objectBindingPatternKeywordIdentifiers06.ts, 1, 18)) diff --git a/tests/baselines/reference/systemModule13.symbols b/tests/baselines/reference/systemModule13.symbols index d9e64335c2b..8245029e006 100644 --- a/tests/baselines/reference/systemModule13.symbols +++ b/tests/baselines/reference/systemModule13.symbols @@ -6,7 +6,10 @@ export let [x,y,z] = [1, 2, 3]; >z : Symbol(z, Decl(systemModule13.ts, 1, 16)) export const {a: z0, b: {c: z1}} = {a: true, b: {c: "123"}}; +>a : Symbol(a, Decl(systemModule13.ts, 2, 36)) >z0 : Symbol(z0, Decl(systemModule13.ts, 2, 14)) +>b : Symbol(b, Decl(systemModule13.ts, 2, 44)) +>c : Symbol(c, Decl(systemModule13.ts, 2, 49)) >z1 : Symbol(z1, Decl(systemModule13.ts, 2, 25)) >a : Symbol(a, Decl(systemModule13.ts, 2, 36)) >b : Symbol(b, Decl(systemModule13.ts, 2, 44)) diff --git a/tests/baselines/reference/systemModule8.symbols b/tests/baselines/reference/systemModule8.symbols index 3365ce7e37d..719d48e4592 100644 --- a/tests/baselines/reference/systemModule8.symbols +++ b/tests/baselines/reference/systemModule8.symbols @@ -78,7 +78,10 @@ export let [y] = [1]; >y : Symbol(y, Decl(systemModule8.ts, 27, 12)) export const {a: z0, b: {c: z1}} = {a: true, b: {c: "123"}}; +>a : Symbol(a, Decl(systemModule8.ts, 28, 36)) >z0 : Symbol(z0, Decl(systemModule8.ts, 28, 14)) +>b : Symbol(b, Decl(systemModule8.ts, 28, 44)) +>c : Symbol(c, Decl(systemModule8.ts, 28, 49)) >z1 : Symbol(z1, Decl(systemModule8.ts, 28, 25)) >a : Symbol(a, Decl(systemModule8.ts, 28, 36)) >b : Symbol(b, Decl(systemModule8.ts, 28, 44)) From c0faaeecbe045dd070f17d41fe314f6561f67ccc Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 1 Jul 2015 14:26:05 -0700 Subject: [PATCH 11/78] Added more test cases for object binding patterns. --- ...lRefsObjectBindingElementPropertyName04.ts | 21 +++++++++++++++++ ...lRefsObjectBindingElementPropertyName05.ts | 21 +++++++++++++++++ ...lRefsObjectBindingElementPropertyName06.ts | 23 +++++++++++++++++++ ...lRefsObjectBindingElementPropertyName07.ts | 15 ++++++++++++ 4 files changed, 80 insertions(+) create mode 100644 tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName04.ts create mode 100644 tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName05.ts create mode 100644 tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName06.ts create mode 100644 tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName07.ts diff --git a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName04.ts b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName04.ts new file mode 100644 index 00000000000..ad72bd99bb8 --- /dev/null +++ b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName04.ts @@ -0,0 +1,21 @@ +/// + +////interface I { +//// [|property1|]: number; +//// property2: string; +////} +//// +////function f({ [|property1|]: p1 }: I, +//// { [|property1|] }: I, +//// { property1: p2 }) { +////} + +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/findAllRefsObjectBindingElementPropertyName05.ts b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName05.ts new file mode 100644 index 00000000000..aa6432fa62e --- /dev/null +++ b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName05.ts @@ -0,0 +1,21 @@ +/// + +////interface I { +//// property1: number; +//// property2: string; +////} +//// +////function f({ [|property1|]: p }, { property1 }) { +//// let x = property1; +////} + +// Notice only one range. +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/findAllRefsObjectBindingElementPropertyName06.ts b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName06.ts new file mode 100644 index 00000000000..4ce33f2b6ad --- /dev/null +++ b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName06.ts @@ -0,0 +1,23 @@ +/// + +////interface I { +//// [|property1|]: number; +//// property2: string; +////} +//// +////for (let { [|property1|]: p } of []) { +////} +////for (let { [|property1|] } of []) { +////} +////for (var { [|property1|]: p } of []) { +////} + +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/findAllRefsObjectBindingElementPropertyName07.ts b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName07.ts new file mode 100644 index 00000000000..6448d2396b3 --- /dev/null +++ b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName07.ts @@ -0,0 +1,15 @@ +/// + +////let p, b; +//// +////p, [{ [|a|]: p, b }] = [{ [|a|]: 10, b: true }]; + +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 From 726eea2896e4c8054f0e162c10399e4b930c1845 Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Tue, 30 Jun 2015 16:11:09 -0700 Subject: [PATCH 12/78] dispose script snapshots from the old source file --- src/services/services.ts | 13 +++++++++++++ src/services/shims.ts | 9 +++++++++ 2 files changed, 22 insertions(+) diff --git a/src/services/services.ts b/src/services/services.ts index 521c6db155a..41996349fba 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -91,6 +91,9 @@ module ts { * not happen and the entire document will be re - parsed. */ getChangeRange(oldSnapshot: IScriptSnapshot): TextChangeRange; + + /** Releases all resources held by this script snapshot */ + dispose?(): void; } export module ScriptSnapshot { @@ -1873,6 +1876,16 @@ module ts { // after incremental parsing nameTable might not be up-to-date // drop it so it can be lazily recreated later newSourceFile.nameTable = undefined; + + // dispose all resources held by old script snapshot + if (sourceFile.scriptSnapshot) { + if (sourceFile.scriptSnapshot.dispose) { + sourceFile.scriptSnapshot.dispose(); + } + + sourceFile.scriptSnapshot = undefined; + } + return newSourceFile; } } diff --git a/src/services/shims.ts b/src/services/shims.ts index d6f9f7a968a..6743f48df1d 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -34,6 +34,9 @@ module ts { * Or undefined value if there was no change. */ getChangeRange(oldSnapshot: ScriptSnapshotShim): string; + + /** Releases all resources held by this script snapshot */ + dispose?(): void; } export interface Logger { @@ -242,6 +245,12 @@ module ts { return createTextChangeRange( createTextSpan(decoded.span.start, decoded.span.length), decoded.newLength); } + + public dispose(): void { + if ("dispose" in this.scriptSnapshotShim) { + this.scriptSnapshotShim.dispose(); + } + } } export class LanguageServiceShimHostAdapter implements LanguageServiceHost { From ee1350b40e6cdd4a49eb298f591ad62afb4f3993 Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Wed, 1 Jul 2015 23:14:40 -0700 Subject: [PATCH 13/78] dispose snapshot only if new file differs from the old file --- 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 41996349fba..a446c45aa8f 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1878,7 +1878,7 @@ module ts { newSourceFile.nameTable = undefined; // dispose all resources held by old script snapshot - if (sourceFile.scriptSnapshot) { + if (sourceFile !== newSourceFile && sourceFile.scriptSnapshot) { if (sourceFile.scriptSnapshot.dispose) { sourceFile.scriptSnapshot.dispose(); } From e190761d96beaa0aa39e84de010695c63b05e64d Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Thu, 9 Jul 2015 13:13:49 -0700 Subject: [PATCH 14/78] addressed PR feedback: added comments --- src/services/shims.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/services/shims.ts b/src/services/shims.ts index 6743f48df1d..e583a0d3d18 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -247,6 +247,8 @@ module ts { } public dispose(): void { + // if scriptSnapshotShim is a COM object then property check becomes method call with no arguments + // 'in' does not have this effect if ("dispose" in this.scriptSnapshotShim) { this.scriptSnapshotShim.dispose(); } From 443752ace77a0d38711bf3e339ce3841dd7bef9e Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 9 Jul 2015 16:57:52 -0700 Subject: [PATCH 15/78] Added tests for completion lists in export clauses. --- .../completionListInExportClause01.ts | 39 +++++++++++++++++++ .../completionListInExportClause02.ts | 14 +++++++ 2 files changed, 53 insertions(+) create mode 100644 tests/cases/fourslash/completionListInExportClause01.ts create mode 100644 tests/cases/fourslash/completionListInExportClause02.ts diff --git a/tests/cases/fourslash/completionListInExportClause01.ts b/tests/cases/fourslash/completionListInExportClause01.ts new file mode 100644 index 00000000000..6e6cd6c678b --- /dev/null +++ b/tests/cases/fourslash/completionListInExportClause01.ts @@ -0,0 +1,39 @@ +/// + +// @Filename: m1.ts +////export var foo: number = 1; +////export function bar() { return 10; } +////export function baz() { return 10; } + +// @Filename: m2.ts +////export {/*1*/, /*2*/ from "m1" +////export {/*3*/} from "m1" +////export {foo,/*4*/ from "m1" +////export {bar as /*5*/, /*6*/ from "m1" +////export {foo, bar, baz as b,/*7*/} from "m1" +function verifyCompletionAtMarker(marker: string, showBuilder: boolean, ...completions: string[]) { + goTo.marker(marker); + if (completions.length) { + for (let completion of completions) { + verify.completionListContains(completion); + } + } + else { + verify.completionListIsEmpty(); + } + + if (showBuilder) { + verify.completionListAllowsNewIdentifier(); + } + else { + verify.not.completionListAllowsNewIdentifier(); + } +} + +verifyCompletionAtMarker("1", /*showBuilder*/ false, "foo", "bar", "baz"); +verifyCompletionAtMarker("2", /*showBuilder*/ false, "foo", "bar", "baz"); +verifyCompletionAtMarker("3", /*showBuilder*/ false, "foo", "bar", "baz"); +verifyCompletionAtMarker("4", /*showBuilder*/ false, "bar", "baz"); +verifyCompletionAtMarker("5", /*showBuilder*/ true); +verifyCompletionAtMarker("6", /*showBuilder*/ false, "foo", "baz"); +verifyCompletionAtMarker("7", /*showBuilder*/ false); \ No newline at end of file diff --git a/tests/cases/fourslash/completionListInExportClause02.ts b/tests/cases/fourslash/completionListInExportClause02.ts new file mode 100644 index 00000000000..4b40976f521 --- /dev/null +++ b/tests/cases/fourslash/completionListInExportClause02.ts @@ -0,0 +1,14 @@ +/// + +////declare module "M1" { +//// export var V; +////} +////var W; +////declare module "M2" { +//// export { /**/ } from "M1" +////} + +goTo.marker(); +verify.completionListContains("V"); +verify.not.completionListContains("W"); +verify.not.completionListAllowsNewIdentifier(); \ No newline at end of file From 64056005ff1ca6a6c18aa4fdc170a5543a33d08c Mon Sep 17 00:00:00 2001 From: Dan Quirk Date: Thu, 9 Jul 2015 18:04:30 -0700 Subject: [PATCH 16/78] Create top level describe block for runners so status is reported at runner level --- src/harness/compilerRunner.ts | 46 ++++---- src/harness/fourslashRunner.ts | 118 +++++++++++---------- src/harness/projectsRunner.ts | 188 +++++++++++++++++---------------- 3 files changed, 179 insertions(+), 173 deletions(-) diff --git a/src/harness/compilerRunner.ts b/src/harness/compilerRunner.ts index 1b399e1b706..1c8dccc6173 100644 --- a/src/harness/compilerRunner.ts +++ b/src/harness/compilerRunner.ts @@ -100,7 +100,7 @@ class CompilerBaselineRunner extends RunnerBase { }); beforeEach(() => { - /* The compiler doesn't handle certain flags flipping during a single compilation setting. Tests on these flags will need + /* The compiler doesn't handle certain flags flipping during a single compilation setting. Tests on these flags will need a fresh compiler instance for themselves and then create a fresh one for the next test. Would be nice to get dev fixes eventually to remove this limitation. */ for (var i = 0; i < tcSettings.length; ++i) { @@ -261,19 +261,19 @@ class CompilerBaselineRunner extends RunnerBase { // NEWTODO: Type baselines if (result.errors.length === 0) { - // The full walker simulates the types that you would get from doing a full + // The full walker simulates the types that you would get from doing a full // compile. The pull walker simulates the types you get when you just do // a type query for a random node (like how the LS would do it). Most of the // time, these will be the same. However, occasionally, they can be different. // Specifically, when the compiler internally depends on symbol IDs to order - // things, then we may see different results because symbols can be created in a + // things, then we may see different results because symbols can be created in a // different order with 'pull' operations, and thus can produce slightly differing // output. // // For example, with a full type check, we may see a type outputed as: number | string // But with a pull type check, we may see it as: string | number // - // These types are equivalent, but depend on what order the compiler observed + // These types are equivalent, but depend on what order the compiler observed // certain parts of the program. let allFiles = toBeCompiled.concat(otherFiles).filter(file => !!program.getSourceFile(file.unitName)); @@ -384,25 +384,27 @@ class CompilerBaselineRunner extends RunnerBase { } public initializeTests() { - describe("Setup compiler for compiler baselines", () => { - var harnessCompiler = Harness.Compiler.getCompiler(); - this.parseOptions(); - }); - - // this will set up a series of describe/it blocks to run between the setup and cleanup phases - if (this.tests.length === 0) { - var testFiles = this.enumerateFiles(this.basePath, /\.tsx?$/, { recursive: true }); - testFiles.forEach(fn => { - fn = fn.replace(/\\/g, "/"); - this.checkTestCodeOutput(fn); + describe('Compiler tests', () => { + describe("Setup compiler for compiler baselines", () => { + var harnessCompiler = Harness.Compiler.getCompiler(); + this.parseOptions(); }); - } - else { - this.tests.forEach(test => this.checkTestCodeOutput(test)); - } - describe("Cleanup after compiler baselines", () => { - var harnessCompiler = Harness.Compiler.getCompiler(); + // this will set up a series of describe/it blocks to run between the setup and cleanup phases + if (this.tests.length === 0) { + var testFiles = this.enumerateFiles(this.basePath, /\.tsx?$/, { recursive: true }); + testFiles.forEach(fn => { + fn = fn.replace(/\\/g, "/"); + this.checkTestCodeOutput(fn); + }); + } + else { + this.tests.forEach(test => this.checkTestCodeOutput(test)); + } + + describe("Cleanup after compiler baselines", () => { + var harnessCompiler = Harness.Compiler.getCompiler(); + }); }); } @@ -434,4 +436,4 @@ class CompilerBaselineRunner extends RunnerBase { } } } -} \ No newline at end of file +} diff --git a/src/harness/fourslashRunner.ts b/src/harness/fourslashRunner.ts index d11c5e639e5..9287f7361a5 100644 --- a/src/harness/fourslashRunner.ts +++ b/src/harness/fourslashRunner.ts @@ -2,7 +2,7 @@ /// /// -const enum FourSlashTestType { +const enum FourSlashTestType { Native, Shims, Server @@ -35,70 +35,72 @@ class FourSlashRunner extends RunnerBase { this.tests = this.enumerateFiles(this.basePath, /\.ts/i, { recursive: false }); } + describe('Fourslash tests', () => { this.tests.forEach((fn: string) => { - describe(fn, () => { - fn = ts.normalizeSlashes(fn); - var justName = fn.replace(/^.*[\\\/]/, ''); + describe(fn, () => { + fn = ts.normalizeSlashes(fn); + var justName = fn.replace(/^.*[\\\/]/, ''); - // Convert to relative path - var testIndex = fn.indexOf('tests/'); - if (testIndex >= 0) fn = fn.substr(testIndex); + // Convert to relative path + var testIndex = fn.indexOf('tests/'); + if (testIndex >= 0) fn = fn.substr(testIndex); - if (justName && !justName.match(/fourslash\.ts$/i) && !justName.match(/\.d\.ts$/i)) { - it(this.testSuiteName + ' test ' + justName + ' runs correctly',() => { - FourSlash.runFourSlashTest(this.basePath, this.testType, fn); - }); - } + if (justName && !justName.match(/fourslash\.ts$/i) && !justName.match(/\.d\.ts$/i)) { + it(this.testSuiteName + ' test ' + justName + ' runs correctly',() => { + FourSlash.runFourSlashTest(this.basePath, this.testType, fn); + }); + } + }); }); - }); - describe('Generate Tao XML', () => { - var invalidReasons: any = {}; - FourSlash.xmlData.forEach(xml => { - if (xml.invalidReason !== null) { - invalidReasons[xml.invalidReason] = (invalidReasons[xml.invalidReason] || 0) + 1; + describe('Generate Tao XML', () => { + var invalidReasons: any = {}; + FourSlash.xmlData.forEach(xml => { + if (xml.invalidReason !== null) { + invalidReasons[xml.invalidReason] = (invalidReasons[xml.invalidReason] || 0) + 1; + } + }); + var invalidReport: { reason: string; count: number }[] = []; + for (var reason in invalidReasons) { + if (invalidReasons.hasOwnProperty(reason)) { + invalidReport.push({ reason: reason, count: invalidReasons[reason] }); + } } - }); - var invalidReport: { reason: string; count: number }[] = []; - for (var reason in invalidReasons) { - if (invalidReasons.hasOwnProperty(reason)) { - invalidReport.push({ reason: reason, count: invalidReasons[reason] }); - } - } - invalidReport.sort((lhs, rhs) => lhs.count > rhs.count ? -1 : lhs.count === rhs.count ? 0 : 1); + invalidReport.sort((lhs, rhs) => lhs.count > rhs.count ? -1 : lhs.count === rhs.count ? 0 : 1); - var lines: string[] = []; - lines.push(''); + lines.push(''); + lines.push(' '); + lines.push(' '); + lines.push(' '); + lines.push(' '); + FourSlash.xmlData.forEach(xml => { + if (xml.invalidReason !== null) { + lines.push(''); + } else { + lines.push(' '); + xml.actions.forEach(action => { + lines.push(' ' + action); + }); + lines.push(' '); + } + }); + lines.push(' '); + lines.push(' '); + lines.push(' '); + lines.push(' '); + lines.push(' '); + lines.push(' '); + lines.push(' '); + lines.push(' '); + lines.push(''); + Harness.IO.writeFile('built/local/fourslash.xml', lines.join('\r\n')); }); - lines.push('-->'); - lines.push(''); - lines.push(' '); - lines.push(' '); - lines.push(' '); - lines.push(' '); - FourSlash.xmlData.forEach(xml => { - if (xml.invalidReason !== null) { - lines.push(''); - } else { - lines.push(' '); - xml.actions.forEach(action => { - lines.push(' ' + action); - }); - lines.push(' '); - } - }); - lines.push(' '); - lines.push(' '); - lines.push(' '); - lines.push(' '); - lines.push(' '); - lines.push(' '); - lines.push(' '); - lines.push(' '); - lines.push(''); - Harness.IO.writeFile('built/local/fourslash.xml', lines.join('\r\n')); }); } } @@ -108,4 +110,4 @@ class GeneratedFourslashRunner extends FourSlashRunner { super(testType); this.basePath += '/generated/'; } -} \ No newline at end of file +} diff --git a/src/harness/projectsRunner.ts b/src/harness/projectsRunner.ts index 5eb0016ff8d..01dc52308ff 100644 --- a/src/harness/projectsRunner.ts +++ b/src/harness/projectsRunner.ts @@ -89,7 +89,7 @@ class ProjectRunner extends RunnerBase { } // When test case output goes to tests/baselines/local/projectOutput/testCaseName/moduleKind/ - // We have these two separate locations because when comparing baselines the baseline verifier will delete the existing file + // We have these two separate locations because when comparing baselines the baseline verifier will delete the existing file // so even if it was created by compiler in that location, the file will be deleted by verified before we can read it // so lets keep these two locations separate function getProjectOutputFolder(fileName: string, moduleKind: ts.ModuleKind) { @@ -194,7 +194,7 @@ class ProjectRunner extends RunnerBase { }; } } - + function batchCompilerProjectTestCase(moduleKind: ts.ModuleKind): BatchCompileProjectTestCaseResult{ var nonSubfolderDiskFiles = 0; @@ -230,7 +230,7 @@ class ProjectRunner extends RunnerBase { var diskRelativeName = ts.getRelativePathToDirectoryOrUrl(testCase.projectRoot, diskFileName, getCurrentDirectory(), Harness.Compiler.getCanonicalFileName, /*isAbsolutePathAnUrl*/ false); if (ts.isRootedDiskPath(diskRelativeName) || diskRelativeName.substr(0, 3) === "../") { - // If the generated output file resides in the parent folder or is rooted path, + // If the generated output file resides in the parent folder or is rooted path, // we need to instead create files that can live in the project reference folder // but make sure extension of these files matches with the fileName the compiler asked to write diskRelativeName = "diskFile" + nonSubfolderDiskFiles++ + @@ -330,108 +330,110 @@ class ProjectRunner extends RunnerBase { var name = 'Compiling project for ' + testCase.scenario + ': testcase ' + testCaseFileName; - describe(name, () => { - function verifyCompilerResults(moduleKind: ts.ModuleKind) { - function getCompilerResolutionInfo() { - var resolutionInfo: ProjectRunnerTestCaseResolutionInfo = { - scenario: testCase.scenario, - projectRoot: testCase.projectRoot, - inputFiles: testCase.inputFiles, - out: testCase.out, - outDir: testCase.outDir, - sourceMap: testCase.sourceMap, - mapRoot: testCase.mapRoot, - resolveMapRoot: testCase.resolveMapRoot, - sourceRoot: testCase.sourceRoot, - resolveSourceRoot: testCase.resolveSourceRoot, - declaration: testCase.declaration, - baselineCheck: testCase.baselineCheck, - runTest: testCase.runTest, - bug: testCase.bug, - rootDir: testCase.rootDir, - resolvedInputFiles: ts.map(compilerResult.program.getSourceFiles(), inputFile => inputFile.fileName), - emittedFiles: ts.map(compilerResult.outputFiles, outputFile => outputFile.emittedFileName) - }; + describe('Projects tests', () => { + describe(name, () => { + function verifyCompilerResults(moduleKind: ts.ModuleKind) { + function getCompilerResolutionInfo() { + var resolutionInfo: ProjectRunnerTestCaseResolutionInfo = { + scenario: testCase.scenario, + projectRoot: testCase.projectRoot, + inputFiles: testCase.inputFiles, + out: testCase.out, + outDir: testCase.outDir, + sourceMap: testCase.sourceMap, + mapRoot: testCase.mapRoot, + resolveMapRoot: testCase.resolveMapRoot, + sourceRoot: testCase.sourceRoot, + resolveSourceRoot: testCase.resolveSourceRoot, + declaration: testCase.declaration, + baselineCheck: testCase.baselineCheck, + runTest: testCase.runTest, + bug: testCase.bug, + rootDir: testCase.rootDir, + resolvedInputFiles: ts.map(compilerResult.program.getSourceFiles(), inputFile => inputFile.fileName), + emittedFiles: ts.map(compilerResult.outputFiles, outputFile => outputFile.emittedFileName) + }; - return resolutionInfo; - } + return resolutionInfo; + } - var compilerResult: BatchCompileProjectTestCaseResult; + var compilerResult: BatchCompileProjectTestCaseResult; - it(name + ": " + moduleNameToString(moduleKind) , () => { - // Compile using node - compilerResult = batchCompilerProjectTestCase(moduleKind); - }); - - it('Resolution information of (' + moduleNameToString(moduleKind) + '): ' + testCaseFileName, () => { - Harness.Baseline.runBaseline('Resolution information of (' + moduleNameToString(compilerResult.moduleKind) + '): ' + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + '.json', () => { - return JSON.stringify(getCompilerResolutionInfo(), undefined, " "); + it(name + ": " + moduleNameToString(moduleKind) , () => { + // Compile using node + compilerResult = batchCompilerProjectTestCase(moduleKind); }); - }); - - it('Errors for (' + moduleNameToString(moduleKind) + '): ' + testCaseFileName, () => { - if (compilerResult.errors.length) { - Harness.Baseline.runBaseline('Errors for (' + moduleNameToString(compilerResult.moduleKind) + '): ' + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + '.errors.txt', () => { - return getErrorsBaseline(compilerResult); + it('Resolution information of (' + moduleNameToString(moduleKind) + '): ' + testCaseFileName, () => { + Harness.Baseline.runBaseline('Resolution information of (' + moduleNameToString(compilerResult.moduleKind) + '): ' + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + '.json', () => { + return JSON.stringify(getCompilerResolutionInfo(), undefined, " "); }); - } - }); + }); - it('Baseline of emitted result (' + moduleNameToString(moduleKind) + '): ' + testCaseFileName, () => { - if (testCase.baselineCheck) { - ts.forEach(compilerResult.outputFiles, outputFile => { - - Harness.Baseline.runBaseline('Baseline of emitted result (' + moduleNameToString(compilerResult.moduleKind) + '): ' + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + outputFile.fileName, () => { - try { - return ts.sys.readFile(getProjectOutputFolder(outputFile.fileName, compilerResult.moduleKind)); - } - catch (e) { - return undefined; - } - }); - }); - } - }); - - - it('SourceMapRecord for (' + moduleNameToString(moduleKind) + '): ' + testCaseFileName, () => { - if (compilerResult.sourceMapData) { - Harness.Baseline.runBaseline('SourceMapRecord for (' + moduleNameToString(compilerResult.moduleKind) + '): ' + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + '.sourcemap.txt', () => { - return Harness.SourceMapRecoder.getSourceMapRecord(compilerResult.sourceMapData, compilerResult.program, - ts.filter(compilerResult.outputFiles, outputFile => Harness.Compiler.isJS(outputFile.emittedFileName))); - }); - } - }); - - // Verify that all the generated .d.ts files compile - - it('Errors in generated Dts files for (' + moduleNameToString(moduleKind) + '): ' + testCaseFileName, () => { - if (!compilerResult.errors.length && testCase.declaration) { - var dTsCompileResult = compileCompileDTsFiles(compilerResult); - if (dTsCompileResult.errors.length) { - Harness.Baseline.runBaseline('Errors in generated Dts files for (' + moduleNameToString(compilerResult.moduleKind) + '): ' + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + '.dts.errors.txt', () => { - return getErrorsBaseline(dTsCompileResult); + it('Errors for (' + moduleNameToString(moduleKind) + '): ' + testCaseFileName, () => { + if (compilerResult.errors.length) { + Harness.Baseline.runBaseline('Errors for (' + moduleNameToString(compilerResult.moduleKind) + '): ' + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + '.errors.txt', () => { + return getErrorsBaseline(compilerResult); }); } - } - }); + }); + + + it('Baseline of emitted result (' + moduleNameToString(moduleKind) + '): ' + testCaseFileName, () => { + if (testCase.baselineCheck) { + ts.forEach(compilerResult.outputFiles, outputFile => { + + Harness.Baseline.runBaseline('Baseline of emitted result (' + moduleNameToString(compilerResult.moduleKind) + '): ' + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + outputFile.fileName, () => { + try { + return ts.sys.readFile(getProjectOutputFolder(outputFile.fileName, compilerResult.moduleKind)); + } + catch (e) { + return undefined; + } + }); + }); + } + }); + + + it('SourceMapRecord for (' + moduleNameToString(moduleKind) + '): ' + testCaseFileName, () => { + if (compilerResult.sourceMapData) { + Harness.Baseline.runBaseline('SourceMapRecord for (' + moduleNameToString(compilerResult.moduleKind) + '): ' + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + '.sourcemap.txt', () => { + return Harness.SourceMapRecoder.getSourceMapRecord(compilerResult.sourceMapData, compilerResult.program, + ts.filter(compilerResult.outputFiles, outputFile => Harness.Compiler.isJS(outputFile.emittedFileName))); + }); + } + }); + + // Verify that all the generated .d.ts files compile + + it('Errors in generated Dts files for (' + moduleNameToString(moduleKind) + '): ' + testCaseFileName, () => { + if (!compilerResult.errors.length && testCase.declaration) { + var dTsCompileResult = compileCompileDTsFiles(compilerResult); + if (dTsCompileResult.errors.length) { + Harness.Baseline.runBaseline('Errors in generated Dts files for (' + moduleNameToString(compilerResult.moduleKind) + '): ' + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + '.dts.errors.txt', () => { + return getErrorsBaseline(dTsCompileResult); + }); + } + } + }); + after(() => { + compilerResult = undefined; + }); + } + + verifyCompilerResults(ts.ModuleKind.CommonJS); + verifyCompilerResults(ts.ModuleKind.AMD); + after(() => { - compilerResult = undefined; + // Mocha holds onto the closure environment of the describe callback even after the test is done. + // Therefore we have to clean out large objects after the test is done. + testCase = undefined; + testFileText = undefined; + testCaseJustName = undefined; }); - } - - verifyCompilerResults(ts.ModuleKind.CommonJS); - verifyCompilerResults(ts.ModuleKind.AMD); - - after(() => { - // Mocha holds onto the closure environment of the describe callback even after the test is done. - // Therefore we have to clean out large objects after the test is done. - testCase = undefined; - testFileText = undefined; - testCaseJustName = undefined; }); }); } -} \ No newline at end of file +} From 123e02974ed79a4e16b83d7a60c8a23af6ce48d2 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 10 Jul 2015 15:22:32 -0700 Subject: [PATCH 17/78] Newline. --- tests/cases/fourslash/completionListInExportClause01.ts | 1 + tests/cases/fourslash/completionListInImportClause01.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/tests/cases/fourslash/completionListInExportClause01.ts b/tests/cases/fourslash/completionListInExportClause01.ts index 6e6cd6c678b..12726444bd2 100644 --- a/tests/cases/fourslash/completionListInExportClause01.ts +++ b/tests/cases/fourslash/completionListInExportClause01.ts @@ -11,6 +11,7 @@ ////export {foo,/*4*/ from "m1" ////export {bar as /*5*/, /*6*/ from "m1" ////export {foo, bar, baz as b,/*7*/} from "m1" + function verifyCompletionAtMarker(marker: string, showBuilder: boolean, ...completions: string[]) { goTo.marker(marker); if (completions.length) { diff --git a/tests/cases/fourslash/completionListInImportClause01.ts b/tests/cases/fourslash/completionListInImportClause01.ts index 1191216baf1..2b679ffe550 100644 --- a/tests/cases/fourslash/completionListInImportClause01.ts +++ b/tests/cases/fourslash/completionListInImportClause01.ts @@ -11,6 +11,7 @@ ////import {foo,/*4*/ from "m1" ////import {bar as /*5*/, /*6*/ from "m1" ////import {foo, bar, baz as b,/*7*/} from "m1" + function verifyCompletionAtMarker(marker: string, showBuilder: boolean, ...completions: string[]) { goTo.marker(marker); if (completions.length) { From a309b1dd6705fe7deb2e774af2f43a3396cd9fef Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 10 Jul 2015 15:38:06 -0700 Subject: [PATCH 18/78] Handle export declarations with module specifiers as well. --- src/services/services.ts | 99 +++++++++++++++++++++------------------- 1 file changed, 53 insertions(+), 46 deletions(-) diff --git a/src/services/services.ts b/src/services/services.ts index 3f656fe75ff..b311898f38d 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -3014,17 +3014,17 @@ namespace ts { function tryGetGlobalSymbols(): boolean { let objectLikeContainer: ObjectLiteralExpression | BindingPattern; - let importClause: ImportClause; + let namedImportsOrExports: NamedImportsOrExports; let jsxContainer: JsxOpeningLikeElement; if (objectLikeContainer = tryGetObjectLikeCompletionContainer(contextToken)) { return tryGetObjectLikeCompletionSymbols(objectLikeContainer); } - if (importClause = getAncestor(contextToken, SyntaxKind.ImportClause)) { + if (namedImportsOrExports = tryGetNamedImportsOrExportsForCompletion(contextToken)) { // cursor is in an import clause // try to show exported member for imported module - return tryGetImportClauseCompletionSymbols(importClause); + return tryGetImportOrExportClauseCompletionSymbols(namedImportsOrExports); } if (jsxContainer = tryGetContainingJsxElement(contextToken)) { @@ -3109,18 +3109,6 @@ namespace ts { return result; } - function shouldShowCompletionsInImportsClause(node: Node): boolean { - if (node) { - // import {| - // import {a,| - if (node.kind === SyntaxKind.OpenBraceToken || node.kind === SyntaxKind.CommaToken) { - return node.parent.kind === SyntaxKind.NamedImports; - } - } - - return false; - } - function isNewIdentifierDefinitionLocation(previousToken: Node): boolean { if (previousToken) { let containingNodeKind = previousToken.parent.kind; @@ -3252,38 +3240,44 @@ namespace ts { } /** - * Aggregates relevant symbols for completion in import clauses; for instance, + * Aggregates relevant symbols for completion in import clauses and export clauses + * whose declarations have a module specifier; for instance, symbols will be aggregated for * - * import { $ } from "moduleName"; + * import { | } from "moduleName"; + * export { a as foo, | } from "moduleName"; + * + * but not for + * + * export { | }; * * Relevant symbols are stored in the captured 'symbols' variable. * * @returns true if 'symbols' was successfully populated; false otherwise. */ - function tryGetImportClauseCompletionSymbols(importClause: ImportClause): boolean { + function tryGetImportOrExportClauseCompletionSymbols(namedImportsOrExports: NamedImportsOrExports): boolean { // cursor is in import clause // try to show exported member for imported module - if (shouldShowCompletionsInImportsClause(contextToken)) { - isMemberCompletion = true; - isNewIdentifierLocation = false; + isMemberCompletion = true; + isNewIdentifierLocation = false; - let importDeclaration = importClause.parent; - Debug.assert(importDeclaration !== undefined && importDeclaration.kind === SyntaxKind.ImportDeclaration); + let declarationKind = namedImportsOrExports.kind === SyntaxKind.NamedImports ? + SyntaxKind.ImportDeclaration : + SyntaxKind.ExportDeclaration; + let importOrExportDeclaration = getAncestor(namedImportsOrExports, declarationKind); + let moduleSpecifier = importOrExportDeclaration.moduleSpecifier; - let exports: Symbol[]; - let moduleSpecifierSymbol = typeChecker.getSymbolAtLocation(importDeclaration.moduleSpecifier); - if (moduleSpecifierSymbol) { - exports = typeChecker.getExportsOfModule(moduleSpecifierSymbol); - } - - //let exports = typeInfoResolver.getExportsOfImportDeclaration(importDeclaration); - symbols = exports ? filterModuleExports(exports, importDeclaration) : emptyArray; + if (!moduleSpecifier) { + return false; } - else { - isMemberCompletion = false; - isNewIdentifierLocation = true; + + let exports: Symbol[]; + let moduleSpecifierSymbol = typeChecker.getSymbolAtLocation(importOrExportDeclaration.moduleSpecifier); + if (moduleSpecifierSymbol) { + exports = typeChecker.getExportsOfModule(moduleSpecifierSymbol); } + symbols = exports ? filterModuleExports(exports, namedImportsOrExports) : emptyArray; + return true; } @@ -3307,6 +3301,26 @@ namespace ts { return undefined; } + /** + * Returns the containing list of named imports or exports of a context token, + * on the condition that one exists and that the context implies completion should be given. + */ + function tryGetNamedImportsOrExportsForCompletion(contextToken: Node): NamedImportsOrExports { + if (contextToken) { + switch (contextToken.kind) { + case SyntaxKind.OpenBraceToken: // import { | + case SyntaxKind.CommaToken: // import { a as 0, | + switch (contextToken.parent.kind) { + case SyntaxKind.NamedImports: + case SyntaxKind.NamedExports: + return contextToken.parent; + } + } + } + + return undefined; + } + function tryGetContainingJsxElement(contextToken: Node): JsxOpeningLikeElement { if (contextToken) { let parent = contextToken.parent; @@ -3452,25 +3466,18 @@ namespace ts { return false; } - function filterModuleExports(exports: Symbol[], importDeclaration: ImportDeclaration): Symbol[] { + function filterModuleExports(exports: Symbol[], namedImportsOrExports: NamedImportsOrExports): Symbol[] { let exisingImports: Map = {}; - if (!importDeclaration.importClause) { - return exports; - } - - if (importDeclaration.importClause.namedBindings && - importDeclaration.importClause.namedBindings.kind === SyntaxKind.NamedImports) { - - forEach((importDeclaration.importClause.namedBindings).elements, el => { - let name = el.propertyName || el.name; - exisingImports[name.text] = true; - }); + for (let element of namedImportsOrExports.elements) { + let name = element.propertyName || element.name; + exisingImports[name.text] = true; } if (isEmpty(exisingImports)) { return exports; } + return filter(exports, e => !lookUp(exisingImports, e.name)); } From 7a0b224ba5b066bf89402a0b86c1e8ebf2160e13 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 10 Jul 2015 16:20:12 -0700 Subject: [PATCH 19/78] Added tests. --- ...ationWithModuleSpecifierNameOnNextLine1.ts | 20 +++++++++++++++++++ .../cases/compiler/unclosedExportClause01.ts | 16 +++++++++++++++ .../cases/compiler/unclosedExportClause02.ts | 20 +++++++++++++++++++ 3 files changed, 56 insertions(+) create mode 100644 tests/cases/compiler/exportDeclarationWithModuleSpecifierNameOnNextLine1.ts create mode 100644 tests/cases/compiler/unclosedExportClause01.ts create mode 100644 tests/cases/compiler/unclosedExportClause02.ts diff --git a/tests/cases/compiler/exportDeclarationWithModuleSpecifierNameOnNextLine1.ts b/tests/cases/compiler/exportDeclarationWithModuleSpecifierNameOnNextLine1.ts new file mode 100644 index 00000000000..ea3f55db16b --- /dev/null +++ b/tests/cases/compiler/exportDeclarationWithModuleSpecifierNameOnNextLine1.ts @@ -0,0 +1,20 @@ +// @module: commonjs + +// @filename: t1.ts +export var x = "x"; + +// @filename: t2.ts +export { x } from + "./t1"; + +// @filename: t3.ts +export { } from + "./t1"; + +// @filename: t4.ts +export { x as a } from + "./t1"; + +// @filename: t5.ts +export { x as a, } from + "./t1"; \ No newline at end of file diff --git a/tests/cases/compiler/unclosedExportClause01.ts b/tests/cases/compiler/unclosedExportClause01.ts new file mode 100644 index 00000000000..3bcbc713d61 --- /dev/null +++ b/tests/cases/compiler/unclosedExportClause01.ts @@ -0,0 +1,16 @@ +// @module: commonjs + +// @filename: t1.ts +export var x = "x"; + +// @filename: t2.ts +export { x, from "./t1" + +// @filename: t3.ts +export { from "./t1" + +// @filename: t4.ts +export { x as a from "./t1" + +// @filename: t5.ts +export { x as a, from "./t1" \ No newline at end of file diff --git a/tests/cases/compiler/unclosedExportClause02.ts b/tests/cases/compiler/unclosedExportClause02.ts new file mode 100644 index 00000000000..45dcb65a4cb --- /dev/null +++ b/tests/cases/compiler/unclosedExportClause02.ts @@ -0,0 +1,20 @@ +// @module: commonjs + +// @filename: t1.ts +export var x = "x"; + +// @filename: t2.ts +export { x, from + "./t1"; + +// @filename: t3.ts +export { from + "./t1"; + +// @filename: t4.ts +export { x as a from + "./t1"; + +// @filename: t5.ts +export { x as a, from + "./t1"; \ No newline at end of file From 120d0d11a0c2f2d2ec474461d945477a3ed041ae Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 10 Jul 2015 16:20:25 -0700 Subject: [PATCH 20/78] Accepted baselines. --- ...ationWithModuleSpecifierNameOnNextLine1.js | 34 +++++++++++ ...WithModuleSpecifierNameOnNextLine1.symbols | 28 +++++++++ ...onWithModuleSpecifierNameOnNextLine1.types | 29 ++++++++++ .../unclosedExportClause01.errors.txt | 53 +++++++++++++++++ .../reference/unclosedExportClause01.js | 28 +++++++++ .../unclosedExportClause02.errors.txt | 57 +++++++++++++++++++ .../reference/unclosedExportClause02.js | 32 +++++++++++ 7 files changed, 261 insertions(+) create mode 100644 tests/baselines/reference/exportDeclarationWithModuleSpecifierNameOnNextLine1.js create mode 100644 tests/baselines/reference/exportDeclarationWithModuleSpecifierNameOnNextLine1.symbols create mode 100644 tests/baselines/reference/exportDeclarationWithModuleSpecifierNameOnNextLine1.types create mode 100644 tests/baselines/reference/unclosedExportClause01.errors.txt create mode 100644 tests/baselines/reference/unclosedExportClause01.js create mode 100644 tests/baselines/reference/unclosedExportClause02.errors.txt create mode 100644 tests/baselines/reference/unclosedExportClause02.js diff --git a/tests/baselines/reference/exportDeclarationWithModuleSpecifierNameOnNextLine1.js b/tests/baselines/reference/exportDeclarationWithModuleSpecifierNameOnNextLine1.js new file mode 100644 index 00000000000..a6700fb5e59 --- /dev/null +++ b/tests/baselines/reference/exportDeclarationWithModuleSpecifierNameOnNextLine1.js @@ -0,0 +1,34 @@ +//// [tests/cases/compiler/exportDeclarationWithModuleSpecifierNameOnNextLine1.ts] //// + +//// [t1.ts] + +export var x = "x"; + +//// [t2.ts] +export { x } from + "./t1"; + +//// [t3.ts] +export { } from + "./t1"; + +//// [t4.ts] +export { x as a } from + "./t1"; + +//// [t5.ts] +export { x as a, } from + "./t1"; + +//// [t1.js] +exports.x = "x"; +//// [t2.js] +var t1_1 = require("./t1"); +exports.x = t1_1.x; +//// [t3.js] +//// [t4.js] +var t1_1 = require("./t1"); +exports.a = t1_1.x; +//// [t5.js] +var t1_1 = require("./t1"); +exports.a = t1_1.x; diff --git a/tests/baselines/reference/exportDeclarationWithModuleSpecifierNameOnNextLine1.symbols b/tests/baselines/reference/exportDeclarationWithModuleSpecifierNameOnNextLine1.symbols new file mode 100644 index 00000000000..331766f7712 --- /dev/null +++ b/tests/baselines/reference/exportDeclarationWithModuleSpecifierNameOnNextLine1.symbols @@ -0,0 +1,28 @@ +=== tests/cases/compiler/t1.ts === + +export var x = "x"; +>x : Symbol(x, Decl(t1.ts, 1, 10)) + +=== tests/cases/compiler/t2.ts === +export { x } from +>x : Symbol(x, Decl(t2.ts, 0, 8)) + + "./t1"; + +=== tests/cases/compiler/t3.ts === +export { } from +No type information for this code. "./t1"; +No type information for this code. +No type information for this code.=== tests/cases/compiler/t4.ts === +export { x as a } from +>x : Symbol(a, Decl(t4.ts, 0, 8)) +>a : Symbol(a, Decl(t4.ts, 0, 8)) + + "./t1"; + +=== tests/cases/compiler/t5.ts === +export { x as a, } from +>x : Symbol(a, Decl(t5.ts, 0, 8)) +>a : Symbol(a, Decl(t5.ts, 0, 8)) + + "./t1"; diff --git a/tests/baselines/reference/exportDeclarationWithModuleSpecifierNameOnNextLine1.types b/tests/baselines/reference/exportDeclarationWithModuleSpecifierNameOnNextLine1.types new file mode 100644 index 00000000000..1ad841fe947 --- /dev/null +++ b/tests/baselines/reference/exportDeclarationWithModuleSpecifierNameOnNextLine1.types @@ -0,0 +1,29 @@ +=== tests/cases/compiler/t1.ts === + +export var x = "x"; +>x : string +>"x" : string + +=== tests/cases/compiler/t2.ts === +export { x } from +>x : string + + "./t1"; + +=== tests/cases/compiler/t3.ts === +export { } from +No type information for this code. "./t1"; +No type information for this code. +No type information for this code.=== tests/cases/compiler/t4.ts === +export { x as a } from +>x : string +>a : string + + "./t1"; + +=== tests/cases/compiler/t5.ts === +export { x as a, } from +>x : string +>a : string + + "./t1"; diff --git a/tests/baselines/reference/unclosedExportClause01.errors.txt b/tests/baselines/reference/unclosedExportClause01.errors.txt new file mode 100644 index 00000000000..22c38f4af8e --- /dev/null +++ b/tests/baselines/reference/unclosedExportClause01.errors.txt @@ -0,0 +1,53 @@ +tests/cases/compiler/t2.ts(1,10): error TS2304: Cannot find name 'x'. +tests/cases/compiler/t2.ts(1,13): error TS2304: Cannot find name 'from'. +tests/cases/compiler/t2.ts(1,18): error TS1005: ',' expected. +tests/cases/compiler/t3.ts(1,10): error TS2304: Cannot find name 'from'. +tests/cases/compiler/t3.ts(1,15): error TS1005: ',' expected. +tests/cases/compiler/t4.ts(1,10): error TS2304: Cannot find name 'x'. +tests/cases/compiler/t4.ts(1,17): error TS1005: ',' expected. +tests/cases/compiler/t4.ts(1,17): error TS2304: Cannot find name 'from'. +tests/cases/compiler/t4.ts(1,22): error TS1005: ',' expected. +tests/cases/compiler/t5.ts(1,10): error TS2304: Cannot find name 'x'. +tests/cases/compiler/t5.ts(1,18): error TS2304: Cannot find name 'from'. +tests/cases/compiler/t5.ts(1,23): error TS1005: ',' expected. + + +==== tests/cases/compiler/t1.ts (0 errors) ==== + + export var x = "x"; + +==== tests/cases/compiler/t2.ts (3 errors) ==== + export { x, from "./t1" + ~ +!!! error TS2304: Cannot find name 'x'. + ~~~~ +!!! error TS2304: Cannot find name 'from'. + ~~~~~~ +!!! error TS1005: ',' expected. + +==== tests/cases/compiler/t3.ts (2 errors) ==== + export { from "./t1" + ~~~~ +!!! error TS2304: Cannot find name 'from'. + ~~~~~~ +!!! error TS1005: ',' expected. + +==== tests/cases/compiler/t4.ts (4 errors) ==== + export { x as a from "./t1" + ~ +!!! error TS2304: Cannot find name 'x'. + ~~~~ +!!! error TS1005: ',' expected. + ~~~~ +!!! error TS2304: Cannot find name 'from'. + ~~~~~~ +!!! error TS1005: ',' expected. + +==== tests/cases/compiler/t5.ts (3 errors) ==== + export { x as a, from "./t1" + ~ +!!! error TS2304: Cannot find name 'x'. + ~~~~ +!!! error TS2304: Cannot find name 'from'. + ~~~~~~ +!!! error TS1005: ',' expected. \ No newline at end of file diff --git a/tests/baselines/reference/unclosedExportClause01.js b/tests/baselines/reference/unclosedExportClause01.js new file mode 100644 index 00000000000..2316fca36ec --- /dev/null +++ b/tests/baselines/reference/unclosedExportClause01.js @@ -0,0 +1,28 @@ +//// [tests/cases/compiler/unclosedExportClause01.ts] //// + +//// [t1.ts] + +export var x = "x"; + +//// [t2.ts] +export { x, from "./t1" + +//// [t3.ts] +export { from "./t1" + +//// [t4.ts] +export { x as a from "./t1" + +//// [t5.ts] +export { x as a, from "./t1" + +//// [t1.js] +exports.x = "x"; +//// [t2.js] +"./t1"; +//// [t3.js] +"./t1"; +//// [t4.js] +"./t1"; +//// [t5.js] +"./t1"; diff --git a/tests/baselines/reference/unclosedExportClause02.errors.txt b/tests/baselines/reference/unclosedExportClause02.errors.txt new file mode 100644 index 00000000000..a4809e2c0c3 --- /dev/null +++ b/tests/baselines/reference/unclosedExportClause02.errors.txt @@ -0,0 +1,57 @@ +tests/cases/compiler/t2.ts(1,10): error TS2304: Cannot find name 'x'. +tests/cases/compiler/t2.ts(1,13): error TS2304: Cannot find name 'from'. +tests/cases/compiler/t2.ts(2,5): error TS1005: ',' expected. +tests/cases/compiler/t3.ts(1,10): error TS2304: Cannot find name 'from'. +tests/cases/compiler/t3.ts(2,5): error TS1005: ',' expected. +tests/cases/compiler/t4.ts(1,10): error TS2304: Cannot find name 'x'. +tests/cases/compiler/t4.ts(1,17): error TS1005: ',' expected. +tests/cases/compiler/t4.ts(1,17): error TS2304: Cannot find name 'from'. +tests/cases/compiler/t4.ts(2,5): error TS1005: ',' expected. +tests/cases/compiler/t5.ts(1,10): error TS2304: Cannot find name 'x'. +tests/cases/compiler/t5.ts(1,18): error TS2304: Cannot find name 'from'. +tests/cases/compiler/t5.ts(2,5): error TS1005: ',' expected. + + +==== tests/cases/compiler/t1.ts (0 errors) ==== + + export var x = "x"; + +==== tests/cases/compiler/t2.ts (3 errors) ==== + export { x, from + ~ +!!! error TS2304: Cannot find name 'x'. + ~~~~ +!!! error TS2304: Cannot find name 'from'. + "./t1"; + ~~~~~~ +!!! error TS1005: ',' expected. + +==== tests/cases/compiler/t3.ts (2 errors) ==== + export { from + ~~~~ +!!! error TS2304: Cannot find name 'from'. + "./t1"; + ~~~~~~ +!!! error TS1005: ',' expected. + +==== tests/cases/compiler/t4.ts (4 errors) ==== + export { x as a from + ~ +!!! error TS2304: Cannot find name 'x'. + ~~~~ +!!! error TS1005: ',' expected. + ~~~~ +!!! error TS2304: Cannot find name 'from'. + "./t1"; + ~~~~~~ +!!! error TS1005: ',' expected. + +==== tests/cases/compiler/t5.ts (3 errors) ==== + export { x as a, from + ~ +!!! error TS2304: Cannot find name 'x'. + ~~~~ +!!! error TS2304: Cannot find name 'from'. + "./t1"; + ~~~~~~ +!!! error TS1005: ',' expected. \ No newline at end of file diff --git a/tests/baselines/reference/unclosedExportClause02.js b/tests/baselines/reference/unclosedExportClause02.js new file mode 100644 index 00000000000..964cc29899c --- /dev/null +++ b/tests/baselines/reference/unclosedExportClause02.js @@ -0,0 +1,32 @@ +//// [tests/cases/compiler/unclosedExportClause02.ts] //// + +//// [t1.ts] + +export var x = "x"; + +//// [t2.ts] +export { x, from + "./t1"; + +//// [t3.ts] +export { from + "./t1"; + +//// [t4.ts] +export { x as a from + "./t1"; + +//// [t5.ts] +export { x as a, from + "./t1"; + +//// [t1.js] +exports.x = "x"; +//// [t2.js] +"./t1"; +//// [t3.js] +"./t1"; +//// [t4.js] +"./t1"; +//// [t5.js] +"./t1"; From 69f93fe116b95acd0e4072fc9b2ebe0c17c0ee1f Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 10 Jul 2015 16:27:40 -0700 Subject: [PATCH 21/78] Added error recovery for missing 'from' keyword in an export declaration. --- src/compiler/parser.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 3635a88b608..c01e1036a0d 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -4345,6 +4345,10 @@ namespace ts { } } + function nextTokenIsStringLiteralOnSameLine() { + return !scanner.hasPrecedingLineBreak() && token === SyntaxKind.StringLiteral; + } + function nextTokenIsIdentifierOrStringLiteralOnSameLine() { nextToken(); return !scanner.hasPrecedingLineBreak() && (isIdentifier() || token === SyntaxKind.StringLiteral); @@ -5135,7 +5139,12 @@ namespace ts { } else { node.exportClause = parseNamedImportsOrExports(SyntaxKind.NamedExports); - if (parseOptional(SyntaxKind.FromKeyword)) { + + // It is not uncommon to accidentally omit the 'from' keyword. Additionally, in editing scenarios, + // the 'from' keyword be parsed as a named export when the export clause is unterminated (i.e. `export { from "moduleName";`) + // If we don't have a 'from' keyword, see if we have a string literal such that ASI won't take effect. + if (token === SyntaxKind.FromKeyword || lookAhead(nextTokenIsStringLiteralOnSameLine)) { + parseExpected(SyntaxKind.FromKeyword) node.moduleSpecifier = parseModuleSpecifier(); } } From 5c03b8ef122e374a3f4547149a1dd0961cf77852 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 10 Jul 2015 16:27:55 -0700 Subject: [PATCH 22/78] Updated baselines. --- .../unclosedExportClause01.errors.txt | 31 +++++++------------ .../reference/unclosedExportClause01.js | 10 +++--- 2 files changed, 17 insertions(+), 24 deletions(-) diff --git a/tests/baselines/reference/unclosedExportClause01.errors.txt b/tests/baselines/reference/unclosedExportClause01.errors.txt index 22c38f4af8e..6590bc5cfed 100644 --- a/tests/baselines/reference/unclosedExportClause01.errors.txt +++ b/tests/baselines/reference/unclosedExportClause01.errors.txt @@ -1,14 +1,11 @@ -tests/cases/compiler/t2.ts(1,10): error TS2304: Cannot find name 'x'. -tests/cases/compiler/t2.ts(1,13): error TS2304: Cannot find name 'from'. +tests/cases/compiler/t2.ts(1,13): error TS2305: Module '"tests/cases/compiler/t1"' has no exported member 'from'. tests/cases/compiler/t2.ts(1,18): error TS1005: ',' expected. -tests/cases/compiler/t3.ts(1,10): error TS2304: Cannot find name 'from'. +tests/cases/compiler/t3.ts(1,10): error TS2305: Module '"tests/cases/compiler/t1"' has no exported member 'from'. tests/cases/compiler/t3.ts(1,15): error TS1005: ',' expected. -tests/cases/compiler/t4.ts(1,10): error TS2304: Cannot find name 'x'. tests/cases/compiler/t4.ts(1,17): error TS1005: ',' expected. -tests/cases/compiler/t4.ts(1,17): error TS2304: Cannot find name 'from'. +tests/cases/compiler/t4.ts(1,17): error TS2305: Module '"tests/cases/compiler/t1"' has no exported member 'from'. tests/cases/compiler/t4.ts(1,22): error TS1005: ',' expected. -tests/cases/compiler/t5.ts(1,10): error TS2304: Cannot find name 'x'. -tests/cases/compiler/t5.ts(1,18): error TS2304: Cannot find name 'from'. +tests/cases/compiler/t5.ts(1,18): error TS2305: Module '"tests/cases/compiler/t1"' has no exported member 'from'. tests/cases/compiler/t5.ts(1,23): error TS1005: ',' expected. @@ -16,38 +13,32 @@ tests/cases/compiler/t5.ts(1,23): error TS1005: ',' expected. export var x = "x"; -==== tests/cases/compiler/t2.ts (3 errors) ==== +==== tests/cases/compiler/t2.ts (2 errors) ==== export { x, from "./t1" - ~ -!!! error TS2304: Cannot find name 'x'. ~~~~ -!!! error TS2304: Cannot find name 'from'. +!!! error TS2305: Module '"tests/cases/compiler/t1"' has no exported member 'from'. ~~~~~~ !!! error TS1005: ',' expected. ==== tests/cases/compiler/t3.ts (2 errors) ==== export { from "./t1" ~~~~ -!!! error TS2304: Cannot find name 'from'. +!!! error TS2305: Module '"tests/cases/compiler/t1"' has no exported member 'from'. ~~~~~~ !!! error TS1005: ',' expected. -==== tests/cases/compiler/t4.ts (4 errors) ==== +==== tests/cases/compiler/t4.ts (3 errors) ==== export { x as a from "./t1" - ~ -!!! error TS2304: Cannot find name 'x'. ~~~~ !!! error TS1005: ',' expected. ~~~~ -!!! error TS2304: Cannot find name 'from'. +!!! error TS2305: Module '"tests/cases/compiler/t1"' has no exported member 'from'. ~~~~~~ !!! error TS1005: ',' expected. -==== tests/cases/compiler/t5.ts (3 errors) ==== +==== tests/cases/compiler/t5.ts (2 errors) ==== export { x as a, from "./t1" - ~ -!!! error TS2304: Cannot find name 'x'. ~~~~ -!!! error TS2304: Cannot find name 'from'. +!!! error TS2305: Module '"tests/cases/compiler/t1"' has no exported member 'from'. ~~~~~~ !!! error TS1005: ',' expected. \ No newline at end of file diff --git a/tests/baselines/reference/unclosedExportClause01.js b/tests/baselines/reference/unclosedExportClause01.js index 2316fca36ec..a683f8d987d 100644 --- a/tests/baselines/reference/unclosedExportClause01.js +++ b/tests/baselines/reference/unclosedExportClause01.js @@ -19,10 +19,12 @@ export { x as a, from "./t1" //// [t1.js] exports.x = "x"; //// [t2.js] -"./t1"; +var t1_1 = require("./t1"); +exports.x = t1_1.x; //// [t3.js] -"./t1"; //// [t4.js] -"./t1"; +var t1_1 = require("./t1"); +exports.a = t1_1.x; //// [t5.js] -"./t1"; +var t1_1 = require("./t1"); +exports.a = t1_1.x; From afec273e8746e7b34e93ff0febf5fb2ebf762403 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 10 Jul 2015 16:49:02 -0700 Subject: [PATCH 23/78] Clarify function name. --- src/services/services.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/services/services.ts b/src/services/services.ts index b311898f38d..6e728784a54 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -3103,7 +3103,7 @@ namespace ts { function isCompletionListBlocker(contextToken: Node): boolean { let start = new Date().getTime(); let result = isInStringOrRegularExpressionOrTemplateLiteral(contextToken) || - isIdentifierDefinitionLocation(contextToken) || + isSolelyIdentifierDefinitionLocation(contextToken) || isDotOfNumericLiteral(contextToken); log("getCompletionsAtPosition: isCompletionListBlocker: " + (new Date().getTime() - start)); return result; @@ -3368,7 +3368,10 @@ namespace ts { return false; } - function isIdentifierDefinitionLocation(contextToken: Node): boolean { + /** + * @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; switch (contextToken.kind) { case SyntaxKind.CommaToken: From d394f25763f1b7e3ce56e62f9d5d5f92d04ea3b4 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 10 Jul 2015 17:20:47 -0700 Subject: [PATCH 24/78] Added test for completion in namespace imports. --- .../completionListInNamespaceImportName01.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 tests/cases/fourslash/completionListInNamespaceImportName01.ts diff --git a/tests/cases/fourslash/completionListInNamespaceImportName01.ts b/tests/cases/fourslash/completionListInNamespaceImportName01.ts new file mode 100644 index 00000000000..ac1c0e13e07 --- /dev/null +++ b/tests/cases/fourslash/completionListInNamespaceImportName01.ts @@ -0,0 +1,11 @@ +/// + +// @Filename: m1.ts +////export var foo: number = 1; + +// @Filename: m2.ts +////import * as /**/ from "m1" + +goTo.marker(); +verify.completionListIsEmpty(); +verify.completionListAllowsNewIdentifier(); \ No newline at end of file From 49af6605953077b97d33838b7511097c90dc3d9c Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 10 Jul 2015 17:23:11 -0700 Subject: [PATCH 25/78] Account for export/import specifier renames and namespace import names in completion. --- src/services/services.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/services/services.ts b/src/services/services.ts index 6e728784a54..bff222f388b 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -3428,6 +3428,11 @@ namespace ts { case SyntaxKind.ProtectedKeyword: return containingNodeKind === SyntaxKind.Parameter; + case SyntaxKind.AsKeyword: + containingNodeKind === SyntaxKind.ImportSpecifier || + containingNodeKind === SyntaxKind.ExportSpecifier || + containingNodeKind === SyntaxKind.NamespaceImport; + case SyntaxKind.ClassKeyword: case SyntaxKind.EnumKeyword: case SyntaxKind.InterfaceKeyword: From 55b39d45f640dfde8329f5369156a13a82d06d74 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 10 Jul 2015 17:33:56 -0700 Subject: [PATCH 26/78] Add analogous export test. --- .../fourslash/completionListInExportClause03.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 tests/cases/fourslash/completionListInExportClause03.ts diff --git a/tests/cases/fourslash/completionListInExportClause03.ts b/tests/cases/fourslash/completionListInExportClause03.ts new file mode 100644 index 00000000000..426c85d02ea --- /dev/null +++ b/tests/cases/fourslash/completionListInExportClause03.ts @@ -0,0 +1,16 @@ +/// + +////declare module "M1" { +//// export var abc: number; +//// export var def: string; +////} +//// +////declare module "M2" { +//// export { abc/**/ } from "M1"; +////} + +// Ensure we don't filter out the current item. +goTo.marker(); +verify.completionListContains("abc"); +verify.completionListContains("def"); +verify.not.completionListAllowsNewIdentifier(); \ No newline at end of file From 616d84e4a09e9cb1ee9869106f66410bc86390f7 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 10 Jul 2015 17:42:33 -0700 Subject: [PATCH 27/78] Fix merge mistake. --- src/services/services.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/services/services.ts b/src/services/services.ts index 1fe2b784a2d..1c27fe500ec 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -3477,10 +3477,6 @@ namespace ts { function filterModuleExports(exports: Symbol[], namedImportsOrExports: NamedImportsOrExports): Symbol[] { let exisingImports: Map = {}; - if (!importDeclaration.importClause) { - return exports; - } - for (let element of namedImportsOrExports.elements) { // If this is the current item we are editing right now, do not filter it out if (element.getStart() <= position && position <= element.getEnd()) { From 48ca1c49c45147443052a9a97d77b735c676d822 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 10 Jul 2015 17:55:04 -0700 Subject: [PATCH 28/78] Fixed conversion from forEach to for-of --- src/services/services.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/services/services.ts b/src/services/services.ts index 1c27fe500ec..6c5deec9cd3 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -3479,8 +3479,8 @@ namespace ts { for (let element of namedImportsOrExports.elements) { // If this is the current item we are editing right now, do not filter it out - if (element.getStart() <= position && position <= element.getEnd()) { - return; + if (element.getStart() <= position && poition <= element.getEnd()) { + continue; } let name = element.propertyName || element.name; From a6d17d82c2befda41ea742333759dbffa256d88b Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 10 Jul 2015 17:58:49 -0700 Subject: [PATCH 29/78] Pick your poition. --- 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 6c5deec9cd3..dff8e46e2b5 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -3479,7 +3479,7 @@ namespace ts { for (let element of namedImportsOrExports.elements) { // If this is the current item we are editing right now, do not filter it out - if (element.getStart() <= position && poition <= element.getEnd()) { + if (element.getStart() <= position && position <= element.getEnd()) { continue; } From 2f15958d32fa51d46f87dc155892770d27abb0fe Mon Sep 17 00:00:00 2001 From: Dan Quirk Date: Fri, 10 Jul 2015 18:08:19 -0700 Subject: [PATCH 30/78] Use new mocha-fivemat-progress-reporter by default instead of dot reporter --- Jakefile.js | 2 +- package.json | 3 ++- src/harness/compilerRunner.ts | 12 +++++++----- src/harness/fourslashRunner.ts | 2 +- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/Jakefile.js b/Jakefile.js index 517f5e862d5..1c6dfa25e7b 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -562,7 +562,7 @@ task("runtests", ["tests", builtLocalDirectory], function() { colors = process.env.colors || process.env.color colors = colors ? ' --no-colors ' : ' --colors '; tests = tests ? ' -g ' + tests : ''; - reporter = process.env.reporter || process.env.r || 'dot'; + reporter = process.env.reporter || process.env.r || 'mocha-fivemat-progress-reporter'; // timeout normally isn't necessary but Travis-CI has been timing out on compiler baselines occasionally // default timeout is 2sec which really should be enough, but maybe we just need a small amount longer var cmd = host + " -R " + reporter + tests + colors + ' -t ' + testTimeout + ' ' + run; diff --git a/package.json b/package.json index d6a8f538b78..9349efbd0ac 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,8 @@ "mocha": "latest", "chai": "latest", "browserify": "latest", - "istanbul": "latest" + "istanbul": "latest", + "mocha-fivemat-progress-reporter": "latest" }, "scripts": { "test": "jake runtests" diff --git a/src/harness/compilerRunner.ts b/src/harness/compilerRunner.ts index 1c8dccc6173..39d4b053956 100644 --- a/src/harness/compilerRunner.ts +++ b/src/harness/compilerRunner.ts @@ -10,6 +10,7 @@ const enum CompilerTestType { class CompilerBaselineRunner extends RunnerBase { private basePath = 'tests/cases'; + private testSuiteName: string; private errors: boolean; private emit: boolean; private decl: boolean; @@ -24,16 +25,17 @@ class CompilerBaselineRunner extends RunnerBase { this.decl = true; this.output = true; if (testType === CompilerTestType.Conformance) { - this.basePath += '/conformance'; + this.testSuiteName = 'conformance'; } else if (testType === CompilerTestType.Regressions) { - this.basePath += '/compiler'; + this.testSuiteName = 'compiler'; } else if (testType === CompilerTestType.Test262) { - this.basePath += '/test262'; + this.testSuiteName = 'test262'; } else { - this.basePath += '/compiler'; // default to this for historical reasons + this.testSuiteName = 'compiler'; // default to this for historical reasons } + this.basePath += '/' + this.testSuiteName; } public checkTestCodeOutput(fileName: string) { @@ -384,7 +386,7 @@ class CompilerBaselineRunner extends RunnerBase { } public initializeTests() { - describe('Compiler tests', () => { + describe(this.testSuiteName + ' tests', () => { describe("Setup compiler for compiler baselines", () => { var harnessCompiler = Harness.Compiler.getCompiler(); this.parseOptions(); diff --git a/src/harness/fourslashRunner.ts b/src/harness/fourslashRunner.ts index 9287f7361a5..37d55974612 100644 --- a/src/harness/fourslashRunner.ts +++ b/src/harness/fourslashRunner.ts @@ -35,7 +35,7 @@ class FourSlashRunner extends RunnerBase { this.tests = this.enumerateFiles(this.basePath, /\.ts/i, { recursive: false }); } - describe('Fourslash tests', () => { + describe(this.testSuiteName + ' tests', () => { this.tests.forEach((fn: string) => { describe(fn, () => { fn = ts.normalizeSlashes(fn); From 59be264be521e154c4a97fa1d5365083c1f00c19 Mon Sep 17 00:00:00 2001 From: Jason Freeman Date: Fri, 10 Jul 2015 18:16:51 -0700 Subject: [PATCH 31/78] Take the apparent type of the source in type argument inference --- src/compiler/checker.ts | 47 ++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index dd5e42e0f4c..ae44585fc5b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5508,30 +5508,33 @@ namespace ts { inferFromTypes(sourceType, target); } } - else if (source.flags & TypeFlags.ObjectType && (target.flags & (TypeFlags.Reference | TypeFlags.Tuple) || - (target.flags & TypeFlags.Anonymous) && target.symbol && target.symbol.flags & (SymbolFlags.Method | SymbolFlags.TypeLiteral | SymbolFlags.Class))) { - // If source is an object type, and target is a type reference, a tuple type, the type of a method, or a type literal, infer from members - if (isInProcess(source, target)) { - return; - } - if (isDeeplyNestedGeneric(source, sourceStack, depth) && isDeeplyNestedGeneric(target, targetStack, depth)) { - return; - } + else { + source = getApparentType(source); + if (source.flags & TypeFlags.ObjectType && (target.flags & (TypeFlags.Reference | TypeFlags.Tuple) || + (target.flags & TypeFlags.Anonymous) && target.symbol && target.symbol.flags & (SymbolFlags.Method | SymbolFlags.TypeLiteral | SymbolFlags.Class))) { + // If source is an object type, and target is a type reference, a tuple type, the type of a method, or a type literal, infer from members + if (isInProcess(source, target)) { + return; + } + if (isDeeplyNestedGeneric(source, sourceStack, depth) && isDeeplyNestedGeneric(target, targetStack, depth)) { + return; + } - if (depth === 0) { - sourceStack = []; - targetStack = []; + if (depth === 0) { + sourceStack = []; + targetStack = []; + } + sourceStack[depth] = source; + targetStack[depth] = target; + depth++; + inferFromProperties(source, target); + inferFromSignatures(source, target, SignatureKind.Call); + inferFromSignatures(source, target, SignatureKind.Construct); + inferFromIndexTypes(source, target, IndexKind.String, IndexKind.String); + inferFromIndexTypes(source, target, IndexKind.Number, IndexKind.Number); + inferFromIndexTypes(source, target, IndexKind.String, IndexKind.Number); + depth--; } - sourceStack[depth] = source; - targetStack[depth] = target; - depth++; - inferFromProperties(source, target); - inferFromSignatures(source, target, SignatureKind.Call); - inferFromSignatures(source, target, SignatureKind.Construct); - inferFromIndexTypes(source, target, IndexKind.String, IndexKind.String); - inferFromIndexTypes(source, target, IndexKind.Number, IndexKind.Number); - inferFromIndexTypes(source, target, IndexKind.String, IndexKind.Number); - depth--; } } From 72ef479ddd98731f3423f2acfd0db83103317148 Mon Sep 17 00:00:00 2001 From: Jason Freeman Date: Fri, 10 Jul 2015 18:16:59 -0700 Subject: [PATCH 32/78] Add tests --- .../typeArgumentInferenceApparentType1.js | 12 ++++++++ ...typeArgumentInferenceApparentType1.symbols | 16 +++++++++++ .../typeArgumentInferenceApparentType1.types | 18 ++++++++++++ .../typeArgumentInferenceApparentType2.js | 17 +++++++++++ ...typeArgumentInferenceApparentType2.symbols | 27 ++++++++++++++++++ .../typeArgumentInferenceApparentType2.types | 28 +++++++++++++++++++ .../typeArgumentInferenceApparentType1.ts | 6 ++++ .../typeArgumentInferenceApparentType2.ts | 8 ++++++ 8 files changed, 132 insertions(+) create mode 100644 tests/baselines/reference/typeArgumentInferenceApparentType1.js create mode 100644 tests/baselines/reference/typeArgumentInferenceApparentType1.symbols create mode 100644 tests/baselines/reference/typeArgumentInferenceApparentType1.types create mode 100644 tests/baselines/reference/typeArgumentInferenceApparentType2.js create mode 100644 tests/baselines/reference/typeArgumentInferenceApparentType2.symbols create mode 100644 tests/baselines/reference/typeArgumentInferenceApparentType2.types create mode 100644 tests/cases/compiler/typeArgumentInferenceApparentType1.ts create mode 100644 tests/cases/compiler/typeArgumentInferenceApparentType2.ts diff --git a/tests/baselines/reference/typeArgumentInferenceApparentType1.js b/tests/baselines/reference/typeArgumentInferenceApparentType1.js new file mode 100644 index 00000000000..7a4f1ea19f5 --- /dev/null +++ b/tests/baselines/reference/typeArgumentInferenceApparentType1.js @@ -0,0 +1,12 @@ +//// [typeArgumentInferenceApparentType1.ts] +function method(iterable: Iterable): T { + return; +} + +var res: string = method("test"); + +//// [typeArgumentInferenceApparentType1.js] +function method(iterable) { + return; +} +var res = method("test"); diff --git a/tests/baselines/reference/typeArgumentInferenceApparentType1.symbols b/tests/baselines/reference/typeArgumentInferenceApparentType1.symbols new file mode 100644 index 00000000000..abcb8fdfc68 --- /dev/null +++ b/tests/baselines/reference/typeArgumentInferenceApparentType1.symbols @@ -0,0 +1,16 @@ +=== tests/cases/compiler/typeArgumentInferenceApparentType1.ts === +function method(iterable: Iterable): T { +>method : Symbol(method, Decl(typeArgumentInferenceApparentType1.ts, 0, 0)) +>T : Symbol(T, Decl(typeArgumentInferenceApparentType1.ts, 0, 16)) +>iterable : Symbol(iterable, Decl(typeArgumentInferenceApparentType1.ts, 0, 19)) +>Iterable : Symbol(Iterable, Decl(lib.d.ts, 1681, 1)) +>T : Symbol(T, Decl(typeArgumentInferenceApparentType1.ts, 0, 16)) +>T : Symbol(T, Decl(typeArgumentInferenceApparentType1.ts, 0, 16)) + + return; +} + +var res: string = method("test"); +>res : Symbol(res, Decl(typeArgumentInferenceApparentType1.ts, 4, 3)) +>method : Symbol(method, Decl(typeArgumentInferenceApparentType1.ts, 0, 0)) + diff --git a/tests/baselines/reference/typeArgumentInferenceApparentType1.types b/tests/baselines/reference/typeArgumentInferenceApparentType1.types new file mode 100644 index 00000000000..29fd1aeca18 --- /dev/null +++ b/tests/baselines/reference/typeArgumentInferenceApparentType1.types @@ -0,0 +1,18 @@ +=== tests/cases/compiler/typeArgumentInferenceApparentType1.ts === +function method(iterable: Iterable): T { +>method : (iterable: Iterable) => T +>T : T +>iterable : Iterable +>Iterable : Iterable +>T : T +>T : T + + return; +} + +var res: string = method("test"); +>res : string +>method("test") : string +>method : (iterable: Iterable) => T +>"test" : string + diff --git a/tests/baselines/reference/typeArgumentInferenceApparentType2.js b/tests/baselines/reference/typeArgumentInferenceApparentType2.js new file mode 100644 index 00000000000..cf9f3bca00e --- /dev/null +++ b/tests/baselines/reference/typeArgumentInferenceApparentType2.js @@ -0,0 +1,17 @@ +//// [typeArgumentInferenceApparentType2.ts] +function method(iterable: Iterable): T { + function inner>() { + var u: U; + var res: T = method(u); + } + return; +} + +//// [typeArgumentInferenceApparentType2.js] +function method(iterable) { + function inner() { + var u; + var res = method(u); + } + return; +} diff --git a/tests/baselines/reference/typeArgumentInferenceApparentType2.symbols b/tests/baselines/reference/typeArgumentInferenceApparentType2.symbols new file mode 100644 index 00000000000..86cf8e7cdcd --- /dev/null +++ b/tests/baselines/reference/typeArgumentInferenceApparentType2.symbols @@ -0,0 +1,27 @@ +=== tests/cases/compiler/typeArgumentInferenceApparentType2.ts === +function method(iterable: Iterable): T { +>method : Symbol(method, Decl(typeArgumentInferenceApparentType2.ts, 0, 0)) +>T : Symbol(T, Decl(typeArgumentInferenceApparentType2.ts, 0, 16)) +>iterable : Symbol(iterable, Decl(typeArgumentInferenceApparentType2.ts, 0, 19)) +>Iterable : Symbol(Iterable, Decl(lib.d.ts, 1681, 1)) +>T : Symbol(T, Decl(typeArgumentInferenceApparentType2.ts, 0, 16)) +>T : Symbol(T, Decl(typeArgumentInferenceApparentType2.ts, 0, 16)) + + function inner>() { +>inner : Symbol(inner, Decl(typeArgumentInferenceApparentType2.ts, 0, 46)) +>U : Symbol(U, Decl(typeArgumentInferenceApparentType2.ts, 1, 19)) +>Iterable : Symbol(Iterable, Decl(lib.d.ts, 1681, 1)) +>T : Symbol(T, Decl(typeArgumentInferenceApparentType2.ts, 0, 16)) + + var u: U; +>u : Symbol(u, Decl(typeArgumentInferenceApparentType2.ts, 2, 11)) +>U : Symbol(U, Decl(typeArgumentInferenceApparentType2.ts, 1, 19)) + + var res: T = method(u); +>res : Symbol(res, Decl(typeArgumentInferenceApparentType2.ts, 3, 11)) +>T : Symbol(T, Decl(typeArgumentInferenceApparentType2.ts, 0, 16)) +>method : Symbol(method, Decl(typeArgumentInferenceApparentType2.ts, 0, 0)) +>u : Symbol(u, Decl(typeArgumentInferenceApparentType2.ts, 2, 11)) + } + return; +} diff --git a/tests/baselines/reference/typeArgumentInferenceApparentType2.types b/tests/baselines/reference/typeArgumentInferenceApparentType2.types new file mode 100644 index 00000000000..6a0e6ae6454 --- /dev/null +++ b/tests/baselines/reference/typeArgumentInferenceApparentType2.types @@ -0,0 +1,28 @@ +=== tests/cases/compiler/typeArgumentInferenceApparentType2.ts === +function method(iterable: Iterable): T { +>method : (iterable: Iterable) => T +>T : T +>iterable : Iterable +>Iterable : Iterable +>T : T +>T : T + + function inner>() { +>inner : >() => void +>U : U +>Iterable : Iterable +>T : T + + var u: U; +>u : U +>U : U + + var res: T = method(u); +>res : T +>T : T +>method(u) : T +>method : (iterable: Iterable) => T +>u : U + } + return; +} diff --git a/tests/cases/compiler/typeArgumentInferenceApparentType1.ts b/tests/cases/compiler/typeArgumentInferenceApparentType1.ts new file mode 100644 index 00000000000..4cc4a0dd4e5 --- /dev/null +++ b/tests/cases/compiler/typeArgumentInferenceApparentType1.ts @@ -0,0 +1,6 @@ +//@target: ES6 +function method(iterable: Iterable): T { + return; +} + +var res: string = method("test"); \ No newline at end of file diff --git a/tests/cases/compiler/typeArgumentInferenceApparentType2.ts b/tests/cases/compiler/typeArgumentInferenceApparentType2.ts new file mode 100644 index 00000000000..88ae4df8c4c --- /dev/null +++ b/tests/cases/compiler/typeArgumentInferenceApparentType2.ts @@ -0,0 +1,8 @@ +//@target: ES6 +function method(iterable: Iterable): T { + function inner>() { + var u: U; + var res: T = method(u); + } + return; +} \ No newline at end of file From b33a35b1224a8a377007f4081d0408771d2081f7 Mon Sep 17 00:00:00 2001 From: Dick van den Brink Date: Mon, 13 Jul 2015 23:38:10 +0200 Subject: [PATCH 33/78] Highlight abstract keywords on classes and members --- src/services/services.ts | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/services/services.ts b/src/services/services.ts index 10e38f98613..64f9a6bc14d 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -4694,6 +4694,10 @@ namespace ts { if (!(container.kind === SyntaxKind.ModuleBlock || container.kind === SyntaxKind.SourceFile)) { return undefined; } + } else if (modifier === SyntaxKind.AbstractKeyword) { + if (!(container.kind === SyntaxKind.ClassDeclaration || declaration.kind === SyntaxKind.ClassDeclaration)) { + return undefined; + } } else { // unsupported modifier @@ -4707,7 +4711,13 @@ namespace ts { switch (container.kind) { case SyntaxKind.ModuleBlock: case SyntaxKind.SourceFile: - nodes = (container).statements; + // Container is either a class declaration or the declaration is a classDeclaration + if (modifierFlag & NodeFlags.Abstract) { + nodes = ((declaration).members).concat(declaration); + } + else { + nodes = (container).statements; + } break; case SyntaxKind.Constructor: nodes = ((container).parameters).concat( @@ -4727,6 +4737,9 @@ namespace ts { nodes = nodes.concat(constructor.parameters); } } + else if (modifierFlag & NodeFlags.Abstract) { + nodes = nodes.concat(container); + } break; default: Debug.fail("Invalid container kind.") @@ -4754,6 +4767,8 @@ namespace ts { return NodeFlags.Export; case SyntaxKind.DeclareKeyword: return NodeFlags.Ambient; + case SyntaxKind.AbstractKeyword: + return NodeFlags.Abstract; default: Debug.fail(); } From 758abffd19c67d6f47e1b652415d9ed15403e556 Mon Sep 17 00:00:00 2001 From: Dick van den Brink Date: Tue, 14 Jul 2015 00:02:20 +0200 Subject: [PATCH 34/78] Added test for occurrences on abstract keyword --- .../cases/fourslash/getOccurrencesAbstract.ts | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 tests/cases/fourslash/getOccurrencesAbstract.ts diff --git a/tests/cases/fourslash/getOccurrencesAbstract.ts b/tests/cases/fourslash/getOccurrencesAbstract.ts new file mode 100644 index 00000000000..47252dd6f3b --- /dev/null +++ b/tests/cases/fourslash/getOccurrencesAbstract.ts @@ -0,0 +1,20 @@ +/// + +////[|abstract|] class Animal { +//// [|abstract|] walk(): void; +//// [|abstract|] makeSound(): void; +////} +////// Abstract class below should not get highlighted +////abstract class Foo { +//// abstract foo(): void; +//// abstract bar(): void; +////} + +test.ranges().forEach(r => { + goTo.position(r.start); + verify.occurrencesAtPositionCount(test.ranges().length); + + test.ranges().forEach(range => { + verify.occurrencesAtPositionContains(range, false); + }); +}); From fc47329ed2f12c55ee62345639fc1985d420697b Mon Sep 17 00:00:00 2001 From: Dick van den Brink Date: Tue, 14 Jul 2015 00:43:16 +0200 Subject: [PATCH 35/78] PR feedback for abstract keyword occurrences --- src/services/services.ts | 3 ++- tests/cases/fourslash/getOccurrencesAbstract.ts | 14 ++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/services/services.ts b/src/services/services.ts index 64f9a6bc14d..0d4099b9b47 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -4694,7 +4694,8 @@ namespace ts { if (!(container.kind === SyntaxKind.ModuleBlock || container.kind === SyntaxKind.SourceFile)) { return undefined; } - } else if (modifier === SyntaxKind.AbstractKeyword) { + } + else if (modifier === SyntaxKind.AbstractKeyword) { if (!(container.kind === SyntaxKind.ClassDeclaration || declaration.kind === SyntaxKind.ClassDeclaration)) { return undefined; } diff --git a/tests/cases/fourslash/getOccurrencesAbstract.ts b/tests/cases/fourslash/getOccurrencesAbstract.ts index 47252dd6f3b..8746cf1b489 100644 --- a/tests/cases/fourslash/getOccurrencesAbstract.ts +++ b/tests/cases/fourslash/getOccurrencesAbstract.ts @@ -10,11 +10,13 @@ //// abstract bar(): void; ////} -test.ranges().forEach(r => { - goTo.position(r.start); - verify.occurrencesAtPositionCount(test.ranges().length); +const ranges = test.ranges(); - test.ranges().forEach(range => { +for(let r of ranges) { + goTo.position(r.start); + verify.occurrencesAtPositionCount(ranges.length); + + for(let range of ranges) { verify.occurrencesAtPositionContains(range, false); - }); -}); + } +} From 2718539588b425fe743bd40adaa7c22527c2eda2 Mon Sep 17 00:00:00 2001 From: Dick van den Brink Date: Tue, 14 Jul 2015 01:39:39 +0200 Subject: [PATCH 36/78] Added more test cases for highlighting abstract keyword --- ...bstract.ts => getOccurrencesAbstract01.ts} | 6 ++-- .../fourslash/getOccurrencesAbstract02.ts | 29 +++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) rename tests/cases/fourslash/{getOccurrencesAbstract.ts => getOccurrencesAbstract01.ts} (74%) create mode 100644 tests/cases/fourslash/getOccurrencesAbstract02.ts diff --git a/tests/cases/fourslash/getOccurrencesAbstract.ts b/tests/cases/fourslash/getOccurrencesAbstract01.ts similarity index 74% rename from tests/cases/fourslash/getOccurrencesAbstract.ts rename to tests/cases/fourslash/getOccurrencesAbstract01.ts index 8746cf1b489..3e48ba4841a 100644 --- a/tests/cases/fourslash/getOccurrencesAbstract.ts +++ b/tests/cases/fourslash/getOccurrencesAbstract01.ts @@ -1,6 +1,8 @@ /// ////[|abstract|] class Animal { +//// [|abstract|] prop1; // Does not compile +//// [|abstract|] abstract(); //// [|abstract|] walk(): void; //// [|abstract|] makeSound(): void; ////} @@ -12,11 +14,11 @@ const ranges = test.ranges(); -for(let r of ranges) { +for (let r of ranges) { goTo.position(r.start); verify.occurrencesAtPositionCount(ranges.length); - for(let range of ranges) { + for (let range of ranges) { verify.occurrencesAtPositionContains(range, false); } } diff --git a/tests/cases/fourslash/getOccurrencesAbstract02.ts b/tests/cases/fourslash/getOccurrencesAbstract02.ts new file mode 100644 index 00000000000..8daafdbdc8e --- /dev/null +++ b/tests/cases/fourslash/getOccurrencesAbstract02.ts @@ -0,0 +1,29 @@ +/// + +////// Not valid TS (abstract methods can only appear in abstract classes) +////class Animal { +//// [|abstract|] walk(): void; +//// [|abstract|] makeSound(): void; +////} +////// abstract cannot appear here, won't get highlighted +////let c = /*1*/abstract class Foo { +//// /*2*/abstract foo(): void; +//// abstract bar(): void; +////} + +const ranges = test.ranges(); + +for (let r of ranges) { + goTo.position(r.start); + verify.occurrencesAtPositionCount(ranges.length); + + for (let range of ranges) { + verify.occurrencesAtPositionContains(range, false); + } +} + +goTo.marker("1"); +verify.occurrencesAtPositionCount(0); + +goTo.marker("2"); +verify.occurrencesAtPositionCount(2); From 96c1b9c3585fd204681772f32e8ce7bb36eff882 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 13 Jul 2015 16:44:07 -0700 Subject: [PATCH 37/78] Classify Identifiers as 'Identifier', not 'Text'. --- 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 10e38f98613..0a20cabd1c9 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -6574,7 +6574,7 @@ namespace ts { } } - return ClassificationType.text; + return ClassificationType.identifier; } } From 9c7d1211a7fddf9f3f9ac0484037024d0671634a Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 13 Jul 2015 16:57:11 -0700 Subject: [PATCH 38/78] Update tests. --- .../syntacticClassificationWithErrors.ts | 4 ++-- .../fourslash/syntacticClassifications1.ts | 4 ++-- ...syntacticClassificationsConflictMarkers1.ts | 4 ++-- ...syntacticClassificationsConflictMarkers2.ts | 2 +- .../syntacticClassificationsDocComment1.ts | 2 +- .../syntacticClassificationsDocComment2.ts | 4 ++-- .../syntacticClassificationsDocComment3.ts | 2 +- .../syntacticClassificationsForOfKeyword.ts | 4 ++-- .../syntacticClassificationsForOfKeyword2.ts | 4 ++-- .../syntacticClassificationsForOfKeyword3.ts | 6 +++--- ...acticClassificationsFunctionWithComments.ts | 4 ++-- .../syntacticClassificationsObjectLiteral.ts | 18 +++++++++--------- .../syntacticClassificationsTemplates1.ts | 8 ++++---- .../syntacticClassificationsTemplates2.ts | 2 +- 14 files changed, 34 insertions(+), 34 deletions(-) diff --git a/tests/cases/fourslash/syntacticClassificationWithErrors.ts b/tests/cases/fourslash/syntacticClassificationWithErrors.ts index b4572d3e620..166a22a1a51 100644 --- a/tests/cases/fourslash/syntacticClassificationWithErrors.ts +++ b/tests/cases/fourslash/syntacticClassificationWithErrors.ts @@ -8,7 +8,7 @@ let c = classification verify.syntacticClassificationsAre( c.keyword("class"), c.className("A"), c.punctuation("{"), - c.text("a"), c.punctuation(":"), + c.identifier("a"), c.punctuation(":"), c.punctuation("}"), - c.text("c"), c.operator("=") + c.identifier("c"), c.operator("=") ); \ No newline at end of file diff --git a/tests/cases/fourslash/syntacticClassifications1.ts b/tests/cases/fourslash/syntacticClassifications1.ts index 88f655683a3..1dbe2944b8a 100644 --- a/tests/cases/fourslash/syntacticClassifications1.ts +++ b/tests/cases/fourslash/syntacticClassifications1.ts @@ -22,8 +22,8 @@ var c = classification; verify.syntacticClassificationsAre( c.comment("// comment"), c.keyword("module"), c.moduleName("M"), c.punctuation("{"), - c.keyword("var"), c.text("v"), c.operator("="), c.numericLiteral("0"), c.operator("+"), c.numericLiteral("1"), c.punctuation(";"), - c.keyword("var"), c.text("s"), c.operator("="), c.stringLiteral('"string"'), c.punctuation(";"), + c.keyword("var"), c.identifier("v"), c.operator("="), c.numericLiteral("0"), c.operator("+"), c.numericLiteral("1"), c.punctuation(";"), + c.keyword("var"), c.identifier("s"), c.operator("="), c.stringLiteral('"string"'), c.punctuation(";"), c.keyword("class"), c.className("C"), c.punctuation("<"), c.typeParameterName("T"), c.punctuation(">"), c.punctuation("{"), c.punctuation("}"), c.keyword("enum"), c.enumName("E"), c.punctuation("{"), diff --git a/tests/cases/fourslash/syntacticClassificationsConflictMarkers1.ts b/tests/cases/fourslash/syntacticClassificationsConflictMarkers1.ts index 7f26038c33e..99db7443a4c 100644 --- a/tests/cases/fourslash/syntacticClassificationsConflictMarkers1.ts +++ b/tests/cases/fourslash/syntacticClassificationsConflictMarkers1.ts @@ -12,8 +12,8 @@ var c = classification; verify.syntacticClassificationsAre( c.keyword("class"), c.className("C"), c.punctuation("{"), c.comment("<<<<<<< HEAD"), - c.text("v"), c.operator("="), c.numericLiteral("1"), c.punctuation(";"), + c.identifier("v"), c.operator("="), c.numericLiteral("1"), c.punctuation(";"), c.comment("======="), - c.text("v"), c.punctuation("="), c.numericLiteral("2"), c.punctuation(";"), + c.identifier("v"), c.punctuation("="), c.numericLiteral("2"), c.punctuation(";"), c.comment(">>>>>>> Branch - a"), c.punctuation("}")); \ No newline at end of file diff --git a/tests/cases/fourslash/syntacticClassificationsConflictMarkers2.ts b/tests/cases/fourslash/syntacticClassificationsConflictMarkers2.ts index 92ede0d104b..18363c0389e 100644 --- a/tests/cases/fourslash/syntacticClassificationsConflictMarkers2.ts +++ b/tests/cases/fourslash/syntacticClassificationsConflictMarkers2.ts @@ -11,5 +11,5 @@ verify.syntacticClassificationsAre( c.comment("<<<<<<< HEAD"), c.keyword("class"), c.className("C"), c.punctuation("{"), c.punctuation("}"), c.comment("======="), - c.keyword("class"), c.text("D"), c.punctuation("{"), c.punctuation("}"), + c.keyword("class"), c.identifier("D"), c.punctuation("{"), c.punctuation("}"), c.comment(">>>>>>> Branch - a")); \ No newline at end of file diff --git a/tests/cases/fourslash/syntacticClassificationsDocComment1.ts b/tests/cases/fourslash/syntacticClassificationsDocComment1.ts index fe812b4c780..1ea3bf9684a 100644 --- a/tests/cases/fourslash/syntacticClassificationsDocComment1.ts +++ b/tests/cases/fourslash/syntacticClassificationsDocComment1.ts @@ -13,5 +13,5 @@ verify.syntacticClassificationsAre( c.punctuation("}"), c.comment(" */"), c.keyword("var"), - c.text("v"), + c.identifier("v"), c.punctuation(";")); diff --git a/tests/cases/fourslash/syntacticClassificationsDocComment2.ts b/tests/cases/fourslash/syntacticClassificationsDocComment2.ts index 201251dde6d..38dca4edcf2 100644 --- a/tests/cases/fourslash/syntacticClassificationsDocComment2.ts +++ b/tests/cases/fourslash/syntacticClassificationsDocComment2.ts @@ -15,12 +15,12 @@ verify.syntacticClassificationsAre( c.punctuation("{"), c.keyword("function"), c.punctuation("("), - c.text("x"), + c.identifier("x"), c.punctuation(")"), c.punctuation(":"), c.keyword("string"), c.punctuation("}"), c.comment(" */"), c.keyword("var"), - c.text("v"), + c.identifier("v"), c.punctuation(";")); diff --git a/tests/cases/fourslash/syntacticClassificationsDocComment3.ts b/tests/cases/fourslash/syntacticClassificationsDocComment3.ts index 6aca8cc415f..d7996fbbc54 100644 --- a/tests/cases/fourslash/syntacticClassificationsDocComment3.ts +++ b/tests/cases/fourslash/syntacticClassificationsDocComment3.ts @@ -15,5 +15,5 @@ verify.syntacticClassificationsAre( c.keyword("number"), c.comment(" /* } */"), c.keyword("var"), - c.text("v"), + c.identifier("v"), c.punctuation(";")); diff --git a/tests/cases/fourslash/syntacticClassificationsForOfKeyword.ts b/tests/cases/fourslash/syntacticClassificationsForOfKeyword.ts index a7a8c704ce6..22d7aa8ba94 100644 --- a/tests/cases/fourslash/syntacticClassificationsForOfKeyword.ts +++ b/tests/cases/fourslash/syntacticClassificationsForOfKeyword.ts @@ -7,9 +7,9 @@ verify.syntacticClassificationsAre( c.keyword("for"), c.punctuation("("), c.keyword("var"), - c.text("of"), + c.identifier("of"), c.keyword("of"), - c.text("of"), + c.identifier("of"), c.punctuation(")"), c.punctuation("{"), c.punctuation("}") diff --git a/tests/cases/fourslash/syntacticClassificationsForOfKeyword2.ts b/tests/cases/fourslash/syntacticClassificationsForOfKeyword2.ts index 30cfaea51e0..190663caa99 100644 --- a/tests/cases/fourslash/syntacticClassificationsForOfKeyword2.ts +++ b/tests/cases/fourslash/syntacticClassificationsForOfKeyword2.ts @@ -7,9 +7,9 @@ verify.syntacticClassificationsAre( c.keyword("for"), c.punctuation("("), c.keyword("var"), - c.text("of"), + c.identifier("of"), c.keyword("in"), - c.text("of"), + c.identifier("of"), c.punctuation(")"), c.punctuation("{"), c.punctuation("}") diff --git a/tests/cases/fourslash/syntacticClassificationsForOfKeyword3.ts b/tests/cases/fourslash/syntacticClassificationsForOfKeyword3.ts index 3af4733f3b2..ef96c99fed4 100644 --- a/tests/cases/fourslash/syntacticClassificationsForOfKeyword3.ts +++ b/tests/cases/fourslash/syntacticClassificationsForOfKeyword3.ts @@ -7,11 +7,11 @@ verify.syntacticClassificationsAre( c.keyword("for"), c.punctuation("("), c.keyword("var"), - c.text("of"), + c.identifier("of"), c.punctuation(";"), - c.text("of"), + c.identifier("of"), c.punctuation(";"), - c.text("of"), + c.identifier("of"), c.punctuation(")"), c.punctuation("{"), c.punctuation("}") diff --git a/tests/cases/fourslash/syntacticClassificationsFunctionWithComments.ts b/tests/cases/fourslash/syntacticClassificationsFunctionWithComments.ts index f7e5b7355a7..05a5aaa173e 100644 --- a/tests/cases/fourslash/syntacticClassificationsFunctionWithComments.ts +++ b/tests/cases/fourslash/syntacticClassificationsFunctionWithComments.ts @@ -19,7 +19,7 @@ var firstCommentText = var c = classification; verify.syntacticClassificationsAre( c.comment(firstCommentText), - c.keyword("function"), c.text("myFunction"), c.punctuation("("), c.comment("/* x */"), c.parameterName("x"), c.punctuation(":"), c.keyword("any"), c.punctuation(")"), c.punctuation("{"), - c.keyword("var"), c.text("y"), c.operator("="), c.text("x"), c.operator("?"), c.text("x"), c.operator("++"), c.operator(":"), c.operator("++"), c.text("x"), c.punctuation(";"), + c.keyword("function"), c.identifier("myFunction"), c.punctuation("("), c.comment("/* x */"), c.parameterName("x"), c.punctuation(":"), c.keyword("any"), c.punctuation(")"), c.punctuation("{"), + c.keyword("var"), c.identifier("y"), c.operator("="), c.identifier("x"), c.operator("?"), c.identifier("x"), c.operator("++"), c.operator(":"), c.operator("++"), c.identifier("x"), c.punctuation(";"), c.punctuation("}"), c.comment("// end of file")); \ No newline at end of file diff --git a/tests/cases/fourslash/syntacticClassificationsObjectLiteral.ts b/tests/cases/fourslash/syntacticClassificationsObjectLiteral.ts index 59642468ce9..c5bab5181a3 100644 --- a/tests/cases/fourslash/syntacticClassificationsObjectLiteral.ts +++ b/tests/cases/fourslash/syntacticClassificationsObjectLiteral.ts @@ -13,13 +13,13 @@ var c = classification; verify.syntacticClassificationsAre( - c.keyword("var"), c.text("v"), c.operator("="), c.numericLiteral("10e0"), c.punctuation(";"), - c.keyword("var"), c.text("x"), c.operator("="), c.punctuation("{"), - c.text("p1"), c.punctuation(":"), c.numericLiteral("1"), c.punctuation(","), - c.text("p2"), c.punctuation(":"), c.numericLiteral("2"), c.punctuation(","), - c.text("any"), c.punctuation(":"), c.numericLiteral("3"), c.punctuation(","), - c.text("function"), c.punctuation(":"), c.numericLiteral("4"), c.punctuation(","), - c.text("var"), c.punctuation(":"), c.numericLiteral("5"), c.punctuation(","), - c.text("void"), c.punctuation(":"), c.keyword("void"), c.numericLiteral("0"), c.punctuation(","), - c.text("v"), c.punctuation(":"), c.text("v"), c.operator("+="), c.text("v"), c.punctuation(","), + c.keyword("var"), c.identifier("v"), c.operator("="), c.numericLiteral("10e0"), c.punctuation(";"), + c.keyword("var"), c.identifier("x"), c.operator("="), c.punctuation("{"), + c.identifier("p1"), c.punctuation(":"), c.numericLiteral("1"), c.punctuation(","), + c.identifier("p2"), c.punctuation(":"), c.numericLiteral("2"), c.punctuation(","), + c.identifier("any"), c.punctuation(":"), c.numericLiteral("3"), c.punctuation(","), + c.identifier("function"), c.punctuation(":"), c.numericLiteral("4"), c.punctuation(","), + c.identifier("var"), c.punctuation(":"), c.numericLiteral("5"), c.punctuation(","), + c.identifier("void"), c.punctuation(":"), c.keyword("void"), c.numericLiteral("0"), c.punctuation(","), + c.identifier("v"), c.punctuation(":"), c.identifier("v"), c.operator("+="), c.identifier("v"), c.punctuation(","), c.punctuation("}"), c.punctuation(";")); \ No newline at end of file diff --git a/tests/cases/fourslash/syntacticClassificationsTemplates1.ts b/tests/cases/fourslash/syntacticClassificationsTemplates1.ts index 8ee48fb8a11..6c27aab3f40 100644 --- a/tests/cases/fourslash/syntacticClassificationsTemplates1.ts +++ b/tests/cases/fourslash/syntacticClassificationsTemplates1.ts @@ -8,8 +8,8 @@ var c = classification; verify.syntacticClassificationsAre( - c.keyword("var"), c.text("v"), c.operator("="), c.numericLiteral("10e0"), c.punctuation(";"), - c.keyword("var"), c.text("x"), c.operator("="), c.punctuation("{"), - c.text("p1"), c.punctuation(":"), c.stringLiteral("`hello world`"), c.punctuation(","), - c.text("p2"), c.punctuation(":"), c.stringLiteral("`goodbye ${"), c.numericLiteral("0"), c.stringLiteral("} cruel ${"), c.numericLiteral("0"), c.stringLiteral("} world`"), c.punctuation(","), + c.keyword("var"), c.identifier("v"), c.operator("="), c.numericLiteral("10e0"), c.punctuation(";"), + c.keyword("var"), c.identifier("x"), c.operator("="), c.punctuation("{"), + c.identifier("p1"), c.punctuation(":"), c.stringLiteral("`hello world`"), c.punctuation(","), + c.identifier("p2"), c.punctuation(":"), c.stringLiteral("`goodbye ${"), c.numericLiteral("0"), c.stringLiteral("} cruel ${"), c.numericLiteral("0"), c.stringLiteral("} world`"), c.punctuation(","), c.punctuation("}"), c.punctuation(";")); \ No newline at end of file diff --git a/tests/cases/fourslash/syntacticClassificationsTemplates2.ts b/tests/cases/fourslash/syntacticClassificationsTemplates2.ts index 913dc039012..25bb64e78ba 100644 --- a/tests/cases/fourslash/syntacticClassificationsTemplates2.ts +++ b/tests/cases/fourslash/syntacticClassificationsTemplates2.ts @@ -6,6 +6,6 @@ var c = classification; verify.syntacticClassificationsAre( - c.keyword("var"), c.text("tiredOfCanonicalExamples"), c.operator("="), + c.keyword("var"), c.identifier("tiredOfCanonicalExamples"), c.operator("="), c.stringLiteral("`goodbye \"${"), c.stringLiteral("`hello world`"), c.stringLiteral("}\" \nand ${"), c.stringLiteral("`good${"), c.stringLiteral("\" \""), c.stringLiteral("}riddance`"), c.stringLiteral("}`"), c.punctuation(";")); \ No newline at end of file From 785097445e7cf141f3d0f42a2322adba6b3d8bbb Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 13 Jul 2015 17:02:55 -0700 Subject: [PATCH 39/78] Update shim tests. --- tests/cases/fourslash/shims/getSyntacticClassifications.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/cases/fourslash/shims/getSyntacticClassifications.ts b/tests/cases/fourslash/shims/getSyntacticClassifications.ts index 88f655683a3..1dbe2944b8a 100644 --- a/tests/cases/fourslash/shims/getSyntacticClassifications.ts +++ b/tests/cases/fourslash/shims/getSyntacticClassifications.ts @@ -22,8 +22,8 @@ var c = classification; verify.syntacticClassificationsAre( c.comment("// comment"), c.keyword("module"), c.moduleName("M"), c.punctuation("{"), - c.keyword("var"), c.text("v"), c.operator("="), c.numericLiteral("0"), c.operator("+"), c.numericLiteral("1"), c.punctuation(";"), - c.keyword("var"), c.text("s"), c.operator("="), c.stringLiteral('"string"'), c.punctuation(";"), + c.keyword("var"), c.identifier("v"), c.operator("="), c.numericLiteral("0"), c.operator("+"), c.numericLiteral("1"), c.punctuation(";"), + c.keyword("var"), c.identifier("s"), c.operator("="), c.stringLiteral('"string"'), c.punctuation(";"), c.keyword("class"), c.className("C"), c.punctuation("<"), c.typeParameterName("T"), c.punctuation(">"), c.punctuation("{"), c.punctuation("}"), c.keyword("enum"), c.enumName("E"), c.punctuation("{"), From 30c6947ae3ad737bf89ec52e5de2a2e0080fb4e2 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Mon, 13 Jul 2015 17:55:48 -0700 Subject: [PATCH 40/78] Addressed CR feedback. --- src/compiler/parser.ts | 8 ++----- src/services/services.ts | 45 ++++++++++++++++++++++++++++------------ 2 files changed, 34 insertions(+), 19 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 986967edb45..8c220604e89 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -4345,10 +4345,6 @@ namespace ts { } } - function nextTokenIsStringLiteralOnSameLine() { - return !scanner.hasPrecedingLineBreak() && token === SyntaxKind.StringLiteral; - } - function nextTokenIsIdentifierOrStringLiteralOnSameLine() { nextToken(); return !scanner.hasPrecedingLineBreak() && (isIdentifier() || token === SyntaxKind.StringLiteral); @@ -5141,9 +5137,9 @@ namespace ts { node.exportClause = parseNamedImportsOrExports(SyntaxKind.NamedExports); // It is not uncommon to accidentally omit the 'from' keyword. Additionally, in editing scenarios, - // the 'from' keyword be parsed as a named export when the export clause is unterminated (i.e. `export { from "moduleName";`) + // the 'from' keyword can be parsed as a named export when the export clause is unterminated (i.e. `export { from "moduleName";`) // If we don't have a 'from' keyword, see if we have a string literal such that ASI won't take effect. - if (token === SyntaxKind.FromKeyword || lookAhead(nextTokenIsStringLiteralOnSameLine)) { + if (token === SyntaxKind.FromKeyword || (token === SyntaxKind.StringLiteral && !scanner.hasPrecedingLineBreak())) { parseExpected(SyntaxKind.FromKeyword) node.moduleSpecifier = parseModuleSpecifier(); } diff --git a/src/services/services.ts b/src/services/services.ts index dff8e46e2b5..0229a356b97 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -3255,11 +3255,6 @@ namespace ts { * @returns true if 'symbols' was successfully populated; false otherwise. */ function tryGetImportOrExportClauseCompletionSymbols(namedImportsOrExports: NamedImportsOrExports): boolean { - // cursor is in import clause - // try to show exported member for imported module - isMemberCompletion = true; - isNewIdentifierLocation = false; - let declarationKind = namedImportsOrExports.kind === SyntaxKind.NamedImports ? SyntaxKind.ImportDeclaration : SyntaxKind.ExportDeclaration; @@ -3270,13 +3265,16 @@ namespace ts { return false; } + isMemberCompletion = true; + isNewIdentifierLocation = false; + let exports: Symbol[]; let moduleSpecifierSymbol = typeChecker.getSymbolAtLocation(importOrExportDeclaration.moduleSpecifier); if (moduleSpecifierSymbol) { exports = typeChecker.getExportsOfModule(moduleSpecifierSymbol); } - symbols = exports ? filterModuleExports(exports, namedImportsOrExports) : emptyArray; + symbols = exports ? filterNamedImportOrExportCompletionItems(exports, namedImportsOrExports.elements) : emptyArray; return true; } @@ -3474,26 +3472,41 @@ namespace ts { return false; } - function filterModuleExports(exports: Symbol[], namedImportsOrExports: NamedImportsOrExports): Symbol[] { - let exisingImports: Map = {}; + /** + * Filters out completion suggestions for named imports or exports. + * + * @param exportsOfModule The list of symbols which a module exposes. + * @param namedImportsOrExports The list of existing import/export specifiers in the import/export clause. + * + * @returns Symbols to be suggested at an import/export clause, barring those whose named imports/exports + * do not occur at the current position and have not otherwise been typed. + */ + function filterNamedImportOrExportCompletionItems(exportsOfModule: Symbol[], namedImportsOrExports: ImportOrExportSpecifier[]): Symbol[] { + let exisingImportsOrExports: Map = {}; - for (let element of namedImportsOrExports.elements) { + 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; } let name = element.propertyName || element.name; - exisingImports[name.text] = true; + exisingImportsOrExports[name.text] = true; } - if (isEmpty(exisingImports)) { - return exports; + if (isEmpty(exisingImportsOrExports)) { + return exportsOfModule; } - return filter(exports, e => !lookUp(exisingImports, e.name)); + return filter(exportsOfModule, e => !lookUp(exisingImportsOrExports, e.name)); } + /** + * Filters out completion suggestions for named imports or exports. + * + * @returns Symbols to be suggested in an object binding pattern or object literal expression, barring those whose declarations + * do not occur at the current position and have not otherwise been typed. + */ function filterObjectMembersList(contextualMemberSymbols: Symbol[], existingMembers: Declaration[]): Symbol[] { if (!existingMembers || existingMembers.length === 0) { return contextualMemberSymbols; @@ -3538,6 +3551,12 @@ namespace ts { return filteredMembers; } + /** + * Filters out completion suggestions from 'symbols' according to existing JSX attributes. + * + * @returns Symbols to be suggested in a JSX element, barring those whose attributes + * do not occur at the current position and have not otherwise been typed. + */ function filterJsxAttributes(attributes: NodeArray, symbols: Symbol[]): Symbol[] { let seenNames: Map = {}; for (let attr of attributes) { From 4f7c62482a1ca8e01f38c468d60ccd77bfc51833 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Mon, 13 Jul 2015 17:59:42 -0700 Subject: [PATCH 41/78] Just use 'filter' --- src/services/services.ts | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/src/services/services.ts b/src/services/services.ts index 0229a356b97..13fba85d93f 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -3541,14 +3541,7 @@ namespace ts { existingMemberNames[existingName] = true; } - let filteredMembers: Symbol[] = []; - forEach(contextualMemberSymbols, s => { - if (!existingMemberNames[s.name]) { - filteredMembers.push(s); - } - }); - - return filteredMembers; + return filter(contextualMemberSymbols, m => !lookUp(existingMemberNames, m.name)); } /** @@ -3569,13 +3562,8 @@ namespace ts { seenNames[(attr).name.text] = true; } } - let result: Symbol[] = []; - for (let sym of symbols) { - if (!seenNames[sym.name]) { - result.push(sym); - } - } - return result; + + return filter(symbols, a => !lookUp(seenNames, a.name)); } } From 076028c57dbafdfab8c561823c22168ca39274ff Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Mon, 13 Jul 2015 18:03:06 -0700 Subject: [PATCH 42/78] Changed order of parameters. --- src/services/services.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/services/services.ts b/src/services/services.ts index 13fba85d93f..eb778bce0c7 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -3034,7 +3034,7 @@ namespace ts { attrsType = typeChecker.getJsxElementAttributesType(jsxContainer); if (attrsType) { - symbols = filterJsxAttributes((jsxContainer).attributes, typeChecker.getPropertiesOfType(attrsType)); + symbols = filterJsxAttributes(typeChecker.getPropertiesOfType(attrsType), (jsxContainer).attributes); isMemberCompletion = true; isNewIdentifierLocation = false; return true; @@ -3550,7 +3550,7 @@ namespace ts { * @returns Symbols to be suggested in a JSX element, barring those whose attributes * do not occur at the current position and have not otherwise been typed. */ - function filterJsxAttributes(attributes: NodeArray, symbols: Symbol[]): Symbol[] { + function filterJsxAttributes(symbols: Symbol[], attributes: NodeArray): Symbol[] { let seenNames: Map = {}; for (let attr of attributes) { // If this is the current item we are editing right now, do not filter it out From 1066f0e3cca7b1ddcf219490487edb7b13631ab5 Mon Sep 17 00:00:00 2001 From: "shyyko.serhiy@gmail.com" Date: Tue, 14 Jul 2015 15:28:05 +0300 Subject: [PATCH 43/78] fixed issue #3454 --- src/compiler/emitter.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index fd0d4ad796e..1c032c0aa25 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -4219,6 +4219,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi scopeEmitStart(node, "constructor"); increaseIndent(); if (ctor) { + var startIndex = emitDirectivePrologues(ctor.body.statements, /*startWithNewLine*/ true); emitDetachedComments(ctor.body.statements); } emitCaptureThisForNodeIfNecessary(node); @@ -4253,7 +4254,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi if (superCall) { statements = statements.slice(1); } - emitLines(statements); + emitLinesStartingAt(statements, startIndex); } emitTempDeclarations(/*newLine*/ true); writeLine(); From aec0fb4818b7031fc1474b5497f084287e303133 Mon Sep 17 00:00:00 2001 From: "shyyko.serhiy@gmail.com" Date: Tue, 14 Jul 2015 17:02:18 +0300 Subject: [PATCH 44/78] fixed strictModeInConstructor baseline reference --- tests/baselines/reference/strictModeInConstructor.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/baselines/reference/strictModeInConstructor.js b/tests/baselines/reference/strictModeInConstructor.js index 7fd74aa108f..7d1adc48fa0 100644 --- a/tests/baselines/reference/strictModeInConstructor.js +++ b/tests/baselines/reference/strictModeInConstructor.js @@ -74,8 +74,8 @@ var A = (function () { var B = (function (_super) { __extends(B, _super); function B() { - this.s = 9; "use strict"; // No error + this.s = 9; _super.call(this); } return B; From 12809125f8eb406e7743b75425595c065e8e05af Mon Sep 17 00:00:00 2001 From: "shyyko.serhiy@gmail.com" Date: Tue, 14 Jul 2015 17:21:47 +0300 Subject: [PATCH 45/78] added comment --- src/compiler/emitter.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 1c032c0aa25..7b083ba7363 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -4219,6 +4219,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi scopeEmitStart(node, "constructor"); increaseIndent(); if (ctor) { + // Emit all the directive prologues (like "use strict"). These have to come before + // any other preamble code we write (like parameter initializers). var startIndex = emitDirectivePrologues(ctor.body.statements, /*startWithNewLine*/ true); emitDetachedComments(ctor.body.statements); } From dfa108f4ec5e2074fe3ef0a26471fa52a5581d1e Mon Sep 17 00:00:00 2001 From: Jason Freeman Date: Tue, 14 Jul 2015 11:17:07 -0700 Subject: [PATCH 46/78] Allow tuples to be widened --- src/compiler/checker.ts | 60 +++++++++++++------ .../diagnosticInformationMap.generated.ts | 1 + src/compiler/diagnosticMessages.json | 8 +++ 3 files changed, 50 insertions(+), 19 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index da45c08ab44..5209f02847e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5299,7 +5299,7 @@ namespace ts { * Check if a Type was written as a tuple type literal. * Prefer using isTupleLikeType() unless the use of `elementTypes` is required. */ - function isTupleType(type: Type): boolean { + function isTupleType(type: Type): type is TupleType { return (type.flags & TypeFlags.Tuple) && !!(type).elementTypes; } @@ -5341,37 +5341,53 @@ namespace ts { if (isArrayType(type)) { return createArrayType(getWidenedType((type).typeArguments[0])); } + if (isTupleType(type)) { + return createTupleType(map(type.elementTypes, getWidenedType)); + } } return type; } - function reportWideningErrorsInType(type: Type): boolean { + function reportWideningErrorsInType(type: Type, expression: Expression): boolean { + let errorReported = false; if (type.flags & TypeFlags.Union) { - let errorReported = false; - forEach((type).types, t => { - if (reportWideningErrorsInType(t)) { + for (let t of (type).types) { + if (reportWideningErrorsInType(t, expression)) { errorReported = true; } - }); - return errorReported; + } } if (isArrayType(type)) { - return reportWideningErrorsInType((type).typeArguments[0]); + return reportWideningErrorsInType((type).typeArguments[0], expression); + } + if (isTupleType(type)) { + let { elementTypes } = type; + for (let i = 0; i < elementTypes.length; i++) { + let t = elementTypes[i]; + if (t.flags & TypeFlags.ContainsUndefinedOrNull) { + if (reportWideningErrorsInType(t, expression)) { + errorReported = true; + } + else if (expression.kind === SyntaxKind.ArrayLiteralExpression) { + let element = (expression).elements[i]; + error(element, Diagnostics.Array_element_at_index_0_implicitly_has_an_1_type, i, typeToString(getWidenedType(t))); + errorReported = true; + } + } + } } if (type.flags & TypeFlags.ObjectLiteral) { - let errorReported = false; - forEach(getPropertiesOfObjectType(type), p => { + for (let p of getPropertiesOfObjectType(type)) { let t = getTypeOfSymbol(p); if (t.flags & TypeFlags.ContainsUndefinedOrNull) { - if (!reportWideningErrorsInType(t)) { + if (!reportWideningErrorsInType(t, expression)) { error(p.valueDeclaration, Diagnostics.Object_literal_s_property_0_implicitly_has_an_1_type, p.name, typeToString(getWidenedType(t))); } errorReported = true; } - }); - return errorReported; + } } - return false; + return errorReported; } function reportImplicitAnyError(declaration: Declaration, type: Type) { @@ -5409,7 +5425,7 @@ namespace ts { function reportErrorsFromWidening(declaration: Declaration, type: Type) { if (produceDiagnostics && compilerOptions.noImplicitAny && type.flags & TypeFlags.ContainsUndefinedOrNull) { // Report implicit any error within type if possible, otherwise report error on declaration - if (!reportWideningErrorsInType(type)) { + if (!reportWideningErrorsInType(type, declaration.kind === SyntaxKind.VariableDeclaration && (declaration).initializer)) { reportImplicitAnyError(declaration, type); } } @@ -6785,6 +6801,7 @@ namespace ts { let hasSpreadElement = false; let elementTypes: Type[] = []; let inDestructuringPattern = isAssignmentTarget(node); + let typeFlags: TypeFlags; for (let e of elements) { if (inDestructuringPattern && e.kind === SyntaxKind.SpreadElementExpression) { // Given the following situation: @@ -6804,21 +6821,23 @@ namespace ts { (languageVersion >= ScriptTarget.ES6 ? getElementTypeOfIterable(restArrayType, /*errorNode*/ undefined) : undefined); if (restElementType) { elementTypes.push(restElementType); + typeFlags |= restElementType.flags; } } else { let type = checkExpression(e, contextualMapper); elementTypes.push(type); + typeFlags |= type.flags; } hasSpreadElement = hasSpreadElement || e.kind === SyntaxKind.SpreadElementExpression; } if (!hasSpreadElement) { let contextualType = getContextualType(node); if (contextualType && contextualTypeIsTupleLikeType(contextualType) || inDestructuringPattern) { - return createTupleType(elementTypes); + return addTypeFlags(createTupleType(elementTypes), typeFlags & TypeFlags.RequiresWidening); } } - return createArrayType(getUnionType(elementTypes)); + return addTypeFlags(createArrayType(getUnionType(elementTypes)), typeFlags & TypeFlags.RequiresWidening); } function isNumericName(name: DeclarationName): boolean { @@ -6934,8 +6953,7 @@ namespace ts { let stringIndexType = getIndexType(IndexKind.String); let numberIndexType = getIndexType(IndexKind.Number); let result = createAnonymousType(node.symbol, propertiesTable, emptyArray, emptyArray, stringIndexType, numberIndexType); - result.flags |= TypeFlags.ObjectLiteral | TypeFlags.ContainsObjectLiteral | (typeFlags & TypeFlags.ContainsUndefinedOrNull); - return result; + return addTypeFlags(result, TypeFlags.ObjectLiteral | TypeFlags.ContainsObjectLiteral | (typeFlags & TypeFlags.ContainsUndefinedOrNull)); function getIndexType(kind: IndexKind) { if (contextualType && contextualTypeHasIndexSignature(contextualType, kind)) { @@ -6961,6 +6979,10 @@ namespace ts { } } + function addTypeFlags(type: Type, flags: TypeFlags): Type { + type.flags |= flags; + return type; + } function checkJsxSelfClosingElement(node: JsxSelfClosingElement) { checkJsxOpeningLikeElement(node); diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index a0a95d47c8c..ce28cbbc387 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -589,6 +589,7 @@ namespace ts { Function_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions: { code: 7024, category: DiagnosticCategory.Error, key: "Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions." }, Generator_implicitly_has_type_0_because_it_does_not_yield_any_values_Consider_supplying_a_return_type: { code: 7025, category: DiagnosticCategory.Error, key: "Generator implicitly has type '{0}' because it does not yield any values. Consider supplying a return type." }, JSX_element_implicitly_has_type_any_because_no_interface_JSX_0_exists: { code: 7026, category: DiagnosticCategory.Error, key: "JSX element implicitly has type 'any' because no interface 'JSX.{0}' exists" }, + Array_element_at_index_0_implicitly_has_an_1_type: { code: 7027, category: DiagnosticCategory.Error, key: "Array element at index {0} implicitly has an '{1}' type." }, You_cannot_rename_this_element: { code: 8000, category: DiagnosticCategory.Error, key: "You cannot rename this element." }, You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library: { code: 8001, category: DiagnosticCategory.Error, key: "You cannot rename elements that are defined in the standard TypeScript library." }, import_can_only_be_used_in_a_ts_file: { code: 8002, category: DiagnosticCategory.Error, key: "'import ... =' can only be used in a .ts file." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index acf4e74ae9f..65e3bab9ec5 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2347,6 +2347,14 @@ "category": "Error", "code": 7026 }, + "JSX element implicitly has type 'any' because no interface 'JSX.{0}' exists": { + "category": "Error", + "code": 7026 + }, + "Array element at index {0} implicitly has an '{1}' type.": { + "category": "Error", + "code": 7027 + }, "You cannot rename this element.": { From 6954cd2fd72b872c7317cad6e04e34f81f252565 Mon Sep 17 00:00:00 2001 From: Jason Freeman Date: Tue, 14 Jul 2015 11:49:50 -0700 Subject: [PATCH 47/78] Add new tests --- tests/cases/conformance/types/tuple/wideningTuples1.ts | 5 +++++ tests/cases/conformance/types/tuple/wideningTuples2.ts | 6 ++++++ tests/cases/conformance/types/tuple/wideningTuples3.ts | 4 ++++ tests/cases/conformance/types/tuple/wideningTuples4.ts | 4 ++++ tests/cases/conformance/types/tuple/wideningTuples5.ts | 2 ++ tests/cases/conformance/types/tuple/wideningTuples6.ts | 3 +++ tests/cases/conformance/types/tuple/wideningTuples7.ts | 5 +++++ 7 files changed, 29 insertions(+) create mode 100644 tests/cases/conformance/types/tuple/wideningTuples1.ts create mode 100644 tests/cases/conformance/types/tuple/wideningTuples2.ts create mode 100644 tests/cases/conformance/types/tuple/wideningTuples3.ts create mode 100644 tests/cases/conformance/types/tuple/wideningTuples4.ts create mode 100644 tests/cases/conformance/types/tuple/wideningTuples5.ts create mode 100644 tests/cases/conformance/types/tuple/wideningTuples6.ts create mode 100644 tests/cases/conformance/types/tuple/wideningTuples7.ts diff --git a/tests/cases/conformance/types/tuple/wideningTuples1.ts b/tests/cases/conformance/types/tuple/wideningTuples1.ts new file mode 100644 index 00000000000..f4885435dcf --- /dev/null +++ b/tests/cases/conformance/types/tuple/wideningTuples1.ts @@ -0,0 +1,5 @@ +//@noImplicitAny: true +declare function foo(x: T): T; + +var y = foo([undefined]); +y = [""]; \ No newline at end of file diff --git a/tests/cases/conformance/types/tuple/wideningTuples2.ts b/tests/cases/conformance/types/tuple/wideningTuples2.ts new file mode 100644 index 00000000000..d8bf1248546 --- /dev/null +++ b/tests/cases/conformance/types/tuple/wideningTuples2.ts @@ -0,0 +1,6 @@ +//@noImplicitAny: true +var foo: () => [any] = function bar() { + let intermediate = bar(); + intermediate = [""]; + return [undefined]; +}; \ No newline at end of file diff --git a/tests/cases/conformance/types/tuple/wideningTuples3.ts b/tests/cases/conformance/types/tuple/wideningTuples3.ts new file mode 100644 index 00000000000..a6837be2a0f --- /dev/null +++ b/tests/cases/conformance/types/tuple/wideningTuples3.ts @@ -0,0 +1,4 @@ +//@noImplicitAny: true +var a: [any]; + +var b = a = [undefined, null]; \ No newline at end of file diff --git a/tests/cases/conformance/types/tuple/wideningTuples4.ts b/tests/cases/conformance/types/tuple/wideningTuples4.ts new file mode 100644 index 00000000000..550ba07f600 --- /dev/null +++ b/tests/cases/conformance/types/tuple/wideningTuples4.ts @@ -0,0 +1,4 @@ +var a: [any]; + +var b = a = [undefined, null]; +b = ["", ""]; \ No newline at end of file diff --git a/tests/cases/conformance/types/tuple/wideningTuples5.ts b/tests/cases/conformance/types/tuple/wideningTuples5.ts new file mode 100644 index 00000000000..36434c6eafe --- /dev/null +++ b/tests/cases/conformance/types/tuple/wideningTuples5.ts @@ -0,0 +1,2 @@ +//@noImplicitAny: true +var [a, b] = [undefined, null]; \ No newline at end of file diff --git a/tests/cases/conformance/types/tuple/wideningTuples6.ts b/tests/cases/conformance/types/tuple/wideningTuples6.ts new file mode 100644 index 00000000000..cac228ecb4d --- /dev/null +++ b/tests/cases/conformance/types/tuple/wideningTuples6.ts @@ -0,0 +1,3 @@ +var [a, b] = [undefined, null]; +a = ""; +b = ""; \ No newline at end of file diff --git a/tests/cases/conformance/types/tuple/wideningTuples7.ts b/tests/cases/conformance/types/tuple/wideningTuples7.ts new file mode 100644 index 00000000000..1a4d212d362 --- /dev/null +++ b/tests/cases/conformance/types/tuple/wideningTuples7.ts @@ -0,0 +1,5 @@ +//@noImplicitAny: true +var foo = function bar() { + let intermediate: [string]; + return intermediate = [undefined]; +}; \ No newline at end of file From 6f94314774c0a2788904caf6966296dea2e7382c Mon Sep 17 00:00:00 2001 From: Jason Freeman Date: Tue, 14 Jul 2015 11:50:00 -0700 Subject: [PATCH 48/78] Accept baselines --- ...cturingParameterDeclaration1ES5.errors.txt | 20 +---------------- tests/baselines/reference/wideningTuples1.js | 9 ++++++++ .../reference/wideningTuples1.symbols | 16 ++++++++++++++ .../baselines/reference/wideningTuples1.types | 21 ++++++++++++++++++ tests/baselines/reference/wideningTuples2.js | 13 +++++++++++ .../reference/wideningTuples2.symbols | 16 ++++++++++++++ .../baselines/reference/wideningTuples2.types | 22 +++++++++++++++++++ .../reference/wideningTuples3.errors.txt | 9 ++++++++ tests/baselines/reference/wideningTuples3.js | 8 +++++++ tests/baselines/reference/wideningTuples4.js | 10 +++++++++ .../reference/wideningTuples4.symbols | 12 ++++++++++ .../baselines/reference/wideningTuples4.types | 19 ++++++++++++++++ .../reference/wideningTuples5.errors.txt | 10 +++++++++ tests/baselines/reference/wideningTuples5.js | 5 +++++ tests/baselines/reference/wideningTuples6.js | 9 ++++++++ .../reference/wideningTuples6.symbols | 12 ++++++++++ .../baselines/reference/wideningTuples6.types | 18 +++++++++++++++ .../reference/wideningTuples7.errors.txt | 10 +++++++++ tests/baselines/reference/wideningTuples7.js | 11 ++++++++++ 19 files changed, 231 insertions(+), 19 deletions(-) create mode 100644 tests/baselines/reference/wideningTuples1.js create mode 100644 tests/baselines/reference/wideningTuples1.symbols create mode 100644 tests/baselines/reference/wideningTuples1.types create mode 100644 tests/baselines/reference/wideningTuples2.js create mode 100644 tests/baselines/reference/wideningTuples2.symbols create mode 100644 tests/baselines/reference/wideningTuples2.types create mode 100644 tests/baselines/reference/wideningTuples3.errors.txt create mode 100644 tests/baselines/reference/wideningTuples3.js create mode 100644 tests/baselines/reference/wideningTuples4.js create mode 100644 tests/baselines/reference/wideningTuples4.symbols create mode 100644 tests/baselines/reference/wideningTuples4.types create mode 100644 tests/baselines/reference/wideningTuples5.errors.txt create mode 100644 tests/baselines/reference/wideningTuples5.js create mode 100644 tests/baselines/reference/wideningTuples6.js create mode 100644 tests/baselines/reference/wideningTuples6.symbols create mode 100644 tests/baselines/reference/wideningTuples6.types create mode 100644 tests/baselines/reference/wideningTuples7.errors.txt create mode 100644 tests/baselines/reference/wideningTuples7.js diff --git a/tests/baselines/reference/destructuringParameterDeclaration1ES5.errors.txt b/tests/baselines/reference/destructuringParameterDeclaration1ES5.errors.txt index 269d2b5640d..8e51c2b6111 100644 --- a/tests/baselines/reference/destructuringParameterDeclaration1ES5.errors.txt +++ b/tests/baselines/reference/destructuringParameterDeclaration1ES5.errors.txt @@ -1,16 +1,8 @@ -tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5.ts(32,4): error TS2345: Argument of type '[string, number, number]' is not assignable to parameter of type '[undefined, null, undefined]'. - Types of property '0' are incompatible. - Type 'string' is not assignable to type 'undefined'. -tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5.ts(33,4): error TS2345: Argument of type '[[string], number, [[boolean, boolean]]]' is not assignable to parameter of type '[[undefined], undefined, [[undefined, undefined]]]'. - Types of property '0' are incompatible. - Type '[string]' is not assignable to type '[undefined]'. - Types of property '0' are incompatible. - Type 'string' is not assignable to type 'undefined'. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5.ts(62,10): error TS2393: Duplicate function implementation. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5.ts(63,10): error TS2393: Duplicate function implementation. -==== tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5.ts (4 errors) ==== +==== tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5.ts (2 errors) ==== // A parameter declaration may specify either an identifier or a binding pattern. // The identifiers specified in parameter declarations and binding patterns // in a parameter list must be unique within that parameter list. @@ -43,17 +35,7 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5. b2("string", { x: 200, y: "string" }); b2("string", { x: 200, y: true }); b6(["string", 1, 2]); // Shouldn't be an error - ~~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '[string, number, number]' is not assignable to parameter of type '[undefined, null, undefined]'. -!!! error TS2345: Types of property '0' are incompatible. -!!! error TS2345: Type 'string' is not assignable to type 'undefined'. b7([["string"], 1, [[true, false]]]); // Shouldn't be an error - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '[[string], number, [[boolean, boolean]]]' is not assignable to parameter of type '[[undefined], undefined, [[undefined, undefined]]]'. -!!! error TS2345: Types of property '0' are incompatible. -!!! error TS2345: Type '[string]' is not assignable to type '[undefined]'. -!!! error TS2345: Types of property '0' are incompatible. -!!! error TS2345: Type 'string' is not assignable to type 'undefined'. // If the declaration specifies a binding pattern, the parameter type is the implied type of that binding pattern (section 5.1.3) diff --git a/tests/baselines/reference/wideningTuples1.js b/tests/baselines/reference/wideningTuples1.js new file mode 100644 index 00000000000..ed39a735bfe --- /dev/null +++ b/tests/baselines/reference/wideningTuples1.js @@ -0,0 +1,9 @@ +//// [wideningTuples1.ts] +declare function foo(x: T): T; + +var y = foo([undefined]); +y = [""]; + +//// [wideningTuples1.js] +var y = foo([undefined]); +y = [""]; diff --git a/tests/baselines/reference/wideningTuples1.symbols b/tests/baselines/reference/wideningTuples1.symbols new file mode 100644 index 00000000000..819510b7319 --- /dev/null +++ b/tests/baselines/reference/wideningTuples1.symbols @@ -0,0 +1,16 @@ +=== tests/cases/conformance/types/tuple/wideningTuples1.ts === +declare function foo(x: T): T; +>foo : Symbol(foo, Decl(wideningTuples1.ts, 0, 0)) +>T : Symbol(T, Decl(wideningTuples1.ts, 0, 21)) +>x : Symbol(x, Decl(wideningTuples1.ts, 0, 38)) +>T : Symbol(T, Decl(wideningTuples1.ts, 0, 21)) +>T : Symbol(T, Decl(wideningTuples1.ts, 0, 21)) + +var y = foo([undefined]); +>y : Symbol(y, Decl(wideningTuples1.ts, 2, 3)) +>foo : Symbol(foo, Decl(wideningTuples1.ts, 0, 0)) +>undefined : Symbol(undefined) + +y = [""]; +>y : Symbol(y, Decl(wideningTuples1.ts, 2, 3)) + diff --git a/tests/baselines/reference/wideningTuples1.types b/tests/baselines/reference/wideningTuples1.types new file mode 100644 index 00000000000..1fdd4a6cb53 --- /dev/null +++ b/tests/baselines/reference/wideningTuples1.types @@ -0,0 +1,21 @@ +=== tests/cases/conformance/types/tuple/wideningTuples1.ts === +declare function foo(x: T): T; +>foo : (x: T) => T +>T : T +>x : T +>T : T +>T : T + +var y = foo([undefined]); +>y : [any] +>foo([undefined]) : [any] +>foo : (x: T) => T +>[undefined] : [undefined] +>undefined : undefined + +y = [""]; +>y = [""] : [string] +>y : [any] +>[""] : [string] +>"" : string + diff --git a/tests/baselines/reference/wideningTuples2.js b/tests/baselines/reference/wideningTuples2.js new file mode 100644 index 00000000000..fa74e089961 --- /dev/null +++ b/tests/baselines/reference/wideningTuples2.js @@ -0,0 +1,13 @@ +//// [wideningTuples2.ts] +var foo: () => [any] = function bar() { + let intermediate = bar(); + intermediate = [""]; + return [undefined]; +}; + +//// [wideningTuples2.js] +var foo = function bar() { + var intermediate = bar(); + intermediate = [""]; + return [undefined]; +}; diff --git a/tests/baselines/reference/wideningTuples2.symbols b/tests/baselines/reference/wideningTuples2.symbols new file mode 100644 index 00000000000..74186045e90 --- /dev/null +++ b/tests/baselines/reference/wideningTuples2.symbols @@ -0,0 +1,16 @@ +=== tests/cases/conformance/types/tuple/wideningTuples2.ts === +var foo: () => [any] = function bar() { +>foo : Symbol(foo, Decl(wideningTuples2.ts, 0, 3)) +>bar : Symbol(bar, Decl(wideningTuples2.ts, 0, 22)) + + let intermediate = bar(); +>intermediate : Symbol(intermediate, Decl(wideningTuples2.ts, 1, 7)) +>bar : Symbol(bar, Decl(wideningTuples2.ts, 0, 22)) + + intermediate = [""]; +>intermediate : Symbol(intermediate, Decl(wideningTuples2.ts, 1, 7)) + + return [undefined]; +>undefined : Symbol(undefined) + +}; diff --git a/tests/baselines/reference/wideningTuples2.types b/tests/baselines/reference/wideningTuples2.types new file mode 100644 index 00000000000..c07166c53f0 --- /dev/null +++ b/tests/baselines/reference/wideningTuples2.types @@ -0,0 +1,22 @@ +=== tests/cases/conformance/types/tuple/wideningTuples2.ts === +var foo: () => [any] = function bar() { +>foo : () => [any] +>function bar() { let intermediate = bar(); intermediate = [""]; return [undefined];} : () => [any] +>bar : () => [any] + + let intermediate = bar(); +>intermediate : [any] +>bar() : [any] +>bar : () => [any] + + intermediate = [""]; +>intermediate = [""] : [string] +>intermediate : [any] +>[""] : [string] +>"" : string + + return [undefined]; +>[undefined] : [undefined] +>undefined : undefined + +}; diff --git a/tests/baselines/reference/wideningTuples3.errors.txt b/tests/baselines/reference/wideningTuples3.errors.txt new file mode 100644 index 00000000000..43c7e349a0c --- /dev/null +++ b/tests/baselines/reference/wideningTuples3.errors.txt @@ -0,0 +1,9 @@ +tests/cases/conformance/types/tuple/wideningTuples3.ts(3,5): error TS7005: Variable 'b' implicitly has an '[any, any]' type. + + +==== tests/cases/conformance/types/tuple/wideningTuples3.ts (1 errors) ==== + var a: [any]; + + var b = a = [undefined, null]; + ~ +!!! error TS7005: Variable 'b' implicitly has an '[any, any]' type. \ No newline at end of file diff --git a/tests/baselines/reference/wideningTuples3.js b/tests/baselines/reference/wideningTuples3.js new file mode 100644 index 00000000000..dfeaae745d4 --- /dev/null +++ b/tests/baselines/reference/wideningTuples3.js @@ -0,0 +1,8 @@ +//// [wideningTuples3.ts] +var a: [any]; + +var b = a = [undefined, null]; + +//// [wideningTuples3.js] +var a; +var b = a = [undefined, null]; diff --git a/tests/baselines/reference/wideningTuples4.js b/tests/baselines/reference/wideningTuples4.js new file mode 100644 index 00000000000..b4d16a3058b --- /dev/null +++ b/tests/baselines/reference/wideningTuples4.js @@ -0,0 +1,10 @@ +//// [wideningTuples4.ts] +var a: [any]; + +var b = a = [undefined, null]; +b = ["", ""]; + +//// [wideningTuples4.js] +var a; +var b = a = [undefined, null]; +b = ["", ""]; diff --git a/tests/baselines/reference/wideningTuples4.symbols b/tests/baselines/reference/wideningTuples4.symbols new file mode 100644 index 00000000000..95e7cc3cff8 --- /dev/null +++ b/tests/baselines/reference/wideningTuples4.symbols @@ -0,0 +1,12 @@ +=== tests/cases/conformance/types/tuple/wideningTuples4.ts === +var a: [any]; +>a : Symbol(a, Decl(wideningTuples4.ts, 0, 3)) + +var b = a = [undefined, null]; +>b : Symbol(b, Decl(wideningTuples4.ts, 2, 3)) +>a : Symbol(a, Decl(wideningTuples4.ts, 0, 3)) +>undefined : Symbol(undefined) + +b = ["", ""]; +>b : Symbol(b, Decl(wideningTuples4.ts, 2, 3)) + diff --git a/tests/baselines/reference/wideningTuples4.types b/tests/baselines/reference/wideningTuples4.types new file mode 100644 index 00000000000..6d101dd1e01 --- /dev/null +++ b/tests/baselines/reference/wideningTuples4.types @@ -0,0 +1,19 @@ +=== tests/cases/conformance/types/tuple/wideningTuples4.ts === +var a: [any]; +>a : [any] + +var b = a = [undefined, null]; +>b : [any, any] +>a = [undefined, null] : [undefined, null] +>a : [any] +>[undefined, null] : [undefined, null] +>undefined : undefined +>null : null + +b = ["", ""]; +>b = ["", ""] : [string, string] +>b : [any, any] +>["", ""] : [string, string] +>"" : string +>"" : string + diff --git a/tests/baselines/reference/wideningTuples5.errors.txt b/tests/baselines/reference/wideningTuples5.errors.txt new file mode 100644 index 00000000000..bfd72079f55 --- /dev/null +++ b/tests/baselines/reference/wideningTuples5.errors.txt @@ -0,0 +1,10 @@ +tests/cases/conformance/types/tuple/wideningTuples5.ts(1,6): error TS7005: Variable 'a' implicitly has an 'any' type. +tests/cases/conformance/types/tuple/wideningTuples5.ts(1,9): error TS7005: Variable 'b' implicitly has an 'any' type. + + +==== tests/cases/conformance/types/tuple/wideningTuples5.ts (2 errors) ==== + var [a, b] = [undefined, null]; + ~ +!!! error TS7005: Variable 'a' implicitly has an 'any' type. + ~ +!!! error TS7005: Variable 'b' implicitly has an 'any' type. \ No newline at end of file diff --git a/tests/baselines/reference/wideningTuples5.js b/tests/baselines/reference/wideningTuples5.js new file mode 100644 index 00000000000..5763fb3340f --- /dev/null +++ b/tests/baselines/reference/wideningTuples5.js @@ -0,0 +1,5 @@ +//// [wideningTuples5.ts] +var [a, b] = [undefined, null]; + +//// [wideningTuples5.js] +var _a = [undefined, null], a = _a[0], b = _a[1]; diff --git a/tests/baselines/reference/wideningTuples6.js b/tests/baselines/reference/wideningTuples6.js new file mode 100644 index 00000000000..b1d5e8ec0bd --- /dev/null +++ b/tests/baselines/reference/wideningTuples6.js @@ -0,0 +1,9 @@ +//// [wideningTuples6.ts] +var [a, b] = [undefined, null]; +a = ""; +b = ""; + +//// [wideningTuples6.js] +var _a = [undefined, null], a = _a[0], b = _a[1]; +a = ""; +b = ""; diff --git a/tests/baselines/reference/wideningTuples6.symbols b/tests/baselines/reference/wideningTuples6.symbols new file mode 100644 index 00000000000..88de6a7b9b7 --- /dev/null +++ b/tests/baselines/reference/wideningTuples6.symbols @@ -0,0 +1,12 @@ +=== tests/cases/conformance/types/tuple/wideningTuples6.ts === +var [a, b] = [undefined, null]; +>a : Symbol(a, Decl(wideningTuples6.ts, 0, 5)) +>b : Symbol(b, Decl(wideningTuples6.ts, 0, 7)) +>undefined : Symbol(undefined) + +a = ""; +>a : Symbol(a, Decl(wideningTuples6.ts, 0, 5)) + +b = ""; +>b : Symbol(b, Decl(wideningTuples6.ts, 0, 7)) + diff --git a/tests/baselines/reference/wideningTuples6.types b/tests/baselines/reference/wideningTuples6.types new file mode 100644 index 00000000000..d75c0b49e9e --- /dev/null +++ b/tests/baselines/reference/wideningTuples6.types @@ -0,0 +1,18 @@ +=== tests/cases/conformance/types/tuple/wideningTuples6.ts === +var [a, b] = [undefined, null]; +>a : any +>b : any +>[undefined, null] : [undefined, null] +>undefined : undefined +>null : null + +a = ""; +>a = "" : string +>a : any +>"" : string + +b = ""; +>b = "" : string +>b : any +>"" : string + diff --git a/tests/baselines/reference/wideningTuples7.errors.txt b/tests/baselines/reference/wideningTuples7.errors.txt new file mode 100644 index 00000000000..25fd1f58e64 --- /dev/null +++ b/tests/baselines/reference/wideningTuples7.errors.txt @@ -0,0 +1,10 @@ +tests/cases/conformance/types/tuple/wideningTuples7.ts(1,20): error TS7010: 'bar', which lacks return-type annotation, implicitly has an '[any]' return type. + + +==== tests/cases/conformance/types/tuple/wideningTuples7.ts (1 errors) ==== + var foo = function bar() { + ~~~ +!!! error TS7010: 'bar', which lacks return-type annotation, implicitly has an '[any]' return type. + let intermediate: [string]; + return intermediate = [undefined]; + }; \ No newline at end of file diff --git a/tests/baselines/reference/wideningTuples7.js b/tests/baselines/reference/wideningTuples7.js new file mode 100644 index 00000000000..4d94a1909ad --- /dev/null +++ b/tests/baselines/reference/wideningTuples7.js @@ -0,0 +1,11 @@ +//// [wideningTuples7.ts] +var foo = function bar() { + let intermediate: [string]; + return intermediate = [undefined]; +}; + +//// [wideningTuples7.js] +var foo = function bar() { + var intermediate; + return intermediate = [undefined]; +}; From 6fc08ea3e62baee65235abcb23c7572b8c61140d Mon Sep 17 00:00:00 2001 From: Jason Freeman Date: Tue, 14 Jul 2015 13:44:40 -0700 Subject: [PATCH 49/78] Clean up and address CR feedback --- src/compiler/checker.ts | 55 +++++++++---------- .../diagnosticInformationMap.generated.ts | 1 - src/compiler/diagnosticMessages.json | 8 --- 3 files changed, 25 insertions(+), 39 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5209f02847e..20e0af5e873 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3943,7 +3943,7 @@ namespace ts { let id = getTypeListId(elementTypes); let type = tupleTypes[id]; if (!type) { - type = tupleTypes[id] = createObjectType(TypeFlags.Tuple); + type = tupleTypes[id] = createObjectType(TypeFlags.Tuple | getWideningFlagsOfTypes(elementTypes)); type.elementTypes = elementTypes; } return type; @@ -5300,7 +5300,7 @@ namespace ts { * Prefer using isTupleLikeType() unless the use of `elementTypes` is required. */ function isTupleType(type: Type): type is TupleType { - return (type.flags & TypeFlags.Tuple) && !!(type).elementTypes; + return !!(type.flags & TypeFlags.Tuple); } function getWidenedTypeOfObjectLiteral(type: Type): Type { @@ -5348,31 +5348,33 @@ namespace ts { return type; } - function reportWideningErrorsInType(type: Type, expression: Expression): boolean { + /** + * Reports implicit any errors that occur as a result of widening 'null' and 'undefined' + * to 'any'. A call to reportWideningErrorsInType is normally accompanied by a call to + * getWidenedType. But in some cases getWidenedType is called without reporting errors + * (type argument inference is an example). + * + * The return value indicates whether an error was in fact reported. The particular circumstances + * are on a best effort basis. Currently, if the null or undefined that causes widening is inside + * an object literal property (arbitrarily deeply), this function reports an error. If no error is + * reported, reportImplicitAnyError is a suitable fallback to report a general error. + */ + function reportWideningErrorsInType(type: Type): boolean { let errorReported = false; if (type.flags & TypeFlags.Union) { for (let t of (type).types) { - if (reportWideningErrorsInType(t, expression)) { + if (reportWideningErrorsInType(t)) { errorReported = true; } } } if (isArrayType(type)) { - return reportWideningErrorsInType((type).typeArguments[0], expression); + return reportWideningErrorsInType((type).typeArguments[0]); } if (isTupleType(type)) { - let { elementTypes } = type; - for (let i = 0; i < elementTypes.length; i++) { - let t = elementTypes[i]; - if (t.flags & TypeFlags.ContainsUndefinedOrNull) { - if (reportWideningErrorsInType(t, expression)) { - errorReported = true; - } - else if (expression.kind === SyntaxKind.ArrayLiteralExpression) { - let element = (expression).elements[i]; - error(element, Diagnostics.Array_element_at_index_0_implicitly_has_an_1_type, i, typeToString(getWidenedType(t))); - errorReported = true; - } + for (let t of type.elementTypes) { + if (reportWideningErrorsInType(t)) { + errorReported = true; } } } @@ -5380,7 +5382,7 @@ namespace ts { for (let p of getPropertiesOfObjectType(type)) { let t = getTypeOfSymbol(p); if (t.flags & TypeFlags.ContainsUndefinedOrNull) { - if (!reportWideningErrorsInType(t, expression)) { + if (!reportWideningErrorsInType(t)) { error(p.valueDeclaration, Diagnostics.Object_literal_s_property_0_implicitly_has_an_1_type, p.name, typeToString(getWidenedType(t))); } errorReported = true; @@ -5425,7 +5427,7 @@ namespace ts { function reportErrorsFromWidening(declaration: Declaration, type: Type) { if (produceDiagnostics && compilerOptions.noImplicitAny && type.flags & TypeFlags.ContainsUndefinedOrNull) { // Report implicit any error within type if possible, otherwise report error on declaration - if (!reportWideningErrorsInType(type, declaration.kind === SyntaxKind.VariableDeclaration && (declaration).initializer)) { + if (!reportWideningErrorsInType(type)) { reportImplicitAnyError(declaration, type); } } @@ -6801,7 +6803,6 @@ namespace ts { let hasSpreadElement = false; let elementTypes: Type[] = []; let inDestructuringPattern = isAssignmentTarget(node); - let typeFlags: TypeFlags; for (let e of elements) { if (inDestructuringPattern && e.kind === SyntaxKind.SpreadElementExpression) { // Given the following situation: @@ -6821,23 +6822,21 @@ namespace ts { (languageVersion >= ScriptTarget.ES6 ? getElementTypeOfIterable(restArrayType, /*errorNode*/ undefined) : undefined); if (restElementType) { elementTypes.push(restElementType); - typeFlags |= restElementType.flags; } } else { let type = checkExpression(e, contextualMapper); elementTypes.push(type); - typeFlags |= type.flags; } hasSpreadElement = hasSpreadElement || e.kind === SyntaxKind.SpreadElementExpression; } if (!hasSpreadElement) { let contextualType = getContextualType(node); if (contextualType && contextualTypeIsTupleLikeType(contextualType) || inDestructuringPattern) { - return addTypeFlags(createTupleType(elementTypes), typeFlags & TypeFlags.RequiresWidening); + return createTupleType(elementTypes); } } - return addTypeFlags(createArrayType(getUnionType(elementTypes)), typeFlags & TypeFlags.RequiresWidening); + return createArrayType(getUnionType(elementTypes)); } function isNumericName(name: DeclarationName): boolean { @@ -6953,7 +6952,8 @@ namespace ts { let stringIndexType = getIndexType(IndexKind.String); let numberIndexType = getIndexType(IndexKind.Number); let result = createAnonymousType(node.symbol, propertiesTable, emptyArray, emptyArray, stringIndexType, numberIndexType); - return addTypeFlags(result, TypeFlags.ObjectLiteral | TypeFlags.ContainsObjectLiteral | (typeFlags & TypeFlags.ContainsUndefinedOrNull)); + result.flags |= TypeFlags.ObjectLiteral | TypeFlags.ContainsObjectLiteral | (typeFlags & TypeFlags.ContainsUndefinedOrNull); + return result; function getIndexType(kind: IndexKind) { if (contextualType && contextualTypeHasIndexSignature(contextualType, kind)) { @@ -6979,11 +6979,6 @@ namespace ts { } } - function addTypeFlags(type: Type, flags: TypeFlags): Type { - type.flags |= flags; - return type; - } - function checkJsxSelfClosingElement(node: JsxSelfClosingElement) { checkJsxOpeningLikeElement(node); return jsxElementType || anyType; diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index ce28cbbc387..a0a95d47c8c 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -589,7 +589,6 @@ namespace ts { Function_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions: { code: 7024, category: DiagnosticCategory.Error, key: "Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions." }, Generator_implicitly_has_type_0_because_it_does_not_yield_any_values_Consider_supplying_a_return_type: { code: 7025, category: DiagnosticCategory.Error, key: "Generator implicitly has type '{0}' because it does not yield any values. Consider supplying a return type." }, JSX_element_implicitly_has_type_any_because_no_interface_JSX_0_exists: { code: 7026, category: DiagnosticCategory.Error, key: "JSX element implicitly has type 'any' because no interface 'JSX.{0}' exists" }, - Array_element_at_index_0_implicitly_has_an_1_type: { code: 7027, category: DiagnosticCategory.Error, key: "Array element at index {0} implicitly has an '{1}' type." }, You_cannot_rename_this_element: { code: 8000, category: DiagnosticCategory.Error, key: "You cannot rename this element." }, You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library: { code: 8001, category: DiagnosticCategory.Error, key: "You cannot rename elements that are defined in the standard TypeScript library." }, import_can_only_be_used_in_a_ts_file: { code: 8002, category: DiagnosticCategory.Error, key: "'import ... =' can only be used in a .ts file." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 65e3bab9ec5..acf4e74ae9f 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2347,14 +2347,6 @@ "category": "Error", "code": 7026 }, - "JSX element implicitly has type 'any' because no interface 'JSX.{0}' exists": { - "category": "Error", - "code": 7026 - }, - "Array element at index {0} implicitly has an '{1}' type.": { - "category": "Error", - "code": 7027 - }, "You cannot rename this element.": { From acb9f709e497f9ef5ab8c288f0bc16b43dde77c6 Mon Sep 17 00:00:00 2001 From: Dick van den Brink Date: Wed, 15 Jul 2015 00:17:27 +0200 Subject: [PATCH 50/78] Fix occurrences in ClassExpressions --- src/services/services.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/services/services.ts b/src/services/services.ts index 453542aeb08..fc939a37513 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -4682,12 +4682,13 @@ namespace ts { // Make sure we only highlight the keyword when it makes sense to do so. if (isAccessibilityModifier(modifier)) { if (!(container.kind === SyntaxKind.ClassDeclaration || + container.kind === SyntaxKind.ClassExpression || (declaration.kind === SyntaxKind.Parameter && hasKind(container, SyntaxKind.Constructor)))) { return undefined; } } else if (modifier === SyntaxKind.StaticKeyword) { - if (container.kind !== SyntaxKind.ClassDeclaration) { + if (!(container.kind === SyntaxKind.ClassDeclaration || container.kind === SyntaxKind.ClassExpression)) { return undefined; } } @@ -4726,12 +4727,13 @@ namespace ts { (container.parent).members); break; case SyntaxKind.ClassDeclaration: - nodes = (container).members; + case SyntaxKind.ClassExpression: + nodes = (container).members; // 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 => { + let constructor = forEach((container).members, member => { return member.kind === SyntaxKind.Constructor && member; }); From 46292a2263adc49e5644046b710a72ada91d569e Mon Sep 17 00:00:00 2001 From: Dick van den Brink Date: Wed, 15 Jul 2015 00:18:59 +0200 Subject: [PATCH 51/78] Add test for occurrences in ClassExpressions --- ...etOccurrencesClassExpressionConstructor.ts | 23 +++++++++++++++ .../getOccurrencesClassExpressionPrivate.ts | 27 +++++++++++++++++ .../getOccurrencesClassExpressionPublic.ts | 27 +++++++++++++++++ .../getOccurrencesClassExpressionStatic.ts | 29 +++++++++++++++++++ 4 files changed, 106 insertions(+) create mode 100644 tests/cases/fourslash/getOccurrencesClassExpressionConstructor.ts create mode 100644 tests/cases/fourslash/getOccurrencesClassExpressionPrivate.ts create mode 100644 tests/cases/fourslash/getOccurrencesClassExpressionPublic.ts create mode 100644 tests/cases/fourslash/getOccurrencesClassExpressionStatic.ts diff --git a/tests/cases/fourslash/getOccurrencesClassExpressionConstructor.ts b/tests/cases/fourslash/getOccurrencesClassExpressionConstructor.ts new file mode 100644 index 00000000000..5fa778ef8cd --- /dev/null +++ b/tests/cases/fourslash/getOccurrencesClassExpressionConstructor.ts @@ -0,0 +1,23 @@ +/// + +////let A = class Foo { +//// [|constructor|](); +//// [|constructor|](x: number); +//// [|constructor|](y: string); +//// [|constructor|](a?: any) { +//// } +////} +//// +////let B = class D { +//// constructor(x: number) { +//// } +////} + +const ranges = test.ranges(); +for (let r of ranges) { + goTo.position(r.start); + + for (let range of ranges) { + verify.occurrencesAtPositionContains(range, false); + } +} diff --git a/tests/cases/fourslash/getOccurrencesClassExpressionPrivate.ts b/tests/cases/fourslash/getOccurrencesClassExpressionPrivate.ts new file mode 100644 index 00000000000..b008ec237b8 --- /dev/null +++ b/tests/cases/fourslash/getOccurrencesClassExpressionPrivate.ts @@ -0,0 +1,27 @@ +/// + +////let A = class Foo { +//// [|private|] foo; +//// [|private|] private; +//// constructor([|private|] y: string, public x: string) { +//// } +//// [|private|] method() { } +//// public method2() { } +//// [|private|] static static() { } +////} +//// +////let B = class D { +//// constructor(private x: number) { +//// } +//// private test() {} +//// public test2() {} +////} + +const ranges = test.ranges(); +for (let r of ranges) { + goTo.position(r.start); + + for (let range of ranges) { + verify.occurrencesAtPositionContains(range, false); + } +} diff --git a/tests/cases/fourslash/getOccurrencesClassExpressionPublic.ts b/tests/cases/fourslash/getOccurrencesClassExpressionPublic.ts new file mode 100644 index 00000000000..3070fd4f6ca --- /dev/null +++ b/tests/cases/fourslash/getOccurrencesClassExpressionPublic.ts @@ -0,0 +1,27 @@ +/// + +////let A = class Foo { +//// [|public|] foo; +//// [|public|] public; +//// constructor([|public|] y: string, private x: string) { +//// } +//// [|public|] method() { } +//// private method2() {} +//// [|public|] static static() { } +////} +//// +////let B = class D { +//// constructor(private x: number) { +//// } +//// private test() {} +//// public test2() {} +////} + +const ranges = test.ranges(); +for (let r of ranges) { + goTo.position(r.start); + + for (let range of ranges) { + verify.occurrencesAtPositionContains(range, false); + } +} diff --git a/tests/cases/fourslash/getOccurrencesClassExpressionStatic.ts b/tests/cases/fourslash/getOccurrencesClassExpressionStatic.ts new file mode 100644 index 00000000000..567c0c4eccd --- /dev/null +++ b/tests/cases/fourslash/getOccurrencesClassExpressionStatic.ts @@ -0,0 +1,29 @@ +/// + +////let A = class Foo { +//// public static foo; +//// [|static|] a; +//// constructor(public y: string, private x: string) { +//// } +//// public method() { } +//// private method2() {} +//// public [|static|] static() { } +//// private [|static|] static2() { } +////} +//// +////let B = class D { +//// static a; +//// constructor(private x: number) { +//// } +//// private static test() {} +//// public static test2() {} +////} + +const ranges = test.ranges(); +for (let r of ranges) { + goTo.position(r.start); + + for (let range of ranges) { + verify.occurrencesAtPositionContains(range, false); + } +} From 7076e3c9dd67008fb28b296e9ba3fcb348cec4f9 Mon Sep 17 00:00:00 2001 From: Dan Quirk Date: Tue, 14 Jul 2015 16:16:30 -0700 Subject: [PATCH 52/78] Fix most tslint errors in the harness --- src/harness/compilerRunner.ts | 2 +- src/harness/fourslash.ts | 31 ++++++++++++++++--------------- src/harness/fourslashRunner.ts | 2 +- src/harness/projectsRunner.ts | 8 ++++---- src/harness/runner.ts | 10 +++++----- src/harness/sourceMapRecorder.ts | 13 +++++++------ src/harness/test262Runner.ts | 8 ++++---- src/harness/typeWriter.ts | 2 +- 8 files changed, 39 insertions(+), 37 deletions(-) diff --git a/src/harness/compilerRunner.ts b/src/harness/compilerRunner.ts index 39d4b053956..de96105a812 100644 --- a/src/harness/compilerRunner.ts +++ b/src/harness/compilerRunner.ts @@ -44,7 +44,7 @@ class CompilerBaselineRunner extends RunnerBase { // Everything declared here should be cleared out in the "after" callback. var justName: string; var content: string; - var testCaseContent: { settings: Harness.TestCaseParser.CompilerSetting[]; testUnitData: Harness.TestCaseParser.TestUnitData[]; } + var testCaseContent: { settings: Harness.TestCaseParser.CompilerSetting[]; testUnitData: Harness.TestCaseParser.TestUnitData[]; }; var units: Harness.TestCaseParser.TestUnitData[]; var tcSettings: Harness.TestCaseParser.CompilerSetting[]; diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index c374f8add60..e28f92552c4 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -1,6 +1,6 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -135,7 +135,7 @@ module FourSlash { var fileMetadataNames = [metadataOptionNames.fileName, metadataOptionNames.emitThisFile, metadataOptionNames.resolveReference]; var globalMetadataNames = [metadataOptionNames.allowNonTsExtensions, metadataOptionNames.baselineFile, metadataOptionNames.declaration, metadataOptionNames.mapRoot, metadataOptionNames.module, metadataOptionNames.out, - metadataOptionNames.outDir, metadataOptionNames.sourceMap, metadataOptionNames.sourceRoot] + metadataOptionNames.outDir, metadataOptionNames.sourceMap, metadataOptionNames.sourceRoot]; function convertGlobalOptionsToCompilerOptions(globalOptions: { [idx: string]: string }): ts.CompilerOptions { var settings: ts.CompilerOptions = { target: ts.ScriptTarget.ES5 }; @@ -192,7 +192,7 @@ module FourSlash { export class TestCancellationToken implements ts.HostCancellationToken { // 0 - cancelled - // >0 - not cancelled + // >0 - not cancelled // <0 - not cancelled and value denotes number of isCancellationRequested after which token become cancelled private static NotCanceled: number = -1; private numberOfCallsBeforeCancellation: number = TestCancellationToken.NotCanceled; @@ -271,7 +271,7 @@ module FourSlash { private taoInvalidReason: string = null; private inputFiles: ts.Map = {}; // Map between inputFile's fileName and its content for easily looking up when resolving references - + // Add input file which has matched file name with the given reference-file path. // This is necessary when resolveReference flag is specified private addMatchedInputFile(referenceFilePath: string) { @@ -426,7 +426,7 @@ module FourSlash { this.activeFile = fileToOpen; var fileName = fileToOpen.fileName.replace(Harness.IO.directoryName(fileToOpen.fileName), '').substr(1); this.scenarioActions.push(''); - + // Let the host know that this file is now open this.languageServiceAdapterHost.openFile(fileToOpen.fileName); } @@ -755,7 +755,7 @@ module FourSlash { error += "Expected documentation: " + expectedDocumentation + " to equal: " + ts.displayPartsToString(details.documentation) + "."; } if (expectedKind) { - error += "Expected kind: " + expectedKind + " to equal: " + filterCompletions[0].kind + "." + error += "Expected kind: " + expectedKind + " to equal: " + filterCompletions[0].kind + "."; } this.raiseError(error); } @@ -1151,6 +1151,7 @@ module FourSlash { var length: number; var prefixString = " >"; + var pos = 0; var addSpanInfoString = () => { if (previousSpanInfo) { resultString += currentLine; @@ -1163,7 +1164,7 @@ module FourSlash { } }; - for (var pos = 0; pos < this.activeFile.content.length; pos++) { + for (pos < this.activeFile.content.length; pos++) { if (pos === 0 || pos === fileLineMap[nextLine]) { nextLine++; addSpanInfoString(); @@ -1347,7 +1348,7 @@ module FourSlash { var offset = this.currentCaretPosition; var ch = ""; - var checkCadence = (count >> 2) + 1 + var checkCadence = (count >> 2) + 1; for (var i = 0; i < count; i++) { // Make the edit @@ -1363,7 +1364,7 @@ module FourSlash { var edits = this.languageService.getFormattingEditsAfterKeystroke(this.activeFile.fileName, offset, ch, this.formatCodeOptions); if (edits.length) { offset += this.applyEdits(this.activeFile.fileName, edits, true); - //this.checkPostEditInvariants(); + // this.checkPostEditInvariants(); } } } @@ -1388,7 +1389,7 @@ module FourSlash { var offset = this.currentCaretPosition; var ch = ""; - var checkCadence = (count >> 2) + 1 + var checkCadence = (count >> 2) + 1; for (var i = 0; i < count; i++) { offset--; @@ -1503,8 +1504,8 @@ module FourSlash { } private checkPostEditInvariants() { - if (this.testType !== FourSlashTestType.Native) { - // getSourcefile() results can not be serialized. Only perform these verifications + if (this.testType !== FourSlashTestType.Native) { + // getSourcefile() results can not be serialized. Only perform these verifications // if running against a native LS object. return; } @@ -1883,7 +1884,7 @@ module FourSlash { assert.equal( expected.join(","), actual.fileNameList.map( file => { - return file.replace(this.basePath + "/", "") + return file.replace(this.basePath + "/", ""); }).join(",") ); } @@ -2156,7 +2157,7 @@ module FourSlash { // Get the text of the entire line the caret is currently at private getCurrentLineContent() { - var text = this.getFileContent(this.activeFile.fileName) + var text = this.getFileContent(this.activeFile.fileName); var pos = this.currentCaretPosition; var startPos = pos, endPos = pos; @@ -2286,7 +2287,7 @@ module FourSlash { } public setCancelled(numberOfCalls: number): void { - this.cancellationToken.setCancelled(numberOfCalls) + this.cancellationToken.setCancelled(numberOfCalls); } public resetCancelled(): void { diff --git a/src/harness/fourslashRunner.ts b/src/harness/fourslashRunner.ts index 97a7f191ec9..aa7174cc83b 100644 --- a/src/harness/fourslashRunner.ts +++ b/src/harness/fourslashRunner.ts @@ -46,7 +46,7 @@ class FourSlashRunner extends RunnerBase { if (testIndex >= 0) fn = fn.substr(testIndex); if (justName && !justName.match(/fourslash\.ts$/i) && !justName.match(/\.d\.ts$/i)) { - it(this.testSuiteName + ' test ' + justName + ' runs correctly',() => { + it(this.testSuiteName + ' test ' + justName + ' runs correctly', () => { FourSlash.runFourSlashTest(this.basePath, this.testType, fn); }); } diff --git a/src/harness/projectsRunner.ts b/src/harness/projectsRunner.ts index 01dc52308ff..23b1e823439 100644 --- a/src/harness/projectsRunner.ts +++ b/src/harness/projectsRunner.ts @@ -124,7 +124,7 @@ class ProjectRunner extends RunnerBase { return ts.sys.resolvePath(testCase.projectRoot); } - function compileProjectFiles(moduleKind: ts.ModuleKind, getInputFiles: ()=> string[], + function compileProjectFiles(moduleKind: ts.ModuleKind, getInputFiles: () => string[], getSourceFileText: (fileName: string) => string, writeFile: (fileName: string, data: string, writeByteOrderMark: boolean) => void): CompileProjectFilesResult { @@ -302,7 +302,7 @@ class ProjectRunner extends RunnerBase { } }); - return compileProjectFiles(compilerResult.moduleKind,getInputFiles, getSourceFileText, writeFile); + return compileProjectFiles(compilerResult.moduleKind, getInputFiles, getSourceFileText, writeFile); function findOutpuDtsFile(fileName: string) { return ts.forEach(compilerResult.outputFiles, outputFile => outputFile.emittedFileName === fileName ? outputFile : undefined); @@ -333,6 +333,8 @@ class ProjectRunner extends RunnerBase { describe('Projects tests', () => { describe(name, () => { function verifyCompilerResults(moduleKind: ts.ModuleKind) { + var compilerResult: BatchCompileProjectTestCaseResult; + function getCompilerResolutionInfo() { var resolutionInfo: ProjectRunnerTestCaseResolutionInfo = { scenario: testCase.scenario, @@ -357,8 +359,6 @@ class ProjectRunner extends RunnerBase { return resolutionInfo; } - var compilerResult: BatchCompileProjectTestCaseResult; - it(name + ": " + moduleNameToString(moduleKind) , () => { // Compile using node compilerResult = batchCompilerProjectTestCase(moduleKind); diff --git a/src/harness/runner.ts b/src/harness/runner.ts index 13d93302f18..558f8419f25 100644 --- a/src/harness/runner.ts +++ b/src/harness/runner.ts @@ -1,6 +1,6 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -20,6 +20,9 @@ /// /// +var runners: RunnerBase[] = []; +var iterations: number = 1; + function runTests(runners: RunnerBase[]) { for (var i = iterations; i > 0; i--) { for (var j = 0; j < runners.length; j++) { @@ -28,9 +31,6 @@ function runTests(runners: RunnerBase[]) { } } -var runners: RunnerBase[] = []; -var iterations: number = 1; - // users can define tests to run in mytest.config that will override cmd line args, otherwise use cmd line args (test.config), otherwise no options var mytestconfig = 'mytest.config'; var testconfig = 'test.config'; @@ -99,7 +99,7 @@ if (runners.length === 0) { runners.push(new FourSlashRunner(FourSlashTestType.Native)); runners.push(new FourSlashRunner(FourSlashTestType.Shims)); runners.push(new FourSlashRunner(FourSlashTestType.Server)); - //runners.push(new GeneratedFourslashRunner()); + // runners.push(new GeneratedFourslashRunner()); } ts.sys.newLine = '\r\n'; diff --git a/src/harness/sourceMapRecorder.ts b/src/harness/sourceMapRecorder.ts index ed079774d94..346997c07aa 100644 --- a/src/harness/sourceMapRecorder.ts +++ b/src/harness/sourceMapRecorder.ts @@ -1,6 +1,6 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -143,7 +143,7 @@ module Harness.SourceMapRecoder { return { error: errorDecodeOfEncodedMapping, sourceMapSpan: decodeOfEncodedMapping }; } - // 2. Relative sourceIndex + // 2. Relative sourceIndex decodeOfEncodedMapping.sourceIndex += base64VLQFormatDecode(); // Incorrect sourceIndex dont support this map if (createErrorIfCondition(decodeOfEncodedMapping.sourceIndex < 0, "Invalid sourceIndex found")) { @@ -165,7 +165,7 @@ module Harness.SourceMapRecoder { return { error: errorDecodeOfEncodedMapping, sourceMapSpan: decodeOfEncodedMapping }; } - // 4. Relative sourceColumn 0 based + // 4. Relative sourceColumn 0 based decodeOfEncodedMapping.sourceColumn += base64VLQFormatDecode(); // Incorrect sourceColumn dont support this map if (createErrorIfCondition(decodeOfEncodedMapping.sourceColumn < 1, "Invalid sourceLine found")) { @@ -278,7 +278,7 @@ module Harness.SourceMapRecoder { } if (spansOnSingleLine.length && spansOnSingleLine[0].sourceMapSpan.emittedLine !== sourceMapSpan.emittedLine) { - // On different line from the one that we have been recording till now, + // On different line from the one that we have been recording till now, writeRecordedSpans(); spansOnSingleLine = [{ sourceMapSpan: sourceMapSpan, decodeErrors: decodedErrors }]; } @@ -329,6 +329,8 @@ module Harness.SourceMapRecoder { } function writeRecordedSpans() { + var markerIds: string[] = []; + function getMarkerId(markerIndex: number) { var markerId = ""; if (spanMarkerContinues) { @@ -416,7 +418,6 @@ module Harness.SourceMapRecoder { writeJsFileLines(currentJsLine); // Emit markers - var markerIds: string[] = []; iterateSpans(writeSourceMapMarker); var jsFileText = getTextOfLine(currentJsLine, jsLineMap, jsFile.code); @@ -455,7 +456,7 @@ module Harness.SourceMapRecoder { SourceMapSpanWriter.recordSourceMapSpan(decodedSourceMapping); } } - SourceMapSpanWriter.close();// If the last spans werent emitted, emit them + SourceMapSpanWriter.close(); // If the last spans werent emitted, emit them } sourceMapRecoder.Close(); return sourceMapRecoder.lines.join('\r\n'); diff --git a/src/harness/test262Runner.ts b/src/harness/test262Runner.ts index 5f8250c5e23..dea5e9b4741 100644 --- a/src/harness/test262Runner.ts +++ b/src/harness/test262Runner.ts @@ -63,7 +63,7 @@ class Test262BaselineRunner extends RunnerBase { it('has the expected emitted code', () => { Harness.Baseline.runBaseline('has the expected emitted code', testState.filename + '.output.js', () => { - var files = testState.compilerResult.files.filter(f=> f.fileName !== Test262BaselineRunner.helpersFilePath); + var files = testState.compilerResult.files.filter(f => f.fileName !== Test262BaselineRunner.helpersFilePath); return Harness.Compiler.collateOutputs(files); }, false, Test262BaselineRunner.baselineOptions); }); @@ -84,8 +84,8 @@ class Test262BaselineRunner extends RunnerBase { Utils.assertInvariants(sourceFile, /*parent:*/ undefined); }); - it('has the expected AST',() => { - Harness.Baseline.runBaseline('has the expected AST', testState.filename + '.AST.txt',() => { + it('has the expected AST', () => { + Harness.Baseline.runBaseline('has the expected AST', testState.filename + '.AST.txt', () => { var sourceFile = testState.program.getSourceFile(Test262BaselineRunner.getTestFilePath(testState.filename)); return Utils.sourceFileToJSON(sourceFile); }, false, Test262BaselineRunner.baselineOptions); @@ -105,4 +105,4 @@ class Test262BaselineRunner extends RunnerBase { this.tests.forEach(test => this.runTest(test)); } } -} \ No newline at end of file +} diff --git a/src/harness/typeWriter.ts b/src/harness/typeWriter.ts index b68e606c79d..b138b360d8c 100644 --- a/src/harness/typeWriter.ts +++ b/src/harness/typeWriter.ts @@ -13,7 +13,7 @@ class TypeWriterWalker { private checker: ts.TypeChecker; constructor(private program: ts.Program, fullTypeCheck: boolean) { - // Consider getting both the diagnostics checker and the non-diagnostics checker to verify + // Consider getting both the diagnostics checker and the non-diagnostics checker to verify // they are consistent. this.checker = fullTypeCheck ? program.getDiagnosticsProducingTypeChecker() From 53308fe07f53999f97a8b8954ad3383a8b6bf112 Mon Sep 17 00:00:00 2001 From: Dan Quirk Date: Tue, 14 Jul 2015 17:00:51 -0700 Subject: [PATCH 53/78] Fix semicolon --- 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 e28f92552c4..c83537a0847 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -1164,7 +1164,7 @@ module FourSlash { } }; - for (pos < this.activeFile.content.length; pos++) { + for (; pos < this.activeFile.content.length; pos++) { if (pos === 0 || pos === fileLineMap[nextLine]) { nextLine++; addSpanInfoString(); From fcf872f52e45174cfe80d55f6e7dd1fd9598bb10 Mon Sep 17 00:00:00 2001 From: Dan Quirk Date: Tue, 14 Jul 2015 17:01:10 -0700 Subject: [PATCH 54/78] Update linting task to include harness sources --- Jakefile.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Jakefile.js b/Jakefile.js index cdf8e30efe0..f1e973a2d80 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -730,8 +730,9 @@ task("update-sublime", ["local", serverFile], function() { // run this task automatically desc("Runs tslint on the compiler sources"); task("lint", [], function() { - for(var i in compilerSources) { - var f = compilerSources[i]; + var lintTagets = compilerSources.concat(harnessSources); + for(var i in lintTagets) { + var f = lintTagets[i]; var cmd = 'tslint -f ' + f; exec(cmd, function() { console.log('SUCCESS: No linter errors'); }, From cb4577e3e8fd147f28de894d52ed666b7e927d33 Mon Sep 17 00:00:00 2001 From: Dan Quirk Date: Tue, 14 Jul 2015 17:47:07 -0700 Subject: [PATCH 55/78] var->let and a few misc other fixes --- src/harness/compilerRunner.ts | 80 +-- src/harness/fourslash.ts | 708 +++++++++++++------------- src/harness/fourslashRunner.ts | 20 +- src/harness/harness.ts | 370 +++++++------- src/harness/harnessLanguageService.ts | 64 +-- src/harness/loggedIO.ts | 38 +- src/harness/projectsRunner.ts | 78 +-- src/harness/runner.ts | 16 +- src/harness/runnerbase.ts | 8 +- src/harness/rwcRunner.ts | 54 +- src/harness/sourceMapRecorder.ts | 96 ++-- src/harness/test262Runner.ts | 24 +- src/harness/typeWriter.ts | 20 +- 13 files changed, 786 insertions(+), 790 deletions(-) diff --git a/src/harness/compilerRunner.ts b/src/harness/compilerRunner.ts index de96105a812..97c808ef542 100644 --- a/src/harness/compilerRunner.ts +++ b/src/harness/compilerRunner.ts @@ -42,27 +42,27 @@ class CompilerBaselineRunner extends RunnerBase { describe('compiler tests for ' + fileName, () => { // Mocha holds onto the closure environment of the describe callback even after the test is done. // Everything declared here should be cleared out in the "after" callback. - var justName: string; - var content: string; - var testCaseContent: { settings: Harness.TestCaseParser.CompilerSetting[]; testUnitData: Harness.TestCaseParser.TestUnitData[]; }; + let justName: string; + let content: string; + let testCaseContent: { settings: Harness.TestCaseParser.CompilerSetting[]; testUnitData: Harness.TestCaseParser.TestUnitData[]; }; - var units: Harness.TestCaseParser.TestUnitData[]; - var tcSettings: Harness.TestCaseParser.CompilerSetting[]; - var createNewInstance: boolean; + let units: Harness.TestCaseParser.TestUnitData[]; + let tcSettings: Harness.TestCaseParser.CompilerSetting[]; + let createNewInstance: boolean; - var lastUnit: Harness.TestCaseParser.TestUnitData; - var rootDir: string; + let lastUnit: Harness.TestCaseParser.TestUnitData; + let rootDir: string; - var result: Harness.Compiler.CompilerResult; - var program: ts.Program; - var options: ts.CompilerOptions; + let result: Harness.Compiler.CompilerResult; + let program: ts.Program; + let options: ts.CompilerOptions; // equivalent to the files that will be passed on the command line - var toBeCompiled: { unitName: string; content: string }[]; + let toBeCompiled: { unitName: string; content: string }[]; // equivalent to other files on the file system not directly passed to the compiler (ie things that are referenced by other files) - var otherFiles: { unitName: string; content: string }[]; - var harnessCompiler: Harness.Compiler.HarnessCompiler; + let otherFiles: { unitName: string; content: string }[]; + let harnessCompiler: Harness.Compiler.HarnessCompiler; - var createNewInstance = false; + let createNewInstance = false; before(() => { justName = fileName.replace(/^.*[\\\/]/, ''); // strips the fileName from the path. @@ -105,7 +105,7 @@ class CompilerBaselineRunner extends RunnerBase { /* The compiler doesn't handle certain flags flipping during a single compilation setting. Tests on these flags will need a fresh compiler instance for themselves and then create a fresh one for the next test. Would be nice to get dev fixes eventually to remove this limitation. */ - for (var i = 0; i < tcSettings.length; ++i) { + for (let i = 0; i < tcSettings.length; ++i) { // noImplicitAny is passed to getCompiler, but target is just passed in the settings blob to setCompilerSettings if (!createNewInstance && (tcSettings[i].flag == "noimplicitany" || tcSettings[i].flag === 'target')) { harnessCompiler = Harness.Compiler.getCompiler(); @@ -162,7 +162,7 @@ class CompilerBaselineRunner extends RunnerBase { it('Correct sourcemap content for ' + fileName, () => { if (options.sourceMap || options.inlineSourceMap) { Harness.Baseline.runBaseline('Correct sourcemap content for ' + fileName, justName.replace(/\.tsx?$/, '.sourcemap.txt'), () => { - var record = result.getSourceMapRecord(); + let record = result.getSourceMapRecord(); if (options.noEmitOnError && result.errors.length !== 0 && record === undefined) { // Because of the noEmitOnError option no files are created. We need to return null because baselining isn't required. return null; @@ -180,18 +180,18 @@ class CompilerBaselineRunner extends RunnerBase { // check js output Harness.Baseline.runBaseline('Correct JS output for ' + fileName, justName.replace(/\.tsx?/, '.js'), () => { - var tsCode = ''; - var tsSources = otherFiles.concat(toBeCompiled); + let tsCode = ''; + let tsSources = otherFiles.concat(toBeCompiled); if (tsSources.length > 1) { tsCode += '//// [' + fileName + '] ////\r\n\r\n'; } - for (var i = 0; i < tsSources.length; i++) { + for (let i = 0; i < tsSources.length; i++) { tsCode += '//// [' + Harness.Path.getFileName(tsSources[i].unitName) + ']\r\n'; tsCode += tsSources[i].content + (i < (tsSources.length - 1) ? '\r\n' : ''); } - var jsCode = ''; - for (var i = 0; i < result.files.length; i++) { + let jsCode = ''; + for (let i = 0; i < result.files.length; i++) { jsCode += '//// [' + Harness.Path.getFileName(result.files[i].fileName) + ']\r\n'; jsCode += getByteOrderMarkText(result.files[i]); jsCode += result.files[i].code; @@ -199,14 +199,14 @@ class CompilerBaselineRunner extends RunnerBase { if (result.declFilesCode.length > 0) { jsCode += '\r\n\r\n'; - for (var i = 0; i < result.declFilesCode.length; i++) { + for (let i = 0; i < result.declFilesCode.length; i++) { jsCode += '//// [' + Harness.Path.getFileName(result.declFilesCode[i].fileName) + ']\r\n'; jsCode += getByteOrderMarkText(result.declFilesCode[i]); jsCode += result.declFilesCode[i].code; } } - var declFileCompilationResult = harnessCompiler.compileDeclarationFiles(toBeCompiled, otherFiles, result, function (settings) { + let declFileCompilationResult = harnessCompiler.compileDeclarationFiles(toBeCompiled, otherFiles, result, function (settings) { harnessCompiler.setCompilerSettings(tcSettings); }, options); @@ -244,8 +244,8 @@ class CompilerBaselineRunner extends RunnerBase { return null; } - var sourceMapCode = ''; - for (var i = 0; i < result.sourceMaps.length; i++) { + let sourceMapCode = ''; + for (let i = 0; i < result.sourceMaps.length; i++) { sourceMapCode += '//// [' + Harness.Path.getFileName(result.sourceMaps[i].fileName) + ']\r\n'; sourceMapCode += getByteOrderMarkText(result.sourceMaps[i]); sourceMapCode += result.sourceMaps[i].code; @@ -293,7 +293,7 @@ class CompilerBaselineRunner extends RunnerBase { // Produce baselines. The first gives the types for all expressions. // The second gives symbols for all identifiers. - var e1: Error, e2: Error; + let e1: Error, e2: Error; try { checkBaseLines(/*isSymbolBaseLine:*/ false); } @@ -335,20 +335,20 @@ class CompilerBaselineRunner extends RunnerBase { let typeMap: { [fileName: string]: { [lineNum: number]: string[]; } } = {}; allFiles.forEach(file => { - var codeLines = file.content.split('\n'); + let codeLines = file.content.split('\n'); typeWriterResults[file.unitName].forEach(result => { if (isSymbolBaseline && !result.symbol) { return; } - var typeOrSymbolString = isSymbolBaseline ? result.symbol : result.type; - var formattedLine = result.sourceText.replace(/\r?\n/g, "") + " : " + typeOrSymbolString; + let typeOrSymbolString = isSymbolBaseline ? result.symbol : result.type; + let formattedLine = result.sourceText.replace(/\r?\n/g, "") + " : " + typeOrSymbolString; if (!typeMap[file.unitName]) { typeMap[file.unitName] = {}; } - var typeInfo = [formattedLine]; - var existingTypeInfo = typeMap[file.unitName][result.line]; + let typeInfo = [formattedLine]; + let existingTypeInfo = typeMap[file.unitName][result.line]; if (existingTypeInfo) { typeInfo = existingTypeInfo.concat(typeInfo); } @@ -356,11 +356,11 @@ class CompilerBaselineRunner extends RunnerBase { }); typeLines.push('=== ' + file.unitName + ' ===\r\n'); - for (var i = 0; i < codeLines.length; i++) { - var currentCodeLine = codeLines[i]; + for (let i = 0; i < codeLines.length; i++) { + let currentCodeLine = codeLines[i]; typeLines.push(currentCodeLine + '\r\n'); if (typeMap[file.unitName]) { - var typeInfo = typeMap[file.unitName][i]; + let typeInfo = typeMap[file.unitName][i]; if (typeInfo) { typeInfo.forEach(ty => { typeLines.push('>' + ty + '\r\n'); @@ -388,13 +388,13 @@ class CompilerBaselineRunner extends RunnerBase { public initializeTests() { describe(this.testSuiteName + ' tests', () => { describe("Setup compiler for compiler baselines", () => { - var harnessCompiler = Harness.Compiler.getCompiler(); + let harnessCompiler = Harness.Compiler.getCompiler(); this.parseOptions(); }); // this will set up a series of describe/it blocks to run between the setup and cleanup phases if (this.tests.length === 0) { - var testFiles = this.enumerateFiles(this.basePath, /\.tsx?$/, { recursive: true }); + let testFiles = this.enumerateFiles(this.basePath, /\.tsx?$/, { recursive: true }); testFiles.forEach(fn => { fn = fn.replace(/\\/g, "/"); this.checkTestCodeOutput(fn); @@ -405,7 +405,7 @@ class CompilerBaselineRunner extends RunnerBase { } describe("Cleanup after compiler baselines", () => { - var harnessCompiler = Harness.Compiler.getCompiler(); + let harnessCompiler = Harness.Compiler.getCompiler(); }); }); } @@ -417,8 +417,8 @@ class CompilerBaselineRunner extends RunnerBase { this.decl = false; this.output = false; - var opts = this.options.split(','); - for (var i = 0; i < opts.length; i++) { + let opts = this.options.split(','); + for (let i = 0; i < opts.length; i++) { switch (opts[i]) { case 'error': this.errors = true; diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index c83537a0847..9b5d1f0f234 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -100,7 +100,7 @@ module FourSlash { end: number; } - var entityMap: ts.Map = { + let entityMap: ts.Map = { '&': '&', '"': '"', "'": ''', @@ -116,7 +116,7 @@ module FourSlash { // Name of testcase metadata including ts.CompilerOptions properties that will be used by globalOptions // To add additional option, add property into the testOptMetadataNames, refer the property in either globalMetadataNames or fileMetadataNames // Add cases into convertGlobalOptionsToCompilationsSettings function for the compiler to acknowledge such option from meta data - var metadataOptionNames = { + let metadataOptionNames = { baselineFile: 'BaselineFile', declaration: 'declaration', emitThisFile: 'emitThisFile', // This flag is used for testing getEmitOutput feature. It allows test-cases to indicate what file to be output in multiple files project @@ -132,15 +132,15 @@ module FourSlash { }; // List of allowed metadata names - var fileMetadataNames = [metadataOptionNames.fileName, metadataOptionNames.emitThisFile, metadataOptionNames.resolveReference]; - var globalMetadataNames = [metadataOptionNames.allowNonTsExtensions, metadataOptionNames.baselineFile, metadataOptionNames.declaration, + let fileMetadataNames = [metadataOptionNames.fileName, metadataOptionNames.emitThisFile, metadataOptionNames.resolveReference]; + let globalMetadataNames = [metadataOptionNames.allowNonTsExtensions, metadataOptionNames.baselineFile, metadataOptionNames.declaration, metadataOptionNames.mapRoot, metadataOptionNames.module, metadataOptionNames.out, metadataOptionNames.outDir, metadataOptionNames.sourceMap, metadataOptionNames.sourceRoot]; function convertGlobalOptionsToCompilerOptions(globalOptions: { [idx: string]: string }): ts.CompilerOptions { - var settings: ts.CompilerOptions = { target: ts.ScriptTarget.ES5 }; + let settings: ts.CompilerOptions = { target: ts.ScriptTarget.ES5 }; // Convert all property in globalOptions into ts.CompilationSettings - for (var prop in globalOptions) { + for (let prop in globalOptions) { if (globalOptions.hasOwnProperty(prop)) { switch (prop) { case metadataOptionNames.allowNonTsExtensions: @@ -185,7 +185,7 @@ module FourSlash { return settings; } - export var currentTestState: TestState = null; + export let currentTestState: TestState = null; function assertionMessage(msg: string) { return "\nMarker: " + currentTestState.lastKnownMarker + "\nChecking: " + msg + "\n\n"; } @@ -275,7 +275,7 @@ module FourSlash { // Add input file which has matched file name with the given reference-file path. // This is necessary when resolveReference flag is specified private addMatchedInputFile(referenceFilePath: string) { - var inputFile = this.inputFiles[referenceFilePath]; + let inputFile = this.inputFiles[referenceFilePath]; if (inputFile && !Harness.isLibraryFile(referenceFilePath)) { this.languageServiceAdapterHost.addScript(referenceFilePath, inputFile); } @@ -297,13 +297,13 @@ module FourSlash { constructor(private basePath: string, private testType: FourSlashTestType, public testData: FourSlashData) { // Create a new Services Adapter this.cancellationToken = new TestCancellationToken(); - var compilationOptions = convertGlobalOptionsToCompilerOptions(this.testData.globalOptions); - var languageServiceAdapter = this.getLanguageServiceAdapter(testType, this.cancellationToken, compilationOptions); + let compilationOptions = convertGlobalOptionsToCompilerOptions(this.testData.globalOptions); + let languageServiceAdapter = this.getLanguageServiceAdapter(testType, this.cancellationToken, compilationOptions); this.languageServiceAdapterHost = languageServiceAdapter.getHost(); this.languageService = languageServiceAdapter.getLanguageService(); // Initialize the language service with all the scripts - var startResolveFileRef: FourSlashFile; + let startResolveFileRef: FourSlashFile; ts.forEach(testData.files, file => { // Create map between fileName and its content for easily looking up when resolveReference flag is specified @@ -320,14 +320,14 @@ module FourSlash { // Add the entry-point file itself into the languageServiceShimHost this.languageServiceAdapterHost.addScript(startResolveFileRef.fileName, startResolveFileRef.content); - var resolvedResult = languageServiceAdapter.getPreProcessedFileInfo(startResolveFileRef.fileName, startResolveFileRef.content); - var referencedFiles: ts.FileReference[] = resolvedResult.referencedFiles; - var importedFiles: ts.FileReference[] = resolvedResult.importedFiles; + let resolvedResult = languageServiceAdapter.getPreProcessedFileInfo(startResolveFileRef.fileName, startResolveFileRef.content); + let referencedFiles: ts.FileReference[] = resolvedResult.referencedFiles; + let importedFiles: ts.FileReference[] = resolvedResult.importedFiles; // Add triple reference files into language-service host ts.forEach(referencedFiles, referenceFile => { // Fourslash insert tests/cases/fourslash into inputFile.unitName so we will properly append the same base directory to refFile path - var referenceFilePath = this.basePath + '/' + referenceFile.fileName; + let referenceFilePath = this.basePath + '/' + referenceFile.fileName; this.addMatchedInputFile(referenceFilePath); }); @@ -335,7 +335,7 @@ module FourSlash { ts.forEach(importedFiles, importedFile => { // Fourslash insert tests/cases/fourslash into inputFile.unitName and import statement doesn't require ".ts" // so convert them before making appropriate comparison - var importedFilePath = this.basePath + '/' + importedFile.fileName + ".ts"; + let importedFilePath = this.basePath + '/' + importedFile.fileName + ".ts"; this.addMatchedInputFile(importedFilePath); }); @@ -370,8 +370,8 @@ module FourSlash { }; this.testData.files.forEach(file => { - var fileName = file.fileName.replace(Harness.IO.directoryName(file.fileName), '').substr(1); - var fileNameWithoutExtension = fileName.substr(0, fileName.lastIndexOf(".")); + let fileName = file.fileName.replace(Harness.IO.directoryName(file.fileName), '').substr(1); + let fileNameWithoutExtension = fileName.substr(0, fileName.lastIndexOf(".")); this.scenarioActions.push(''); }); @@ -380,18 +380,18 @@ module FourSlash { } private getFileContent(fileName: string): string { - var script = this.languageServiceAdapterHost.getScriptInfo(fileName); + let script = this.languageServiceAdapterHost.getScriptInfo(fileName); return script.content; } // Entry points from fourslash.ts public goToMarker(name = '') { - var marker = this.getMarkerByName(name); + let marker = this.getMarkerByName(name); if (this.activeFile.fileName !== marker.fileName) { this.openFile(marker.fileName); } - var content = this.getFileContent(marker.fileName); + let content = this.getFileContent(marker.fileName); if (marker.position === -1 || marker.position > content.length) { throw new Error('Marker "' + name + '" has been invalidated by unrecoverable edits to the file.'); } @@ -402,8 +402,8 @@ module FourSlash { public goToPosition(pos: number) { this.currentCaretPosition = pos; - var lineStarts = ts.computeLineStarts(this.getFileContent(this.activeFile.fileName)); - var lineCharPos = ts.computeLineAndCharacterOfPosition(lineStarts, pos); + let lineStarts = ts.computeLineStarts(this.getFileContent(this.activeFile.fileName)); + let lineCharPos = ts.computeLineAndCharacterOfPosition(lineStarts, pos); this.scenarioActions.push(``); } @@ -421,10 +421,10 @@ module FourSlash { public openFile(index: number): void; public openFile(name: string): void; public openFile(indexOrName: any) { - var fileToOpen: FourSlashFile = this.findFile(indexOrName); + let fileToOpen: FourSlashFile = this.findFile(indexOrName); fileToOpen.fileName = ts.normalizeSlashes(fileToOpen.fileName); this.activeFile = fileToOpen; - var fileName = fileToOpen.fileName.replace(Harness.IO.directoryName(fileToOpen.fileName), '').substr(1); + let fileName = fileToOpen.fileName.replace(Harness.IO.directoryName(fileToOpen.fileName), '').substr(1); this.scenarioActions.push(''); // Let the host know that this file is now open @@ -432,13 +432,13 @@ module FourSlash { } public verifyErrorExistsBetweenMarkers(startMarkerName: string, endMarkerName: string, negative: boolean) { - var startMarker = this.getMarkerByName(startMarkerName); - var endMarker = this.getMarkerByName(endMarkerName); - var predicate = function (errorMinChar: number, errorLimChar: number, startPos: number, endPos: number) { + let startMarker = this.getMarkerByName(startMarkerName); + let endMarker = this.getMarkerByName(endMarkerName); + let predicate = function (errorMinChar: number, errorLimChar: number, startPos: number, endPos: number) { return ((errorMinChar === startPos) && (errorLimChar === endPos)) ? true : false; }; - var exists = this.anyErrorInRange(predicate, startMarker, endMarker); + let exists = this.anyErrorInRange(predicate, startMarker, endMarker); this.taoInvalidReason = 'verifyErrorExistsBetweenMarkers NYI'; @@ -458,10 +458,10 @@ module FourSlash { } private getDiagnostics(fileName: string): ts.Diagnostic[] { - var syntacticErrors = this.languageService.getSyntacticDiagnostics(fileName); - var semanticErrors = this.languageService.getSemanticDiagnostics(fileName); + let syntacticErrors = this.languageService.getSyntacticDiagnostics(fileName); + let semanticErrors = this.languageService.getSemanticDiagnostics(fileName); - var diagnostics: ts.Diagnostic[] = []; + let diagnostics: ts.Diagnostic[] = []; diagnostics.push.apply(diagnostics, syntacticErrors); diagnostics.push.apply(diagnostics, semanticErrors); @@ -469,10 +469,10 @@ module FourSlash { } private getAllDiagnostics(): ts.Diagnostic[] { - var diagnostics: ts.Diagnostic[] = []; + let diagnostics: ts.Diagnostic[] = []; - var fileNames = this.languageServiceAdapterHost.getFilenames(); - for (var i = 0, n = fileNames.length; i < n; i++) { + let fileNames = this.languageServiceAdapterHost.getFilenames(); + for (let i = 0, n = fileNames.length; i < n; i++) { diagnostics.push.apply(this.getDiagnostics(fileNames[i])); } @@ -480,8 +480,8 @@ module FourSlash { } public verifyErrorExistsAfterMarker(markerName: string, negative: boolean, after: boolean) { - var marker: Marker = this.getMarkerByName(markerName); - var predicate: (errorMinChar: number, errorLimChar: number, startPos: number, endPos: number) => boolean; + let marker: Marker = this.getMarkerByName(markerName); + let predicate: (errorMinChar: number, errorLimChar: number, startPos: number, endPos: number) => boolean; if (after) { predicate = function (errorMinChar: number, errorLimChar: number, startPos: number, endPos: number) { @@ -495,8 +495,8 @@ module FourSlash { this.taoInvalidReason = 'verifyErrorExistsAfterMarker NYI'; - var exists = this.anyErrorInRange(predicate, marker); - var diagnostics = this.getAllDiagnostics(); + let exists = this.anyErrorInRange(predicate, marker); + let diagnostics = this.getAllDiagnostics(); if (exists !== negative) { this.printErrorLog(negative, diagnostics); @@ -506,12 +506,12 @@ module FourSlash { private anyErrorInRange(predicate: (errorMinChar: number, errorLimChar: number, startPos: number, endPos: number) => boolean, startMarker: Marker, endMarker?: Marker) { - var errors = this.getDiagnostics(startMarker.fileName); - var exists = false; + let errors = this.getDiagnostics(startMarker.fileName); + let exists = false; - var startPos = startMarker.position; + let startPos = startMarker.position; if (endMarker !== undefined) { - var endPos = endMarker.position; + let endPos = endMarker.position; } errors.forEach(function (error: ts.Diagnostic) { @@ -538,40 +538,40 @@ module FourSlash { } public verifyNumberOfErrorsInCurrentFile(expected: number) { - var errors = this.getDiagnostics(this.activeFile.fileName); - var actual = errors.length; + let errors = this.getDiagnostics(this.activeFile.fileName); + let actual = errors.length; this.scenarioActions.push(''); if (actual !== expected) { this.printErrorLog(false, errors); - var errorMsg = "Actual number of errors (" + actual + ") does not match expected number (" + expected + ")"; + let errorMsg = "Actual number of errors (" + actual + ") does not match expected number (" + expected + ")"; Harness.IO.log(errorMsg); this.raiseError(errorMsg); } } public verifyEval(expr: string, value: any) { - var emit = this.languageService.getEmitOutput(this.activeFile.fileName); + let emit = this.languageService.getEmitOutput(this.activeFile.fileName); if (emit.outputFiles.length !== 1) { throw new Error("Expected exactly one output from emit of " + this.activeFile.fileName); } this.taoInvalidReason = 'verifyEval impossible'; - var evaluation = new Function(emit.outputFiles[0].text + ';\r\nreturn (' + expr + ');')(); + let evaluation = new Function(emit.outputFiles[0].text + ';\r\nreturn (' + expr + ');')(); if (evaluation !== value) { this.raiseError('Expected evaluation of expression "' + expr + '" to equal "' + value + '", but got "' + evaluation + '"'); } } public verifyGetEmitOutputForCurrentFile(expected: string): void { - var emit = this.languageService.getEmitOutput(this.activeFile.fileName); + let emit = this.languageService.getEmitOutput(this.activeFile.fileName); if (emit.outputFiles.length !== 1) { throw new Error("Expected exactly one output from emit of " + this.activeFile.fileName); } this.taoInvalidReason = 'verifyGetEmitOutputForCurrentFile impossible'; - var actual = emit.outputFiles[0].text; + let actual = emit.outputFiles[0].text; if (actual !== expected) { this.raiseError("Expected emit output to be '" + expected + "', but got '" + actual + "'"); } @@ -585,7 +585,7 @@ module FourSlash { this.taoInvalidReason = 'verifyMemberListContains only supports the "symbol" parameter'; } - var members = this.getMemberListAtCaret(); + let members = this.getMemberListAtCaret(); if (members) { this.assertItemInCompletionList(members.entries, symbol, text, documentation, kind); } @@ -607,10 +607,10 @@ module FourSlash { this.scenarioActions.push(''); } - var members = this.getMemberListAtCaret(); + let members = this.getMemberListAtCaret(); if (members) { - var match = members.entries.length === expectedCount; + let match = members.entries.length === expectedCount; if ((!match && !negative) || (match && negative)) { this.raiseError("Member list count was " + members.entries.length + ". Expected " + expectedCount); @@ -625,7 +625,7 @@ module FourSlash { this.scenarioActions.push(''); this.scenarioActions.push(''); - var members = this.getMemberListAtCaret(); + let members = this.getMemberListAtCaret(); if (members && members.entries.filter(e => e.name === symbol).length !== 0) { this.raiseError('Member list did contain ' + symbol); } @@ -634,8 +634,8 @@ module FourSlash { public verifyCompletionListItemsCountIsGreaterThan(count: number) { this.taoInvalidReason = 'verifyCompletionListItemsCountIsGreaterThan NYI'; - var completions = this.getCompletionListAtCaret(); - var itemsCount = completions.entries.length; + let completions = this.getCompletionListAtCaret(); + let itemsCount = completions.entries.length; if (itemsCount <= count) { this.raiseError('Expected completion list items count to be greater than ' + count + ', but is actually ' + itemsCount); @@ -649,13 +649,13 @@ module FourSlash { this.scenarioActions.push(''); } - var members = this.getMemberListAtCaret(); + let members = this.getMemberListAtCaret(); if ((!members || members.entries.length === 0) && negative) { this.raiseError("Member list is empty at Caret"); } else if ((members && members.entries.length !== 0) && !negative) { - var errorMsg = "\n" + "Member List contains: [" + members.entries[0].name; - for (var i = 1; i < members.entries.length; i++) { + let errorMsg = "\n" + "Member List contains: [" + members.entries[0].name; + for (let i = 1; i < members.entries.length; i++) { errorMsg += ", " + members.entries[i].name; } errorMsg += "]\n"; @@ -668,13 +668,13 @@ module FourSlash { public verifyCompletionListIsEmpty(negative: boolean) { this.scenarioActions.push(''); - var completions = this.getCompletionListAtCaret(); + let completions = this.getCompletionListAtCaret(); if ((!completions || completions.entries.length === 0) && negative) { this.raiseError("Completion list is empty at Caret"); } else if ((completions && completions.entries.length !== 0) && !negative) { - var errorMsg = "\n" + "Completion List contains: [" + completions.entries[0].name; - for (var i = 1; i < completions.entries.length; i++) { + let errorMsg = "\n" + "Completion List contains: [" + completions.entries[0].name; + for (let i = 1; i < completions.entries.length; i++) { errorMsg += ", " + completions.entries[i].name; } errorMsg += "]\n"; @@ -685,7 +685,7 @@ module FourSlash { } public verifyCompletionListAllowsNewIdentifier(negative: boolean) { - var completions = this.getCompletionListAtCaret(); + let completions = this.getCompletionListAtCaret(); if ((completions && !completions.isNewIdentifierLocation) && !negative) { this.raiseError("Expected builder completion entry"); @@ -695,7 +695,7 @@ module FourSlash { } public verifyCompletionListContains(symbol: string, text?: string, documentation?: string, kind?: string) { - var completions = this.getCompletionListAtCaret(); + let completions = this.getCompletionListAtCaret(); if (completions) { this.assertItemInCompletionList(completions.entries, symbol, text, documentation, kind); } @@ -737,7 +737,7 @@ module FourSlash { this.scenarioActions.push(''); this.scenarioActions.push(''); - var completions = this.getCompletionListAtCaret(); + let completions = this.getCompletionListAtCaret(); if (completions) { let filterCompletions = completions.entries.filter(e => e.name === symbol); filterCompletions = expectedKind ? filterCompletions.filter(e => e.kind === expectedKind) : filterCompletions; @@ -765,7 +765,7 @@ module FourSlash { public verifyCompletionEntryDetails(entryName: string, expectedText: string, expectedDocumentation?: string, kind?: string) { this.taoInvalidReason = 'verifyCompletionEntryDetails NYI'; - var details = this.getCompletionEntryDetails(entryName); + let details = this.getCompletionEntryDetails(entryName); assert.equal(ts.displayPartsToString(details.displayParts), expectedText, assertionMessage("completion entry details text")); @@ -781,14 +781,14 @@ module FourSlash { public verifyReferencesAtPositionListContains(fileName: string, start: number, end: number, isWriteAccess?: boolean) { this.taoInvalidReason = 'verifyReferencesAtPositionListContains NYI'; - var references = this.getReferencesAtCaret(); + let references = this.getReferencesAtCaret(); if (!references || references.length === 0) { this.raiseError('verifyReferencesAtPositionListContains failed - found 0 references, expected at least one.'); } - for (var i = 0; i < references.length; i++) { - var reference = references[i]; + for (let i = 0; i < references.length; i++) { + let reference = references[i]; if (reference && reference.fileName === fileName && reference.textSpan.start === start && ts.textSpanEnd(reference.textSpan) === end) { if (typeof isWriteAccess !== "undefined" && reference.isWriteAccess !== isWriteAccess) { this.raiseError('verifyReferencesAtPositionListContains failed - item isWriteAccess value does not match, actual: ' + reference.isWriteAccess + ', expected: ' + isWriteAccess + '.'); @@ -797,18 +797,18 @@ module FourSlash { } } - var missingItem = { fileName: fileName, start: start, end: end, isWriteAccess: isWriteAccess }; + let missingItem = { fileName: fileName, start: start, end: end, isWriteAccess: isWriteAccess }; this.raiseError('verifyReferencesAtPositionListContains failed - could not find the item: ' + JSON.stringify(missingItem) + ' in the returned list: (' + JSON.stringify(references) + ')'); } public verifyReferencesCountIs(count: number, localFilesOnly: boolean = true) { this.taoInvalidReason = 'verifyReferences NYI'; - var references = this.getReferencesAtCaret(); - var referencesCount = 0; + let references = this.getReferencesAtCaret(); + let referencesCount = 0; if (localFilesOnly) { - var localFiles = this.testData.files.map(file => file.fileName); + let localFiles = this.testData.files.map(file => file.fileName); // Count only the references in local files. Filter the ones in lib and other files. ts.forEach(references, entry => { if (localFiles.some((fileName) => fileName === entry.fileName)) { @@ -821,7 +821,7 @@ module FourSlash { } if (referencesCount !== count) { - var condition = localFilesOnly ? "excluding libs" : "including libs"; + let condition = localFilesOnly ? "excluding libs" : "including libs"; this.raiseError("Expected references count (" + condition + ") to be " + count + ", but is actually " + referencesCount); } } @@ -847,18 +847,18 @@ module FourSlash { } public getSyntacticDiagnostics(expected: string) { - var diagnostics = this.languageService.getSyntacticDiagnostics(this.activeFile.fileName); + let diagnostics = this.languageService.getSyntacticDiagnostics(this.activeFile.fileName); this.testDiagnostics(expected, diagnostics); } public getSemanticDiagnostics(expected: string) { - var diagnostics = this.languageService.getSemanticDiagnostics(this.activeFile.fileName); + let diagnostics = this.languageService.getSemanticDiagnostics(this.activeFile.fileName); this.testDiagnostics(expected, diagnostics); } private testDiagnostics(expected: string, diagnostics: ts.Diagnostic[]) { - var realized = ts.realizeDiagnostics(diagnostics, "\r\n"); - var actual = JSON.stringify(realized, null, " "); + let realized = ts.realizeDiagnostics(diagnostics, "\r\n"); + let actual = JSON.stringify(realized, null, " "); assert.equal(actual, expected); } @@ -870,9 +870,9 @@ module FourSlash { } }); - var actualQuickInfo = this.languageService.getQuickInfoAtPosition(this.activeFile.fileName, this.currentCaretPosition); - var actualQuickInfoText = actualQuickInfo ? ts.displayPartsToString(actualQuickInfo.displayParts) : ""; - var actualQuickInfoDocumentation = actualQuickInfo ? ts.displayPartsToString(actualQuickInfo.documentation) : ""; + let actualQuickInfo = this.languageService.getQuickInfoAtPosition(this.activeFile.fileName, this.currentCaretPosition); + let actualQuickInfoText = actualQuickInfo ? ts.displayPartsToString(actualQuickInfo.displayParts) : ""; + let actualQuickInfoDocumentation = actualQuickInfo ? ts.displayPartsToString(actualQuickInfo.documentation) : ""; if (negative) { if (expectedText !== undefined) { @@ -900,7 +900,7 @@ module FourSlash { this.scenarioActions.push(''); function getDisplayPartsJson(displayParts: ts.SymbolDisplayPart[]) { - var result = ""; + let result = ""; ts.forEach(displayParts, part => { if (result) { result += ",\n "; @@ -917,7 +917,7 @@ module FourSlash { return result; } - var actualQuickInfo = this.languageService.getQuickInfoAtPosition(this.activeFile.fileName, this.currentCaretPosition); + let actualQuickInfo = this.languageService.getQuickInfoAtPosition(this.activeFile.fileName, this.currentCaretPosition); assert.equal(actualQuickInfo.kind, kind, this.messageAtLastKnownMarker("QuickInfo kind")); assert.equal(actualQuickInfo.kindModifiers, kindModifiers, this.messageAtLastKnownMarker("QuickInfo kindModifiers")); assert.equal(JSON.stringify(actualQuickInfo.textSpan), JSON.stringify(textSpan), this.messageAtLastKnownMarker("QuickInfo textSpan")); @@ -926,12 +926,12 @@ module FourSlash { } public verifyRenameLocations(findInStrings: boolean, findInComments: boolean) { - var renameInfo = this.languageService.getRenameInfo(this.activeFile.fileName, this.currentCaretPosition); + let renameInfo = this.languageService.getRenameInfo(this.activeFile.fileName, this.currentCaretPosition); if (renameInfo.canRename) { - var references = this.languageService.findRenameLocations( + let references = this.languageService.findRenameLocations( this.activeFile.fileName, this.currentCaretPosition, findInStrings, findInComments); - var ranges = this.getRanges(); + let ranges = this.getRanges(); if (!references) { if (ranges.length !== 0) { @@ -947,9 +947,9 @@ module FourSlash { ranges = ranges.sort((r1, r2) => r1.start - r2.start); references = references.sort((r1, r2) => r1.textSpan.start - r2.textSpan.start); - for (var i = 0, n = ranges.length; i < n; i++) { - var reference = references[i]; - var range = ranges[i]; + for (let i = 0, n = ranges.length; i < n; i++) { + let reference = references[i]; + let range = ranges[i]; if (reference.textSpan.start !== range.start || ts.textSpanEnd(reference.textSpan) !== range.end) { @@ -966,7 +966,7 @@ module FourSlash { public verifyQuickInfoExists(negative: boolean) { this.taoInvalidReason = 'verifyQuickInfoExists NYI'; - var actualQuickInfo = this.languageService.getQuickInfoAtPosition(this.activeFile.fileName, this.currentCaretPosition); + let actualQuickInfo = this.languageService.getQuickInfoAtPosition(this.activeFile.fileName, this.currentCaretPosition); if (negative) { if (actualQuickInfo) { this.raiseError('verifyQuickInfoExists failed. Expected quick info NOT to exist'); @@ -982,42 +982,42 @@ module FourSlash { public verifyCurrentSignatureHelpIs(expected: string) { this.taoInvalidReason = 'verifyCurrentSignatureHelpIs NYI'; - var help = this.getActiveSignatureHelpItem(); + let help = this.getActiveSignatureHelpItem(); assert.equal( ts.displayPartsToString(help.prefixDisplayParts) + help.parameters.map(p => ts.displayPartsToString(p.displayParts)).join(ts.displayPartsToString(help.separatorDisplayParts)) + ts.displayPartsToString(help.suffixDisplayParts), expected); } - public verifyCurrentParameterIsVariable(isVariable: boolean) { - this.taoInvalidReason = 'verifyCurrentParameterIsVariable NYI'; + public verifyCurrentParameterIsletiable(isletiable: boolean) { + this.taoInvalidReason = 'verifyCurrentParameterIsletiable NYI'; - var signature = this.getActiveSignatureHelpItem(); + let signature = this.getActiveSignatureHelpItem(); assert.isNotNull(signature); - assert.equal(isVariable, signature.isVariadic); + assert.equal(isletiable, signature.isletiadic); } public verifyCurrentParameterHelpName(name: string) { this.taoInvalidReason = 'verifyCurrentParameterHelpName NYI'; - var activeParameter = this.getActiveParameter(); - var activeParameterName = activeParameter.name; + let activeParameter = this.getActiveParameter(); + let activeParameterName = activeParameter.name; assert.equal(activeParameterName, name); } public verifyCurrentParameterSpanIs(parameter: string) { this.taoInvalidReason = 'verifyCurrentParameterSpanIs NYI'; - var activeSignature = this.getActiveSignatureHelpItem(); - var activeParameter = this.getActiveParameter(); + let activeSignature = this.getActiveSignatureHelpItem(); + let activeParameter = this.getActiveParameter(); assert.equal(ts.displayPartsToString(activeParameter.displayParts), parameter); } public verifyCurrentParameterHelpDocComment(docComment: string) { this.taoInvalidReason = 'verifyCurrentParameterHelpDocComment NYI'; - var activeParameter = this.getActiveParameter(); - var activeParameterDocComment = activeParameter.documentation; + let activeParameter = this.getActiveParameter(); + let activeParameterDocComment = activeParameter.documentation; assert.equal(ts.displayPartsToString(activeParameterDocComment), docComment, assertionMessage("current parameter Help DocComment")); } @@ -1036,7 +1036,7 @@ module FourSlash { public verifyCurrentSignatureHelpDocComment(docComment: string) { this.taoInvalidReason = 'verifyCurrentSignatureHelpDocComment NYI'; - var actualDocComment = this.getActiveSignatureHelpItem().documentation; + let actualDocComment = this.getActiveSignatureHelpItem().documentation; assert.equal(ts.displayPartsToString(actualDocComment), docComment, assertionMessage("current signature help doc comment")); } @@ -1044,22 +1044,22 @@ module FourSlash { this.scenarioActions.push(''); this.scenarioActions.push(''); - var help = this.languageService.getSignatureHelpItems(this.activeFile.fileName, this.currentCaretPosition); - var actual = help && help.items ? help.items.length : 0; + let help = this.languageService.getSignatureHelpItems(this.activeFile.fileName, this.currentCaretPosition); + let actual = help && help.items ? help.items.length : 0; assert.equal(actual, expected); } public verifySignatureHelpArgumentCount(expected: number) { this.taoInvalidReason = 'verifySignatureHelpArgumentCount NYI'; - var signatureHelpItems = this.languageService.getSignatureHelpItems(this.activeFile.fileName, this.currentCaretPosition); - var actual = signatureHelpItems.argumentCount; + let signatureHelpItems = this.languageService.getSignatureHelpItems(this.activeFile.fileName, this.currentCaretPosition); + let actual = signatureHelpItems.argumentCount; assert.equal(actual, expected); } public verifySignatureHelpPresent(shouldBePresent = true) { this.taoInvalidReason = 'verifySignatureHelpPresent NYI'; - var actual = this.languageService.getSignatureHelpItems(this.activeFile.fileName, this.currentCaretPosition); + let actual = this.languageService.getSignatureHelpItems(this.activeFile.fileName, this.currentCaretPosition); if (shouldBePresent) { if (!actual) { this.raiseError("Expected signature help to be present, but it wasn't"); @@ -1078,7 +1078,7 @@ module FourSlash { } public verifyRenameInfoSucceeded(displayName?: string, fullDisplayName?: string, kind?: string, kindModifiers?: string) { - var renameInfo = this.languageService.getRenameInfo(this.activeFile.fileName, this.currentCaretPosition); + let renameInfo = this.languageService.getRenameInfo(this.activeFile.fileName, this.currentCaretPosition); if (!renameInfo.canRename) { this.raiseError("Rename did not succeed"); } @@ -1092,7 +1092,7 @@ module FourSlash { this.raiseError("Expected a single range to be selected in the test file."); } - var expectedRange = this.getRanges()[0]; + let expectedRange = this.getRanges()[0]; if (renameInfo.triggerSpan.start !== expectedRange.start || ts.textSpanEnd(renameInfo.triggerSpan) !== expectedRange.end) { this.raiseError("Expected triggerSpan [" + expectedRange.start + "," + expectedRange.end + "). Got [" + @@ -1101,7 +1101,7 @@ module FourSlash { } public verifyRenameInfoFailed(message?: string) { - var renameInfo = this.languageService.getRenameInfo(this.activeFile.fileName, this.currentCaretPosition); + let renameInfo = this.languageService.getRenameInfo(this.activeFile.fileName, this.currentCaretPosition); if (renameInfo.canRename) { this.raiseError("Rename was expected to fail"); } @@ -1110,26 +1110,26 @@ module FourSlash { } private getActiveSignatureHelpItem() { - var help = this.languageService.getSignatureHelpItems(this.activeFile.fileName, this.currentCaretPosition); - var index = help.selectedItemIndex; + let help = this.languageService.getSignatureHelpItems(this.activeFile.fileName, this.currentCaretPosition); + let index = help.selectedItemIndex; return help.items[index]; } private getActiveParameter(): ts.SignatureHelpParameter { - var help = this.languageService.getSignatureHelpItems(this.activeFile.fileName, this.currentCaretPosition); - var item = help.items[help.selectedItemIndex]; - var currentParam = help.argumentIndex; + let help = this.languageService.getSignatureHelpItems(this.activeFile.fileName, this.currentCaretPosition); + let item = help.items[help.selectedItemIndex]; + let currentParam = help.argumentIndex; return item.parameters[currentParam]; } private alignmentForExtraInfo = 50; private spanInfoToString(pos: number, spanInfo: ts.TextSpan, prefixString: string) { - var resultString = "SpanInfo: " + JSON.stringify(spanInfo); + let resultString = "SpanInfo: " + JSON.stringify(spanInfo); if (spanInfo) { - var spanString = this.activeFile.content.substr(spanInfo.start, spanInfo.length); - var spanLineMap = ts.computeLineStarts(spanString); - for (var i = 0; i < spanLineMap.length; i++) { + let spanString = this.activeFile.content.substr(spanInfo.start, spanInfo.length); + let spanLineMap = ts.computeLineStarts(spanString); + for (let i = 0; i < spanLineMap.length; i++) { if (!i) { resultString += "\n"; } @@ -1142,20 +1142,20 @@ module FourSlash { } private baselineCurrentFileLocations(getSpanAtPos: (pos: number) => ts.TextSpan): string { - var fileLineMap = ts.computeLineStarts(this.activeFile.content); - var nextLine = 0; - var resultString = ""; - var currentLine: string; - var previousSpanInfo: string; - var startColumn: number; - var length: number; - var prefixString = " >"; + let fileLineMap = ts.computeLineStarts(this.activeFile.content); + let nextLine = 0; + let resultString = ""; + let currentLine: string; + let previousSpanInfo: string; + let startColumn: number; + let length: number; + let prefixString = " >"; - var pos = 0; - var addSpanInfoString = () => { + let pos = 0; + let addSpanInfoString = () => { if (previousSpanInfo) { resultString += currentLine; - var thisLineMarker = repeatString(startColumn, " ") + repeatString(length, "~"); + let thisLineMarker = repeatString(startColumn, " ") + repeatString(length, "~"); thisLineMarker += repeatString(this.alignmentForExtraInfo - thisLineMarker.length - prefixString.length + 1, " "); resultString += thisLineMarker; resultString += "=> Pos: (" + (pos - length) + " to " + (pos - 1) + ") "; @@ -1175,7 +1175,7 @@ module FourSlash { startColumn = 0; length = 0; } - var spanInfo = this.spanInfoToString(pos, getSpanAtPos(pos), prefixString); + let spanInfo = this.spanInfoToString(pos, getSpanAtPos(pos), prefixString); if (previousSpanInfo && previousSpanInfo !== spanInfo) { addSpanInfoString(); previousSpanInfo = spanInfo; @@ -1191,8 +1191,8 @@ module FourSlash { return resultString; function repeatString(count: number, char: string) { - var result = ""; - for (var i = 0; i < count; i++) { + let result = ""; + for (let i = 0; i < count; i++) { result += char; } return result; @@ -1219,11 +1219,11 @@ module FourSlash { public baselineGetEmitOutput() { this.taoInvalidReason = 'baselineGetEmitOutput impossible'; // Find file to be emitted - var emitFiles: FourSlashFile[] = []; // List of FourSlashFile that has emitThisFile flag on + let emitFiles: FourSlashFile[] = []; // List of FourSlashFile that has emitThisFile flag on - var allFourSlashFiles = this.testData.files; - for (var idx = 0; idx < allFourSlashFiles.length; ++idx) { - var file = allFourSlashFiles[idx]; + let allFourSlashFiles = this.testData.files; + for (let idx = 0; idx < allFourSlashFiles.length; ++idx) { + let file = allFourSlashFiles[idx]; if (file.fileOptions[metadataOptionNames.emitThisFile] === "true") { // Find a file with the flag emitThisFile turned on emitFiles.push(file); @@ -1239,23 +1239,23 @@ module FourSlash { "Generate getEmitOutput baseline : " + emitFiles.join(" "), this.testData.globalOptions[metadataOptionNames.baselineFile], () => { - var resultString = ""; + let resultString = ""; // Loop through all the emittedFiles and emit them one by one emitFiles.forEach(emitFile => { - var emitOutput = this.languageService.getEmitOutput(emitFile.fileName); + let emitOutput = this.languageService.getEmitOutput(emitFile.fileName); // Print emitOutputStatus in readable format resultString += "EmitSkipped: " + emitOutput.emitSkipped + ts.sys.newLine; if (emitOutput.emitSkipped) { resultString += "Diagnostics:" + ts.sys.newLine; - var diagnostics = ts.getPreEmitDiagnostics(this.languageService.getProgram()); - for (var i = 0, n = diagnostics.length; i < n; i++) { + let diagnostics = ts.getPreEmitDiagnostics(this.languageService.getProgram()); + for (let i = 0, n = diagnostics.length; i < n; i++) { resultString += " " + diagnostics[0].messageText + ts.sys.newLine; } } emitOutput.outputFiles.forEach((outputFile, idx, array) => { - var fileName = "FileName : " + outputFile.name + ts.sys.newLine; + let fileName = "FileName : " + outputFile.name + ts.sys.newLine; resultString = resultString + fileName + outputFile.text; }); resultString += ts.sys.newLine; @@ -1275,19 +1275,19 @@ module FourSlash { } public printCurrentParameterHelp() { - var help = this.languageService.getSignatureHelpItems(this.activeFile.fileName, this.currentCaretPosition); + let help = this.languageService.getSignatureHelpItems(this.activeFile.fileName, this.currentCaretPosition); Harness.IO.log(JSON.stringify(help)); } public printCurrentQuickInfo() { - var quickInfo = this.languageService.getQuickInfoAtPosition(this.activeFile.fileName, this.currentCaretPosition); + let quickInfo = this.languageService.getQuickInfoAtPosition(this.activeFile.fileName, this.currentCaretPosition); Harness.IO.log(JSON.stringify(quickInfo)); } public printErrorList() { - var syntacticErrors = this.languageService.getSyntacticDiagnostics(this.activeFile.fileName); - var semanticErrors = this.languageService.getSemanticDiagnostics(this.activeFile.fileName); - var errorList = syntacticErrors.concat(semanticErrors); + let syntacticErrors = this.languageService.getSyntacticDiagnostics(this.activeFile.fileName); + let semanticErrors = this.languageService.getSemanticDiagnostics(this.activeFile.fileName); + let errorList = syntacticErrors.concat(semanticErrors); Harness.IO.log('Error list (' + errorList.length + ' errors)'); if (errorList.length) { @@ -1301,11 +1301,11 @@ module FourSlash { } public printCurrentFileState(makeWhitespaceVisible = false, makeCaretVisible = true) { - for (var i = 0; i < this.testData.files.length; i++) { - var file = this.testData.files[i]; - var active = (this.activeFile === file); + for (let i = 0; i < this.testData.files.length; i++) { + let file = this.testData.files[i]; + let active = (this.activeFile === file); Harness.IO.log('=== Script (' + file.fileName + ') ' + (active ? '(active, cursor at |)' : '') + ' ==='); - var content = this.getFileContent(file.fileName); + let content = this.getFileContent(file.fileName); if (active) { content = content.substr(0, this.currentCaretPosition) + (makeCaretVisible ? '|' : "") + content.substr(this.currentCaretPosition); } @@ -1317,22 +1317,22 @@ module FourSlash { } public printCurrentSignatureHelp() { - var sigHelp = this.getActiveSignatureHelpItem(); + let sigHelp = this.getActiveSignatureHelpItem(); Harness.IO.log(JSON.stringify(sigHelp)); } public printMemberListMembers() { - var members = this.getMemberListAtCaret(); + let members = this.getMemberListAtCaret(); Harness.IO.log(JSON.stringify(members)); } public printCompletionListMembers() { - var completions = this.getCompletionListAtCaret(); + let completions = this.getCompletionListAtCaret(); Harness.IO.log(JSON.stringify(completions)); } public printReferences() { - var references = this.getReferencesAtCaret(); + let references = this.getReferencesAtCaret(); ts.forEach(references, entry => { Harness.IO.log(JSON.stringify(entry)); }); @@ -1345,26 +1345,26 @@ module FourSlash { public deleteChar(count = 1) { this.scenarioActions.push(''); - var offset = this.currentCaretPosition; - var ch = ""; + let offset = this.currentCaretPosition; + let ch = ""; - var checkCadence = (count >> 2) + 1; + let checkCadence = (count >> 2) + 1; - for (var i = 0; i < count; i++) { + for (let i = 0; i < count; i++) { // Make the edit this.languageServiceAdapterHost.editScript(this.activeFile.fileName, offset, offset + 1, ch); this.updateMarkersForEdit(this.activeFile.fileName, offset, offset + 1, ch); if (i % checkCadence === 0) { - this.checkPostEditInvariants(); + this.checkPostEditInletiants(); } // Handle post-keystroke formatting if (this.enableFormatting) { - var edits = this.languageService.getFormattingEditsAfterKeystroke(this.activeFile.fileName, offset, ch, this.formatCodeOptions); + let edits = this.languageService.getFormattingEditsAfterKeystroke(this.activeFile.fileName, offset, ch, this.formatCodeOptions); if (edits.length) { offset += this.applyEdits(this.activeFile.fileName, edits, true); - // this.checkPostEditInvariants(); + // this.checkPostEditInletiants(); } } } @@ -1373,7 +1373,7 @@ module FourSlash { this.currentCaretPosition = offset; this.fixCaretPosition(); - this.checkPostEditInvariants(); + this.checkPostEditInletiants(); } public replace(start: number, length: number, text: string) { @@ -1381,29 +1381,29 @@ module FourSlash { this.languageServiceAdapterHost.editScript(this.activeFile.fileName, start, start + length, text); this.updateMarkersForEdit(this.activeFile.fileName, start, start + length, text); - this.checkPostEditInvariants(); + this.checkPostEditInletiants(); } public deleteCharBehindMarker(count = 1) { this.scenarioActions.push(''); - var offset = this.currentCaretPosition; - var ch = ""; - var checkCadence = (count >> 2) + 1; + let offset = this.currentCaretPosition; + let ch = ""; + let checkCadence = (count >> 2) + 1; - for (var i = 0; i < count; i++) { + for (let i = 0; i < count; i++) { offset--; // Make the edit this.languageServiceAdapterHost.editScript(this.activeFile.fileName, offset, offset + 1, ch); this.updateMarkersForEdit(this.activeFile.fileName, offset, offset + 1, ch); if (i % checkCadence === 0) { - this.checkPostEditInvariants(); + this.checkPostEditInletiants(); } // Handle post-keystroke formatting if (this.enableFormatting) { - var edits = this.languageService.getFormattingEditsAfterKeystroke(this.activeFile.fileName, offset, ch, this.formatCodeOptions); + let edits = this.languageService.getFormattingEditsAfterKeystroke(this.activeFile.fileName, offset, ch, this.formatCodeOptions); if (edits.length) { offset += this.applyEdits(this.activeFile.fileName, edits, true); } @@ -1414,7 +1414,7 @@ module FourSlash { this.currentCaretPosition = offset; this.fixCaretPosition(); - this.checkPostEditInvariants(); + this.checkPostEditInletiants(); } // Enters lines of text at the current caret position @@ -1432,13 +1432,13 @@ module FourSlash { // language service APIs to mimic Visual Studio's behavior // as much as possible private typeHighFidelity(text: string) { - var offset = this.currentCaretPosition; - var prevChar = ' '; - var checkCadence = (text.length >> 2) + 1; + let offset = this.currentCaretPosition; + let prevChar = ' '; + let checkCadence = (text.length >> 2) + 1; - for (var i = 0; i < text.length; i++) { + for (let i = 0; i < text.length; i++) { // Make the edit - var ch = text.charAt(i); + let ch = text.charAt(i); this.languageServiceAdapterHost.editScript(this.activeFile.fileName, offset, offset, ch); this.languageService.getBraceMatchingAtPosition(this.activeFile.fileName, offset); @@ -1454,17 +1454,17 @@ module FourSlash { } if (i % checkCadence === 0) { - this.checkPostEditInvariants(); + this.checkPostEditInletiants(); // this.languageService.getSyntacticDiagnostics(this.activeFile.fileName); // this.languageService.getSemanticDiagnostics(this.activeFile.fileName); } // Handle post-keystroke formatting if (this.enableFormatting) { - var edits = this.languageService.getFormattingEditsAfterKeystroke(this.activeFile.fileName, offset, ch, this.formatCodeOptions); + let edits = this.languageService.getFormattingEditsAfterKeystroke(this.activeFile.fileName, offset, ch, this.formatCodeOptions); if (edits.length) { offset += this.applyEdits(this.activeFile.fileName, edits, true); - // this.checkPostEditInvariants(); + // this.checkPostEditInletiants(); } } } @@ -1473,26 +1473,26 @@ module FourSlash { this.currentCaretPosition = offset; this.fixCaretPosition(); - this.checkPostEditInvariants(); + this.checkPostEditInletiants(); } // Enters text as if the user had pasted it public paste(text: string) { this.scenarioActions.push(''); - var start = this.currentCaretPosition; - var offset = this.currentCaretPosition; + let start = this.currentCaretPosition; + let offset = this.currentCaretPosition; this.languageServiceAdapterHost.editScript(this.activeFile.fileName, offset, offset, text); this.updateMarkersForEdit(this.activeFile.fileName, offset, offset, text); - this.checkPostEditInvariants(); + this.checkPostEditInletiants(); offset += text.length; // Handle formatting if (this.enableFormatting) { - var edits = this.languageService.getFormattingEditsForRange(this.activeFile.fileName, start, offset, this.formatCodeOptions); + let edits = this.languageService.getFormattingEditsForRange(this.activeFile.fileName, start, offset, this.formatCodeOptions); if (edits.length) { offset += this.applyEdits(this.activeFile.fileName, edits, true); - this.checkPostEditInvariants(); + this.checkPostEditInletiants(); } } @@ -1500,27 +1500,27 @@ module FourSlash { this.currentCaretPosition = offset; this.fixCaretPosition(); - this.checkPostEditInvariants(); + this.checkPostEditInletiants(); } - private checkPostEditInvariants() { + private checkPostEditInletiants() { if (this.testType !== FourSlashTestType.Native) { // getSourcefile() results can not be serialized. Only perform these verifications // if running against a native LS object. return; } - var incrementalSourceFile = this.languageService.getSourceFile(this.activeFile.fileName); - Utils.assertInvariants(incrementalSourceFile, /*parent:*/ undefined); + let incrementalSourceFile = this.languageService.getSourceFile(this.activeFile.fileName); + Utils.assertInletiants(incrementalSourceFile, /*parent:*/ undefined); - var incrementalSyntaxDiagnostics = incrementalSourceFile.parseDiagnostics; + let incrementalSyntaxDiagnostics = incrementalSourceFile.parseDiagnostics; // Check syntactic structure - var content = this.getFileContent(this.activeFile.fileName); + let content = this.getFileContent(this.activeFile.fileName); - var referenceSourceFile = ts.createLanguageServiceSourceFile( + let referenceSourceFile = ts.createLanguageServiceSourceFile( this.activeFile.fileName, createScriptSnapShot(content), ts.ScriptTarget.Latest, /*version:*/ "0", /*setNodeParents:*/ false); - var referenceSyntaxDiagnostics = referenceSourceFile.parseDiagnostics; + let referenceSyntaxDiagnostics = referenceSourceFile.parseDiagnostics; Utils.assertDiagnosticsEquals(incrementalSyntaxDiagnostics, referenceSyntaxDiagnostics); Utils.assertStructuralEquals(incrementalSourceFile, referenceSourceFile); @@ -1530,7 +1530,7 @@ module FourSlash { // The caret can potentially end up between the \r and \n, which is confusing. If // that happens, move it back one character if (this.currentCaretPosition > 0) { - var ch = this.getFileContent(this.activeFile.fileName).substring(this.currentCaretPosition - 1, this.currentCaretPosition); + let ch = this.getFileContent(this.activeFile.fileName).substring(this.currentCaretPosition - 1, this.currentCaretPosition); if (ch === '\r') { this.currentCaretPosition--; } @@ -1540,21 +1540,21 @@ module FourSlash { private applyEdits(fileName: string, edits: ts.TextChange[], isFormattingEdit = false): number { // We get back a set of edits, but langSvc.editScript only accepts one at a time. Use this to keep track // of the incremental offset from each edit to the next. Assumption is that these edit ranges don't overlap - var runningOffset = 0; + let runningOffset = 0; edits = edits.sort((a, b) => a.span.start - b.span.start); // Get a snapshot of the content of the file so we can make sure any formatting edits didn't destroy non-whitespace characters - var oldContent = this.getFileContent(this.activeFile.fileName); - for (var j = 0; j < edits.length; j++) { + let oldContent = this.getFileContent(this.activeFile.fileName); + for (let j = 0; j < edits.length; j++) { this.languageServiceAdapterHost.editScript(fileName, edits[j].span.start + runningOffset, ts.textSpanEnd(edits[j].span) + runningOffset, edits[j].newText); this.updateMarkersForEdit(fileName, edits[j].span.start + runningOffset, ts.textSpanEnd(edits[j].span) + runningOffset, edits[j].newText); - var change = (edits[j].span.start - ts.textSpanEnd(edits[j].span)) + edits[j].newText.length; + let change = (edits[j].span.start - ts.textSpanEnd(edits[j].span)) + edits[j].newText.length; runningOffset += change; // TODO: Consider doing this at least some of the time for higher fidelity. Currently causes a failure (bug 707150) // this.languageService.getScriptLexicalStructure(fileName); } if (isFormattingEdit) { - var newContent = this.getFileContent(fileName); + let newContent = this.getFileContent(fileName); if (newContent.replace(/\s/g, '') !== oldContent.replace(/\s/g, '')) { this.raiseError('Formatting operation destroyed non-whitespace content'); @@ -1568,7 +1568,7 @@ module FourSlash { } public setFormatOptions(formatCodeOptions: ts.FormatCodeOptions): ts.FormatCodeOptions { - var oldFormatCodeOptions = this.formatCodeOptions; + let oldFormatCodeOptions = this.formatCodeOptions; this.formatCodeOptions = formatCodeOptions; return oldFormatCodeOptions; } @@ -1576,7 +1576,7 @@ module FourSlash { public formatDocument() { this.scenarioActions.push(''); - var edits = this.languageService.getFormattingEditsForDocument(this.activeFile.fileName, this.formatCodeOptions); + let edits = this.languageService.getFormattingEditsForDocument(this.activeFile.fileName, this.formatCodeOptions); this.currentCaretPosition += this.applyEdits(this.activeFile.fileName, edits, true); this.fixCaretPosition(); } @@ -1584,14 +1584,14 @@ module FourSlash { public formatSelection(start: number, end: number) { this.taoInvalidReason = 'formatSelection NYI'; - var edits = this.languageService.getFormattingEditsForRange(this.activeFile.fileName, start, end, this.formatCodeOptions); + let edits = this.languageService.getFormattingEditsForRange(this.activeFile.fileName, start, end, this.formatCodeOptions); this.currentCaretPosition += this.applyEdits(this.activeFile.fileName, edits, true); this.fixCaretPosition(); } private updateMarkersForEdit(fileName: string, minChar: number, limChar: number, text: string) { - for (var i = 0; i < this.testData.markers.length; i++) { - var marker = this.testData.markers[i]; + for (let i = 0; i < this.testData.markers.length; i++) { + let marker = this.testData.markers[i]; if (marker.fileName === fileName) { if (marker.position > minChar) { if (marker.position < limChar) { @@ -1611,7 +1611,7 @@ module FourSlash { } public goToEOF() { - var len = this.getFileContent(this.activeFile.fileName).length; + let len = this.getFileContent(this.activeFile.fileName).length; this.goToPosition(len); } @@ -1622,7 +1622,7 @@ module FourSlash { this.taoInvalidReason = 'GoToDefinition not supported for non-zero definition indices'; } - var definitions = this.languageService.getDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition); + let definitions = this.languageService.getDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition); if (!definitions || !definitions.length) { this.raiseError('goToDefinition failed - expected to at least one definition location but got 0'); } @@ -1631,7 +1631,7 @@ module FourSlash { this.raiseError('goToDefinition failed - definitionIndex value (' + definitionIndex + ') exceeds definition list size (' + definitions.length + ')'); } - var definition = definitions[definitionIndex]; + let definition = definitions[definitionIndex]; this.openFile(definition.fileName); this.currentCaretPosition = definition.textSpan.start; } @@ -1644,7 +1644,7 @@ module FourSlash { this.taoInvalidReason = 'GoToTypeDefinition not supported for non-zero definition indices'; } - var definitions = this.languageService.getTypeDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition); + let definitions = this.languageService.getTypeDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition); if (!definitions || !definitions.length) { this.raiseError('goToTypeDefinition failed - expected to at least one definition location but got 0'); } @@ -1653,7 +1653,7 @@ module FourSlash { this.raiseError('goToTypeDefinition failed - definitionIndex value (' + definitionIndex + ') exceeds definition list size (' + definitions.length + ')'); } - var definition = definitions[definitionIndex]; + let definition = definitions[definitionIndex]; this.openFile(definition.fileName); this.currentCaretPosition = definition.textSpan.start; } @@ -1661,9 +1661,9 @@ module FourSlash { public verifyDefinitionLocationExists(negative: boolean) { this.taoInvalidReason = 'verifyDefinitionLocationExists NYI'; - var definitions = this.languageService.getDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition); + let definitions = this.languageService.getDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition); - var foundDefinitions = definitions && definitions.length; + let foundDefinitions = definitions && definitions.length; if (foundDefinitions && negative) { this.raiseError('goToDefinition - expected to 0 definition locations but got ' + definitions.length); @@ -1674,19 +1674,19 @@ module FourSlash { } public verifyDefinitionsCount(negative: boolean, expectedCount: number) { - var assertFn = negative ? assert.notEqual : assert.equal; + let assertFn = negative ? assert.notEqual : assert.equal; - var definitions = this.languageService.getDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition); - var actualCount = definitions && definitions.length || 0; + let definitions = this.languageService.getDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition); + let actualCount = definitions && definitions.length || 0; assertFn(actualCount, expectedCount, this.messageAtLastKnownMarker("Definitions Count")); } public verifyTypeDefinitionsCount(negative: boolean, expectedCount: number) { - var assertFn = negative ? assert.notEqual : assert.equal; + let assertFn = negative ? assert.notEqual : assert.equal; - var definitions = this.languageService.getTypeDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition); - var actualCount = definitions && definitions.length || 0; + let definitions = this.languageService.getTypeDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition); + let actualCount = definitions && definitions.length || 0; assertFn(actualCount, expectedCount, this.messageAtLastKnownMarker("Type definitions Count")); } @@ -1694,9 +1694,9 @@ module FourSlash { public verifyDefinitionsName(negative: boolean, expectedName: string, expectedContainerName: string) { this.taoInvalidReason = 'verifyDefinititionsInfo NYI'; - var definitions = this.languageService.getDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition); - var actualDefinitionName = definitions && definitions.length ? definitions[0].name : ""; - var actualDefinitionContainerName = definitions && definitions.length ? definitions[0].containerName : ""; + let definitions = this.languageService.getDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition); + let actualDefinitionName = definitions && definitions.length ? definitions[0].name : ""; + let actualDefinitionContainerName = definitions && definitions.length ? definitions[0].containerName : ""; if (negative) { assert.notEqual(actualDefinitionName, expectedName, this.messageAtLastKnownMarker("Definition Info Name")); assert.notEqual(actualDefinitionContainerName, expectedContainerName, this.messageAtLastKnownMarker("Definition Info Container Name")); @@ -1719,7 +1719,7 @@ module FourSlash { public verifyCaretAtMarker(markerName = '') { this.taoInvalidReason = 'verifyCaretAtMarker NYI'; - var pos = this.getMarkerByName(markerName); + let pos = this.getMarkerByName(markerName); if (pos.fileName !== this.activeFile.fileName) { throw new Error('verifyCaretAtMarker failed - expected to be in file "' + pos.fileName + '", but was in file "' + this.activeFile.fileName + '"'); } @@ -1735,8 +1735,8 @@ module FourSlash { public verifyIndentationAtCurrentPosition(numberOfSpaces: number) { this.taoInvalidReason = 'verifyIndentationAtCurrentPosition NYI'; - var actual = this.getIndentation(this.activeFile.fileName, this.currentCaretPosition); - var lineCol = this.getLineColStringAtPosition(this.currentCaretPosition); + let actual = this.getIndentation(this.activeFile.fileName, this.currentCaretPosition); + let lineCol = this.getLineColStringAtPosition(this.currentCaretPosition); if (actual !== numberOfSpaces) { this.raiseError('verifyIndentationAtCurrentPosition failed at ' + lineCol + ' - expected: ' + numberOfSpaces + ', actual: ' + actual); } @@ -1745,8 +1745,8 @@ module FourSlash { public verifyIndentationAtPosition(fileName: string, position: number, numberOfSpaces: number) { this.taoInvalidReason = 'verifyIndentationAtPosition NYI'; - var actual = this.getIndentation(fileName, position); - var lineCol = this.getLineColStringAtPosition(position); + let actual = this.getIndentation(fileName, position); + let lineCol = this.getLineColStringAtPosition(position); if (actual !== numberOfSpaces) { this.raiseError('verifyIndentationAtPosition failed at ' + lineCol + ' - expected: ' + numberOfSpaces + ', actual: ' + actual); } @@ -1755,7 +1755,7 @@ module FourSlash { public verifyCurrentLineContent(text: string) { this.taoInvalidReason = 'verifyCurrentLineContent NYI'; - var actual = this.getCurrentLineContent(); + let actual = this.getCurrentLineContent(); if (actual !== text) { throw new Error('verifyCurrentLineContent\n' + '\tExpected: "' + text + '"\n' + @@ -1766,8 +1766,8 @@ module FourSlash { public verifyCurrentFileContent(text: string) { this.taoInvalidReason = 'verifyCurrentFileContent NYI'; - var actual = this.getFileContent(this.activeFile.fileName); - var replaceNewlines = (str: string) => str.replace(/\r\n/g, "\n"); + let actual = this.getFileContent(this.activeFile.fileName); + let replaceNewlines = (str: string) => str.replace(/\r\n/g, "\n"); if (replaceNewlines(actual) !== replaceNewlines(text)) { throw new Error('verifyCurrentFileContent\n' + '\tExpected: "' + text + '"\n' + @@ -1778,7 +1778,7 @@ module FourSlash { public verifyTextAtCaretIs(text: string) { this.taoInvalidReason = 'verifyCurrentFileContent NYI'; - var actual = this.getFileContent(this.activeFile.fileName).substring(this.currentCaretPosition, this.currentCaretPosition + text.length); + let actual = this.getFileContent(this.activeFile.fileName).substring(this.currentCaretPosition, this.currentCaretPosition + text.length); if (actual !== text) { throw new Error('verifyTextAtCaretIs\n' + '\tExpected: "' + text + '"\n' + @@ -1789,14 +1789,14 @@ module FourSlash { public verifyCurrentNameOrDottedNameSpanText(text: string) { this.taoInvalidReason = 'verifyCurrentNameOrDottedNameSpanText NYI'; - var span = this.languageService.getNameOrDottedNameSpan(this.activeFile.fileName, this.currentCaretPosition, this.currentCaretPosition); + let span = this.languageService.getNameOrDottedNameSpan(this.activeFile.fileName, this.currentCaretPosition, this.currentCaretPosition); if (!span) { this.raiseError('verifyCurrentNameOrDottedNameSpanText\n' + '\tExpected: "' + text + '"\n' + '\t Actual: undefined'); } - var actual = this.getFileContent(this.activeFile.fileName).substring(span.start, ts.textSpanEnd(span)); + let actual = this.getFileContent(this.activeFile.fileName).substring(span.start, ts.textSpanEnd(span)); if (actual !== text) { this.raiseError('verifyCurrentNameOrDottedNameSpanText\n' + '\tExpected: "' + text + '"\n' + @@ -1833,11 +1833,11 @@ module FourSlash { jsonMismatchString()); } - for (var i = 0; i < expected.length; i++) { - var expectedClassification = expected[i]; - var actualClassification = actual[i]; + for (let i = 0; i < expected.length; i++) { + let expectedClassification = expected[i]; + let actualClassification = actual[i]; - var expectedType: string = (ts.ClassificationTypeNames)[expectedClassification.classificationType]; + let expectedType: string = (ts.ClassificationTypeNames)[expectedClassification.classificationType]; if (expectedType !== actualClassification.classificationType) { this.raiseError('verifyClassifications failed - expected classifications type to be ' + expectedType + ', but was ' + @@ -1845,11 +1845,11 @@ module FourSlash { jsonMismatchString()); } - var expectedSpan = expectedClassification.textSpan; - var actualSpan = actualClassification.textSpan; + let expectedSpan = expectedClassification.textSpan; + let actualSpan = actualClassification.textSpan; if (expectedSpan) { - var expectedLength = expectedSpan.end - expectedSpan.start; + let expectedLength = expectedSpan.end - expectedSpan.start; if (expectedSpan.start !== actualSpan.start || expectedLength !== actualSpan.length) { this.raiseError("verifyClassifications failed - expected span of text to be " + @@ -1859,7 +1859,7 @@ module FourSlash { } } - var actualText = this.activeFile.content.substr(actualSpan.start, actualSpan.length); + let actualText = this.activeFile.content.substr(actualSpan.start, actualSpan.length); if (expectedClassification.text !== actualText) { this.raiseError('verifyClassifications failed - expected classified text to be ' + expectedClassification.text + ', but was ' + @@ -1891,14 +1891,14 @@ module FourSlash { } public verifySemanticClassifications(expected: { classificationType: string; text: string }[]) { - var actual = this.languageService.getSemanticClassifications(this.activeFile.fileName, + let actual = this.languageService.getSemanticClassifications(this.activeFile.fileName, ts.createTextSpan(0, this.activeFile.content.length)); this.verifyClassifications(expected, actual); } public verifySyntacticClassifications(expected: { classificationType: string; text: string }[]) { - var actual = this.languageService.getSyntacticClassifications(this.activeFile.fileName, + let actual = this.languageService.getSyntacticClassifications(this.activeFile.fileName, ts.createTextSpan(0, this.activeFile.content.length)); this.verifyClassifications(expected, actual); @@ -1907,15 +1907,15 @@ module FourSlash { public verifyOutliningSpans(spans: TextSpan[]) { this.taoInvalidReason = 'verifyOutliningSpans NYI'; - var actual = this.languageService.getOutliningSpans(this.activeFile.fileName); + let actual = this.languageService.getOutliningSpans(this.activeFile.fileName); if (actual.length !== spans.length) { this.raiseError('verifyOutliningSpans failed - expected total spans to be ' + spans.length + ', but was ' + actual.length); } - for (var i = 0; i < spans.length; i++) { - var expectedSpan = spans[i]; - var actualSpan = actual[i]; + for (let i = 0; i < spans.length; i++) { + let expectedSpan = spans[i]; + let actualSpan = actual[i]; if (expectedSpan.start !== actualSpan.textSpan.start || expectedSpan.end !== ts.textSpanEnd(actualSpan.textSpan)) { this.raiseError('verifyOutliningSpans failed - span ' + (i + 1) + ' expected: (' + expectedSpan.start + ',' + expectedSpan.end + '), actual: (' + actualSpan.textSpan.start + ',' + ts.textSpanEnd(actualSpan.textSpan) + ')'); } @@ -1923,17 +1923,17 @@ module FourSlash { } public verifyTodoComments(descriptors: string[], spans: TextSpan[]) { - var actual = this.languageService.getTodoComments(this.activeFile.fileName, + let actual = this.languageService.getTodoComments(this.activeFile.fileName, descriptors.map(d => { return { text: d, priority: 0 }; })); if (actual.length !== spans.length) { this.raiseError('verifyTodoComments failed - expected total spans to be ' + spans.length + ', but was ' + actual.length); } - for (var i = 0; i < spans.length; i++) { - var expectedSpan = spans[i]; - var actualComment = actual[i]; - var actualCommentSpan = ts.createTextSpan(actualComment.position, actualComment.message.length); + for (let i = 0; i < spans.length; i++) { + let expectedSpan = spans[i]; + let actualComment = actual[i]; + let actualCommentSpan = ts.createTextSpan(actualComment.position, actualComment.message.length); if (expectedSpan.start !== actualCommentSpan.start || expectedSpan.end !== ts.textSpanEnd(actualCommentSpan)) { this.raiseError('verifyOutliningSpans failed - span ' + (i + 1) + ' expected: (' + expectedSpan.start + ',' + expectedSpan.end + '), actual: (' + actualCommentSpan.start + ',' + ts.textSpanEnd(actualCommentSpan) + ')'); @@ -1944,13 +1944,13 @@ module FourSlash { public verifyMatchingBracePosition(bracePosition: number, expectedMatchPosition: number) { this.taoInvalidReason = 'verifyMatchingBracePosition NYI'; - var actual = this.languageService.getBraceMatchingAtPosition(this.activeFile.fileName, bracePosition); + let actual = this.languageService.getBraceMatchingAtPosition(this.activeFile.fileName, bracePosition); if (actual.length !== 2) { this.raiseError('verifyMatchingBracePosition failed - expected result to contain 2 spans, but it had ' + actual.length); } - var actualMatchPosition = -1; + let actualMatchPosition = -1; if (bracePosition === actual[0].start) { actualMatchPosition = actual[1].start; } else if (bracePosition === actual[1].start) { @@ -1967,7 +1967,7 @@ module FourSlash { public verifyNoMatchingBracePosition(bracePosition: number) { this.taoInvalidReason = 'verifyNoMatchingBracePosition NYI'; - var actual = this.languageService.getBraceMatchingAtPosition(this.activeFile.fileName, bracePosition); + let actual = this.languageService.getBraceMatchingAtPosition(this.activeFile.fileName, bracePosition); if (actual.length !== 0) { this.raiseError('verifyNoMatchingBracePosition failed - expected: 0 spans, actual: ' + actual.length); @@ -1981,12 +1981,12 @@ module FourSlash { public verifyNavigationItemsCount(expected: number, searchValue: string, matchKind?: string) { this.taoInvalidReason = 'verifyNavigationItemsCount NYI'; - var items = this.languageService.getNavigateToItems(searchValue); - var actual = 0; - var item: ts.NavigateToItem = null; + let items = this.languageService.getNavigateToItems(searchValue); + let actual = 0; + let item: ts.NavigateToItem = null; // Count only the match that match the same MatchKind - for (var i = 0; i < items.length; ++i) { + for (let i = 0; i < items.length; ++i) { item = items[i]; if (!matchKind || item.matchKind === matchKind) { actual++; @@ -2011,14 +2011,14 @@ module FourSlash { parentName?: string) { this.taoInvalidReason = 'verifyNavigationItemsListContains NYI'; - var items = this.languageService.getNavigateToItems(searchValue); + let items = this.languageService.getNavigateToItems(searchValue); if (!items || items.length === 0) { this.raiseError('verifyNavigationItemsListContains failed - found 0 navigation items, expected at least one.'); } - for (var i = 0; i < items.length; i++) { - var item = items[i]; + for (let i = 0; i < items.length; i++) { + let item = items[i]; if (item && item.name === name && item.kind === kind && (matchKind === undefined || item.matchKind === matchKind) && (fileName === undefined || item.fileName === fileName) && @@ -2029,7 +2029,7 @@ module FourSlash { // if there was an explicit match kind specified, then it should be validated. if (matchKind !== undefined) { - var missingItem = { name: name, kind: kind, searchValue: searchValue, matchKind: matchKind, fileName: fileName, parentName: parentName }; + let missingItem = { name: name, kind: kind, searchValue: searchValue, matchKind: matchKind, fileName: fileName, parentName: parentName }; this.raiseError('verifyNavigationItemsListContains failed - could not find the item: ' + JSON.stringify(missingItem) + ' in the returned list: (' + JSON.stringify(items) + ')'); } } @@ -2037,8 +2037,8 @@ module FourSlash { public verifyGetScriptLexicalStructureListCount(expected: number) { this.taoInvalidReason = 'verifyNavigationItemsListContains impossible'; - var items = this.languageService.getNavigationBarItems(this.activeFile.fileName); - var actual = this.getNavigationBarItemsCount(items); + let items = this.languageService.getNavigationBarItems(this.activeFile.fileName); + let actual = this.getNavigationBarItemsCount(items); if (expected !== actual) { this.raiseError('verifyGetScriptLexicalStructureListCount failed - found: ' + actual + ' navigation items, expected: ' + expected + '.'); @@ -2046,9 +2046,9 @@ module FourSlash { } private getNavigationBarItemsCount(items: ts.NavigationBarItem[]) { - var result = 0; + let result = 0; if (items) { - for (var i = 0, n = items.length; i < n; i++) { + for (let i = 0, n = items.length; i < n; i++) { result++; result += this.getNavigationBarItemsCount(items[i].childItems); } @@ -2063,7 +2063,7 @@ module FourSlash { markerPosition?: number) { this.taoInvalidReason = 'verifGetScriptLexicalStructureListContains impossible'; - var items = this.languageService.getNavigationBarItems(this.activeFile.fileName); + let items = this.languageService.getNavigationBarItems(this.activeFile.fileName); if (!items || items.length === 0) { this.raiseError('verifyGetScriptLexicalStructureListContains failed - found 0 navigation items, expected at least one.'); @@ -2073,14 +2073,14 @@ module FourSlash { return; } - var missingItem = { name: name, kind: kind }; + let missingItem = { name: name, kind: kind }; this.raiseError('verifyGetScriptLexicalStructureListContains failed - could not find the item: ' + JSON.stringify(missingItem) + ' in the returned list: (' + JSON.stringify(items, null, " ") + ')'); } private navigationBarItemsContains(items: ts.NavigationBarItem[], name: string, kind: string) { if (items) { - for (var i = 0; i < items.length; i++) { - var item = items[i]; + for (let i = 0; i < items.length; i++) { + let item = items[i]; if (item && item.text === name && item.kind === kind) { return true; } @@ -2095,25 +2095,25 @@ module FourSlash { } public printNavigationItems(searchValue: string) { - var items = this.languageService.getNavigateToItems(searchValue); - var length = items && items.length; + let items = this.languageService.getNavigateToItems(searchValue); + let length = items && items.length; Harness.IO.log('NavigationItems list (' + length + ' items)'); - for (var i = 0; i < length; i++) { - var item = items[i]; + for (let i = 0; i < length; i++) { + let item = items[i]; Harness.IO.log('name: ' + item.name + ', kind: ' + item.kind + ', parentName: ' + item.containerName + ', fileName: ' + item.fileName); } } public printScriptLexicalStructureItems() { - var items = this.languageService.getNavigationBarItems(this.activeFile.fileName); - var length = items && items.length; + let items = this.languageService.getNavigationBarItems(this.activeFile.fileName); + let length = items && items.length; Harness.IO.log('NavigationItems list (' + length + ' items)'); - for (var i = 0; i < length; i++) { - var item = items[i]; + for (let i = 0; i < length; i++) { + let item = items[i]; Harness.IO.log('name: ' + item.text + ', kind: ' + item.kind); } } @@ -2125,14 +2125,14 @@ module FourSlash { public verifyOccurrencesAtPositionListContains(fileName: string, start: number, end: number, isWriteAccess?: boolean) { this.taoInvalidReason = 'verifyOccurrencesAtPositionListContains NYI'; - var occurances = this.getOccurancesAtCurrentPosition(); + let occurances = this.getOccurancesAtCurrentPosition(); if (!occurances || occurances.length === 0) { this.raiseError('verifyOccurancesAtPositionListContains failed - found 0 references, expected at least one.'); } - for (var i = 0; i < occurances.length; i++) { - var occurance = occurances[i]; + for (let i = 0; i < occurances.length; i++) { + let occurance = occurances[i]; if (occurance && occurance.fileName === fileName && occurance.textSpan.start === start && ts.textSpanEnd(occurance.textSpan) === end) { if (typeof isWriteAccess !== "undefined" && occurance.isWriteAccess !== isWriteAccess) { this.raiseError('verifyOccurancesAtPositionListContains failed - item isWriteAccess value doe not match, actual: ' + occurance.isWriteAccess + ', expected: ' + isWriteAccess + '.'); @@ -2141,15 +2141,15 @@ module FourSlash { } } - var missingItem = { fileName: fileName, start: start, end: end, isWriteAccess: isWriteAccess }; + let missingItem = { fileName: fileName, start: start, end: end, isWriteAccess: isWriteAccess }; this.raiseError('verifyOccurancesAtPositionListContains failed - could not find the item: ' + JSON.stringify(missingItem) + ' in the returned list: (' + JSON.stringify(occurances) + ')'); } public verifyOccurrencesAtPositionListCount(expectedCount: number) { this.taoInvalidReason = 'verifyOccurrencesAtPositionListCount NYI'; - var occurances = this.getOccurancesAtCurrentPosition(); - var actualCount = occurances ? occurances.length : 0; + let occurances = this.getOccurancesAtCurrentPosition(); + let actualCount = occurances ? occurances.length : 0; if (expectedCount !== actualCount) { this.raiseError('verifyOccurrencesAtPositionListCount failed - actual: ' + actualCount + ', expected:' + expectedCount); } @@ -2157,13 +2157,13 @@ module FourSlash { // Get the text of the entire line the caret is currently at private getCurrentLineContent() { - var text = this.getFileContent(this.activeFile.fileName); + let text = this.getFileContent(this.activeFile.fileName); - var pos = this.currentCaretPosition; - var startPos = pos, endPos = pos; + let pos = this.currentCaretPosition; + let startPos = pos, endPos = pos; while (startPos > 0) { - var ch = text.charCodeAt(startPos - 1); + let ch = text.charCodeAt(startPos - 1); if (ch === ts.CharacterCodes.carriageReturn || ch === ts.CharacterCodes.lineFeed) { break; } @@ -2172,7 +2172,7 @@ module FourSlash { } while (endPos < text.length) { - var ch = text.charCodeAt(endPos); + let ch = text.charCodeAt(endPos); if (ch === ts.CharacterCodes.carriageReturn || ch === ts.CharacterCodes.lineFeed) { break; @@ -2192,11 +2192,11 @@ module FourSlash { this.taoInvalidReason = 'assertItemInCompletionList only supports the "name" parameter'; } - for (var i = 0; i < items.length; i++) { - var item = items[i]; + for (let i = 0; i < items.length; i++) { + let item = items[i]; if (item.name === name) { if (documentation != undefined || text !== undefined) { - var details = this.getCompletionEntryDetails(item.name); + let details = this.getCompletionEntryDetails(item.name); if (documentation !== undefined) { assert.equal(ts.displayPartsToString(details.documentation), documentation, assertionMessage("completion item documentation")); @@ -2214,30 +2214,30 @@ module FourSlash { } } - var itemsString = items.map((item) => JSON.stringify({ name: item.name, kind: item.kind })).join(",\n"); + let itemsString = items.map((item) => JSON.stringify({ name: item.name, kind: item.kind })).join(",\n"); this.raiseError('Expected "' + JSON.stringify({ name, text, documentation, kind }) + '" to be in list [' + itemsString + ']'); } private findFile(indexOrName: any) { - var result: FourSlashFile = null; + let result: FourSlashFile = null; if (typeof indexOrName === 'number') { - var index = indexOrName; + let index = indexOrName; if (index >= this.testData.files.length) { throw new Error('File index (' + index + ') in openFile was out of range. There are only ' + this.testData.files.length + ' files in this test.'); } else { result = this.testData.files[index]; } } else if (typeof indexOrName === 'string') { - var name = indexOrName; + let name = indexOrName; // names are stored in the compiler with this relative path, this allows people to use goTo.file on just the fileName name = name.indexOf('/') === -1 ? (this.basePath + '/' + name) : name; - var availableNames: string[] = []; - var foundIt = false; - for (var i = 0; i < this.testData.files.length; i++) { - var fn = this.testData.files[i].fileName; + let availableNames: string[] = []; + let foundIt = false; + for (let i = 0; i < this.testData.files.length; i++) { + let fn = this.testData.files[i].fileName; if (fn) { if (fn === name) { result = this.testData.files[i]; @@ -2259,15 +2259,15 @@ module FourSlash { } private getLineColStringAtPosition(position: number) { - var pos = this.languageServiceAdapterHost.positionToLineAndCharacter(this.activeFile.fileName, position); + let pos = this.languageServiceAdapterHost.positionToLineAndCharacter(this.activeFile.fileName, position); return 'line ' + (pos.line + 1) + ', col ' + pos.character; } private getMarkerByName(markerName: string) { - var markerPos = this.testData.markerPositions[markerName]; + let markerPos = this.testData.markerPositions[markerName]; if (markerPos === undefined) { - var markerNames: string[] = []; - for (var m in this.testData.markerPositions) markerNames.push(m); + let markerNames: string[] = []; + for (let m in this.testData.markerPositions) markerNames.push(m); throw new Error('Unknown marker "' + markerName + '" Available markers: ' + markerNames.map(m => '"' + m + '"').join(', ')); } else { return markerPos; @@ -2296,12 +2296,12 @@ module FourSlash { } // TOOD: should these just use the Harness's stdout/stderr? - var fsOutput = new Harness.Compiler.WriterAggregator(); - var fsErrors = new Harness.Compiler.WriterAggregator(); - export var xmlData: TestXmlData[] = []; + let fsOutput = new Harness.Compiler.WriterAggregator(); + let fsErrors = new Harness.Compiler.WriterAggregator(); + export let xmlData: TestXmlData[] = []; export function runFourSlashTest(basePath: string, testType: FourSlashTestType, fileName: string) { - var content = Harness.IO.readFile(fileName); - var xml = runFourSlashTestContent(basePath, testType, content, fileName); + let content = Harness.IO.readFile(fileName); + let xml = runFourSlashTestContent(basePath, testType, content, fileName); xmlData.push(xml); } @@ -2366,8 +2366,8 @@ module FourSlash { } function chompLeadingSpace(content: string) { - var lines = content.split("\n"); - for (var i = 0; i < lines.length; i++) { + let lines = content.split("\n"); + for (let i = 0; i < lines.length; i++) { if ((lines[i].length !== 0) && (lines[i].charAt(0) !== ' ')) { return content; } @@ -2378,31 +2378,31 @@ module FourSlash { function parseTestData(basePath: string, contents: string, fileName: string): FourSlashData { // Regex for parsing options in the format "@Alpha: Value of any sort" - var optionRegex = /^\s*@(\w+): (.*)\s*/; + let optionRegex = /^\s*@(\w+): (.*)\s*/; // List of all the subfiles we've parsed out - var files: FourSlashFile[] = []; + let files: FourSlashFile[] = []; // Global options - var globalOptions: { [s: string]: string; } = {}; + let globalOptions: { [s: string]: string; } = {}; // Marker positions // Split up the input file by line // Note: IE JS engine incorrectly handles consecutive delimiters here when using RegExp split, so // we have to string-based splitting instead and try to figure out the delimiting chars - var lines = contents.split('\n'); + let lines = contents.split('\n'); - var markerPositions: MarkerMap = {}; - var markers: Marker[] = []; - var ranges: Range[] = []; + let markerPositions: MarkerMap = {}; + let markers: Marker[] = []; + let ranges: Range[] = []; // Stuff related to the subfile we're parsing - var currentFileContent: string = null; - var currentFileName = fileName; - var currentFileOptions: { [s: string]: string } = {}; + let currentFileContent: string = null; + let currentFileName = fileName; + let currentFileOptions: { [s: string]: string } = {}; - for (var i = 0; i < lines.length; i++) { - var line = lines[i]; - var lineLength = line.length; + for (let i = 0; i < lines.length; i++) { + let line = lines[i]; + let lineLength = line.length; if (lineLength > 0 && line.charAt(lineLength - 1) === '\r') { line = line.substr(0, lineLength - 1); @@ -2422,17 +2422,17 @@ module FourSlash { currentFileContent = currentFileContent + line.substr(4); } else if (line.substr(0, 2) === '//') { // Comment line, check for global/file @options and record them - var match = optionRegex.exec(line.substr(2)); + let match = optionRegex.exec(line.substr(2)); if (match) { - var globalMetadataNamesIndex = globalMetadataNames.indexOf(match[1]); - var fileMetadataNamesIndex = fileMetadataNames.indexOf(match[1]); + let globalMetadataNamesIndex = globalMetadataNames.indexOf(match[1]); + let fileMetadataNamesIndex = fileMetadataNames.indexOf(match[1]); if (globalMetadataNamesIndex === -1) { if (fileMetadataNamesIndex === -1) { throw new Error('Unrecognized metadata name "' + match[1] + '". Available global metadata names are: ' + globalMetadataNames.join(', ') + '; file metadata names are: ' + fileMetadataNames.join(', ')); } else if (fileMetadataNamesIndex === fileMetadataNames.indexOf(metadataOptionNames.fileName)) { // Found an @FileName directive, if this is not the first then create a new subfile if (currentFileContent) { - var file = parseFileContent(currentFileContent, currentFileName, markerPositions, markers, ranges); + let file = parseFileContent(currentFileContent, currentFileName, markerPositions, markers, ranges); file.fileOptions = currentFileOptions; // Store result file @@ -2465,7 +2465,7 @@ module FourSlash { } else { // Empty line or code line, terminate current subfile if there is one if (currentFileContent) { - var file = parseFileContent(currentFileContent, currentFileName, markerPositions, markers, ranges); + let file = parseFileContent(currentFileContent, currentFileName, markerPositions, markers, ranges); file.fileOptions = currentFileOptions; // Store result file @@ -2495,12 +2495,12 @@ module FourSlash { } function reportError(fileName: string, line: number, col: number, message: string) { - var errorMessage = fileName + "(" + line + "," + col + "): " + message; + let errorMessage = fileName + "(" + line + "," + col + "): " + message; throw new Error(errorMessage); } function recordObjectMarker(fileName: string, location: ILocationInformation, text: string, markerMap: MarkerMap, markers: Marker[]): Marker { - var markerValue: any = undefined; + let markerValue: any = undefined; try { // Attempt to parse the marker value as JSON markerValue = JSON.parse("{ " + text + " }"); @@ -2513,7 +2513,7 @@ module FourSlash { return null; } - var marker: Marker = { + let marker: Marker = { fileName: fileName, position: location.position, data: markerValue @@ -2530,14 +2530,14 @@ module FourSlash { } function recordMarker(fileName: string, location: ILocationInformation, name: string, markerMap: MarkerMap, markers: Marker[]): Marker { - var marker: Marker = { + let marker: Marker = { fileName: fileName, position: location.position }; // Verify markers for uniqueness if (markerMap[name] !== undefined) { - var message = "Marker '" + name + "' is duplicated in the source file contents."; + let message = "Marker '" + name + "' is duplicated in the source file contents."; reportError(marker.fileName, location.sourceLine, location.sourceColumn, message); return null; } else { @@ -2551,34 +2551,34 @@ module FourSlash { content = chompLeadingSpace(content); // Any slash-star comment with a character not in this string is not a marker. - var validMarkerChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz$1234567890_'; + let validMarkerChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz$1234567890_'; /// The file content (minus metacharacters) so far - var output: string = ""; + let output: string = ""; /// The current marker (or maybe multi-line comment?) we're parsing, possibly - var openMarker: ILocationInformation = null; + let openMarker: ILocationInformation = null; /// A stack of the open range markers that are still unclosed - var openRanges: IRangeLocationInformation[] = []; + let openRanges: IRangeLocationInformation[] = []; /// A list of ranges we've collected so far */ - var localRanges: Range[] = []; + let localRanges: Range[] = []; /// The latest position of the start of an unflushed plain text area - var lastNormalCharPosition: number = 0; + let lastNormalCharPosition: number = 0; /// The total number of metacharacters removed from the file (so far) - var difference: number = 0; + let difference: number = 0; /// The fourslash file state object we are generating - var state: State = State.none; + let state: State = State.none; /// Current position data - var line: number = 1; - var column: number = 1; + let line: number = 1; + let column: number = 1; - var flush = (lastSafeCharIndex: number) => { + let flush = (lastSafeCharIndex: number) => { if (lastSafeCharIndex === undefined) { output = output + content.substr(lastNormalCharPosition); } else { @@ -2587,9 +2587,9 @@ module FourSlash { }; if (content.length > 0) { - var previousChar = content.charAt(0); - for (var i = 1; i < content.length; i++) { - var currentChar = content.charAt(i); + let previousChar = content.charAt(0); + for (let i = 1; i < content.length; i++) { + let currentChar = content.charAt(i); switch (state) { case State.none: if (previousChar === "[" && currentChar === "|") { @@ -2606,12 +2606,12 @@ module FourSlash { difference += 2; } else if (previousChar === "|" && currentChar === "]") { // found a range end - var rangeStart = openRanges.pop(); + let rangeStart = openRanges.pop(); if (!rangeStart) { reportError(fileName, line, column, "Found range end with no matching start."); } - var range: Range = { + let range: Range = { fileName: fileName, start: rangeStart.position, end: (i - 1) - difference, @@ -2649,8 +2649,8 @@ module FourSlash { // Object markers are only ever terminated by |} and have no content restrictions if (previousChar === "|" && currentChar === "}") { // Record the marker - var objectMarkerNameText = content.substring(openMarker.sourcePosition + 2, i - 1).trim(); - var marker = recordObjectMarker(fileName, openMarker, objectMarkerNameText, markerMap, markers); + let objectMarkerNameText = content.substring(openMarker.sourcePosition + 2, i - 1).trim(); + let marker = recordObjectMarker(fileName, openMarker, objectMarkerNameText, markerMap, markers); if (openRanges.length > 0) { openRanges[openRanges.length - 1].marker = marker; @@ -2670,8 +2670,8 @@ module FourSlash { if (previousChar === "*" && currentChar === "/") { // Record the marker // start + 2 to ignore the */, -1 on the end to ignore the * (/ is next) - var markerNameText = content.substring(openMarker.sourcePosition + 2, i - 1).trim(); - var marker = recordMarker(fileName, openMarker, markerNameText, markerMap, markers); + let markerNameText = content.substring(openMarker.sourcePosition + 2, i - 1).trim(); + let marker = recordMarker(fileName, openMarker, markerNameText, markerMap, markers); if (openRanges.length > 0) { openRanges[openRanges.length - 1].marker = marker; @@ -2719,7 +2719,7 @@ module FourSlash { flush(undefined); if (openRanges.length > 0) { - var openRange = openRanges[0]; + let openRange = openRanges[0]; reportError(fileName, openRange.sourceLine, openRange.sourceColumn, "Unterminated range."); } diff --git a/src/harness/fourslashRunner.ts b/src/harness/fourslashRunner.ts index aa7174cc83b..05a11c4f52d 100644 --- a/src/harness/fourslashRunner.ts +++ b/src/harness/fourslashRunner.ts @@ -35,40 +35,40 @@ class FourSlashRunner extends RunnerBase { this.tests = this.enumerateFiles(this.basePath, /\.ts/i, { recursive: false }); } - describe(this.testSuiteName + ' tests', () => { + describe(this.testSuiteName + ' tests', () => { this.tests.forEach((fn: string) => { describe(fn, () => { fn = ts.normalizeSlashes(fn); - var justName = fn.replace(/^.*[\\\/]/, ''); - + let justName = fn.replace(/^.*[\\\/]/, ''); + // Convert to relative path - var testIndex = fn.indexOf('tests/'); + let testIndex = fn.indexOf('tests/'); if (testIndex >= 0) fn = fn.substr(testIndex); - if (justName && !justName.match(/fourslash\.ts$/i) && !justName.match(/\.d\.ts$/i)) { + if (justName && !justName.match(/fourslash\.ts$/i) && !justName.match(/\.d\.ts$/i)) { it(this.testSuiteName + ' test ' + justName + ' runs correctly', () => { FourSlash.runFourSlashTest(this.basePath, this.testType, fn); }); } }); - }); + }); describe('Generate Tao XML', () => { - var invalidReasons: any = {}; + let invalidReasons: any = {}; FourSlash.xmlData.forEach(xml => { if (xml.invalidReason !== null) { invalidReasons[xml.invalidReason] = (invalidReasons[xml.invalidReason] || 0) + 1; } }); - var invalidReport: { reason: string; count: number }[] = []; - for (var reason in invalidReasons) { + let invalidReport: { reason: string; count: number }[] = []; + for (let reason in invalidReasons) { if (invalidReasons.hasOwnProperty(reason)) { invalidReport.push({ reason: reason, count: invalidReasons[reason] }); } } invalidReport.sort((lhs, rhs) => lhs.count > rhs.count ? -1 : lhs.count === rhs.count ? 0 : 1); - var lines: string[] = []; + let lines: string[] = []; lines.push('