From f7647db7f7d0b9b48fefbc5cd56b9246289b680b Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Tue, 4 Oct 2016 06:30:05 -0700 Subject: [PATCH 01/80] Fix tests changed by #11309 --- .../reference/variableDeclarationInStrictMode1.errors.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/baselines/reference/variableDeclarationInStrictMode1.errors.txt b/tests/baselines/reference/variableDeclarationInStrictMode1.errors.txt index 9dd9a8d41a..46782aaa1d 100644 --- a/tests/baselines/reference/variableDeclarationInStrictMode1.errors.txt +++ b/tests/baselines/reference/variableDeclarationInStrictMode1.errors.txt @@ -1,4 +1,4 @@ -lib.d.ts(28,18): error TS2300: Duplicate identifier 'eval'. +lib.d.ts(32,18): error TS2300: Duplicate identifier 'eval'. tests/cases/compiler/variableDeclarationInStrictMode1.ts(2,5): error TS1100: Invalid use of 'eval' in strict mode. tests/cases/compiler/variableDeclarationInStrictMode1.ts(2,5): error TS2300: Duplicate identifier 'eval'. From a70624d4159e9de3f2c497d2f7ec52082fee7bf6 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 4 Oct 2016 12:08:58 -0700 Subject: [PATCH 02/80] Add test when require is just a function in external module --- ...quireAsFunctionInExternalModule.errors.txt | 20 ++++++++++ .../requireAsFunctionInExternalModule.js | 37 +++++++++++++++++++ .../requireAsFunctionInExternalModule.ts | 16 ++++++++ 3 files changed, 73 insertions(+) create mode 100644 tests/baselines/reference/requireAsFunctionInExternalModule.errors.txt create mode 100644 tests/baselines/reference/requireAsFunctionInExternalModule.js create mode 100644 tests/cases/compiler/requireAsFunctionInExternalModule.ts diff --git a/tests/baselines/reference/requireAsFunctionInExternalModule.errors.txt b/tests/baselines/reference/requireAsFunctionInExternalModule.errors.txt new file mode 100644 index 0000000000..58e3b145f3 --- /dev/null +++ b/tests/baselines/reference/requireAsFunctionInExternalModule.errors.txt @@ -0,0 +1,20 @@ +tests/cases/compiler/m2.ts(1,10): error TS2305: Module '"tests/cases/compiler/m"' has no exported member 'hello'. + + +==== tests/cases/compiler/c.js (0 errors) ==== + export default function require(a) { } + export function has(a) { return true } + +==== tests/cases/compiler/m.js (0 errors) ==== + import require, { has } from "./c" + export function hello() { } + if (has('ember-debug')) { + require('ember-debug'); + } + +==== tests/cases/compiler/m2.ts (1 errors) ==== + import { hello } from "./m"; + ~~~~~ +!!! error TS2305: Module '"tests/cases/compiler/m"' has no exported member 'hello'. + hello(); + \ No newline at end of file diff --git a/tests/baselines/reference/requireAsFunctionInExternalModule.js b/tests/baselines/reference/requireAsFunctionInExternalModule.js new file mode 100644 index 0000000000..a8b14db313 --- /dev/null +++ b/tests/baselines/reference/requireAsFunctionInExternalModule.js @@ -0,0 +1,37 @@ +//// [tests/cases/compiler/requireAsFunctionInExternalModule.ts] //// + +//// [c.js] +export default function require(a) { } +export function has(a) { return true } + +//// [m.js] +import require, { has } from "./c" +export function hello() { } +if (has('ember-debug')) { + require('ember-debug'); +} + +//// [m2.ts] +import { hello } from "./m"; +hello(); + + +//// [c.js] +"use strict"; +function require(a) { } +exports.__esModule = true; +exports["default"] = require; +function has(a) { return true; } +exports.has = has; +//// [m.js] +"use strict"; +var c_1 = require("./c"); +function hello() { } +exports.hello = hello; +if (c_1.has('ember-debug')) { + c_1["default"]('ember-debug'); +} +//// [m2.js] +"use strict"; +var m_1 = require("./m"); +m_1.hello(); diff --git a/tests/cases/compiler/requireAsFunctionInExternalModule.ts b/tests/cases/compiler/requireAsFunctionInExternalModule.ts new file mode 100644 index 0000000000..1715090c32 --- /dev/null +++ b/tests/cases/compiler/requireAsFunctionInExternalModule.ts @@ -0,0 +1,16 @@ +// @allowjs: true +// @outDir: dist +// @Filename: c.js +export default function require(a) { } +export function has(a) { return true } + +// @Filename: m.js +import require, { has } from "./c" +export function hello() { } +if (has('ember-debug')) { + require('ember-debug'); +} + +// @Filename: m2.ts +import { hello } from "./m"; +hello(); From a830c844b7846f56a785d0ed8a2e75d4bec7a14f Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 4 Oct 2016 12:25:07 -0700 Subject: [PATCH 03/80] Bind the source file as external module only if not already done Return type of require call is from external module resolution only if it doesnt resolve to local module Fixes #10931 --- src/compiler/binder.ts | 4 +- src/compiler/checker.ts | 5 ++- ...quireAsFunctionInExternalModule.errors.txt | 20 ---------- .../requireAsFunctionInExternalModule.symbols | 31 ++++++++++++++++ .../requireAsFunctionInExternalModule.types | 37 +++++++++++++++++++ 5 files changed, 75 insertions(+), 22 deletions(-) delete mode 100644 tests/baselines/reference/requireAsFunctionInExternalModule.errors.txt create mode 100644 tests/baselines/reference/requireAsFunctionInExternalModule.symbols create mode 100644 tests/baselines/reference/requireAsFunctionInExternalModule.types diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 2fe7d30ab5..c8785819b9 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -2000,7 +2000,9 @@ namespace ts { function setCommonJsModuleIndicator(node: Node) { if (!file.commonJsModuleIndicator) { file.commonJsModuleIndicator = node; - bindSourceFileAsExternalModule(); + if (!file.externalModuleIndicator) { + bindSourceFileAsExternalModule(); + } } } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 422f2a70dc..1354002a29 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12535,7 +12535,10 @@ namespace ts { } // In JavaScript files, calls to any identifier 'require' are treated as external module imports - if (isInJavaScriptFile(node) && isRequireCall(node, /*checkArgumentIsStringLiteral*/true)) { + if (isInJavaScriptFile(node) && + isRequireCall(node, /*checkArgumentIsStringLiteral*/true) && + // Make sure require is not a local function + !resolveName(node.expression, (node.expression).text, SymbolFlags.Value | SymbolFlags.ExportValue, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined)) { return resolveExternalModuleTypeByLiteral(node.arguments[0]); } diff --git a/tests/baselines/reference/requireAsFunctionInExternalModule.errors.txt b/tests/baselines/reference/requireAsFunctionInExternalModule.errors.txt deleted file mode 100644 index 58e3b145f3..0000000000 --- a/tests/baselines/reference/requireAsFunctionInExternalModule.errors.txt +++ /dev/null @@ -1,20 +0,0 @@ -tests/cases/compiler/m2.ts(1,10): error TS2305: Module '"tests/cases/compiler/m"' has no exported member 'hello'. - - -==== tests/cases/compiler/c.js (0 errors) ==== - export default function require(a) { } - export function has(a) { return true } - -==== tests/cases/compiler/m.js (0 errors) ==== - import require, { has } from "./c" - export function hello() { } - if (has('ember-debug')) { - require('ember-debug'); - } - -==== tests/cases/compiler/m2.ts (1 errors) ==== - import { hello } from "./m"; - ~~~~~ -!!! error TS2305: Module '"tests/cases/compiler/m"' has no exported member 'hello'. - hello(); - \ No newline at end of file diff --git a/tests/baselines/reference/requireAsFunctionInExternalModule.symbols b/tests/baselines/reference/requireAsFunctionInExternalModule.symbols new file mode 100644 index 0000000000..2f44d6b661 --- /dev/null +++ b/tests/baselines/reference/requireAsFunctionInExternalModule.symbols @@ -0,0 +1,31 @@ +=== tests/cases/compiler/c.js === +export default function require(a) { } +>require : Symbol(require, Decl(c.js, 0, 0)) +>a : Symbol(a, Decl(c.js, 0, 32)) + +export function has(a) { return true } +>has : Symbol(has, Decl(c.js, 0, 38)) +>a : Symbol(a, Decl(c.js, 1, 20)) + +=== tests/cases/compiler/m.js === +import require, { has } from "./c" +>require : Symbol(require, Decl(m.js, 0, 6)) +>has : Symbol(has, Decl(m.js, 0, 17)) + +export function hello() { } +>hello : Symbol(hello, Decl(m.js, 0, 34)) + +if (has('ember-debug')) { +>has : Symbol(has, Decl(m.js, 0, 17)) + + require('ember-debug'); +>require : Symbol(require, Decl(m.js, 0, 6)) +} + +=== tests/cases/compiler/m2.ts === +import { hello } from "./m"; +>hello : Symbol(hello, Decl(m2.ts, 0, 8)) + +hello(); +>hello : Symbol(hello, Decl(m2.ts, 0, 8)) + diff --git a/tests/baselines/reference/requireAsFunctionInExternalModule.types b/tests/baselines/reference/requireAsFunctionInExternalModule.types new file mode 100644 index 0000000000..2ce5f3aed3 --- /dev/null +++ b/tests/baselines/reference/requireAsFunctionInExternalModule.types @@ -0,0 +1,37 @@ +=== tests/cases/compiler/c.js === +export default function require(a) { } +>require : (a: any) => void +>a : any + +export function has(a) { return true } +>has : (a: any) => boolean +>a : any +>true : true + +=== tests/cases/compiler/m.js === +import require, { has } from "./c" +>require : (a: any) => void +>has : (a: any) => boolean + +export function hello() { } +>hello : () => void + +if (has('ember-debug')) { +>has('ember-debug') : boolean +>has : (a: any) => boolean +>'ember-debug' : "ember-debug" + + require('ember-debug'); +>require('ember-debug') : void +>require : (a: any) => void +>'ember-debug' : "ember-debug" +} + +=== tests/cases/compiler/m2.ts === +import { hello } from "./m"; +>hello : () => void + +hello(); +>hello() : void +>hello : () => void + From 2c46f9b6870348bd14973c1e5abb2f3ba893c084 Mon Sep 17 00:00:00 2001 From: Andrej Baran Date: Wed, 5 Oct 2016 17:09:58 +0200 Subject: [PATCH 04/80] Add ES8/ES2017 target (#10768) --- src/compiler/commandLineParser.ts | 2 ++ src/compiler/core.ts | 2 +- src/compiler/emitter.ts | 5 +++- src/compiler/transformer.ts | 6 +++-- src/compiler/transformers/ts.ts | 41 +++++++++++++++++++++++++------ src/compiler/types.ts | 4 ++- 6 files changed, 47 insertions(+), 13 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 648447ac26..16d338cac6 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -262,7 +262,9 @@ namespace ts { "es3": ScriptTarget.ES3, "es5": ScriptTarget.ES5, "es6": ScriptTarget.ES6, + "es8": ScriptTarget.ES8, "es2015": ScriptTarget.ES2015, + "es2017": ScriptTarget.ES2017, }), description: Diagnostics.Specify_ECMAScript_target_version_Colon_ES3_default_ES5_or_ES2015, paramType: Diagnostics.VERSION, diff --git a/src/compiler/core.ts b/src/compiler/core.ts index e63bcbf847..3f2cc619cb 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1191,7 +1191,7 @@ namespace ts { export function getEmitModuleKind(compilerOptions: CompilerOptions) { return typeof compilerOptions.module === "number" ? compilerOptions.module : - getEmitScriptTarget(compilerOptions) === ScriptTarget.ES6 ? ModuleKind.ES6 : ModuleKind.CommonJS; + getEmitScriptTarget(compilerOptions) >= ScriptTarget.ES6 ? ModuleKind.ES6 : ModuleKind.CommonJS; } /* @internal */ diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index b3242e211d..b0e31278ff 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -2192,7 +2192,10 @@ const _super = (function (geti, seti) { helpersEmitted = true; } - if (!awaiterEmitted && node.flags & NodeFlags.HasAsyncFunctions) { + // Only emit __awaiter function when target ES5/ES6. + // Only emit __generator function when target ES5. + // For target ES8 and above, we can emit async/await as is. + if ((languageVersion < ScriptTarget.ES8) && (!awaiterEmitted && node.flags & NodeFlags.HasAsyncFunctions)) { writeLines(awaiterHelper); if (languageVersion < ScriptTarget.ES6) { writeLines(generatorHelper); diff --git a/src/compiler/transformer.ts b/src/compiler/transformer.ts index 92407af2bb..415a9ecd1d 100644 --- a/src/compiler/transformer.ts +++ b/src/compiler/transformer.ts @@ -115,7 +115,9 @@ namespace ts { transformers.push(transformJsx); } - transformers.push(transformES7); + if (languageVersion < ScriptTarget.ES8) { + transformers.push(transformES7); + } if (languageVersion < ScriptTarget.ES6) { transformers.push(transformES6); @@ -339,4 +341,4 @@ namespace ts { return statements; } } -} \ No newline at end of file +} diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index f6e8074cb0..40b9e7f64e 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -240,11 +240,14 @@ namespace ts { // ES6 export and default modifiers are elided when inside a namespace. return currentNamespace ? undefined : node; + case SyntaxKind.AsyncKeyword: + // Async keyword is not elided for target ES8 + return languageVersion < ScriptTarget.ES8 ? undefined : node; + case SyntaxKind.PublicKeyword: case SyntaxKind.PrivateKeyword: case SyntaxKind.ProtectedKeyword: case SyntaxKind.AbstractKeyword: - case SyntaxKind.AsyncKeyword: case SyntaxKind.ConstKeyword: case SyntaxKind.DeclareKeyword: case SyntaxKind.ReadonlyKeyword: @@ -2223,6 +2226,14 @@ namespace ts { /*location*/ node ); + // Add ES8 async function expression modifier + // Not sure this is the right place? Might be better to move this + // into createFunctionExpression itself. + if ((languageVersion >= ScriptTarget.ES8) && isAsyncFunctionLike(node)) { + const funcModifiers = visitNodes(node.modifiers, visitor, isModifier); + func.modifiers = createNodeArray(funcModifiers); + } + setOriginalNode(func, node); return func; @@ -2235,7 +2246,7 @@ namespace ts { */ function visitArrowFunction(node: ArrowFunction) { const func = createArrowFunction( - /*modifiers*/ undefined, + visitNodes(node.modifiers, visitor, isModifier), /*typeParameters*/ undefined, visitNodes(node.parameters, visitor, isParameter), /*type*/ undefined, @@ -2250,7 +2261,7 @@ namespace ts { } function transformFunctionBody(node: MethodDeclaration | AccessorDeclaration | FunctionDeclaration | FunctionExpression): FunctionBody { - if (isAsyncFunctionLike(node)) { + if (isAsyncFunctionLike(node) && languageVersion < ScriptTarget.ES8) { return transformAsyncFunctionBody(node); } @@ -2270,7 +2281,7 @@ namespace ts { } function transformConciseBody(node: ArrowFunction): ConciseBody { - if (isAsyncFunctionLike(node)) { + if (isAsyncFunctionLike(node) && languageVersion < ScriptTarget.ES8) { return transformAsyncFunctionBody(node); } @@ -2453,14 +2464,28 @@ namespace ts { * @param node The await expression node. */ function visitAwaitExpression(node: AwaitExpression): Expression { + const targetAtLeastES8 = languageVersion >= ScriptTarget.ES8; return setOriginalNode( - createYield( + targetAtLeastES8 ? createAwaitExpression() : createYieldExpression(), + node + ); + + function createAwaitExpression() { + const awaitExpression = createAwait( + visitNode(node.expression, visitor, isExpression), + /*location*/ node + ); + return awaitExpression; + } + + function createYieldExpression() { + const yieldExpression = createYield( /*asteriskToken*/ undefined, visitNode(node.expression, visitor, isExpression), /*location*/ node - ), - node - ); + ); + return yieldExpression; + } } /** diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 4a4a25fd62..5b193beb15 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2831,8 +2831,10 @@ namespace ts { ES3 = 0, ES5 = 1, ES6 = 2, + ES8 = 3, ES2015 = ES6, - Latest = ES6, + ES2017 = ES8, + Latest = ES8, } export const enum LanguageVariant { From d16e846ab42e1da1558b8bbc6a28bb76ddae207f Mon Sep 17 00:00:00 2001 From: Andrej Baran Date: Thu, 6 Oct 2016 00:41:22 +0200 Subject: [PATCH 05/80] ES8/ES2017 target tests --- src/harness/unittests/commandLineParsing.ts | 2 +- .../convertCompilerOptionsFromJson.ts | 2 +- tests/baselines/reference/es8-async.js | 87 +++++++++++++ tests/baselines/reference/es8-async.symbols | 79 ++++++++++++ tests/baselines/reference/es8-async.types | 121 ++++++++++++++++++ tests/cases/compiler/es8-async.ts | 49 +++++++ 6 files changed, 338 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/es8-async.js create mode 100644 tests/baselines/reference/es8-async.symbols create mode 100644 tests/baselines/reference/es8-async.types create mode 100644 tests/cases/compiler/es8-async.ts diff --git a/src/harness/unittests/commandLineParsing.ts b/src/harness/unittests/commandLineParsing.ts index 028786eef2..42fc242f08 100644 --- a/src/harness/unittests/commandLineParsing.ts +++ b/src/harness/unittests/commandLineParsing.ts @@ -165,7 +165,7 @@ namespace ts { start: undefined, length: undefined, }, { - messageText: "Argument for '--target' option must be: 'es3', 'es5', 'es6', 'es2015'", + messageText: "Argument for '--target' option must be: 'es3', 'es5', 'es6', 'es8', 'es2015', 'es2017'", category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, diff --git a/src/harness/unittests/convertCompilerOptionsFromJson.ts b/src/harness/unittests/convertCompilerOptionsFromJson.ts index ba25409a9b..db3d6cfc10 100644 --- a/src/harness/unittests/convertCompilerOptionsFromJson.ts +++ b/src/harness/unittests/convertCompilerOptionsFromJson.ts @@ -176,7 +176,7 @@ namespace ts { file: undefined, start: 0, length: 0, - messageText: "Argument for '--target' option must be: 'es3', 'es5', 'es6', 'es2015'", + messageText: "Argument for '--target' option must be: 'es3', 'es5', 'es6', 'es8', 'es2015', 'es2017'", code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] diff --git a/tests/baselines/reference/es8-async.js b/tests/baselines/reference/es8-async.js new file mode 100644 index 0000000000..3338b1f88a --- /dev/null +++ b/tests/baselines/reference/es8-async.js @@ -0,0 +1,87 @@ +//// [es8-async.ts] + +async (): Promise => { + await 0; +} + +async function asyncFunc() { + await 0; +} + +const asycnArrowFunc = async (): Promise => { + await 0; +} + +async function asyncIIFE() { + await 0; + + await (async function(): Promise { + await 1; + })(); + + await (async function asyncNamedFunc(): Promise { + await 1; + })(); + + await (async (): Promise => { + await 1; + })(); +} + +class AsyncClass { + asyncPropFunc = async function(): Promise { + await 2; + } + + asyncPropNamedFunc = async function namedFunc(): Promise { + await 2; + } + + asyncPropArrowFunc = async (): Promise => { + await 2; + } + + async asyncMethod(): Promise { + await 2; + } +} + + +//// [es8-async.js] +async () => { + await 0; +}; +async function asyncFunc() { + await 0; +} +const asycnArrowFunc = async () => { + await 0; +}; +async function asyncIIFE() { + await 0; + await (async function () { + await 1; + })(); + await (async function asyncNamedFunc() { + await 1; + })(); + await (async () => { + await 1; + })(); +} +class AsyncClass { + constructor() { + this.asyncPropFunc = async function () { + await 2; + }; + this.asyncPropNamedFunc = async function namedFunc() { + await 2; + }; + this.asyncPropArrowFunc = async () => { + await 2; + }; + } + async asyncMethod() { + await 2; + } +} diff --git a/tests/baselines/reference/es8-async.symbols b/tests/baselines/reference/es8-async.symbols new file mode 100644 index 0000000000..25a77351ae --- /dev/null +++ b/tests/baselines/reference/es8-async.symbols @@ -0,0 +1,79 @@ +=== tests/cases/compiler/es8-async.ts === + +async (): Promise => { +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + + await 0; +} + +async function asyncFunc() { +>asyncFunc : Symbol(asyncFunc, Decl(es8-async.ts, 3, 1)) + + await 0; +} + +const asycnArrowFunc = async (): Promise => { +>asycnArrowFunc : Symbol(asycnArrowFunc, Decl(es8-async.ts, 9, 5)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + + await 0; +} + +async function asyncIIFE() { +>asyncIIFE : Symbol(asyncIIFE, Decl(es8-async.ts, 11, 1)) + + await 0; + + await (async function(): Promise { +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + + await 1; + })(); + + await (async function asyncNamedFunc(): Promise { +>asyncNamedFunc : Symbol(asyncNamedFunc, Decl(es8-async.ts, 20, 11)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + + await 1; + })(); + + await (async (): Promise => { +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + + await 1; + })(); +} + +class AsyncClass { +>AsyncClass : Symbol(AsyncClass, Decl(es8-async.ts, 27, 1)) + + asyncPropFunc = async function(): Promise { +>asyncPropFunc : Symbol(AsyncClass.asyncPropFunc, Decl(es8-async.ts, 29, 18)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + + await 2; + } + + asyncPropNamedFunc = async function namedFunc(): Promise { +>asyncPropNamedFunc : Symbol(AsyncClass.asyncPropNamedFunc, Decl(es8-async.ts, 32, 5)) +>namedFunc : Symbol(namedFunc, Decl(es8-async.ts, 34, 24)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + + await 2; + } + + asyncPropArrowFunc = async (): Promise => { +>asyncPropArrowFunc : Symbol(AsyncClass.asyncPropArrowFunc, Decl(es8-async.ts, 36, 5)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + + await 2; + } + + async asyncMethod(): Promise { +>asyncMethod : Symbol(AsyncClass.asyncMethod, Decl(es8-async.ts, 40, 5)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + + await 2; + } +} + diff --git a/tests/baselines/reference/es8-async.types b/tests/baselines/reference/es8-async.types new file mode 100644 index 0000000000..da0ca06377 --- /dev/null +++ b/tests/baselines/reference/es8-async.types @@ -0,0 +1,121 @@ +=== tests/cases/compiler/es8-async.ts === + +async (): Promise => { +>async (): Promise => { await 0;} : () => Promise +>Promise : Promise + + await 0; +>await 0 : 0 +>0 : 0 +} + +async function asyncFunc() { +>asyncFunc : () => Promise + + await 0; +>await 0 : 0 +>0 : 0 +} + +const asycnArrowFunc = async (): Promise => { +>asycnArrowFunc : () => Promise +>async (): Promise => { await 0;} : () => Promise +>Promise : Promise + + await 0; +>await 0 : 0 +>0 : 0 +} + +async function asyncIIFE() { +>asyncIIFE : () => Promise + + await 0; +>await 0 : 0 +>0 : 0 + + await (async function(): Promise { +>await (async function(): Promise { await 1; })() : void +>(async function(): Promise { await 1; })() : Promise +>(async function(): Promise { await 1; }) : () => Promise +>async function(): Promise { await 1; } : () => Promise +>Promise : Promise + + await 1; +>await 1 : 1 +>1 : 1 + + })(); + + await (async function asyncNamedFunc(): Promise { +>await (async function asyncNamedFunc(): Promise { await 1; })() : void +>(async function asyncNamedFunc(): Promise { await 1; })() : Promise +>(async function asyncNamedFunc(): Promise { await 1; }) : () => Promise +>async function asyncNamedFunc(): Promise { await 1; } : () => Promise +>asyncNamedFunc : () => Promise +>Promise : Promise + + await 1; +>await 1 : 1 +>1 : 1 + + })(); + + await (async (): Promise => { +>await (async (): Promise => { await 1; })() : void +>(async (): Promise => { await 1; })() : Promise +>(async (): Promise => { await 1; }) : () => Promise +>async (): Promise => { await 1; } : () => Promise +>Promise : Promise + + await 1; +>await 1 : 1 +>1 : 1 + + })(); +} + +class AsyncClass { +>AsyncClass : AsyncClass + + asyncPropFunc = async function(): Promise { +>asyncPropFunc : () => Promise +>async function(): Promise { await 2; } : () => Promise +>Promise : Promise + + await 2; +>await 2 : 2 +>2 : 2 + } + + asyncPropNamedFunc = async function namedFunc(): Promise { +>asyncPropNamedFunc : () => Promise +>async function namedFunc(): Promise { await 2; } : () => Promise +>namedFunc : () => Promise +>Promise : Promise + + await 2; +>await 2 : 2 +>2 : 2 + } + + asyncPropArrowFunc = async (): Promise => { +>asyncPropArrowFunc : () => Promise +>async (): Promise => { await 2; } : () => Promise +>Promise : Promise + + await 2; +>await 2 : 2 +>2 : 2 + } + + async asyncMethod(): Promise { +>asyncMethod : () => Promise +>Promise : Promise + + await 2; +>await 2 : 2 +>2 : 2 + } +} + diff --git a/tests/cases/compiler/es8-async.ts b/tests/cases/compiler/es8-async.ts new file mode 100644 index 0000000000..0ceb6e397e --- /dev/null +++ b/tests/cases/compiler/es8-async.ts @@ -0,0 +1,49 @@ +// @target: es8 +// @lib: es2017 +// @noEmitHelpers: true + +async (): Promise => { + await 0; +} + +async function asyncFunc() { + await 0; +} + +const asycnArrowFunc = async (): Promise => { + await 0; +} + +async function asyncIIFE() { + await 0; + + await (async function(): Promise { + await 1; + })(); + + await (async function asyncNamedFunc(): Promise { + await 1; + })(); + + await (async (): Promise => { + await 1; + })(); +} + +class AsyncClass { + asyncPropFunc = async function(): Promise { + await 2; + } + + asyncPropNamedFunc = async function namedFunc(): Promise { + await 2; + } + + asyncPropArrowFunc = async (): Promise => { + await 2; + } + + async asyncMethod(): Promise { + await 2; + } +} From 9ca2569363809e3bd7aaf8bb817ec5a7020d231b Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 6 Oct 2016 11:04:40 -0700 Subject: [PATCH 06/80] Use control flow analysis for variables initialized with [] --- src/compiler/binder.ts | 21 +++ src/compiler/checker.ts | 218 +++++++++++++++++++++------ src/compiler/diagnosticMessages.json | 2 +- src/compiler/types.ts | 14 +- 4 files changed, 210 insertions(+), 45 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 49434e80ab..624ea269d8 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -760,6 +760,15 @@ namespace ts { }; } + function createFlowArrayMutation(antecedent: FlowNode, node: Expression): FlowNode { + setFlowNodeReferenced(antecedent); + return { + flags: FlowFlags.ArrayMutation, + antecedent, + node + }; + } + function finishFlowLabel(flow: FlowLabel): FlowNode { const antecedents = flow.antecedents; if (!antecedents) { @@ -1136,6 +1145,12 @@ namespace ts { forEachChild(node, bind); if (operator === SyntaxKind.EqualsToken && !isAssignmentTarget(node)) { bindAssignmentTargetFlow(node.left); + if (node.left.kind === SyntaxKind.ElementAccessExpression) { + const elementAccess = node.left; + if (isNarrowableReference(elementAccess.expression)) { + currentFlow = createFlowArrayMutation(currentFlow, elementAccess.expression); + } + } } } } @@ -1196,6 +1211,12 @@ namespace ts { else { forEachChild(node, bind); } + if (node.expression.kind === SyntaxKind.PropertyAccessExpression) { + const propertyAccess = node.expression; + if (isNarrowableReference(propertyAccess.expression) && propertyAccess.name.text === "push") { + currentFlow = createFlowArrayMutation(currentFlow, propertyAccess.expression); + } + } } function getContainerFlags(node: Node): ContainerFlags { diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 887a406bb8..eff5296754 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -114,6 +114,7 @@ namespace ts { const intersectionTypes = createMap(); const stringLiteralTypes = createMap(); const numericLiteralTypes = createMap(); + const evolvingArrayTypes: AnonymousType[] = []; const unknownSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient, "unknown"); const resolvingSymbol = createSymbol(SymbolFlags.Transient, "__resolving__"); @@ -175,6 +176,7 @@ namespace ts { let globalBooleanType: ObjectType; let globalRegExpType: ObjectType; let anyArrayType: Type; + let autoArrayType: Type; let anyReadonlyArrayType: Type; // The library files are only loaded when the feature is used. @@ -3051,9 +3053,14 @@ namespace ts { return undefined; } - function isAutoVariableInitializer(initializer: Expression) { - const expr = initializer && skipParentheses(initializer); - return !expr || expr.kind === SyntaxKind.NullKeyword || expr.kind === SyntaxKind.Identifier && getResolvedSymbol(expr) === undefinedSymbol; + function isNullOrUndefined(node: Expression) { + const expr = skipParentheses(node); + return expr.kind === SyntaxKind.NullKeyword || expr.kind === SyntaxKind.Identifier && getResolvedSymbol(expr) === undefinedSymbol; + } + + function isEmptyArrayLiteral(node: Expression) { + const expr = skipParentheses(node); + return expr.kind === SyntaxKind.ArrayLiteralExpression && (expr).elements.length === 0; } function addOptionality(type: Type, optional: boolean): Type { @@ -3094,12 +3101,18 @@ namespace ts { return addOptionality(getTypeFromTypeNode(declaration.type), /*optional*/ declaration.questionToken && includeOptionality); } - // Use control flow type inference for non-ambient, non-exported var or let variables with no initializer - // or a 'null' or 'undefined' initializer. if (declaration.kind === SyntaxKind.VariableDeclaration && !isBindingPattern(declaration.name) && - !(getCombinedNodeFlags(declaration) & NodeFlags.Const) && !(getCombinedModifierFlags(declaration) & ModifierFlags.Export) && - !isInAmbientContext(declaration) && isAutoVariableInitializer(declaration.initializer)) { - return autoType; + !(getCombinedModifierFlags(declaration) & ModifierFlags.Export) && !isInAmbientContext(declaration)) { + // Use control flow tracked 'any' type for non-ambient, non-exported var or let variables with no + // initializer or a 'null' or 'undefined' initializer. + if (!(getCombinedNodeFlags(declaration) & NodeFlags.Const) && (!declaration.initializer || isNullOrUndefined(declaration.initializer))) { + return autoType; + } + // Use control flow tracked 'any[]' type for non-ambient, non-exported variables with an empty array + // literal initializer. + if (declaration.initializer && isEmptyArrayLiteral(declaration.initializer)) { + return autoArrayType; + } } if (declaration.kind === SyntaxKind.Parameter) { @@ -8363,6 +8376,11 @@ namespace ts { getAssignedType(node); } + function isEmptyArrayAssignment(node: VariableDeclaration | BindingElement | Expression) { + return node.kind === SyntaxKind.VariableDeclaration && (node).initializer && isEmptyArrayLiteral((node).initializer) || + node.kind !== SyntaxKind.BindingElement && node.parent.kind === SyntaxKind.BinaryExpression && isEmptyArrayLiteral((node.parent).right); + } + function getReferenceCandidate(node: Expression): Expression { switch (node.kind) { case SyntaxKind.ParenthesizedExpression: @@ -8441,21 +8459,94 @@ namespace ts { return incomplete ? { flags: 0, type } : type; } + // An evolving array type tracks the element types that have so far been seen in an + // 'x.push(value)' or 'x[n] = value' operation along the control flow graph. Evolving + // array types are ultimately converted into manifest array types (using getFinalArrayType) + // and never escape the getFlowTypeOfReference function. + function createEvolvingArrayType(elementType: Type): AnonymousType { + const result = createObjectType(TypeFlags.Anonymous); + result.elementType = elementType; + return result; + } + + function getEvolvingArrayType(elementType: Type): AnonymousType { + return evolvingArrayTypes[elementType.id] || (evolvingArrayTypes[elementType.id] = createEvolvingArrayType(elementType)); + } + + // When adding evolving array element types we do not perform subtype reduction. Instead, + // we defer subtype reduction until the evolving array type is finalized into a manifest + // array type. + function addEvolvingArrayElementType(evolvingArrayType: AnonymousType, node: Expression): AnonymousType { + const elementType = getBaseTypeOfLiteralType(checkExpression(node)); + return isTypeSubsetOf(elementType, evolvingArrayType.elementType) ? evolvingArrayType : getEvolvingArrayType(getUnionType([evolvingArrayType.elementType, elementType])); + } + + function isEvolvingArrayType(type: Type) { + return type.flags & TypeFlags.Anonymous && !!(type).elementType; + } + + // We perform subtype reduction upon obtaining the final array type from an evolving array type. + function getFinalArrayType(evolvingArrayType: AnonymousType): Type { + return evolvingArrayType.finalArrayType || (evolvingArrayType.finalArrayType = createArrayType(getUnionType([evolvingArrayType.elementType], /*subtypeReduction*/ true))); + } + + function finalizeEvolvingArrayType(type: Type): Type { + return isEvolvingArrayType(type) ? getFinalArrayType(type) : type; + } + + function getElementTypeOfEvolvingArrayType(evolvingArrayType: AnonymousType) { + return evolvingArrayType.elementType; + } + + // At flow control branch or loop junctions, if the type along every antecedent code path + // is an evolving array type, we construct a combined evolving array type. Otherwise we + // finalize all evolving array types. + function getUnionOrEvolvingArrayType(types: Type[], subtypeReduction: boolean) { + return types.length && every(types, isEvolvingArrayType) ? + getEvolvingArrayType(getUnionType(map(types, getElementTypeOfEvolvingArrayType))) : + getUnionType(map(types, finalizeEvolvingArrayType), subtypeReduction); + } + + // Return true if the given node is 'x' in an 'x.push(value)' operation. + function isPushCallTarget(node: Node) { + return node.parent.kind === SyntaxKind.PropertyAccessExpression && + (node.parent).name.text === "push" && + node.parent.parent.kind === SyntaxKind.CallExpression; + } + + // Return true if the given node is 'x' in an 'x[n] = value' operation, where 'n' is an + // expression of type any, undefined, or a number-like type. + function isElementAssignmentTarget(node: Node) { + const parent = node.parent; + return parent.kind === SyntaxKind.ElementAccessExpression && + (parent).expression === node && + parent.parent.kind === SyntaxKind.BinaryExpression && + (parent.parent).operatorToken.kind === SyntaxKind.EqualsToken && + (parent.parent).left === parent && + !isAssignmentTarget(parent.parent) && + isTypeAnyOrAllConstituentTypesHaveKind(checkExpression((parent).argumentExpression), TypeFlags.NumberLike | TypeFlags.Undefined); + } + function getFlowTypeOfReference(reference: Node, declaredType: Type, assumeInitialized: boolean, flowContainer: Node) { let key: string; if (!reference.flowNode || assumeInitialized && !(declaredType.flags & TypeFlags.Narrowable)) { return declaredType; } const initialType = assumeInitialized ? declaredType : - declaredType === autoType ? undefinedType : + declaredType === autoType || declaredType === autoArrayType ? undefinedType : includeFalsyTypes(declaredType, TypeFlags.Undefined); const visitedFlowStart = visitedFlowCount; - const result = getTypeFromFlowType(getTypeAtFlowNode(reference.flowNode)); + const evolvedType = getTypeFromFlowType(getTypeAtFlowNode(reference.flowNode)); visitedFlowCount = visitedFlowStart; - if (reference.parent.kind === SyntaxKind.NonNullExpression && getTypeWithFacts(result, TypeFacts.NEUndefinedOrNull).flags & TypeFlags.Never) { + // When the reference is 'x' in an 'x.push(value)' or 'x[n] = value' operation, we give type + // 'any[]' to 'x' instead of using the type determed by control flow analysis such that new + // element types are not considered errors. + const isEvolvingArrayInferenceTarget = isEvolvingArrayType(evolvedType) && (isPushCallTarget(reference) || isElementAssignmentTarget(reference)); + const resultType = isEvolvingArrayInferenceTarget ? anyArrayType : finalizeEvolvingArrayType(evolvedType); + if (reference.parent.kind === SyntaxKind.NonNullExpression && getTypeWithFacts(resultType, TypeFacts.NEUndefinedOrNull).flags & TypeFlags.Never) { return declaredType; } - return result; + return resultType; function getTypeAtFlowNode(flow: FlowNode): FlowType { while (true) { @@ -8492,6 +8583,13 @@ namespace ts { getTypeAtFlowBranchLabel(flow) : getTypeAtFlowLoopLabel(flow); } + else if (flow.flags & FlowFlags.ArrayMutation) { + type = getTypeAtFlowArrayMutation(flow); + if (!type) { + flow = (flow).antecedent; + continue; + } + } else if (flow.flags & FlowFlags.Start) { // Check if we should continue with the control flow of the containing function. const container = (flow).container; @@ -8504,8 +8602,8 @@ namespace ts { } else { // Unreachable code errors are reported in the binding phase. Here we - // simply return the declared type to reduce follow-on errors. - type = declaredType; + // simply return the non-auto declared type to reduce follow-on errors. + type = convertAutoToAny(declaredType); } if (flow.flags & FlowFlags.Shared) { // Record visited node and the associated type in the cache. @@ -8526,9 +8624,17 @@ namespace ts { const flowType = getTypeAtFlowNode(flow.antecedent); return createFlowType(getBaseTypeOfLiteralType(getTypeFromFlowType(flowType)), isIncomplete(flowType)); } - return declaredType === autoType ? getBaseTypeOfLiteralType(getInitialOrAssignedType(node)) : - declaredType.flags & TypeFlags.Union ? getAssignmentReducedType(declaredType, getInitialOrAssignedType(node)) : - declaredType; + if (declaredType === autoType || declaredType === autoArrayType) { + if (isEmptyArrayAssignment(node)) { + return getEvolvingArrayType(neverType); + } + const assignedType = getBaseTypeOfLiteralType(getInitialOrAssignedType(node)); + return isTypeAssignableTo(assignedType, declaredType) ? assignedType : anyArrayType; + } + if (declaredType.flags & TypeFlags.Union) { + return getAssignmentReducedType(declaredType, getInitialOrAssignedType(node)); + } + return declaredType; } // We didn't have a direct match. However, if the reference is a dotted name, this // may be an assignment to a left hand part of the reference. For example, for a @@ -8541,24 +8647,51 @@ namespace ts { return undefined; } + function getTypeAtFlowArrayMutation(flow: FlowArrayMutation): FlowType { + const node = flow.node; + if (isMatchingReference(reference, node)) { + const flowType = getTypeAtFlowNode(flow.antecedent); + const type = getTypeFromFlowType(flowType); + if (isEvolvingArrayType(type)) { + const parent = node.parent; + let evolvedType = type; + if (parent.kind === SyntaxKind.PropertyAccessExpression) { + for (const arg of (parent.parent).arguments) { + evolvedType = addEvolvingArrayElementType(evolvedType, arg); + } + } + else if (isTypeAnyOrAllConstituentTypesHaveKind(checkExpression((parent).argumentExpression), TypeFlags.NumberLike)) { + evolvedType = addEvolvingArrayElementType(evolvedType, (parent.parent).right); + } + return evolvedType === type ? flowType : createFlowType(evolvedType, isIncomplete(flowType)); + } + return flowType; + } + return undefined; + } + function getTypeAtFlowCondition(flow: FlowCondition): FlowType { const flowType = getTypeAtFlowNode(flow.antecedent); - let type = getTypeFromFlowType(flowType); - if (!(type.flags & TypeFlags.Never)) { - // If we have an antecedent type (meaning we're reachable in some way), we first - // attempt to narrow the antecedent type. If that produces the never type, and if - // the antecedent type is incomplete (i.e. a transient type in a loop), then we - // take the type guard as an indication that control *could* reach here once we - // have the complete type. We proceed by switching to the silent never type which - // doesn't report errors when operators are applied to it. Note that this is the - // *only* place a silent never type is ever generated. - const assumeTrue = (flow.flags & FlowFlags.TrueCondition) !== 0; - type = narrowType(type, flow.expression, assumeTrue); - if (type.flags & TypeFlags.Never && isIncomplete(flowType)) { - type = silentNeverType; - } + const type = getTypeFromFlowType(flowType); + if (type.flags & TypeFlags.Never) { + return flowType; } - return createFlowType(type, isIncomplete(flowType)); + // If we have an antecedent type (meaning we're reachable in some way), we first + // attempt to narrow the antecedent type. If that produces the never type, and if + // the antecedent type is incomplete (i.e. a transient type in a loop), then we + // take the type guard as an indication that control *could* reach here once we + // have the complete type. We proceed by switching to the silent never type which + // doesn't report errors when operators are applied to it. Note that this is the + // *only* place a silent never type is ever generated. + const assumeTrue = (flow.flags & FlowFlags.TrueCondition) !== 0; + const nonEvolvingType = finalizeEvolvingArrayType(type); + const narrowedType = narrowType(nonEvolvingType, flow.expression, assumeTrue); + if (narrowedType === nonEvolvingType) { + return flowType; + } + const incomplete = isIncomplete(flowType); + const resultType = incomplete && narrowedType.flags & TypeFlags.Never ? silentNeverType : narrowedType; + return createFlowType(resultType, incomplete); } function getTypeAtSwitchClause(flow: FlowSwitchClause): FlowType { @@ -8601,7 +8734,7 @@ namespace ts { seenIncomplete = true; } } - return createFlowType(getUnionType(antecedentTypes, subtypeReduction), seenIncomplete); + return createFlowType(getUnionOrEvolvingArrayType(antecedentTypes, subtypeReduction), seenIncomplete); } function getTypeAtFlowLoopLabel(flow: FlowLabel): FlowType { @@ -8621,7 +8754,7 @@ namespace ts { // junction is always the non-looping control flow path that leads to the top. for (let i = flowLoopStart; i < flowLoopCount; i++) { if (flowLoopNodes[i] === flow && flowLoopKeys[i] === key) { - return createFlowType(getUnionType(flowLoopTypes[i]), /*incomplete*/ true); + return createFlowType(getUnionOrEvolvingArrayType(flowLoopTypes[i], false), /*incomplete*/ true); } } // Add the flow loop junction and reference to the in-process stack and analyze @@ -8664,7 +8797,7 @@ namespace ts { } // The result is incomplete if the first antecedent (the non-looping control flow path) // is incomplete. - const result = getUnionType(antecedentTypes, subtypeReduction); + const result = getUnionOrEvolvingArrayType(antecedentTypes, subtypeReduction); if (isIncomplete(firstAntecedentType)) { return createFlowType(result, /*incomplete*/ true); } @@ -9143,19 +9276,19 @@ namespace ts { // the entire control flow graph from the variable's declaration (i.e. when the flow container and // declaration container are the same). const assumeInitialized = isParameter || isOuterVariable || - type !== autoType && (!strictNullChecks || (type.flags & TypeFlags.Any) !== 0) || + type !== autoType && type !== autoArrayType && (!strictNullChecks || (type.flags & TypeFlags.Any) !== 0) || isInAmbientContext(declaration); const flowType = getFlowTypeOfReference(node, type, assumeInitialized, flowContainer); // A variable is considered uninitialized when it is possible to analyze the entire control flow graph // from declaration to use, and when the variable's declared type doesn't include undefined but the // control flow based type does include undefined. - if (type === autoType) { - if (flowType === autoType) { + if (type === autoType || type === autoArrayType) { + if (flowType === type) { if (compilerOptions.noImplicitAny) { - error(declaration.name, Diagnostics.Variable_0_implicitly_has_type_any_in_some_locations_where_its_type_cannot_be_determined, symbolToString(symbol)); - error(node, Diagnostics.Variable_0_implicitly_has_an_1_type, symbolToString(symbol), typeToString(anyType)); + error(declaration.name, Diagnostics.Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined, symbolToString(symbol), typeToString(type)); + error(node, Diagnostics.Variable_0_implicitly_has_an_1_type, symbolToString(symbol), typeToString(type)); } - return anyType; + return convertAutoToAny(type); } } else if (!assumeInitialized && !(getFalsyFlags(type) & TypeFlags.Undefined) && getFalsyFlags(flowType) & TypeFlags.Undefined) { @@ -15904,7 +16037,7 @@ namespace ts { } function convertAutoToAny(type: Type) { - return type === autoType ? anyType : type; + return type === autoType ? anyType : type === autoArrayType ? anyArrayType : type; } // Check variable, parameter, or property declaration @@ -19307,6 +19440,7 @@ namespace ts { } anyArrayType = createArrayType(anyType); + autoArrayType = createArrayType(autoType); const symbol = getGlobalSymbol("ReadonlyArray", SymbolFlags.Type, /*diagnostic*/ undefined); globalReadonlyArrayType = symbol && getTypeOfGlobalSymbol(symbol, /*arity*/ 1); diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index fe196b2921..7a73b31e1a 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2953,7 +2953,7 @@ "category": "Error", "code": 7033 }, - "Variable '{0}' implicitly has type 'any' in some locations where its type cannot be determined.": { + "Variable '{0}' implicitly has type '{1}' in some locations where its type cannot be determined.": { "category": "Error", "code": 7034 }, diff --git a/src/compiler/types.ts b/src/compiler/types.ts index ab48ae543c..5b34c5bfbf 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1681,8 +1681,9 @@ namespace ts { TrueCondition = 1 << 5, // Condition known to be true FalseCondition = 1 << 6, // Condition known to be false SwitchClause = 1 << 7, // Switch statement clause - Referenced = 1 << 8, // Referenced as antecedent once - Shared = 1 << 9, // Referenced as antecedent more than once + ArrayMutation = 1 << 8, // Potential array mutation + Referenced = 1 << 9, // Referenced as antecedent once + Shared = 1 << 10, // Referenced as antecedent more than once Label = BranchLabel | LoopLabel, Condition = TrueCondition | FalseCondition } @@ -1725,6 +1726,13 @@ namespace ts { antecedent: FlowNode; } + // FlowArrayMutation represents a node potentially mutates an array, i.e. an + // operation of the form 'x.push(value)' or 'x[n] = value'. + export interface FlowArrayMutation extends FlowNode { + node: Expression; + antecedent: FlowNode; + } + export type FlowType = Type | IncompleteType; // Incomplete types occur during control flow analysis of loops. An IncompleteType @@ -2521,6 +2529,8 @@ namespace ts { export interface AnonymousType extends ObjectType { target?: AnonymousType; // Instantiation target mapper?: TypeMapper; // Instantiation mapper + elementType?: Type; // Element expressions of evolving array type + finalArrayType?: Type; // Final array type of evolving array type } /* @internal */ From b5c10553b5ef29da07d66b5ca0a0e3689dc14790 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 6 Oct 2016 11:05:55 -0700 Subject: [PATCH 07/80] Accept new baselines --- .../reference/arrayLiterals2ES5.types | 8 ++--- .../genericTypeParameterEquivalence2.types | 2 +- .../reference/globalThisCapture.types | 4 +-- .../implicitAnyWidenToAny.errors.txt | 5 +-- .../reference/localClassesInLoop.types | 12 +++---- .../reference/localClassesInLoop_ES6.types | 12 +++---- .../strictNullChecksNoWidening.types | 2 +- tests/baselines/reference/typedArrays.types | 36 +++++++++---------- 8 files changed, 39 insertions(+), 42 deletions(-) diff --git a/tests/baselines/reference/arrayLiterals2ES5.types b/tests/baselines/reference/arrayLiterals2ES5.types index c3256db925..4c5f895114 100644 --- a/tests/baselines/reference/arrayLiterals2ES5.types +++ b/tests/baselines/reference/arrayLiterals2ES5.types @@ -193,10 +193,10 @@ var d5 = [...temp3]; >temp3 : any[] var d6 = [...temp4]; ->d6 : any[] ->[...temp4] : any[] ->...temp4 : any ->temp4 : any[] +>d6 : never[] +>[...temp4] : never[] +>...temp4 : never +>temp4 : never[] var d7 = [...[...temp1]]; >d7 : number[] diff --git a/tests/baselines/reference/genericTypeParameterEquivalence2.types b/tests/baselines/reference/genericTypeParameterEquivalence2.types index 6ab297fe32..095ce27c75 100644 --- a/tests/baselines/reference/genericTypeParameterEquivalence2.types +++ b/tests/baselines/reference/genericTypeParameterEquivalence2.types @@ -105,7 +105,7 @@ function filter(f: (a: A) => boolean, ar: A[]): A[] { } ); return ret; ->ret : any[] +>ret : never[] } // length :: [a] -> Num diff --git a/tests/baselines/reference/globalThisCapture.types b/tests/baselines/reference/globalThisCapture.types index 063100ff78..92a20ff930 100644 --- a/tests/baselines/reference/globalThisCapture.types +++ b/tests/baselines/reference/globalThisCapture.types @@ -13,7 +13,7 @@ var parts = []; // Ensure that the generated code is correct parts[0]; ->parts[0] : any ->parts : any[] +>parts[0] : never +>parts : never[] >0 : 0 diff --git a/tests/baselines/reference/implicitAnyWidenToAny.errors.txt b/tests/baselines/reference/implicitAnyWidenToAny.errors.txt index 95739a450a..7a9314d982 100644 --- a/tests/baselines/reference/implicitAnyWidenToAny.errors.txt +++ b/tests/baselines/reference/implicitAnyWidenToAny.errors.txt @@ -1,8 +1,7 @@ tests/cases/compiler/implicitAnyWidenToAny.ts(4,5): error TS7005: Variable 'widenArray' implicitly has an 'any[]' type. -tests/cases/compiler/implicitAnyWidenToAny.ts(5,5): error TS7005: Variable 'emptyArray' implicitly has an 'any[]' type. -==== tests/cases/compiler/implicitAnyWidenToAny.ts (2 errors) ==== +==== tests/cases/compiler/implicitAnyWidenToAny.ts (1 errors) ==== // these should be errors var x = null; // error at "x" var x1 = undefined; // error at "x1" @@ -10,8 +9,6 @@ tests/cases/compiler/implicitAnyWidenToAny.ts(5,5): error TS7005: Variable 'empt ~~~~~~~~~~ !!! error TS7005: Variable 'widenArray' implicitly has an 'any[]' type. var emptyArray = []; // error at "emptyArray" - ~~~~~~~~~~ -!!! error TS7005: Variable 'emptyArray' implicitly has an 'any[]' type. // these should not be error class AnimalObj { diff --git a/tests/baselines/reference/localClassesInLoop.types b/tests/baselines/reference/localClassesInLoop.types index c88bfc0435..8805044589 100644 --- a/tests/baselines/reference/localClassesInLoop.types +++ b/tests/baselines/reference/localClassesInLoop.types @@ -35,12 +35,12 @@ use(data[0]() === data[1]()); >use(data[0]() === data[1]()) : any >use : (a: any) => any >data[0]() === data[1]() : boolean ->data[0]() : any ->data[0] : any ->data : any[] +>data[0]() : typeof C +>data[0] : () => typeof C +>data : (() => typeof C)[] >0 : 0 ->data[1]() : any ->data[1] : any ->data : any[] +>data[1]() : typeof C +>data[1] : () => typeof C +>data : (() => typeof C)[] >1 : 1 diff --git a/tests/baselines/reference/localClassesInLoop_ES6.types b/tests/baselines/reference/localClassesInLoop_ES6.types index 9d487f6c60..390f4b8b1d 100644 --- a/tests/baselines/reference/localClassesInLoop_ES6.types +++ b/tests/baselines/reference/localClassesInLoop_ES6.types @@ -36,12 +36,12 @@ use(data[0]() === data[1]()); >use(data[0]() === data[1]()) : any >use : (a: any) => any >data[0]() === data[1]() : boolean ->data[0]() : any ->data[0] : any ->data : any[] +>data[0]() : typeof C +>data[0] : () => typeof C +>data : (() => typeof C)[] >0 : 0 ->data[1]() : any ->data[1] : any ->data : any[] +>data[1]() : typeof C +>data[1] : () => typeof C +>data : (() => typeof C)[] >1 : 1 diff --git a/tests/baselines/reference/strictNullChecksNoWidening.types b/tests/baselines/reference/strictNullChecksNoWidening.types index 375977ae37..e24797850e 100644 --- a/tests/baselines/reference/strictNullChecksNoWidening.types +++ b/tests/baselines/reference/strictNullChecksNoWidening.types @@ -14,7 +14,7 @@ var a3 = void 0; >0 : 0 var b1 = []; ->b1 : never[] +>b1 : any[] >[] : never[] var b2 = [,]; diff --git a/tests/baselines/reference/typedArrays.types b/tests/baselines/reference/typedArrays.types index 444d6a74e4..cd2103f646 100644 --- a/tests/baselines/reference/typedArrays.types +++ b/tests/baselines/reference/typedArrays.types @@ -1,7 +1,7 @@ === tests/cases/compiler/typedArrays.ts === function CreateTypedArrayTypes() { ->CreateTypedArrayTypes : () => any[] +>CreateTypedArrayTypes : () => (Int8ArrayConstructor | Uint8ArrayConstructor | Int16ArrayConstructor | Uint16ArrayConstructor | Int32ArrayConstructor | Uint32ArrayConstructor | Float32ArrayConstructor | Float64ArrayConstructor | Uint8ClampedArrayConstructor)[] var typedArrays = []; >typedArrays : any[] @@ -71,11 +71,11 @@ function CreateTypedArrayTypes() { >Uint8ClampedArray : Uint8ClampedArrayConstructor return typedArrays; ->typedArrays : any[] +>typedArrays : (Int8ArrayConstructor | Uint8ArrayConstructor | Int16ArrayConstructor | Uint16ArrayConstructor | Int32ArrayConstructor | Uint32ArrayConstructor | Float32ArrayConstructor | Float64ArrayConstructor | Uint8ClampedArrayConstructor)[] } function CreateTypedArrayInstancesFromLength(obj: number) { ->CreateTypedArrayInstancesFromLength : (obj: number) => any[] +>CreateTypedArrayInstancesFromLength : (obj: number) => (Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array)[] >obj : number var typedArrays = []; @@ -164,11 +164,11 @@ function CreateTypedArrayInstancesFromLength(obj: number) { >obj : number return typedArrays; ->typedArrays : any[] +>typedArrays : (Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array)[] } function CreateTypedArrayInstancesFromArray(obj: number[]) { ->CreateTypedArrayInstancesFromArray : (obj: number[]) => any[] +>CreateTypedArrayInstancesFromArray : (obj: number[]) => (Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array)[] >obj : number[] var typedArrays = []; @@ -257,11 +257,11 @@ function CreateTypedArrayInstancesFromArray(obj: number[]) { >obj : number[] return typedArrays; ->typedArrays : any[] +>typedArrays : (Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array)[] } function CreateIntegerTypedArraysFromArray2(obj:number[]) { ->CreateIntegerTypedArraysFromArray2 : (obj: number[]) => any[] +>CreateIntegerTypedArraysFromArray2 : (obj: number[]) => (Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array)[] >obj : number[] var typedArrays = []; @@ -368,11 +368,11 @@ function CreateIntegerTypedArraysFromArray2(obj:number[]) { >obj : number[] return typedArrays; ->typedArrays : any[] +>typedArrays : (Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array)[] } function CreateIntegerTypedArraysFromArrayLike(obj:ArrayLike) { ->CreateIntegerTypedArraysFromArrayLike : (obj: ArrayLike) => any[] +>CreateIntegerTypedArraysFromArrayLike : (obj: ArrayLike) => (Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array)[] >obj : ArrayLike >ArrayLike : ArrayLike @@ -480,11 +480,11 @@ function CreateIntegerTypedArraysFromArrayLike(obj:ArrayLike) { >obj : ArrayLike return typedArrays; ->typedArrays : any[] +>typedArrays : (Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array)[] } function CreateTypedArraysOf(obj) { ->CreateTypedArraysOf : (obj: any) => any[] +>CreateTypedArraysOf : (obj: any) => (Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array)[] >obj : any var typedArrays = []; @@ -600,11 +600,11 @@ function CreateTypedArraysOf(obj) { >obj : any return typedArrays; ->typedArrays : any[] +>typedArrays : (Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array)[] } function CreateTypedArraysOf2() { ->CreateTypedArraysOf2 : () => any[] +>CreateTypedArraysOf2 : () => (Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array)[] var typedArrays = []; >typedArrays : any[] @@ -737,11 +737,11 @@ function CreateTypedArraysOf2() { >4 : 4 return typedArrays; ->typedArrays : any[] +>typedArrays : (Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array)[] } function CreateTypedArraysFromMapFn(obj:ArrayLike, mapFn: (n:number, v:number)=> number) { ->CreateTypedArraysFromMapFn : (obj: ArrayLike, mapFn: (n: number, v: number) => number) => any[] +>CreateTypedArraysFromMapFn : (obj: ArrayLike, mapFn: (n: number, v: number) => number) => (Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array)[] >obj : ArrayLike >ArrayLike : ArrayLike >mapFn : (n: number, v: number) => number @@ -861,11 +861,11 @@ function CreateTypedArraysFromMapFn(obj:ArrayLike, mapFn: (n:number, v:n >mapFn : (n: number, v: number) => number return typedArrays; ->typedArrays : any[] +>typedArrays : (Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array)[] } function CreateTypedArraysFromThisObj(obj:ArrayLike, mapFn: (n:number, v:number)=> number, thisArg: {}) { ->CreateTypedArraysFromThisObj : (obj: ArrayLike, mapFn: (n: number, v: number) => number, thisArg: {}) => any[] +>CreateTypedArraysFromThisObj : (obj: ArrayLike, mapFn: (n: number, v: number) => number, thisArg: {}) => (Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array)[] >obj : ArrayLike >ArrayLike : ArrayLike >mapFn : (n: number, v: number) => number @@ -995,5 +995,5 @@ function CreateTypedArraysFromThisObj(obj:ArrayLike, mapFn: (n:number, v >thisArg : {} return typedArrays; ->typedArrays : any[] +>typedArrays : (Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array)[] } From 9c4190b1fb31b6317efc15430c2047ca78779ff0 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 6 Oct 2016 13:25:42 -0700 Subject: [PATCH 08/80] Introduce sameMap function --- src/compiler/checker.ts | 26 ++++++++++++++++---------- src/compiler/core.ts | 24 ++++++++++++++++++++++-- 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index eff5296754..414a92ffed 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7404,7 +7404,7 @@ namespace ts { type.flags & TypeFlags.NumberLiteral ? numberType : type.flags & TypeFlags.BooleanLiteral ? booleanType : type.flags & TypeFlags.EnumLiteral ? (type).baseType : - type.flags & TypeFlags.Union && !(type.flags & TypeFlags.Enum) ? getUnionType(map((type).types, getBaseTypeOfLiteralType)) : + type.flags & TypeFlags.Union && !(type.flags & TypeFlags.Enum) ? getUnionType(sameMap((type).types, getBaseTypeOfLiteralType)) : type; } @@ -7413,7 +7413,7 @@ namespace ts { type.flags & TypeFlags.NumberLiteral && type.flags & TypeFlags.FreshLiteral ? numberType : type.flags & TypeFlags.BooleanLiteral ? booleanType : type.flags & TypeFlags.EnumLiteral ? (type).baseType : - type.flags & TypeFlags.Union && !(type.flags & TypeFlags.Enum) ? getUnionType(map((type).types, getWidenedLiteralType)) : + type.flags & TypeFlags.Union && !(type.flags & TypeFlags.Enum) ? getUnionType(sameMap((type).types, getWidenedLiteralType)) : type; } @@ -7552,10 +7552,10 @@ namespace ts { return getWidenedTypeOfObjectLiteral(type); } if (type.flags & TypeFlags.Union) { - return getUnionType(map((type).types, getWidenedConstituentType)); + return getUnionType(sameMap((type).types, getWidenedConstituentType)); } if (isArrayType(type) || isTupleType(type)) { - return createTypeReference((type).target, map((type).typeArguments, getWidenedType)); + return createTypeReference((type).target, sameMap((type).typeArguments, getWidenedType)); } } return type; @@ -7973,7 +7973,7 @@ namespace ts { const widenLiteralTypes = context.inferences[index].topLevel && !hasPrimitiveConstraint(signature.typeParameters[index]) && (context.inferences[index].isFixed || !isTypeParameterAtTopLevel(getReturnTypeOfSignature(signature), signature.typeParameters[index])); - const baseInferences = widenLiteralTypes ? map(inferences, getWidenedLiteralType) : inferences; + const baseInferences = widenLiteralTypes ? sameMap(inferences, getWidenedLiteralType) : inferences; // Infer widened union or supertype, or the unknown type for no common supertype const unionOrSuperType = context.inferUnionTypes ? getUnionType(baseInferences, /*subtypeReduction*/ true) : getCommonSupertype(baseInferences); inferredType = unionOrSuperType ? getWidenedType(unionOrSuperType) : unknownType; @@ -8485,9 +8485,15 @@ namespace ts { return type.flags & TypeFlags.Anonymous && !!(type).elementType; } + function createFinalArrayType(elementType: Type) { + return createArrayType(elementType !== neverType ? + getUnionType([elementType], /*subtypeReduction*/ true) : + strictNullChecks ? neverType : undefinedWideningType); + } + // We perform subtype reduction upon obtaining the final array type from an evolving array type. function getFinalArrayType(evolvingArrayType: AnonymousType): Type { - return evolvingArrayType.finalArrayType || (evolvingArrayType.finalArrayType = createArrayType(getUnionType([evolvingArrayType.elementType], /*subtypeReduction*/ true))); + return evolvingArrayType.finalArrayType || (evolvingArrayType.finalArrayType = createFinalArrayType(evolvingArrayType.elementType)); } function finalizeEvolvingArrayType(type: Type): Type { @@ -8504,7 +8510,7 @@ namespace ts { function getUnionOrEvolvingArrayType(types: Type[], subtypeReduction: boolean) { return types.length && every(types, isEvolvingArrayType) ? getEvolvingArrayType(getUnionType(map(types, getElementTypeOfEvolvingArrayType))) : - getUnionType(map(types, finalizeEvolvingArrayType), subtypeReduction); + getUnionType(sameMap(types, finalizeEvolvingArrayType), subtypeReduction); } // Return true if the given node is 'x' in an 'x.push(value)' operation. @@ -8754,7 +8760,7 @@ namespace ts { // junction is always the non-looping control flow path that leads to the top. for (let i = flowLoopStart; i < flowLoopCount; i++) { if (flowLoopNodes[i] === flow && flowLoopKeys[i] === key) { - return createFlowType(getUnionOrEvolvingArrayType(flowLoopTypes[i], false), /*incomplete*/ true); + return createFlowType(getUnionOrEvolvingArrayType(flowLoopTypes[i], /*subtypeReduction*/ false), /*incomplete*/ true); } } // Add the flow loop junction and reference to the in-process stack and analyze @@ -10728,7 +10734,7 @@ namespace ts { } } - return getUnionType(signatures.map(getReturnTypeOfSignature), /*subtypeReduction*/ true); + return getUnionType(map(signatures, getReturnTypeOfSignature), /*subtypeReduction*/ true); } /// e.g. "props" for React.d.ts, @@ -10778,7 +10784,7 @@ namespace ts { } if (elemType.flags & TypeFlags.Union) { const types = (elemType).types; - return getUnionType(types.map(type => { + return getUnionType(map(types, type => { return getResolvedJsxType(node, type, elemClassType); }), /*subtypeReduction*/ true); } diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 72d05e1cfd..bb3aaf2325 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -257,13 +257,33 @@ namespace ts { if (array) { result = []; for (let i = 0; i < array.length; i++) { - const v = array[i]; - result.push(f(v, i)); + result.push(f(array[i], i)); } } return result; } + // Maps from T to T and avoids allocation of all elements map to themselves + export function sameMap(array: T[], f: (x: T, i: number) => T): T[] { + let result: T[]; + if (array) { + for (let i = 0; i < array.length; i++) { + if (result) { + result.push(f(array[i], i)); + } + else { + const item = array[i]; + const mapped = f(item, i); + if (item !== mapped) { + result = array.slice(0, i); + result.push(mapped); + } + } + } + } + return result || array; + } + /** * Flattens an array containing a mix of array or non-array elements. * From 144f4ffc7c836834947ecb6541225a47aa8e1af8 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 6 Oct 2016 13:33:13 -0700 Subject: [PATCH 09/80] Accept new baselines --- tests/baselines/reference/arrayLiterals2ES5.types | 8 ++++---- .../reference/genericTypeParameterEquivalence2.types | 2 +- tests/baselines/reference/globalThisCapture.types | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/baselines/reference/arrayLiterals2ES5.types b/tests/baselines/reference/arrayLiterals2ES5.types index 4c5f895114..833966a6e4 100644 --- a/tests/baselines/reference/arrayLiterals2ES5.types +++ b/tests/baselines/reference/arrayLiterals2ES5.types @@ -193,10 +193,10 @@ var d5 = [...temp3]; >temp3 : any[] var d6 = [...temp4]; ->d6 : never[] ->[...temp4] : never[] ->...temp4 : never ->temp4 : never[] +>d6 : any[] +>[...temp4] : undefined[] +>...temp4 : undefined +>temp4 : undefined[] var d7 = [...[...temp1]]; >d7 : number[] diff --git a/tests/baselines/reference/genericTypeParameterEquivalence2.types b/tests/baselines/reference/genericTypeParameterEquivalence2.types index 095ce27c75..5125376457 100644 --- a/tests/baselines/reference/genericTypeParameterEquivalence2.types +++ b/tests/baselines/reference/genericTypeParameterEquivalence2.types @@ -105,7 +105,7 @@ function filter(f: (a: A) => boolean, ar: A[]): A[] { } ); return ret; ->ret : never[] +>ret : undefined[] } // length :: [a] -> Num diff --git a/tests/baselines/reference/globalThisCapture.types b/tests/baselines/reference/globalThisCapture.types index 92a20ff930..d17c899d1e 100644 --- a/tests/baselines/reference/globalThisCapture.types +++ b/tests/baselines/reference/globalThisCapture.types @@ -13,7 +13,7 @@ var parts = []; // Ensure that the generated code is correct parts[0]; ->parts[0] : never ->parts : never[] +>parts[0] : undefined +>parts : undefined[] >0 : 0 From a9c2b23df52a2abaffae4ba1470ee87e05aae731 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 6 Oct 2016 13:33:28 -0700 Subject: [PATCH 10/80] Add tests --- .../cases/compiler/controlFlowArrayErrors.ts | 59 ++++++++ tests/cases/compiler/controlFlowArrays.ts | 141 ++++++++++++++++++ 2 files changed, 200 insertions(+) create mode 100644 tests/cases/compiler/controlFlowArrayErrors.ts create mode 100644 tests/cases/compiler/controlFlowArrays.ts diff --git a/tests/cases/compiler/controlFlowArrayErrors.ts b/tests/cases/compiler/controlFlowArrayErrors.ts new file mode 100644 index 0000000000..84da65c41d --- /dev/null +++ b/tests/cases/compiler/controlFlowArrayErrors.ts @@ -0,0 +1,59 @@ +// @noImplicitAny: true + +declare function cond(): boolean; + +function f1() { + let x = []; + let y = x; // Implicit any[] error + x.push(5); + let z = x; +} + +function f2() { + let x; + x = []; + let y = x; // Implicit any[] error + x.push(5); + let z = x; +} + +function f3() { + let x = []; // Implicit any[] error in some locations + x.push(5); + function g() { + x; // Implicit any[] error + } +} + +function f4() { + let x; + x = [5, "hello"]; // Non-evolving array + x.push(true); // Error +} + +function f5() { + let x = [5, "hello"]; // Non-evolving array + x.push(true); // Error +} + +function f6() { + let x; + if (cond()) { + x = []; + x.push(5); + x.push("hello"); + } + else { + x = [true]; // Non-evolving array + } + x; // boolean[] | (string | number)[] + x.push(99); // Error +} + +function f7() { + let x = []; // x has evolving array value + x.push(5); + let y = x; // y has non-evolving array value + x.push("hello"); // Ok + y.push("hello"); // Error +} \ No newline at end of file diff --git a/tests/cases/compiler/controlFlowArrays.ts b/tests/cases/compiler/controlFlowArrays.ts new file mode 100644 index 0000000000..d5eaa9c432 --- /dev/null +++ b/tests/cases/compiler/controlFlowArrays.ts @@ -0,0 +1,141 @@ +// @strictNullChecks: true +// @noImplicitAny: true + +declare function cond(): boolean; + +function f1() { + let x = []; + x[0] = 5; + x[1] = "hello"; + x[2] = true; + return x; // (string | number | boolean)[] +} + +function f2() { + let x = []; + x.push(5); + x.push("hello"); + x.push(true); + return x; // (string | number | boolean)[] +} + +function f3() { + let x; + x = []; + x.push(5, "hello"); + return x; // (string | number)[] +} + +function f4() { + let x = []; + if (cond()) { + x.push(5); + } + else { + x.push("hello"); + } + return x; // (string | number)[] +} + +function f5() { + let x; + if (cond()) { + x = []; + x.push(5); + } + else { + x = []; + x.push("hello"); + } + return x; // (string | number)[] +} + +function f6() { + let x; + if (cond()) { + x = 5; + } + else { + x = []; + x.push("hello"); + } + return x; // number | string[] +} + +function f7() { + let x = null; + if (cond()) { + x = []; + while (cond()) { + x.push("hello"); + } + } + return x; // string[] | null +} + +function f8() { + let x = []; + x.push(5); + if (cond()) return x; // number[] + x.push("hello"); + if (cond()) return x; // (string | number)[] + x.push(true); + return x; // (string | number | boolean)[] +} + +function f9() { + let x = []; + if (cond()) { + x.push(5); + return x; // number[] + } + else { + x.push("hello"); + return x; // string[] + } +} + +function f10() { + let x = []; + if (cond()) { + x.push(true); + x; // boolean[] + } + else { + x.push(5); + x; // number[] + while (cond()) { + x.push("hello"); + } + x; // (string | number)[] + } + x.push(99); + return x; // (string | number | boolean)[] +} + +function f11() { + let x = []; + return x; // never[] +} + +function f12() { + let x; + x = []; + return x; // never[] +} + +function f13() { + var x = []; + x.push(5); + x.push("hello"); + x.push(true); + return x; // (string | number | boolean)[] +} + +function f14() { + const x = []; + x.push(5); + x.push("hello"); + x.push(true); + return x; // (string | number | boolean)[] +} \ No newline at end of file From c0c2271d31a361528deebe88e91539c2635ccbf9 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 6 Oct 2016 13:35:02 -0700 Subject: [PATCH 11/80] Accept new baselines --- .../controlFlowArrayErrors.errors.txt | 85 ++++ .../reference/controlFlowArrayErrors.js | 110 +++++ .../baselines/reference/controlFlowArrays.js | 267 +++++++++++ .../reference/controlFlowArrays.symbols | 350 ++++++++++++++ .../reference/controlFlowArrays.types | 447 ++++++++++++++++++ 5 files changed, 1259 insertions(+) create mode 100644 tests/baselines/reference/controlFlowArrayErrors.errors.txt create mode 100644 tests/baselines/reference/controlFlowArrayErrors.js create mode 100644 tests/baselines/reference/controlFlowArrays.js create mode 100644 tests/baselines/reference/controlFlowArrays.symbols create mode 100644 tests/baselines/reference/controlFlowArrays.types diff --git a/tests/baselines/reference/controlFlowArrayErrors.errors.txt b/tests/baselines/reference/controlFlowArrayErrors.errors.txt new file mode 100644 index 0000000000..7475c27324 --- /dev/null +++ b/tests/baselines/reference/controlFlowArrayErrors.errors.txt @@ -0,0 +1,85 @@ +tests/cases/compiler/controlFlowArrayErrors.ts(6,9): error TS7005: Variable 'y' implicitly has an 'any[]' type. +tests/cases/compiler/controlFlowArrayErrors.ts(14,9): error TS7005: Variable 'y' implicitly has an 'any[]' type. +tests/cases/compiler/controlFlowArrayErrors.ts(20,9): error TS7034: Variable 'x' implicitly has type 'any[]' in some locations where its type cannot be determined. +tests/cases/compiler/controlFlowArrayErrors.ts(23,9): error TS7005: Variable 'x' implicitly has an 'any[]' type. +tests/cases/compiler/controlFlowArrayErrors.ts(30,12): error TS2345: Argument of type 'true' is not assignable to parameter of type 'string | number'. +tests/cases/compiler/controlFlowArrayErrors.ts(35,12): error TS2345: Argument of type 'true' is not assignable to parameter of type 'string | number'. +tests/cases/compiler/controlFlowArrayErrors.ts(49,5): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '((...items: (string | number)[]) => number) | ((...items: boolean[]) => number)' has no compatible call signatures. +tests/cases/compiler/controlFlowArrayErrors.ts(57,12): error TS2345: Argument of type '"hello"' is not assignable to parameter of type 'number'. + + +==== tests/cases/compiler/controlFlowArrayErrors.ts (8 errors) ==== + + declare function cond(): boolean; + + function f1() { + let x = []; + let y = x; // Implicit any[] error + ~ +!!! error TS7005: Variable 'y' implicitly has an 'any[]' type. + x.push(5); + let z = x; + } + + function f2() { + let x; + x = []; + let y = x; // Implicit any[] error + ~ +!!! error TS7005: Variable 'y' implicitly has an 'any[]' type. + x.push(5); + let z = x; + } + + function f3() { + let x = []; // Implicit any[] error in some locations + ~ +!!! error TS7034: Variable 'x' implicitly has type 'any[]' in some locations where its type cannot be determined. + x.push(5); + function g() { + x; // Implicit any[] error + ~ +!!! error TS7005: Variable 'x' implicitly has an 'any[]' type. + } + } + + function f4() { + let x; + x = [5, "hello"]; // Non-evolving array + x.push(true); // Error + ~~~~ +!!! error TS2345: Argument of type 'true' is not assignable to parameter of type 'string | number'. + } + + function f5() { + let x = [5, "hello"]; // Non-evolving array + x.push(true); // Error + ~~~~ +!!! error TS2345: Argument of type 'true' is not assignable to parameter of type 'string | number'. + } + + function f6() { + let x; + if (cond()) { + x = []; + x.push(5); + x.push("hello"); + } + else { + x = [true]; // Non-evolving array + } + x; // boolean[] | (string | number)[] + x.push(99); // Error + ~~~~~~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '((...items: (string | number)[]) => number) | ((...items: boolean[]) => number)' has no compatible call signatures. + } + + function f7() { + let x = []; // x has evolving array value + x.push(5); + let y = x; // y has non-evolving array value + x.push("hello"); // Ok + y.push("hello"); // Error + ~~~~~~~ +!!! error TS2345: Argument of type '"hello"' is not assignable to parameter of type 'number'. + } \ No newline at end of file diff --git a/tests/baselines/reference/controlFlowArrayErrors.js b/tests/baselines/reference/controlFlowArrayErrors.js new file mode 100644 index 0000000000..c158944933 --- /dev/null +++ b/tests/baselines/reference/controlFlowArrayErrors.js @@ -0,0 +1,110 @@ +//// [controlFlowArrayErrors.ts] + +declare function cond(): boolean; + +function f1() { + let x = []; + let y = x; // Implicit any[] error + x.push(5); + let z = x; +} + +function f2() { + let x; + x = []; + let y = x; // Implicit any[] error + x.push(5); + let z = x; +} + +function f3() { + let x = []; // Implicit any[] error in some locations + x.push(5); + function g() { + x; // Implicit any[] error + } +} + +function f4() { + let x; + x = [5, "hello"]; // Non-evolving array + x.push(true); // Error +} + +function f5() { + let x = [5, "hello"]; // Non-evolving array + x.push(true); // Error +} + +function f6() { + let x; + if (cond()) { + x = []; + x.push(5); + x.push("hello"); + } + else { + x = [true]; // Non-evolving array + } + x; // boolean[] | (string | number)[] + x.push(99); // Error +} + +function f7() { + let x = []; // x has evolving array value + x.push(5); + let y = x; // y has non-evolving array value + x.push("hello"); // Ok + y.push("hello"); // Error +} + +//// [controlFlowArrayErrors.js] +function f1() { + var x = []; + var y = x; // Implicit any[] error + x.push(5); + var z = x; +} +function f2() { + var x; + x = []; + var y = x; // Implicit any[] error + x.push(5); + var z = x; +} +function f3() { + var x = []; // Implicit any[] error in some locations + x.push(5); + function g() { + x; // Implicit any[] error + } +} +function f4() { + var x; + x = [5, "hello"]; // Non-evolving array + x.push(true); // Error +} +function f5() { + var x = [5, "hello"]; // Non-evolving array + x.push(true); // Error +} +function f6() { + var x; + if (cond()) { + x = []; + x.push(5); + x.push("hello"); + } + else { + x = [true]; // Non-evolving array + } + x; // boolean[] | (string | number)[] + x.push(99); // Error +} +function f7() { + var x = []; // x has evolving array value + x.push(5); + var y = x; // y has non-evolving array value + x.push("hello"); // Ok + y.push("hello"); // Error +} diff --git a/tests/baselines/reference/controlFlowArrays.js b/tests/baselines/reference/controlFlowArrays.js new file mode 100644 index 0000000000..26885aecd8 --- /dev/null +++ b/tests/baselines/reference/controlFlowArrays.js @@ -0,0 +1,267 @@ +//// [controlFlowArrays.ts] + +declare function cond(): boolean; + +function f1() { + let x = []; + x[0] = 5; + x[1] = "hello"; + x[2] = true; + return x; // (string | number | boolean)[] +} + +function f2() { + let x = []; + x.push(5); + x.push("hello"); + x.push(true); + return x; // (string | number | boolean)[] +} + +function f3() { + let x; + x = []; + x.push(5, "hello"); + return x; // (string | number)[] +} + +function f4() { + let x = []; + if (cond()) { + x.push(5); + } + else { + x.push("hello"); + } + return x; // (string | number)[] +} + +function f5() { + let x; + if (cond()) { + x = []; + x.push(5); + } + else { + x = []; + x.push("hello"); + } + return x; // (string | number)[] +} + +function f6() { + let x; + if (cond()) { + x = 5; + } + else { + x = []; + x.push("hello"); + } + return x; // number | string[] +} + +function f7() { + let x = null; + if (cond()) { + x = []; + while (cond()) { + x.push("hello"); + } + } + return x; // string[] | null +} + +function f8() { + let x = []; + x.push(5); + if (cond()) return x; // number[] + x.push("hello"); + if (cond()) return x; // (string | number)[] + x.push(true); + return x; // (string | number | boolean)[] +} + +function f9() { + let x = []; + if (cond()) { + x.push(5); + return x; // number[] + } + else { + x.push("hello"); + return x; // string[] + } +} + +function f10() { + let x = []; + if (cond()) { + x.push(true); + x; // boolean[] + } + else { + x.push(5); + x; // number[] + while (cond()) { + x.push("hello"); + } + x; // (string | number)[] + } + x.push(99); + return x; // (string | number | boolean)[] +} + +function f11() { + let x = []; + return x; // never[] +} + +function f12() { + let x; + x = []; + return x; // never[] +} + +function f13() { + var x = []; + x.push(5); + x.push("hello"); + x.push(true); + return x; // (string | number | boolean)[] +} + +function f14() { + const x = []; + x.push(5); + x.push("hello"); + x.push(true); + return x; // (string | number | boolean)[] +} + +//// [controlFlowArrays.js] +function f1() { + var x = []; + x[0] = 5; + x[1] = "hello"; + x[2] = true; + return x; // (string | number | boolean)[] +} +function f2() { + var x = []; + x.push(5); + x.push("hello"); + x.push(true); + return x; // (string | number | boolean)[] +} +function f3() { + var x; + x = []; + x.push(5, "hello"); + return x; // (string | number)[] +} +function f4() { + var x = []; + if (cond()) { + x.push(5); + } + else { + x.push("hello"); + } + return x; // (string | number)[] +} +function f5() { + var x; + if (cond()) { + x = []; + x.push(5); + } + else { + x = []; + x.push("hello"); + } + return x; // (string | number)[] +} +function f6() { + var x; + if (cond()) { + x = 5; + } + else { + x = []; + x.push("hello"); + } + return x; // number | string[] +} +function f7() { + var x = null; + if (cond()) { + x = []; + while (cond()) { + x.push("hello"); + } + } + return x; // string[] | null +} +function f8() { + var x = []; + x.push(5); + if (cond()) + return x; // number[] + x.push("hello"); + if (cond()) + return x; // (string | number)[] + x.push(true); + return x; // (string | number | boolean)[] +} +function f9() { + var x = []; + if (cond()) { + x.push(5); + return x; // number[] + } + else { + x.push("hello"); + return x; // string[] + } +} +function f10() { + var x = []; + if (cond()) { + x.push(true); + x; // boolean[] + } + else { + x.push(5); + x; // number[] + while (cond()) { + x.push("hello"); + } + x; // (string | number)[] + } + x.push(99); + return x; // (string | number | boolean)[] +} +function f11() { + var x = []; + return x; // never[] +} +function f12() { + var x; + x = []; + return x; // never[] +} +function f13() { + var x = []; + x.push(5); + x.push("hello"); + x.push(true); + return x; // (string | number | boolean)[] +} +function f14() { + var x = []; + x.push(5); + x.push("hello"); + x.push(true); + return x; // (string | number | boolean)[] +} diff --git a/tests/baselines/reference/controlFlowArrays.symbols b/tests/baselines/reference/controlFlowArrays.symbols new file mode 100644 index 0000000000..5b5ef7f850 --- /dev/null +++ b/tests/baselines/reference/controlFlowArrays.symbols @@ -0,0 +1,350 @@ +=== tests/cases/compiler/controlFlowArrays.ts === + +declare function cond(): boolean; +>cond : Symbol(cond, Decl(controlFlowArrays.ts, 0, 0)) + +function f1() { +>f1 : Symbol(f1, Decl(controlFlowArrays.ts, 1, 33)) + + let x = []; +>x : Symbol(x, Decl(controlFlowArrays.ts, 4, 7)) + + x[0] = 5; +>x : Symbol(x, Decl(controlFlowArrays.ts, 4, 7)) + + x[1] = "hello"; +>x : Symbol(x, Decl(controlFlowArrays.ts, 4, 7)) + + x[2] = true; +>x : Symbol(x, Decl(controlFlowArrays.ts, 4, 7)) + + return x; // (string | number | boolean)[] +>x : Symbol(x, Decl(controlFlowArrays.ts, 4, 7)) +} + +function f2() { +>f2 : Symbol(f2, Decl(controlFlowArrays.ts, 9, 1)) + + let x = []; +>x : Symbol(x, Decl(controlFlowArrays.ts, 12, 7)) + + x.push(5); +>x.push : Symbol(Array.push, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 12, 7)) +>push : Symbol(Array.push, Decl(lib.d.ts, --, --)) + + x.push("hello"); +>x.push : Symbol(Array.push, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 12, 7)) +>push : Symbol(Array.push, Decl(lib.d.ts, --, --)) + + x.push(true); +>x.push : Symbol(Array.push, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 12, 7)) +>push : Symbol(Array.push, Decl(lib.d.ts, --, --)) + + return x; // (string | number | boolean)[] +>x : Symbol(x, Decl(controlFlowArrays.ts, 12, 7)) +} + +function f3() { +>f3 : Symbol(f3, Decl(controlFlowArrays.ts, 17, 1)) + + let x; +>x : Symbol(x, Decl(controlFlowArrays.ts, 20, 7)) + + x = []; +>x : Symbol(x, Decl(controlFlowArrays.ts, 20, 7)) + + x.push(5, "hello"); +>x.push : Symbol(Array.push, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 20, 7)) +>push : Symbol(Array.push, Decl(lib.d.ts, --, --)) + + return x; // (string | number)[] +>x : Symbol(x, Decl(controlFlowArrays.ts, 20, 7)) +} + +function f4() { +>f4 : Symbol(f4, Decl(controlFlowArrays.ts, 24, 1)) + + let x = []; +>x : Symbol(x, Decl(controlFlowArrays.ts, 27, 7)) + + if (cond()) { +>cond : Symbol(cond, Decl(controlFlowArrays.ts, 0, 0)) + + x.push(5); +>x.push : Symbol(Array.push, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 27, 7)) +>push : Symbol(Array.push, Decl(lib.d.ts, --, --)) + } + else { + x.push("hello"); +>x.push : Symbol(Array.push, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 27, 7)) +>push : Symbol(Array.push, Decl(lib.d.ts, --, --)) + } + return x; // (string | number)[] +>x : Symbol(x, Decl(controlFlowArrays.ts, 27, 7)) +} + +function f5() { +>f5 : Symbol(f5, Decl(controlFlowArrays.ts, 35, 1)) + + let x; +>x : Symbol(x, Decl(controlFlowArrays.ts, 38, 7)) + + if (cond()) { +>cond : Symbol(cond, Decl(controlFlowArrays.ts, 0, 0)) + + x = []; +>x : Symbol(x, Decl(controlFlowArrays.ts, 38, 7)) + + x.push(5); +>x.push : Symbol(Array.push, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 38, 7)) +>push : Symbol(Array.push, Decl(lib.d.ts, --, --)) + } + else { + x = []; +>x : Symbol(x, Decl(controlFlowArrays.ts, 38, 7)) + + x.push("hello"); +>x.push : Symbol(Array.push, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 38, 7)) +>push : Symbol(Array.push, Decl(lib.d.ts, --, --)) + } + return x; // (string | number)[] +>x : Symbol(x, Decl(controlFlowArrays.ts, 38, 7)) +} + +function f6() { +>f6 : Symbol(f6, Decl(controlFlowArrays.ts, 48, 1)) + + let x; +>x : Symbol(x, Decl(controlFlowArrays.ts, 51, 7)) + + if (cond()) { +>cond : Symbol(cond, Decl(controlFlowArrays.ts, 0, 0)) + + x = 5; +>x : Symbol(x, Decl(controlFlowArrays.ts, 51, 7)) + } + else { + x = []; +>x : Symbol(x, Decl(controlFlowArrays.ts, 51, 7)) + + x.push("hello"); +>x.push : Symbol(Array.push, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 51, 7)) +>push : Symbol(Array.push, Decl(lib.d.ts, --, --)) + } + return x; // number | string[] +>x : Symbol(x, Decl(controlFlowArrays.ts, 51, 7)) +} + +function f7() { +>f7 : Symbol(f7, Decl(controlFlowArrays.ts, 60, 1)) + + let x = null; +>x : Symbol(x, Decl(controlFlowArrays.ts, 63, 7)) + + if (cond()) { +>cond : Symbol(cond, Decl(controlFlowArrays.ts, 0, 0)) + + x = []; +>x : Symbol(x, Decl(controlFlowArrays.ts, 63, 7)) + + while (cond()) { +>cond : Symbol(cond, Decl(controlFlowArrays.ts, 0, 0)) + + x.push("hello"); +>x.push : Symbol(Array.push, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 63, 7)) +>push : Symbol(Array.push, Decl(lib.d.ts, --, --)) + } + } + return x; // string[] | null +>x : Symbol(x, Decl(controlFlowArrays.ts, 63, 7)) +} + +function f8() { +>f8 : Symbol(f8, Decl(controlFlowArrays.ts, 71, 1)) + + let x = []; +>x : Symbol(x, Decl(controlFlowArrays.ts, 74, 7)) + + x.push(5); +>x.push : Symbol(Array.push, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 74, 7)) +>push : Symbol(Array.push, Decl(lib.d.ts, --, --)) + + if (cond()) return x; // number[] +>cond : Symbol(cond, Decl(controlFlowArrays.ts, 0, 0)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 74, 7)) + + x.push("hello"); +>x.push : Symbol(Array.push, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 74, 7)) +>push : Symbol(Array.push, Decl(lib.d.ts, --, --)) + + if (cond()) return x; // (string | number)[] +>cond : Symbol(cond, Decl(controlFlowArrays.ts, 0, 0)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 74, 7)) + + x.push(true); +>x.push : Symbol(Array.push, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 74, 7)) +>push : Symbol(Array.push, Decl(lib.d.ts, --, --)) + + return x; // (string | number | boolean)[] +>x : Symbol(x, Decl(controlFlowArrays.ts, 74, 7)) +} + +function f9() { +>f9 : Symbol(f9, Decl(controlFlowArrays.ts, 81, 1)) + + let x = []; +>x : Symbol(x, Decl(controlFlowArrays.ts, 84, 7)) + + if (cond()) { +>cond : Symbol(cond, Decl(controlFlowArrays.ts, 0, 0)) + + x.push(5); +>x.push : Symbol(Array.push, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 84, 7)) +>push : Symbol(Array.push, Decl(lib.d.ts, --, --)) + + return x; // number[] +>x : Symbol(x, Decl(controlFlowArrays.ts, 84, 7)) + } + else { + x.push("hello"); +>x.push : Symbol(Array.push, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 84, 7)) +>push : Symbol(Array.push, Decl(lib.d.ts, --, --)) + + return x; // string[] +>x : Symbol(x, Decl(controlFlowArrays.ts, 84, 7)) + } +} + +function f10() { +>f10 : Symbol(f10, Decl(controlFlowArrays.ts, 93, 1)) + + let x = []; +>x : Symbol(x, Decl(controlFlowArrays.ts, 96, 7)) + + if (cond()) { +>cond : Symbol(cond, Decl(controlFlowArrays.ts, 0, 0)) + + x.push(true); +>x.push : Symbol(Array.push, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 96, 7)) +>push : Symbol(Array.push, Decl(lib.d.ts, --, --)) + + x; // boolean[] +>x : Symbol(x, Decl(controlFlowArrays.ts, 96, 7)) + } + else { + x.push(5); +>x.push : Symbol(Array.push, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 96, 7)) +>push : Symbol(Array.push, Decl(lib.d.ts, --, --)) + + x; // number[] +>x : Symbol(x, Decl(controlFlowArrays.ts, 96, 7)) + + while (cond()) { +>cond : Symbol(cond, Decl(controlFlowArrays.ts, 0, 0)) + + x.push("hello"); +>x.push : Symbol(Array.push, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 96, 7)) +>push : Symbol(Array.push, Decl(lib.d.ts, --, --)) + } + x; // (string | number)[] +>x : Symbol(x, Decl(controlFlowArrays.ts, 96, 7)) + } + x.push(99); +>x.push : Symbol(Array.push, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 96, 7)) +>push : Symbol(Array.push, Decl(lib.d.ts, --, --)) + + return x; // (string | number | boolean)[] +>x : Symbol(x, Decl(controlFlowArrays.ts, 96, 7)) +} + +function f11() { +>f11 : Symbol(f11, Decl(controlFlowArrays.ts, 111, 1)) + + let x = []; +>x : Symbol(x, Decl(controlFlowArrays.ts, 114, 7)) + + return x; // never[] +>x : Symbol(x, Decl(controlFlowArrays.ts, 114, 7)) +} + +function f12() { +>f12 : Symbol(f12, Decl(controlFlowArrays.ts, 116, 1)) + + let x; +>x : Symbol(x, Decl(controlFlowArrays.ts, 119, 7)) + + x = []; +>x : Symbol(x, Decl(controlFlowArrays.ts, 119, 7)) + + return x; // never[] +>x : Symbol(x, Decl(controlFlowArrays.ts, 119, 7)) +} + +function f13() { +>f13 : Symbol(f13, Decl(controlFlowArrays.ts, 122, 1)) + + var x = []; +>x : Symbol(x, Decl(controlFlowArrays.ts, 125, 7)) + + x.push(5); +>x.push : Symbol(Array.push, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 125, 7)) +>push : Symbol(Array.push, Decl(lib.d.ts, --, --)) + + x.push("hello"); +>x.push : Symbol(Array.push, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 125, 7)) +>push : Symbol(Array.push, Decl(lib.d.ts, --, --)) + + x.push(true); +>x.push : Symbol(Array.push, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 125, 7)) +>push : Symbol(Array.push, Decl(lib.d.ts, --, --)) + + return x; // (string | number | boolean)[] +>x : Symbol(x, Decl(controlFlowArrays.ts, 125, 7)) +} + +function f14() { +>f14 : Symbol(f14, Decl(controlFlowArrays.ts, 130, 1)) + + const x = []; +>x : Symbol(x, Decl(controlFlowArrays.ts, 133, 9)) + + x.push(5); +>x.push : Symbol(Array.push, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 133, 9)) +>push : Symbol(Array.push, Decl(lib.d.ts, --, --)) + + x.push("hello"); +>x.push : Symbol(Array.push, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 133, 9)) +>push : Symbol(Array.push, Decl(lib.d.ts, --, --)) + + x.push(true); +>x.push : Symbol(Array.push, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 133, 9)) +>push : Symbol(Array.push, Decl(lib.d.ts, --, --)) + + return x; // (string | number | boolean)[] +>x : Symbol(x, Decl(controlFlowArrays.ts, 133, 9)) +} diff --git a/tests/baselines/reference/controlFlowArrays.types b/tests/baselines/reference/controlFlowArrays.types new file mode 100644 index 0000000000..7b36e4067f --- /dev/null +++ b/tests/baselines/reference/controlFlowArrays.types @@ -0,0 +1,447 @@ +=== tests/cases/compiler/controlFlowArrays.ts === + +declare function cond(): boolean; +>cond : () => boolean + +function f1() { +>f1 : () => (string | number | boolean)[] + + let x = []; +>x : any[] +>[] : never[] + + x[0] = 5; +>x[0] = 5 : 5 +>x[0] : any +>x : any[] +>0 : 0 +>5 : 5 + + x[1] = "hello"; +>x[1] = "hello" : "hello" +>x[1] : any +>x : any[] +>1 : 1 +>"hello" : "hello" + + x[2] = true; +>x[2] = true : true +>x[2] : any +>x : any[] +>2 : 2 +>true : true + + return x; // (string | number | boolean)[] +>x : (string | number | boolean)[] +} + +function f2() { +>f2 : () => (string | number | boolean)[] + + let x = []; +>x : any[] +>[] : never[] + + x.push(5); +>x.push(5) : number +>x.push : (...items: any[]) => number +>x : any[] +>push : (...items: any[]) => number +>5 : 5 + + x.push("hello"); +>x.push("hello") : number +>x.push : (...items: any[]) => number +>x : any[] +>push : (...items: any[]) => number +>"hello" : "hello" + + x.push(true); +>x.push(true) : number +>x.push : (...items: any[]) => number +>x : any[] +>push : (...items: any[]) => number +>true : true + + return x; // (string | number | boolean)[] +>x : (string | number | boolean)[] +} + +function f3() { +>f3 : () => (string | number)[] + + let x; +>x : any + + x = []; +>x = [] : never[] +>x : any +>[] : never[] + + x.push(5, "hello"); +>x.push(5, "hello") : number +>x.push : (...items: any[]) => number +>x : any[] +>push : (...items: any[]) => number +>5 : 5 +>"hello" : "hello" + + return x; // (string | number)[] +>x : (string | number)[] +} + +function f4() { +>f4 : () => (string | number)[] + + let x = []; +>x : any[] +>[] : never[] + + if (cond()) { +>cond() : boolean +>cond : () => boolean + + x.push(5); +>x.push(5) : number +>x.push : (...items: any[]) => number +>x : any[] +>push : (...items: any[]) => number +>5 : 5 + } + else { + x.push("hello"); +>x.push("hello") : number +>x.push : (...items: any[]) => number +>x : any[] +>push : (...items: any[]) => number +>"hello" : "hello" + } + return x; // (string | number)[] +>x : (string | number)[] +} + +function f5() { +>f5 : () => (string | number)[] + + let x; +>x : any + + if (cond()) { +>cond() : boolean +>cond : () => boolean + + x = []; +>x = [] : never[] +>x : any +>[] : never[] + + x.push(5); +>x.push(5) : number +>x.push : (...items: any[]) => number +>x : any[] +>push : (...items: any[]) => number +>5 : 5 + } + else { + x = []; +>x = [] : never[] +>x : any +>[] : never[] + + x.push("hello"); +>x.push("hello") : number +>x.push : (...items: any[]) => number +>x : any[] +>push : (...items: any[]) => number +>"hello" : "hello" + } + return x; // (string | number)[] +>x : (string | number)[] +} + +function f6() { +>f6 : () => number | string[] + + let x; +>x : any + + if (cond()) { +>cond() : boolean +>cond : () => boolean + + x = 5; +>x = 5 : 5 +>x : any +>5 : 5 + } + else { + x = []; +>x = [] : never[] +>x : any +>[] : never[] + + x.push("hello"); +>x.push("hello") : number +>x.push : (...items: any[]) => number +>x : any[] +>push : (...items: any[]) => number +>"hello" : "hello" + } + return x; // number | string[] +>x : number | string[] +} + +function f7() { +>f7 : () => string[] | null + + let x = null; +>x : any +>null : null + + if (cond()) { +>cond() : boolean +>cond : () => boolean + + x = []; +>x = [] : never[] +>x : any +>[] : never[] + + while (cond()) { +>cond() : boolean +>cond : () => boolean + + x.push("hello"); +>x.push("hello") : number +>x.push : (...items: any[]) => number +>x : any[] +>push : (...items: any[]) => number +>"hello" : "hello" + } + } + return x; // string[] | null +>x : string[] | null +} + +function f8() { +>f8 : () => (string | number | boolean)[] + + let x = []; +>x : any[] +>[] : never[] + + x.push(5); +>x.push(5) : number +>x.push : (...items: any[]) => number +>x : any[] +>push : (...items: any[]) => number +>5 : 5 + + if (cond()) return x; // number[] +>cond() : boolean +>cond : () => boolean +>x : number[] + + x.push("hello"); +>x.push("hello") : number +>x.push : (...items: any[]) => number +>x : any[] +>push : (...items: any[]) => number +>"hello" : "hello" + + if (cond()) return x; // (string | number)[] +>cond() : boolean +>cond : () => boolean +>x : (string | number)[] + + x.push(true); +>x.push(true) : number +>x.push : (...items: any[]) => number +>x : any[] +>push : (...items: any[]) => number +>true : true + + return x; // (string | number | boolean)[] +>x : (string | number | boolean)[] +} + +function f9() { +>f9 : () => string[] | number[] + + let x = []; +>x : any[] +>[] : never[] + + if (cond()) { +>cond() : boolean +>cond : () => boolean + + x.push(5); +>x.push(5) : number +>x.push : (...items: any[]) => number +>x : any[] +>push : (...items: any[]) => number +>5 : 5 + + return x; // number[] +>x : number[] + } + else { + x.push("hello"); +>x.push("hello") : number +>x.push : (...items: any[]) => number +>x : any[] +>push : (...items: any[]) => number +>"hello" : "hello" + + return x; // string[] +>x : string[] + } +} + +function f10() { +>f10 : () => (string | number | boolean)[] + + let x = []; +>x : any[] +>[] : never[] + + if (cond()) { +>cond() : boolean +>cond : () => boolean + + x.push(true); +>x.push(true) : number +>x.push : (...items: any[]) => number +>x : any[] +>push : (...items: any[]) => number +>true : true + + x; // boolean[] +>x : boolean[] + } + else { + x.push(5); +>x.push(5) : number +>x.push : (...items: any[]) => number +>x : any[] +>push : (...items: any[]) => number +>5 : 5 + + x; // number[] +>x : number[] + + while (cond()) { +>cond() : boolean +>cond : () => boolean + + x.push("hello"); +>x.push("hello") : number +>x.push : (...items: any[]) => number +>x : any[] +>push : (...items: any[]) => number +>"hello" : "hello" + } + x; // (string | number)[] +>x : (string | number)[] + } + x.push(99); +>x.push(99) : number +>x.push : (...items: any[]) => number +>x : any[] +>push : (...items: any[]) => number +>99 : 99 + + return x; // (string | number | boolean)[] +>x : (string | number | boolean)[] +} + +function f11() { +>f11 : () => never[] + + let x = []; +>x : any[] +>[] : never[] + + return x; // never[] +>x : never[] +} + +function f12() { +>f12 : () => never[] + + let x; +>x : any + + x = []; +>x = [] : never[] +>x : any +>[] : never[] + + return x; // never[] +>x : never[] +} + +function f13() { +>f13 : () => (string | number | boolean)[] + + var x = []; +>x : any[] +>[] : never[] + + x.push(5); +>x.push(5) : number +>x.push : (...items: any[]) => number +>x : any[] +>push : (...items: any[]) => number +>5 : 5 + + x.push("hello"); +>x.push("hello") : number +>x.push : (...items: any[]) => number +>x : any[] +>push : (...items: any[]) => number +>"hello" : "hello" + + x.push(true); +>x.push(true) : number +>x.push : (...items: any[]) => number +>x : any[] +>push : (...items: any[]) => number +>true : true + + return x; // (string | number | boolean)[] +>x : (string | number | boolean)[] +} + +function f14() { +>f14 : () => (string | number | boolean)[] + + const x = []; +>x : any[] +>[] : never[] + + x.push(5); +>x.push(5) : number +>x.push : (...items: any[]) => number +>x : any[] +>push : (...items: any[]) => number +>5 : 5 + + x.push("hello"); +>x.push("hello") : number +>x.push : (...items: any[]) => number +>x : any[] +>push : (...items: any[]) => number +>"hello" : "hello" + + x.push(true); +>x.push(true) : number +>x.push : (...items: any[]) => number +>x : any[] +>push : (...items: any[]) => number +>true : true + + return x; // (string | number | boolean)[] +>x : (string | number | boolean)[] +} From 12906a74dec4337b55a8be37dc8b29cdd84fea2a Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 6 Oct 2016 16:55:08 -0700 Subject: [PATCH 12/80] Fix some minor issues --- src/compiler/checker.ts | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f95ff1ccfe..0a606afe69 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8510,12 +8510,12 @@ namespace ts { } function isEvolvingArrayType(type: Type) { - return type.flags & TypeFlags.Anonymous && !!(type).elementType; + return !!(type.flags & TypeFlags.Anonymous && (type).elementType); } function createFinalArrayType(elementType: Type) { return createArrayType(elementType !== neverType ? - getUnionType([elementType], /*subtypeReduction*/ true) : + elementType.flags & TypeFlags.Union ? getUnionType((elementType).types, /*subtypeReduction*/ true) : elementType : strictNullChecks ? neverType : undefinedWideningType); } @@ -8528,16 +8528,29 @@ namespace ts { return isEvolvingArrayType(type) ? getFinalArrayType(type) : type; } - function getElementTypeOfEvolvingArrayType(evolvingArrayType: AnonymousType) { - return evolvingArrayType.elementType; + function getElementTypeOfEvolvingArrayType(type: Type) { + return isEvolvingArrayType(type) ? (type).elementType : neverType; + } + + function isEvolvingArrayTypeList(types: Type[]) { + let hasEvolvingArrayType = false; + for (const t of types) { + if (!(t.flags & TypeFlags.Never)) { + if (!isEvolvingArrayType(t)) { + return false; + } + hasEvolvingArrayType = true; + } + } + return hasEvolvingArrayType; } // At flow control branch or loop junctions, if the type along every antecedent code path // is an evolving array type, we construct a combined evolving array type. Otherwise we // finalize all evolving array types. function getUnionOrEvolvingArrayType(types: Type[], subtypeReduction: boolean) { - return types.length && every(types, isEvolvingArrayType) ? - getEvolvingArrayType(getUnionType(map(types, getElementTypeOfEvolvingArrayType))) : + return isEvolvingArrayTypeList(types) ? + getEvolvingArrayType(getUnionType(map(types, getElementTypeOfEvolvingArrayType))) : getUnionType(sameMap(types, finalizeEvolvingArrayType), subtypeReduction); } @@ -9211,6 +9224,10 @@ namespace ts { } } + function isConstVariable(symbol: Symbol) { + return symbol.flags & SymbolFlags.Variable && (getDeclarationNodeFlagsFromSymbol(symbol) & NodeFlags.Const) !== 0 && getTypeOfSymbol(symbol) !== autoArrayType; + } + function checkIdentifier(node: Identifier): Type { const symbol = getResolvedSymbol(node); @@ -9303,7 +9320,7 @@ namespace ts { // analysis to include the immediately enclosing function. while (flowContainer !== declarationContainer && (flowContainer.kind === SyntaxKind.FunctionExpression || flowContainer.kind === SyntaxKind.ArrowFunction) && - (isReadonlySymbol(localOrExportSymbol) || isParameter && !isParameterAssigned(localOrExportSymbol))) { + (isConstVariable(localOrExportSymbol) || isParameter && !isParameterAssigned(localOrExportSymbol))) { flowContainer = getControlFlowContainer(flowContainer); } // We only look for uninitialized variables in strict null checking mode, and only when we can analyze From 2f5af2e04b995873b89fb3cc8744fbdfa36a1a8f Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 6 Oct 2016 17:02:33 -0700 Subject: [PATCH 13/80] Add additional test --- .../reference/controlFlowArrayErrors.errors.txt | 16 +++++++++++++++- .../reference/controlFlowArrayErrors.js | 15 +++++++++++++++ tests/cases/compiler/controlFlowArrayErrors.ts | 8 ++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/tests/baselines/reference/controlFlowArrayErrors.errors.txt b/tests/baselines/reference/controlFlowArrayErrors.errors.txt index 7475c27324..bc13de261e 100644 --- a/tests/baselines/reference/controlFlowArrayErrors.errors.txt +++ b/tests/baselines/reference/controlFlowArrayErrors.errors.txt @@ -6,9 +6,11 @@ tests/cases/compiler/controlFlowArrayErrors.ts(30,12): error TS2345: Argument of tests/cases/compiler/controlFlowArrayErrors.ts(35,12): error TS2345: Argument of type 'true' is not assignable to parameter of type 'string | number'. tests/cases/compiler/controlFlowArrayErrors.ts(49,5): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '((...items: (string | number)[]) => number) | ((...items: boolean[]) => number)' has no compatible call signatures. tests/cases/compiler/controlFlowArrayErrors.ts(57,12): error TS2345: Argument of type '"hello"' is not assignable to parameter of type 'number'. +tests/cases/compiler/controlFlowArrayErrors.ts(61,11): error TS7034: Variable 'x' implicitly has type 'any[]' in some locations where its type cannot be determined. +tests/cases/compiler/controlFlowArrayErrors.ts(64,9): error TS7005: Variable 'x' implicitly has an 'any[]' type. -==== tests/cases/compiler/controlFlowArrayErrors.ts (8 errors) ==== +==== tests/cases/compiler/controlFlowArrayErrors.ts (10 errors) ==== declare function cond(): boolean; @@ -82,4 +84,16 @@ tests/cases/compiler/controlFlowArrayErrors.ts(57,12): error TS2345: Argument of y.push("hello"); // Error ~~~~~~~ !!! error TS2345: Argument of type '"hello"' is not assignable to parameter of type 'number'. + } + + function f8() { + const x = []; // Implicit any[] error in some locations + ~ +!!! error TS7034: Variable 'x' implicitly has type 'any[]' in some locations where its type cannot be determined. + x.push(5); + function g() { + x; // Implicit any[] error + ~ +!!! error TS7005: Variable 'x' implicitly has an 'any[]' type. + } } \ No newline at end of file diff --git a/tests/baselines/reference/controlFlowArrayErrors.js b/tests/baselines/reference/controlFlowArrayErrors.js index c158944933..538addc31c 100644 --- a/tests/baselines/reference/controlFlowArrayErrors.js +++ b/tests/baselines/reference/controlFlowArrayErrors.js @@ -56,6 +56,14 @@ function f7() { let y = x; // y has non-evolving array value x.push("hello"); // Ok y.push("hello"); // Error +} + +function f8() { + const x = []; // Implicit any[] error in some locations + x.push(5); + function g() { + x; // Implicit any[] error + } } //// [controlFlowArrayErrors.js] @@ -108,3 +116,10 @@ function f7() { x.push("hello"); // Ok y.push("hello"); // Error } +function f8() { + var x = []; // Implicit any[] error in some locations + x.push(5); + function g() { + x; // Implicit any[] error + } +} diff --git a/tests/cases/compiler/controlFlowArrayErrors.ts b/tests/cases/compiler/controlFlowArrayErrors.ts index 84da65c41d..aab3a974cd 100644 --- a/tests/cases/compiler/controlFlowArrayErrors.ts +++ b/tests/cases/compiler/controlFlowArrayErrors.ts @@ -56,4 +56,12 @@ function f7() { let y = x; // y has non-evolving array value x.push("hello"); // Ok y.push("hello"); // Error +} + +function f8() { + const x = []; // Implicit any[] error in some locations + x.push(5); + function g() { + x; // Implicit any[] error + } } \ No newline at end of file From 71b9b3351755e3e6978cec656c91032c0bfb0ab1 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 8 Oct 2016 15:26:17 -0700 Subject: [PATCH 14/80] Fix issue in control flow analysis of nested loops --- src/compiler/checker.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0a606afe69..2ff5700082 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8797,10 +8797,14 @@ namespace ts { } // If this flow loop junction and reference are already being processed, return // the union of the types computed for each branch so far, marked as incomplete. - // We should never see an empty array here because the first antecedent of a loop - // junction is always the non-looping control flow path that leads to the top. + // It is possible to see an empty array in cases where loops are nested and the + // back edge of the outer loop reaches an inner loop that is already being analyzed. + // In such cases we restart the analysis of the inner loop, which will then see + // a non-empty in-process array for the outer loop and eventually terminate because + // the first antecedent of a loop junction is always the non-looping control flow + // path that leads to the top. for (let i = flowLoopStart; i < flowLoopCount; i++) { - if (flowLoopNodes[i] === flow && flowLoopKeys[i] === key) { + if (flowLoopNodes[i] === flow && flowLoopKeys[i] === key && flowLoopTypes[i].length) { return createFlowType(getUnionOrEvolvingArrayType(flowLoopTypes[i], /*subtypeReduction*/ false), /*incomplete*/ true); } } From d202b1c037634939003b88fec921465969dec028 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 8 Oct 2016 15:27:49 -0700 Subject: [PATCH 15/80] Add test --- tests/cases/compiler/controlFlowArrays.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/cases/compiler/controlFlowArrays.ts b/tests/cases/compiler/controlFlowArrays.ts index d5eaa9c432..781b8c09d1 100644 --- a/tests/cases/compiler/controlFlowArrays.ts +++ b/tests/cases/compiler/controlFlowArrays.ts @@ -138,4 +138,13 @@ function f14() { x.push("hello"); x.push(true); return x; // (string | number | boolean)[] +} + +function f15() { + let x = []; + while (cond()) { + while (cond()) {} + x.push("hello"); + } + return x; // string[] } \ No newline at end of file From 89826a52ad09a5c854670caff7960e83a71fae43 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 8 Oct 2016 15:27:57 -0700 Subject: [PATCH 16/80] Accept new baselines --- .../baselines/reference/controlFlowArrays.js | 17 ++++++++++++ .../reference/controlFlowArrays.symbols | 21 +++++++++++++++ .../reference/controlFlowArrays.types | 26 +++++++++++++++++++ 3 files changed, 64 insertions(+) diff --git a/tests/baselines/reference/controlFlowArrays.js b/tests/baselines/reference/controlFlowArrays.js index 26885aecd8..c5ec1a7642 100644 --- a/tests/baselines/reference/controlFlowArrays.js +++ b/tests/baselines/reference/controlFlowArrays.js @@ -137,6 +137,15 @@ function f14() { x.push("hello"); x.push(true); return x; // (string | number | boolean)[] +} + +function f15() { + let x = []; + while (cond()) { + while (cond()) {} + x.push("hello"); + } + return x; // string[] } //// [controlFlowArrays.js] @@ -265,3 +274,11 @@ function f14() { x.push(true); return x; // (string | number | boolean)[] } +function f15() { + var x = []; + while (cond()) { + while (cond()) { } + x.push("hello"); + } + return x; // string[] +} diff --git a/tests/baselines/reference/controlFlowArrays.symbols b/tests/baselines/reference/controlFlowArrays.symbols index 5b5ef7f850..fd7c6ba89b 100644 --- a/tests/baselines/reference/controlFlowArrays.symbols +++ b/tests/baselines/reference/controlFlowArrays.symbols @@ -348,3 +348,24 @@ function f14() { return x; // (string | number | boolean)[] >x : Symbol(x, Decl(controlFlowArrays.ts, 133, 9)) } + +function f15() { +>f15 : Symbol(f15, Decl(controlFlowArrays.ts, 138, 1)) + + let x = []; +>x : Symbol(x, Decl(controlFlowArrays.ts, 141, 7)) + + while (cond()) { +>cond : Symbol(cond, Decl(controlFlowArrays.ts, 0, 0)) + + while (cond()) {} +>cond : Symbol(cond, Decl(controlFlowArrays.ts, 0, 0)) + + x.push("hello"); +>x.push : Symbol(Array.push, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 141, 7)) +>push : Symbol(Array.push, Decl(lib.d.ts, --, --)) + } + return x; // string[] +>x : Symbol(x, Decl(controlFlowArrays.ts, 141, 7)) +} diff --git a/tests/baselines/reference/controlFlowArrays.types b/tests/baselines/reference/controlFlowArrays.types index 7b36e4067f..3fb84215ed 100644 --- a/tests/baselines/reference/controlFlowArrays.types +++ b/tests/baselines/reference/controlFlowArrays.types @@ -445,3 +445,29 @@ function f14() { return x; // (string | number | boolean)[] >x : (string | number | boolean)[] } + +function f15() { +>f15 : () => string[] + + let x = []; +>x : any[] +>[] : never[] + + while (cond()) { +>cond() : boolean +>cond : () => boolean + + while (cond()) {} +>cond() : boolean +>cond : () => boolean + + x.push("hello"); +>x.push("hello") : number +>x.push : (...items: any[]) => number +>x : any[] +>push : (...items: any[]) => number +>"hello" : "hello" + } + return x; // string[] +>x : string[] +} From e6b588a956d5046469dbfa240d35ab1cc09c0046 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 11 Oct 2016 10:14:06 -0700 Subject: [PATCH 17/80] Support parentheses and comma operator with evolving arrays --- src/compiler/binder.ts | 10 +++++----- src/compiler/checker.ts | 34 ++++++++++++++++++++++++---------- src/compiler/types.ts | 2 +- 3 files changed, 30 insertions(+), 16 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 1b121394a8..6926403d9b 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -760,7 +760,7 @@ namespace ts { }; } - function createFlowArrayMutation(antecedent: FlowNode, node: Expression): FlowNode { + function createFlowArrayMutation(antecedent: FlowNode, node: CallExpression | BinaryExpression): FlowNode { setFlowNodeReferenced(antecedent); return { flags: FlowFlags.ArrayMutation, @@ -1151,8 +1151,8 @@ namespace ts { bindAssignmentTargetFlow(node.left); if (node.left.kind === SyntaxKind.ElementAccessExpression) { const elementAccess = node.left; - if (isNarrowableReference(elementAccess.expression)) { - currentFlow = createFlowArrayMutation(currentFlow, elementAccess.expression); + if (isNarrowableOperand(elementAccess.expression)) { + currentFlow = createFlowArrayMutation(currentFlow, node); } } } @@ -1217,8 +1217,8 @@ namespace ts { } if (node.expression.kind === SyntaxKind.PropertyAccessExpression) { const propertyAccess = node.expression; - if (isNarrowableReference(propertyAccess.expression) && propertyAccess.name.text === "push") { - currentFlow = createFlowArrayMutation(currentFlow, propertyAccess.expression); + if (isNarrowableOperand(propertyAccess.expression) && propertyAccess.name.text === "push") { + currentFlow = createFlowArrayMutation(currentFlow, node); } } } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2ff5700082..379d61850e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8424,6 +8424,14 @@ namespace ts { return node; } + function getReferenceParent(node: Node): Node { + const parent = node.parent; + return parent.kind === SyntaxKind.ParenthesizedExpression || + parent.kind === SyntaxKind.BinaryExpression && (parent).operatorToken.kind === SyntaxKind.EqualsToken && (parent).left === node || + parent.kind === SyntaxKind.BinaryExpression && (parent).operatorToken.kind === SyntaxKind.CommaToken && (parent).right === node ? + getReferenceParent(parent) : parent; + } + function getTypeOfSwitchClause(clause: CaseClause | DefaultClause) { if (clause.kind === SyntaxKind.CaseClause) { const caseType = getRegularTypeOfLiteralType(checkExpression((clause).expression)); @@ -8556,15 +8564,16 @@ namespace ts { // Return true if the given node is 'x' in an 'x.push(value)' operation. function isPushCallTarget(node: Node) { - return node.parent.kind === SyntaxKind.PropertyAccessExpression && - (node.parent).name.text === "push" && - node.parent.parent.kind === SyntaxKind.CallExpression; + const parent = getReferenceParent(node); + return parent.kind === SyntaxKind.PropertyAccessExpression && + (parent).name.text === "push" && + parent.parent.kind === SyntaxKind.CallExpression; } // Return true if the given node is 'x' in an 'x[n] = value' operation, where 'n' is an // expression of type any, undefined, or a number-like type. function isElementAssignmentTarget(node: Node) { - const parent = node.parent; + const parent = getReferenceParent(node); return parent.kind === SyntaxKind.ElementAccessExpression && (parent).expression === node && parent.parent.kind === SyntaxKind.BinaryExpression && @@ -8696,19 +8705,24 @@ namespace ts { function getTypeAtFlowArrayMutation(flow: FlowArrayMutation): FlowType { const node = flow.node; - if (isMatchingReference(reference, node)) { + const expr = node.kind === SyntaxKind.CallExpression ? + ((node).expression).expression : + ((node).left).expression; + if (isMatchingReference(reference, getReferenceCandidate(expr))) { const flowType = getTypeAtFlowNode(flow.antecedent); const type = getTypeFromFlowType(flowType); if (isEvolvingArrayType(type)) { - const parent = node.parent; let evolvedType = type; - if (parent.kind === SyntaxKind.PropertyAccessExpression) { - for (const arg of (parent.parent).arguments) { + if (node.kind === SyntaxKind.CallExpression) { + for (const arg of (node).arguments) { evolvedType = addEvolvingArrayElementType(evolvedType, arg); } } - else if (isTypeAnyOrAllConstituentTypesHaveKind(checkExpression((parent).argumentExpression), TypeFlags.NumberLike)) { - evolvedType = addEvolvingArrayElementType(evolvedType, (parent.parent).right); + else { + const indexType = checkExpression(((node).left).argumentExpression); + if (isTypeAnyOrAllConstituentTypesHaveKind(indexType, TypeFlags.NumberLike | TypeFlags.Undefined)) { + evolvedType = addEvolvingArrayElementType(evolvedType, (node).right); + } } return evolvedType === type ? flowType : createFlowType(evolvedType, isIncomplete(flowType)); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 9759c2ab54..5c32649d97 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1955,7 +1955,7 @@ namespace ts { // FlowArrayMutation represents a node potentially mutates an array, i.e. an // operation of the form 'x.push(value)' or 'x[n] = value'. export interface FlowArrayMutation extends FlowNode { - node: Expression; + node: CallExpression | BinaryExpression; antecedent: FlowNode; } From 612ed1e24a0932b005a57d27092e39711046be10 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 11 Oct 2016 10:27:40 -0700 Subject: [PATCH 18/80] Fix minor issue --- src/compiler/checker.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 379d61850e..9e2b7a3174 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8424,12 +8424,12 @@ namespace ts { return node; } - function getReferenceParent(node: Node): Node { + function getReferenceRoot(node: Node): Node { const parent = node.parent; return parent.kind === SyntaxKind.ParenthesizedExpression || parent.kind === SyntaxKind.BinaryExpression && (parent).operatorToken.kind === SyntaxKind.EqualsToken && (parent).left === node || parent.kind === SyntaxKind.BinaryExpression && (parent).operatorToken.kind === SyntaxKind.CommaToken && (parent).right === node ? - getReferenceParent(parent) : parent; + getReferenceRoot(parent) : node; } function getTypeOfSwitchClause(clause: CaseClause | DefaultClause) { @@ -8564,7 +8564,7 @@ namespace ts { // Return true if the given node is 'x' in an 'x.push(value)' operation. function isPushCallTarget(node: Node) { - const parent = getReferenceParent(node); + const parent = getReferenceRoot(node).parent; return parent.kind === SyntaxKind.PropertyAccessExpression && (parent).name.text === "push" && parent.parent.kind === SyntaxKind.CallExpression; @@ -8573,9 +8573,10 @@ namespace ts { // Return true if the given node is 'x' in an 'x[n] = value' operation, where 'n' is an // expression of type any, undefined, or a number-like type. function isElementAssignmentTarget(node: Node) { - const parent = getReferenceParent(node); + const root = getReferenceRoot(node); + const parent = root.parent; return parent.kind === SyntaxKind.ElementAccessExpression && - (parent).expression === node && + (parent).expression === root && parent.parent.kind === SyntaxKind.BinaryExpression && (parent.parent).operatorToken.kind === SyntaxKind.EqualsToken && (parent.parent).left === parent && From e9858de363e22b0f0318ef8b2848306e944aff50 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 11 Oct 2016 10:28:13 -0700 Subject: [PATCH 19/80] Add test --- tests/cases/compiler/controlFlowArrays.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/cases/compiler/controlFlowArrays.ts b/tests/cases/compiler/controlFlowArrays.ts index 781b8c09d1..e89a244375 100644 --- a/tests/cases/compiler/controlFlowArrays.ts +++ b/tests/cases/compiler/controlFlowArrays.ts @@ -147,4 +147,13 @@ function f15() { x.push("hello"); } return x; // string[] +} + +function f16() { + let x; + let y; + (x = [], x).push(5); + (x.push("hello"), x).push(true); + ((x))[3] = { a: 1 }; + return x; // (string | number | boolean | { a: number })[] } \ No newline at end of file From c9e2f959184beda9e25ee97d186a5dea0f44bb88 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 11 Oct 2016 10:32:00 -0700 Subject: [PATCH 20/80] Accept new baselines --- .../baselines/reference/controlFlowArrays.js | 17 +++++++ .../reference/controlFlowArrays.symbols | 31 ++++++++++++ .../reference/controlFlowArrays.types | 50 +++++++++++++++++++ 3 files changed, 98 insertions(+) diff --git a/tests/baselines/reference/controlFlowArrays.js b/tests/baselines/reference/controlFlowArrays.js index c5ec1a7642..d6f387ab98 100644 --- a/tests/baselines/reference/controlFlowArrays.js +++ b/tests/baselines/reference/controlFlowArrays.js @@ -146,6 +146,15 @@ function f15() { x.push("hello"); } return x; // string[] +} + +function f16() { + let x; + let y; + (x = [], x).push(5); + (x.push("hello"), x).push(true); + ((x))[3] = { a: 1 }; + return x; // (string | number | boolean | { a: number })[] } //// [controlFlowArrays.js] @@ -282,3 +291,11 @@ function f15() { } return x; // string[] } +function f16() { + var x; + var y; + (x = [], x).push(5); + (x.push("hello"), x).push(true); + ((x))[3] = { a: 1 }; + return x; // (string | number | boolean | { a: number })[] +} diff --git a/tests/baselines/reference/controlFlowArrays.symbols b/tests/baselines/reference/controlFlowArrays.symbols index fd7c6ba89b..204a217199 100644 --- a/tests/baselines/reference/controlFlowArrays.symbols +++ b/tests/baselines/reference/controlFlowArrays.symbols @@ -369,3 +369,34 @@ function f15() { return x; // string[] >x : Symbol(x, Decl(controlFlowArrays.ts, 141, 7)) } + +function f16() { +>f16 : Symbol(f16, Decl(controlFlowArrays.ts, 147, 1)) + + let x; +>x : Symbol(x, Decl(controlFlowArrays.ts, 150, 7)) + + let y; +>y : Symbol(y, Decl(controlFlowArrays.ts, 151, 7)) + + (x = [], x).push(5); +>(x = [], x).push : Symbol(Array.push, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 150, 7)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 150, 7)) +>push : Symbol(Array.push, Decl(lib.d.ts, --, --)) + + (x.push("hello"), x).push(true); +>(x.push("hello"), x).push : Symbol(Array.push, Decl(lib.d.ts, --, --)) +>x.push : Symbol(Array.push, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 150, 7)) +>push : Symbol(Array.push, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 150, 7)) +>push : Symbol(Array.push, Decl(lib.d.ts, --, --)) + + ((x))[3] = { a: 1 }; +>x : Symbol(x, Decl(controlFlowArrays.ts, 150, 7)) +>a : Symbol(a, Decl(controlFlowArrays.ts, 154, 16)) + + return x; // (string | number | boolean | { a: number })[] +>x : Symbol(x, Decl(controlFlowArrays.ts, 150, 7)) +} diff --git a/tests/baselines/reference/controlFlowArrays.types b/tests/baselines/reference/controlFlowArrays.types index 3fb84215ed..3a91ce7e19 100644 --- a/tests/baselines/reference/controlFlowArrays.types +++ b/tests/baselines/reference/controlFlowArrays.types @@ -471,3 +471,53 @@ function f15() { return x; // string[] >x : string[] } + +function f16() { +>f16 : () => (string | number | boolean | { a: number; })[] + + let x; +>x : any + + let y; +>y : any + + (x = [], x).push(5); +>(x = [], x).push(5) : number +>(x = [], x).push : (...items: any[]) => number +>(x = [], x) : any[] +>x = [], x : any[] +>x = [] : never[] +>x : any +>[] : never[] +>x : any[] +>push : (...items: any[]) => number +>5 : 5 + + (x.push("hello"), x).push(true); +>(x.push("hello"), x).push(true) : number +>(x.push("hello"), x).push : (...items: any[]) => number +>(x.push("hello"), x) : any[] +>x.push("hello"), x : any[] +>x.push("hello") : number +>x.push : (...items: any[]) => number +>x : any[] +>push : (...items: any[]) => number +>"hello" : "hello" +>x : any[] +>push : (...items: any[]) => number +>true : true + + ((x))[3] = { a: 1 }; +>((x))[3] = { a: 1 } : { a: number; } +>((x))[3] : any +>((x)) : any[] +>(x) : any[] +>x : any[] +>3 : 3 +>{ a: 1 } : { a: number; } +>a : number +>1 : 1 + + return x; // (string | number | boolean | { a: number })[] +>x : (string | number | boolean | { a: number; })[] +} From d7e33c90a2fb6748c39630fc2a9f5d8e8272e9a7 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Tue, 11 Oct 2016 13:51:53 -0700 Subject: [PATCH 21/80] Guard localeCompare function --- src/compiler/core.ts | 22 ++++++++++++++++++++-- src/harness/harness.ts | 2 +- src/server/session.ts | 2 +- src/services/navigateTo.ts | 4 ++-- src/services/navigationBar.ts | 6 ++---- 5 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 7c68306211..5ad9fa2c19 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -20,6 +20,24 @@ namespace ts { const createObject = Object.create; + // More efficient to create a collator once and use its `compare` than to call `a.localeCompare(b)` many times. + export const collator: { compare(a: string, b: string): number } = typeof Intl === "object" && typeof Intl.Collator === "function" ? new Intl.Collator() : undefined; + + /** + * Use this function instead of calling "String.prototype.localeCompre". This function will preform appropriate check to make sure that + * "typeof Intl" is correct as there are reported issues #11110 nad #11339. + * @param a reference string to compare + * @param b string to compare against + * @param locales string of BCP 47 language tag or an array of string of BCP 47 language tag + * @param options an object of Intl.CollatorOptions to specify localeCompare properties + */ + export function localeCompare(a: string, b: string, locales?: string | string[], options?: Intl.CollatorOptions): number | undefined { + if (collator && String.prototype.localeCompare) { + return a.localeCompare(b, locales, options); + } + return undefined; + } + export function createMap(template?: MapLike): Map { const map: Map = createObject(null); // tslint:disable-line:no-null-keyword @@ -1016,8 +1034,8 @@ namespace ts { if (a === undefined) return Comparison.LessThan; if (b === undefined) return Comparison.GreaterThan; if (ignoreCase) { - if (String.prototype.localeCompare) { - const result = a.localeCompare(b, /*locales*/ undefined, { usage: "sort", sensitivity: "accent" }); + const result = localeCompare(a, b, /*locales*/ undefined, /*options*/ { usage: "sort", sensitivity: "accent" }); + if (result) { return result < 0 ? Comparison.LessThan : result > 0 ? Comparison.GreaterThan : Comparison.EqualTo; } diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 7c82aeece7..f26a9dd062 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -1634,7 +1634,7 @@ namespace Harness { export function collateOutputs(outputFiles: Harness.Compiler.GeneratedFile[]): string { // Collect, test, and sort the fileNames - outputFiles.sort((a, b) => cleanName(a.fileName).localeCompare(cleanName(b.fileName))); + outputFiles.sort((a, b) => ts.localeCompare(cleanName(a.fileName), cleanName(b.fileName))); // Emit them let result = ""; diff --git a/src/server/session.ts b/src/server/session.ts index 3b95bdd6fb..d4633f119e 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -959,7 +959,7 @@ namespace ts.server { result.push({ name, kind, kindModifiers, sortText, replacementSpan: convertedSpan }); } return result; - }, []).sort((a, b) => a.name.localeCompare(b.name)); + }, []).sort((a, b) => localeCompare(a.name, b.name)); } else { return completions; diff --git a/src/services/navigateTo.ts b/src/services/navigateTo.ts index 44aa25f500..8c968db7eb 100644 --- a/src/services/navigateTo.ts +++ b/src/services/navigateTo.ts @@ -188,8 +188,8 @@ namespace ts.NavigateTo { // We first sort case insensitively. So "Aaa" will come before "bar". // Then we sort case sensitively, so "aaa" will come before "Aaa". return i1.matchKind - i2.matchKind || - i1.name.localeCompare(i2.name, undefined, baseSensitivity) || - i1.name.localeCompare(i2.name); + ts.localeCompare(i1.name, i2.name, /*locales*/ undefined, /*options*/ baseSensitivity) || + ts.localeCompare(i1.name, i2.name); } function createNavigateToItem(rawItem: RawNavigateToItem): NavigateToItem { diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index 0397ae7322..f981ad6016 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -323,10 +323,8 @@ namespace ts.NavigationBar { } } - // More efficient to create a collator once and use its `compare` than to call `a.localeCompare(b)` many times. - const collator: { compare(a: string, b: string): number } = typeof Intl === "object" && typeof Intl.Collator === "function" ? new Intl.Collator() : undefined; // Intl is missing in Safari, and node 0.10 treats "a" as greater than "B". - const localeCompareIsCorrect = collator && collator.compare("a", "B") < 0; + const localeCompareIsCorrect = ts.collator && ts.collator.compare("a", "B") < 0; const localeCompareFix: (a: string, b: string) => number = localeCompareIsCorrect ? collator.compare : function(a, b) { // This isn't perfect, but it passes all of our tests. for (let i = 0; i < Math.min(a.length, b.length); i++) { @@ -337,7 +335,7 @@ namespace ts.NavigationBar { if (chA === "'" && chB === "\"") { return -1; } - const cmp = chA.toLocaleLowerCase().localeCompare(chB.toLocaleLowerCase()); + const cmp = ts.localeCompare(chA.toLocaleLowerCase(), chB.toLocaleLowerCase()); if (cmp !== 0) { return cmp; } From 38278ee0788bb8dc26b5052f103591b8fd0be0ab Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 11 Oct 2016 18:28:19 -0700 Subject: [PATCH 22/80] Fix typo --- src/compiler/core.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 36548334a6..47e533c9a6 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -271,7 +271,7 @@ namespace ts { return result; } - // Maps from T to T and avoids allocation of all elements map to themselves + // Maps from T to T and avoids allocation if all elements map to themselves export function sameMap(array: T[], f: (x: T, i: number) => T): T[] { let result: T[]; if (array) { From f42c79150253b003f6f7e38011d57cf0af77df10 Mon Sep 17 00:00:00 2001 From: Andrej Baran Date: Wed, 12 Oct 2016 21:28:11 +0200 Subject: [PATCH 23/80] Don't use es8. Add es2016 target. Rename es7 to es2016. Update getDefaultLibFileName for new targets. --- Jakefile.js | 4 +- src/compiler/binder.ts | 4 +- src/compiler/commandLineParser.ts | 2 +- src/compiler/emitter.ts | 4 +- src/compiler/transformer.ts | 7 +-- .../transformers/{es7.ts => es2016.ts} | 10 ++-- src/compiler/transformers/ts.ts | 3 +- src/compiler/tsconfig.json | 2 +- src/compiler/types.ts | 53 ++++++++++--------- src/compiler/utilities.ts | 10 +++- src/harness/harness.ts | 10 +++- src/harness/tsconfig.json | 2 +- src/harness/unittests/commandLineParsing.ts | 2 +- .../convertCompilerOptionsFromJson.ts | 2 +- src/services/tsconfig.json | 2 +- .../{es8-async.ts => es2017basicAsync.ts} | 2 +- 16 files changed, 69 insertions(+), 50 deletions(-) rename src/compiler/transformers/{es7.ts => es2016.ts} (91%) rename tests/cases/compiler/{es8-async.ts => es2017basicAsync.ts} (97%) diff --git a/Jakefile.js b/Jakefile.js index 64a8553ef3..ecbd0ae2be 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -74,7 +74,7 @@ var compilerSources = [ "transformers/module/system.ts", "transformers/module/module.ts", "transformers/jsx.ts", - "transformers/es7.ts", + "transformers/es2016.ts", "transformers/generators.ts", "transformers/es6.ts", "transformer.ts", @@ -108,7 +108,7 @@ var servicesSources = [ "transformers/module/system.ts", "transformers/module/module.ts", "transformers/jsx.ts", - "transformers/es7.ts", + "transformers/es2016.ts", "transformers/generators.ts", "transformers/es6.ts", "transformer.ts", diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 2fe7d30ab5..ce482dcdfd 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -2411,8 +2411,8 @@ namespace ts { } else if (operatorTokenKind === SyntaxKind.AsteriskAsteriskToken || operatorTokenKind === SyntaxKind.AsteriskAsteriskEqualsToken) { - // Exponentiation is ES7 syntax. - transformFlags |= TransformFlags.AssertES7; + // Exponentiation is ES2016 syntax. + transformFlags |= TransformFlags.AssertES2016; } node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 16d338cac6..b77f6898b3 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -262,8 +262,8 @@ namespace ts { "es3": ScriptTarget.ES3, "es5": ScriptTarget.ES5, "es6": ScriptTarget.ES6, - "es8": ScriptTarget.ES8, "es2015": ScriptTarget.ES2015, + "es2016": ScriptTarget.ES2016, "es2017": ScriptTarget.ES2017, }), description: Diagnostics.Specify_ECMAScript_target_version_Colon_ES3_default_ES5_or_ES2015, diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index b0e31278ff..a3f69e2fd4 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -2194,8 +2194,8 @@ const _super = (function (geti, seti) { // Only emit __awaiter function when target ES5/ES6. // Only emit __generator function when target ES5. - // For target ES8 and above, we can emit async/await as is. - if ((languageVersion < ScriptTarget.ES8) && (!awaiterEmitted && node.flags & NodeFlags.HasAsyncFunctions)) { + // For target ES2017 and above, we can emit async/await as is. + if ((languageVersion < ScriptTarget.ES2017) && (!awaiterEmitted && node.flags & NodeFlags.HasAsyncFunctions)) { writeLines(awaiterHelper); if (languageVersion < ScriptTarget.ES6) { writeLines(generatorHelper); diff --git a/src/compiler/transformer.ts b/src/compiler/transformer.ts index 415a9ecd1d..9e54826805 100644 --- a/src/compiler/transformer.ts +++ b/src/compiler/transformer.ts @@ -1,7 +1,7 @@ /// /// /// -/// +/// /// /// /// @@ -115,8 +115,9 @@ namespace ts { transformers.push(transformJsx); } - if (languageVersion < ScriptTarget.ES8) { - transformers.push(transformES7); + + if (languageVersion < ScriptTarget.ES2016) { + transformers.push(transformES2016); } if (languageVersion < ScriptTarget.ES6) { diff --git a/src/compiler/transformers/es7.ts b/src/compiler/transformers/es2016.ts similarity index 91% rename from src/compiler/transformers/es7.ts rename to src/compiler/transformers/es2016.ts index 4d5e96134c..fba1d30090 100644 --- a/src/compiler/transformers/es7.ts +++ b/src/compiler/transformers/es2016.ts @@ -3,7 +3,7 @@ /*@internal*/ namespace ts { - export function transformES7(context: TransformationContext) { + export function transformES2016(context: TransformationContext) { const { hoistVariableDeclaration } = context; return transformSourceFile; @@ -17,10 +17,10 @@ namespace ts { } function visitor(node: Node): VisitResult { - if (node.transformFlags & TransformFlags.ES7) { + if (node.transformFlags & TransformFlags.ES2016) { return visitorWorker(node); } - else if (node.transformFlags & TransformFlags.ContainsES7) { + else if (node.transformFlags & TransformFlags.ContainsES2016) { return visitEachChild(node, visitor, context); } else { @@ -40,7 +40,7 @@ namespace ts { } function visitBinaryExpression(node: BinaryExpression): Expression { - // We are here because ES7 adds support for the exponentiation operator. + // We are here because ES2016 adds support for the exponentiation operator. const left = visitNode(node.left, visitor, isExpression); const right = visitNode(node.right, visitor, isExpression); if (node.operatorToken.kind === SyntaxKind.AsteriskAsteriskEqualsToken) { @@ -98,4 +98,4 @@ namespace ts { } } } -} \ No newline at end of file +} diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 40b9e7f64e..c98fbfc26c 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -241,8 +241,7 @@ namespace ts { return currentNamespace ? undefined : node; case SyntaxKind.AsyncKeyword: - // Async keyword is not elided for target ES8 - return languageVersion < ScriptTarget.ES8 ? undefined : node; + return node; case SyntaxKind.PublicKeyword: case SyntaxKind.PrivateKeyword: diff --git a/src/compiler/tsconfig.json b/src/compiler/tsconfig.json index f128c994af..fc0f016f66 100644 --- a/src/compiler/tsconfig.json +++ b/src/compiler/tsconfig.json @@ -24,7 +24,7 @@ "visitor.ts", "transformers/ts.ts", "transformers/jsx.ts", - "transformers/es7.ts", + "transformers/es2016.ts", "transformers/es6.ts", "transformers/generators.ts", "transformers/destructuring.ts", diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 5b193beb15..b89887cafa 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2831,10 +2831,10 @@ namespace ts { ES3 = 0, ES5 = 1, ES6 = 2, - ES8 = 3, ES2015 = ES6, - ES2017 = ES8, - Latest = ES8, + ES2016 = 3, + ES2017 = 4, + Latest = ES2017, } export const enum LanguageVariant { @@ -3119,29 +3119,31 @@ namespace ts { ContainsTypeScript = 1 << 1, Jsx = 1 << 2, ContainsJsx = 1 << 3, - ES7 = 1 << 4, - ContainsES7 = 1 << 5, - ES6 = 1 << 6, - ContainsES6 = 1 << 7, - DestructuringAssignment = 1 << 8, - Generator = 1 << 9, - ContainsGenerator = 1 << 10, + ES2017 = 1 << 4, + ContainsES2017 = 1 << 5, + ES2016 = 1 << 6, + ContainsES2016 = 1 << 7, + ES6 = 1 << 8, + ContainsES6 = 1 << 9, + DestructuringAssignment = 1 << 10, + Generator = 1 << 11, + ContainsGenerator = 1 << 12, // Markers // - Flags used to indicate that a subtree contains a specific transformation. - ContainsDecorators = 1 << 11, - ContainsPropertyInitializer = 1 << 12, - ContainsLexicalThis = 1 << 13, - ContainsCapturedLexicalThis = 1 << 14, - ContainsLexicalThisInComputedPropertyName = 1 << 15, - ContainsDefaultValueAssignments = 1 << 16, - ContainsParameterPropertyAssignments = 1 << 17, - ContainsSpreadElementExpression = 1 << 18, - ContainsComputedPropertyName = 1 << 19, - ContainsBlockScopedBinding = 1 << 20, - ContainsBindingPattern = 1 << 21, - ContainsYield = 1 << 22, - ContainsHoistedDeclarationOrCompletion = 1 << 23, + ContainsDecorators = 1 << 13, + ContainsPropertyInitializer = 1 << 14, + ContainsLexicalThis = 1 << 15, + ContainsCapturedLexicalThis = 1 << 16, + ContainsLexicalThisInComputedPropertyName = 1 << 17, + ContainsDefaultValueAssignments = 1 << 18, + ContainsParameterPropertyAssignments = 1 << 19, + ContainsSpreadElementExpression = 1 << 20, + ContainsComputedPropertyName = 1 << 21, + ContainsBlockScopedBinding = 1 << 22, + ContainsBindingPattern = 1 << 23, + ContainsYield = 1 << 24, + ContainsHoistedDeclarationOrCompletion = 1 << 25, HasComputedFlags = 1 << 29, // Transform flags have been computed. @@ -3149,14 +3151,15 @@ namespace ts { // - Bitmasks that are used to assert facts about the syntax of a node and its subtree. AssertTypeScript = TypeScript | ContainsTypeScript, AssertJsx = Jsx | ContainsJsx, - AssertES7 = ES7 | ContainsES7, + AssertES2017 = ES2017 | ContainsES2017, + AssertES2016 = ES2016 | ContainsES2016, AssertES6 = ES6 | ContainsES6, AssertGenerator = Generator | ContainsGenerator, // Scope Exclusions // - Bitmasks that exclude flags from propagating out of a specific context // into the subtree flags of their container. - NodeExcludes = TypeScript | Jsx | ES7 | ES6 | DestructuringAssignment | Generator | HasComputedFlags, + NodeExcludes = TypeScript | Jsx | ES2017 | ES2016 | ES6 | DestructuringAssignment | Generator | HasComputedFlags, ArrowFunctionExcludes = NodeExcludes | ContainsDecorators | ContainsDefaultValueAssignments | ContainsLexicalThis | ContainsParameterPropertyAssignments | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion, FunctionExcludes = NodeExcludes | ContainsDecorators | ContainsDefaultValueAssignments | ContainsCapturedLexicalThis | ContainsLexicalThis | ContainsParameterPropertyAssignments | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion, ConstructorExcludes = NodeExcludes | ContainsDefaultValueAssignments | ContainsLexicalThis | ContainsCapturedLexicalThis | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion, diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 1a4d95feca..b661cefb5a 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -4141,7 +4141,15 @@ namespace ts { namespace ts { export function getDefaultLibFileName(options: CompilerOptions): string { - return options.target === ScriptTarget.ES6 ? "lib.es6.d.ts" : "lib.d.ts"; + switch (options.target) { + case ScriptTarget.ES2016: + return "lib.es2016.d.ts"; + case ScriptTarget.ES6: + return "lib.es2015.d.ts"; + + default: + return "lib.d.ts"; + } } export function textSpanEnd(span: TextSpan) { diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 7c82aeece7..b8703ebc8f 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -941,7 +941,15 @@ namespace Harness { } export function getDefaultLibFileName(options: ts.CompilerOptions): string { - return options.target === ts.ScriptTarget.ES6 ? es2015DefaultLibFileName : defaultLibFileName; + switch (options.target) { + case ts.ScriptTarget.ES2016: + return "lib.es2016.d.ts"; + case ts.ScriptTarget.ES6: + return es2015DefaultLibFileName; + + default: + return defaultLibFileName; + } } // Cache these between executions so we don't have to re-parse them for every test diff --git a/src/harness/tsconfig.json b/src/harness/tsconfig.json index f9d302ace8..aa46c8ee8d 100644 --- a/src/harness/tsconfig.json +++ b/src/harness/tsconfig.json @@ -26,7 +26,7 @@ "../compiler/visitor.ts", "../compiler/transformers/ts.ts", "../compiler/transformers/jsx.ts", - "../compiler/transformers/es7.ts", + "../compiler/transformers/es2016.ts", "../compiler/transformers/es6.ts", "../compiler/transformers/generators.ts", "../compiler/transformers/destructuring.ts", diff --git a/src/harness/unittests/commandLineParsing.ts b/src/harness/unittests/commandLineParsing.ts index 42fc242f08..cd9bf88df6 100644 --- a/src/harness/unittests/commandLineParsing.ts +++ b/src/harness/unittests/commandLineParsing.ts @@ -165,7 +165,7 @@ namespace ts { start: undefined, length: undefined, }, { - messageText: "Argument for '--target' option must be: 'es3', 'es5', 'es6', 'es8', 'es2015', 'es2017'", + messageText: "Argument for '--target' option must be: 'es3', 'es5', 'es6', 'es2015', 'es2016', 'es2017'", category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, diff --git a/src/harness/unittests/convertCompilerOptionsFromJson.ts b/src/harness/unittests/convertCompilerOptionsFromJson.ts index db3d6cfc10..13f54e369e 100644 --- a/src/harness/unittests/convertCompilerOptionsFromJson.ts +++ b/src/harness/unittests/convertCompilerOptionsFromJson.ts @@ -176,7 +176,7 @@ namespace ts { file: undefined, start: 0, length: 0, - messageText: "Argument for '--target' option must be: 'es3', 'es5', 'es6', 'es8', 'es2015', 'es2017'", + messageText: "Argument for '--target' option must be: 'es3', 'es5', 'es6', 'es2015', 'es2016', 'es2017'", code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] diff --git a/src/services/tsconfig.json b/src/services/tsconfig.json index 58312c6f38..e759ab35b4 100644 --- a/src/services/tsconfig.json +++ b/src/services/tsconfig.json @@ -25,7 +25,7 @@ "../compiler/visitor.ts", "../compiler/transformers/ts.ts", "../compiler/transformers/jsx.ts", - "../compiler/transformers/es7.ts", + "../compiler/transformers/es2016.ts", "../compiler/transformers/es6.ts", "../compiler/transformers/generators.ts", "../compiler/transformers/destructuring.ts", diff --git a/tests/cases/compiler/es8-async.ts b/tests/cases/compiler/es2017basicAsync.ts similarity index 97% rename from tests/cases/compiler/es8-async.ts rename to tests/cases/compiler/es2017basicAsync.ts index 0ceb6e397e..b13a5d29bc 100644 --- a/tests/cases/compiler/es8-async.ts +++ b/tests/cases/compiler/es2017basicAsync.ts @@ -1,4 +1,4 @@ -// @target: es8 +// @target: es2017 // @lib: es2017 // @noEmitHelpers: true From 994dae70f065edd683b1c943fbd3c911c83dad57 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Wed, 12 Oct 2016 12:28:15 -0700 Subject: [PATCH 24/80] Move import/export elision to ts transform --- src/compiler/core.ts | 13 +- src/compiler/factory.ts | 26 +-- src/compiler/transformers/module/es6.ts | 115 +----------- src/compiler/transformers/module/module.ts | 43 +++-- src/compiler/transformers/module/system.ts | 31 ++-- src/compiler/transformers/ts.ts | 165 +++++++++++++++++- src/compiler/utilities.ts | 29 ++- .../reference/declareModifierOnImport1.js | 1 + ...ndingFollowedWithNamespaceBinding1InEs5.js | 2 +- ...FollowedWithNamespaceBinding1WithExport.js | 1 - ...tBindingFollowedWithNamespaceBindingDts.js | 2 +- ...BindingFollowedWithNamespaceBindingDts1.js | 1 - ...indingFollowedWithNamespaceBindingInEs5.js | 2 +- ...gFollowedWithNamespaceBindingWithExport.js | 2 +- .../importDeclWithDeclareModifier.js | 1 + ...ler-options module-kind is out-of-range.js | 1 + ...r-options target-script is out-of-range.js | 1 + .../reference/typeAliasDeclarationEmit.js | 1 + .../reference/typeAliasDeclarationEmit2.js | 1 + 19 files changed, 251 insertions(+), 187 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 7c68306211..4fb0b4d651 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -399,6 +399,17 @@ namespace ts { return result; } + export function some(array: T[], predicate?: (value: T) => boolean): boolean { + if (array) { + for (const v of array) { + if (!predicate || predicate(v)) { + return true; + } + } + } + return false; + } + export function concatenate(array1: T[], array2: T[]): T[] { if (!array2 || !array2.length) return array1; if (!array1 || !array1.length) return array2; @@ -1177,7 +1188,7 @@ namespace ts { /** * Returns the path except for its basename. Eg: - * + * * /path/to/file.ext -> /path/to */ export function getDirectoryPath(path: Path): Path; diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 97a36f46b1..582f82315d 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -2206,7 +2206,7 @@ namespace ts { * @param visitor: Optional callback used to visit any custom prologue directives. */ export function addPrologueDirectives(target: Statement[], source: Statement[], ensureUseStrict?: boolean, visitor?: (node: Node) => VisitResult): number { - Debug.assert(target.length === 0, "PrologueDirectives should be at the first statement in the target statements array"); + Debug.assert(target.length === 0, "Prologue directives should be at the first statement in the target statements array"); let foundUseStrict = false; let statementOffset = 0; const numStatements = source.length; @@ -2219,16 +2219,20 @@ namespace ts { target.push(statement); } else { - if (ensureUseStrict && !foundUseStrict) { - target.push(startOnNewLine(createStatement(createLiteral("use strict")))); - foundUseStrict = true; - } - if (getEmitFlags(statement) & EmitFlags.CustomPrologue) { - target.push(visitor ? visitNode(statement, visitor, isStatement) : statement); - } - else { - break; - } + break; + } + statementOffset++; + } + if (ensureUseStrict && !foundUseStrict) { + target.push(startOnNewLine(createStatement(createLiteral("use strict")))); + } + while (statementOffset < numStatements) { + const statement = source[statementOffset]; + if (getEmitFlags(statement) & EmitFlags.CustomPrologue) { + target.push(visitor ? visitNode(statement, visitor, isStatement) : statement); + } + else { + break; } statementOffset++; } diff --git a/src/compiler/transformers/module/es6.ts b/src/compiler/transformers/module/es6.ts index 09a2890727..9eac37bee2 100644 --- a/src/compiler/transformers/module/es6.ts +++ b/src/compiler/transformers/module/es6.ts @@ -5,10 +5,6 @@ namespace ts { export function transformES6Module(context: TransformationContext) { const compilerOptions = context.getCompilerOptions(); - const resolver = context.getEmitResolver(); - - let currentSourceFile: SourceFile; - return transformSourceFile; function transformSourceFile(node: SourceFile) { @@ -17,128 +13,31 @@ namespace ts { } if (isExternalModule(node) || compilerOptions.isolatedModules) { - currentSourceFile = node; return visitEachChild(node, visitor, context); } + return node; } function visitor(node: Node): VisitResult { switch (node.kind) { - case SyntaxKind.ImportDeclaration: - return visitImportDeclaration(node); case SyntaxKind.ImportEqualsDeclaration: return visitImportEqualsDeclaration(node); - case SyntaxKind.ImportClause: - return visitImportClause(node); - case SyntaxKind.NamedImports: - case SyntaxKind.NamespaceImport: - return visitNamedBindings(node); - case SyntaxKind.ImportSpecifier: - return visitImportSpecifier(node); case SyntaxKind.ExportAssignment: return visitExportAssignment(node); - case SyntaxKind.ExportDeclaration: - return visitExportDeclaration(node); - case SyntaxKind.NamedExports: - return visitNamedExports(node); - case SyntaxKind.ExportSpecifier: - return visitExportSpecifier(node); } return node; } - function visitExportAssignment(node: ExportAssignment): ExportAssignment { - if (node.isExportEquals) { - return undefined; // do not emit export equals for ES6 - } - const original = getOriginalNode(node); - return nodeIsSynthesized(original) || resolver.isValueAliasDeclaration(original) ? node : undefined; + function visitImportEqualsDeclaration(node: ImportEqualsDeclaration): VisitResult { + // Elide `import=` as it is not legal with --module ES6 + return undefined; } - function visitExportDeclaration(node: ExportDeclaration): ExportDeclaration { - if (!node.exportClause) { - return resolver.moduleExportsSomeValue(node.moduleSpecifier) ? node : undefined; - } - if (!resolver.isValueAliasDeclaration(node)) { - return undefined; - } - const newExportClause = visitNode(node.exportClause, visitor, isNamedExports, /*optional*/ true); - if (node.exportClause === newExportClause) { - return node; - } - return newExportClause - ? createExportDeclaration( - /*decorators*/ undefined, - /*modifiers*/ undefined, - newExportClause, - node.moduleSpecifier) - : undefined; - } - - function visitNamedExports(node: NamedExports): NamedExports { - const newExports = visitNodes(node.elements, visitor, isExportSpecifier); - if (node.elements === newExports) { - return node; - } - return newExports.length ? createNamedExports(newExports) : undefined; - } - - function visitExportSpecifier(node: ExportSpecifier): ExportSpecifier { - return resolver.isValueAliasDeclaration(node) ? node : undefined; - } - - function visitImportEqualsDeclaration(node: ImportEqualsDeclaration): ImportEqualsDeclaration { - return !isExternalModuleImportEqualsDeclaration(node) || resolver.isReferencedAliasDeclaration(node) ? node : undefined; - } - - function visitImportDeclaration(node: ImportDeclaration) { - if (node.importClause) { - const newImportClause = visitNode(node.importClause, visitor, isImportClause); - if (!newImportClause.name && !newImportClause.namedBindings) { - return undefined; - } - else if (newImportClause !== node.importClause) { - return createImportDeclaration( - /*decorators*/ undefined, - /*modifiers*/ undefined, - newImportClause, - node.moduleSpecifier); - } - } - return node; - } - - function visitImportClause(node: ImportClause): ImportClause { - let newDefaultImport = node.name; - if (!resolver.isReferencedAliasDeclaration(node)) { - newDefaultImport = undefined; - } - const newNamedBindings = visitNode(node.namedBindings, visitor, isNamedImportBindings, /*optional*/ true); - return newDefaultImport !== node.name || newNamedBindings !== node.namedBindings - ? createImportClause(newDefaultImport, newNamedBindings) - : node; - } - - function visitNamedBindings(node: NamedImportBindings): VisitResult { - if (node.kind === SyntaxKind.NamespaceImport) { - return resolver.isReferencedAliasDeclaration(node) ? node : undefined; - } - else { - const newNamedImportElements = visitNodes((node).elements, visitor, isImportSpecifier); - if (!newNamedImportElements || newNamedImportElements.length == 0) { - return undefined; - } - if (newNamedImportElements === (node).elements) { - return node; - } - return createNamedImports(newNamedImportElements); - } - } - - function visitImportSpecifier(node: ImportSpecifier) { - return resolver.isReferencedAliasDeclaration(node) ? node : undefined; + function visitExportAssignment(node: ExportAssignment): VisitResult { + // Elide `export=` as it is not legal with --module ES6 + return node.isExportEquals ? undefined : node; } } } \ No newline at end of file diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index 516ed5433b..9485261603 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -59,7 +59,7 @@ namespace ts { currentSourceFile = node; // Collect information about the external module. - ({ externalImports, exportSpecifiers, exportEquals, hasExportStarsToExportValues } = collectExternalModuleInfo(node, resolver)); + ({ externalImports, exportSpecifiers, exportEquals, hasExportStarsToExportValues } = collectExternalModuleInfo(node)); // Perform the transformation. const transformModule = transformModuleDelegates[moduleKind] || transformModuleDelegates[ModuleKind.None]; @@ -228,7 +228,7 @@ namespace ts { } function addExportEqualsIfNeeded(statements: Statement[], emitAsReturn: boolean) { - if (exportEquals && resolver.isValueAliasDeclaration(exportEquals)) { + if (exportEquals) { if (emitAsReturn) { const statement = createReturn( exportEquals.expression, @@ -461,23 +461,21 @@ namespace ts { ); } for (const specifier of node.exportClause.elements) { - if (resolver.isValueAliasDeclaration(specifier)) { - const exportedValue = createPropertyAccess( - generatedName, - specifier.propertyName || specifier.name - ); - statements.push( - createStatement( - createExportAssignment(specifier.name, exportedValue), - /*location*/ specifier - ) - ); - } + const exportedValue = createPropertyAccess( + generatedName, + specifier.propertyName || specifier.name + ); + statements.push( + createStatement( + createExportAssignment(specifier.name, exportedValue), + /*location*/ specifier + ) + ); } return singleOrMany(statements); } - else if (resolver.moduleExportsSomeValue(node.moduleSpecifier)) { + else { // export * from "mod"; return createStatement( createCall( @@ -495,15 +493,14 @@ namespace ts { } function visitExportAssignment(node: ExportAssignment): VisitResult { - if (!node.isExportEquals) { - if (nodeIsSynthesized(node) || resolver.isValueAliasDeclaration(node)) { - const statements: Statement[] = []; - addExportDefault(statements, node.expression, /*location*/ node); - return statements; - } + if (node.isExportEquals) { + // Elide as `export=` is handled in addExportEqualsIfNeeded + return undefined; } - return undefined; + const statements: Statement[] = []; + addExportDefault(statements, node.expression, /*location*/ node); + return statements; } function addExportDefault(statements: Statement[], expression: Expression, location: TextRange): void { @@ -568,7 +565,7 @@ namespace ts { } function collectExportMembers(names: Identifier[], node: Node): Identifier[] { - if (isAliasSymbolDeclaration(node) && resolver.isValueAliasDeclaration(node) && isDeclaration(node)) { + if (isAliasSymbolDeclaration(node) && isDeclaration(node)) { const name = node.name; if (isIdentifier(name)) { names.push(name); diff --git a/src/compiler/transformers/module/system.ts b/src/compiler/transformers/module/system.ts index 303c0e1bb9..0bb188eb39 100644 --- a/src/compiler/transformers/module/system.ts +++ b/src/compiler/transformers/module/system.ts @@ -91,7 +91,7 @@ namespace ts { Debug.assert(!exportFunctionForFile); // Collect information about the external module and dependency groups. - ({ externalImports, exportSpecifiers, exportEquals, hasExportStarsToExportValues } = collectExternalModuleInfo(node, resolver)); + ({ externalImports, exportSpecifiers, exportEquals, hasExportStarsToExportValues } = collectExternalModuleInfo(node)); // Make sure that the name of the 'exports' function does not conflict with // existing identifiers. @@ -573,28 +573,23 @@ namespace ts { } function visitExportSpecifier(specifier: ExportSpecifier): Statement { - if (resolver.getReferencedValueDeclaration(specifier.propertyName || specifier.name) - || resolver.isValueAliasDeclaration(specifier)) { - recordExportName(specifier.name); - return createExportStatement( - specifier.name, - specifier.propertyName || specifier.name - ); - } - return undefined; + recordExportName(specifier.name); + return createExportStatement( + specifier.name, + specifier.propertyName || specifier.name + ); } function visitExportAssignment(node: ExportAssignment): Statement { - if (!node.isExportEquals) { - if (nodeIsSynthesized(node) || resolver.isValueAliasDeclaration(node)) { - return createExportStatement( - createLiteral("default"), - node.expression - ); - } + if (node.isExportEquals) { + // Elide `export=` as it is illegal in a SystemJS module. + return undefined; } - return undefined; + return createExportStatement( + createLiteral("default"), + node.expression + ); } /** diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 41f03d20f2..3c87036621 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -147,6 +147,35 @@ namespace ts { return node; } + /** + * Specialized visitor that visits the immediate children of a SourceFile. + * + * @param node The node to visit. + */ + function sourceElementVisitor(node: Node): VisitResult { + return saveStateAndInvoke(node, sourceElementVisitorWorker); + } + + /** + * Specialized visitor that visits the immediate children of a SourceFile. + * + * @param node The node to visit. + */ + function sourceElementVisitorWorker(node: Node): VisitResult { + switch (node.kind) { + case SyntaxKind.ImportDeclaration: + return visitImportDeclaration(node); + case SyntaxKind.ImportEqualsDeclaration: + return visitImportEqualsDeclaration(node); + case SyntaxKind.ExportAssignment: + return visitExportAssignment(node); + case SyntaxKind.ExportDeclaration: + return visitExportDeclaration(node); + default: + return visitorWorker(node); + } + } + /** * Specialized visitor that visits the immediate children of a namespace. * @@ -457,7 +486,7 @@ namespace ts { statements.push(externalHelpersModuleImport); currentSourceFileExternalHelpersModuleName = externalHelpersModuleName; - addRange(statements, visitNodes(node.statements, visitor, isStatement, statementOffset)); + addRange(statements, visitNodes(node.statements, sourceElementVisitor, isStatement, statementOffset)); addRange(statements, endLexicalEnvironment()); currentSourceFileExternalHelpersModuleName = undefined; @@ -465,7 +494,7 @@ namespace ts { node.externalHelpersModuleName = externalHelpersModuleName; } else { - node = visitEachChild(node, visitor, context); + node = visitEachChild(node, sourceElementVisitor, context); } setEmitFlags(node, EmitFlags.EmitEmitHelpers | getEmitFlags(node)); @@ -2993,6 +3022,133 @@ namespace ts { } } + /** + * Visits an import declaration, eliding it if it is not referenced. + * + * @param node The import declaration node. + */ + function visitImportDeclaration(node: ImportDeclaration): VisitResult { + if (!node.importClause) { + // Do not elide a side-effect only import declaration. + // import "foo"; + return node; + } + + // Elide the declaration if the import clause was elided. + const importClause = visitNode(node.importClause, visitImportClause, isImportClause, /*optional*/ true); + return importClause + ? updateImportDeclaration( + node, + /*decorators*/ undefined, + /*modifiers*/ undefined, + importClause, + node.moduleSpecifier) + : undefined; + } + + /** + * Visits an import clause, eliding it if it is not referenced. + * + * @param node The import clause node. + */ + function visitImportClause(node: ImportClause): VisitResult { + // Elide the import clause if we elide both its name and its named bindings. + const name = resolver.isReferencedAliasDeclaration(node) ? node.name : undefined; + const namedBindings = visitNode(node.namedBindings, visitNamedImportBindings, isNamedImportBindings, /*optional*/ true); + return (name || namedBindings) ? updateImportClause(node, name, namedBindings) : undefined; + } + + /** + * Visits named import bindings, eliding it if it is not referenced. + * + * @param node The named import bindings node. + */ + function visitNamedImportBindings(node: NamedImportBindings): VisitResult { + if (node.kind === SyntaxKind.NamespaceImport) { + // Elide a namespace import if it is not referenced. + return resolver.isReferencedAliasDeclaration(node) ? node : undefined; + } + else { + // Elide named imports if all of its import specifiers are elided. + const elements = visitNodes(node.elements, visitImportSpecifier, isImportSpecifier); + return some(elements) ? updateNamedImports(node, elements) : undefined; + } + } + + /** + * Visits an import specifier, eliding it if it is not referenced. + * + * @param node The import specifier node. + */ + function visitImportSpecifier(node: ImportSpecifier): VisitResult { + // Elide an import specifier if it is not referenced. + return resolver.isReferencedAliasDeclaration(node) ? node : undefined; + } + + /** + * Visits an export assignment, eliding it if it does not contain a clause that resolves + * to a value. + * + * @param node The export assignment node. + */ + function visitExportAssignment(node: ExportAssignment): VisitResult { + // Elide the export assignment if it does not reference a value. + return resolver.isValueAliasDeclaration(node) + ? visitEachChild(node, visitor, context) + : undefined; + } + + /** + * Visits an export declaration, eliding it if it does not contain a clause that resolves + * to a value. + * + * @param node The export declaration node. + */ + function visitExportDeclaration(node: ExportDeclaration): VisitResult { + if (!node.exportClause) { + // Elide a star export if the module it references does not export a value. + return resolver.moduleExportsSomeValue(node.moduleSpecifier) ? node : undefined; + } + + if (!resolver.isValueAliasDeclaration(node)) { + // Elide the export declaration if it does not export a value. + return undefined; + } + + // Elide the export declaration if all of its named exports are elided. + const exportClause = visitNode(node.exportClause, visitNamedExports, isNamedExports, /*optional*/ true); + return exportClause + ? updateExportDeclaration( + node, + /*decorators*/ undefined, + /*modifiers*/ undefined, + exportClause, + node.moduleSpecifier) + : undefined; + } + + /** + * Visits named exports, eliding it if it does not contain an export specifier that + * resolves to a value. + * + * @param node The named exports node. + */ + function visitNamedExports(node: NamedExports): VisitResult { + // Elide the named exports if all of its export specifiers were elided. + const elements = visitNodes(node.elements, visitExportSpecifier, isExportSpecifier); + return some(elements) ? updateNamedExports(node, elements) : undefined; + } + + /** + * Visits an export specifier, eliding it if it does not resolve to a value. + * + * @param node The export specifier node. + */ + function visitExportSpecifier(node: ExportSpecifier): VisitResult { + // Elide an export specifier if it does not reference a value. + return resolver.isValueAliasDeclaration(node) ? node : undefined; + } + /** * Determines whether to emit an import equals declaration. * @@ -3014,7 +3170,10 @@ namespace ts { */ function visitImportEqualsDeclaration(node: ImportEqualsDeclaration): VisitResult { if (isExternalModuleImportEqualsDeclaration(node)) { - return visitEachChild(node, visitor, context); + // Elide external module `import=` if it is not referenced. + return resolver.isReferencedAliasDeclaration(node) + ? visitEachChild(node, visitor, context) + : undefined; } if (!shouldEmitImportEqualsDeclaration(node)) { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 558015bb0e..eee79894a0 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -3496,7 +3496,7 @@ namespace ts { return positionIsSynthesized(range.pos) ? -1 : skipTrivia(sourceFile.text, range.pos); } - export function collectExternalModuleInfo(sourceFile: SourceFile, resolver: EmitResolver) { + export function collectExternalModuleInfo(sourceFile: SourceFile) { const externalImports: (ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration)[] = []; const exportSpecifiers = createMap(); let exportEquals: ExportAssignment = undefined; @@ -3504,19 +3504,16 @@ namespace ts { for (const node of sourceFile.statements) { switch (node.kind) { case SyntaxKind.ImportDeclaration: - if (!(node).importClause || - resolver.isReferencedAliasDeclaration((node).importClause, /*checkChildren*/ true)) { - // import "mod" - // import x from "mod" where x is referenced - // import * as x from "mod" where x is referenced - // import { x, y } from "mod" where at least one import is referenced - externalImports.push(node); - } + // import "mod" + // import x from "mod" + // import * as x from "mod" + // import { x, y } from "mod" + externalImports.push(node); break; case SyntaxKind.ImportEqualsDeclaration: - if ((node).moduleReference.kind === SyntaxKind.ExternalModuleReference && resolver.isReferencedAliasDeclaration(node)) { - // import x = require("mod") where x is referenced + if ((node).moduleReference.kind === SyntaxKind.ExternalModuleReference) { + // import x = require("mod") externalImports.push(node); } break; @@ -3525,13 +3522,11 @@ namespace ts { if ((node).moduleSpecifier) { if (!(node).exportClause) { // export * from "mod" - if (resolver.moduleExportsSomeValue((node).moduleSpecifier)) { - externalImports.push(node); - hasExportStarsToExportValues = true; - } + externalImports.push(node); + hasExportStarsToExportValues = true; } - else if (resolver.isValueAliasDeclaration(node)) { - // export { x, y } from "mod" where at least one export is a value symbol + else { + // export { x, y } from "mod" externalImports.push(node); } } diff --git a/tests/baselines/reference/declareModifierOnImport1.js b/tests/baselines/reference/declareModifierOnImport1.js index 510407b4de..3dc3601d47 100644 --- a/tests/baselines/reference/declareModifierOnImport1.js +++ b/tests/baselines/reference/declareModifierOnImport1.js @@ -2,3 +2,4 @@ declare import a = b; //// [declareModifierOnImport1.js] +var a = b; diff --git a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBinding1InEs5.js b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBinding1InEs5.js index d62cfbc287..0a0e028b69 100644 --- a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBinding1InEs5.js +++ b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBinding1InEs5.js @@ -16,7 +16,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.default = a; //// [es6ImportDefaultBindingFollowedWithNamespaceBindingInEs5_1.js] "use strict"; -var es6ImportDefaultBindingFollowedWithNamespaceBindingInEs5_0_1 = require("./es6ImportDefaultBindingFollowedWithNamespaceBindingInEs5_0"), nameSpaceBinding = es6ImportDefaultBindingFollowedWithNamespaceBindingInEs5_0_1; +var es6ImportDefaultBindingFollowedWithNamespaceBindingInEs5_0_1 = require("./es6ImportDefaultBindingFollowedWithNamespaceBindingInEs5_0"); var x = es6ImportDefaultBindingFollowedWithNamespaceBindingInEs5_0_1.default; diff --git a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBinding1WithExport.js b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBinding1WithExport.js index c19f68463f..5f2cb4e97e 100644 --- a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBinding1WithExport.js +++ b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBinding1WithExport.js @@ -19,7 +19,6 @@ define(["require", "exports"], function (require, exports) { //// [client.js] define(["require", "exports", "server"], function (require, exports, server_1) { "use strict"; - var nameSpaceBinding = server_1; exports.x = server_1.default; }); diff --git a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBindingDts.js b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBindingDts.js index 20abd2e613..60bdc65484 100644 --- a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBindingDts.js +++ b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBindingDts.js @@ -18,7 +18,7 @@ var a = (function () { exports.a = a; //// [client.js] "use strict"; -var server_1 = require("./server"), nameSpaceBinding = server_1; +var nameSpaceBinding = require("./server"); exports.x = new nameSpaceBinding.a(); diff --git a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBindingDts1.js b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBindingDts1.js index 5a2f1f3529..8752157edd 100644 --- a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBindingDts1.js +++ b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBindingDts1.js @@ -23,7 +23,6 @@ define(["require", "exports"], function (require, exports) { //// [client.js] define(["require", "exports", "server"], function (require, exports, server_1) { "use strict"; - var nameSpaceBinding = server_1; exports.x = new server_1.default(); }); diff --git a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBindingInEs5.js b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBindingInEs5.js index 2639291d85..9d11e15475 100644 --- a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBindingInEs5.js +++ b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBindingInEs5.js @@ -13,7 +13,7 @@ var x: number = nameSpaceBinding.a; exports.a = 10; //// [es6ImportDefaultBindingFollowedWithNamespaceBindingInEs5_1.js] "use strict"; -var es6ImportDefaultBindingFollowedWithNamespaceBindingInEs5_0_1 = require("./es6ImportDefaultBindingFollowedWithNamespaceBindingInEs5_0"), nameSpaceBinding = es6ImportDefaultBindingFollowedWithNamespaceBindingInEs5_0_1; +var nameSpaceBinding = require("./es6ImportDefaultBindingFollowedWithNamespaceBindingInEs5_0"); var x = nameSpaceBinding.a; diff --git a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBindingWithExport.js b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBindingWithExport.js index f417a086df..e16ebf9995 100644 --- a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBindingWithExport.js +++ b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBindingWithExport.js @@ -13,7 +13,7 @@ export var x: number = nameSpaceBinding.a; exports.a = 10; //// [client.js] "use strict"; -var server_1 = require("./server"), nameSpaceBinding = server_1; +var nameSpaceBinding = require("./server"); exports.x = nameSpaceBinding.a; diff --git a/tests/baselines/reference/importDeclWithDeclareModifier.js b/tests/baselines/reference/importDeclWithDeclareModifier.js index e5267678a4..7c3d378293 100644 --- a/tests/baselines/reference/importDeclWithDeclareModifier.js +++ b/tests/baselines/reference/importDeclWithDeclareModifier.js @@ -9,4 +9,5 @@ var b: a; //// [importDeclWithDeclareModifier.js] "use strict"; +exports.a = x.c; var b; diff --git a/tests/baselines/reference/transpile/Report an error when compiler-options module-kind is out-of-range.js b/tests/baselines/reference/transpile/Report an error when compiler-options module-kind is out-of-range.js index c7570e8119..1ceb1bcd14 100644 --- a/tests/baselines/reference/transpile/Report an error when compiler-options module-kind is out-of-range.js +++ b/tests/baselines/reference/transpile/Report an error when compiler-options module-kind is out-of-range.js @@ -1 +1,2 @@ +"use strict"; //# sourceMappingURL=file.js.map \ No newline at end of file diff --git a/tests/baselines/reference/transpile/Report an error when compiler-options target-script is out-of-range.js b/tests/baselines/reference/transpile/Report an error when compiler-options target-script is out-of-range.js index c7570e8119..1ceb1bcd14 100644 --- a/tests/baselines/reference/transpile/Report an error when compiler-options target-script is out-of-range.js +++ b/tests/baselines/reference/transpile/Report an error when compiler-options target-script is out-of-range.js @@ -1 +1,2 @@ +"use strict"; //# sourceMappingURL=file.js.map \ No newline at end of file diff --git a/tests/baselines/reference/typeAliasDeclarationEmit.js b/tests/baselines/reference/typeAliasDeclarationEmit.js index 6e82fe4b07..1f72e1d1b0 100644 --- a/tests/baselines/reference/typeAliasDeclarationEmit.js +++ b/tests/baselines/reference/typeAliasDeclarationEmit.js @@ -6,6 +6,7 @@ export type CallbackArray = () => T; //// [typeAliasDeclarationEmit.js] define(["require", "exports"], function (require, exports) { + "use strict"; }); diff --git a/tests/baselines/reference/typeAliasDeclarationEmit2.js b/tests/baselines/reference/typeAliasDeclarationEmit2.js index 4bb1bd3efd..b94eb56a2a 100644 --- a/tests/baselines/reference/typeAliasDeclarationEmit2.js +++ b/tests/baselines/reference/typeAliasDeclarationEmit2.js @@ -4,6 +4,7 @@ export type A = { value: a }; //// [typeAliasDeclarationEmit2.js] define(["require", "exports"], function (require, exports) { + "use strict"; }); From 5d52c9fd3b28b25d2752b5157bc51453187065c9 Mon Sep 17 00:00:00 2001 From: Andrej Baran Date: Wed, 12 Oct 2016 21:34:00 +0200 Subject: [PATCH 25/80] Move async/await into separate es2017 transformer --- Jakefile.js | 2 + src/compiler/binder.ts | 24 +- src/compiler/transformer.ts | 4 + src/compiler/transformers/es2017.ts | 544 ++++++++++++++++++ src/compiler/transformers/module/module.ts | 4 +- src/compiler/transformers/module/system.ts | 6 +- src/compiler/transformers/ts.ts | 238 +------- src/compiler/tsconfig.json | 1 + src/compiler/utilities.ts | 2 + src/harness/harness.ts | 2 + src/harness/tsconfig.json | 1 + src/services/tsconfig.json | 1 + .../{es8-async.js => es2017basicAsync.js} | 4 +- ...async.symbols => es2017basicAsync.symbols} | 22 +- ...es8-async.types => es2017basicAsync.types} | 2 +- 15 files changed, 614 insertions(+), 243 deletions(-) create mode 100644 src/compiler/transformers/es2017.ts rename tests/baselines/reference/{es8-async.js => es2017basicAsync.js} (94%) rename tests/baselines/reference/{es8-async.symbols => es2017basicAsync.symbols} (78%) rename tests/baselines/reference/{es8-async.types => es2017basicAsync.types} (94%) diff --git a/Jakefile.js b/Jakefile.js index ecbd0ae2be..8d46368653 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -74,6 +74,7 @@ var compilerSources = [ "transformers/module/system.ts", "transformers/module/module.ts", "transformers/jsx.ts", + "transformers/es2017.ts", "transformers/es2016.ts", "transformers/generators.ts", "transformers/es6.ts", @@ -108,6 +109,7 @@ var servicesSources = [ "transformers/module/system.ts", "transformers/module/module.ts", "transformers/jsx.ts", + "transformers/es2017.ts", "transformers/es2016.ts", "transformers/generators.ts", "transformers/es6.ts", diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index ce482dcdfd..4edbb5d9e1 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -2555,6 +2555,11 @@ namespace ts { // extends clause of a class. let transformFlags = subtreeFlags | TransformFlags.AssertES6; + // propagate ES2017 + if (node.expression.transformFlags & TransformFlags.ContainsES2017) { + transformFlags |= TransformFlags.ContainsES2017; + } + // If an ExpressionWithTypeArguments contains type arguments, then it // is TypeScript syntax. if (node.typeArguments) { @@ -2595,6 +2600,11 @@ namespace ts { transformFlags |= TransformFlags.AssertTypeScript; } + // Async MethodDeclaration is ES2017 + if (modifierFlags & ModifierFlags.Async) { + transformFlags |= TransformFlags.AssertES2017; + } + // Currently, we only support generators that were originally async function bodies. if (asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) { transformFlags |= TransformFlags.AssertGenerator; @@ -2656,7 +2666,7 @@ namespace ts { // If a FunctionDeclaration is async, then it is TypeScript syntax. if (modifierFlags & ModifierFlags.Async) { - transformFlags |= TransformFlags.AssertTypeScript; + transformFlags |= TransformFlags.AssertTypeScript | TransformFlags.AssertES2017; } // If a FunctionDeclaration's subtree has marked the container as needing to capture the @@ -2687,7 +2697,7 @@ namespace ts { // An async function expression is TypeScript syntax. if (modifierFlags & ModifierFlags.Async) { - transformFlags |= TransformFlags.AssertTypeScript; + transformFlags |= TransformFlags.AssertTypeScript | TransformFlags.AssertES2017; } // If a FunctionExpression's subtree has marked the container as needing to capture the @@ -2717,7 +2727,7 @@ namespace ts { // An async arrow function is TypeScript syntax. if (modifierFlags & ModifierFlags.Async) { - transformFlags |= TransformFlags.AssertTypeScript; + transformFlags |= TransformFlags.AssertTypeScript | TransformFlags.AssertES2017; } // If an ArrowFunction contains a lexical this, its container must capture the lexical this. @@ -2856,14 +2866,18 @@ namespace ts { let excludeFlags = TransformFlags.NodeExcludes; switch (kind) { + case SyntaxKind.AsyncKeyword: + case SyntaxKind.AwaitExpression: + // Typescript async/await are ES2017 features + transformFlags |= TransformFlags.AssertTypeScript | TransformFlags.AssertES2017; + break; + case SyntaxKind.PublicKeyword: case SyntaxKind.PrivateKeyword: case SyntaxKind.ProtectedKeyword: case SyntaxKind.AbstractKeyword: case SyntaxKind.DeclareKeyword: - case SyntaxKind.AsyncKeyword: case SyntaxKind.ConstKeyword: - case SyntaxKind.AwaitExpression: case SyntaxKind.EnumDeclaration: case SyntaxKind.EnumMember: case SyntaxKind.TypeAssertionExpression: diff --git a/src/compiler/transformer.ts b/src/compiler/transformer.ts index 9e54826805..55b83ea669 100644 --- a/src/compiler/transformer.ts +++ b/src/compiler/transformer.ts @@ -1,6 +1,7 @@ /// /// /// +/// /// /// /// @@ -115,6 +116,9 @@ namespace ts { transformers.push(transformJsx); } + if (languageVersion < ScriptTarget.ES2017) { + transformers.push(transformES2017); + } if (languageVersion < ScriptTarget.ES2016) { transformers.push(transformES2016); diff --git a/src/compiler/transformers/es2017.ts b/src/compiler/transformers/es2017.ts new file mode 100644 index 0000000000..33376bbceb --- /dev/null +++ b/src/compiler/transformers/es2017.ts @@ -0,0 +1,544 @@ +/// +/// + +/*@internal*/ +namespace ts { + type SuperContainer = ClassDeclaration | MethodDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | ConstructorDeclaration; + + export function transformES2017(context: TransformationContext) { + + const enum ES2017SubstitutionFlags { + /** Enables substitutions for async methods with `super` calls. */ + AsyncMethodsWithSuper = 1 << 0 + } + + const { + startLexicalEnvironment, + endLexicalEnvironment, + } = context; + + const resolver = context.getEmitResolver(); + const compilerOptions = context.getCompilerOptions(); + const languageVersion = getEmitScriptTarget(compilerOptions); + + // These variables contain state that changes as we descend into the tree. + let currentSourceFileExternalHelpersModuleName: Identifier; + /** + * Keeps track of whether expression substitution has been enabled for specific edge cases. + * They are persisted between each SourceFile transformation and should not be reset. + */ + let enabledSubstitutions: ES2017SubstitutionFlags; + + /** + * Keeps track of whether we are within any containing namespaces when performing + * just-in-time substitution while printing an expression identifier. + */ + let applicableSubstitutions: ES2017SubstitutionFlags; + + /** + * This keeps track of containers where `super` is valid, for use with + * just-in-time substitution for `super` expressions inside of async methods. + */ + let currentSuperContainer: SuperContainer; + + // Save the previous transformation hooks. + const previousOnEmitNode = context.onEmitNode; + const previousOnSubstituteNode = context.onSubstituteNode; + + // Set new transformation hooks. + context.onEmitNode = onEmitNode; + context.onSubstituteNode = onSubstituteNode; + + let currentScope: SourceFile | Block | ModuleBlock | CaseBlock; + + return transformSourceFile; + + function transformSourceFile(node: SourceFile) { + if (isDeclarationFile(node)) { + return node; + } + + currentSourceFileExternalHelpersModuleName = node.externalHelpersModuleName; + + return visitEachChild(node, visitor, context); + } + + function visitor(node: Node): VisitResult { + if (node.transformFlags & TransformFlags.ES2017) { + return visitorWorker(node); + } + else if (node.transformFlags & TransformFlags.ContainsES2017) { + return visitEachChild(node, visitor, context); + } + + // node = visitEachChild(node, visitor, context); + // return visitEachChild(node, visitor, context); + return node; + } + + function visitorWorker(node: Node): VisitResult { + switch (node.kind) { + case SyntaxKind.AsyncKeyword: + return undefined; + + case SyntaxKind.AwaitExpression: + // Typescript 'await' expressions must be transformed for targets < ES2017. + return visitAwaitExpression(node); + + case SyntaxKind.MethodDeclaration: + // TypeScript method declarations may be 'async' + return visitMethodDeclaration(node); + + case SyntaxKind.FunctionDeclaration: + // TypeScript function declarations may be 'async' + return visitFunctionDeclaration(node); + + case SyntaxKind.FunctionExpression: + // TypeScript function expressions may be 'async' + return visitFunctionExpression(node); + + case SyntaxKind.ArrowFunction: + // TypeScript arrow functions may be 'async' + return visitArrowFunction(node); + + default: + Debug.failBadSyntaxKind(node); + return node; + } + } + + /** + * Visits an await expression. + * + * This function will be called any time a ES2017 await expression is encountered. + * + * @param node The await expression node. + */ + function visitAwaitExpression(node: AwaitExpression): Expression { + return setOriginalNode( + createYield( + /*asteriskToken*/ undefined, + visitNode(node.expression, visitor, isExpression), + /*location*/ node + ), + node + ); + } + + /** + * Visits a method declaration of a class. + * + * This function will be called when one of the following conditions are met: + * - The node is marked as async + * + * @param node The method node. + */ + function visitMethodDeclaration(node: MethodDeclaration) { + if (!isAsyncFunctionLike(node)) { + return node; + } + const method = createMethod( + /*decorators*/ undefined, + visitNodes(node.modifiers, visitor, isModifier), + node.asteriskToken, + node.name, + /*typeParameters*/ undefined, + visitNodes(node.parameters, visitor, isParameter), + /*type*/ undefined, + transformFunctionBody(node), + /*location*/ node + ); + + // While we emit the source map for the node after skipping decorators and modifiers, + // we need to emit the comments for the original range. + setCommentRange(method, node); + setSourceMapRange(method, moveRangePastDecorators(node)); + setOriginalNode(method, node); + + return method; + } + + /** + * Visits a function declaration. + * + * This function will be called when one of the following conditions are met: + * - The node is an overload + * - The node is marked async + * - The node is exported from a TypeScript namespace + * + * @param node The function node. + */ + function visitFunctionDeclaration(node: FunctionDeclaration): VisitResult { + if (!isAsyncFunctionLike(node)) { + return node; + } + const func = createFunctionDeclaration( + /*decorators*/ undefined, + visitNodes(node.modifiers, visitor, isModifier), + node.asteriskToken, + node.name, + /*typeParameters*/ undefined, + visitNodes(node.parameters, visitor, isParameter), + /*type*/ undefined, + transformFunctionBody(node), + /*location*/ node + ); + setOriginalNode(func, node); + + return func; + } + + /** + * Visits a function expression node. + * + * This function will be called when one of the following conditions are met: + * - The node is marked async + * + * @param node The function expression node. + */ + function visitFunctionExpression(node: FunctionExpression): Expression { + if (!isAsyncFunctionLike(node)) { + return node; + } + if (nodeIsMissing(node.body)) { + return createOmittedExpression(); + } + + const func = createFunctionExpression( + node.asteriskToken, + node.name, + /*typeParameters*/ undefined, + visitNodes(node.parameters, visitor, isParameter), + /*type*/ undefined, + transformFunctionBody(node), + /*location*/ node + ); + + node.modifiers = visitNodes(node.modifiers, visitor, isModifier); + + setOriginalNode(func, node); + + return func; + } + + /** + * @remarks + * This function will be called when one of the following conditions are met: + * - The node is marked async + */ + function visitArrowFunction(node: ArrowFunction) { + if (!isAsyncFunctionLike(node)) { + return node; + } + const func = createArrowFunction( + visitNodes(node.modifiers, visitor, isModifier), + /*typeParameters*/ undefined, + visitNodes(node.parameters, visitor, isParameter), + /*type*/ undefined, + node.equalsGreaterThanToken, + transformConciseBody(node), + /*location*/ node + ); + + setOriginalNode(func, node); + + return func; + } + + function transformFunctionBody(node: MethodDeclaration | AccessorDeclaration | FunctionDeclaration | FunctionExpression): FunctionBody { + return transformAsyncFunctionBody(node); + } + + function transformConciseBody(node: ArrowFunction): ConciseBody { + return transformAsyncFunctionBody(node); + } + + function transformFunctionBodyWorker(body: Block, start = 0) { + const savedCurrentScope = currentScope; + currentScope = body; + startLexicalEnvironment(); + + const statements = visitNodes(body.statements, visitor, isStatement, start); + const visited = updateBlock(body, statements); + const declarations = endLexicalEnvironment(); + currentScope = savedCurrentScope; + return mergeFunctionBodyLexicalEnvironment(visited, declarations); + } + + function transformAsyncFunctionBody(node: FunctionLikeDeclaration): ConciseBody | FunctionBody { + const nodeType = node.original ? (node.original).type : node.type; + const promiseConstructor = languageVersion < ScriptTarget.ES6 ? getPromiseConstructor(nodeType) : undefined; + const isArrowFunction = node.kind === SyntaxKind.ArrowFunction; + const hasLexicalArguments = (resolver.getNodeCheckFlags(node) & NodeCheckFlags.CaptureArguments) !== 0; + + // An async function is emit as an outer function that calls an inner + // generator function. To preserve lexical bindings, we pass the current + // `this` and `arguments` objects to `__awaiter`. The generator function + // passed to `__awaiter` is executed inside of the callback to the + // promise constructor. + + + if (!isArrowFunction) { + const statements: Statement[] = []; + const statementOffset = addPrologueDirectives(statements, (node.body).statements, /*ensureUseStrict*/ false, visitor); + statements.push( + createReturn( + createAwaiterHelper( + currentSourceFileExternalHelpersModuleName, + hasLexicalArguments, + promiseConstructor, + transformFunctionBodyWorker(node.body, statementOffset) + ) + ) + ); + + const block = createBlock(statements, /*location*/ node.body, /*multiLine*/ true); + + // Minor optimization, emit `_super` helper to capture `super` access in an arrow. + // This step isn't needed if we eventually transform this to ES5. + if (languageVersion >= ScriptTarget.ES6) { + if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.AsyncMethodWithSuperBinding) { + enableSubstitutionForAsyncMethodsWithSuper(); + setEmitFlags(block, EmitFlags.EmitAdvancedSuperHelper); + } + else if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.AsyncMethodWithSuper) { + enableSubstitutionForAsyncMethodsWithSuper(); + setEmitFlags(block, EmitFlags.EmitSuperHelper); + } + } + + return block; + } + else { + return createAwaiterHelper( + currentSourceFileExternalHelpersModuleName, + hasLexicalArguments, + promiseConstructor, + transformConciseBodyWorker(node.body, /*forceBlockFunctionBody*/ true) + ); + } + } + + function transformConciseBodyWorker(body: Block | Expression, forceBlockFunctionBody: boolean) { + if (isBlock(body)) { + return transformFunctionBodyWorker(body); + } + else { + startLexicalEnvironment(); + const visited: Expression | Block = visitNode(body, visitor, isConciseBody); + const declarations = endLexicalEnvironment(); + const merged = mergeFunctionBodyLexicalEnvironment(visited, declarations); + if (forceBlockFunctionBody && !isBlock(merged)) { + return createBlock([ + createReturn(merged) + ]); + } + else { + return merged; + } + } + } + + function getPromiseConstructor(type: TypeNode) { + const typeName = getEntityNameFromTypeNode(type); + if (typeName && isEntityName(typeName)) { + const serializationKind = resolver.getTypeReferenceSerializationKind(typeName); + if (serializationKind === TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue + || serializationKind === TypeReferenceSerializationKind.Unknown) { + return typeName; + } + } + + return undefined; + } + + function enableSubstitutionForAsyncMethodsWithSuper() { + if ((enabledSubstitutions & ES2017SubstitutionFlags.AsyncMethodsWithSuper) === 0) { + enabledSubstitutions |= ES2017SubstitutionFlags.AsyncMethodsWithSuper; + + // We need to enable substitutions for call, property access, and element access + // if we need to rewrite super calls. + context.enableSubstitution(SyntaxKind.CallExpression); + context.enableSubstitution(SyntaxKind.PropertyAccessExpression); + context.enableSubstitution(SyntaxKind.ElementAccessExpression); + + // We need to be notified when entering and exiting declarations that bind super. + context.enableEmitNotification(SyntaxKind.ClassDeclaration); + context.enableEmitNotification(SyntaxKind.MethodDeclaration); + context.enableEmitNotification(SyntaxKind.GetAccessor); + context.enableEmitNotification(SyntaxKind.SetAccessor); + context.enableEmitNotification(SyntaxKind.Constructor); + } + } + + function substituteExpression(node: Expression) { + switch (node.kind) { + case SyntaxKind.PropertyAccessExpression: + return substitutePropertyAccessExpression(node); + case SyntaxKind.ElementAccessExpression: + return substituteElementAccessExpression(node); + case SyntaxKind.CallExpression: + if (enabledSubstitutions & ES2017SubstitutionFlags.AsyncMethodsWithSuper) { + return substituteCallExpression(node); + } + break; + } + + return node; + } + + function substitutePropertyAccessExpression(node: PropertyAccessExpression) { + if (enabledSubstitutions & ES2017SubstitutionFlags.AsyncMethodsWithSuper && node.expression.kind === SyntaxKind.SuperKeyword) { + const flags = getSuperContainerAsyncMethodFlags(); + if (flags) { + return createSuperAccessInAsyncMethod( + createLiteral(node.name.text), + flags, + node + ); + } + } + + return substituteConstantValue(node); + } + + function substituteElementAccessExpression(node: ElementAccessExpression) { + if (enabledSubstitutions & ES2017SubstitutionFlags.AsyncMethodsWithSuper && node.expression.kind === SyntaxKind.SuperKeyword) { + const flags = getSuperContainerAsyncMethodFlags(); + if (flags) { + return createSuperAccessInAsyncMethod( + node.argumentExpression, + flags, + node + ); + } + } + + return substituteConstantValue(node); + } + + function substituteConstantValue(node: PropertyAccessExpression | ElementAccessExpression): LeftHandSideExpression { + const constantValue = tryGetConstEnumValue(node); + if (constantValue !== undefined) { + const substitute = createLiteral(constantValue); + setSourceMapRange(substitute, node); + setCommentRange(substitute, node); + if (!compilerOptions.removeComments) { + const propertyName = isPropertyAccessExpression(node) + ? declarationNameToString(node.name) + : getTextOfNode(node.argumentExpression); + substitute.trailingComment = ` ${propertyName} `; + } + + setConstantValue(node, constantValue); + return substitute; + } + + return node; + } + + function tryGetConstEnumValue(node: Node): number { + if (compilerOptions.isolatedModules) { + return undefined; + } + + return isPropertyAccessExpression(node) || isElementAccessExpression(node) + ? resolver.getConstantValue(node) + : undefined; + } + + function substituteCallExpression(node: CallExpression): Expression { + const expression = node.expression; + if (isSuperProperty(expression)) { + const flags = getSuperContainerAsyncMethodFlags(); + if (flags) { + const argumentExpression = isPropertyAccessExpression(expression) + ? substitutePropertyAccessExpression(expression) + : substituteElementAccessExpression(expression); + return createCall( + createPropertyAccess(argumentExpression, "call"), + /*typeArguments*/ undefined, + [ + createThis(), + ...node.arguments + ] + ); + } + } + return node; + } + + function isSuperContainer(node: Node): node is SuperContainer { + const kind = node.kind; + return kind === SyntaxKind.ClassDeclaration + || kind === SyntaxKind.Constructor + || kind === SyntaxKind.MethodDeclaration + || kind === SyntaxKind.GetAccessor + || kind === SyntaxKind.SetAccessor; + } + + /** + * Hook for node emit. + * + * @param node The node to emit. + * @param emit A callback used to emit the node in the printer. + */ + function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void { + const savedApplicableSubstitutions = applicableSubstitutions; + const savedCurrentSuperContainer = currentSuperContainer; + // If we need to support substitutions for `super` in an async method, + // we should track it here. + if (enabledSubstitutions & ES2017SubstitutionFlags.AsyncMethodsWithSuper && isSuperContainer(node)) { + currentSuperContainer = node; + } + + previousOnEmitNode(emitContext, node, emitCallback); + + applicableSubstitutions = savedApplicableSubstitutions; + currentSuperContainer = savedCurrentSuperContainer; + } + + /** + * Hooks node substitutions. + * + * @param node The node to substitute. + * @param isExpression A value indicating whether the node is to be used in an expression + * position. + */ + function onSubstituteNode(emitContext: EmitContext, node: Node) { + node = previousOnSubstituteNode(emitContext, node); + if (emitContext === EmitContext.Expression) { + return substituteExpression(node); + } + + return node; + } + + function createSuperAccessInAsyncMethod(argumentExpression: Expression, flags: NodeCheckFlags, location: TextRange): LeftHandSideExpression { + if (flags & NodeCheckFlags.AsyncMethodWithSuperBinding) { + return createPropertyAccess( + createCall( + createIdentifier("_super"), + /*typeArguments*/ undefined, + [argumentExpression] + ), + "value", + location + ); + } + else { + return createCall( + createIdentifier("_super"), + /*typeArguments*/ undefined, + [argumentExpression], + location + ); + } + } + + function getSuperContainerAsyncMethodFlags() { + return currentSuperContainer !== undefined + && resolver.getNodeCheckFlags(currentSuperContainer) & (NodeCheckFlags.AsyncMethodWithSuper | NodeCheckFlags.AsyncMethodWithSuperBinding); + } + } +} diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index c4e9b4c31c..3877169e6c 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -701,11 +701,13 @@ namespace ts { const statements: Statement[] = []; const name = node.name || getGeneratedNameForNode(node); if (hasModifier(node, ModifierFlags.Export)) { + // Keep async modifier for ES2017 transformer + const isAsync = hasModifier(node, ModifierFlags.Async); statements.push( setOriginalNode( createFunctionDeclaration( /*decorators*/ undefined, - /*modifiers*/ undefined, + isAsync ? [createNode(SyntaxKind.AsyncKeyword)] : undefined, node.asteriskToken, name, /*typeParameters*/ undefined, diff --git a/src/compiler/transformers/module/system.ts b/src/compiler/transformers/module/system.ts index 4a137c89a9..d4ee4f36b8 100644 --- a/src/compiler/transformers/module/system.ts +++ b/src/compiler/transformers/module/system.ts @@ -662,9 +662,11 @@ namespace ts { if (hasModifier(node, ModifierFlags.Export)) { // If the function is exported, ensure it has a name and rewrite the function without any export flags. const name = node.name || getGeneratedNameForNode(node); + // Keep async modifier for ES2017 transformer + const isAsync = hasModifier(node, ModifierFlags.Async); const newNode = createFunctionDeclaration( /*decorators*/ undefined, - /*modifiers*/ undefined, + isAsync ? [createNode(SyntaxKind.AsyncKeyword)] : undefined, node.asteriskToken, name, /*typeParameters*/ undefined, @@ -1402,4 +1404,4 @@ namespace ts { return updated; } } -} \ No newline at end of file +} diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index c98fbfc26c..30276deff9 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -4,8 +4,6 @@ /*@internal*/ namespace ts { - type SuperContainer = ClassDeclaration | MethodDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | ConstructorDeclaration; - /** * Indicates whether to emit type metadata in the new format. */ @@ -16,8 +14,6 @@ namespace ts { ClassAliases = 1 << 0, /** Enables substitutions for namespace exports. */ NamespaceExports = 1 << 1, - /** Enables substitutions for async methods with `super` calls. */ - AsyncMethodsWithSuper = 1 << 2, /* Enables substitutions for unqualified enum members */ NonQualifiedEnumMembers = 1 << 3 } @@ -72,12 +68,6 @@ namespace ts { */ let applicableSubstitutions: TypeScriptSubstitutionFlags; - /** - * This keeps track of containers where `super` is valid, for use with - * just-in-time substitution for `super` expressions inside of async methods. - */ - let currentSuperContainer: SuperContainer; - return transformSourceFile; /** @@ -240,6 +230,7 @@ namespace ts { // ES6 export and default modifiers are elided when inside a namespace. return currentNamespace ? undefined : node; + // Typescript ES2017 async/await are handled by ES2017 transformer case SyntaxKind.AsyncKeyword: return node; @@ -388,7 +379,7 @@ namespace ts { return visitEnumDeclaration(node); case SyntaxKind.AwaitExpression: - // TypeScript 'await' expressions must be transformed. + // Typescript ES2017 async/await are handled by ES2017 transformer return visitAwaitExpression(node); case SyntaxKind.VariableStatement: @@ -2225,13 +2216,9 @@ namespace ts { /*location*/ node ); - // Add ES8 async function expression modifier - // Not sure this is the right place? Might be better to move this - // into createFunctionExpression itself. - if ((languageVersion >= ScriptTarget.ES8) && isAsyncFunctionLike(node)) { - const funcModifiers = visitNodes(node.modifiers, visitor, isModifier); - func.modifiers = createNodeArray(funcModifiers); - } + // Keep modifiers in case of async functions + const funcModifiers = visitNodes(node.modifiers, visitor, isModifier); + func.modifiers = createNodeArray(funcModifiers); setOriginalNode(func, node); @@ -2260,9 +2247,9 @@ namespace ts { } function transformFunctionBody(node: MethodDeclaration | AccessorDeclaration | FunctionDeclaration | FunctionExpression): FunctionBody { - if (isAsyncFunctionLike(node) && languageVersion < ScriptTarget.ES8) { - return transformAsyncFunctionBody(node); - } + // if (isAsyncFunctionLike(node) && languageVersion < ScriptTarget.ES2017) { + // return transformAsyncFunctionBody(node); + // } return transformFunctionBodyWorker(node.body); } @@ -2280,9 +2267,9 @@ namespace ts { } function transformConciseBody(node: ArrowFunction): ConciseBody { - if (isAsyncFunctionLike(node) && languageVersion < ScriptTarget.ES8) { - return transformAsyncFunctionBody(node); - } + // if (isAsyncFunctionLike(node) && languageVersion < ScriptTarget.ES2017) { + // return transformAsyncFunctionBody(node); + // } return transformConciseBodyWorker(node.body, /*forceBlockFunctionBody*/ false); } @@ -2307,72 +2294,6 @@ namespace ts { } } - function getPromiseConstructor(type: TypeNode) { - const typeName = getEntityNameFromTypeNode(type); - if (typeName && isEntityName(typeName)) { - const serializationKind = resolver.getTypeReferenceSerializationKind(typeName); - if (serializationKind === TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue - || serializationKind === TypeReferenceSerializationKind.Unknown) { - return typeName; - } - } - - return undefined; - } - - function transformAsyncFunctionBody(node: FunctionLikeDeclaration): ConciseBody | FunctionBody { - const promiseConstructor = languageVersion < ScriptTarget.ES6 ? getPromiseConstructor(node.type) : undefined; - const isArrowFunction = node.kind === SyntaxKind.ArrowFunction; - const hasLexicalArguments = (resolver.getNodeCheckFlags(node) & NodeCheckFlags.CaptureArguments) !== 0; - - // An async function is emit as an outer function that calls an inner - // generator function. To preserve lexical bindings, we pass the current - // `this` and `arguments` objects to `__awaiter`. The generator function - // passed to `__awaiter` is executed inside of the callback to the - // promise constructor. - - - if (!isArrowFunction) { - const statements: Statement[] = []; - const statementOffset = addPrologueDirectives(statements, (node.body).statements, /*ensureUseStrict*/ false, visitor); - statements.push( - createReturn( - createAwaiterHelper( - currentSourceFileExternalHelpersModuleName, - hasLexicalArguments, - promiseConstructor, - transformFunctionBodyWorker(node.body, statementOffset) - ) - ) - ); - - const block = createBlock(statements, /*location*/ node.body, /*multiLine*/ true); - - // Minor optimization, emit `_super` helper to capture `super` access in an arrow. - // This step isn't needed if we eventually transform this to ES5. - if (languageVersion >= ScriptTarget.ES6) { - if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.AsyncMethodWithSuperBinding) { - enableSubstitutionForAsyncMethodsWithSuper(); - setEmitFlags(block, EmitFlags.EmitAdvancedSuperHelper); - } - else if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.AsyncMethodWithSuper) { - enableSubstitutionForAsyncMethodsWithSuper(); - setEmitFlags(block, EmitFlags.EmitSuperHelper); - } - } - - return block; - } - else { - return createAwaiterHelper( - currentSourceFileExternalHelpersModuleName, - hasLexicalArguments, - promiseConstructor, - transformConciseBodyWorker(node.body, /*forceBlockFunctionBody*/ true) - ); - } - } - /** * Visits a parameter declaration node. * @@ -2458,33 +2379,18 @@ namespace ts { /** * Visits an await expression. * - * This function will be called any time a TypeScript await expression is encountered. + * This function will be called any time a ES2017 await expression is encountered. * * @param node The await expression node. */ function visitAwaitExpression(node: AwaitExpression): Expression { - const targetAtLeastES8 = languageVersion >= ScriptTarget.ES8; - return setOriginalNode( - targetAtLeastES8 ? createAwaitExpression() : createYieldExpression(), + return updateNode( + createAwait( + visitNode(node.expression, visitor, isExpression), + /*location*/ node + ), node ); - - function createAwaitExpression() { - const awaitExpression = createAwait( - visitNode(node.expression, visitor, isExpression), - /*location*/ node - ); - return awaitExpression; - } - - function createYieldExpression() { - const yieldExpression = createYield( - /*asteriskToken*/ undefined, - visitNode(node.expression, visitor, isExpression), - /*location*/ node - ); - return yieldExpression; - } } /** @@ -3241,25 +3147,6 @@ namespace ts { } } - function enableSubstitutionForAsyncMethodsWithSuper() { - if ((enabledSubstitutions & TypeScriptSubstitutionFlags.AsyncMethodsWithSuper) === 0) { - enabledSubstitutions |= TypeScriptSubstitutionFlags.AsyncMethodsWithSuper; - - // We need to enable substitutions for call, property access, and element access - // if we need to rewrite super calls. - context.enableSubstitution(SyntaxKind.CallExpression); - context.enableSubstitution(SyntaxKind.PropertyAccessExpression); - context.enableSubstitution(SyntaxKind.ElementAccessExpression); - - // We need to be notified when entering and exiting declarations that bind super. - context.enableEmitNotification(SyntaxKind.ClassDeclaration); - context.enableEmitNotification(SyntaxKind.MethodDeclaration); - context.enableEmitNotification(SyntaxKind.GetAccessor); - context.enableEmitNotification(SyntaxKind.SetAccessor); - context.enableEmitNotification(SyntaxKind.Constructor); - } - } - function enableSubstitutionForClassAliases() { if ((enabledSubstitutions & TypeScriptSubstitutionFlags.ClassAliases) === 0) { enabledSubstitutions |= TypeScriptSubstitutionFlags.ClassAliases; @@ -3287,15 +3174,6 @@ namespace ts { } } - function isSuperContainer(node: Node): node is SuperContainer { - const kind = node.kind; - return kind === SyntaxKind.ClassDeclaration - || kind === SyntaxKind.Constructor - || kind === SyntaxKind.MethodDeclaration - || kind === SyntaxKind.GetAccessor - || kind === SyntaxKind.SetAccessor; - } - function isTransformedModuleDeclaration(node: Node): boolean { return getOriginalNode(node).kind === SyntaxKind.ModuleDeclaration; } @@ -3312,12 +3190,6 @@ namespace ts { */ function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void { const savedApplicableSubstitutions = applicableSubstitutions; - const savedCurrentSuperContainer = currentSuperContainer; - // If we need to support substitutions for `super` in an async method, - // we should track it here. - if (enabledSubstitutions & TypeScriptSubstitutionFlags.AsyncMethodsWithSuper && isSuperContainer(node)) { - currentSuperContainer = node; - } if (enabledSubstitutions & TypeScriptSubstitutionFlags.NamespaceExports && isTransformedModuleDeclaration(node)) { applicableSubstitutions |= TypeScriptSubstitutionFlags.NamespaceExports; @@ -3330,7 +3202,6 @@ namespace ts { previousOnEmitNode(emitContext, node, emitCallback); applicableSubstitutions = savedApplicableSubstitutions; - currentSuperContainer = savedCurrentSuperContainer; } /** @@ -3377,11 +3248,6 @@ namespace ts { return substitutePropertyAccessExpression(node); case SyntaxKind.ElementAccessExpression: return substituteElementAccessExpression(node); - case SyntaxKind.CallExpression: - if (enabledSubstitutions & TypeScriptSubstitutionFlags.AsyncMethodsWithSuper) { - return substituteCallExpression(node); - } - break; } return node; @@ -3436,54 +3302,11 @@ namespace ts { return undefined; } - function substituteCallExpression(node: CallExpression): Expression { - const expression = node.expression; - if (isSuperProperty(expression)) { - const flags = getSuperContainerAsyncMethodFlags(); - if (flags) { - const argumentExpression = isPropertyAccessExpression(expression) - ? substitutePropertyAccessExpression(expression) - : substituteElementAccessExpression(expression); - return createCall( - createPropertyAccess(argumentExpression, "call"), - /*typeArguments*/ undefined, - [ - createThis(), - ...node.arguments - ] - ); - } - } - return node; - } - function substitutePropertyAccessExpression(node: PropertyAccessExpression) { - if (enabledSubstitutions & TypeScriptSubstitutionFlags.AsyncMethodsWithSuper && node.expression.kind === SyntaxKind.SuperKeyword) { - const flags = getSuperContainerAsyncMethodFlags(); - if (flags) { - return createSuperAccessInAsyncMethod( - createLiteral(node.name.text), - flags, - node - ); - } - } - return substituteConstantValue(node); } function substituteElementAccessExpression(node: ElementAccessExpression) { - if (enabledSubstitutions & TypeScriptSubstitutionFlags.AsyncMethodsWithSuper && node.expression.kind === SyntaxKind.SuperKeyword) { - const flags = getSuperContainerAsyncMethodFlags(); - if (flags) { - return createSuperAccessInAsyncMethod( - node.argumentExpression, - flags, - node - ); - } - } - return substituteConstantValue(node); } @@ -3516,32 +3339,5 @@ namespace ts { ? resolver.getConstantValue(node) : undefined; } - - function createSuperAccessInAsyncMethod(argumentExpression: Expression, flags: NodeCheckFlags, location: TextRange): LeftHandSideExpression { - if (flags & NodeCheckFlags.AsyncMethodWithSuperBinding) { - return createPropertyAccess( - createCall( - createIdentifier("_super"), - /*typeArguments*/ undefined, - [argumentExpression] - ), - "value", - location - ); - } - else { - return createCall( - createIdentifier("_super"), - /*typeArguments*/ undefined, - [argumentExpression], - location - ); - } - } - - function getSuperContainerAsyncMethodFlags() { - return currentSuperContainer !== undefined - && resolver.getNodeCheckFlags(currentSuperContainer) & (NodeCheckFlags.AsyncMethodWithSuper | NodeCheckFlags.AsyncMethodWithSuperBinding); - } } } diff --git a/src/compiler/tsconfig.json b/src/compiler/tsconfig.json index fc0f016f66..de710e74a4 100644 --- a/src/compiler/tsconfig.json +++ b/src/compiler/tsconfig.json @@ -24,6 +24,7 @@ "visitor.ts", "transformers/ts.ts", "transformers/jsx.ts", + "transformers/es2017.ts", "transformers/es2016.ts", "transformers/es6.ts", "transformers/generators.ts", diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index b661cefb5a..92ce6ecc6a 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -4142,6 +4142,8 @@ namespace ts { namespace ts { export function getDefaultLibFileName(options: CompilerOptions): string { switch (options.target) { + case ScriptTarget.ES2017: + return "lib.es2017.d.ts"; case ScriptTarget.ES2016: return "lib.es2016.d.ts"; case ScriptTarget.ES6: diff --git a/src/harness/harness.ts b/src/harness/harness.ts index b8703ebc8f..c50f33a74c 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -942,6 +942,8 @@ namespace Harness { export function getDefaultLibFileName(options: ts.CompilerOptions): string { switch (options.target) { + case ts.ScriptTarget.ES2017: + return "lib.es2017.d.ts"; case ts.ScriptTarget.ES2016: return "lib.es2016.d.ts"; case ts.ScriptTarget.ES6: diff --git a/src/harness/tsconfig.json b/src/harness/tsconfig.json index aa46c8ee8d..c8b90645ce 100644 --- a/src/harness/tsconfig.json +++ b/src/harness/tsconfig.json @@ -26,6 +26,7 @@ "../compiler/visitor.ts", "../compiler/transformers/ts.ts", "../compiler/transformers/jsx.ts", + "../compiler/transformers/es2017.ts", "../compiler/transformers/es2016.ts", "../compiler/transformers/es6.ts", "../compiler/transformers/generators.ts", diff --git a/src/services/tsconfig.json b/src/services/tsconfig.json index e759ab35b4..45e3c9036e 100644 --- a/src/services/tsconfig.json +++ b/src/services/tsconfig.json @@ -25,6 +25,7 @@ "../compiler/visitor.ts", "../compiler/transformers/ts.ts", "../compiler/transformers/jsx.ts", + "../compiler/transformers/es2017.ts", "../compiler/transformers/es2016.ts", "../compiler/transformers/es6.ts", "../compiler/transformers/generators.ts", diff --git a/tests/baselines/reference/es8-async.js b/tests/baselines/reference/es2017basicAsync.js similarity index 94% rename from tests/baselines/reference/es8-async.js rename to tests/baselines/reference/es2017basicAsync.js index 3338b1f88a..da219f4614 100644 --- a/tests/baselines/reference/es8-async.js +++ b/tests/baselines/reference/es2017basicAsync.js @@ -1,4 +1,4 @@ -//// [es8-async.ts] +//// [es2017-async.ts] async (): Promise => { await 0; @@ -47,7 +47,7 @@ class AsyncClass { } -//// [es8-async.js] +//// [es2017-async.js] async () => { await 0; }; diff --git a/tests/baselines/reference/es8-async.symbols b/tests/baselines/reference/es2017basicAsync.symbols similarity index 78% rename from tests/baselines/reference/es8-async.symbols rename to tests/baselines/reference/es2017basicAsync.symbols index 25a77351ae..be3b2e723f 100644 --- a/tests/baselines/reference/es8-async.symbols +++ b/tests/baselines/reference/es2017basicAsync.symbols @@ -1,4 +1,4 @@ -=== tests/cases/compiler/es8-async.ts === +=== tests/cases/compiler/es2017-async.ts === async (): Promise => { >Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) @@ -7,20 +7,20 @@ async (): Promise => { } async function asyncFunc() { ->asyncFunc : Symbol(asyncFunc, Decl(es8-async.ts, 3, 1)) +>asyncFunc : Symbol(asyncFunc, Decl(es2017-async.ts, 3, 1)) await 0; } const asycnArrowFunc = async (): Promise => { ->asycnArrowFunc : Symbol(asycnArrowFunc, Decl(es8-async.ts, 9, 5)) +>asycnArrowFunc : Symbol(asycnArrowFunc, Decl(es2017-async.ts, 9, 5)) >Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) await 0; } async function asyncIIFE() { ->asyncIIFE : Symbol(asyncIIFE, Decl(es8-async.ts, 11, 1)) +>asyncIIFE : Symbol(asyncIIFE, Decl(es2017-async.ts, 11, 1)) await 0; @@ -31,7 +31,7 @@ async function asyncIIFE() { })(); await (async function asyncNamedFunc(): Promise { ->asyncNamedFunc : Symbol(asyncNamedFunc, Decl(es8-async.ts, 20, 11)) +>asyncNamedFunc : Symbol(asyncNamedFunc, Decl(es2017-async.ts, 20, 11)) >Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) await 1; @@ -45,32 +45,32 @@ async function asyncIIFE() { } class AsyncClass { ->AsyncClass : Symbol(AsyncClass, Decl(es8-async.ts, 27, 1)) +>AsyncClass : Symbol(AsyncClass, Decl(es2017-async.ts, 27, 1)) asyncPropFunc = async function(): Promise { ->asyncPropFunc : Symbol(AsyncClass.asyncPropFunc, Decl(es8-async.ts, 29, 18)) +>asyncPropFunc : Symbol(AsyncClass.asyncPropFunc, Decl(es2017-async.ts, 29, 18)) >Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) await 2; } asyncPropNamedFunc = async function namedFunc(): Promise { ->asyncPropNamedFunc : Symbol(AsyncClass.asyncPropNamedFunc, Decl(es8-async.ts, 32, 5)) ->namedFunc : Symbol(namedFunc, Decl(es8-async.ts, 34, 24)) +>asyncPropNamedFunc : Symbol(AsyncClass.asyncPropNamedFunc, Decl(es2017-async.ts, 32, 5)) +>namedFunc : Symbol(namedFunc, Decl(es2017-async.ts, 34, 24)) >Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) await 2; } asyncPropArrowFunc = async (): Promise => { ->asyncPropArrowFunc : Symbol(AsyncClass.asyncPropArrowFunc, Decl(es8-async.ts, 36, 5)) +>asyncPropArrowFunc : Symbol(AsyncClass.asyncPropArrowFunc, Decl(es2017-async.ts, 36, 5)) >Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) await 2; } async asyncMethod(): Promise { ->asyncMethod : Symbol(AsyncClass.asyncMethod, Decl(es8-async.ts, 40, 5)) +>asyncMethod : Symbol(AsyncClass.asyncMethod, Decl(es2017-async.ts, 40, 5)) >Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) await 2; diff --git a/tests/baselines/reference/es8-async.types b/tests/baselines/reference/es2017basicAsync.types similarity index 94% rename from tests/baselines/reference/es8-async.types rename to tests/baselines/reference/es2017basicAsync.types index da0ca06377..79f3a005e6 100644 --- a/tests/baselines/reference/es8-async.types +++ b/tests/baselines/reference/es2017basicAsync.types @@ -1,4 +1,4 @@ -=== tests/cases/compiler/es8-async.ts === +=== tests/cases/compiler/es2017-async.ts === async (): Promise => { >async (): Promise => { await 0;} : () => Promise From 1b4c0e331e5aa11133f0a36e1ba24d7ee748a58a Mon Sep 17 00:00:00 2001 From: Andrej Baran Date: Wed, 12 Oct 2016 21:34:55 +0200 Subject: [PATCH 26/80] Add es2017 async conformance --- ...owFunctionWithParameterNameAsync_es2017.js | 6 + ...ctionWithParameterNameAsync_es2017.symbols | 7 + ...unctionWithParameterNameAsync_es2017.types | 8 ++ .../reference/asyncAliasReturnType_es2017.js | 9 ++ .../asyncAliasReturnType_es2017.symbols | 11 ++ .../asyncAliasReturnType_es2017.types | 11 ++ .../asyncArrowFunction10_es2017.errors.txt | 12 ++ .../reference/asyncArrowFunction10_es2017.js | 13 ++ .../reference/asyncArrowFunction1_es2017.js | 8 ++ .../asyncArrowFunction1_es2017.symbols | 7 + .../asyncArrowFunction1_es2017.types | 8 ++ .../reference/asyncArrowFunction2_es2017.js | 7 + .../asyncArrowFunction2_es2017.symbols | 5 + .../asyncArrowFunction2_es2017.types | 6 + .../asyncArrowFunction3_es2017.errors.txt | 8 ++ .../reference/asyncArrowFunction3_es2017.js | 7 + .../reference/asyncArrowFunction4_es2017.js | 7 + .../asyncArrowFunction4_es2017.symbols | 4 + .../asyncArrowFunction4_es2017.types | 5 + .../asyncArrowFunction5_es2017.errors.txt | 24 ++++ .../reference/asyncArrowFunction5_es2017.js | 9 ++ .../asyncArrowFunction6_es2017.errors.txt | 12 ++ .../reference/asyncArrowFunction6_es2017.js | 8 ++ .../asyncArrowFunction7_es2017.errors.txt | 15 ++ .../reference/asyncArrowFunction7_es2017.js | 14 ++ .../asyncArrowFunction8_es2017.errors.txt | 10 ++ .../reference/asyncArrowFunction8_es2017.js | 10 ++ .../asyncArrowFunction9_es2017.errors.txt | 23 ++++ .../reference/asyncArrowFunction9_es2017.js | 8 ++ ...ncArrowFunctionCapturesArguments_es2017.js | 16 +++ ...owFunctionCapturesArguments_es2017.symbols | 20 +++ ...rrowFunctionCapturesArguments_es2017.types | 23 ++++ .../asyncArrowFunctionCapturesThis_es2017.js | 14 ++ ...ncArrowFunctionCapturesThis_es2017.symbols | 13 ++ ...syncArrowFunctionCapturesThis_es2017.types | 15 ++ ...syncAwaitIsolatedModules_es2017.errors.txt | 45 ++++++ .../asyncAwaitIsolatedModules_es2017.js | 73 ++++++++++ .../baselines/reference/asyncAwait_es2017.js | 73 ++++++++++ .../reference/asyncAwait_es2017.symbols | 118 ++++++++++++++++ .../reference/asyncAwait_es2017.types | 129 ++++++++++++++++++ .../reference/asyncClass_es2017.errors.txt | 8 ++ .../baselines/reference/asyncClass_es2017.js | 7 + .../asyncConstructor_es2017.errors.txt | 10 ++ .../reference/asyncConstructor_es2017.js | 11 ++ .../reference/asyncDeclare_es2017.errors.txt | 7 + .../reference/asyncDeclare_es2017.js | 4 + .../reference/asyncEnum_es2017.errors.txt | 9 ++ tests/baselines/reference/asyncEnum_es2017.js | 10 ++ ...yncFunctionDeclaration10_es2017.errors.txt | 26 ++++ .../asyncFunctionDeclaration10_es2017.js | 7 + .../asyncFunctionDeclaration11_es2017.js | 7 + .../asyncFunctionDeclaration11_es2017.symbols | 5 + .../asyncFunctionDeclaration11_es2017.types | 5 + ...yncFunctionDeclaration12_es2017.errors.txt | 16 +++ .../asyncFunctionDeclaration12_es2017.js | 5 + ...yncFunctionDeclaration13_es2017.errors.txt | 11 ++ .../asyncFunctionDeclaration13_es2017.js | 12 ++ .../asyncFunctionDeclaration14_es2017.js | 9 ++ .../asyncFunctionDeclaration14_es2017.symbols | 7 + .../asyncFunctionDeclaration14_es2017.types | 7 + ...yncFunctionDeclaration15_es2017.errors.txt | 48 +++++++ .../asyncFunctionDeclaration15_es2017.js | 64 +++++++++ .../asyncFunctionDeclaration1_es2017.js | 7 + .../asyncFunctionDeclaration1_es2017.symbols | 5 + .../asyncFunctionDeclaration1_es2017.types | 5 + .../asyncFunctionDeclaration2_es2017.js | 7 + .../asyncFunctionDeclaration2_es2017.symbols | 5 + .../asyncFunctionDeclaration2_es2017.types | 5 + ...syncFunctionDeclaration3_es2017.errors.txt | 8 ++ .../asyncFunctionDeclaration3_es2017.js | 7 + .../asyncFunctionDeclaration4_es2017.js | 7 + .../asyncFunctionDeclaration4_es2017.symbols | 4 + .../asyncFunctionDeclaration4_es2017.types | 4 + ...syncFunctionDeclaration5_es2017.errors.txt | 20 +++ .../asyncFunctionDeclaration5_es2017.js | 7 + ...syncFunctionDeclaration6_es2017.errors.txt | 11 ++ .../asyncFunctionDeclaration6_es2017.js | 7 + ...syncFunctionDeclaration7_es2017.errors.txt | 14 ++ .../asyncFunctionDeclaration7_es2017.js | 13 ++ ...syncFunctionDeclaration8_es2017.errors.txt | 10 ++ .../asyncFunctionDeclaration8_es2017.js | 5 + ...syncFunctionDeclaration9_es2017.errors.txt | 9 ++ .../asyncFunctionDeclaration9_es2017.js | 9 ++ .../reference/asyncGetter_es2017.errors.txt | 13 ++ .../baselines/reference/asyncGetter_es2017.js | 11 ++ .../asyncImportedPromise_es2017.errors.txt | 13 ++ .../reference/asyncImportedPromise_es2017.js | 21 +++ .../asyncInterface_es2017.errors.txt | 8 ++ .../reference/asyncInterface_es2017.js | 5 + .../reference/asyncMethodWithSuper_es2017.js | 90 ++++++++++++ .../asyncMethodWithSuper_es2017.symbols | 102 ++++++++++++++ .../asyncMethodWithSuper_es2017.types | 123 +++++++++++++++++ .../reference/asyncModule_es2017.errors.txt | 8 ++ .../baselines/reference/asyncModule_es2017.js | 5 + .../reference/asyncMultiFile_es2017.js | 11 ++ .../reference/asyncMultiFile_es2017.symbols | 8 ++ .../reference/asyncMultiFile_es2017.types | 8 ++ ...asyncQualifiedReturnType_es2017.errors.txt | 13 ++ .../asyncQualifiedReturnType_es2017.js | 18 +++ .../reference/asyncSetter_es2017.errors.txt | 10 ++ .../baselines/reference/asyncSetter_es2017.js | 11 ++ ...syncUnParenthesizedArrowFunction_es2017.js | 9 ++ ...nParenthesizedArrowFunction_es2017.symbols | 19 +++ ...cUnParenthesizedArrowFunction_es2017.types | 25 ++++ .../reference/asyncUseStrict_es2017.js | 13 ++ .../reference/asyncUseStrict_es2017.symbols | 18 +++ .../reference/asyncUseStrict_es2017.types | 22 +++ .../awaitBinaryExpression1_es2017.js | 17 +++ .../awaitBinaryExpression1_es2017.symbols | 29 ++++ .../awaitBinaryExpression1_es2017.types | 33 +++++ .../awaitBinaryExpression2_es2017.js | 17 +++ .../awaitBinaryExpression2_es2017.symbols | 29 ++++ .../awaitBinaryExpression2_es2017.types | 33 +++++ .../awaitBinaryExpression3_es2017.js | 17 +++ .../awaitBinaryExpression3_es2017.symbols | 29 ++++ .../awaitBinaryExpression3_es2017.types | 33 +++++ .../awaitBinaryExpression4_es2017.js | 17 +++ .../awaitBinaryExpression4_es2017.symbols | 29 ++++ .../awaitBinaryExpression4_es2017.types | 34 +++++ .../awaitBinaryExpression5_es2017.js | 19 +++ .../awaitBinaryExpression5_es2017.symbols | 34 +++++ .../awaitBinaryExpression5_es2017.types | 38 ++++++ .../reference/awaitCallExpression1_es2017.js | 21 +++ .../awaitCallExpression1_es2017.symbols | 59 ++++++++ .../awaitCallExpression1_es2017.types | 62 +++++++++ .../reference/awaitCallExpression2_es2017.js | 21 +++ .../awaitCallExpression2_es2017.symbols | 59 ++++++++ .../awaitCallExpression2_es2017.types | 63 +++++++++ .../reference/awaitCallExpression3_es2017.js | 21 +++ .../awaitCallExpression3_es2017.symbols | 59 ++++++++ .../awaitCallExpression3_es2017.types | 63 +++++++++ .../reference/awaitCallExpression4_es2017.js | 21 +++ .../awaitCallExpression4_es2017.symbols | 59 ++++++++ .../awaitCallExpression4_es2017.types | 64 +++++++++ .../reference/awaitCallExpression5_es2017.js | 21 +++ .../awaitCallExpression5_es2017.symbols | 61 +++++++++ .../awaitCallExpression5_es2017.types | 64 +++++++++ .../reference/awaitCallExpression6_es2017.js | 21 +++ .../awaitCallExpression6_es2017.symbols | 61 +++++++++ .../awaitCallExpression6_es2017.types | 65 +++++++++ .../reference/awaitCallExpression7_es2017.js | 21 +++ .../awaitCallExpression7_es2017.symbols | 61 +++++++++ .../awaitCallExpression7_es2017.types | 65 +++++++++ .../reference/awaitCallExpression8_es2017.js | 21 +++ .../awaitCallExpression8_es2017.symbols | 61 +++++++++ .../awaitCallExpression8_es2017.types | 66 +++++++++ .../reference/awaitClassExpression_es2017.js | 14 ++ .../awaitClassExpression_es2017.symbols | 18 +++ .../awaitClassExpression_es2017.types | 20 +++ .../baselines/reference/awaitUnion_es2017.js | 22 +++ .../reference/awaitUnion_es2017.symbols | 44 ++++++ .../reference/awaitUnion_es2017.types | 49 +++++++ .../reference/await_unaryExpression_es2017.js | 31 +++++ .../await_unaryExpression_es2017.symbols | 25 ++++ .../await_unaryExpression_es2017.types | 37 +++++ .../await_unaryExpression_es2017_1.js | 38 ++++++ .../await_unaryExpression_es2017_1.symbols | 31 +++++ .../await_unaryExpression_es2017_1.types | 46 +++++++ .../await_unaryExpression_es2017_2.js | 24 ++++ .../await_unaryExpression_es2017_2.symbols | 19 +++ .../await_unaryExpression_es2017_2.types | 28 ++++ .../await_unaryExpression_es2017_3.errors.txt | 27 ++++ .../await_unaryExpression_es2017_3.js | 37 +++++ tests/baselines/reference/es2017basicAsync.js | 4 +- .../reference/es2017basicAsync.symbols | 22 +-- .../reference/es2017basicAsync.types | 2 +- .../es2017/asyncAliasReturnType_es2017.ts | 6 + ...owFunctionWithParameterNameAsync_es2017.ts | 4 + .../asyncArrowFunction10_es2017.ts | 7 + .../asyncArrowFunction1_es2017.ts | 5 + .../asyncArrowFunction2_es2017.ts | 4 + .../asyncArrowFunction3_es2017.ts | 4 + .../asyncArrowFunction4_es2017.ts | 4 + .../asyncArrowFunction5_es2017.ts | 5 + .../asyncArrowFunction6_es2017.ts | 5 + .../asyncArrowFunction7_es2017.ts | 8 ++ .../asyncArrowFunction8_es2017.ts | 6 + .../asyncArrowFunction9_es2017.ts | 4 + ...ncArrowFunctionCapturesArguments_es2017.ts | 8 ++ .../asyncArrowFunctionCapturesThis_es2017.ts | 7 + ...syncUnParenthesizedArrowFunction_es2017.ts | 6 + .../asyncAwaitIsolatedModules_es2017.ts | 41 ++++++ .../async/es2017/asyncAwait_es2017.ts | 40 ++++++ .../async/es2017/asyncClass_es2017.ts | 4 + .../async/es2017/asyncConstructor_es2017.ts | 6 + .../async/es2017/asyncDeclare_es2017.ts | 3 + .../async/es2017/asyncEnum_es2017.ts | 5 + .../async/es2017/asyncGetter_es2017.ts | 6 + .../es2017/asyncImportedPromise_es2017.ts | 10 ++ .../async/es2017/asyncInterface_es2017.ts | 4 + .../es2017/asyncMethodWithSuper_es2017.ts | 52 +++++++ .../async/es2017/asyncModule_es2017.ts | 4 + .../async/es2017/asyncMultiFile_es2017.ts | 5 + .../es2017/asyncQualifiedReturnType_es2017.ts | 9 ++ .../async/es2017/asyncSetter_es2017.ts | 6 + .../async/es2017/asyncUseStrict_es2017.ts | 8 ++ .../awaitBinaryExpression1_es2017.ts | 11 ++ .../awaitBinaryExpression2_es2017.ts | 11 ++ .../awaitBinaryExpression3_es2017.ts | 11 ++ .../awaitBinaryExpression4_es2017.ts | 11 ++ .../awaitBinaryExpression5_es2017.ts | 12 ++ .../awaitCallExpression1_es2017.ts | 15 ++ .../awaitCallExpression2_es2017.ts | 15 ++ .../awaitCallExpression3_es2017.ts | 15 ++ .../awaitCallExpression4_es2017.ts | 15 ++ .../awaitCallExpression5_es2017.ts | 15 ++ .../awaitCallExpression6_es2017.ts | 15 ++ .../awaitCallExpression7_es2017.ts | 15 ++ .../awaitCallExpression8_es2017.ts | 15 ++ .../es2017/awaitClassExpression_es2017.ts | 9 ++ .../async/es2017/awaitUnion_es2017.ts | 14 ++ .../es2017/await_unaryExpression_es2017.ts | 17 +++ .../es2017/await_unaryExpression_es2017_1.ts | 21 +++ .../es2017/await_unaryExpression_es2017_2.ts | 13 ++ .../es2017/await_unaryExpression_es2017_3.ts | 19 +++ .../asyncFunctionDeclaration10_es2017.ts | 4 + .../asyncFunctionDeclaration11_es2017.ts | 4 + .../asyncFunctionDeclaration12_es2017.ts | 3 + .../asyncFunctionDeclaration13_es2017.ts | 6 + .../asyncFunctionDeclaration14_es2017.ts | 5 + .../asyncFunctionDeclaration15_es2017.ts | 25 ++++ .../asyncFunctionDeclaration1_es2017.ts | 4 + .../asyncFunctionDeclaration2_es2017.ts | 4 + .../asyncFunctionDeclaration3_es2017.ts | 4 + .../asyncFunctionDeclaration4_es2017.ts | 4 + .../asyncFunctionDeclaration5_es2017.ts | 4 + .../asyncFunctionDeclaration6_es2017.ts | 4 + .../asyncFunctionDeclaration7_es2017.ts | 7 + .../asyncFunctionDeclaration8_es2017.ts | 3 + .../asyncFunctionDeclaration9_es2017.ts | 5 + 230 files changed, 4602 insertions(+), 14 deletions(-) create mode 100644 tests/baselines/reference/arrowFunctionWithParameterNameAsync_es2017.js create mode 100644 tests/baselines/reference/arrowFunctionWithParameterNameAsync_es2017.symbols create mode 100644 tests/baselines/reference/arrowFunctionWithParameterNameAsync_es2017.types create mode 100644 tests/baselines/reference/asyncAliasReturnType_es2017.js create mode 100644 tests/baselines/reference/asyncAliasReturnType_es2017.symbols create mode 100644 tests/baselines/reference/asyncAliasReturnType_es2017.types create mode 100644 tests/baselines/reference/asyncArrowFunction10_es2017.errors.txt create mode 100644 tests/baselines/reference/asyncArrowFunction10_es2017.js create mode 100644 tests/baselines/reference/asyncArrowFunction1_es2017.js create mode 100644 tests/baselines/reference/asyncArrowFunction1_es2017.symbols create mode 100644 tests/baselines/reference/asyncArrowFunction1_es2017.types create mode 100644 tests/baselines/reference/asyncArrowFunction2_es2017.js create mode 100644 tests/baselines/reference/asyncArrowFunction2_es2017.symbols create mode 100644 tests/baselines/reference/asyncArrowFunction2_es2017.types create mode 100644 tests/baselines/reference/asyncArrowFunction3_es2017.errors.txt create mode 100644 tests/baselines/reference/asyncArrowFunction3_es2017.js create mode 100644 tests/baselines/reference/asyncArrowFunction4_es2017.js create mode 100644 tests/baselines/reference/asyncArrowFunction4_es2017.symbols create mode 100644 tests/baselines/reference/asyncArrowFunction4_es2017.types create mode 100644 tests/baselines/reference/asyncArrowFunction5_es2017.errors.txt create mode 100644 tests/baselines/reference/asyncArrowFunction5_es2017.js create mode 100644 tests/baselines/reference/asyncArrowFunction6_es2017.errors.txt create mode 100644 tests/baselines/reference/asyncArrowFunction6_es2017.js create mode 100644 tests/baselines/reference/asyncArrowFunction7_es2017.errors.txt create mode 100644 tests/baselines/reference/asyncArrowFunction7_es2017.js create mode 100644 tests/baselines/reference/asyncArrowFunction8_es2017.errors.txt create mode 100644 tests/baselines/reference/asyncArrowFunction8_es2017.js create mode 100644 tests/baselines/reference/asyncArrowFunction9_es2017.errors.txt create mode 100644 tests/baselines/reference/asyncArrowFunction9_es2017.js create mode 100644 tests/baselines/reference/asyncArrowFunctionCapturesArguments_es2017.js create mode 100644 tests/baselines/reference/asyncArrowFunctionCapturesArguments_es2017.symbols create mode 100644 tests/baselines/reference/asyncArrowFunctionCapturesArguments_es2017.types create mode 100644 tests/baselines/reference/asyncArrowFunctionCapturesThis_es2017.js create mode 100644 tests/baselines/reference/asyncArrowFunctionCapturesThis_es2017.symbols create mode 100644 tests/baselines/reference/asyncArrowFunctionCapturesThis_es2017.types create mode 100644 tests/baselines/reference/asyncAwaitIsolatedModules_es2017.errors.txt create mode 100644 tests/baselines/reference/asyncAwaitIsolatedModules_es2017.js create mode 100644 tests/baselines/reference/asyncAwait_es2017.js create mode 100644 tests/baselines/reference/asyncAwait_es2017.symbols create mode 100644 tests/baselines/reference/asyncAwait_es2017.types create mode 100644 tests/baselines/reference/asyncClass_es2017.errors.txt create mode 100644 tests/baselines/reference/asyncClass_es2017.js create mode 100644 tests/baselines/reference/asyncConstructor_es2017.errors.txt create mode 100644 tests/baselines/reference/asyncConstructor_es2017.js create mode 100644 tests/baselines/reference/asyncDeclare_es2017.errors.txt create mode 100644 tests/baselines/reference/asyncDeclare_es2017.js create mode 100644 tests/baselines/reference/asyncEnum_es2017.errors.txt create mode 100644 tests/baselines/reference/asyncEnum_es2017.js create mode 100644 tests/baselines/reference/asyncFunctionDeclaration10_es2017.errors.txt create mode 100644 tests/baselines/reference/asyncFunctionDeclaration10_es2017.js create mode 100644 tests/baselines/reference/asyncFunctionDeclaration11_es2017.js create mode 100644 tests/baselines/reference/asyncFunctionDeclaration11_es2017.symbols create mode 100644 tests/baselines/reference/asyncFunctionDeclaration11_es2017.types create mode 100644 tests/baselines/reference/asyncFunctionDeclaration12_es2017.errors.txt create mode 100644 tests/baselines/reference/asyncFunctionDeclaration12_es2017.js create mode 100644 tests/baselines/reference/asyncFunctionDeclaration13_es2017.errors.txt create mode 100644 tests/baselines/reference/asyncFunctionDeclaration13_es2017.js create mode 100644 tests/baselines/reference/asyncFunctionDeclaration14_es2017.js create mode 100644 tests/baselines/reference/asyncFunctionDeclaration14_es2017.symbols create mode 100644 tests/baselines/reference/asyncFunctionDeclaration14_es2017.types create mode 100644 tests/baselines/reference/asyncFunctionDeclaration15_es2017.errors.txt create mode 100644 tests/baselines/reference/asyncFunctionDeclaration15_es2017.js create mode 100644 tests/baselines/reference/asyncFunctionDeclaration1_es2017.js create mode 100644 tests/baselines/reference/asyncFunctionDeclaration1_es2017.symbols create mode 100644 tests/baselines/reference/asyncFunctionDeclaration1_es2017.types create mode 100644 tests/baselines/reference/asyncFunctionDeclaration2_es2017.js create mode 100644 tests/baselines/reference/asyncFunctionDeclaration2_es2017.symbols create mode 100644 tests/baselines/reference/asyncFunctionDeclaration2_es2017.types create mode 100644 tests/baselines/reference/asyncFunctionDeclaration3_es2017.errors.txt create mode 100644 tests/baselines/reference/asyncFunctionDeclaration3_es2017.js create mode 100644 tests/baselines/reference/asyncFunctionDeclaration4_es2017.js create mode 100644 tests/baselines/reference/asyncFunctionDeclaration4_es2017.symbols create mode 100644 tests/baselines/reference/asyncFunctionDeclaration4_es2017.types create mode 100644 tests/baselines/reference/asyncFunctionDeclaration5_es2017.errors.txt create mode 100644 tests/baselines/reference/asyncFunctionDeclaration5_es2017.js create mode 100644 tests/baselines/reference/asyncFunctionDeclaration6_es2017.errors.txt create mode 100644 tests/baselines/reference/asyncFunctionDeclaration6_es2017.js create mode 100644 tests/baselines/reference/asyncFunctionDeclaration7_es2017.errors.txt create mode 100644 tests/baselines/reference/asyncFunctionDeclaration7_es2017.js create mode 100644 tests/baselines/reference/asyncFunctionDeclaration8_es2017.errors.txt create mode 100644 tests/baselines/reference/asyncFunctionDeclaration8_es2017.js create mode 100644 tests/baselines/reference/asyncFunctionDeclaration9_es2017.errors.txt create mode 100644 tests/baselines/reference/asyncFunctionDeclaration9_es2017.js create mode 100644 tests/baselines/reference/asyncGetter_es2017.errors.txt create mode 100644 tests/baselines/reference/asyncGetter_es2017.js create mode 100644 tests/baselines/reference/asyncImportedPromise_es2017.errors.txt create mode 100644 tests/baselines/reference/asyncImportedPromise_es2017.js create mode 100644 tests/baselines/reference/asyncInterface_es2017.errors.txt create mode 100644 tests/baselines/reference/asyncInterface_es2017.js create mode 100644 tests/baselines/reference/asyncMethodWithSuper_es2017.js create mode 100644 tests/baselines/reference/asyncMethodWithSuper_es2017.symbols create mode 100644 tests/baselines/reference/asyncMethodWithSuper_es2017.types create mode 100644 tests/baselines/reference/asyncModule_es2017.errors.txt create mode 100644 tests/baselines/reference/asyncModule_es2017.js create mode 100644 tests/baselines/reference/asyncMultiFile_es2017.js create mode 100644 tests/baselines/reference/asyncMultiFile_es2017.symbols create mode 100644 tests/baselines/reference/asyncMultiFile_es2017.types create mode 100644 tests/baselines/reference/asyncQualifiedReturnType_es2017.errors.txt create mode 100644 tests/baselines/reference/asyncQualifiedReturnType_es2017.js create mode 100644 tests/baselines/reference/asyncSetter_es2017.errors.txt create mode 100644 tests/baselines/reference/asyncSetter_es2017.js create mode 100644 tests/baselines/reference/asyncUnParenthesizedArrowFunction_es2017.js create mode 100644 tests/baselines/reference/asyncUnParenthesizedArrowFunction_es2017.symbols create mode 100644 tests/baselines/reference/asyncUnParenthesizedArrowFunction_es2017.types create mode 100644 tests/baselines/reference/asyncUseStrict_es2017.js create mode 100644 tests/baselines/reference/asyncUseStrict_es2017.symbols create mode 100644 tests/baselines/reference/asyncUseStrict_es2017.types create mode 100644 tests/baselines/reference/awaitBinaryExpression1_es2017.js create mode 100644 tests/baselines/reference/awaitBinaryExpression1_es2017.symbols create mode 100644 tests/baselines/reference/awaitBinaryExpression1_es2017.types create mode 100644 tests/baselines/reference/awaitBinaryExpression2_es2017.js create mode 100644 tests/baselines/reference/awaitBinaryExpression2_es2017.symbols create mode 100644 tests/baselines/reference/awaitBinaryExpression2_es2017.types create mode 100644 tests/baselines/reference/awaitBinaryExpression3_es2017.js create mode 100644 tests/baselines/reference/awaitBinaryExpression3_es2017.symbols create mode 100644 tests/baselines/reference/awaitBinaryExpression3_es2017.types create mode 100644 tests/baselines/reference/awaitBinaryExpression4_es2017.js create mode 100644 tests/baselines/reference/awaitBinaryExpression4_es2017.symbols create mode 100644 tests/baselines/reference/awaitBinaryExpression4_es2017.types create mode 100644 tests/baselines/reference/awaitBinaryExpression5_es2017.js create mode 100644 tests/baselines/reference/awaitBinaryExpression5_es2017.symbols create mode 100644 tests/baselines/reference/awaitBinaryExpression5_es2017.types create mode 100644 tests/baselines/reference/awaitCallExpression1_es2017.js create mode 100644 tests/baselines/reference/awaitCallExpression1_es2017.symbols create mode 100644 tests/baselines/reference/awaitCallExpression1_es2017.types create mode 100644 tests/baselines/reference/awaitCallExpression2_es2017.js create mode 100644 tests/baselines/reference/awaitCallExpression2_es2017.symbols create mode 100644 tests/baselines/reference/awaitCallExpression2_es2017.types create mode 100644 tests/baselines/reference/awaitCallExpression3_es2017.js create mode 100644 tests/baselines/reference/awaitCallExpression3_es2017.symbols create mode 100644 tests/baselines/reference/awaitCallExpression3_es2017.types create mode 100644 tests/baselines/reference/awaitCallExpression4_es2017.js create mode 100644 tests/baselines/reference/awaitCallExpression4_es2017.symbols create mode 100644 tests/baselines/reference/awaitCallExpression4_es2017.types create mode 100644 tests/baselines/reference/awaitCallExpression5_es2017.js create mode 100644 tests/baselines/reference/awaitCallExpression5_es2017.symbols create mode 100644 tests/baselines/reference/awaitCallExpression5_es2017.types create mode 100644 tests/baselines/reference/awaitCallExpression6_es2017.js create mode 100644 tests/baselines/reference/awaitCallExpression6_es2017.symbols create mode 100644 tests/baselines/reference/awaitCallExpression6_es2017.types create mode 100644 tests/baselines/reference/awaitCallExpression7_es2017.js create mode 100644 tests/baselines/reference/awaitCallExpression7_es2017.symbols create mode 100644 tests/baselines/reference/awaitCallExpression7_es2017.types create mode 100644 tests/baselines/reference/awaitCallExpression8_es2017.js create mode 100644 tests/baselines/reference/awaitCallExpression8_es2017.symbols create mode 100644 tests/baselines/reference/awaitCallExpression8_es2017.types create mode 100644 tests/baselines/reference/awaitClassExpression_es2017.js create mode 100644 tests/baselines/reference/awaitClassExpression_es2017.symbols create mode 100644 tests/baselines/reference/awaitClassExpression_es2017.types create mode 100644 tests/baselines/reference/awaitUnion_es2017.js create mode 100644 tests/baselines/reference/awaitUnion_es2017.symbols create mode 100644 tests/baselines/reference/awaitUnion_es2017.types create mode 100644 tests/baselines/reference/await_unaryExpression_es2017.js create mode 100644 tests/baselines/reference/await_unaryExpression_es2017.symbols create mode 100644 tests/baselines/reference/await_unaryExpression_es2017.types create mode 100644 tests/baselines/reference/await_unaryExpression_es2017_1.js create mode 100644 tests/baselines/reference/await_unaryExpression_es2017_1.symbols create mode 100644 tests/baselines/reference/await_unaryExpression_es2017_1.types create mode 100644 tests/baselines/reference/await_unaryExpression_es2017_2.js create mode 100644 tests/baselines/reference/await_unaryExpression_es2017_2.symbols create mode 100644 tests/baselines/reference/await_unaryExpression_es2017_2.types create mode 100644 tests/baselines/reference/await_unaryExpression_es2017_3.errors.txt create mode 100644 tests/baselines/reference/await_unaryExpression_es2017_3.js create mode 100644 tests/cases/conformance/async/es2017/asyncAliasReturnType_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/asyncArrowFunction/arrowFunctionWithParameterNameAsync_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction10_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction1_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction2_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction3_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction4_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction5_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction6_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction7_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction8_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction9_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunctionCapturesArguments_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunctionCapturesThis_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/asyncArrowFunction/asyncUnParenthesizedArrowFunction_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/asyncAwaitIsolatedModules_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/asyncAwait_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/asyncClass_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/asyncConstructor_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/asyncDeclare_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/asyncEnum_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/asyncGetter_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/asyncImportedPromise_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/asyncInterface_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/asyncMethodWithSuper_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/asyncModule_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/asyncMultiFile_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/asyncQualifiedReturnType_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/asyncSetter_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/asyncUseStrict_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/awaitBinaryExpression/awaitBinaryExpression1_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/awaitBinaryExpression/awaitBinaryExpression2_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/awaitBinaryExpression/awaitBinaryExpression3_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/awaitBinaryExpression/awaitBinaryExpression4_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/awaitBinaryExpression/awaitBinaryExpression5_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression1_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression2_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression3_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression4_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression5_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression6_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression7_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression8_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/awaitClassExpression_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/awaitUnion_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/await_unaryExpression_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/await_unaryExpression_es2017_1.ts create mode 100644 tests/cases/conformance/async/es2017/await_unaryExpression_es2017_2.ts create mode 100644 tests/cases/conformance/async/es2017/await_unaryExpression_es2017_3.ts create mode 100644 tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration10_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration11_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration12_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration13_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration14_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration15_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration1_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration2_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration3_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration4_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration5_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration6_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration7_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration8_es2017.ts create mode 100644 tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration9_es2017.ts diff --git a/tests/baselines/reference/arrowFunctionWithParameterNameAsync_es2017.js b/tests/baselines/reference/arrowFunctionWithParameterNameAsync_es2017.js new file mode 100644 index 0000000000..daaff29cad --- /dev/null +++ b/tests/baselines/reference/arrowFunctionWithParameterNameAsync_es2017.js @@ -0,0 +1,6 @@ +//// [arrowFunctionWithParameterNameAsync_es2017.ts] + +const x = async => async; + +//// [arrowFunctionWithParameterNameAsync_es2017.js] +var x = function (async) { return async; }; diff --git a/tests/baselines/reference/arrowFunctionWithParameterNameAsync_es2017.symbols b/tests/baselines/reference/arrowFunctionWithParameterNameAsync_es2017.symbols new file mode 100644 index 0000000000..481697c0af --- /dev/null +++ b/tests/baselines/reference/arrowFunctionWithParameterNameAsync_es2017.symbols @@ -0,0 +1,7 @@ +=== tests/cases/conformance/async/es2017/asyncArrowFunction/arrowFunctionWithParameterNameAsync_es2017.ts === + +const x = async => async; +>x : Symbol(x, Decl(arrowFunctionWithParameterNameAsync_es2017.ts, 1, 5)) +>async : Symbol(async, Decl(arrowFunctionWithParameterNameAsync_es2017.ts, 1, 9)) +>async : Symbol(async, Decl(arrowFunctionWithParameterNameAsync_es2017.ts, 1, 9)) + diff --git a/tests/baselines/reference/arrowFunctionWithParameterNameAsync_es2017.types b/tests/baselines/reference/arrowFunctionWithParameterNameAsync_es2017.types new file mode 100644 index 0000000000..ccb8654284 --- /dev/null +++ b/tests/baselines/reference/arrowFunctionWithParameterNameAsync_es2017.types @@ -0,0 +1,8 @@ +=== tests/cases/conformance/async/es2017/asyncArrowFunction/arrowFunctionWithParameterNameAsync_es2017.ts === + +const x = async => async; +>x : (async: any) => any +>async => async : (async: any) => any +>async : any +>async : any + diff --git a/tests/baselines/reference/asyncAliasReturnType_es2017.js b/tests/baselines/reference/asyncAliasReturnType_es2017.js new file mode 100644 index 0000000000..f76f2b13b4 --- /dev/null +++ b/tests/baselines/reference/asyncAliasReturnType_es2017.js @@ -0,0 +1,9 @@ +//// [asyncAliasReturnType_es2017.ts] +type PromiseAlias = Promise; + +async function f(): PromiseAlias { +} + +//// [asyncAliasReturnType_es2017.js] +async function f() { +} diff --git a/tests/baselines/reference/asyncAliasReturnType_es2017.symbols b/tests/baselines/reference/asyncAliasReturnType_es2017.symbols new file mode 100644 index 0000000000..cc4fc5b809 --- /dev/null +++ b/tests/baselines/reference/asyncAliasReturnType_es2017.symbols @@ -0,0 +1,11 @@ +=== tests/cases/conformance/async/es2017/asyncAliasReturnType_es2017.ts === +type PromiseAlias = Promise; +>PromiseAlias : Symbol(PromiseAlias, Decl(asyncAliasReturnType_es2017.ts, 0, 0)) +>T : Symbol(T, Decl(asyncAliasReturnType_es2017.ts, 0, 18)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) +>T : Symbol(T, Decl(asyncAliasReturnType_es2017.ts, 0, 18)) + +async function f(): PromiseAlias { +>f : Symbol(f, Decl(asyncAliasReturnType_es2017.ts, 0, 34)) +>PromiseAlias : Symbol(PromiseAlias, Decl(asyncAliasReturnType_es2017.ts, 0, 0)) +} diff --git a/tests/baselines/reference/asyncAliasReturnType_es2017.types b/tests/baselines/reference/asyncAliasReturnType_es2017.types new file mode 100644 index 0000000000..67c521b77f --- /dev/null +++ b/tests/baselines/reference/asyncAliasReturnType_es2017.types @@ -0,0 +1,11 @@ +=== tests/cases/conformance/async/es2017/asyncAliasReturnType_es2017.ts === +type PromiseAlias = Promise; +>PromiseAlias : Promise +>T : T +>Promise : Promise +>T : T + +async function f(): PromiseAlias { +>f : () => Promise +>PromiseAlias : Promise +} diff --git a/tests/baselines/reference/asyncArrowFunction10_es2017.errors.txt b/tests/baselines/reference/asyncArrowFunction10_es2017.errors.txt new file mode 100644 index 0000000000..923dbed6da --- /dev/null +++ b/tests/baselines/reference/asyncArrowFunction10_es2017.errors.txt @@ -0,0 +1,12 @@ +tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction10_es2017.ts(4,11): error TS2304: Cannot find name 'await'. + + +==== tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction10_es2017.ts (1 errors) ==== + + var foo = async (): Promise => { + // Legal to use 'await' in a type context. + var v: await; + ~~~~~ +!!! error TS2304: Cannot find name 'await'. + } + \ No newline at end of file diff --git a/tests/baselines/reference/asyncArrowFunction10_es2017.js b/tests/baselines/reference/asyncArrowFunction10_es2017.js new file mode 100644 index 0000000000..3c966201bc --- /dev/null +++ b/tests/baselines/reference/asyncArrowFunction10_es2017.js @@ -0,0 +1,13 @@ +//// [asyncArrowFunction10_es2017.ts] + +var foo = async (): Promise => { + // Legal to use 'await' in a type context. + var v: await; +} + + +//// [asyncArrowFunction10_es2017.js] +var foo = async () => { + // Legal to use 'await' in a type context. + var v; +}; diff --git a/tests/baselines/reference/asyncArrowFunction1_es2017.js b/tests/baselines/reference/asyncArrowFunction1_es2017.js new file mode 100644 index 0000000000..ff6a462424 --- /dev/null +++ b/tests/baselines/reference/asyncArrowFunction1_es2017.js @@ -0,0 +1,8 @@ +//// [asyncArrowFunction1_es2017.ts] + +var foo = async (): Promise => { +}; + +//// [asyncArrowFunction1_es2017.js] +var foo = async () => { +}; diff --git a/tests/baselines/reference/asyncArrowFunction1_es2017.symbols b/tests/baselines/reference/asyncArrowFunction1_es2017.symbols new file mode 100644 index 0000000000..35fd033d6b --- /dev/null +++ b/tests/baselines/reference/asyncArrowFunction1_es2017.symbols @@ -0,0 +1,7 @@ +=== tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction1_es2017.ts === + +var foo = async (): Promise => { +>foo : Symbol(foo, Decl(asyncArrowFunction1_es2017.ts, 1, 3)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + +}; diff --git a/tests/baselines/reference/asyncArrowFunction1_es2017.types b/tests/baselines/reference/asyncArrowFunction1_es2017.types new file mode 100644 index 0000000000..bdc6cacc91 --- /dev/null +++ b/tests/baselines/reference/asyncArrowFunction1_es2017.types @@ -0,0 +1,8 @@ +=== tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction1_es2017.ts === + +var foo = async (): Promise => { +>foo : () => Promise +>async (): Promise => {} : () => Promise +>Promise : Promise + +}; diff --git a/tests/baselines/reference/asyncArrowFunction2_es2017.js b/tests/baselines/reference/asyncArrowFunction2_es2017.js new file mode 100644 index 0000000000..d2a5d0306b --- /dev/null +++ b/tests/baselines/reference/asyncArrowFunction2_es2017.js @@ -0,0 +1,7 @@ +//// [asyncArrowFunction2_es2017.ts] +var f = (await) => { +} + +//// [asyncArrowFunction2_es2017.js] +var f = (await) => { +}; diff --git a/tests/baselines/reference/asyncArrowFunction2_es2017.symbols b/tests/baselines/reference/asyncArrowFunction2_es2017.symbols new file mode 100644 index 0000000000..a56c5bb62c --- /dev/null +++ b/tests/baselines/reference/asyncArrowFunction2_es2017.symbols @@ -0,0 +1,5 @@ +=== tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction2_es2017.ts === +var f = (await) => { +>f : Symbol(f, Decl(asyncArrowFunction2_es2017.ts, 0, 3)) +>await : Symbol(await, Decl(asyncArrowFunction2_es2017.ts, 0, 9)) +} diff --git a/tests/baselines/reference/asyncArrowFunction2_es2017.types b/tests/baselines/reference/asyncArrowFunction2_es2017.types new file mode 100644 index 0000000000..1feb033e6e --- /dev/null +++ b/tests/baselines/reference/asyncArrowFunction2_es2017.types @@ -0,0 +1,6 @@ +=== tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction2_es2017.ts === +var f = (await) => { +>f : (await: any) => void +>(await) => {} : (await: any) => void +>await : any +} diff --git a/tests/baselines/reference/asyncArrowFunction3_es2017.errors.txt b/tests/baselines/reference/asyncArrowFunction3_es2017.errors.txt new file mode 100644 index 0000000000..1c1fd71176 --- /dev/null +++ b/tests/baselines/reference/asyncArrowFunction3_es2017.errors.txt @@ -0,0 +1,8 @@ +tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction3_es2017.ts(1,20): error TS2372: Parameter 'await' cannot be referenced in its initializer. + + +==== tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction3_es2017.ts (1 errors) ==== + function f(await = await) { + ~~~~~ +!!! error TS2372: Parameter 'await' cannot be referenced in its initializer. + } \ No newline at end of file diff --git a/tests/baselines/reference/asyncArrowFunction3_es2017.js b/tests/baselines/reference/asyncArrowFunction3_es2017.js new file mode 100644 index 0000000000..7ae371facc --- /dev/null +++ b/tests/baselines/reference/asyncArrowFunction3_es2017.js @@ -0,0 +1,7 @@ +//// [asyncArrowFunction3_es2017.ts] +function f(await = await) { +} + +//// [asyncArrowFunction3_es2017.js] +function f(await = await) { +} diff --git a/tests/baselines/reference/asyncArrowFunction4_es2017.js b/tests/baselines/reference/asyncArrowFunction4_es2017.js new file mode 100644 index 0000000000..ebec1e6dbd --- /dev/null +++ b/tests/baselines/reference/asyncArrowFunction4_es2017.js @@ -0,0 +1,7 @@ +//// [asyncArrowFunction4_es2017.ts] +var await = () => { +} + +//// [asyncArrowFunction4_es2017.js] +var await = () => { +}; diff --git a/tests/baselines/reference/asyncArrowFunction4_es2017.symbols b/tests/baselines/reference/asyncArrowFunction4_es2017.symbols new file mode 100644 index 0000000000..b44fc0dbdf --- /dev/null +++ b/tests/baselines/reference/asyncArrowFunction4_es2017.symbols @@ -0,0 +1,4 @@ +=== tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction4_es2017.ts === +var await = () => { +>await : Symbol(await, Decl(asyncArrowFunction4_es2017.ts, 0, 3)) +} diff --git a/tests/baselines/reference/asyncArrowFunction4_es2017.types b/tests/baselines/reference/asyncArrowFunction4_es2017.types new file mode 100644 index 0000000000..6af5f94c75 --- /dev/null +++ b/tests/baselines/reference/asyncArrowFunction4_es2017.types @@ -0,0 +1,5 @@ +=== tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction4_es2017.ts === +var await = () => { +>await : () => void +>() => {} : () => void +} diff --git a/tests/baselines/reference/asyncArrowFunction5_es2017.errors.txt b/tests/baselines/reference/asyncArrowFunction5_es2017.errors.txt new file mode 100644 index 0000000000..3df5617710 --- /dev/null +++ b/tests/baselines/reference/asyncArrowFunction5_es2017.errors.txt @@ -0,0 +1,24 @@ +tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction5_es2017.ts(2,11): error TS2304: Cannot find name 'async'. +tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction5_es2017.ts(2,18): error TS2304: Cannot find name 'await'. +tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction5_es2017.ts(2,24): error TS1005: ',' expected. +tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction5_es2017.ts(2,26): error TS2403: Subsequent variable declarations must have the same type. Variable 'Promise' must be of type 'PromiseConstructor', but here has type 'void'. +tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction5_es2017.ts(2,33): error TS1005: '=' expected. +tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction5_es2017.ts(2,40): error TS1109: Expression expected. + + +==== tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction5_es2017.ts (6 errors) ==== + + var foo = async (await): Promise => { + ~~~~~ +!!! error TS2304: Cannot find name 'async'. + ~~~~~ +!!! error TS2304: Cannot find name 'await'. + ~ +!!! error TS1005: ',' expected. + ~~~~~~~ +!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'Promise' must be of type 'PromiseConstructor', but here has type 'void'. + ~ +!!! error TS1005: '=' expected. + ~~ +!!! error TS1109: Expression expected. + } \ No newline at end of file diff --git a/tests/baselines/reference/asyncArrowFunction5_es2017.js b/tests/baselines/reference/asyncArrowFunction5_es2017.js new file mode 100644 index 0000000000..0c61a141f1 --- /dev/null +++ b/tests/baselines/reference/asyncArrowFunction5_es2017.js @@ -0,0 +1,9 @@ +//// [asyncArrowFunction5_es2017.ts] + +var foo = async (await): Promise => { +} + +//// [asyncArrowFunction5_es2017.js] +var foo = async(await), Promise = ; +{ +} diff --git a/tests/baselines/reference/asyncArrowFunction6_es2017.errors.txt b/tests/baselines/reference/asyncArrowFunction6_es2017.errors.txt new file mode 100644 index 0000000000..202ecb1727 --- /dev/null +++ b/tests/baselines/reference/asyncArrowFunction6_es2017.errors.txt @@ -0,0 +1,12 @@ +tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction6_es2017.ts(2,22): error TS2524: 'await' expressions cannot be used in a parameter initializer. +tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction6_es2017.ts(2,27): error TS1109: Expression expected. + + +==== tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction6_es2017.ts (2 errors) ==== + + var foo = async (a = await): Promise => { + ~~~~~ +!!! error TS2524: 'await' expressions cannot be used in a parameter initializer. + ~ +!!! error TS1109: Expression expected. + } \ No newline at end of file diff --git a/tests/baselines/reference/asyncArrowFunction6_es2017.js b/tests/baselines/reference/asyncArrowFunction6_es2017.js new file mode 100644 index 0000000000..c36f75a180 --- /dev/null +++ b/tests/baselines/reference/asyncArrowFunction6_es2017.js @@ -0,0 +1,8 @@ +//// [asyncArrowFunction6_es2017.ts] + +var foo = async (a = await): Promise => { +} + +//// [asyncArrowFunction6_es2017.js] +var foo = async (a = await ) => { +}; diff --git a/tests/baselines/reference/asyncArrowFunction7_es2017.errors.txt b/tests/baselines/reference/asyncArrowFunction7_es2017.errors.txt new file mode 100644 index 0000000000..33e0362428 --- /dev/null +++ b/tests/baselines/reference/asyncArrowFunction7_es2017.errors.txt @@ -0,0 +1,15 @@ +tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction7_es2017.ts(4,24): error TS2524: 'await' expressions cannot be used in a parameter initializer. +tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction7_es2017.ts(4,29): error TS1109: Expression expected. + + +==== tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction7_es2017.ts (2 errors) ==== + + var bar = async (): Promise => { + // 'await' here is an identifier, and not an await expression. + var foo = async (a = await): Promise => { + ~~~~~ +!!! error TS2524: 'await' expressions cannot be used in a parameter initializer. + ~ +!!! error TS1109: Expression expected. + } + } \ No newline at end of file diff --git a/tests/baselines/reference/asyncArrowFunction7_es2017.js b/tests/baselines/reference/asyncArrowFunction7_es2017.js new file mode 100644 index 0000000000..11d8c879eb --- /dev/null +++ b/tests/baselines/reference/asyncArrowFunction7_es2017.js @@ -0,0 +1,14 @@ +//// [asyncArrowFunction7_es2017.ts] + +var bar = async (): Promise => { + // 'await' here is an identifier, and not an await expression. + var foo = async (a = await): Promise => { + } +} + +//// [asyncArrowFunction7_es2017.js] +var bar = async () => { + // 'await' here is an identifier, and not an await expression. + var foo = async (a = await ) => { + }; +}; diff --git a/tests/baselines/reference/asyncArrowFunction8_es2017.errors.txt b/tests/baselines/reference/asyncArrowFunction8_es2017.errors.txt new file mode 100644 index 0000000000..75e460490b --- /dev/null +++ b/tests/baselines/reference/asyncArrowFunction8_es2017.errors.txt @@ -0,0 +1,10 @@ +tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction8_es2017.ts(3,19): error TS1109: Expression expected. + + +==== tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction8_es2017.ts (1 errors) ==== + + var foo = async (): Promise => { + var v = { [await]: foo } + ~ +!!! error TS1109: Expression expected. + } \ No newline at end of file diff --git a/tests/baselines/reference/asyncArrowFunction8_es2017.js b/tests/baselines/reference/asyncArrowFunction8_es2017.js new file mode 100644 index 0000000000..1358f186ce --- /dev/null +++ b/tests/baselines/reference/asyncArrowFunction8_es2017.js @@ -0,0 +1,10 @@ +//// [asyncArrowFunction8_es2017.ts] + +var foo = async (): Promise => { + var v = { [await]: foo } +} + +//// [asyncArrowFunction8_es2017.js] +var foo = async () => { + var v = { [await ]: foo }; +}; diff --git a/tests/baselines/reference/asyncArrowFunction9_es2017.errors.txt b/tests/baselines/reference/asyncArrowFunction9_es2017.errors.txt new file mode 100644 index 0000000000..ee94f3f9ca --- /dev/null +++ b/tests/baselines/reference/asyncArrowFunction9_es2017.errors.txt @@ -0,0 +1,23 @@ +tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction9_es2017.ts(1,11): error TS2304: Cannot find name 'async'. +tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction9_es2017.ts(1,18): error TS2304: Cannot find name 'a'. +tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction9_es2017.ts(1,37): error TS1005: ',' expected. +tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction9_es2017.ts(1,39): error TS2403: Subsequent variable declarations must have the same type. Variable 'Promise' must be of type 'PromiseConstructor', but here has type 'void'. +tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction9_es2017.ts(1,46): error TS1005: '=' expected. +tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction9_es2017.ts(1,53): error TS1109: Expression expected. + + +==== tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction9_es2017.ts (6 errors) ==== + var foo = async (a = await => await): Promise => { + ~~~~~ +!!! error TS2304: Cannot find name 'async'. + ~ +!!! error TS2304: Cannot find name 'a'. + ~ +!!! error TS1005: ',' expected. + ~~~~~~~ +!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'Promise' must be of type 'PromiseConstructor', but here has type 'void'. + ~ +!!! error TS1005: '=' expected. + ~~ +!!! error TS1109: Expression expected. + } \ No newline at end of file diff --git a/tests/baselines/reference/asyncArrowFunction9_es2017.js b/tests/baselines/reference/asyncArrowFunction9_es2017.js new file mode 100644 index 0000000000..c1fec991ec --- /dev/null +++ b/tests/baselines/reference/asyncArrowFunction9_es2017.js @@ -0,0 +1,8 @@ +//// [asyncArrowFunction9_es2017.ts] +var foo = async (a = await => await): Promise => { +} + +//// [asyncArrowFunction9_es2017.js] +var foo = async(a = await => await), Promise = ; +{ +} diff --git a/tests/baselines/reference/asyncArrowFunctionCapturesArguments_es2017.js b/tests/baselines/reference/asyncArrowFunctionCapturesArguments_es2017.js new file mode 100644 index 0000000000..f7f813ad50 --- /dev/null +++ b/tests/baselines/reference/asyncArrowFunctionCapturesArguments_es2017.js @@ -0,0 +1,16 @@ +//// [asyncArrowFunctionCapturesArguments_es2017.ts] +class C { + method() { + function other() {} + var fn = async () => await other.apply(this, arguments); + } +} + + +//// [asyncArrowFunctionCapturesArguments_es2017.js] +class C { + method() { + function other() { } + var fn = async () => await other.apply(this, arguments); + } +} diff --git a/tests/baselines/reference/asyncArrowFunctionCapturesArguments_es2017.symbols b/tests/baselines/reference/asyncArrowFunctionCapturesArguments_es2017.symbols new file mode 100644 index 0000000000..ccd9b48e40 --- /dev/null +++ b/tests/baselines/reference/asyncArrowFunctionCapturesArguments_es2017.symbols @@ -0,0 +1,20 @@ +=== tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunctionCapturesArguments_es2017.ts === +class C { +>C : Symbol(C, Decl(asyncArrowFunctionCapturesArguments_es2017.ts, 0, 0)) + + method() { +>method : Symbol(C.method, Decl(asyncArrowFunctionCapturesArguments_es2017.ts, 0, 9)) + + function other() {} +>other : Symbol(other, Decl(asyncArrowFunctionCapturesArguments_es2017.ts, 1, 13)) + + var fn = async () => await other.apply(this, arguments); +>fn : Symbol(fn, Decl(asyncArrowFunctionCapturesArguments_es2017.ts, 3, 9)) +>other.apply : Symbol(Function.apply, Decl(lib.es5.d.ts, --, --)) +>other : Symbol(other, Decl(asyncArrowFunctionCapturesArguments_es2017.ts, 1, 13)) +>apply : Symbol(Function.apply, Decl(lib.es5.d.ts, --, --)) +>this : Symbol(C, Decl(asyncArrowFunctionCapturesArguments_es2017.ts, 0, 0)) +>arguments : Symbol(arguments) + } +} + diff --git a/tests/baselines/reference/asyncArrowFunctionCapturesArguments_es2017.types b/tests/baselines/reference/asyncArrowFunctionCapturesArguments_es2017.types new file mode 100644 index 0000000000..a7a80424e1 --- /dev/null +++ b/tests/baselines/reference/asyncArrowFunctionCapturesArguments_es2017.types @@ -0,0 +1,23 @@ +=== tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunctionCapturesArguments_es2017.ts === +class C { +>C : C + + method() { +>method : () => void + + function other() {} +>other : () => void + + var fn = async () => await other.apply(this, arguments); +>fn : () => Promise +>async () => await other.apply(this, arguments) : () => Promise +>await other.apply(this, arguments) : any +>other.apply(this, arguments) : any +>other.apply : (this: Function, thisArg: any, argArray?: any) => any +>other : () => void +>apply : (this: Function, thisArg: any, argArray?: any) => any +>this : this +>arguments : IArguments + } +} + diff --git a/tests/baselines/reference/asyncArrowFunctionCapturesThis_es2017.js b/tests/baselines/reference/asyncArrowFunctionCapturesThis_es2017.js new file mode 100644 index 0000000000..13560557ff --- /dev/null +++ b/tests/baselines/reference/asyncArrowFunctionCapturesThis_es2017.js @@ -0,0 +1,14 @@ +//// [asyncArrowFunctionCapturesThis_es2017.ts] +class C { + method() { + var fn = async () => await this; + } +} + + +//// [asyncArrowFunctionCapturesThis_es2017.js] +class C { + method() { + var fn = async () => await this; + } +} diff --git a/tests/baselines/reference/asyncArrowFunctionCapturesThis_es2017.symbols b/tests/baselines/reference/asyncArrowFunctionCapturesThis_es2017.symbols new file mode 100644 index 0000000000..bc14bafa0c --- /dev/null +++ b/tests/baselines/reference/asyncArrowFunctionCapturesThis_es2017.symbols @@ -0,0 +1,13 @@ +=== tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunctionCapturesThis_es2017.ts === +class C { +>C : Symbol(C, Decl(asyncArrowFunctionCapturesThis_es2017.ts, 0, 0)) + + method() { +>method : Symbol(C.method, Decl(asyncArrowFunctionCapturesThis_es2017.ts, 0, 9)) + + var fn = async () => await this; +>fn : Symbol(fn, Decl(asyncArrowFunctionCapturesThis_es2017.ts, 2, 9)) +>this : Symbol(C, Decl(asyncArrowFunctionCapturesThis_es2017.ts, 0, 0)) + } +} + diff --git a/tests/baselines/reference/asyncArrowFunctionCapturesThis_es2017.types b/tests/baselines/reference/asyncArrowFunctionCapturesThis_es2017.types new file mode 100644 index 0000000000..57f59302bb --- /dev/null +++ b/tests/baselines/reference/asyncArrowFunctionCapturesThis_es2017.types @@ -0,0 +1,15 @@ +=== tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunctionCapturesThis_es2017.ts === +class C { +>C : C + + method() { +>method : () => void + + var fn = async () => await this; +>fn : () => Promise +>async () => await this : () => Promise +>await this : this +>this : this + } +} + diff --git a/tests/baselines/reference/asyncAwaitIsolatedModules_es2017.errors.txt b/tests/baselines/reference/asyncAwaitIsolatedModules_es2017.errors.txt new file mode 100644 index 0000000000..95927c283a --- /dev/null +++ b/tests/baselines/reference/asyncAwaitIsolatedModules_es2017.errors.txt @@ -0,0 +1,45 @@ +tests/cases/conformance/async/es2017/asyncAwaitIsolatedModules_es2017.ts(1,27): error TS2307: Cannot find module 'missing'. + + +==== tests/cases/conformance/async/es2017/asyncAwaitIsolatedModules_es2017.ts (1 errors) ==== + import { MyPromise } from "missing"; + ~~~~~~~~~ +!!! error TS2307: Cannot find module 'missing'. + + declare var p: Promise; + declare var mp: MyPromise; + + async function f0() { } + async function f1(): Promise { } + async function f3(): MyPromise { } + + let f4 = async function() { } + let f5 = async function(): Promise { } + let f6 = async function(): MyPromise { } + + let f7 = async () => { }; + let f8 = async (): Promise => { }; + let f9 = async (): MyPromise => { }; + let f10 = async () => p; + let f11 = async () => mp; + let f12 = async (): Promise => mp; + let f13 = async (): MyPromise => p; + + let o = { + async m1() { }, + async m2(): Promise { }, + async m3(): MyPromise { } + }; + + class C { + async m1() { } + async m2(): Promise { } + async m3(): MyPromise { } + static async m4() { } + static async m5(): Promise { } + static async m6(): MyPromise { } + } + + module M { + export async function f1() { } + } \ No newline at end of file diff --git a/tests/baselines/reference/asyncAwaitIsolatedModules_es2017.js b/tests/baselines/reference/asyncAwaitIsolatedModules_es2017.js new file mode 100644 index 0000000000..065aa675b6 --- /dev/null +++ b/tests/baselines/reference/asyncAwaitIsolatedModules_es2017.js @@ -0,0 +1,73 @@ +//// [asyncAwaitIsolatedModules_es2017.ts] +import { MyPromise } from "missing"; + +declare var p: Promise; +declare var mp: MyPromise; + +async function f0() { } +async function f1(): Promise { } +async function f3(): MyPromise { } + +let f4 = async function() { } +let f5 = async function(): Promise { } +let f6 = async function(): MyPromise { } + +let f7 = async () => { }; +let f8 = async (): Promise => { }; +let f9 = async (): MyPromise => { }; +let f10 = async () => p; +let f11 = async () => mp; +let f12 = async (): Promise => mp; +let f13 = async (): MyPromise => p; + +let o = { + async m1() { }, + async m2(): Promise { }, + async m3(): MyPromise { } +}; + +class C { + async m1() { } + async m2(): Promise { } + async m3(): MyPromise { } + static async m4() { } + static async m5(): Promise { } + static async m6(): MyPromise { } +} + +module M { + export async function f1() { } +} + +//// [asyncAwaitIsolatedModules_es2017.js] +async function f0() { } +async function f1() { } +async function f3() { } +let f4 = async function () { }; +let f5 = async function () { }; +let f6 = async function () { }; +let f7 = async () => { }; +let f8 = async () => { }; +let f9 = async () => { }; +let f10 = async () => p; +let f11 = async () => mp; +let f12 = async () => mp; +let f13 = async () => p; +let o = { + async m1() { }, + async m2() { }, + async m3() { } +}; +class C { + async m1() { } + async m2() { } + async m3() { } + static async m4() { } + static async m5() { } + static async m6() { } +} +var M; +(function (M) { + async function f1() { } + M.f1 = f1; +})(M || (M = {})); diff --git a/tests/baselines/reference/asyncAwait_es2017.js b/tests/baselines/reference/asyncAwait_es2017.js new file mode 100644 index 0000000000..314c99fa21 --- /dev/null +++ b/tests/baselines/reference/asyncAwait_es2017.js @@ -0,0 +1,73 @@ +//// [asyncAwait_es2017.ts] +type MyPromise = Promise; +declare var MyPromise: typeof Promise; +declare var p: Promise; +declare var mp: MyPromise; + +async function f0() { } +async function f1(): Promise { } +async function f3(): MyPromise { } + +let f4 = async function() { } +let f5 = async function(): Promise { } +let f6 = async function(): MyPromise { } + +let f7 = async () => { }; +let f8 = async (): Promise => { }; +let f9 = async (): MyPromise => { }; +let f10 = async () => p; +let f11 = async () => mp; +let f12 = async (): Promise => mp; +let f13 = async (): MyPromise => p; + +let o = { + async m1() { }, + async m2(): Promise { }, + async m3(): MyPromise { } +}; + +class C { + async m1() { } + async m2(): Promise { } + async m3(): MyPromise { } + static async m4() { } + static async m5(): Promise { } + static async m6(): MyPromise { } +} + +module M { + export async function f1() { } +} + +//// [asyncAwait_es2017.js] +async function f0() { } +async function f1() { } +async function f3() { } +let f4 = async function () { }; +let f5 = async function () { }; +let f6 = async function () { }; +let f7 = async () => { }; +let f8 = async () => { }; +let f9 = async () => { }; +let f10 = async () => p; +let f11 = async () => mp; +let f12 = async () => mp; +let f13 = async () => p; +let o = { + async m1() { }, + async m2() { }, + async m3() { } +}; +class C { + async m1() { } + async m2() { } + async m3() { } + static async m4() { } + static async m5() { } + static async m6() { } +} +var M; +(function (M) { + async function f1() { } + M.f1 = f1; +})(M || (M = {})); diff --git a/tests/baselines/reference/asyncAwait_es2017.symbols b/tests/baselines/reference/asyncAwait_es2017.symbols new file mode 100644 index 0000000000..34dc9802a2 --- /dev/null +++ b/tests/baselines/reference/asyncAwait_es2017.symbols @@ -0,0 +1,118 @@ +=== tests/cases/conformance/async/es2017/asyncAwait_es2017.ts === +type MyPromise = Promise; +>MyPromise : Symbol(MyPromise, Decl(asyncAwait_es2017.ts, 0, 0), Decl(asyncAwait_es2017.ts, 1, 11)) +>T : Symbol(T, Decl(asyncAwait_es2017.ts, 0, 15)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) +>T : Symbol(T, Decl(asyncAwait_es2017.ts, 0, 15)) + +declare var MyPromise: typeof Promise; +>MyPromise : Symbol(MyPromise, Decl(asyncAwait_es2017.ts, 0, 0), Decl(asyncAwait_es2017.ts, 1, 11)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + +declare var p: Promise; +>p : Symbol(p, Decl(asyncAwait_es2017.ts, 2, 11)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + +declare var mp: MyPromise; +>mp : Symbol(mp, Decl(asyncAwait_es2017.ts, 3, 11)) +>MyPromise : Symbol(MyPromise, Decl(asyncAwait_es2017.ts, 0, 0), Decl(asyncAwait_es2017.ts, 1, 11)) + +async function f0() { } +>f0 : Symbol(f0, Decl(asyncAwait_es2017.ts, 3, 34)) + +async function f1(): Promise { } +>f1 : Symbol(f1, Decl(asyncAwait_es2017.ts, 5, 23)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + +async function f3(): MyPromise { } +>f3 : Symbol(f3, Decl(asyncAwait_es2017.ts, 6, 38)) +>MyPromise : Symbol(MyPromise, Decl(asyncAwait_es2017.ts, 0, 0), Decl(asyncAwait_es2017.ts, 1, 11)) + +let f4 = async function() { } +>f4 : Symbol(f4, Decl(asyncAwait_es2017.ts, 9, 3)) + +let f5 = async function(): Promise { } +>f5 : Symbol(f5, Decl(asyncAwait_es2017.ts, 10, 3)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + +let f6 = async function(): MyPromise { } +>f6 : Symbol(f6, Decl(asyncAwait_es2017.ts, 11, 3)) +>MyPromise : Symbol(MyPromise, Decl(asyncAwait_es2017.ts, 0, 0), Decl(asyncAwait_es2017.ts, 1, 11)) + +let f7 = async () => { }; +>f7 : Symbol(f7, Decl(asyncAwait_es2017.ts, 13, 3)) + +let f8 = async (): Promise => { }; +>f8 : Symbol(f8, Decl(asyncAwait_es2017.ts, 14, 3)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + +let f9 = async (): MyPromise => { }; +>f9 : Symbol(f9, Decl(asyncAwait_es2017.ts, 15, 3)) +>MyPromise : Symbol(MyPromise, Decl(asyncAwait_es2017.ts, 0, 0), Decl(asyncAwait_es2017.ts, 1, 11)) + +let f10 = async () => p; +>f10 : Symbol(f10, Decl(asyncAwait_es2017.ts, 16, 3)) +>p : Symbol(p, Decl(asyncAwait_es2017.ts, 2, 11)) + +let f11 = async () => mp; +>f11 : Symbol(f11, Decl(asyncAwait_es2017.ts, 17, 3)) +>mp : Symbol(mp, Decl(asyncAwait_es2017.ts, 3, 11)) + +let f12 = async (): Promise => mp; +>f12 : Symbol(f12, Decl(asyncAwait_es2017.ts, 18, 3)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) +>mp : Symbol(mp, Decl(asyncAwait_es2017.ts, 3, 11)) + +let f13 = async (): MyPromise => p; +>f13 : Symbol(f13, Decl(asyncAwait_es2017.ts, 19, 3)) +>MyPromise : Symbol(MyPromise, Decl(asyncAwait_es2017.ts, 0, 0), Decl(asyncAwait_es2017.ts, 1, 11)) +>p : Symbol(p, Decl(asyncAwait_es2017.ts, 2, 11)) + +let o = { +>o : Symbol(o, Decl(asyncAwait_es2017.ts, 21, 3)) + + async m1() { }, +>m1 : Symbol(m1, Decl(asyncAwait_es2017.ts, 21, 9)) + + async m2(): Promise { }, +>m2 : Symbol(m2, Decl(asyncAwait_es2017.ts, 22, 16)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + + async m3(): MyPromise { } +>m3 : Symbol(m3, Decl(asyncAwait_es2017.ts, 23, 31)) +>MyPromise : Symbol(MyPromise, Decl(asyncAwait_es2017.ts, 0, 0), Decl(asyncAwait_es2017.ts, 1, 11)) + +}; + +class C { +>C : Symbol(C, Decl(asyncAwait_es2017.ts, 25, 2)) + + async m1() { } +>m1 : Symbol(C.m1, Decl(asyncAwait_es2017.ts, 27, 9)) + + async m2(): Promise { } +>m2 : Symbol(C.m2, Decl(asyncAwait_es2017.ts, 28, 15)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + + async m3(): MyPromise { } +>m3 : Symbol(C.m3, Decl(asyncAwait_es2017.ts, 29, 30)) +>MyPromise : Symbol(MyPromise, Decl(asyncAwait_es2017.ts, 0, 0), Decl(asyncAwait_es2017.ts, 1, 11)) + + static async m4() { } +>m4 : Symbol(C.m4, Decl(asyncAwait_es2017.ts, 30, 32)) + + static async m5(): Promise { } +>m5 : Symbol(C.m5, Decl(asyncAwait_es2017.ts, 31, 22)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + + static async m6(): MyPromise { } +>m6 : Symbol(C.m6, Decl(asyncAwait_es2017.ts, 32, 37)) +>MyPromise : Symbol(MyPromise, Decl(asyncAwait_es2017.ts, 0, 0), Decl(asyncAwait_es2017.ts, 1, 11)) +} + +module M { +>M : Symbol(M, Decl(asyncAwait_es2017.ts, 34, 1)) + + export async function f1() { } +>f1 : Symbol(f1, Decl(asyncAwait_es2017.ts, 36, 10)) +} diff --git a/tests/baselines/reference/asyncAwait_es2017.types b/tests/baselines/reference/asyncAwait_es2017.types new file mode 100644 index 0000000000..a1226d0cbf --- /dev/null +++ b/tests/baselines/reference/asyncAwait_es2017.types @@ -0,0 +1,129 @@ +=== tests/cases/conformance/async/es2017/asyncAwait_es2017.ts === +type MyPromise = Promise; +>MyPromise : Promise +>T : T +>Promise : Promise +>T : T + +declare var MyPromise: typeof Promise; +>MyPromise : PromiseConstructor +>Promise : PromiseConstructor + +declare var p: Promise; +>p : Promise +>Promise : Promise + +declare var mp: MyPromise; +>mp : Promise +>MyPromise : Promise + +async function f0() { } +>f0 : () => Promise + +async function f1(): Promise { } +>f1 : () => Promise +>Promise : Promise + +async function f3(): MyPromise { } +>f3 : () => Promise +>MyPromise : Promise + +let f4 = async function() { } +>f4 : () => Promise +>async function() { } : () => Promise + +let f5 = async function(): Promise { } +>f5 : () => Promise +>async function(): Promise { } : () => Promise +>Promise : Promise + +let f6 = async function(): MyPromise { } +>f6 : () => Promise +>async function(): MyPromise { } : () => Promise +>MyPromise : Promise + +let f7 = async () => { }; +>f7 : () => Promise +>async () => { } : () => Promise + +let f8 = async (): Promise => { }; +>f8 : () => Promise +>async (): Promise => { } : () => Promise +>Promise : Promise + +let f9 = async (): MyPromise => { }; +>f9 : () => Promise +>async (): MyPromise => { } : () => Promise +>MyPromise : Promise + +let f10 = async () => p; +>f10 : () => Promise +>async () => p : () => Promise +>p : Promise + +let f11 = async () => mp; +>f11 : () => Promise +>async () => mp : () => Promise +>mp : Promise + +let f12 = async (): Promise => mp; +>f12 : () => Promise +>async (): Promise => mp : () => Promise +>Promise : Promise +>mp : Promise + +let f13 = async (): MyPromise => p; +>f13 : () => Promise +>async (): MyPromise => p : () => Promise +>MyPromise : Promise +>p : Promise + +let o = { +>o : { m1(): Promise; m2(): Promise; m3(): Promise; } +>{ async m1() { }, async m2(): Promise { }, async m3(): MyPromise { }} : { m1(): Promise; m2(): Promise; m3(): Promise; } + + async m1() { }, +>m1 : () => Promise + + async m2(): Promise { }, +>m2 : () => Promise +>Promise : Promise + + async m3(): MyPromise { } +>m3 : () => Promise +>MyPromise : Promise + +}; + +class C { +>C : C + + async m1() { } +>m1 : () => Promise + + async m2(): Promise { } +>m2 : () => Promise +>Promise : Promise + + async m3(): MyPromise { } +>m3 : () => Promise +>MyPromise : Promise + + static async m4() { } +>m4 : () => Promise + + static async m5(): Promise { } +>m5 : () => Promise +>Promise : Promise + + static async m6(): MyPromise { } +>m6 : () => Promise +>MyPromise : Promise +} + +module M { +>M : typeof M + + export async function f1() { } +>f1 : () => Promise +} diff --git a/tests/baselines/reference/asyncClass_es2017.errors.txt b/tests/baselines/reference/asyncClass_es2017.errors.txt new file mode 100644 index 0000000000..37612b0b0f --- /dev/null +++ b/tests/baselines/reference/asyncClass_es2017.errors.txt @@ -0,0 +1,8 @@ +tests/cases/conformance/async/es2017/asyncClass_es2017.ts(1,1): error TS1042: 'async' modifier cannot be used here. + + +==== tests/cases/conformance/async/es2017/asyncClass_es2017.ts (1 errors) ==== + async class C { + ~~~~~ +!!! error TS1042: 'async' modifier cannot be used here. + } \ No newline at end of file diff --git a/tests/baselines/reference/asyncClass_es2017.js b/tests/baselines/reference/asyncClass_es2017.js new file mode 100644 index 0000000000..e619bd50b9 --- /dev/null +++ b/tests/baselines/reference/asyncClass_es2017.js @@ -0,0 +1,7 @@ +//// [asyncClass_es2017.ts] +async class C { +} + +//// [asyncClass_es2017.js] +async class C { +} diff --git a/tests/baselines/reference/asyncConstructor_es2017.errors.txt b/tests/baselines/reference/asyncConstructor_es2017.errors.txt new file mode 100644 index 0000000000..3b0c1b42fa --- /dev/null +++ b/tests/baselines/reference/asyncConstructor_es2017.errors.txt @@ -0,0 +1,10 @@ +tests/cases/conformance/async/es2017/asyncConstructor_es2017.ts(2,3): error TS1089: 'async' modifier cannot appear on a constructor declaration. + + +==== tests/cases/conformance/async/es2017/asyncConstructor_es2017.ts (1 errors) ==== + class C { + async constructor() { + ~~~~~ +!!! error TS1089: 'async' modifier cannot appear on a constructor declaration. + } + } \ No newline at end of file diff --git a/tests/baselines/reference/asyncConstructor_es2017.js b/tests/baselines/reference/asyncConstructor_es2017.js new file mode 100644 index 0000000000..7dcd6ec694 --- /dev/null +++ b/tests/baselines/reference/asyncConstructor_es2017.js @@ -0,0 +1,11 @@ +//// [asyncConstructor_es2017.ts] +class C { + async constructor() { + } +} + +//// [asyncConstructor_es2017.js] +class C { + async constructor() { + } +} diff --git a/tests/baselines/reference/asyncDeclare_es2017.errors.txt b/tests/baselines/reference/asyncDeclare_es2017.errors.txt new file mode 100644 index 0000000000..bb74a3865d --- /dev/null +++ b/tests/baselines/reference/asyncDeclare_es2017.errors.txt @@ -0,0 +1,7 @@ +tests/cases/conformance/async/es2017/asyncDeclare_es2017.ts(1,9): error TS1040: 'async' modifier cannot be used in an ambient context. + + +==== tests/cases/conformance/async/es2017/asyncDeclare_es2017.ts (1 errors) ==== + declare async function foo(): Promise; + ~~~~~ +!!! error TS1040: 'async' modifier cannot be used in an ambient context. \ No newline at end of file diff --git a/tests/baselines/reference/asyncDeclare_es2017.js b/tests/baselines/reference/asyncDeclare_es2017.js new file mode 100644 index 0000000000..2ff588b285 --- /dev/null +++ b/tests/baselines/reference/asyncDeclare_es2017.js @@ -0,0 +1,4 @@ +//// [asyncDeclare_es2017.ts] +declare async function foo(): Promise; + +//// [asyncDeclare_es2017.js] diff --git a/tests/baselines/reference/asyncEnum_es2017.errors.txt b/tests/baselines/reference/asyncEnum_es2017.errors.txt new file mode 100644 index 0000000000..8e0015d0b2 --- /dev/null +++ b/tests/baselines/reference/asyncEnum_es2017.errors.txt @@ -0,0 +1,9 @@ +tests/cases/conformance/async/es2017/asyncEnum_es2017.ts(1,1): error TS1042: 'async' modifier cannot be used here. + + +==== tests/cases/conformance/async/es2017/asyncEnum_es2017.ts (1 errors) ==== + async enum E { + ~~~~~ +!!! error TS1042: 'async' modifier cannot be used here. + Value + } \ No newline at end of file diff --git a/tests/baselines/reference/asyncEnum_es2017.js b/tests/baselines/reference/asyncEnum_es2017.js new file mode 100644 index 0000000000..df1f846c2f --- /dev/null +++ b/tests/baselines/reference/asyncEnum_es2017.js @@ -0,0 +1,10 @@ +//// [asyncEnum_es2017.ts] +async enum E { + Value +} + +//// [asyncEnum_es2017.js] +var E; +(function (E) { + E[E["Value"] = 0] = "Value"; +})(E || (E = {})); diff --git a/tests/baselines/reference/asyncFunctionDeclaration10_es2017.errors.txt b/tests/baselines/reference/asyncFunctionDeclaration10_es2017.errors.txt new file mode 100644 index 0000000000..d5da343226 --- /dev/null +++ b/tests/baselines/reference/asyncFunctionDeclaration10_es2017.errors.txt @@ -0,0 +1,26 @@ +tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration10_es2017.ts(1,20): error TS2371: A parameter initializer is only allowed in a function or constructor implementation. +tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration10_es2017.ts(1,30): error TS1109: Expression expected. +tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration10_es2017.ts(1,33): error TS1138: Parameter declaration expected. +tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration10_es2017.ts(1,33): error TS2304: Cannot find name 'await'. +tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration10_es2017.ts(1,38): error TS1005: ';' expected. +tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration10_es2017.ts(1,39): error TS1128: Declaration or statement expected. +tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration10_es2017.ts(1,53): error TS1109: Expression expected. + + +==== tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration10_es2017.ts (7 errors) ==== + async function foo(a = await => await): Promise { + ~~~~~~~~~ +!!! error TS2371: A parameter initializer is only allowed in a function or constructor implementation. + ~~ +!!! error TS1109: Expression expected. + ~~~~~ +!!! error TS1138: Parameter declaration expected. + ~~~~~ +!!! error TS2304: Cannot find name 'await'. + ~ +!!! error TS1005: ';' expected. + ~ +!!! error TS1128: Declaration or statement expected. + ~ +!!! error TS1109: Expression expected. + } \ No newline at end of file diff --git a/tests/baselines/reference/asyncFunctionDeclaration10_es2017.js b/tests/baselines/reference/asyncFunctionDeclaration10_es2017.js new file mode 100644 index 0000000000..0e687c1e0d --- /dev/null +++ b/tests/baselines/reference/asyncFunctionDeclaration10_es2017.js @@ -0,0 +1,7 @@ +//// [asyncFunctionDeclaration10_es2017.ts] +async function foo(a = await => await): Promise { +} + +//// [asyncFunctionDeclaration10_es2017.js] +await; +Promise < void > {}; diff --git a/tests/baselines/reference/asyncFunctionDeclaration11_es2017.js b/tests/baselines/reference/asyncFunctionDeclaration11_es2017.js new file mode 100644 index 0000000000..0ae906ebfe --- /dev/null +++ b/tests/baselines/reference/asyncFunctionDeclaration11_es2017.js @@ -0,0 +1,7 @@ +//// [asyncFunctionDeclaration11_es2017.ts] +async function await(): Promise { +} + +//// [asyncFunctionDeclaration11_es2017.js] +async function await() { +} diff --git a/tests/baselines/reference/asyncFunctionDeclaration11_es2017.symbols b/tests/baselines/reference/asyncFunctionDeclaration11_es2017.symbols new file mode 100644 index 0000000000..02c35d81d6 --- /dev/null +++ b/tests/baselines/reference/asyncFunctionDeclaration11_es2017.symbols @@ -0,0 +1,5 @@ +=== tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration11_es2017.ts === +async function await(): Promise { +>await : Symbol(await, Decl(asyncFunctionDeclaration11_es2017.ts, 0, 0)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) +} diff --git a/tests/baselines/reference/asyncFunctionDeclaration11_es2017.types b/tests/baselines/reference/asyncFunctionDeclaration11_es2017.types new file mode 100644 index 0000000000..b86601bf33 --- /dev/null +++ b/tests/baselines/reference/asyncFunctionDeclaration11_es2017.types @@ -0,0 +1,5 @@ +=== tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration11_es2017.ts === +async function await(): Promise { +>await : () => Promise +>Promise : Promise +} diff --git a/tests/baselines/reference/asyncFunctionDeclaration12_es2017.errors.txt b/tests/baselines/reference/asyncFunctionDeclaration12_es2017.errors.txt new file mode 100644 index 0000000000..f951bee715 --- /dev/null +++ b/tests/baselines/reference/asyncFunctionDeclaration12_es2017.errors.txt @@ -0,0 +1,16 @@ +tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration12_es2017.ts(1,24): error TS1005: '(' expected. +tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration12_es2017.ts(1,29): error TS1005: '=' expected. +tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration12_es2017.ts(1,33): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value. +tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration12_es2017.ts(1,47): error TS1005: '=>' expected. + + +==== tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration12_es2017.ts (4 errors) ==== + var v = async function await(): Promise { } + ~~~~~ +!!! error TS1005: '(' expected. + ~ +!!! error TS1005: '=' expected. + ~~~~~~~~~~~~~ +!!! error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value. + ~ +!!! error TS1005: '=>' expected. \ No newline at end of file diff --git a/tests/baselines/reference/asyncFunctionDeclaration12_es2017.js b/tests/baselines/reference/asyncFunctionDeclaration12_es2017.js new file mode 100644 index 0000000000..69f5993f5c --- /dev/null +++ b/tests/baselines/reference/asyncFunctionDeclaration12_es2017.js @@ -0,0 +1,5 @@ +//// [asyncFunctionDeclaration12_es2017.ts] +var v = async function await(): Promise { } + +//// [asyncFunctionDeclaration12_es2017.js] +var v = , await = () => { }; diff --git a/tests/baselines/reference/asyncFunctionDeclaration13_es2017.errors.txt b/tests/baselines/reference/asyncFunctionDeclaration13_es2017.errors.txt new file mode 100644 index 0000000000..41ea0a7caf --- /dev/null +++ b/tests/baselines/reference/asyncFunctionDeclaration13_es2017.errors.txt @@ -0,0 +1,11 @@ +tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration13_es2017.ts(3,11): error TS2304: Cannot find name 'await'. + + +==== tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration13_es2017.ts (1 errors) ==== + async function foo(): Promise { + // Legal to use 'await' in a type context. + var v: await; + ~~~~~ +!!! error TS2304: Cannot find name 'await'. + } + \ No newline at end of file diff --git a/tests/baselines/reference/asyncFunctionDeclaration13_es2017.js b/tests/baselines/reference/asyncFunctionDeclaration13_es2017.js new file mode 100644 index 0000000000..a16236aea7 --- /dev/null +++ b/tests/baselines/reference/asyncFunctionDeclaration13_es2017.js @@ -0,0 +1,12 @@ +//// [asyncFunctionDeclaration13_es2017.ts] +async function foo(): Promise { + // Legal to use 'await' in a type context. + var v: await; +} + + +//// [asyncFunctionDeclaration13_es2017.js] +async function foo() { + // Legal to use 'await' in a type context. + var v; +} diff --git a/tests/baselines/reference/asyncFunctionDeclaration14_es2017.js b/tests/baselines/reference/asyncFunctionDeclaration14_es2017.js new file mode 100644 index 0000000000..308b8f1763 --- /dev/null +++ b/tests/baselines/reference/asyncFunctionDeclaration14_es2017.js @@ -0,0 +1,9 @@ +//// [asyncFunctionDeclaration14_es2017.ts] +async function foo(): Promise { + return; +} + +//// [asyncFunctionDeclaration14_es2017.js] +async function foo() { + return; +} diff --git a/tests/baselines/reference/asyncFunctionDeclaration14_es2017.symbols b/tests/baselines/reference/asyncFunctionDeclaration14_es2017.symbols new file mode 100644 index 0000000000..1b5bca844c --- /dev/null +++ b/tests/baselines/reference/asyncFunctionDeclaration14_es2017.symbols @@ -0,0 +1,7 @@ +=== tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration14_es2017.ts === +async function foo(): Promise { +>foo : Symbol(foo, Decl(asyncFunctionDeclaration14_es2017.ts, 0, 0)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + + return; +} diff --git a/tests/baselines/reference/asyncFunctionDeclaration14_es2017.types b/tests/baselines/reference/asyncFunctionDeclaration14_es2017.types new file mode 100644 index 0000000000..1e505f93a2 --- /dev/null +++ b/tests/baselines/reference/asyncFunctionDeclaration14_es2017.types @@ -0,0 +1,7 @@ +=== tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration14_es2017.ts === +async function foo(): Promise { +>foo : () => Promise +>Promise : Promise + + return; +} diff --git a/tests/baselines/reference/asyncFunctionDeclaration15_es2017.errors.txt b/tests/baselines/reference/asyncFunctionDeclaration15_es2017.errors.txt new file mode 100644 index 0000000000..efc1e2440b --- /dev/null +++ b/tests/baselines/reference/asyncFunctionDeclaration15_es2017.errors.txt @@ -0,0 +1,48 @@ +tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration15_es2017.ts(6,23): error TS1064: The return type of an async function or method must be the global Promise type. +tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration15_es2017.ts(7,23): error TS1064: The return type of an async function or method must be the global Promise type. +tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration15_es2017.ts(8,23): error TS1064: The return type of an async function or method must be the global Promise type. +tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration15_es2017.ts(9,23): error TS1064: The return type of an async function or method must be the global Promise type. +tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration15_es2017.ts(10,23): error TS1064: The return type of an async function or method must be the global Promise type. +tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration15_es2017.ts(17,16): error TS1059: Return expression in async function does not have a valid callable 'then' member. +tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration15_es2017.ts(23,25): error TS1058: Operand for 'await' does not have a valid callable 'then' member. + + +==== tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration15_es2017.ts (7 errors) ==== + declare class Thenable { then(): void; } + declare let a: any; + declare let obj: { then: string; }; + declare let thenable: Thenable; + async function fn1() { } // valid: Promise + async function fn2(): { } { } // error + ~~~ +!!! error TS1064: The return type of an async function or method must be the global Promise type. + async function fn3(): any { } // error + ~~~ +!!! error TS1064: The return type of an async function or method must be the global Promise type. + async function fn4(): number { } // error + ~~~~~~ +!!! error TS1064: The return type of an async function or method must be the global Promise type. + async function fn5(): PromiseLike { } // error + ~~~~~~~~~~~~~~~~~ +!!! error TS1064: The return type of an async function or method must be the global Promise type. + async function fn6(): Thenable { } // error + ~~~~~~~~ +!!! error TS1064: The return type of an async function or method must be the global Promise type. + async function fn7() { return; } // valid: Promise + async function fn8() { return 1; } // valid: Promise + async function fn9() { return null; } // valid: Promise + async function fn10() { return undefined; } // valid: Promise + async function fn11() { return a; } // valid: Promise + async function fn12() { return obj; } // valid: Promise<{ then: string; }> + async function fn13() { return thenable; } // error + ~~~~ +!!! error TS1059: Return expression in async function does not have a valid callable 'then' member. + async function fn14() { await 1; } // valid: Promise + async function fn15() { await null; } // valid: Promise + async function fn16() { await undefined; } // valid: Promise + async function fn17() { await a; } // valid: Promise + async function fn18() { await obj; } // valid: Promise + async function fn19() { await thenable; } // error + ~~~~~~~~~~~~~~ +!!! error TS1058: Operand for 'await' does not have a valid callable 'then' member. + \ No newline at end of file diff --git a/tests/baselines/reference/asyncFunctionDeclaration15_es2017.js b/tests/baselines/reference/asyncFunctionDeclaration15_es2017.js new file mode 100644 index 0000000000..5704366025 --- /dev/null +++ b/tests/baselines/reference/asyncFunctionDeclaration15_es2017.js @@ -0,0 +1,64 @@ +//// [asyncFunctionDeclaration15_es2017.ts] +declare class Thenable { then(): void; } +declare let a: any; +declare let obj: { then: string; }; +declare let thenable: Thenable; +async function fn1() { } // valid: Promise +async function fn2(): { } { } // error +async function fn3(): any { } // error +async function fn4(): number { } // error +async function fn5(): PromiseLike { } // error +async function fn6(): Thenable { } // error +async function fn7() { return; } // valid: Promise +async function fn8() { return 1; } // valid: Promise +async function fn9() { return null; } // valid: Promise +async function fn10() { return undefined; } // valid: Promise +async function fn11() { return a; } // valid: Promise +async function fn12() { return obj; } // valid: Promise<{ then: string; }> +async function fn13() { return thenable; } // error +async function fn14() { await 1; } // valid: Promise +async function fn15() { await null; } // valid: Promise +async function fn16() { await undefined; } // valid: Promise +async function fn17() { await a; } // valid: Promise +async function fn18() { await obj; } // valid: Promise +async function fn19() { await thenable; } // error + + +//// [asyncFunctionDeclaration15_es2017.js] +async function fn1() { } // valid: Promise +// valid: Promise +async function fn2() { } // error +// error +async function fn3() { } // error +// error +async function fn4() { } // error +// error +async function fn5() { } // error +// error +async function fn6() { } // error +// error +async function fn7() { return; } // valid: Promise +// valid: Promise +async function fn8() { return 1; } // valid: Promise +// valid: Promise +async function fn9() { return null; } // valid: Promise +// valid: Promise +async function fn10() { return undefined; } // valid: Promise +// valid: Promise +async function fn11() { return a; } // valid: Promise +// valid: Promise +async function fn12() { return obj; } // valid: Promise<{ then: string; }> +// valid: Promise<{ then: string; }> +async function fn13() { return thenable; } // error +// error +async function fn14() { await 1; } // valid: Promise +// valid: Promise +async function fn15() { await null; } // valid: Promise +// valid: Promise +async function fn16() { await undefined; } // valid: Promise +// valid: Promise +async function fn17() { await a; } // valid: Promise +// valid: Promise +async function fn18() { await obj; } // valid: Promise +// valid: Promise +async function fn19() { await thenable; } // error diff --git a/tests/baselines/reference/asyncFunctionDeclaration1_es2017.js b/tests/baselines/reference/asyncFunctionDeclaration1_es2017.js new file mode 100644 index 0000000000..549fd226b2 --- /dev/null +++ b/tests/baselines/reference/asyncFunctionDeclaration1_es2017.js @@ -0,0 +1,7 @@ +//// [asyncFunctionDeclaration1_es2017.ts] +async function foo(): Promise { +} + +//// [asyncFunctionDeclaration1_es2017.js] +async function foo() { +} diff --git a/tests/baselines/reference/asyncFunctionDeclaration1_es2017.symbols b/tests/baselines/reference/asyncFunctionDeclaration1_es2017.symbols new file mode 100644 index 0000000000..a712df4589 --- /dev/null +++ b/tests/baselines/reference/asyncFunctionDeclaration1_es2017.symbols @@ -0,0 +1,5 @@ +=== tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration1_es2017.ts === +async function foo(): Promise { +>foo : Symbol(foo, Decl(asyncFunctionDeclaration1_es2017.ts, 0, 0)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) +} diff --git a/tests/baselines/reference/asyncFunctionDeclaration1_es2017.types b/tests/baselines/reference/asyncFunctionDeclaration1_es2017.types new file mode 100644 index 0000000000..ff97e686c4 --- /dev/null +++ b/tests/baselines/reference/asyncFunctionDeclaration1_es2017.types @@ -0,0 +1,5 @@ +=== tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration1_es2017.ts === +async function foo(): Promise { +>foo : () => Promise +>Promise : Promise +} diff --git a/tests/baselines/reference/asyncFunctionDeclaration2_es2017.js b/tests/baselines/reference/asyncFunctionDeclaration2_es2017.js new file mode 100644 index 0000000000..6de061456e --- /dev/null +++ b/tests/baselines/reference/asyncFunctionDeclaration2_es2017.js @@ -0,0 +1,7 @@ +//// [asyncFunctionDeclaration2_es2017.ts] +function f(await) { +} + +//// [asyncFunctionDeclaration2_es2017.js] +function f(await) { +} diff --git a/tests/baselines/reference/asyncFunctionDeclaration2_es2017.symbols b/tests/baselines/reference/asyncFunctionDeclaration2_es2017.symbols new file mode 100644 index 0000000000..aed41f5031 --- /dev/null +++ b/tests/baselines/reference/asyncFunctionDeclaration2_es2017.symbols @@ -0,0 +1,5 @@ +=== tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration2_es2017.ts === +function f(await) { +>f : Symbol(f, Decl(asyncFunctionDeclaration2_es2017.ts, 0, 0)) +>await : Symbol(await, Decl(asyncFunctionDeclaration2_es2017.ts, 0, 11)) +} diff --git a/tests/baselines/reference/asyncFunctionDeclaration2_es2017.types b/tests/baselines/reference/asyncFunctionDeclaration2_es2017.types new file mode 100644 index 0000000000..8413bea692 --- /dev/null +++ b/tests/baselines/reference/asyncFunctionDeclaration2_es2017.types @@ -0,0 +1,5 @@ +=== tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration2_es2017.ts === +function f(await) { +>f : (await: any) => void +>await : any +} diff --git a/tests/baselines/reference/asyncFunctionDeclaration3_es2017.errors.txt b/tests/baselines/reference/asyncFunctionDeclaration3_es2017.errors.txt new file mode 100644 index 0000000000..53a8507483 --- /dev/null +++ b/tests/baselines/reference/asyncFunctionDeclaration3_es2017.errors.txt @@ -0,0 +1,8 @@ +tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration3_es2017.ts(1,20): error TS2372: Parameter 'await' cannot be referenced in its initializer. + + +==== tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration3_es2017.ts (1 errors) ==== + function f(await = await) { + ~~~~~ +!!! error TS2372: Parameter 'await' cannot be referenced in its initializer. + } \ No newline at end of file diff --git a/tests/baselines/reference/asyncFunctionDeclaration3_es2017.js b/tests/baselines/reference/asyncFunctionDeclaration3_es2017.js new file mode 100644 index 0000000000..d6110265fd --- /dev/null +++ b/tests/baselines/reference/asyncFunctionDeclaration3_es2017.js @@ -0,0 +1,7 @@ +//// [asyncFunctionDeclaration3_es2017.ts] +function f(await = await) { +} + +//// [asyncFunctionDeclaration3_es2017.js] +function f(await = await) { +} diff --git a/tests/baselines/reference/asyncFunctionDeclaration4_es2017.js b/tests/baselines/reference/asyncFunctionDeclaration4_es2017.js new file mode 100644 index 0000000000..6209531e54 --- /dev/null +++ b/tests/baselines/reference/asyncFunctionDeclaration4_es2017.js @@ -0,0 +1,7 @@ +//// [asyncFunctionDeclaration4_es2017.ts] +function await() { +} + +//// [asyncFunctionDeclaration4_es2017.js] +function await() { +} diff --git a/tests/baselines/reference/asyncFunctionDeclaration4_es2017.symbols b/tests/baselines/reference/asyncFunctionDeclaration4_es2017.symbols new file mode 100644 index 0000000000..7afbd879c5 --- /dev/null +++ b/tests/baselines/reference/asyncFunctionDeclaration4_es2017.symbols @@ -0,0 +1,4 @@ +=== tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration4_es2017.ts === +function await() { +>await : Symbol(await, Decl(asyncFunctionDeclaration4_es2017.ts, 0, 0)) +} diff --git a/tests/baselines/reference/asyncFunctionDeclaration4_es2017.types b/tests/baselines/reference/asyncFunctionDeclaration4_es2017.types new file mode 100644 index 0000000000..f7c4248f7c --- /dev/null +++ b/tests/baselines/reference/asyncFunctionDeclaration4_es2017.types @@ -0,0 +1,4 @@ +=== tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration4_es2017.ts === +function await() { +>await : () => void +} diff --git a/tests/baselines/reference/asyncFunctionDeclaration5_es2017.errors.txt b/tests/baselines/reference/asyncFunctionDeclaration5_es2017.errors.txt new file mode 100644 index 0000000000..ad8c028020 --- /dev/null +++ b/tests/baselines/reference/asyncFunctionDeclaration5_es2017.errors.txt @@ -0,0 +1,20 @@ +tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration5_es2017.ts(1,20): error TS1138: Parameter declaration expected. +tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration5_es2017.ts(1,20): error TS2304: Cannot find name 'await'. +tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration5_es2017.ts(1,25): error TS1005: ';' expected. +tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration5_es2017.ts(1,26): error TS1128: Declaration or statement expected. +tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration5_es2017.ts(1,40): error TS1109: Expression expected. + + +==== tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration5_es2017.ts (5 errors) ==== + async function foo(await): Promise { + ~~~~~ +!!! error TS1138: Parameter declaration expected. + ~~~~~ +!!! error TS2304: Cannot find name 'await'. + ~ +!!! error TS1005: ';' expected. + ~ +!!! error TS1128: Declaration or statement expected. + ~ +!!! error TS1109: Expression expected. + } \ No newline at end of file diff --git a/tests/baselines/reference/asyncFunctionDeclaration5_es2017.js b/tests/baselines/reference/asyncFunctionDeclaration5_es2017.js new file mode 100644 index 0000000000..13c04c5d5b --- /dev/null +++ b/tests/baselines/reference/asyncFunctionDeclaration5_es2017.js @@ -0,0 +1,7 @@ +//// [asyncFunctionDeclaration5_es2017.ts] +async function foo(await): Promise { +} + +//// [asyncFunctionDeclaration5_es2017.js] +await; +Promise < void > {}; diff --git a/tests/baselines/reference/asyncFunctionDeclaration6_es2017.errors.txt b/tests/baselines/reference/asyncFunctionDeclaration6_es2017.errors.txt new file mode 100644 index 0000000000..b5a5ddccdc --- /dev/null +++ b/tests/baselines/reference/asyncFunctionDeclaration6_es2017.errors.txt @@ -0,0 +1,11 @@ +tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration6_es2017.ts(1,24): error TS2524: 'await' expressions cannot be used in a parameter initializer. +tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration6_es2017.ts(1,29): error TS1109: Expression expected. + + +==== tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration6_es2017.ts (2 errors) ==== + async function foo(a = await): Promise { + ~~~~~ +!!! error TS2524: 'await' expressions cannot be used in a parameter initializer. + ~ +!!! error TS1109: Expression expected. + } \ No newline at end of file diff --git a/tests/baselines/reference/asyncFunctionDeclaration6_es2017.js b/tests/baselines/reference/asyncFunctionDeclaration6_es2017.js new file mode 100644 index 0000000000..6df0200084 --- /dev/null +++ b/tests/baselines/reference/asyncFunctionDeclaration6_es2017.js @@ -0,0 +1,7 @@ +//// [asyncFunctionDeclaration6_es2017.ts] +async function foo(a = await): Promise { +} + +//// [asyncFunctionDeclaration6_es2017.js] +async function foo(a = await ) { +} diff --git a/tests/baselines/reference/asyncFunctionDeclaration7_es2017.errors.txt b/tests/baselines/reference/asyncFunctionDeclaration7_es2017.errors.txt new file mode 100644 index 0000000000..ad9ec9a043 --- /dev/null +++ b/tests/baselines/reference/asyncFunctionDeclaration7_es2017.errors.txt @@ -0,0 +1,14 @@ +tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration7_es2017.ts(3,26): error TS2524: 'await' expressions cannot be used in a parameter initializer. +tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration7_es2017.ts(3,31): error TS1109: Expression expected. + + +==== tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration7_es2017.ts (2 errors) ==== + async function bar(): Promise { + // 'await' here is an identifier, and not a yield expression. + async function foo(a = await): Promise { + ~~~~~ +!!! error TS2524: 'await' expressions cannot be used in a parameter initializer. + ~ +!!! error TS1109: Expression expected. + } + } \ No newline at end of file diff --git a/tests/baselines/reference/asyncFunctionDeclaration7_es2017.js b/tests/baselines/reference/asyncFunctionDeclaration7_es2017.js new file mode 100644 index 0000000000..c9aaa80b9b --- /dev/null +++ b/tests/baselines/reference/asyncFunctionDeclaration7_es2017.js @@ -0,0 +1,13 @@ +//// [asyncFunctionDeclaration7_es2017.ts] +async function bar(): Promise { + // 'await' here is an identifier, and not a yield expression. + async function foo(a = await): Promise { + } +} + +//// [asyncFunctionDeclaration7_es2017.js] +async function bar() { + // 'await' here is an identifier, and not a yield expression. + async function foo(a = await ) { + } +} diff --git a/tests/baselines/reference/asyncFunctionDeclaration8_es2017.errors.txt b/tests/baselines/reference/asyncFunctionDeclaration8_es2017.errors.txt new file mode 100644 index 0000000000..b82f012d69 --- /dev/null +++ b/tests/baselines/reference/asyncFunctionDeclaration8_es2017.errors.txt @@ -0,0 +1,10 @@ +tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration8_es2017.ts(1,12): error TS2304: Cannot find name 'await'. +tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration8_es2017.ts(1,20): error TS2304: Cannot find name 'foo'. + + +==== tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration8_es2017.ts (2 errors) ==== + var v = { [await]: foo } + ~~~~~ +!!! error TS2304: Cannot find name 'await'. + ~~~ +!!! error TS2304: Cannot find name 'foo'. \ No newline at end of file diff --git a/tests/baselines/reference/asyncFunctionDeclaration8_es2017.js b/tests/baselines/reference/asyncFunctionDeclaration8_es2017.js new file mode 100644 index 0000000000..db7bfa4f9f --- /dev/null +++ b/tests/baselines/reference/asyncFunctionDeclaration8_es2017.js @@ -0,0 +1,5 @@ +//// [asyncFunctionDeclaration8_es2017.ts] +var v = { [await]: foo } + +//// [asyncFunctionDeclaration8_es2017.js] +var v = { [await]: foo }; diff --git a/tests/baselines/reference/asyncFunctionDeclaration9_es2017.errors.txt b/tests/baselines/reference/asyncFunctionDeclaration9_es2017.errors.txt new file mode 100644 index 0000000000..27c41d8b25 --- /dev/null +++ b/tests/baselines/reference/asyncFunctionDeclaration9_es2017.errors.txt @@ -0,0 +1,9 @@ +tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration9_es2017.ts(2,19): error TS1109: Expression expected. + + +==== tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration9_es2017.ts (1 errors) ==== + async function foo(): Promise { + var v = { [await]: foo } + ~ +!!! error TS1109: Expression expected. + } \ No newline at end of file diff --git a/tests/baselines/reference/asyncFunctionDeclaration9_es2017.js b/tests/baselines/reference/asyncFunctionDeclaration9_es2017.js new file mode 100644 index 0000000000..08cb8e44ba --- /dev/null +++ b/tests/baselines/reference/asyncFunctionDeclaration9_es2017.js @@ -0,0 +1,9 @@ +//// [asyncFunctionDeclaration9_es2017.ts] +async function foo(): Promise { + var v = { [await]: foo } +} + +//// [asyncFunctionDeclaration9_es2017.js] +async function foo() { + var v = { [await ]: foo }; +} diff --git a/tests/baselines/reference/asyncGetter_es2017.errors.txt b/tests/baselines/reference/asyncGetter_es2017.errors.txt new file mode 100644 index 0000000000..386e95d597 --- /dev/null +++ b/tests/baselines/reference/asyncGetter_es2017.errors.txt @@ -0,0 +1,13 @@ +tests/cases/conformance/async/es2017/asyncGetter_es2017.ts(2,3): error TS1042: 'async' modifier cannot be used here. +tests/cases/conformance/async/es2017/asyncGetter_es2017.ts(2,13): error TS2378: A 'get' accessor must return a value. + + +==== tests/cases/conformance/async/es2017/asyncGetter_es2017.ts (2 errors) ==== + class C { + async get foo() { + ~~~~~ +!!! error TS1042: 'async' modifier cannot be used here. + ~~~ +!!! error TS2378: A 'get' accessor must return a value. + } + } \ No newline at end of file diff --git a/tests/baselines/reference/asyncGetter_es2017.js b/tests/baselines/reference/asyncGetter_es2017.js new file mode 100644 index 0000000000..ad8fa347cb --- /dev/null +++ b/tests/baselines/reference/asyncGetter_es2017.js @@ -0,0 +1,11 @@ +//// [asyncGetter_es2017.ts] +class C { + async get foo() { + } +} + +//// [asyncGetter_es2017.js] +class C { + async get foo() { + } +} diff --git a/tests/baselines/reference/asyncImportedPromise_es2017.errors.txt b/tests/baselines/reference/asyncImportedPromise_es2017.errors.txt new file mode 100644 index 0000000000..a0348b2e69 --- /dev/null +++ b/tests/baselines/reference/asyncImportedPromise_es2017.errors.txt @@ -0,0 +1,13 @@ +tests/cases/conformance/async/es2017/test.ts(3,25): error TS1064: The return type of an async function or method must be the global Promise type. + + +==== tests/cases/conformance/async/es2017/task.ts (0 errors) ==== + export class Task extends Promise { } + +==== tests/cases/conformance/async/es2017/test.ts (1 errors) ==== + import { Task } from "./task"; + class Test { + async example(): Task { return; } + ~~~~~~~ +!!! error TS1064: The return type of an async function or method must be the global Promise type. + } \ No newline at end of file diff --git a/tests/baselines/reference/asyncImportedPromise_es2017.js b/tests/baselines/reference/asyncImportedPromise_es2017.js new file mode 100644 index 0000000000..a48c58c170 --- /dev/null +++ b/tests/baselines/reference/asyncImportedPromise_es2017.js @@ -0,0 +1,21 @@ +//// [tests/cases/conformance/async/es2017/asyncImportedPromise_es2017.ts] //// + +//// [task.ts] +export class Task extends Promise { } + +//// [test.ts] +import { Task } from "./task"; +class Test { + async example(): Task { return; } +} + +//// [task.js] +"use strict"; +class Task extends Promise { +} +exports.Task = Task; +//// [test.js] +"use strict"; +class Test { + async example() { return; } +} diff --git a/tests/baselines/reference/asyncInterface_es2017.errors.txt b/tests/baselines/reference/asyncInterface_es2017.errors.txt new file mode 100644 index 0000000000..dfbc878979 --- /dev/null +++ b/tests/baselines/reference/asyncInterface_es2017.errors.txt @@ -0,0 +1,8 @@ +tests/cases/conformance/async/es2017/asyncInterface_es2017.ts(1,1): error TS1042: 'async' modifier cannot be used here. + + +==== tests/cases/conformance/async/es2017/asyncInterface_es2017.ts (1 errors) ==== + async interface I { + ~~~~~ +!!! error TS1042: 'async' modifier cannot be used here. + } \ No newline at end of file diff --git a/tests/baselines/reference/asyncInterface_es2017.js b/tests/baselines/reference/asyncInterface_es2017.js new file mode 100644 index 0000000000..4d89738953 --- /dev/null +++ b/tests/baselines/reference/asyncInterface_es2017.js @@ -0,0 +1,5 @@ +//// [asyncInterface_es2017.ts] +async interface I { +} + +//// [asyncInterface_es2017.js] diff --git a/tests/baselines/reference/asyncMethodWithSuper_es2017.js b/tests/baselines/reference/asyncMethodWithSuper_es2017.js new file mode 100644 index 0000000000..b692579316 --- /dev/null +++ b/tests/baselines/reference/asyncMethodWithSuper_es2017.js @@ -0,0 +1,90 @@ +//// [asyncMethodWithSuper_es2017.ts] +class A { + x() { + } +} + +class B extends A { + // async method with only call/get on 'super' does not require a binding + async simple() { + // call with property access + super.x(); + + // call with element access + super["x"](); + + // property access (read) + const a = super.x; + + // element access (read) + const b = super["x"]; + } + + // async method with assignment/destructuring on 'super' requires a binding + async advanced() { + const f = () => {}; + + // call with property access + super.x(); + + // call with element access + super["x"](); + + // property access (read) + const a = super.x; + + // element access (read) + const b = super["x"]; + + // property access (assign) + super.x = f; + + // element access (assign) + super["x"] = f; + + // destructuring assign with property access + ({ f: super.x } = { f }); + + // destructuring assign with element access + ({ f: super["x"] } = { f }); + } +} + +//// [asyncMethodWithSuper_es2017.js] +class A { + x() { + } +} +class B extends A { + // async method with only call/get on 'super' does not require a binding + async simple() { + // call with property access + super.x(); + // call with element access + super["x"](); + // property access (read) + const a = super.x; + // element access (read) + const b = super["x"]; + } + // async method with assignment/destructuring on 'super' requires a binding + async advanced() { + const f = () => { }; + // call with property access + super.x(); + // call with element access + super["x"](); + // property access (read) + const a = super.x; + // element access (read) + const b = super["x"]; + // property access (assign) + super.x = f; + // element access (assign) + super["x"] = f; + // destructuring assign with property access + ({ f: super.x } = { f }); + // destructuring assign with element access + ({ f: super["x"] } = { f }); + } +} diff --git a/tests/baselines/reference/asyncMethodWithSuper_es2017.symbols b/tests/baselines/reference/asyncMethodWithSuper_es2017.symbols new file mode 100644 index 0000000000..39ed91d7ac --- /dev/null +++ b/tests/baselines/reference/asyncMethodWithSuper_es2017.symbols @@ -0,0 +1,102 @@ +=== tests/cases/conformance/async/es2017/asyncMethodWithSuper_es2017.ts === +class A { +>A : Symbol(A, Decl(asyncMethodWithSuper_es2017.ts, 0, 0)) + + x() { +>x : Symbol(A.x, Decl(asyncMethodWithSuper_es2017.ts, 0, 9)) + } +} + +class B extends A { +>B : Symbol(B, Decl(asyncMethodWithSuper_es2017.ts, 3, 1)) +>A : Symbol(A, Decl(asyncMethodWithSuper_es2017.ts, 0, 0)) + + // async method with only call/get on 'super' does not require a binding + async simple() { +>simple : Symbol(B.simple, Decl(asyncMethodWithSuper_es2017.ts, 5, 19)) + + // call with property access + super.x(); +>super.x : Symbol(A.x, Decl(asyncMethodWithSuper_es2017.ts, 0, 9)) +>super : Symbol(A, Decl(asyncMethodWithSuper_es2017.ts, 0, 0)) +>x : Symbol(A.x, Decl(asyncMethodWithSuper_es2017.ts, 0, 9)) + + // call with element access + super["x"](); +>super : Symbol(A, Decl(asyncMethodWithSuper_es2017.ts, 0, 0)) +>"x" : Symbol(A.x, Decl(asyncMethodWithSuper_es2017.ts, 0, 9)) + + // property access (read) + const a = super.x; +>a : Symbol(a, Decl(asyncMethodWithSuper_es2017.ts, 15, 13)) +>super.x : Symbol(A.x, Decl(asyncMethodWithSuper_es2017.ts, 0, 9)) +>super : Symbol(A, Decl(asyncMethodWithSuper_es2017.ts, 0, 0)) +>x : Symbol(A.x, Decl(asyncMethodWithSuper_es2017.ts, 0, 9)) + + // element access (read) + const b = super["x"]; +>b : Symbol(b, Decl(asyncMethodWithSuper_es2017.ts, 18, 13)) +>super : Symbol(A, Decl(asyncMethodWithSuper_es2017.ts, 0, 0)) +>"x" : Symbol(A.x, Decl(asyncMethodWithSuper_es2017.ts, 0, 9)) + } + + // async method with assignment/destructuring on 'super' requires a binding + async advanced() { +>advanced : Symbol(B.advanced, Decl(asyncMethodWithSuper_es2017.ts, 19, 5)) + + const f = () => {}; +>f : Symbol(f, Decl(asyncMethodWithSuper_es2017.ts, 23, 13)) + + // call with property access + super.x(); +>super.x : Symbol(A.x, Decl(asyncMethodWithSuper_es2017.ts, 0, 9)) +>super : Symbol(A, Decl(asyncMethodWithSuper_es2017.ts, 0, 0)) +>x : Symbol(A.x, Decl(asyncMethodWithSuper_es2017.ts, 0, 9)) + + // call with element access + super["x"](); +>super : Symbol(A, Decl(asyncMethodWithSuper_es2017.ts, 0, 0)) +>"x" : Symbol(A.x, Decl(asyncMethodWithSuper_es2017.ts, 0, 9)) + + // property access (read) + const a = super.x; +>a : Symbol(a, Decl(asyncMethodWithSuper_es2017.ts, 32, 13)) +>super.x : Symbol(A.x, Decl(asyncMethodWithSuper_es2017.ts, 0, 9)) +>super : Symbol(A, Decl(asyncMethodWithSuper_es2017.ts, 0, 0)) +>x : Symbol(A.x, Decl(asyncMethodWithSuper_es2017.ts, 0, 9)) + + // element access (read) + const b = super["x"]; +>b : Symbol(b, Decl(asyncMethodWithSuper_es2017.ts, 35, 13)) +>super : Symbol(A, Decl(asyncMethodWithSuper_es2017.ts, 0, 0)) +>"x" : Symbol(A.x, Decl(asyncMethodWithSuper_es2017.ts, 0, 9)) + + // property access (assign) + super.x = f; +>super.x : Symbol(A.x, Decl(asyncMethodWithSuper_es2017.ts, 0, 9)) +>super : Symbol(A, Decl(asyncMethodWithSuper_es2017.ts, 0, 0)) +>x : Symbol(A.x, Decl(asyncMethodWithSuper_es2017.ts, 0, 9)) +>f : Symbol(f, Decl(asyncMethodWithSuper_es2017.ts, 23, 13)) + + // element access (assign) + super["x"] = f; +>super : Symbol(A, Decl(asyncMethodWithSuper_es2017.ts, 0, 0)) +>"x" : Symbol(A.x, Decl(asyncMethodWithSuper_es2017.ts, 0, 9)) +>f : Symbol(f, Decl(asyncMethodWithSuper_es2017.ts, 23, 13)) + + // destructuring assign with property access + ({ f: super.x } = { f }); +>f : Symbol(f, Decl(asyncMethodWithSuper_es2017.ts, 44, 10)) +>super.x : Symbol(A.x, Decl(asyncMethodWithSuper_es2017.ts, 0, 9)) +>super : Symbol(A, Decl(asyncMethodWithSuper_es2017.ts, 0, 0)) +>x : Symbol(A.x, Decl(asyncMethodWithSuper_es2017.ts, 0, 9)) +>f : Symbol(f, Decl(asyncMethodWithSuper_es2017.ts, 44, 27)) + + // destructuring assign with element access + ({ f: super["x"] } = { f }); +>f : Symbol(f, Decl(asyncMethodWithSuper_es2017.ts, 47, 10)) +>super : Symbol(A, Decl(asyncMethodWithSuper_es2017.ts, 0, 0)) +>"x" : Symbol(A.x, Decl(asyncMethodWithSuper_es2017.ts, 0, 9)) +>f : Symbol(f, Decl(asyncMethodWithSuper_es2017.ts, 47, 30)) + } +} diff --git a/tests/baselines/reference/asyncMethodWithSuper_es2017.types b/tests/baselines/reference/asyncMethodWithSuper_es2017.types new file mode 100644 index 0000000000..b2678e8b83 --- /dev/null +++ b/tests/baselines/reference/asyncMethodWithSuper_es2017.types @@ -0,0 +1,123 @@ +=== tests/cases/conformance/async/es2017/asyncMethodWithSuper_es2017.ts === +class A { +>A : A + + x() { +>x : () => void + } +} + +class B extends A { +>B : B +>A : A + + // async method with only call/get on 'super' does not require a binding + async simple() { +>simple : () => Promise + + // call with property access + super.x(); +>super.x() : void +>super.x : () => void +>super : A +>x : () => void + + // call with element access + super["x"](); +>super["x"]() : void +>super["x"] : () => void +>super : A +>"x" : "x" + + // property access (read) + const a = super.x; +>a : () => void +>super.x : () => void +>super : A +>x : () => void + + // element access (read) + const b = super["x"]; +>b : () => void +>super["x"] : () => void +>super : A +>"x" : "x" + } + + // async method with assignment/destructuring on 'super' requires a binding + async advanced() { +>advanced : () => Promise + + const f = () => {}; +>f : () => void +>() => {} : () => void + + // call with property access + super.x(); +>super.x() : void +>super.x : () => void +>super : A +>x : () => void + + // call with element access + super["x"](); +>super["x"]() : void +>super["x"] : () => void +>super : A +>"x" : "x" + + // property access (read) + const a = super.x; +>a : () => void +>super.x : () => void +>super : A +>x : () => void + + // element access (read) + const b = super["x"]; +>b : () => void +>super["x"] : () => void +>super : A +>"x" : "x" + + // property access (assign) + super.x = f; +>super.x = f : () => void +>super.x : () => void +>super : A +>x : () => void +>f : () => void + + // element access (assign) + super["x"] = f; +>super["x"] = f : () => void +>super["x"] : () => void +>super : A +>"x" : "x" +>f : () => void + + // destructuring assign with property access + ({ f: super.x } = { f }); +>({ f: super.x } = { f }) : { f: () => void; } +>{ f: super.x } = { f } : { f: () => void; } +>{ f: super.x } : { f: () => void; } +>f : () => void +>super.x : () => void +>super : A +>x : () => void +>{ f } : { f: () => void; } +>f : () => void + + // destructuring assign with element access + ({ f: super["x"] } = { f }); +>({ f: super["x"] } = { f }) : { f: () => void; } +>{ f: super["x"] } = { f } : { f: () => void; } +>{ f: super["x"] } : { f: () => void; } +>f : () => void +>super["x"] : () => void +>super : A +>"x" : "x" +>{ f } : { f: () => void; } +>f : () => void + } +} diff --git a/tests/baselines/reference/asyncModule_es2017.errors.txt b/tests/baselines/reference/asyncModule_es2017.errors.txt new file mode 100644 index 0000000000..8b6a4c3dc6 --- /dev/null +++ b/tests/baselines/reference/asyncModule_es2017.errors.txt @@ -0,0 +1,8 @@ +tests/cases/conformance/async/es2017/asyncModule_es2017.ts(1,1): error TS1042: 'async' modifier cannot be used here. + + +==== tests/cases/conformance/async/es2017/asyncModule_es2017.ts (1 errors) ==== + async module M { + ~~~~~ +!!! error TS1042: 'async' modifier cannot be used here. + } \ No newline at end of file diff --git a/tests/baselines/reference/asyncModule_es2017.js b/tests/baselines/reference/asyncModule_es2017.js new file mode 100644 index 0000000000..fe3e17d5e7 --- /dev/null +++ b/tests/baselines/reference/asyncModule_es2017.js @@ -0,0 +1,5 @@ +//// [asyncModule_es2017.ts] +async module M { +} + +//// [asyncModule_es2017.js] diff --git a/tests/baselines/reference/asyncMultiFile_es2017.js b/tests/baselines/reference/asyncMultiFile_es2017.js new file mode 100644 index 0000000000..804a58e4b4 --- /dev/null +++ b/tests/baselines/reference/asyncMultiFile_es2017.js @@ -0,0 +1,11 @@ +//// [tests/cases/conformance/async/es2017/asyncMultiFile_es2017.ts] //// + +//// [a.ts] +async function f() {} +//// [b.ts] +function g() { } + +//// [a.js] +async function f() { } +//// [b.js] +function g() { } diff --git a/tests/baselines/reference/asyncMultiFile_es2017.symbols b/tests/baselines/reference/asyncMultiFile_es2017.symbols new file mode 100644 index 0000000000..9d8ff6dbe8 --- /dev/null +++ b/tests/baselines/reference/asyncMultiFile_es2017.symbols @@ -0,0 +1,8 @@ +=== tests/cases/conformance/async/es2017/a.ts === +async function f() {} +>f : Symbol(f, Decl(a.ts, 0, 0)) + +=== tests/cases/conformance/async/es2017/b.ts === +function g() { } +>g : Symbol(g, Decl(b.ts, 0, 0)) + diff --git a/tests/baselines/reference/asyncMultiFile_es2017.types b/tests/baselines/reference/asyncMultiFile_es2017.types new file mode 100644 index 0000000000..e1f8da34c9 --- /dev/null +++ b/tests/baselines/reference/asyncMultiFile_es2017.types @@ -0,0 +1,8 @@ +=== tests/cases/conformance/async/es2017/a.ts === +async function f() {} +>f : () => Promise + +=== tests/cases/conformance/async/es2017/b.ts === +function g() { } +>g : () => void + diff --git a/tests/baselines/reference/asyncQualifiedReturnType_es2017.errors.txt b/tests/baselines/reference/asyncQualifiedReturnType_es2017.errors.txt new file mode 100644 index 0000000000..b9027c3653 --- /dev/null +++ b/tests/baselines/reference/asyncQualifiedReturnType_es2017.errors.txt @@ -0,0 +1,13 @@ +tests/cases/conformance/async/es2017/asyncQualifiedReturnType_es2017.ts(6,21): error TS1064: The return type of an async function or method must be the global Promise type. + + +==== tests/cases/conformance/async/es2017/asyncQualifiedReturnType_es2017.ts (1 errors) ==== + namespace X { + export class MyPromise extends Promise { + } + } + + async function f(): X.MyPromise { + ~~~~~~~~~~~~~~~~~ +!!! error TS1064: The return type of an async function or method must be the global Promise type. + } \ No newline at end of file diff --git a/tests/baselines/reference/asyncQualifiedReturnType_es2017.js b/tests/baselines/reference/asyncQualifiedReturnType_es2017.js new file mode 100644 index 0000000000..164a4fef61 --- /dev/null +++ b/tests/baselines/reference/asyncQualifiedReturnType_es2017.js @@ -0,0 +1,18 @@ +//// [asyncQualifiedReturnType_es2017.ts] +namespace X { + export class MyPromise extends Promise { + } +} + +async function f(): X.MyPromise { +} + +//// [asyncQualifiedReturnType_es2017.js] +var X; +(function (X) { + class MyPromise extends Promise { + } + X.MyPromise = MyPromise; +})(X || (X = {})); +async function f() { +} diff --git a/tests/baselines/reference/asyncSetter_es2017.errors.txt b/tests/baselines/reference/asyncSetter_es2017.errors.txt new file mode 100644 index 0000000000..0acd8538f2 --- /dev/null +++ b/tests/baselines/reference/asyncSetter_es2017.errors.txt @@ -0,0 +1,10 @@ +tests/cases/conformance/async/es2017/asyncSetter_es2017.ts(2,3): error TS1042: 'async' modifier cannot be used here. + + +==== tests/cases/conformance/async/es2017/asyncSetter_es2017.ts (1 errors) ==== + class C { + async set foo(value) { + ~~~~~ +!!! error TS1042: 'async' modifier cannot be used here. + } + } \ No newline at end of file diff --git a/tests/baselines/reference/asyncSetter_es2017.js b/tests/baselines/reference/asyncSetter_es2017.js new file mode 100644 index 0000000000..8260c5232a --- /dev/null +++ b/tests/baselines/reference/asyncSetter_es2017.js @@ -0,0 +1,11 @@ +//// [asyncSetter_es2017.ts] +class C { + async set foo(value) { + } +} + +//// [asyncSetter_es2017.js] +class C { + async set foo(value) { + } +} diff --git a/tests/baselines/reference/asyncUnParenthesizedArrowFunction_es2017.js b/tests/baselines/reference/asyncUnParenthesizedArrowFunction_es2017.js new file mode 100644 index 0000000000..c97fda4301 --- /dev/null +++ b/tests/baselines/reference/asyncUnParenthesizedArrowFunction_es2017.js @@ -0,0 +1,9 @@ +//// [asyncUnParenthesizedArrowFunction_es2017.ts] + +declare function someOtherFunction(i: any): Promise; +const x = async i => await someOtherFunction(i) +const x1 = async (i) => await someOtherFunction(i); + +//// [asyncUnParenthesizedArrowFunction_es2017.js] +const x = async (i) => await someOtherFunction(i); +const x1 = async (i) => await someOtherFunction(i); diff --git a/tests/baselines/reference/asyncUnParenthesizedArrowFunction_es2017.symbols b/tests/baselines/reference/asyncUnParenthesizedArrowFunction_es2017.symbols new file mode 100644 index 0000000000..b5f83de602 --- /dev/null +++ b/tests/baselines/reference/asyncUnParenthesizedArrowFunction_es2017.symbols @@ -0,0 +1,19 @@ +=== tests/cases/conformance/async/es2017/asyncArrowFunction/asyncUnParenthesizedArrowFunction_es2017.ts === + +declare function someOtherFunction(i: any): Promise; +>someOtherFunction : Symbol(someOtherFunction, Decl(asyncUnParenthesizedArrowFunction_es2017.ts, 0, 0)) +>i : Symbol(i, Decl(asyncUnParenthesizedArrowFunction_es2017.ts, 1, 35)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + +const x = async i => await someOtherFunction(i) +>x : Symbol(x, Decl(asyncUnParenthesizedArrowFunction_es2017.ts, 2, 5)) +>i : Symbol(i, Decl(asyncUnParenthesizedArrowFunction_es2017.ts, 2, 15)) +>someOtherFunction : Symbol(someOtherFunction, Decl(asyncUnParenthesizedArrowFunction_es2017.ts, 0, 0)) +>i : Symbol(i, Decl(asyncUnParenthesizedArrowFunction_es2017.ts, 2, 15)) + +const x1 = async (i) => await someOtherFunction(i); +>x1 : Symbol(x1, Decl(asyncUnParenthesizedArrowFunction_es2017.ts, 3, 5)) +>i : Symbol(i, Decl(asyncUnParenthesizedArrowFunction_es2017.ts, 3, 18)) +>someOtherFunction : Symbol(someOtherFunction, Decl(asyncUnParenthesizedArrowFunction_es2017.ts, 0, 0)) +>i : Symbol(i, Decl(asyncUnParenthesizedArrowFunction_es2017.ts, 3, 18)) + diff --git a/tests/baselines/reference/asyncUnParenthesizedArrowFunction_es2017.types b/tests/baselines/reference/asyncUnParenthesizedArrowFunction_es2017.types new file mode 100644 index 0000000000..ff573e29ed --- /dev/null +++ b/tests/baselines/reference/asyncUnParenthesizedArrowFunction_es2017.types @@ -0,0 +1,25 @@ +=== tests/cases/conformance/async/es2017/asyncArrowFunction/asyncUnParenthesizedArrowFunction_es2017.ts === + +declare function someOtherFunction(i: any): Promise; +>someOtherFunction : (i: any) => Promise +>i : any +>Promise : Promise + +const x = async i => await someOtherFunction(i) +>x : (i: any) => Promise +>async i => await someOtherFunction(i) : (i: any) => Promise +>i : any +>await someOtherFunction(i) : void +>someOtherFunction(i) : Promise +>someOtherFunction : (i: any) => Promise +>i : any + +const x1 = async (i) => await someOtherFunction(i); +>x1 : (i: any) => Promise +>async (i) => await someOtherFunction(i) : (i: any) => Promise +>i : any +>await someOtherFunction(i) : void +>someOtherFunction(i) : Promise +>someOtherFunction : (i: any) => Promise +>i : any + diff --git a/tests/baselines/reference/asyncUseStrict_es2017.js b/tests/baselines/reference/asyncUseStrict_es2017.js new file mode 100644 index 0000000000..1b9d1dc7f2 --- /dev/null +++ b/tests/baselines/reference/asyncUseStrict_es2017.js @@ -0,0 +1,13 @@ +//// [asyncUseStrict_es2017.ts] +declare var a: boolean; +declare var p: Promise; +async function func(): Promise { + "use strict"; + var b = await p || a; +} + +//// [asyncUseStrict_es2017.js] +async function func() { + "use strict"; + var b = await p || a; +} diff --git a/tests/baselines/reference/asyncUseStrict_es2017.symbols b/tests/baselines/reference/asyncUseStrict_es2017.symbols new file mode 100644 index 0000000000..23fd654ca2 --- /dev/null +++ b/tests/baselines/reference/asyncUseStrict_es2017.symbols @@ -0,0 +1,18 @@ +=== tests/cases/conformance/async/es2017/asyncUseStrict_es2017.ts === +declare var a: boolean; +>a : Symbol(a, Decl(asyncUseStrict_es2017.ts, 0, 11)) + +declare var p: Promise; +>p : Symbol(p, Decl(asyncUseStrict_es2017.ts, 1, 11)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + +async function func(): Promise { +>func : Symbol(func, Decl(asyncUseStrict_es2017.ts, 1, 32)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + + "use strict"; + var b = await p || a; +>b : Symbol(b, Decl(asyncUseStrict_es2017.ts, 4, 7)) +>p : Symbol(p, Decl(asyncUseStrict_es2017.ts, 1, 11)) +>a : Symbol(a, Decl(asyncUseStrict_es2017.ts, 0, 11)) +} diff --git a/tests/baselines/reference/asyncUseStrict_es2017.types b/tests/baselines/reference/asyncUseStrict_es2017.types new file mode 100644 index 0000000000..267eda8352 --- /dev/null +++ b/tests/baselines/reference/asyncUseStrict_es2017.types @@ -0,0 +1,22 @@ +=== tests/cases/conformance/async/es2017/asyncUseStrict_es2017.ts === +declare var a: boolean; +>a : boolean + +declare var p: Promise; +>p : Promise +>Promise : Promise + +async function func(): Promise { +>func : () => Promise +>Promise : Promise + + "use strict"; +>"use strict" : "use strict" + + var b = await p || a; +>b : boolean +>await p || a : boolean +>await p : boolean +>p : Promise +>a : boolean +} diff --git a/tests/baselines/reference/awaitBinaryExpression1_es2017.js b/tests/baselines/reference/awaitBinaryExpression1_es2017.js new file mode 100644 index 0000000000..9016a2b582 --- /dev/null +++ b/tests/baselines/reference/awaitBinaryExpression1_es2017.js @@ -0,0 +1,17 @@ +//// [awaitBinaryExpression1_es2017.ts] +declare var a: boolean; +declare var p: Promise; +declare function before(): void; +declare function after(): void; +async function func(): Promise { + before(); + var b = await p || a; + after(); +} + +//// [awaitBinaryExpression1_es2017.js] +async function func() { + before(); + var b = await p || a; + after(); +} diff --git a/tests/baselines/reference/awaitBinaryExpression1_es2017.symbols b/tests/baselines/reference/awaitBinaryExpression1_es2017.symbols new file mode 100644 index 0000000000..827769b3db --- /dev/null +++ b/tests/baselines/reference/awaitBinaryExpression1_es2017.symbols @@ -0,0 +1,29 @@ +=== tests/cases/conformance/async/es2017/awaitBinaryExpression/awaitBinaryExpression1_es2017.ts === +declare var a: boolean; +>a : Symbol(a, Decl(awaitBinaryExpression1_es2017.ts, 0, 11)) + +declare var p: Promise; +>p : Symbol(p, Decl(awaitBinaryExpression1_es2017.ts, 1, 11)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + +declare function before(): void; +>before : Symbol(before, Decl(awaitBinaryExpression1_es2017.ts, 1, 32)) + +declare function after(): void; +>after : Symbol(after, Decl(awaitBinaryExpression1_es2017.ts, 2, 32)) + +async function func(): Promise { +>func : Symbol(func, Decl(awaitBinaryExpression1_es2017.ts, 3, 31)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + + before(); +>before : Symbol(before, Decl(awaitBinaryExpression1_es2017.ts, 1, 32)) + + var b = await p || a; +>b : Symbol(b, Decl(awaitBinaryExpression1_es2017.ts, 6, 7)) +>p : Symbol(p, Decl(awaitBinaryExpression1_es2017.ts, 1, 11)) +>a : Symbol(a, Decl(awaitBinaryExpression1_es2017.ts, 0, 11)) + + after(); +>after : Symbol(after, Decl(awaitBinaryExpression1_es2017.ts, 2, 32)) +} diff --git a/tests/baselines/reference/awaitBinaryExpression1_es2017.types b/tests/baselines/reference/awaitBinaryExpression1_es2017.types new file mode 100644 index 0000000000..c86631804c --- /dev/null +++ b/tests/baselines/reference/awaitBinaryExpression1_es2017.types @@ -0,0 +1,33 @@ +=== tests/cases/conformance/async/es2017/awaitBinaryExpression/awaitBinaryExpression1_es2017.ts === +declare var a: boolean; +>a : boolean + +declare var p: Promise; +>p : Promise +>Promise : Promise + +declare function before(): void; +>before : () => void + +declare function after(): void; +>after : () => void + +async function func(): Promise { +>func : () => Promise +>Promise : Promise + + before(); +>before() : void +>before : () => void + + var b = await p || a; +>b : boolean +>await p || a : boolean +>await p : boolean +>p : Promise +>a : boolean + + after(); +>after() : void +>after : () => void +} diff --git a/tests/baselines/reference/awaitBinaryExpression2_es2017.js b/tests/baselines/reference/awaitBinaryExpression2_es2017.js new file mode 100644 index 0000000000..1d5ad324fd --- /dev/null +++ b/tests/baselines/reference/awaitBinaryExpression2_es2017.js @@ -0,0 +1,17 @@ +//// [awaitBinaryExpression2_es2017.ts] +declare var a: boolean; +declare var p: Promise; +declare function before(): void; +declare function after(): void; +async function func(): Promise { + before(); + var b = await p && a; + after(); +} + +//// [awaitBinaryExpression2_es2017.js] +async function func() { + before(); + var b = await p && a; + after(); +} diff --git a/tests/baselines/reference/awaitBinaryExpression2_es2017.symbols b/tests/baselines/reference/awaitBinaryExpression2_es2017.symbols new file mode 100644 index 0000000000..549eb49cf9 --- /dev/null +++ b/tests/baselines/reference/awaitBinaryExpression2_es2017.symbols @@ -0,0 +1,29 @@ +=== tests/cases/conformance/async/es2017/awaitBinaryExpression/awaitBinaryExpression2_es2017.ts === +declare var a: boolean; +>a : Symbol(a, Decl(awaitBinaryExpression2_es2017.ts, 0, 11)) + +declare var p: Promise; +>p : Symbol(p, Decl(awaitBinaryExpression2_es2017.ts, 1, 11)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + +declare function before(): void; +>before : Symbol(before, Decl(awaitBinaryExpression2_es2017.ts, 1, 32)) + +declare function after(): void; +>after : Symbol(after, Decl(awaitBinaryExpression2_es2017.ts, 2, 32)) + +async function func(): Promise { +>func : Symbol(func, Decl(awaitBinaryExpression2_es2017.ts, 3, 31)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + + before(); +>before : Symbol(before, Decl(awaitBinaryExpression2_es2017.ts, 1, 32)) + + var b = await p && a; +>b : Symbol(b, Decl(awaitBinaryExpression2_es2017.ts, 6, 7)) +>p : Symbol(p, Decl(awaitBinaryExpression2_es2017.ts, 1, 11)) +>a : Symbol(a, Decl(awaitBinaryExpression2_es2017.ts, 0, 11)) + + after(); +>after : Symbol(after, Decl(awaitBinaryExpression2_es2017.ts, 2, 32)) +} diff --git a/tests/baselines/reference/awaitBinaryExpression2_es2017.types b/tests/baselines/reference/awaitBinaryExpression2_es2017.types new file mode 100644 index 0000000000..f803b1ac84 --- /dev/null +++ b/tests/baselines/reference/awaitBinaryExpression2_es2017.types @@ -0,0 +1,33 @@ +=== tests/cases/conformance/async/es2017/awaitBinaryExpression/awaitBinaryExpression2_es2017.ts === +declare var a: boolean; +>a : boolean + +declare var p: Promise; +>p : Promise +>Promise : Promise + +declare function before(): void; +>before : () => void + +declare function after(): void; +>after : () => void + +async function func(): Promise { +>func : () => Promise +>Promise : Promise + + before(); +>before() : void +>before : () => void + + var b = await p && a; +>b : boolean +>await p && a : boolean +>await p : boolean +>p : Promise +>a : boolean + + after(); +>after() : void +>after : () => void +} diff --git a/tests/baselines/reference/awaitBinaryExpression3_es2017.js b/tests/baselines/reference/awaitBinaryExpression3_es2017.js new file mode 100644 index 0000000000..c752ec3be4 --- /dev/null +++ b/tests/baselines/reference/awaitBinaryExpression3_es2017.js @@ -0,0 +1,17 @@ +//// [awaitBinaryExpression3_es2017.ts] +declare var a: number; +declare var p: Promise; +declare function before(): void; +declare function after(): void; +async function func(): Promise { + before(); + var b = await p + a; + after(); +} + +//// [awaitBinaryExpression3_es2017.js] +async function func() { + before(); + var b = await p + a; + after(); +} diff --git a/tests/baselines/reference/awaitBinaryExpression3_es2017.symbols b/tests/baselines/reference/awaitBinaryExpression3_es2017.symbols new file mode 100644 index 0000000000..29c8fb7f39 --- /dev/null +++ b/tests/baselines/reference/awaitBinaryExpression3_es2017.symbols @@ -0,0 +1,29 @@ +=== tests/cases/conformance/async/es2017/awaitBinaryExpression/awaitBinaryExpression3_es2017.ts === +declare var a: number; +>a : Symbol(a, Decl(awaitBinaryExpression3_es2017.ts, 0, 11)) + +declare var p: Promise; +>p : Symbol(p, Decl(awaitBinaryExpression3_es2017.ts, 1, 11)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + +declare function before(): void; +>before : Symbol(before, Decl(awaitBinaryExpression3_es2017.ts, 1, 31)) + +declare function after(): void; +>after : Symbol(after, Decl(awaitBinaryExpression3_es2017.ts, 2, 32)) + +async function func(): Promise { +>func : Symbol(func, Decl(awaitBinaryExpression3_es2017.ts, 3, 31)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + + before(); +>before : Symbol(before, Decl(awaitBinaryExpression3_es2017.ts, 1, 31)) + + var b = await p + a; +>b : Symbol(b, Decl(awaitBinaryExpression3_es2017.ts, 6, 7)) +>p : Symbol(p, Decl(awaitBinaryExpression3_es2017.ts, 1, 11)) +>a : Symbol(a, Decl(awaitBinaryExpression3_es2017.ts, 0, 11)) + + after(); +>after : Symbol(after, Decl(awaitBinaryExpression3_es2017.ts, 2, 32)) +} diff --git a/tests/baselines/reference/awaitBinaryExpression3_es2017.types b/tests/baselines/reference/awaitBinaryExpression3_es2017.types new file mode 100644 index 0000000000..623d069523 --- /dev/null +++ b/tests/baselines/reference/awaitBinaryExpression3_es2017.types @@ -0,0 +1,33 @@ +=== tests/cases/conformance/async/es2017/awaitBinaryExpression/awaitBinaryExpression3_es2017.ts === +declare var a: number; +>a : number + +declare var p: Promise; +>p : Promise +>Promise : Promise + +declare function before(): void; +>before : () => void + +declare function after(): void; +>after : () => void + +async function func(): Promise { +>func : () => Promise +>Promise : Promise + + before(); +>before() : void +>before : () => void + + var b = await p + a; +>b : number +>await p + a : number +>await p : number +>p : Promise +>a : number + + after(); +>after() : void +>after : () => void +} diff --git a/tests/baselines/reference/awaitBinaryExpression4_es2017.js b/tests/baselines/reference/awaitBinaryExpression4_es2017.js new file mode 100644 index 0000000000..3fc296ea14 --- /dev/null +++ b/tests/baselines/reference/awaitBinaryExpression4_es2017.js @@ -0,0 +1,17 @@ +//// [awaitBinaryExpression4_es2017.ts] +declare var a: boolean; +declare var p: Promise; +declare function before(): void; +declare function after(): void; +async function func(): Promise { + before(); + var b = (await p, a); + after(); +} + +//// [awaitBinaryExpression4_es2017.js] +async function func() { + before(); + var b = (await p, a); + after(); +} diff --git a/tests/baselines/reference/awaitBinaryExpression4_es2017.symbols b/tests/baselines/reference/awaitBinaryExpression4_es2017.symbols new file mode 100644 index 0000000000..0db5a20e0c --- /dev/null +++ b/tests/baselines/reference/awaitBinaryExpression4_es2017.symbols @@ -0,0 +1,29 @@ +=== tests/cases/conformance/async/es2017/awaitBinaryExpression/awaitBinaryExpression4_es2017.ts === +declare var a: boolean; +>a : Symbol(a, Decl(awaitBinaryExpression4_es2017.ts, 0, 11)) + +declare var p: Promise; +>p : Symbol(p, Decl(awaitBinaryExpression4_es2017.ts, 1, 11)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + +declare function before(): void; +>before : Symbol(before, Decl(awaitBinaryExpression4_es2017.ts, 1, 32)) + +declare function after(): void; +>after : Symbol(after, Decl(awaitBinaryExpression4_es2017.ts, 2, 32)) + +async function func(): Promise { +>func : Symbol(func, Decl(awaitBinaryExpression4_es2017.ts, 3, 31)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + + before(); +>before : Symbol(before, Decl(awaitBinaryExpression4_es2017.ts, 1, 32)) + + var b = (await p, a); +>b : Symbol(b, Decl(awaitBinaryExpression4_es2017.ts, 6, 7)) +>p : Symbol(p, Decl(awaitBinaryExpression4_es2017.ts, 1, 11)) +>a : Symbol(a, Decl(awaitBinaryExpression4_es2017.ts, 0, 11)) + + after(); +>after : Symbol(after, Decl(awaitBinaryExpression4_es2017.ts, 2, 32)) +} diff --git a/tests/baselines/reference/awaitBinaryExpression4_es2017.types b/tests/baselines/reference/awaitBinaryExpression4_es2017.types new file mode 100644 index 0000000000..714b6b1ea3 --- /dev/null +++ b/tests/baselines/reference/awaitBinaryExpression4_es2017.types @@ -0,0 +1,34 @@ +=== tests/cases/conformance/async/es2017/awaitBinaryExpression/awaitBinaryExpression4_es2017.ts === +declare var a: boolean; +>a : boolean + +declare var p: Promise; +>p : Promise +>Promise : Promise + +declare function before(): void; +>before : () => void + +declare function after(): void; +>after : () => void + +async function func(): Promise { +>func : () => Promise +>Promise : Promise + + before(); +>before() : void +>before : () => void + + var b = (await p, a); +>b : boolean +>(await p, a) : boolean +>await p, a : boolean +>await p : boolean +>p : Promise +>a : boolean + + after(); +>after() : void +>after : () => void +} diff --git a/tests/baselines/reference/awaitBinaryExpression5_es2017.js b/tests/baselines/reference/awaitBinaryExpression5_es2017.js new file mode 100644 index 0000000000..b6c5e12ce7 --- /dev/null +++ b/tests/baselines/reference/awaitBinaryExpression5_es2017.js @@ -0,0 +1,19 @@ +//// [awaitBinaryExpression5_es2017.ts] +declare var a: boolean; +declare var p: Promise; +declare function before(): void; +declare function after(): void; +async function func(): Promise { + before(); + var o: { a: boolean; }; + o.a = await p; + after(); +} + +//// [awaitBinaryExpression5_es2017.js] +async function func() { + before(); + var o; + o.a = await p; + after(); +} diff --git a/tests/baselines/reference/awaitBinaryExpression5_es2017.symbols b/tests/baselines/reference/awaitBinaryExpression5_es2017.symbols new file mode 100644 index 0000000000..e2d30c658f --- /dev/null +++ b/tests/baselines/reference/awaitBinaryExpression5_es2017.symbols @@ -0,0 +1,34 @@ +=== tests/cases/conformance/async/es2017/awaitBinaryExpression/awaitBinaryExpression5_es2017.ts === +declare var a: boolean; +>a : Symbol(a, Decl(awaitBinaryExpression5_es2017.ts, 0, 11)) + +declare var p: Promise; +>p : Symbol(p, Decl(awaitBinaryExpression5_es2017.ts, 1, 11)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + +declare function before(): void; +>before : Symbol(before, Decl(awaitBinaryExpression5_es2017.ts, 1, 32)) + +declare function after(): void; +>after : Symbol(after, Decl(awaitBinaryExpression5_es2017.ts, 2, 32)) + +async function func(): Promise { +>func : Symbol(func, Decl(awaitBinaryExpression5_es2017.ts, 3, 31)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + + before(); +>before : Symbol(before, Decl(awaitBinaryExpression5_es2017.ts, 1, 32)) + + var o: { a: boolean; }; +>o : Symbol(o, Decl(awaitBinaryExpression5_es2017.ts, 6, 7)) +>a : Symbol(a, Decl(awaitBinaryExpression5_es2017.ts, 6, 12)) + + o.a = await p; +>o.a : Symbol(a, Decl(awaitBinaryExpression5_es2017.ts, 6, 12)) +>o : Symbol(o, Decl(awaitBinaryExpression5_es2017.ts, 6, 7)) +>a : Symbol(a, Decl(awaitBinaryExpression5_es2017.ts, 6, 12)) +>p : Symbol(p, Decl(awaitBinaryExpression5_es2017.ts, 1, 11)) + + after(); +>after : Symbol(after, Decl(awaitBinaryExpression5_es2017.ts, 2, 32)) +} diff --git a/tests/baselines/reference/awaitBinaryExpression5_es2017.types b/tests/baselines/reference/awaitBinaryExpression5_es2017.types new file mode 100644 index 0000000000..763f9e5086 --- /dev/null +++ b/tests/baselines/reference/awaitBinaryExpression5_es2017.types @@ -0,0 +1,38 @@ +=== tests/cases/conformance/async/es2017/awaitBinaryExpression/awaitBinaryExpression5_es2017.ts === +declare var a: boolean; +>a : boolean + +declare var p: Promise; +>p : Promise +>Promise : Promise + +declare function before(): void; +>before : () => void + +declare function after(): void; +>after : () => void + +async function func(): Promise { +>func : () => Promise +>Promise : Promise + + before(); +>before() : void +>before : () => void + + var o: { a: boolean; }; +>o : { a: boolean; } +>a : boolean + + o.a = await p; +>o.a = await p : boolean +>o.a : boolean +>o : { a: boolean; } +>a : boolean +>await p : boolean +>p : Promise + + after(); +>after() : void +>after : () => void +} diff --git a/tests/baselines/reference/awaitCallExpression1_es2017.js b/tests/baselines/reference/awaitCallExpression1_es2017.js new file mode 100644 index 0000000000..89fe7dfd91 --- /dev/null +++ b/tests/baselines/reference/awaitCallExpression1_es2017.js @@ -0,0 +1,21 @@ +//// [awaitCallExpression1_es2017.ts] +declare var a: boolean; +declare var p: Promise; +declare function fn(arg0: boolean, arg1: boolean, arg2: boolean): void; +declare var o: { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }; +declare var pfn: Promise<{ (arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +declare var po: Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +declare function before(): void; +declare function after(): void; +async function func(): Promise { + before(); + var b = fn(a, a, a); + after(); +} + +//// [awaitCallExpression1_es2017.js] +async function func() { + before(); + var b = fn(a, a, a); + after(); +} diff --git a/tests/baselines/reference/awaitCallExpression1_es2017.symbols b/tests/baselines/reference/awaitCallExpression1_es2017.symbols new file mode 100644 index 0000000000..68c28d1535 --- /dev/null +++ b/tests/baselines/reference/awaitCallExpression1_es2017.symbols @@ -0,0 +1,59 @@ +=== tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression1_es2017.ts === +declare var a: boolean; +>a : Symbol(a, Decl(awaitCallExpression1_es2017.ts, 0, 11)) + +declare var p: Promise; +>p : Symbol(p, Decl(awaitCallExpression1_es2017.ts, 1, 11)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + +declare function fn(arg0: boolean, arg1: boolean, arg2: boolean): void; +>fn : Symbol(fn, Decl(awaitCallExpression1_es2017.ts, 1, 32)) +>arg0 : Symbol(arg0, Decl(awaitCallExpression1_es2017.ts, 2, 20)) +>arg1 : Symbol(arg1, Decl(awaitCallExpression1_es2017.ts, 2, 34)) +>arg2 : Symbol(arg2, Decl(awaitCallExpression1_es2017.ts, 2, 49)) + +declare var o: { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }; +>o : Symbol(o, Decl(awaitCallExpression1_es2017.ts, 3, 11)) +>fn : Symbol(fn, Decl(awaitCallExpression1_es2017.ts, 3, 16)) +>arg0 : Symbol(arg0, Decl(awaitCallExpression1_es2017.ts, 3, 20)) +>arg1 : Symbol(arg1, Decl(awaitCallExpression1_es2017.ts, 3, 34)) +>arg2 : Symbol(arg2, Decl(awaitCallExpression1_es2017.ts, 3, 49)) + +declare var pfn: Promise<{ (arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +>pfn : Symbol(pfn, Decl(awaitCallExpression1_es2017.ts, 4, 11)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) +>arg0 : Symbol(arg0, Decl(awaitCallExpression1_es2017.ts, 4, 28)) +>arg1 : Symbol(arg1, Decl(awaitCallExpression1_es2017.ts, 4, 42)) +>arg2 : Symbol(arg2, Decl(awaitCallExpression1_es2017.ts, 4, 57)) + +declare var po: Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +>po : Symbol(po, Decl(awaitCallExpression1_es2017.ts, 5, 11)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) +>fn : Symbol(fn, Decl(awaitCallExpression1_es2017.ts, 5, 25)) +>arg0 : Symbol(arg0, Decl(awaitCallExpression1_es2017.ts, 5, 29)) +>arg1 : Symbol(arg1, Decl(awaitCallExpression1_es2017.ts, 5, 43)) +>arg2 : Symbol(arg2, Decl(awaitCallExpression1_es2017.ts, 5, 58)) + +declare function before(): void; +>before : Symbol(before, Decl(awaitCallExpression1_es2017.ts, 5, 84)) + +declare function after(): void; +>after : Symbol(after, Decl(awaitCallExpression1_es2017.ts, 6, 32)) + +async function func(): Promise { +>func : Symbol(func, Decl(awaitCallExpression1_es2017.ts, 7, 31)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + + before(); +>before : Symbol(before, Decl(awaitCallExpression1_es2017.ts, 5, 84)) + + var b = fn(a, a, a); +>b : Symbol(b, Decl(awaitCallExpression1_es2017.ts, 10, 7)) +>fn : Symbol(fn, Decl(awaitCallExpression1_es2017.ts, 1, 32)) +>a : Symbol(a, Decl(awaitCallExpression1_es2017.ts, 0, 11)) +>a : Symbol(a, Decl(awaitCallExpression1_es2017.ts, 0, 11)) +>a : Symbol(a, Decl(awaitCallExpression1_es2017.ts, 0, 11)) + + after(); +>after : Symbol(after, Decl(awaitCallExpression1_es2017.ts, 6, 32)) +} diff --git a/tests/baselines/reference/awaitCallExpression1_es2017.types b/tests/baselines/reference/awaitCallExpression1_es2017.types new file mode 100644 index 0000000000..c5cea09187 --- /dev/null +++ b/tests/baselines/reference/awaitCallExpression1_es2017.types @@ -0,0 +1,62 @@ +=== tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression1_es2017.ts === +declare var a: boolean; +>a : boolean + +declare var p: Promise; +>p : Promise +>Promise : Promise + +declare function fn(arg0: boolean, arg1: boolean, arg2: boolean): void; +>fn : (arg0: boolean, arg1: boolean, arg2: boolean) => void +>arg0 : boolean +>arg1 : boolean +>arg2 : boolean + +declare var o: { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }; +>o : { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; } +>fn : (arg0: boolean, arg1: boolean, arg2: boolean) => void +>arg0 : boolean +>arg1 : boolean +>arg2 : boolean + +declare var pfn: Promise<{ (arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +>pfn : Promise<(arg0: boolean, arg1: boolean, arg2: boolean) => void> +>Promise : Promise +>arg0 : boolean +>arg1 : boolean +>arg2 : boolean + +declare var po: Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +>po : Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }> +>Promise : Promise +>fn : (arg0: boolean, arg1: boolean, arg2: boolean) => void +>arg0 : boolean +>arg1 : boolean +>arg2 : boolean + +declare function before(): void; +>before : () => void + +declare function after(): void; +>after : () => void + +async function func(): Promise { +>func : () => Promise +>Promise : Promise + + before(); +>before() : void +>before : () => void + + var b = fn(a, a, a); +>b : void +>fn(a, a, a) : void +>fn : (arg0: boolean, arg1: boolean, arg2: boolean) => void +>a : boolean +>a : boolean +>a : boolean + + after(); +>after() : void +>after : () => void +} diff --git a/tests/baselines/reference/awaitCallExpression2_es2017.js b/tests/baselines/reference/awaitCallExpression2_es2017.js new file mode 100644 index 0000000000..24b3012f85 --- /dev/null +++ b/tests/baselines/reference/awaitCallExpression2_es2017.js @@ -0,0 +1,21 @@ +//// [awaitCallExpression2_es2017.ts] +declare var a: boolean; +declare var p: Promise; +declare function fn(arg0: boolean, arg1: boolean, arg2: boolean): void; +declare var o: { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }; +declare var pfn: Promise<{ (arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +declare var po: Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +declare function before(): void; +declare function after(): void; +async function func(): Promise { + before(); + var b = fn(await p, a, a); + after(); +} + +//// [awaitCallExpression2_es2017.js] +async function func() { + before(); + var b = fn(await p, a, a); + after(); +} diff --git a/tests/baselines/reference/awaitCallExpression2_es2017.symbols b/tests/baselines/reference/awaitCallExpression2_es2017.symbols new file mode 100644 index 0000000000..4528ae4c07 --- /dev/null +++ b/tests/baselines/reference/awaitCallExpression2_es2017.symbols @@ -0,0 +1,59 @@ +=== tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression2_es2017.ts === +declare var a: boolean; +>a : Symbol(a, Decl(awaitCallExpression2_es2017.ts, 0, 11)) + +declare var p: Promise; +>p : Symbol(p, Decl(awaitCallExpression2_es2017.ts, 1, 11)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + +declare function fn(arg0: boolean, arg1: boolean, arg2: boolean): void; +>fn : Symbol(fn, Decl(awaitCallExpression2_es2017.ts, 1, 32)) +>arg0 : Symbol(arg0, Decl(awaitCallExpression2_es2017.ts, 2, 20)) +>arg1 : Symbol(arg1, Decl(awaitCallExpression2_es2017.ts, 2, 34)) +>arg2 : Symbol(arg2, Decl(awaitCallExpression2_es2017.ts, 2, 49)) + +declare var o: { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }; +>o : Symbol(o, Decl(awaitCallExpression2_es2017.ts, 3, 11)) +>fn : Symbol(fn, Decl(awaitCallExpression2_es2017.ts, 3, 16)) +>arg0 : Symbol(arg0, Decl(awaitCallExpression2_es2017.ts, 3, 20)) +>arg1 : Symbol(arg1, Decl(awaitCallExpression2_es2017.ts, 3, 34)) +>arg2 : Symbol(arg2, Decl(awaitCallExpression2_es2017.ts, 3, 49)) + +declare var pfn: Promise<{ (arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +>pfn : Symbol(pfn, Decl(awaitCallExpression2_es2017.ts, 4, 11)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) +>arg0 : Symbol(arg0, Decl(awaitCallExpression2_es2017.ts, 4, 28)) +>arg1 : Symbol(arg1, Decl(awaitCallExpression2_es2017.ts, 4, 42)) +>arg2 : Symbol(arg2, Decl(awaitCallExpression2_es2017.ts, 4, 57)) + +declare var po: Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +>po : Symbol(po, Decl(awaitCallExpression2_es2017.ts, 5, 11)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) +>fn : Symbol(fn, Decl(awaitCallExpression2_es2017.ts, 5, 25)) +>arg0 : Symbol(arg0, Decl(awaitCallExpression2_es2017.ts, 5, 29)) +>arg1 : Symbol(arg1, Decl(awaitCallExpression2_es2017.ts, 5, 43)) +>arg2 : Symbol(arg2, Decl(awaitCallExpression2_es2017.ts, 5, 58)) + +declare function before(): void; +>before : Symbol(before, Decl(awaitCallExpression2_es2017.ts, 5, 84)) + +declare function after(): void; +>after : Symbol(after, Decl(awaitCallExpression2_es2017.ts, 6, 32)) + +async function func(): Promise { +>func : Symbol(func, Decl(awaitCallExpression2_es2017.ts, 7, 31)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + + before(); +>before : Symbol(before, Decl(awaitCallExpression2_es2017.ts, 5, 84)) + + var b = fn(await p, a, a); +>b : Symbol(b, Decl(awaitCallExpression2_es2017.ts, 10, 7)) +>fn : Symbol(fn, Decl(awaitCallExpression2_es2017.ts, 1, 32)) +>p : Symbol(p, Decl(awaitCallExpression2_es2017.ts, 1, 11)) +>a : Symbol(a, Decl(awaitCallExpression2_es2017.ts, 0, 11)) +>a : Symbol(a, Decl(awaitCallExpression2_es2017.ts, 0, 11)) + + after(); +>after : Symbol(after, Decl(awaitCallExpression2_es2017.ts, 6, 32)) +} diff --git a/tests/baselines/reference/awaitCallExpression2_es2017.types b/tests/baselines/reference/awaitCallExpression2_es2017.types new file mode 100644 index 0000000000..a15609a407 --- /dev/null +++ b/tests/baselines/reference/awaitCallExpression2_es2017.types @@ -0,0 +1,63 @@ +=== tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression2_es2017.ts === +declare var a: boolean; +>a : boolean + +declare var p: Promise; +>p : Promise +>Promise : Promise + +declare function fn(arg0: boolean, arg1: boolean, arg2: boolean): void; +>fn : (arg0: boolean, arg1: boolean, arg2: boolean) => void +>arg0 : boolean +>arg1 : boolean +>arg2 : boolean + +declare var o: { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }; +>o : { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; } +>fn : (arg0: boolean, arg1: boolean, arg2: boolean) => void +>arg0 : boolean +>arg1 : boolean +>arg2 : boolean + +declare var pfn: Promise<{ (arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +>pfn : Promise<(arg0: boolean, arg1: boolean, arg2: boolean) => void> +>Promise : Promise +>arg0 : boolean +>arg1 : boolean +>arg2 : boolean + +declare var po: Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +>po : Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }> +>Promise : Promise +>fn : (arg0: boolean, arg1: boolean, arg2: boolean) => void +>arg0 : boolean +>arg1 : boolean +>arg2 : boolean + +declare function before(): void; +>before : () => void + +declare function after(): void; +>after : () => void + +async function func(): Promise { +>func : () => Promise +>Promise : Promise + + before(); +>before() : void +>before : () => void + + var b = fn(await p, a, a); +>b : void +>fn(await p, a, a) : void +>fn : (arg0: boolean, arg1: boolean, arg2: boolean) => void +>await p : boolean +>p : Promise +>a : boolean +>a : boolean + + after(); +>after() : void +>after : () => void +} diff --git a/tests/baselines/reference/awaitCallExpression3_es2017.js b/tests/baselines/reference/awaitCallExpression3_es2017.js new file mode 100644 index 0000000000..6b432851b0 --- /dev/null +++ b/tests/baselines/reference/awaitCallExpression3_es2017.js @@ -0,0 +1,21 @@ +//// [awaitCallExpression3_es2017.ts] +declare var a: boolean; +declare var p: Promise; +declare function fn(arg0: boolean, arg1: boolean, arg2: boolean): void; +declare var o: { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }; +declare var pfn: Promise<{ (arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +declare var po: Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +declare function before(): void; +declare function after(): void; +async function func(): Promise { + before(); + var b = fn(a, await p, a); + after(); +} + +//// [awaitCallExpression3_es2017.js] +async function func() { + before(); + var b = fn(a, await p, a); + after(); +} diff --git a/tests/baselines/reference/awaitCallExpression3_es2017.symbols b/tests/baselines/reference/awaitCallExpression3_es2017.symbols new file mode 100644 index 0000000000..a1120103fb --- /dev/null +++ b/tests/baselines/reference/awaitCallExpression3_es2017.symbols @@ -0,0 +1,59 @@ +=== tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression3_es2017.ts === +declare var a: boolean; +>a : Symbol(a, Decl(awaitCallExpression3_es2017.ts, 0, 11)) + +declare var p: Promise; +>p : Symbol(p, Decl(awaitCallExpression3_es2017.ts, 1, 11)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + +declare function fn(arg0: boolean, arg1: boolean, arg2: boolean): void; +>fn : Symbol(fn, Decl(awaitCallExpression3_es2017.ts, 1, 32)) +>arg0 : Symbol(arg0, Decl(awaitCallExpression3_es2017.ts, 2, 20)) +>arg1 : Symbol(arg1, Decl(awaitCallExpression3_es2017.ts, 2, 34)) +>arg2 : Symbol(arg2, Decl(awaitCallExpression3_es2017.ts, 2, 49)) + +declare var o: { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }; +>o : Symbol(o, Decl(awaitCallExpression3_es2017.ts, 3, 11)) +>fn : Symbol(fn, Decl(awaitCallExpression3_es2017.ts, 3, 16)) +>arg0 : Symbol(arg0, Decl(awaitCallExpression3_es2017.ts, 3, 20)) +>arg1 : Symbol(arg1, Decl(awaitCallExpression3_es2017.ts, 3, 34)) +>arg2 : Symbol(arg2, Decl(awaitCallExpression3_es2017.ts, 3, 49)) + +declare var pfn: Promise<{ (arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +>pfn : Symbol(pfn, Decl(awaitCallExpression3_es2017.ts, 4, 11)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) +>arg0 : Symbol(arg0, Decl(awaitCallExpression3_es2017.ts, 4, 28)) +>arg1 : Symbol(arg1, Decl(awaitCallExpression3_es2017.ts, 4, 42)) +>arg2 : Symbol(arg2, Decl(awaitCallExpression3_es2017.ts, 4, 57)) + +declare var po: Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +>po : Symbol(po, Decl(awaitCallExpression3_es2017.ts, 5, 11)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) +>fn : Symbol(fn, Decl(awaitCallExpression3_es2017.ts, 5, 25)) +>arg0 : Symbol(arg0, Decl(awaitCallExpression3_es2017.ts, 5, 29)) +>arg1 : Symbol(arg1, Decl(awaitCallExpression3_es2017.ts, 5, 43)) +>arg2 : Symbol(arg2, Decl(awaitCallExpression3_es2017.ts, 5, 58)) + +declare function before(): void; +>before : Symbol(before, Decl(awaitCallExpression3_es2017.ts, 5, 84)) + +declare function after(): void; +>after : Symbol(after, Decl(awaitCallExpression3_es2017.ts, 6, 32)) + +async function func(): Promise { +>func : Symbol(func, Decl(awaitCallExpression3_es2017.ts, 7, 31)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + + before(); +>before : Symbol(before, Decl(awaitCallExpression3_es2017.ts, 5, 84)) + + var b = fn(a, await p, a); +>b : Symbol(b, Decl(awaitCallExpression3_es2017.ts, 10, 7)) +>fn : Symbol(fn, Decl(awaitCallExpression3_es2017.ts, 1, 32)) +>a : Symbol(a, Decl(awaitCallExpression3_es2017.ts, 0, 11)) +>p : Symbol(p, Decl(awaitCallExpression3_es2017.ts, 1, 11)) +>a : Symbol(a, Decl(awaitCallExpression3_es2017.ts, 0, 11)) + + after(); +>after : Symbol(after, Decl(awaitCallExpression3_es2017.ts, 6, 32)) +} diff --git a/tests/baselines/reference/awaitCallExpression3_es2017.types b/tests/baselines/reference/awaitCallExpression3_es2017.types new file mode 100644 index 0000000000..a491836fa0 --- /dev/null +++ b/tests/baselines/reference/awaitCallExpression3_es2017.types @@ -0,0 +1,63 @@ +=== tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression3_es2017.ts === +declare var a: boolean; +>a : boolean + +declare var p: Promise; +>p : Promise +>Promise : Promise + +declare function fn(arg0: boolean, arg1: boolean, arg2: boolean): void; +>fn : (arg0: boolean, arg1: boolean, arg2: boolean) => void +>arg0 : boolean +>arg1 : boolean +>arg2 : boolean + +declare var o: { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }; +>o : { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; } +>fn : (arg0: boolean, arg1: boolean, arg2: boolean) => void +>arg0 : boolean +>arg1 : boolean +>arg2 : boolean + +declare var pfn: Promise<{ (arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +>pfn : Promise<(arg0: boolean, arg1: boolean, arg2: boolean) => void> +>Promise : Promise +>arg0 : boolean +>arg1 : boolean +>arg2 : boolean + +declare var po: Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +>po : Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }> +>Promise : Promise +>fn : (arg0: boolean, arg1: boolean, arg2: boolean) => void +>arg0 : boolean +>arg1 : boolean +>arg2 : boolean + +declare function before(): void; +>before : () => void + +declare function after(): void; +>after : () => void + +async function func(): Promise { +>func : () => Promise +>Promise : Promise + + before(); +>before() : void +>before : () => void + + var b = fn(a, await p, a); +>b : void +>fn(a, await p, a) : void +>fn : (arg0: boolean, arg1: boolean, arg2: boolean) => void +>a : boolean +>await p : boolean +>p : Promise +>a : boolean + + after(); +>after() : void +>after : () => void +} diff --git a/tests/baselines/reference/awaitCallExpression4_es2017.js b/tests/baselines/reference/awaitCallExpression4_es2017.js new file mode 100644 index 0000000000..9243ac58f8 --- /dev/null +++ b/tests/baselines/reference/awaitCallExpression4_es2017.js @@ -0,0 +1,21 @@ +//// [awaitCallExpression4_es2017.ts] +declare var a: boolean; +declare var p: Promise; +declare function fn(arg0: boolean, arg1: boolean, arg2: boolean): void; +declare var o: { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }; +declare var pfn: Promise<{ (arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +declare var po: Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +declare function before(): void; +declare function after(): void; +async function func(): Promise { + before(); + var b = (await pfn)(a, a, a); + after(); +} + +//// [awaitCallExpression4_es2017.js] +async function func() { + before(); + var b = (await pfn)(a, a, a); + after(); +} diff --git a/tests/baselines/reference/awaitCallExpression4_es2017.symbols b/tests/baselines/reference/awaitCallExpression4_es2017.symbols new file mode 100644 index 0000000000..fb607d9841 --- /dev/null +++ b/tests/baselines/reference/awaitCallExpression4_es2017.symbols @@ -0,0 +1,59 @@ +=== tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression4_es2017.ts === +declare var a: boolean; +>a : Symbol(a, Decl(awaitCallExpression4_es2017.ts, 0, 11)) + +declare var p: Promise; +>p : Symbol(p, Decl(awaitCallExpression4_es2017.ts, 1, 11)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + +declare function fn(arg0: boolean, arg1: boolean, arg2: boolean): void; +>fn : Symbol(fn, Decl(awaitCallExpression4_es2017.ts, 1, 32)) +>arg0 : Symbol(arg0, Decl(awaitCallExpression4_es2017.ts, 2, 20)) +>arg1 : Symbol(arg1, Decl(awaitCallExpression4_es2017.ts, 2, 34)) +>arg2 : Symbol(arg2, Decl(awaitCallExpression4_es2017.ts, 2, 49)) + +declare var o: { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }; +>o : Symbol(o, Decl(awaitCallExpression4_es2017.ts, 3, 11)) +>fn : Symbol(fn, Decl(awaitCallExpression4_es2017.ts, 3, 16)) +>arg0 : Symbol(arg0, Decl(awaitCallExpression4_es2017.ts, 3, 20)) +>arg1 : Symbol(arg1, Decl(awaitCallExpression4_es2017.ts, 3, 34)) +>arg2 : Symbol(arg2, Decl(awaitCallExpression4_es2017.ts, 3, 49)) + +declare var pfn: Promise<{ (arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +>pfn : Symbol(pfn, Decl(awaitCallExpression4_es2017.ts, 4, 11)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) +>arg0 : Symbol(arg0, Decl(awaitCallExpression4_es2017.ts, 4, 28)) +>arg1 : Symbol(arg1, Decl(awaitCallExpression4_es2017.ts, 4, 42)) +>arg2 : Symbol(arg2, Decl(awaitCallExpression4_es2017.ts, 4, 57)) + +declare var po: Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +>po : Symbol(po, Decl(awaitCallExpression4_es2017.ts, 5, 11)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) +>fn : Symbol(fn, Decl(awaitCallExpression4_es2017.ts, 5, 25)) +>arg0 : Symbol(arg0, Decl(awaitCallExpression4_es2017.ts, 5, 29)) +>arg1 : Symbol(arg1, Decl(awaitCallExpression4_es2017.ts, 5, 43)) +>arg2 : Symbol(arg2, Decl(awaitCallExpression4_es2017.ts, 5, 58)) + +declare function before(): void; +>before : Symbol(before, Decl(awaitCallExpression4_es2017.ts, 5, 84)) + +declare function after(): void; +>after : Symbol(after, Decl(awaitCallExpression4_es2017.ts, 6, 32)) + +async function func(): Promise { +>func : Symbol(func, Decl(awaitCallExpression4_es2017.ts, 7, 31)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + + before(); +>before : Symbol(before, Decl(awaitCallExpression4_es2017.ts, 5, 84)) + + var b = (await pfn)(a, a, a); +>b : Symbol(b, Decl(awaitCallExpression4_es2017.ts, 10, 7)) +>pfn : Symbol(pfn, Decl(awaitCallExpression4_es2017.ts, 4, 11)) +>a : Symbol(a, Decl(awaitCallExpression4_es2017.ts, 0, 11)) +>a : Symbol(a, Decl(awaitCallExpression4_es2017.ts, 0, 11)) +>a : Symbol(a, Decl(awaitCallExpression4_es2017.ts, 0, 11)) + + after(); +>after : Symbol(after, Decl(awaitCallExpression4_es2017.ts, 6, 32)) +} diff --git a/tests/baselines/reference/awaitCallExpression4_es2017.types b/tests/baselines/reference/awaitCallExpression4_es2017.types new file mode 100644 index 0000000000..3f1b478e66 --- /dev/null +++ b/tests/baselines/reference/awaitCallExpression4_es2017.types @@ -0,0 +1,64 @@ +=== tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression4_es2017.ts === +declare var a: boolean; +>a : boolean + +declare var p: Promise; +>p : Promise +>Promise : Promise + +declare function fn(arg0: boolean, arg1: boolean, arg2: boolean): void; +>fn : (arg0: boolean, arg1: boolean, arg2: boolean) => void +>arg0 : boolean +>arg1 : boolean +>arg2 : boolean + +declare var o: { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }; +>o : { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; } +>fn : (arg0: boolean, arg1: boolean, arg2: boolean) => void +>arg0 : boolean +>arg1 : boolean +>arg2 : boolean + +declare var pfn: Promise<{ (arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +>pfn : Promise<(arg0: boolean, arg1: boolean, arg2: boolean) => void> +>Promise : Promise +>arg0 : boolean +>arg1 : boolean +>arg2 : boolean + +declare var po: Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +>po : Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }> +>Promise : Promise +>fn : (arg0: boolean, arg1: boolean, arg2: boolean) => void +>arg0 : boolean +>arg1 : boolean +>arg2 : boolean + +declare function before(): void; +>before : () => void + +declare function after(): void; +>after : () => void + +async function func(): Promise { +>func : () => Promise +>Promise : Promise + + before(); +>before() : void +>before : () => void + + var b = (await pfn)(a, a, a); +>b : void +>(await pfn)(a, a, a) : void +>(await pfn) : (arg0: boolean, arg1: boolean, arg2: boolean) => void +>await pfn : (arg0: boolean, arg1: boolean, arg2: boolean) => void +>pfn : Promise<(arg0: boolean, arg1: boolean, arg2: boolean) => void> +>a : boolean +>a : boolean +>a : boolean + + after(); +>after() : void +>after : () => void +} diff --git a/tests/baselines/reference/awaitCallExpression5_es2017.js b/tests/baselines/reference/awaitCallExpression5_es2017.js new file mode 100644 index 0000000000..d08823ac5a --- /dev/null +++ b/tests/baselines/reference/awaitCallExpression5_es2017.js @@ -0,0 +1,21 @@ +//// [awaitCallExpression5_es2017.ts] +declare var a: boolean; +declare var p: Promise; +declare function fn(arg0: boolean, arg1: boolean, arg2: boolean): void; +declare var o: { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }; +declare var pfn: Promise<{ (arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +declare var po: Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +declare function before(): void; +declare function after(): void; +async function func(): Promise { + before(); + var b = o.fn(a, a, a); + after(); +} + +//// [awaitCallExpression5_es2017.js] +async function func() { + before(); + var b = o.fn(a, a, a); + after(); +} diff --git a/tests/baselines/reference/awaitCallExpression5_es2017.symbols b/tests/baselines/reference/awaitCallExpression5_es2017.symbols new file mode 100644 index 0000000000..3854353314 --- /dev/null +++ b/tests/baselines/reference/awaitCallExpression5_es2017.symbols @@ -0,0 +1,61 @@ +=== tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression5_es2017.ts === +declare var a: boolean; +>a : Symbol(a, Decl(awaitCallExpression5_es2017.ts, 0, 11)) + +declare var p: Promise; +>p : Symbol(p, Decl(awaitCallExpression5_es2017.ts, 1, 11)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + +declare function fn(arg0: boolean, arg1: boolean, arg2: boolean): void; +>fn : Symbol(fn, Decl(awaitCallExpression5_es2017.ts, 1, 32)) +>arg0 : Symbol(arg0, Decl(awaitCallExpression5_es2017.ts, 2, 20)) +>arg1 : Symbol(arg1, Decl(awaitCallExpression5_es2017.ts, 2, 34)) +>arg2 : Symbol(arg2, Decl(awaitCallExpression5_es2017.ts, 2, 49)) + +declare var o: { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }; +>o : Symbol(o, Decl(awaitCallExpression5_es2017.ts, 3, 11)) +>fn : Symbol(fn, Decl(awaitCallExpression5_es2017.ts, 3, 16)) +>arg0 : Symbol(arg0, Decl(awaitCallExpression5_es2017.ts, 3, 20)) +>arg1 : Symbol(arg1, Decl(awaitCallExpression5_es2017.ts, 3, 34)) +>arg2 : Symbol(arg2, Decl(awaitCallExpression5_es2017.ts, 3, 49)) + +declare var pfn: Promise<{ (arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +>pfn : Symbol(pfn, Decl(awaitCallExpression5_es2017.ts, 4, 11)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) +>arg0 : Symbol(arg0, Decl(awaitCallExpression5_es2017.ts, 4, 28)) +>arg1 : Symbol(arg1, Decl(awaitCallExpression5_es2017.ts, 4, 42)) +>arg2 : Symbol(arg2, Decl(awaitCallExpression5_es2017.ts, 4, 57)) + +declare var po: Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +>po : Symbol(po, Decl(awaitCallExpression5_es2017.ts, 5, 11)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) +>fn : Symbol(fn, Decl(awaitCallExpression5_es2017.ts, 5, 25)) +>arg0 : Symbol(arg0, Decl(awaitCallExpression5_es2017.ts, 5, 29)) +>arg1 : Symbol(arg1, Decl(awaitCallExpression5_es2017.ts, 5, 43)) +>arg2 : Symbol(arg2, Decl(awaitCallExpression5_es2017.ts, 5, 58)) + +declare function before(): void; +>before : Symbol(before, Decl(awaitCallExpression5_es2017.ts, 5, 84)) + +declare function after(): void; +>after : Symbol(after, Decl(awaitCallExpression5_es2017.ts, 6, 32)) + +async function func(): Promise { +>func : Symbol(func, Decl(awaitCallExpression5_es2017.ts, 7, 31)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + + before(); +>before : Symbol(before, Decl(awaitCallExpression5_es2017.ts, 5, 84)) + + var b = o.fn(a, a, a); +>b : Symbol(b, Decl(awaitCallExpression5_es2017.ts, 10, 7)) +>o.fn : Symbol(fn, Decl(awaitCallExpression5_es2017.ts, 3, 16)) +>o : Symbol(o, Decl(awaitCallExpression5_es2017.ts, 3, 11)) +>fn : Symbol(fn, Decl(awaitCallExpression5_es2017.ts, 3, 16)) +>a : Symbol(a, Decl(awaitCallExpression5_es2017.ts, 0, 11)) +>a : Symbol(a, Decl(awaitCallExpression5_es2017.ts, 0, 11)) +>a : Symbol(a, Decl(awaitCallExpression5_es2017.ts, 0, 11)) + + after(); +>after : Symbol(after, Decl(awaitCallExpression5_es2017.ts, 6, 32)) +} diff --git a/tests/baselines/reference/awaitCallExpression5_es2017.types b/tests/baselines/reference/awaitCallExpression5_es2017.types new file mode 100644 index 0000000000..f31320e44f --- /dev/null +++ b/tests/baselines/reference/awaitCallExpression5_es2017.types @@ -0,0 +1,64 @@ +=== tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression5_es2017.ts === +declare var a: boolean; +>a : boolean + +declare var p: Promise; +>p : Promise +>Promise : Promise + +declare function fn(arg0: boolean, arg1: boolean, arg2: boolean): void; +>fn : (arg0: boolean, arg1: boolean, arg2: boolean) => void +>arg0 : boolean +>arg1 : boolean +>arg2 : boolean + +declare var o: { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }; +>o : { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; } +>fn : (arg0: boolean, arg1: boolean, arg2: boolean) => void +>arg0 : boolean +>arg1 : boolean +>arg2 : boolean + +declare var pfn: Promise<{ (arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +>pfn : Promise<(arg0: boolean, arg1: boolean, arg2: boolean) => void> +>Promise : Promise +>arg0 : boolean +>arg1 : boolean +>arg2 : boolean + +declare var po: Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +>po : Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }> +>Promise : Promise +>fn : (arg0: boolean, arg1: boolean, arg2: boolean) => void +>arg0 : boolean +>arg1 : boolean +>arg2 : boolean + +declare function before(): void; +>before : () => void + +declare function after(): void; +>after : () => void + +async function func(): Promise { +>func : () => Promise +>Promise : Promise + + before(); +>before() : void +>before : () => void + + var b = o.fn(a, a, a); +>b : void +>o.fn(a, a, a) : void +>o.fn : (arg0: boolean, arg1: boolean, arg2: boolean) => void +>o : { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; } +>fn : (arg0: boolean, arg1: boolean, arg2: boolean) => void +>a : boolean +>a : boolean +>a : boolean + + after(); +>after() : void +>after : () => void +} diff --git a/tests/baselines/reference/awaitCallExpression6_es2017.js b/tests/baselines/reference/awaitCallExpression6_es2017.js new file mode 100644 index 0000000000..77a47ba806 --- /dev/null +++ b/tests/baselines/reference/awaitCallExpression6_es2017.js @@ -0,0 +1,21 @@ +//// [awaitCallExpression6_es2017.ts] +declare var a: boolean; +declare var p: Promise; +declare function fn(arg0: boolean, arg1: boolean, arg2: boolean): void; +declare var o: { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }; +declare var pfn: Promise<{ (arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +declare var po: Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +declare function before(): void; +declare function after(): void; +async function func(): Promise { + before(); + var b = o.fn(await p, a, a); + after(); +} + +//// [awaitCallExpression6_es2017.js] +async function func() { + before(); + var b = o.fn(await p, a, a); + after(); +} diff --git a/tests/baselines/reference/awaitCallExpression6_es2017.symbols b/tests/baselines/reference/awaitCallExpression6_es2017.symbols new file mode 100644 index 0000000000..6a65151032 --- /dev/null +++ b/tests/baselines/reference/awaitCallExpression6_es2017.symbols @@ -0,0 +1,61 @@ +=== tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression6_es2017.ts === +declare var a: boolean; +>a : Symbol(a, Decl(awaitCallExpression6_es2017.ts, 0, 11)) + +declare var p: Promise; +>p : Symbol(p, Decl(awaitCallExpression6_es2017.ts, 1, 11)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + +declare function fn(arg0: boolean, arg1: boolean, arg2: boolean): void; +>fn : Symbol(fn, Decl(awaitCallExpression6_es2017.ts, 1, 32)) +>arg0 : Symbol(arg0, Decl(awaitCallExpression6_es2017.ts, 2, 20)) +>arg1 : Symbol(arg1, Decl(awaitCallExpression6_es2017.ts, 2, 34)) +>arg2 : Symbol(arg2, Decl(awaitCallExpression6_es2017.ts, 2, 49)) + +declare var o: { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }; +>o : Symbol(o, Decl(awaitCallExpression6_es2017.ts, 3, 11)) +>fn : Symbol(fn, Decl(awaitCallExpression6_es2017.ts, 3, 16)) +>arg0 : Symbol(arg0, Decl(awaitCallExpression6_es2017.ts, 3, 20)) +>arg1 : Symbol(arg1, Decl(awaitCallExpression6_es2017.ts, 3, 34)) +>arg2 : Symbol(arg2, Decl(awaitCallExpression6_es2017.ts, 3, 49)) + +declare var pfn: Promise<{ (arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +>pfn : Symbol(pfn, Decl(awaitCallExpression6_es2017.ts, 4, 11)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) +>arg0 : Symbol(arg0, Decl(awaitCallExpression6_es2017.ts, 4, 28)) +>arg1 : Symbol(arg1, Decl(awaitCallExpression6_es2017.ts, 4, 42)) +>arg2 : Symbol(arg2, Decl(awaitCallExpression6_es2017.ts, 4, 57)) + +declare var po: Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +>po : Symbol(po, Decl(awaitCallExpression6_es2017.ts, 5, 11)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) +>fn : Symbol(fn, Decl(awaitCallExpression6_es2017.ts, 5, 25)) +>arg0 : Symbol(arg0, Decl(awaitCallExpression6_es2017.ts, 5, 29)) +>arg1 : Symbol(arg1, Decl(awaitCallExpression6_es2017.ts, 5, 43)) +>arg2 : Symbol(arg2, Decl(awaitCallExpression6_es2017.ts, 5, 58)) + +declare function before(): void; +>before : Symbol(before, Decl(awaitCallExpression6_es2017.ts, 5, 84)) + +declare function after(): void; +>after : Symbol(after, Decl(awaitCallExpression6_es2017.ts, 6, 32)) + +async function func(): Promise { +>func : Symbol(func, Decl(awaitCallExpression6_es2017.ts, 7, 31)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + + before(); +>before : Symbol(before, Decl(awaitCallExpression6_es2017.ts, 5, 84)) + + var b = o.fn(await p, a, a); +>b : Symbol(b, Decl(awaitCallExpression6_es2017.ts, 10, 7)) +>o.fn : Symbol(fn, Decl(awaitCallExpression6_es2017.ts, 3, 16)) +>o : Symbol(o, Decl(awaitCallExpression6_es2017.ts, 3, 11)) +>fn : Symbol(fn, Decl(awaitCallExpression6_es2017.ts, 3, 16)) +>p : Symbol(p, Decl(awaitCallExpression6_es2017.ts, 1, 11)) +>a : Symbol(a, Decl(awaitCallExpression6_es2017.ts, 0, 11)) +>a : Symbol(a, Decl(awaitCallExpression6_es2017.ts, 0, 11)) + + after(); +>after : Symbol(after, Decl(awaitCallExpression6_es2017.ts, 6, 32)) +} diff --git a/tests/baselines/reference/awaitCallExpression6_es2017.types b/tests/baselines/reference/awaitCallExpression6_es2017.types new file mode 100644 index 0000000000..ccce4cad36 --- /dev/null +++ b/tests/baselines/reference/awaitCallExpression6_es2017.types @@ -0,0 +1,65 @@ +=== tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression6_es2017.ts === +declare var a: boolean; +>a : boolean + +declare var p: Promise; +>p : Promise +>Promise : Promise + +declare function fn(arg0: boolean, arg1: boolean, arg2: boolean): void; +>fn : (arg0: boolean, arg1: boolean, arg2: boolean) => void +>arg0 : boolean +>arg1 : boolean +>arg2 : boolean + +declare var o: { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }; +>o : { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; } +>fn : (arg0: boolean, arg1: boolean, arg2: boolean) => void +>arg0 : boolean +>arg1 : boolean +>arg2 : boolean + +declare var pfn: Promise<{ (arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +>pfn : Promise<(arg0: boolean, arg1: boolean, arg2: boolean) => void> +>Promise : Promise +>arg0 : boolean +>arg1 : boolean +>arg2 : boolean + +declare var po: Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +>po : Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }> +>Promise : Promise +>fn : (arg0: boolean, arg1: boolean, arg2: boolean) => void +>arg0 : boolean +>arg1 : boolean +>arg2 : boolean + +declare function before(): void; +>before : () => void + +declare function after(): void; +>after : () => void + +async function func(): Promise { +>func : () => Promise +>Promise : Promise + + before(); +>before() : void +>before : () => void + + var b = o.fn(await p, a, a); +>b : void +>o.fn(await p, a, a) : void +>o.fn : (arg0: boolean, arg1: boolean, arg2: boolean) => void +>o : { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; } +>fn : (arg0: boolean, arg1: boolean, arg2: boolean) => void +>await p : boolean +>p : Promise +>a : boolean +>a : boolean + + after(); +>after() : void +>after : () => void +} diff --git a/tests/baselines/reference/awaitCallExpression7_es2017.js b/tests/baselines/reference/awaitCallExpression7_es2017.js new file mode 100644 index 0000000000..b3391ced6b --- /dev/null +++ b/tests/baselines/reference/awaitCallExpression7_es2017.js @@ -0,0 +1,21 @@ +//// [awaitCallExpression7_es2017.ts] +declare var a: boolean; +declare var p: Promise; +declare function fn(arg0: boolean, arg1: boolean, arg2: boolean): void; +declare var o: { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }; +declare var pfn: Promise<{ (arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +declare var po: Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +declare function before(): void; +declare function after(): void; +async function func(): Promise { + before(); + var b = o.fn(a, await p, a); + after(); +} + +//// [awaitCallExpression7_es2017.js] +async function func() { + before(); + var b = o.fn(a, await p, a); + after(); +} diff --git a/tests/baselines/reference/awaitCallExpression7_es2017.symbols b/tests/baselines/reference/awaitCallExpression7_es2017.symbols new file mode 100644 index 0000000000..e95078c685 --- /dev/null +++ b/tests/baselines/reference/awaitCallExpression7_es2017.symbols @@ -0,0 +1,61 @@ +=== tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression7_es2017.ts === +declare var a: boolean; +>a : Symbol(a, Decl(awaitCallExpression7_es2017.ts, 0, 11)) + +declare var p: Promise; +>p : Symbol(p, Decl(awaitCallExpression7_es2017.ts, 1, 11)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + +declare function fn(arg0: boolean, arg1: boolean, arg2: boolean): void; +>fn : Symbol(fn, Decl(awaitCallExpression7_es2017.ts, 1, 32)) +>arg0 : Symbol(arg0, Decl(awaitCallExpression7_es2017.ts, 2, 20)) +>arg1 : Symbol(arg1, Decl(awaitCallExpression7_es2017.ts, 2, 34)) +>arg2 : Symbol(arg2, Decl(awaitCallExpression7_es2017.ts, 2, 49)) + +declare var o: { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }; +>o : Symbol(o, Decl(awaitCallExpression7_es2017.ts, 3, 11)) +>fn : Symbol(fn, Decl(awaitCallExpression7_es2017.ts, 3, 16)) +>arg0 : Symbol(arg0, Decl(awaitCallExpression7_es2017.ts, 3, 20)) +>arg1 : Symbol(arg1, Decl(awaitCallExpression7_es2017.ts, 3, 34)) +>arg2 : Symbol(arg2, Decl(awaitCallExpression7_es2017.ts, 3, 49)) + +declare var pfn: Promise<{ (arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +>pfn : Symbol(pfn, Decl(awaitCallExpression7_es2017.ts, 4, 11)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) +>arg0 : Symbol(arg0, Decl(awaitCallExpression7_es2017.ts, 4, 28)) +>arg1 : Symbol(arg1, Decl(awaitCallExpression7_es2017.ts, 4, 42)) +>arg2 : Symbol(arg2, Decl(awaitCallExpression7_es2017.ts, 4, 57)) + +declare var po: Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +>po : Symbol(po, Decl(awaitCallExpression7_es2017.ts, 5, 11)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) +>fn : Symbol(fn, Decl(awaitCallExpression7_es2017.ts, 5, 25)) +>arg0 : Symbol(arg0, Decl(awaitCallExpression7_es2017.ts, 5, 29)) +>arg1 : Symbol(arg1, Decl(awaitCallExpression7_es2017.ts, 5, 43)) +>arg2 : Symbol(arg2, Decl(awaitCallExpression7_es2017.ts, 5, 58)) + +declare function before(): void; +>before : Symbol(before, Decl(awaitCallExpression7_es2017.ts, 5, 84)) + +declare function after(): void; +>after : Symbol(after, Decl(awaitCallExpression7_es2017.ts, 6, 32)) + +async function func(): Promise { +>func : Symbol(func, Decl(awaitCallExpression7_es2017.ts, 7, 31)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + + before(); +>before : Symbol(before, Decl(awaitCallExpression7_es2017.ts, 5, 84)) + + var b = o.fn(a, await p, a); +>b : Symbol(b, Decl(awaitCallExpression7_es2017.ts, 10, 7)) +>o.fn : Symbol(fn, Decl(awaitCallExpression7_es2017.ts, 3, 16)) +>o : Symbol(o, Decl(awaitCallExpression7_es2017.ts, 3, 11)) +>fn : Symbol(fn, Decl(awaitCallExpression7_es2017.ts, 3, 16)) +>a : Symbol(a, Decl(awaitCallExpression7_es2017.ts, 0, 11)) +>p : Symbol(p, Decl(awaitCallExpression7_es2017.ts, 1, 11)) +>a : Symbol(a, Decl(awaitCallExpression7_es2017.ts, 0, 11)) + + after(); +>after : Symbol(after, Decl(awaitCallExpression7_es2017.ts, 6, 32)) +} diff --git a/tests/baselines/reference/awaitCallExpression7_es2017.types b/tests/baselines/reference/awaitCallExpression7_es2017.types new file mode 100644 index 0000000000..aefe791685 --- /dev/null +++ b/tests/baselines/reference/awaitCallExpression7_es2017.types @@ -0,0 +1,65 @@ +=== tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression7_es2017.ts === +declare var a: boolean; +>a : boolean + +declare var p: Promise; +>p : Promise +>Promise : Promise + +declare function fn(arg0: boolean, arg1: boolean, arg2: boolean): void; +>fn : (arg0: boolean, arg1: boolean, arg2: boolean) => void +>arg0 : boolean +>arg1 : boolean +>arg2 : boolean + +declare var o: { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }; +>o : { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; } +>fn : (arg0: boolean, arg1: boolean, arg2: boolean) => void +>arg0 : boolean +>arg1 : boolean +>arg2 : boolean + +declare var pfn: Promise<{ (arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +>pfn : Promise<(arg0: boolean, arg1: boolean, arg2: boolean) => void> +>Promise : Promise +>arg0 : boolean +>arg1 : boolean +>arg2 : boolean + +declare var po: Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +>po : Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }> +>Promise : Promise +>fn : (arg0: boolean, arg1: boolean, arg2: boolean) => void +>arg0 : boolean +>arg1 : boolean +>arg2 : boolean + +declare function before(): void; +>before : () => void + +declare function after(): void; +>after : () => void + +async function func(): Promise { +>func : () => Promise +>Promise : Promise + + before(); +>before() : void +>before : () => void + + var b = o.fn(a, await p, a); +>b : void +>o.fn(a, await p, a) : void +>o.fn : (arg0: boolean, arg1: boolean, arg2: boolean) => void +>o : { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; } +>fn : (arg0: boolean, arg1: boolean, arg2: boolean) => void +>a : boolean +>await p : boolean +>p : Promise +>a : boolean + + after(); +>after() : void +>after : () => void +} diff --git a/tests/baselines/reference/awaitCallExpression8_es2017.js b/tests/baselines/reference/awaitCallExpression8_es2017.js new file mode 100644 index 0000000000..7e04402e90 --- /dev/null +++ b/tests/baselines/reference/awaitCallExpression8_es2017.js @@ -0,0 +1,21 @@ +//// [awaitCallExpression8_es2017.ts] +declare var a: boolean; +declare var p: Promise; +declare function fn(arg0: boolean, arg1: boolean, arg2: boolean): void; +declare var o: { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }; +declare var pfn: Promise<{ (arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +declare var po: Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +declare function before(): void; +declare function after(): void; +async function func(): Promise { + before(); + var b = (await po).fn(a, a, a); + after(); +} + +//// [awaitCallExpression8_es2017.js] +async function func() { + before(); + var b = (await po).fn(a, a, a); + after(); +} diff --git a/tests/baselines/reference/awaitCallExpression8_es2017.symbols b/tests/baselines/reference/awaitCallExpression8_es2017.symbols new file mode 100644 index 0000000000..e3fd465c12 --- /dev/null +++ b/tests/baselines/reference/awaitCallExpression8_es2017.symbols @@ -0,0 +1,61 @@ +=== tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression8_es2017.ts === +declare var a: boolean; +>a : Symbol(a, Decl(awaitCallExpression8_es2017.ts, 0, 11)) + +declare var p: Promise; +>p : Symbol(p, Decl(awaitCallExpression8_es2017.ts, 1, 11)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + +declare function fn(arg0: boolean, arg1: boolean, arg2: boolean): void; +>fn : Symbol(fn, Decl(awaitCallExpression8_es2017.ts, 1, 32)) +>arg0 : Symbol(arg0, Decl(awaitCallExpression8_es2017.ts, 2, 20)) +>arg1 : Symbol(arg1, Decl(awaitCallExpression8_es2017.ts, 2, 34)) +>arg2 : Symbol(arg2, Decl(awaitCallExpression8_es2017.ts, 2, 49)) + +declare var o: { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }; +>o : Symbol(o, Decl(awaitCallExpression8_es2017.ts, 3, 11)) +>fn : Symbol(fn, Decl(awaitCallExpression8_es2017.ts, 3, 16)) +>arg0 : Symbol(arg0, Decl(awaitCallExpression8_es2017.ts, 3, 20)) +>arg1 : Symbol(arg1, Decl(awaitCallExpression8_es2017.ts, 3, 34)) +>arg2 : Symbol(arg2, Decl(awaitCallExpression8_es2017.ts, 3, 49)) + +declare var pfn: Promise<{ (arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +>pfn : Symbol(pfn, Decl(awaitCallExpression8_es2017.ts, 4, 11)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) +>arg0 : Symbol(arg0, Decl(awaitCallExpression8_es2017.ts, 4, 28)) +>arg1 : Symbol(arg1, Decl(awaitCallExpression8_es2017.ts, 4, 42)) +>arg2 : Symbol(arg2, Decl(awaitCallExpression8_es2017.ts, 4, 57)) + +declare var po: Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +>po : Symbol(po, Decl(awaitCallExpression8_es2017.ts, 5, 11)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) +>fn : Symbol(fn, Decl(awaitCallExpression8_es2017.ts, 5, 25)) +>arg0 : Symbol(arg0, Decl(awaitCallExpression8_es2017.ts, 5, 29)) +>arg1 : Symbol(arg1, Decl(awaitCallExpression8_es2017.ts, 5, 43)) +>arg2 : Symbol(arg2, Decl(awaitCallExpression8_es2017.ts, 5, 58)) + +declare function before(): void; +>before : Symbol(before, Decl(awaitCallExpression8_es2017.ts, 5, 84)) + +declare function after(): void; +>after : Symbol(after, Decl(awaitCallExpression8_es2017.ts, 6, 32)) + +async function func(): Promise { +>func : Symbol(func, Decl(awaitCallExpression8_es2017.ts, 7, 31)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + + before(); +>before : Symbol(before, Decl(awaitCallExpression8_es2017.ts, 5, 84)) + + var b = (await po).fn(a, a, a); +>b : Symbol(b, Decl(awaitCallExpression8_es2017.ts, 10, 7)) +>(await po).fn : Symbol(fn, Decl(awaitCallExpression8_es2017.ts, 5, 25)) +>po : Symbol(po, Decl(awaitCallExpression8_es2017.ts, 5, 11)) +>fn : Symbol(fn, Decl(awaitCallExpression8_es2017.ts, 5, 25)) +>a : Symbol(a, Decl(awaitCallExpression8_es2017.ts, 0, 11)) +>a : Symbol(a, Decl(awaitCallExpression8_es2017.ts, 0, 11)) +>a : Symbol(a, Decl(awaitCallExpression8_es2017.ts, 0, 11)) + + after(); +>after : Symbol(after, Decl(awaitCallExpression8_es2017.ts, 6, 32)) +} diff --git a/tests/baselines/reference/awaitCallExpression8_es2017.types b/tests/baselines/reference/awaitCallExpression8_es2017.types new file mode 100644 index 0000000000..a9a115d39f --- /dev/null +++ b/tests/baselines/reference/awaitCallExpression8_es2017.types @@ -0,0 +1,66 @@ +=== tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression8_es2017.ts === +declare var a: boolean; +>a : boolean + +declare var p: Promise; +>p : Promise +>Promise : Promise + +declare function fn(arg0: boolean, arg1: boolean, arg2: boolean): void; +>fn : (arg0: boolean, arg1: boolean, arg2: boolean) => void +>arg0 : boolean +>arg1 : boolean +>arg2 : boolean + +declare var o: { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }; +>o : { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; } +>fn : (arg0: boolean, arg1: boolean, arg2: boolean) => void +>arg0 : boolean +>arg1 : boolean +>arg2 : boolean + +declare var pfn: Promise<{ (arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +>pfn : Promise<(arg0: boolean, arg1: boolean, arg2: boolean) => void> +>Promise : Promise +>arg0 : boolean +>arg1 : boolean +>arg2 : boolean + +declare var po: Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +>po : Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }> +>Promise : Promise +>fn : (arg0: boolean, arg1: boolean, arg2: boolean) => void +>arg0 : boolean +>arg1 : boolean +>arg2 : boolean + +declare function before(): void; +>before : () => void + +declare function after(): void; +>after : () => void + +async function func(): Promise { +>func : () => Promise +>Promise : Promise + + before(); +>before() : void +>before : () => void + + var b = (await po).fn(a, a, a); +>b : void +>(await po).fn(a, a, a) : void +>(await po).fn : (arg0: boolean, arg1: boolean, arg2: boolean) => void +>(await po) : { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; } +>await po : { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; } +>po : Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }> +>fn : (arg0: boolean, arg1: boolean, arg2: boolean) => void +>a : boolean +>a : boolean +>a : boolean + + after(); +>after() : void +>after : () => void +} diff --git a/tests/baselines/reference/awaitClassExpression_es2017.js b/tests/baselines/reference/awaitClassExpression_es2017.js new file mode 100644 index 0000000000..d84f01f61c --- /dev/null +++ b/tests/baselines/reference/awaitClassExpression_es2017.js @@ -0,0 +1,14 @@ +//// [awaitClassExpression_es2017.ts] +declare class C { } +declare var p: Promise; + +async function func(): Promise { + class D extends (await p) { + } +} + +//// [awaitClassExpression_es2017.js] +async function func() { + class D extends (await p) { + } +} diff --git a/tests/baselines/reference/awaitClassExpression_es2017.symbols b/tests/baselines/reference/awaitClassExpression_es2017.symbols new file mode 100644 index 0000000000..bebffa2bba --- /dev/null +++ b/tests/baselines/reference/awaitClassExpression_es2017.symbols @@ -0,0 +1,18 @@ +=== tests/cases/conformance/async/es2017/awaitClassExpression_es2017.ts === +declare class C { } +>C : Symbol(C, Decl(awaitClassExpression_es2017.ts, 0, 0)) + +declare var p: Promise; +>p : Symbol(p, Decl(awaitClassExpression_es2017.ts, 1, 11)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) +>C : Symbol(C, Decl(awaitClassExpression_es2017.ts, 0, 0)) + +async function func(): Promise { +>func : Symbol(func, Decl(awaitClassExpression_es2017.ts, 1, 33)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + + class D extends (await p) { +>D : Symbol(D, Decl(awaitClassExpression_es2017.ts, 3, 38)) +>p : Symbol(p, Decl(awaitClassExpression_es2017.ts, 1, 11)) + } +} diff --git a/tests/baselines/reference/awaitClassExpression_es2017.types b/tests/baselines/reference/awaitClassExpression_es2017.types new file mode 100644 index 0000000000..39d17b1cc5 --- /dev/null +++ b/tests/baselines/reference/awaitClassExpression_es2017.types @@ -0,0 +1,20 @@ +=== tests/cases/conformance/async/es2017/awaitClassExpression_es2017.ts === +declare class C { } +>C : C + +declare var p: Promise; +>p : Promise +>Promise : Promise +>C : typeof C + +async function func(): Promise { +>func : () => Promise +>Promise : Promise + + class D extends (await p) { +>D : D +>(await p) : C +>await p : typeof C +>p : Promise + } +} diff --git a/tests/baselines/reference/awaitUnion_es2017.js b/tests/baselines/reference/awaitUnion_es2017.js new file mode 100644 index 0000000000..12f8b95a65 --- /dev/null +++ b/tests/baselines/reference/awaitUnion_es2017.js @@ -0,0 +1,22 @@ +//// [awaitUnion_es2017.ts] +declare let a: number | string; +declare let b: PromiseLike | PromiseLike; +declare let c: PromiseLike; +declare let d: number | PromiseLike; +declare let e: number | PromiseLike; +async function f() { + let await_a = await a; + let await_b = await b; + let await_c = await c; + let await_d = await d; + let await_e = await e; +} + +//// [awaitUnion_es2017.js] +async function f() { + let await_a = await a; + let await_b = await b; + let await_c = await c; + let await_d = await d; + let await_e = await e; +} diff --git a/tests/baselines/reference/awaitUnion_es2017.symbols b/tests/baselines/reference/awaitUnion_es2017.symbols new file mode 100644 index 0000000000..e70abce4f0 --- /dev/null +++ b/tests/baselines/reference/awaitUnion_es2017.symbols @@ -0,0 +1,44 @@ +=== tests/cases/conformance/async/es2017/awaitUnion_es2017.ts === +declare let a: number | string; +>a : Symbol(a, Decl(awaitUnion_es2017.ts, 0, 11)) + +declare let b: PromiseLike | PromiseLike; +>b : Symbol(b, Decl(awaitUnion_es2017.ts, 1, 11)) +>PromiseLike : Symbol(PromiseLike, Decl(lib.es5.d.ts, --, --)) +>PromiseLike : Symbol(PromiseLike, Decl(lib.es5.d.ts, --, --)) + +declare let c: PromiseLike; +>c : Symbol(c, Decl(awaitUnion_es2017.ts, 2, 11)) +>PromiseLike : Symbol(PromiseLike, Decl(lib.es5.d.ts, --, --)) + +declare let d: number | PromiseLike; +>d : Symbol(d, Decl(awaitUnion_es2017.ts, 3, 11)) +>PromiseLike : Symbol(PromiseLike, Decl(lib.es5.d.ts, --, --)) + +declare let e: number | PromiseLike; +>e : Symbol(e, Decl(awaitUnion_es2017.ts, 4, 11)) +>PromiseLike : Symbol(PromiseLike, Decl(lib.es5.d.ts, --, --)) + +async function f() { +>f : Symbol(f, Decl(awaitUnion_es2017.ts, 4, 53)) + + let await_a = await a; +>await_a : Symbol(await_a, Decl(awaitUnion_es2017.ts, 6, 4)) +>a : Symbol(a, Decl(awaitUnion_es2017.ts, 0, 11)) + + let await_b = await b; +>await_b : Symbol(await_b, Decl(awaitUnion_es2017.ts, 7, 4)) +>b : Symbol(b, Decl(awaitUnion_es2017.ts, 1, 11)) + + let await_c = await c; +>await_c : Symbol(await_c, Decl(awaitUnion_es2017.ts, 8, 4)) +>c : Symbol(c, Decl(awaitUnion_es2017.ts, 2, 11)) + + let await_d = await d; +>await_d : Symbol(await_d, Decl(awaitUnion_es2017.ts, 9, 4)) +>d : Symbol(d, Decl(awaitUnion_es2017.ts, 3, 11)) + + let await_e = await e; +>await_e : Symbol(await_e, Decl(awaitUnion_es2017.ts, 10, 4)) +>e : Symbol(e, Decl(awaitUnion_es2017.ts, 4, 11)) +} diff --git a/tests/baselines/reference/awaitUnion_es2017.types b/tests/baselines/reference/awaitUnion_es2017.types new file mode 100644 index 0000000000..58f8a4ec4b --- /dev/null +++ b/tests/baselines/reference/awaitUnion_es2017.types @@ -0,0 +1,49 @@ +=== tests/cases/conformance/async/es2017/awaitUnion_es2017.ts === +declare let a: number | string; +>a : string | number + +declare let b: PromiseLike | PromiseLike; +>b : PromiseLike | PromiseLike +>PromiseLike : PromiseLike +>PromiseLike : PromiseLike + +declare let c: PromiseLike; +>c : PromiseLike +>PromiseLike : PromiseLike + +declare let d: number | PromiseLike; +>d : number | PromiseLike +>PromiseLike : PromiseLike + +declare let e: number | PromiseLike; +>e : number | PromiseLike +>PromiseLike : PromiseLike + +async function f() { +>f : () => Promise + + let await_a = await a; +>await_a : string | number +>await a : string | number +>a : string | number + + let await_b = await b; +>await_b : string | number +>await b : string | number +>b : PromiseLike | PromiseLike + + let await_c = await c; +>await_c : string | number +>await c : string | number +>c : PromiseLike + + let await_d = await d; +>await_d : string | number +>await d : string | number +>d : number | PromiseLike + + let await_e = await e; +>await_e : string | number +>await e : string | number +>e : number | PromiseLike +} diff --git a/tests/baselines/reference/await_unaryExpression_es2017.js b/tests/baselines/reference/await_unaryExpression_es2017.js new file mode 100644 index 0000000000..83fce6588e --- /dev/null +++ b/tests/baselines/reference/await_unaryExpression_es2017.js @@ -0,0 +1,31 @@ +//// [await_unaryExpression_es2017.ts] + +async function bar() { + !await 42; // OK +} + +async function bar1() { + +await 42; // OK +} + +async function bar3() { + -await 42; // OK +} + +async function bar4() { + ~await 42; // OK +} + +//// [await_unaryExpression_es2017.js] +async function bar() { + !await 42; // OK +} +async function bar1() { + +await 42; // OK +} +async function bar3() { + -await 42; // OK +} +async function bar4() { + ~await 42; // OK +} diff --git a/tests/baselines/reference/await_unaryExpression_es2017.symbols b/tests/baselines/reference/await_unaryExpression_es2017.symbols new file mode 100644 index 0000000000..1aa3103117 --- /dev/null +++ b/tests/baselines/reference/await_unaryExpression_es2017.symbols @@ -0,0 +1,25 @@ +=== tests/cases/conformance/async/es2017/await_unaryExpression_es2017.ts === + +async function bar() { +>bar : Symbol(bar, Decl(await_unaryExpression_es2017.ts, 0, 0)) + + !await 42; // OK +} + +async function bar1() { +>bar1 : Symbol(bar1, Decl(await_unaryExpression_es2017.ts, 3, 1)) + + +await 42; // OK +} + +async function bar3() { +>bar3 : Symbol(bar3, Decl(await_unaryExpression_es2017.ts, 7, 1)) + + -await 42; // OK +} + +async function bar4() { +>bar4 : Symbol(bar4, Decl(await_unaryExpression_es2017.ts, 11, 1)) + + ~await 42; // OK +} diff --git a/tests/baselines/reference/await_unaryExpression_es2017.types b/tests/baselines/reference/await_unaryExpression_es2017.types new file mode 100644 index 0000000000..4f4254df31 --- /dev/null +++ b/tests/baselines/reference/await_unaryExpression_es2017.types @@ -0,0 +1,37 @@ +=== tests/cases/conformance/async/es2017/await_unaryExpression_es2017.ts === + +async function bar() { +>bar : () => Promise + + !await 42; // OK +>!await 42 : boolean +>await 42 : 42 +>42 : 42 +} + +async function bar1() { +>bar1 : () => Promise + + +await 42; // OK +>+await 42 : number +>await 42 : 42 +>42 : 42 +} + +async function bar3() { +>bar3 : () => Promise + + -await 42; // OK +>-await 42 : number +>await 42 : 42 +>42 : 42 +} + +async function bar4() { +>bar4 : () => Promise + + ~await 42; // OK +>~await 42 : number +>await 42 : 42 +>42 : 42 +} diff --git a/tests/baselines/reference/await_unaryExpression_es2017_1.js b/tests/baselines/reference/await_unaryExpression_es2017_1.js new file mode 100644 index 0000000000..f863fb19a7 --- /dev/null +++ b/tests/baselines/reference/await_unaryExpression_es2017_1.js @@ -0,0 +1,38 @@ +//// [await_unaryExpression_es2017_1.ts] + +async function bar() { + !await 42; // OK +} + +async function bar1() { + delete await 42; // OK +} + +async function bar2() { + delete await 42; // OK +} + +async function bar3() { + void await 42; +} + +async function bar4() { + +await 42; +} + +//// [await_unaryExpression_es2017_1.js] +async function bar() { + !await 42; // OK +} +async function bar1() { + delete await 42; // OK +} +async function bar2() { + delete await 42; // OK +} +async function bar3() { + void await 42; +} +async function bar4() { + +await 42; +} diff --git a/tests/baselines/reference/await_unaryExpression_es2017_1.symbols b/tests/baselines/reference/await_unaryExpression_es2017_1.symbols new file mode 100644 index 0000000000..81bb31a7ef --- /dev/null +++ b/tests/baselines/reference/await_unaryExpression_es2017_1.symbols @@ -0,0 +1,31 @@ +=== tests/cases/conformance/async/es2017/await_unaryExpression_es2017_1.ts === + +async function bar() { +>bar : Symbol(bar, Decl(await_unaryExpression_es2017_1.ts, 0, 0)) + + !await 42; // OK +} + +async function bar1() { +>bar1 : Symbol(bar1, Decl(await_unaryExpression_es2017_1.ts, 3, 1)) + + delete await 42; // OK +} + +async function bar2() { +>bar2 : Symbol(bar2, Decl(await_unaryExpression_es2017_1.ts, 7, 1)) + + delete await 42; // OK +} + +async function bar3() { +>bar3 : Symbol(bar3, Decl(await_unaryExpression_es2017_1.ts, 11, 1)) + + void await 42; +} + +async function bar4() { +>bar4 : Symbol(bar4, Decl(await_unaryExpression_es2017_1.ts, 15, 1)) + + +await 42; +} diff --git a/tests/baselines/reference/await_unaryExpression_es2017_1.types b/tests/baselines/reference/await_unaryExpression_es2017_1.types new file mode 100644 index 0000000000..7afa4fe900 --- /dev/null +++ b/tests/baselines/reference/await_unaryExpression_es2017_1.types @@ -0,0 +1,46 @@ +=== tests/cases/conformance/async/es2017/await_unaryExpression_es2017_1.ts === + +async function bar() { +>bar : () => Promise + + !await 42; // OK +>!await 42 : boolean +>await 42 : 42 +>42 : 42 +} + +async function bar1() { +>bar1 : () => Promise + + delete await 42; // OK +>delete await 42 : boolean +>await 42 : 42 +>42 : 42 +} + +async function bar2() { +>bar2 : () => Promise + + delete await 42; // OK +>delete await 42 : boolean +>await 42 : 42 +>42 : 42 +} + +async function bar3() { +>bar3 : () => Promise + + void await 42; +>void await 42 : undefined +>await 42 : 42 +>42 : 42 +} + +async function bar4() { +>bar4 : () => Promise + + +await 42; +>+await 42 : number +>await 42 : 42 +>42 : 42 +} diff --git a/tests/baselines/reference/await_unaryExpression_es2017_2.js b/tests/baselines/reference/await_unaryExpression_es2017_2.js new file mode 100644 index 0000000000..b982b20245 --- /dev/null +++ b/tests/baselines/reference/await_unaryExpression_es2017_2.js @@ -0,0 +1,24 @@ +//// [await_unaryExpression_es2017_2.ts] + +async function bar1() { + delete await 42; +} + +async function bar2() { + delete await 42; +} + +async function bar3() { + void await 42; +} + +//// [await_unaryExpression_es2017_2.js] +async function bar1() { + delete await 42; +} +async function bar2() { + delete await 42; +} +async function bar3() { + void await 42; +} diff --git a/tests/baselines/reference/await_unaryExpression_es2017_2.symbols b/tests/baselines/reference/await_unaryExpression_es2017_2.symbols new file mode 100644 index 0000000000..d4b8a7493d --- /dev/null +++ b/tests/baselines/reference/await_unaryExpression_es2017_2.symbols @@ -0,0 +1,19 @@ +=== tests/cases/conformance/async/es2017/await_unaryExpression_es2017_2.ts === + +async function bar1() { +>bar1 : Symbol(bar1, Decl(await_unaryExpression_es2017_2.ts, 0, 0)) + + delete await 42; +} + +async function bar2() { +>bar2 : Symbol(bar2, Decl(await_unaryExpression_es2017_2.ts, 3, 1)) + + delete await 42; +} + +async function bar3() { +>bar3 : Symbol(bar3, Decl(await_unaryExpression_es2017_2.ts, 7, 1)) + + void await 42; +} diff --git a/tests/baselines/reference/await_unaryExpression_es2017_2.types b/tests/baselines/reference/await_unaryExpression_es2017_2.types new file mode 100644 index 0000000000..acaa76d2d6 --- /dev/null +++ b/tests/baselines/reference/await_unaryExpression_es2017_2.types @@ -0,0 +1,28 @@ +=== tests/cases/conformance/async/es2017/await_unaryExpression_es2017_2.ts === + +async function bar1() { +>bar1 : () => Promise + + delete await 42; +>delete await 42 : boolean +>await 42 : 42 +>42 : 42 +} + +async function bar2() { +>bar2 : () => Promise + + delete await 42; +>delete await 42 : boolean +>await 42 : 42 +>42 : 42 +} + +async function bar3() { +>bar3 : () => Promise + + void await 42; +>void await 42 : undefined +>await 42 : 42 +>42 : 42 +} diff --git a/tests/baselines/reference/await_unaryExpression_es2017_3.errors.txt b/tests/baselines/reference/await_unaryExpression_es2017_3.errors.txt new file mode 100644 index 0000000000..5d11c4bbb2 --- /dev/null +++ b/tests/baselines/reference/await_unaryExpression_es2017_3.errors.txt @@ -0,0 +1,27 @@ +tests/cases/conformance/async/es2017/await_unaryExpression_es2017_3.ts(3,7): error TS1109: Expression expected. +tests/cases/conformance/async/es2017/await_unaryExpression_es2017_3.ts(7,7): error TS1109: Expression expected. + + +==== tests/cases/conformance/async/es2017/await_unaryExpression_es2017_3.ts (2 errors) ==== + + async function bar1() { + ++await 42; // Error + ~~~~~ +!!! error TS1109: Expression expected. + } + + async function bar2() { + --await 42; // Error + ~~~~~ +!!! error TS1109: Expression expected. + } + + async function bar3() { + var x = 42; + await x++; // OK but shouldn't need parenthesis + } + + async function bar4() { + var x = 42; + await x--; // OK but shouldn't need parenthesis + } \ No newline at end of file diff --git a/tests/baselines/reference/await_unaryExpression_es2017_3.js b/tests/baselines/reference/await_unaryExpression_es2017_3.js new file mode 100644 index 0000000000..5e3c3c3a4b --- /dev/null +++ b/tests/baselines/reference/await_unaryExpression_es2017_3.js @@ -0,0 +1,37 @@ +//// [await_unaryExpression_es2017_3.ts] + +async function bar1() { + ++await 42; // Error +} + +async function bar2() { + --await 42; // Error +} + +async function bar3() { + var x = 42; + await x++; // OK but shouldn't need parenthesis +} + +async function bar4() { + var x = 42; + await x--; // OK but shouldn't need parenthesis +} + +//// [await_unaryExpression_es2017_3.js] +async function bar1() { + ++; + await 42; // Error +} +async function bar2() { + --; + await 42; // Error +} +async function bar3() { + var x = 42; + await x++; // OK but shouldn't need parenthesis +} +async function bar4() { + var x = 42; + await x--; // OK but shouldn't need parenthesis +} diff --git a/tests/baselines/reference/es2017basicAsync.js b/tests/baselines/reference/es2017basicAsync.js index da219f4614..b19eaa4b0b 100644 --- a/tests/baselines/reference/es2017basicAsync.js +++ b/tests/baselines/reference/es2017basicAsync.js @@ -1,4 +1,4 @@ -//// [es2017-async.ts] +//// [es2017basicAsync.ts] async (): Promise => { await 0; @@ -47,7 +47,7 @@ class AsyncClass { } -//// [es2017-async.js] +//// [es2017basicAsync.js] async () => { await 0; }; diff --git a/tests/baselines/reference/es2017basicAsync.symbols b/tests/baselines/reference/es2017basicAsync.symbols index be3b2e723f..75f4d2cfa7 100644 --- a/tests/baselines/reference/es2017basicAsync.symbols +++ b/tests/baselines/reference/es2017basicAsync.symbols @@ -1,4 +1,4 @@ -=== tests/cases/compiler/es2017-async.ts === +=== tests/cases/compiler/es2017basicAsync.ts === async (): Promise => { >Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) @@ -7,20 +7,20 @@ async (): Promise => { } async function asyncFunc() { ->asyncFunc : Symbol(asyncFunc, Decl(es2017-async.ts, 3, 1)) +>asyncFunc : Symbol(asyncFunc, Decl(es2017basicAsync.ts, 3, 1)) await 0; } const asycnArrowFunc = async (): Promise => { ->asycnArrowFunc : Symbol(asycnArrowFunc, Decl(es2017-async.ts, 9, 5)) +>asycnArrowFunc : Symbol(asycnArrowFunc, Decl(es2017basicAsync.ts, 9, 5)) >Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) await 0; } async function asyncIIFE() { ->asyncIIFE : Symbol(asyncIIFE, Decl(es2017-async.ts, 11, 1)) +>asyncIIFE : Symbol(asyncIIFE, Decl(es2017basicAsync.ts, 11, 1)) await 0; @@ -31,7 +31,7 @@ async function asyncIIFE() { })(); await (async function asyncNamedFunc(): Promise { ->asyncNamedFunc : Symbol(asyncNamedFunc, Decl(es2017-async.ts, 20, 11)) +>asyncNamedFunc : Symbol(asyncNamedFunc, Decl(es2017basicAsync.ts, 20, 11)) >Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) await 1; @@ -45,32 +45,32 @@ async function asyncIIFE() { } class AsyncClass { ->AsyncClass : Symbol(AsyncClass, Decl(es2017-async.ts, 27, 1)) +>AsyncClass : Symbol(AsyncClass, Decl(es2017basicAsync.ts, 27, 1)) asyncPropFunc = async function(): Promise { ->asyncPropFunc : Symbol(AsyncClass.asyncPropFunc, Decl(es2017-async.ts, 29, 18)) +>asyncPropFunc : Symbol(AsyncClass.asyncPropFunc, Decl(es2017basicAsync.ts, 29, 18)) >Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) await 2; } asyncPropNamedFunc = async function namedFunc(): Promise { ->asyncPropNamedFunc : Symbol(AsyncClass.asyncPropNamedFunc, Decl(es2017-async.ts, 32, 5)) ->namedFunc : Symbol(namedFunc, Decl(es2017-async.ts, 34, 24)) +>asyncPropNamedFunc : Symbol(AsyncClass.asyncPropNamedFunc, Decl(es2017basicAsync.ts, 32, 5)) +>namedFunc : Symbol(namedFunc, Decl(es2017basicAsync.ts, 34, 24)) >Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) await 2; } asyncPropArrowFunc = async (): Promise => { ->asyncPropArrowFunc : Symbol(AsyncClass.asyncPropArrowFunc, Decl(es2017-async.ts, 36, 5)) +>asyncPropArrowFunc : Symbol(AsyncClass.asyncPropArrowFunc, Decl(es2017basicAsync.ts, 36, 5)) >Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) await 2; } async asyncMethod(): Promise { ->asyncMethod : Symbol(AsyncClass.asyncMethod, Decl(es2017-async.ts, 40, 5)) +>asyncMethod : Symbol(AsyncClass.asyncMethod, Decl(es2017basicAsync.ts, 40, 5)) >Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) await 2; diff --git a/tests/baselines/reference/es2017basicAsync.types b/tests/baselines/reference/es2017basicAsync.types index 79f3a005e6..71c2dbe50f 100644 --- a/tests/baselines/reference/es2017basicAsync.types +++ b/tests/baselines/reference/es2017basicAsync.types @@ -1,4 +1,4 @@ -=== tests/cases/compiler/es2017-async.ts === +=== tests/cases/compiler/es2017basicAsync.ts === async (): Promise => { >async (): Promise => { await 0;} : () => Promise diff --git a/tests/cases/conformance/async/es2017/asyncAliasReturnType_es2017.ts b/tests/cases/conformance/async/es2017/asyncAliasReturnType_es2017.ts new file mode 100644 index 0000000000..87bbc42e16 --- /dev/null +++ b/tests/cases/conformance/async/es2017/asyncAliasReturnType_es2017.ts @@ -0,0 +1,6 @@ +// @target: es2017 +// @noEmitHelpers: true +type PromiseAlias = Promise; + +async function f(): PromiseAlias { +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/asyncArrowFunction/arrowFunctionWithParameterNameAsync_es2017.ts b/tests/cases/conformance/async/es2017/asyncArrowFunction/arrowFunctionWithParameterNameAsync_es2017.ts new file mode 100644 index 0000000000..1ade02c09d --- /dev/null +++ b/tests/cases/conformance/async/es2017/asyncArrowFunction/arrowFunctionWithParameterNameAsync_es2017.ts @@ -0,0 +1,4 @@ +// @target: ES5 +// @noEmitHelpers: true + +const x = async => async; \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction10_es2017.ts b/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction10_es2017.ts new file mode 100644 index 0000000000..09d97cc253 --- /dev/null +++ b/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction10_es2017.ts @@ -0,0 +1,7 @@ +// @target: es2017 +// @noEmitHelpers: true + +var foo = async (): Promise => { + // Legal to use 'await' in a type context. + var v: await; +} diff --git a/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction1_es2017.ts b/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction1_es2017.ts new file mode 100644 index 0000000000..0f9ec479a3 --- /dev/null +++ b/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction1_es2017.ts @@ -0,0 +1,5 @@ +// @target: es2017 +// @noEmitHelpers: true + +var foo = async (): Promise => { +}; \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction2_es2017.ts b/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction2_es2017.ts new file mode 100644 index 0000000000..b11441372f --- /dev/null +++ b/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction2_es2017.ts @@ -0,0 +1,4 @@ +// @target: es2017 +// @noEmitHelpers: true +var f = (await) => { +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction3_es2017.ts b/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction3_es2017.ts new file mode 100644 index 0000000000..9b5924fc14 --- /dev/null +++ b/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction3_es2017.ts @@ -0,0 +1,4 @@ +// @target: es2017 +// @noEmitHelpers: true +function f(await = await) { +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction4_es2017.ts b/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction4_es2017.ts new file mode 100644 index 0000000000..5a98827783 --- /dev/null +++ b/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction4_es2017.ts @@ -0,0 +1,4 @@ +// @target: es2017 +// @noEmitHelpers: true +var await = () => { +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction5_es2017.ts b/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction5_es2017.ts new file mode 100644 index 0000000000..aabe5a9937 --- /dev/null +++ b/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction5_es2017.ts @@ -0,0 +1,5 @@ +// @target: es2017 +// @noEmitHelpers: true + +var foo = async (await): Promise => { +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction6_es2017.ts b/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction6_es2017.ts new file mode 100644 index 0000000000..d82ce86442 --- /dev/null +++ b/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction6_es2017.ts @@ -0,0 +1,5 @@ +// @target: es2017 +// @noEmitHelpers: true + +var foo = async (a = await): Promise => { +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction7_es2017.ts b/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction7_es2017.ts new file mode 100644 index 0000000000..bc49c5995e --- /dev/null +++ b/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction7_es2017.ts @@ -0,0 +1,8 @@ +// @target: es2017 +// @noEmitHelpers: true + +var bar = async (): Promise => { + // 'await' here is an identifier, and not an await expression. + var foo = async (a = await): Promise => { + } +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction8_es2017.ts b/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction8_es2017.ts new file mode 100644 index 0000000000..387b09c791 --- /dev/null +++ b/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction8_es2017.ts @@ -0,0 +1,6 @@ +// @target: es2017 +// @noEmitHelpers: true + +var foo = async (): Promise => { + var v = { [await]: foo } +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction9_es2017.ts b/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction9_es2017.ts new file mode 100644 index 0000000000..93254fee5c --- /dev/null +++ b/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction9_es2017.ts @@ -0,0 +1,4 @@ +// @target: es2017 +// @noEmitHelpers: true +var foo = async (a = await => await): Promise => { +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunctionCapturesArguments_es2017.ts b/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunctionCapturesArguments_es2017.ts new file mode 100644 index 0000000000..c71c6ddecb --- /dev/null +++ b/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunctionCapturesArguments_es2017.ts @@ -0,0 +1,8 @@ +// @target: es2017 +// @noEmitHelpers: true +class C { + method() { + function other() {} + var fn = async () => await other.apply(this, arguments); + } +} diff --git a/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunctionCapturesThis_es2017.ts b/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunctionCapturesThis_es2017.ts new file mode 100644 index 0000000000..3f398d9be8 --- /dev/null +++ b/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunctionCapturesThis_es2017.ts @@ -0,0 +1,7 @@ +// @target: es2017 +// @noEmitHelpers: true +class C { + method() { + var fn = async () => await this; + } +} diff --git a/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncUnParenthesizedArrowFunction_es2017.ts b/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncUnParenthesizedArrowFunction_es2017.ts new file mode 100644 index 0000000000..9b63b7bd46 --- /dev/null +++ b/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncUnParenthesizedArrowFunction_es2017.ts @@ -0,0 +1,6 @@ +// @target: es2017 +// @noEmitHelpers: true + +declare function someOtherFunction(i: any): Promise; +const x = async i => await someOtherFunction(i) +const x1 = async (i) => await someOtherFunction(i); \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/asyncAwaitIsolatedModules_es2017.ts b/tests/cases/conformance/async/es2017/asyncAwaitIsolatedModules_es2017.ts new file mode 100644 index 0000000000..c0ab4838f7 --- /dev/null +++ b/tests/cases/conformance/async/es2017/asyncAwaitIsolatedModules_es2017.ts @@ -0,0 +1,41 @@ +// @target: es2017 +// @isolatedModules: true +import { MyPromise } from "missing"; + +declare var p: Promise; +declare var mp: MyPromise; + +async function f0() { } +async function f1(): Promise { } +async function f3(): MyPromise { } + +let f4 = async function() { } +let f5 = async function(): Promise { } +let f6 = async function(): MyPromise { } + +let f7 = async () => { }; +let f8 = async (): Promise => { }; +let f9 = async (): MyPromise => { }; +let f10 = async () => p; +let f11 = async () => mp; +let f12 = async (): Promise => mp; +let f13 = async (): MyPromise => p; + +let o = { + async m1() { }, + async m2(): Promise { }, + async m3(): MyPromise { } +}; + +class C { + async m1() { } + async m2(): Promise { } + async m3(): MyPromise { } + static async m4() { } + static async m5(): Promise { } + static async m6(): MyPromise { } +} + +module M { + export async function f1() { } +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/asyncAwait_es2017.ts b/tests/cases/conformance/async/es2017/asyncAwait_es2017.ts new file mode 100644 index 0000000000..a255cb7cb7 --- /dev/null +++ b/tests/cases/conformance/async/es2017/asyncAwait_es2017.ts @@ -0,0 +1,40 @@ +// @target: es2017 +type MyPromise = Promise; +declare var MyPromise: typeof Promise; +declare var p: Promise; +declare var mp: MyPromise; + +async function f0() { } +async function f1(): Promise { } +async function f3(): MyPromise { } + +let f4 = async function() { } +let f5 = async function(): Promise { } +let f6 = async function(): MyPromise { } + +let f7 = async () => { }; +let f8 = async (): Promise => { }; +let f9 = async (): MyPromise => { }; +let f10 = async () => p; +let f11 = async () => mp; +let f12 = async (): Promise => mp; +let f13 = async (): MyPromise => p; + +let o = { + async m1() { }, + async m2(): Promise { }, + async m3(): MyPromise { } +}; + +class C { + async m1() { } + async m2(): Promise { } + async m3(): MyPromise { } + static async m4() { } + static async m5(): Promise { } + static async m6(): MyPromise { } +} + +module M { + export async function f1() { } +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/asyncClass_es2017.ts b/tests/cases/conformance/async/es2017/asyncClass_es2017.ts new file mode 100644 index 0000000000..78746c972d --- /dev/null +++ b/tests/cases/conformance/async/es2017/asyncClass_es2017.ts @@ -0,0 +1,4 @@ +// @target: es2017 +// @noEmitHelpers: true +async class C { +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/asyncConstructor_es2017.ts b/tests/cases/conformance/async/es2017/asyncConstructor_es2017.ts new file mode 100644 index 0000000000..874c0b9923 --- /dev/null +++ b/tests/cases/conformance/async/es2017/asyncConstructor_es2017.ts @@ -0,0 +1,6 @@ +// @target: es2017 +// @noEmitHelpers: true +class C { + async constructor() { + } +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/asyncDeclare_es2017.ts b/tests/cases/conformance/async/es2017/asyncDeclare_es2017.ts new file mode 100644 index 0000000000..d7fd4888fe --- /dev/null +++ b/tests/cases/conformance/async/es2017/asyncDeclare_es2017.ts @@ -0,0 +1,3 @@ +// @target: es2017 +// @noEmitHelpers: true +declare async function foo(): Promise; \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/asyncEnum_es2017.ts b/tests/cases/conformance/async/es2017/asyncEnum_es2017.ts new file mode 100644 index 0000000000..dc995206e8 --- /dev/null +++ b/tests/cases/conformance/async/es2017/asyncEnum_es2017.ts @@ -0,0 +1,5 @@ +// @target: es2017 +// @noEmitHelpers: true +async enum E { + Value +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/asyncGetter_es2017.ts b/tests/cases/conformance/async/es2017/asyncGetter_es2017.ts new file mode 100644 index 0000000000..340c33138c --- /dev/null +++ b/tests/cases/conformance/async/es2017/asyncGetter_es2017.ts @@ -0,0 +1,6 @@ +// @target: es2017 +// @noEmitHelpers: true +class C { + async get foo() { + } +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/asyncImportedPromise_es2017.ts b/tests/cases/conformance/async/es2017/asyncImportedPromise_es2017.ts new file mode 100644 index 0000000000..81f5b690ed --- /dev/null +++ b/tests/cases/conformance/async/es2017/asyncImportedPromise_es2017.ts @@ -0,0 +1,10 @@ +// @target: es2017 +// @module: commonjs +// @filename: task.ts +export class Task extends Promise { } + +// @filename: test.ts +import { Task } from "./task"; +class Test { + async example(): Task { return; } +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/asyncInterface_es2017.ts b/tests/cases/conformance/async/es2017/asyncInterface_es2017.ts new file mode 100644 index 0000000000..252730f9ff --- /dev/null +++ b/tests/cases/conformance/async/es2017/asyncInterface_es2017.ts @@ -0,0 +1,4 @@ +// @target: es2017 +// @noEmitHelpers: true +async interface I { +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/asyncMethodWithSuper_es2017.ts b/tests/cases/conformance/async/es2017/asyncMethodWithSuper_es2017.ts new file mode 100644 index 0000000000..b9005c4859 --- /dev/null +++ b/tests/cases/conformance/async/es2017/asyncMethodWithSuper_es2017.ts @@ -0,0 +1,52 @@ +// @target: es2017 +// @noEmitHelpers: true +class A { + x() { + } +} + +class B extends A { + // async method with only call/get on 'super' does not require a binding + async simple() { + // call with property access + super.x(); + + // call with element access + super["x"](); + + // property access (read) + const a = super.x; + + // element access (read) + const b = super["x"]; + } + + // async method with assignment/destructuring on 'super' requires a binding + async advanced() { + const f = () => {}; + + // call with property access + super.x(); + + // call with element access + super["x"](); + + // property access (read) + const a = super.x; + + // element access (read) + const b = super["x"]; + + // property access (assign) + super.x = f; + + // element access (assign) + super["x"] = f; + + // destructuring assign with property access + ({ f: super.x } = { f }); + + // destructuring assign with element access + ({ f: super["x"] } = { f }); + } +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/asyncModule_es2017.ts b/tests/cases/conformance/async/es2017/asyncModule_es2017.ts new file mode 100644 index 0000000000..7c577e27fb --- /dev/null +++ b/tests/cases/conformance/async/es2017/asyncModule_es2017.ts @@ -0,0 +1,4 @@ +// @target: es2017 +// @noEmitHelpers: true +async module M { +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/asyncMultiFile_es2017.ts b/tests/cases/conformance/async/es2017/asyncMultiFile_es2017.ts new file mode 100644 index 0000000000..920bdfb8bd --- /dev/null +++ b/tests/cases/conformance/async/es2017/asyncMultiFile_es2017.ts @@ -0,0 +1,5 @@ +// @target: es2017 +// @filename: a.ts +async function f() {} +// @filename: b.ts +function g() { } \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/asyncQualifiedReturnType_es2017.ts b/tests/cases/conformance/async/es2017/asyncQualifiedReturnType_es2017.ts new file mode 100644 index 0000000000..95695168ce --- /dev/null +++ b/tests/cases/conformance/async/es2017/asyncQualifiedReturnType_es2017.ts @@ -0,0 +1,9 @@ +// @target: es2017 +// @noEmitHelpers: true +namespace X { + export class MyPromise extends Promise { + } +} + +async function f(): X.MyPromise { +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/asyncSetter_es2017.ts b/tests/cases/conformance/async/es2017/asyncSetter_es2017.ts new file mode 100644 index 0000000000..658c07d42e --- /dev/null +++ b/tests/cases/conformance/async/es2017/asyncSetter_es2017.ts @@ -0,0 +1,6 @@ +// @target: es2017 +// @noEmitHelpers: true +class C { + async set foo(value) { + } +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/asyncUseStrict_es2017.ts b/tests/cases/conformance/async/es2017/asyncUseStrict_es2017.ts new file mode 100644 index 0000000000..c4d4cafef8 --- /dev/null +++ b/tests/cases/conformance/async/es2017/asyncUseStrict_es2017.ts @@ -0,0 +1,8 @@ +// @target: es2017 +// @noEmitHelpers: true +declare var a: boolean; +declare var p: Promise; +async function func(): Promise { + "use strict"; + var b = await p || a; +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/awaitBinaryExpression/awaitBinaryExpression1_es2017.ts b/tests/cases/conformance/async/es2017/awaitBinaryExpression/awaitBinaryExpression1_es2017.ts new file mode 100644 index 0000000000..ef9076a8be --- /dev/null +++ b/tests/cases/conformance/async/es2017/awaitBinaryExpression/awaitBinaryExpression1_es2017.ts @@ -0,0 +1,11 @@ +// @target: es2017 +// @noEmitHelpers: true +declare var a: boolean; +declare var p: Promise; +declare function before(): void; +declare function after(): void; +async function func(): Promise { + before(); + var b = await p || a; + after(); +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/awaitBinaryExpression/awaitBinaryExpression2_es2017.ts b/tests/cases/conformance/async/es2017/awaitBinaryExpression/awaitBinaryExpression2_es2017.ts new file mode 100644 index 0000000000..84d2f62229 --- /dev/null +++ b/tests/cases/conformance/async/es2017/awaitBinaryExpression/awaitBinaryExpression2_es2017.ts @@ -0,0 +1,11 @@ +// @target: es2017 +// @noEmitHelpers: true +declare var a: boolean; +declare var p: Promise; +declare function before(): void; +declare function after(): void; +async function func(): Promise { + before(); + var b = await p && a; + after(); +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/awaitBinaryExpression/awaitBinaryExpression3_es2017.ts b/tests/cases/conformance/async/es2017/awaitBinaryExpression/awaitBinaryExpression3_es2017.ts new file mode 100644 index 0000000000..1f3a8245d4 --- /dev/null +++ b/tests/cases/conformance/async/es2017/awaitBinaryExpression/awaitBinaryExpression3_es2017.ts @@ -0,0 +1,11 @@ +// @target: es2017 +// @noEmitHelpers: true +declare var a: number; +declare var p: Promise; +declare function before(): void; +declare function after(): void; +async function func(): Promise { + before(); + var b = await p + a; + after(); +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/awaitBinaryExpression/awaitBinaryExpression4_es2017.ts b/tests/cases/conformance/async/es2017/awaitBinaryExpression/awaitBinaryExpression4_es2017.ts new file mode 100644 index 0000000000..6c36f1e4ce --- /dev/null +++ b/tests/cases/conformance/async/es2017/awaitBinaryExpression/awaitBinaryExpression4_es2017.ts @@ -0,0 +1,11 @@ +// @target: es2017 +// @noEmitHelpers: true +declare var a: boolean; +declare var p: Promise; +declare function before(): void; +declare function after(): void; +async function func(): Promise { + before(); + var b = (await p, a); + after(); +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/awaitBinaryExpression/awaitBinaryExpression5_es2017.ts b/tests/cases/conformance/async/es2017/awaitBinaryExpression/awaitBinaryExpression5_es2017.ts new file mode 100644 index 0000000000..abbcbb95ba --- /dev/null +++ b/tests/cases/conformance/async/es2017/awaitBinaryExpression/awaitBinaryExpression5_es2017.ts @@ -0,0 +1,12 @@ +// @target: es2017 +// @noEmitHelpers: true +declare var a: boolean; +declare var p: Promise; +declare function before(): void; +declare function after(): void; +async function func(): Promise { + before(); + var o: { a: boolean; }; + o.a = await p; + after(); +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression1_es2017.ts b/tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression1_es2017.ts new file mode 100644 index 0000000000..da46e04ed1 --- /dev/null +++ b/tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression1_es2017.ts @@ -0,0 +1,15 @@ +// @target: es2017 +// @noEmitHelpers: true +declare var a: boolean; +declare var p: Promise; +declare function fn(arg0: boolean, arg1: boolean, arg2: boolean): void; +declare var o: { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }; +declare var pfn: Promise<{ (arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +declare var po: Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +declare function before(): void; +declare function after(): void; +async function func(): Promise { + before(); + var b = fn(a, a, a); + after(); +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression2_es2017.ts b/tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression2_es2017.ts new file mode 100644 index 0000000000..baf75ab95c --- /dev/null +++ b/tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression2_es2017.ts @@ -0,0 +1,15 @@ +// @target: es2017 +// @noEmitHelpers: true +declare var a: boolean; +declare var p: Promise; +declare function fn(arg0: boolean, arg1: boolean, arg2: boolean): void; +declare var o: { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }; +declare var pfn: Promise<{ (arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +declare var po: Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +declare function before(): void; +declare function after(): void; +async function func(): Promise { + before(); + var b = fn(await p, a, a); + after(); +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression3_es2017.ts b/tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression3_es2017.ts new file mode 100644 index 0000000000..17cf6d8c6c --- /dev/null +++ b/tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression3_es2017.ts @@ -0,0 +1,15 @@ +// @target: es2017 +// @noEmitHelpers: true +declare var a: boolean; +declare var p: Promise; +declare function fn(arg0: boolean, arg1: boolean, arg2: boolean): void; +declare var o: { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }; +declare var pfn: Promise<{ (arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +declare var po: Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +declare function before(): void; +declare function after(): void; +async function func(): Promise { + before(); + var b = fn(a, await p, a); + after(); +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression4_es2017.ts b/tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression4_es2017.ts new file mode 100644 index 0000000000..ef5e1d203d --- /dev/null +++ b/tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression4_es2017.ts @@ -0,0 +1,15 @@ +// @target: es2017 +// @noEmitHelpers: true +declare var a: boolean; +declare var p: Promise; +declare function fn(arg0: boolean, arg1: boolean, arg2: boolean): void; +declare var o: { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }; +declare var pfn: Promise<{ (arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +declare var po: Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +declare function before(): void; +declare function after(): void; +async function func(): Promise { + before(); + var b = (await pfn)(a, a, a); + after(); +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression5_es2017.ts b/tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression5_es2017.ts new file mode 100644 index 0000000000..8494bc11b4 --- /dev/null +++ b/tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression5_es2017.ts @@ -0,0 +1,15 @@ +// @target: es2017 +// @noEmitHelpers: true +declare var a: boolean; +declare var p: Promise; +declare function fn(arg0: boolean, arg1: boolean, arg2: boolean): void; +declare var o: { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }; +declare var pfn: Promise<{ (arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +declare var po: Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +declare function before(): void; +declare function after(): void; +async function func(): Promise { + before(); + var b = o.fn(a, a, a); + after(); +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression6_es2017.ts b/tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression6_es2017.ts new file mode 100644 index 0000000000..7939572bae --- /dev/null +++ b/tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression6_es2017.ts @@ -0,0 +1,15 @@ +// @target: es2017 +// @noEmitHelpers: true +declare var a: boolean; +declare var p: Promise; +declare function fn(arg0: boolean, arg1: boolean, arg2: boolean): void; +declare var o: { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }; +declare var pfn: Promise<{ (arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +declare var po: Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +declare function before(): void; +declare function after(): void; +async function func(): Promise { + before(); + var b = o.fn(await p, a, a); + after(); +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression7_es2017.ts b/tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression7_es2017.ts new file mode 100644 index 0000000000..3f1231a50d --- /dev/null +++ b/tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression7_es2017.ts @@ -0,0 +1,15 @@ +// @target: es2017 +// @noEmitHelpers: true +declare var a: boolean; +declare var p: Promise; +declare function fn(arg0: boolean, arg1: boolean, arg2: boolean): void; +declare var o: { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }; +declare var pfn: Promise<{ (arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +declare var po: Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +declare function before(): void; +declare function after(): void; +async function func(): Promise { + before(); + var b = o.fn(a, await p, a); + after(); +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression8_es2017.ts b/tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression8_es2017.ts new file mode 100644 index 0000000000..c669122bad --- /dev/null +++ b/tests/cases/conformance/async/es2017/awaitCallExpression/awaitCallExpression8_es2017.ts @@ -0,0 +1,15 @@ +// @target: es2017 +// @noEmitHelpers: true +declare var a: boolean; +declare var p: Promise; +declare function fn(arg0: boolean, arg1: boolean, arg2: boolean): void; +declare var o: { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }; +declare var pfn: Promise<{ (arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +declare var po: Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }>; +declare function before(): void; +declare function after(): void; +async function func(): Promise { + before(); + var b = (await po).fn(a, a, a); + after(); +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/awaitClassExpression_es2017.ts b/tests/cases/conformance/async/es2017/awaitClassExpression_es2017.ts new file mode 100644 index 0000000000..fe34d53a03 --- /dev/null +++ b/tests/cases/conformance/async/es2017/awaitClassExpression_es2017.ts @@ -0,0 +1,9 @@ +// @target: es2017 +// @noEmitHelpers: true +declare class C { } +declare var p: Promise; + +async function func(): Promise { + class D extends (await p) { + } +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/awaitUnion_es2017.ts b/tests/cases/conformance/async/es2017/awaitUnion_es2017.ts new file mode 100644 index 0000000000..493aa838ff --- /dev/null +++ b/tests/cases/conformance/async/es2017/awaitUnion_es2017.ts @@ -0,0 +1,14 @@ +// @target: es2017 +// @noEmitHelpers: true +declare let a: number | string; +declare let b: PromiseLike | PromiseLike; +declare let c: PromiseLike; +declare let d: number | PromiseLike; +declare let e: number | PromiseLike; +async function f() { + let await_a = await a; + let await_b = await b; + let await_c = await c; + let await_d = await d; + let await_e = await e; +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/await_unaryExpression_es2017.ts b/tests/cases/conformance/async/es2017/await_unaryExpression_es2017.ts new file mode 100644 index 0000000000..dee2554653 --- /dev/null +++ b/tests/cases/conformance/async/es2017/await_unaryExpression_es2017.ts @@ -0,0 +1,17 @@ +// @target: es2017 + +async function bar() { + !await 42; // OK +} + +async function bar1() { + +await 42; // OK +} + +async function bar3() { + -await 42; // OK +} + +async function bar4() { + ~await 42; // OK +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/await_unaryExpression_es2017_1.ts b/tests/cases/conformance/async/es2017/await_unaryExpression_es2017_1.ts new file mode 100644 index 0000000000..f38260b332 --- /dev/null +++ b/tests/cases/conformance/async/es2017/await_unaryExpression_es2017_1.ts @@ -0,0 +1,21 @@ +// @target: es2017 + +async function bar() { + !await 42; // OK +} + +async function bar1() { + delete await 42; // OK +} + +async function bar2() { + delete await 42; // OK +} + +async function bar3() { + void await 42; +} + +async function bar4() { + +await 42; +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/await_unaryExpression_es2017_2.ts b/tests/cases/conformance/async/es2017/await_unaryExpression_es2017_2.ts new file mode 100644 index 0000000000..b48c661f0b --- /dev/null +++ b/tests/cases/conformance/async/es2017/await_unaryExpression_es2017_2.ts @@ -0,0 +1,13 @@ +// @target: es2017 + +async function bar1() { + delete await 42; +} + +async function bar2() { + delete await 42; +} + +async function bar3() { + void await 42; +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/await_unaryExpression_es2017_3.ts b/tests/cases/conformance/async/es2017/await_unaryExpression_es2017_3.ts new file mode 100644 index 0000000000..d2c608d0e7 --- /dev/null +++ b/tests/cases/conformance/async/es2017/await_unaryExpression_es2017_3.ts @@ -0,0 +1,19 @@ +// @target: es2017 + +async function bar1() { + ++await 42; // Error +} + +async function bar2() { + --await 42; // Error +} + +async function bar3() { + var x = 42; + await x++; // OK but shouldn't need parenthesis +} + +async function bar4() { + var x = 42; + await x--; // OK but shouldn't need parenthesis +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration10_es2017.ts b/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration10_es2017.ts new file mode 100644 index 0000000000..9b74471394 --- /dev/null +++ b/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration10_es2017.ts @@ -0,0 +1,4 @@ +// @target: es2017 +// @noEmitHelpers: true +async function foo(a = await => await): Promise { +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration11_es2017.ts b/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration11_es2017.ts new file mode 100644 index 0000000000..9613e86616 --- /dev/null +++ b/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration11_es2017.ts @@ -0,0 +1,4 @@ +// @target: es2017 +// @noEmitHelpers: true +async function await(): Promise { +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration12_es2017.ts b/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration12_es2017.ts new file mode 100644 index 0000000000..02b6e833c2 --- /dev/null +++ b/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration12_es2017.ts @@ -0,0 +1,3 @@ +// @target: es2017 +// @noEmitHelpers: true +var v = async function await(): Promise { } \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration13_es2017.ts b/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration13_es2017.ts new file mode 100644 index 0000000000..40177c1fbc --- /dev/null +++ b/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration13_es2017.ts @@ -0,0 +1,6 @@ +// @target: es2017 +// @noEmitHelpers: true +async function foo(): Promise { + // Legal to use 'await' in a type context. + var v: await; +} diff --git a/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration14_es2017.ts b/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration14_es2017.ts new file mode 100644 index 0000000000..06bd2de3ee --- /dev/null +++ b/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration14_es2017.ts @@ -0,0 +1,5 @@ +// @target: es2017 +// @noEmitHelpers: true +async function foo(): Promise { + return; +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration15_es2017.ts b/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration15_es2017.ts new file mode 100644 index 0000000000..2585dc666f --- /dev/null +++ b/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration15_es2017.ts @@ -0,0 +1,25 @@ +// @target: es2017 +// @noEmitHelpers: true +declare class Thenable { then(): void; } +declare let a: any; +declare let obj: { then: string; }; +declare let thenable: Thenable; +async function fn1() { } // valid: Promise +async function fn2(): { } { } // error +async function fn3(): any { } // error +async function fn4(): number { } // error +async function fn5(): PromiseLike { } // error +async function fn6(): Thenable { } // error +async function fn7() { return; } // valid: Promise +async function fn8() { return 1; } // valid: Promise +async function fn9() { return null; } // valid: Promise +async function fn10() { return undefined; } // valid: Promise +async function fn11() { return a; } // valid: Promise +async function fn12() { return obj; } // valid: Promise<{ then: string; }> +async function fn13() { return thenable; } // error +async function fn14() { await 1; } // valid: Promise +async function fn15() { await null; } // valid: Promise +async function fn16() { await undefined; } // valid: Promise +async function fn17() { await a; } // valid: Promise +async function fn18() { await obj; } // valid: Promise +async function fn19() { await thenable; } // error diff --git a/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration1_es2017.ts b/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration1_es2017.ts new file mode 100644 index 0000000000..178611ad91 --- /dev/null +++ b/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration1_es2017.ts @@ -0,0 +1,4 @@ +// @target: es2017 +// @noEmitHelpers: true +async function foo(): Promise { +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration2_es2017.ts b/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration2_es2017.ts new file mode 100644 index 0000000000..08711a4cfb --- /dev/null +++ b/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration2_es2017.ts @@ -0,0 +1,4 @@ +// @target: es2017 +// @noEmitHelpers: true +function f(await) { +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration3_es2017.ts b/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration3_es2017.ts new file mode 100644 index 0000000000..9b5924fc14 --- /dev/null +++ b/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration3_es2017.ts @@ -0,0 +1,4 @@ +// @target: es2017 +// @noEmitHelpers: true +function f(await = await) { +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration4_es2017.ts b/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration4_es2017.ts new file mode 100644 index 0000000000..84c6c93b90 --- /dev/null +++ b/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration4_es2017.ts @@ -0,0 +1,4 @@ +// @target: es2017 +// @noEmitHelpers: true +function await() { +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration5_es2017.ts b/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration5_es2017.ts new file mode 100644 index 0000000000..c57fb73d6d --- /dev/null +++ b/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration5_es2017.ts @@ -0,0 +1,4 @@ +// @target: es2017 +// @noEmitHelpers: true +async function foo(await): Promise { +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration6_es2017.ts b/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration6_es2017.ts new file mode 100644 index 0000000000..1ceb160c12 --- /dev/null +++ b/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration6_es2017.ts @@ -0,0 +1,4 @@ +// @target: es2017 +// @noEmitHelpers: true +async function foo(a = await): Promise { +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration7_es2017.ts b/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration7_es2017.ts new file mode 100644 index 0000000000..e5c2649d34 --- /dev/null +++ b/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration7_es2017.ts @@ -0,0 +1,7 @@ +// @target: es2017 +// @noEmitHelpers: true +async function bar(): Promise { + // 'await' here is an identifier, and not a yield expression. + async function foo(a = await): Promise { + } +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration8_es2017.ts b/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration8_es2017.ts new file mode 100644 index 0000000000..64e62a2719 --- /dev/null +++ b/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration8_es2017.ts @@ -0,0 +1,3 @@ +// @target: es2017 +// @noEmitHelpers: true +var v = { [await]: foo } \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration9_es2017.ts b/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration9_es2017.ts new file mode 100644 index 0000000000..7d3b7213b9 --- /dev/null +++ b/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration9_es2017.ts @@ -0,0 +1,5 @@ +// @target: es2017 +// @noEmitHelpers: true +async function foo(): Promise { + var v = { [await]: foo } +} \ No newline at end of file From c03b04bd4f278dc338ba15017ee8c47b20d96163 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Wed, 12 Oct 2016 14:26:30 -0700 Subject: [PATCH 27/80] Only use localeCompare in CompareStrings --- src/compiler/core.ts | 20 +++++++++++++------- src/harness/harness.ts | 2 +- src/server/session.ts | 2 +- src/services/navigateTo.ts | 4 ++-- src/services/navigationBar.ts | 2 +- 5 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 5ad9fa2c19..47eb66db07 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -23,6 +23,10 @@ namespace ts { // More efficient to create a collator once and use its `compare` than to call `a.localeCompare(b)` many times. export const collator: { compare(a: string, b: string): number } = typeof Intl === "object" && typeof Intl.Collator === "function" ? new Intl.Collator() : undefined; + // This means "compare in a case insensitive manner but consider accentsor other diacritic marks" + // (e.g. a ≠ b, a ≠ á, a = A) + const accentSensitivity: Intl.CollatorOptions = { usage: "sort", sensitivity: "accent" }; + /** * Use this function instead of calling "String.prototype.localeCompre". This function will preform appropriate check to make sure that * "typeof Intl" is correct as there are reported issues #11110 nad #11339. @@ -1029,13 +1033,13 @@ namespace ts { return a < b ? Comparison.LessThan : Comparison.GreaterThan; } - export function compareStrings(a: string, b: string, ignoreCase?: boolean): Comparison { + export function compareStrings(a: string, b: string, locales?: string | string[], options?: Intl.CollatorOptions): Comparison { if (a === b) return Comparison.EqualTo; if (a === undefined) return Comparison.LessThan; if (b === undefined) return Comparison.GreaterThan; - if (ignoreCase) { - const result = localeCompare(a, b, /*locales*/ undefined, /*options*/ { usage: "sort", sensitivity: "accent" }); - if (result) { + if (options) { + if (collator && String.prototype.localeCompare) { + const result = a.localeCompare(b, locales, options); return result < 0 ? Comparison.LessThan : result > 0 ? Comparison.GreaterThan : Comparison.EqualTo; } @@ -1048,7 +1052,7 @@ namespace ts { } export function compareStringsCaseInsensitive(a: string, b: string) { - return compareStrings(a, b, /*ignoreCase*/ true); + return compareStrings(a, b, /*locales*/ undefined, accentSensitivity); } function getDiagnosticFileName(diagnostic: Diagnostic): string { @@ -1418,7 +1422,8 @@ namespace ts { const bComponents = getNormalizedPathComponents(b, currentDirectory); const sharedLength = Math.min(aComponents.length, bComponents.length); for (let i = 0; i < sharedLength; i++) { - const result = compareStrings(aComponents[i], bComponents[i], ignoreCase); + const result = compareStrings(aComponents[i], bComponents[i], + /*locales*/ undefined, /*options*/ ignoreCase ? accentSensitivity : undefined); if (result !== Comparison.EqualTo) { return result; } @@ -1440,7 +1445,8 @@ namespace ts { } for (let i = 0; i < parentComponents.length; i++) { - const result = compareStrings(parentComponents[i], childComponents[i], ignoreCase); + const result = compareStrings(parentComponents[i], childComponents[i], + /*locales*/ undefined, /*options*/ ignoreCase ? accentSensitivity : undefined); if (result !== Comparison.EqualTo) { return false; } diff --git a/src/harness/harness.ts b/src/harness/harness.ts index f26a9dd062..9d27257c80 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -1634,7 +1634,7 @@ namespace Harness { export function collateOutputs(outputFiles: Harness.Compiler.GeneratedFile[]): string { // Collect, test, and sort the fileNames - outputFiles.sort((a, b) => ts.localeCompare(cleanName(a.fileName), cleanName(b.fileName))); + outputFiles.sort((a, b) => ts.compareStrings(cleanName(a.fileName), cleanName(b.fileName))); // Emit them let result = ""; diff --git a/src/server/session.ts b/src/server/session.ts index d4633f119e..cebdef717b 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -959,7 +959,7 @@ namespace ts.server { result.push({ name, kind, kindModifiers, sortText, replacementSpan: convertedSpan }); } return result; - }, []).sort((a, b) => localeCompare(a.name, b.name)); + }, []).sort((a, b) => ts.compareStrings(a.name, b.name)); } else { return completions; diff --git a/src/services/navigateTo.ts b/src/services/navigateTo.ts index 8c968db7eb..2433dbe979 100644 --- a/src/services/navigateTo.ts +++ b/src/services/navigateTo.ts @@ -188,8 +188,8 @@ namespace ts.NavigateTo { // We first sort case insensitively. So "Aaa" will come before "bar". // Then we sort case sensitively, so "aaa" will come before "Aaa". return i1.matchKind - i2.matchKind || - ts.localeCompare(i1.name, i2.name, /*locales*/ undefined, /*options*/ baseSensitivity) || - ts.localeCompare(i1.name, i2.name); + ts.compareStrings(i1.name, i2.name, /*locales*/ undefined, /*options*/ baseSensitivity) || + ts.compareStrings(i1.name, i2.name); } function createNavigateToItem(rawItem: RawNavigateToItem): NavigateToItem { diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index f981ad6016..4dacf202ef 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -335,7 +335,7 @@ namespace ts.NavigationBar { if (chA === "'" && chB === "\"") { return -1; } - const cmp = ts.localeCompare(chA.toLocaleLowerCase(), chB.toLocaleLowerCase()); + const cmp = ts.compareStrings(chA.toLocaleLowerCase(), chB.toLocaleLowerCase()); if (cmp !== 0) { return cmp; } From e60e97f5c9d7a2c21ba36631c17f9278166feeae Mon Sep 17 00:00:00 2001 From: Andrej Baran Date: Thu, 13 Oct 2016 01:04:38 +0200 Subject: [PATCH 28/80] Cleanup comments --- src/compiler/transformers/es2017.ts | 2 -- src/compiler/transformers/ts.ts | 8 -------- 2 files changed, 10 deletions(-) diff --git a/src/compiler/transformers/es2017.ts b/src/compiler/transformers/es2017.ts index 33376bbceb..166e116082 100644 --- a/src/compiler/transformers/es2017.ts +++ b/src/compiler/transformers/es2017.ts @@ -71,8 +71,6 @@ namespace ts { return visitEachChild(node, visitor, context); } - // node = visitEachChild(node, visitor, context); - // return visitEachChild(node, visitor, context); return node; } diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 30276deff9..2aa20410d8 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -2247,10 +2247,6 @@ namespace ts { } function transformFunctionBody(node: MethodDeclaration | AccessorDeclaration | FunctionDeclaration | FunctionExpression): FunctionBody { - // if (isAsyncFunctionLike(node) && languageVersion < ScriptTarget.ES2017) { - // return transformAsyncFunctionBody(node); - // } - return transformFunctionBodyWorker(node.body); } @@ -2267,10 +2263,6 @@ namespace ts { } function transformConciseBody(node: ArrowFunction): ConciseBody { - // if (isAsyncFunctionLike(node) && languageVersion < ScriptTarget.ES2017) { - // return transformAsyncFunctionBody(node); - // } - return transformConciseBodyWorker(node.body, /*forceBlockFunctionBody*/ false); } From f0fd77ae8edb070e9f01cb0b5f6c69e9454f393a Mon Sep 17 00:00:00 2001 From: Andrej Baran Date: Thu, 13 Oct 2016 11:58:01 +0200 Subject: [PATCH 29/80] Make async/await an ES2017 feature only --- src/compiler/binder.ts | 31 ++++++++---------- src/compiler/transformers/es2017.ts | 13 ++++---- src/compiler/transformers/ts.ts | 49 ++++++----------------------- 3 files changed, 28 insertions(+), 65 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 4edbb5d9e1..3f5db2ae7c 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -2555,11 +2555,6 @@ namespace ts { // extends clause of a class. let transformFlags = subtreeFlags | TransformFlags.AssertES6; - // propagate ES2017 - if (node.expression.transformFlags & TransformFlags.ContainsES2017) { - transformFlags |= TransformFlags.ContainsES2017; - } - // If an ExpressionWithTypeArguments contains type arguments, then it // is TypeScript syntax. if (node.typeArguments) { @@ -2591,16 +2586,16 @@ namespace ts { const typeParameters = node.typeParameters; const asteriskToken = node.asteriskToken; - // A MethodDeclaration is TypeScript syntax if it is either async, abstract, overloaded, + // A MethodDeclaration is TypeScript syntax if it is either abstract, overloaded, // generic, or has a decorator. if (!body || typeParameters - || (modifierFlags & (ModifierFlags.Async | ModifierFlags.Abstract)) + || (modifierFlags & ModifierFlags.Abstract) || (subtreeFlags & TransformFlags.ContainsDecorators)) { transformFlags |= TransformFlags.AssertTypeScript; } - // Async MethodDeclaration is ES2017 + // An async method declaration is ES2017 syntax. if (modifierFlags & ModifierFlags.Async) { transformFlags |= TransformFlags.AssertES2017; } @@ -2619,10 +2614,10 @@ namespace ts { const modifierFlags = getModifierFlags(node); const body = node.body; - // A MethodDeclaration is TypeScript syntax if it is either async, abstract, overloaded, + // An accessor is TypeScript syntax if it is either abstract, overloaded, // generic, or has a decorator. if (!body - || (modifierFlags & (ModifierFlags.Async | ModifierFlags.Abstract)) + || (modifierFlags & ModifierFlags.Abstract) || (subtreeFlags & TransformFlags.ContainsDecorators)) { transformFlags |= TransformFlags.AssertTypeScript; } @@ -2664,9 +2659,9 @@ namespace ts { transformFlags |= TransformFlags.AssertTypeScript | TransformFlags.AssertES6; } - // If a FunctionDeclaration is async, then it is TypeScript syntax. + // An async function declaration is ES2017 syntax. if (modifierFlags & ModifierFlags.Async) { - transformFlags |= TransformFlags.AssertTypeScript | TransformFlags.AssertES2017; + transformFlags |= TransformFlags.AssertES2017; } // If a FunctionDeclaration's subtree has marked the container as needing to capture the @@ -2695,9 +2690,9 @@ namespace ts { const modifierFlags = getModifierFlags(node); const asteriskToken = node.asteriskToken; - // An async function expression is TypeScript syntax. + // An async function expression is ES2017 syntax. if (modifierFlags & ModifierFlags.Async) { - transformFlags |= TransformFlags.AssertTypeScript | TransformFlags.AssertES2017; + transformFlags |= TransformFlags.AssertES2017; } // If a FunctionExpression's subtree has marked the container as needing to capture the @@ -2725,9 +2720,9 @@ namespace ts { let transformFlags = subtreeFlags | TransformFlags.AssertES6; const modifierFlags = getModifierFlags(node); - // An async arrow function is TypeScript syntax. + // An async arrow function is ES2017 syntax. if (modifierFlags & ModifierFlags.Async) { - transformFlags |= TransformFlags.AssertTypeScript | TransformFlags.AssertES2017; + transformFlags |= TransformFlags.AssertES2017; } // If an ArrowFunction contains a lexical this, its container must capture the lexical this. @@ -2868,8 +2863,8 @@ namespace ts { switch (kind) { case SyntaxKind.AsyncKeyword: case SyntaxKind.AwaitExpression: - // Typescript async/await are ES2017 features - transformFlags |= TransformFlags.AssertTypeScript | TransformFlags.AssertES2017; + // async/await is ES2017 syntax + transformFlags |= TransformFlags.AssertES2017; break; case SyntaxKind.PublicKeyword: diff --git a/src/compiler/transformers/es2017.ts b/src/compiler/transformers/es2017.ts index 166e116082..7555c3bdd7 100644 --- a/src/compiler/transformers/es2017.ts +++ b/src/compiler/transformers/es2017.ts @@ -77,26 +77,27 @@ namespace ts { function visitorWorker(node: Node): VisitResult { switch (node.kind) { case SyntaxKind.AsyncKeyword: + // ES2017 async modifier should be elided for targets < ES2017 return undefined; case SyntaxKind.AwaitExpression: - // Typescript 'await' expressions must be transformed for targets < ES2017. + // ES2017 'await' expressions must be transformed for targets < ES2017. return visitAwaitExpression(node); case SyntaxKind.MethodDeclaration: - // TypeScript method declarations may be 'async' + // ES2017 method declarations may be 'async' return visitMethodDeclaration(node); case SyntaxKind.FunctionDeclaration: - // TypeScript function declarations may be 'async' + // ES2017 function declarations may be 'async' return visitFunctionDeclaration(node); case SyntaxKind.FunctionExpression: - // TypeScript function expressions may be 'async' + // ES2017 function expressions may be 'async' return visitFunctionExpression(node); case SyntaxKind.ArrowFunction: - // TypeScript arrow functions may be 'async' + // ES2017 arrow functions may be 'async' return visitArrowFunction(node); default: @@ -160,9 +161,7 @@ namespace ts { * Visits a function declaration. * * This function will be called when one of the following conditions are met: - * - The node is an overload * - The node is marked async - * - The node is exported from a TypeScript namespace * * @param node The function node. */ diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 2aa20410d8..61f40e1ed8 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -230,10 +230,6 @@ namespace ts { // ES6 export and default modifiers are elided when inside a namespace. return currentNamespace ? undefined : node; - // Typescript ES2017 async/await are handled by ES2017 transformer - case SyntaxKind.AsyncKeyword: - return node; - case SyntaxKind.PublicKeyword: case SyntaxKind.PrivateKeyword: case SyntaxKind.ProtectedKeyword: @@ -297,7 +293,6 @@ namespace ts { // - property declarations // - index signatures // - method overload signatures - // - async methods return visitClassDeclaration(node); case SyntaxKind.ClassExpression: @@ -310,7 +305,6 @@ namespace ts { // - property declarations // - index signatures // - method overload signatures - // - async methods return visitClassExpression(node); case SyntaxKind.HeritageClause: @@ -325,7 +319,7 @@ namespace ts { return visitExpressionWithTypeArguments(node); case SyntaxKind.MethodDeclaration: - // TypeScript method declarations may be 'async', and may have decorators, modifiers + // TypeScript method declarations may have decorators, modifiers // or type annotations. return visitMethodDeclaration(node); @@ -334,19 +328,19 @@ namespace ts { return visitGetAccessor(node); case SyntaxKind.SetAccessor: - // Set Accessors can have TypeScript modifiers, decorators, and type annotations. + // Set Accessors can have TypeScript modifiers and type annotations. return visitSetAccessor(node); case SyntaxKind.FunctionDeclaration: - // TypeScript function declarations may be 'async' + // Typescript function declarations can have modifiers, decorators, and type annotations. return visitFunctionDeclaration(node); case SyntaxKind.FunctionExpression: - // TypeScript function expressions may be 'async' + // TypeScript function expressions can have modifiers and type annotations. return visitFunctionExpression(node); case SyntaxKind.ArrowFunction: - // TypeScript arrow functions may be 'async' + // TypeScript arrow functions can have modifiers and type annotations. return visitArrowFunction(node); case SyntaxKind.Parameter: @@ -378,10 +372,6 @@ namespace ts { // TypeScript enum declarations do not exist in ES6 and must be rewritten. return visitEnumDeclaration(node); - case SyntaxKind.AwaitExpression: - // Typescript ES2017 async/await are handled by ES2017 transformer - return visitAwaitExpression(node); - case SyntaxKind.VariableStatement: // TypeScript namespace exports for variable statements must be transformed. return visitVariableStatement(node); @@ -2050,7 +2040,7 @@ namespace ts { * * This function will be called when one of the following conditions are met: * - The node is an overload - * - The node is marked as abstract, async, public, private, protected, or readonly + * - The node is marked as abstract, public, private, protected, or readonly * - The node has both a decorator and a computed property name * * @param node The method node. @@ -2161,8 +2151,8 @@ namespace ts { * * This function will be called when one of the following conditions are met: * - The node is an overload - * - The node is marked async * - The node is exported from a TypeScript namespace + * - The node has decorators * * @param node The function node. */ @@ -2197,7 +2187,7 @@ namespace ts { * Visits a function expression node. * * This function will be called when one of the following conditions are met: - * - The node is marked async + * - The node has type annotations * * @param node The function expression node. */ @@ -2216,10 +2206,6 @@ namespace ts { /*location*/ node ); - // Keep modifiers in case of async functions - const funcModifiers = visitNodes(node.modifiers, visitor, isModifier); - func.modifiers = createNodeArray(funcModifiers); - setOriginalNode(func, node); return func; @@ -2228,7 +2214,7 @@ namespace ts { /** * @remarks * This function will be called when one of the following conditions are met: - * - The node is marked async + * - The node has type annotations */ function visitArrowFunction(node: ArrowFunction) { const func = createArrowFunction( @@ -2368,23 +2354,6 @@ namespace ts { } } - /** - * Visits an await expression. - * - * This function will be called any time a ES2017 await expression is encountered. - * - * @param node The await expression node. - */ - function visitAwaitExpression(node: AwaitExpression): Expression { - return updateNode( - createAwait( - visitNode(node.expression, visitor, isExpression), - /*location*/ node - ), - node - ); - } - /** * Visits a parenthesized expression that contains either a type assertion or an `as` * expression. From 4284a749b45c441dab54f699e1aa5087527ffeac Mon Sep 17 00:00:00 2001 From: Andrej Baran Date: Thu, 13 Oct 2016 11:32:26 +0200 Subject: [PATCH 30/80] Adjust some async conformance baselines --- .../reference/asyncFunctionDeclaration10_es2017.js | 1 + tests/baselines/reference/asyncFunctionDeclaration10_es5.js | 6 ++++++ tests/baselines/reference/asyncFunctionDeclaration10_es6.js | 3 +++ .../reference/asyncFunctionDeclaration12_es2017.js | 2 +- .../baselines/reference/asyncFunctionDeclaration5_es2017.js | 1 + tests/baselines/reference/asyncFunctionDeclaration5_es5.js | 5 +++++ tests/baselines/reference/asyncFunctionDeclaration5_es6.js | 3 +++ 7 files changed, 20 insertions(+), 1 deletion(-) diff --git a/tests/baselines/reference/asyncFunctionDeclaration10_es2017.js b/tests/baselines/reference/asyncFunctionDeclaration10_es2017.js index 0e687c1e0d..f8a2220431 100644 --- a/tests/baselines/reference/asyncFunctionDeclaration10_es2017.js +++ b/tests/baselines/reference/asyncFunctionDeclaration10_es2017.js @@ -3,5 +3,6 @@ async function foo(a = await => await): Promise { } //// [asyncFunctionDeclaration10_es2017.js] +async function foo(a = await ) { } await; Promise < void > {}; diff --git a/tests/baselines/reference/asyncFunctionDeclaration10_es5.js b/tests/baselines/reference/asyncFunctionDeclaration10_es5.js index 05ff9daa9d..758bdab5dc 100644 --- a/tests/baselines/reference/asyncFunctionDeclaration10_es5.js +++ b/tests/baselines/reference/asyncFunctionDeclaration10_es5.js @@ -3,5 +3,11 @@ async function foo(a = await => await): Promise { } //// [asyncFunctionDeclaration10_es5.js] +function foo(a) { + if (a === void 0) { a = yield ; } + return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { + return [2 /*return*/]; + }); }); +} await; Promise < void > {}; diff --git a/tests/baselines/reference/asyncFunctionDeclaration10_es6.js b/tests/baselines/reference/asyncFunctionDeclaration10_es6.js index 141c0cbab5..1f175035bf 100644 --- a/tests/baselines/reference/asyncFunctionDeclaration10_es6.js +++ b/tests/baselines/reference/asyncFunctionDeclaration10_es6.js @@ -3,5 +3,8 @@ async function foo(a = await => await): Promise { } //// [asyncFunctionDeclaration10_es6.js] +function foo(a = yield ) { + return __awaiter(this, void 0, void 0, function* () { }); +} await; Promise < void > {}; diff --git a/tests/baselines/reference/asyncFunctionDeclaration12_es2017.js b/tests/baselines/reference/asyncFunctionDeclaration12_es2017.js index 69f5993f5c..93fbb06102 100644 --- a/tests/baselines/reference/asyncFunctionDeclaration12_es2017.js +++ b/tests/baselines/reference/asyncFunctionDeclaration12_es2017.js @@ -2,4 +2,4 @@ var v = async function await(): Promise { } //// [asyncFunctionDeclaration12_es2017.js] -var v = , await = () => { }; +var v = async function () { }, await = () => { }; diff --git a/tests/baselines/reference/asyncFunctionDeclaration5_es2017.js b/tests/baselines/reference/asyncFunctionDeclaration5_es2017.js index 13c04c5d5b..904bbe62f0 100644 --- a/tests/baselines/reference/asyncFunctionDeclaration5_es2017.js +++ b/tests/baselines/reference/asyncFunctionDeclaration5_es2017.js @@ -3,5 +3,6 @@ async function foo(await): Promise { } //// [asyncFunctionDeclaration5_es2017.js] +async function foo() { } await; Promise < void > {}; diff --git a/tests/baselines/reference/asyncFunctionDeclaration5_es5.js b/tests/baselines/reference/asyncFunctionDeclaration5_es5.js index 22c18ff6ad..5f8f8f4273 100644 --- a/tests/baselines/reference/asyncFunctionDeclaration5_es5.js +++ b/tests/baselines/reference/asyncFunctionDeclaration5_es5.js @@ -3,5 +3,10 @@ async function foo(await): Promise { } //// [asyncFunctionDeclaration5_es5.js] +function foo() { + return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { + return [2 /*return*/]; + }); }); +} await; Promise < void > {}; diff --git a/tests/baselines/reference/asyncFunctionDeclaration5_es6.js b/tests/baselines/reference/asyncFunctionDeclaration5_es6.js index 8d28c37146..9521b76041 100644 --- a/tests/baselines/reference/asyncFunctionDeclaration5_es6.js +++ b/tests/baselines/reference/asyncFunctionDeclaration5_es6.js @@ -3,5 +3,8 @@ async function foo(await): Promise { } //// [asyncFunctionDeclaration5_es6.js] +function foo() { + return __awaiter(this, void 0, void 0, function* () { }); +} await; Promise < void > {}; From 7df3fda2b36e6a1eda5478a9077074e57e35c925 Mon Sep 17 00:00:00 2001 From: Andrej Baran Date: Thu, 13 Oct 2016 12:03:53 +0200 Subject: [PATCH 31/80] Refactor createFunctionExpresson --- src/compiler/factory.ts | 17 +++++++++++------ src/compiler/transformers/es2017.ts | 3 +-- src/compiler/transformers/es6.ts | 5 ++++- src/compiler/transformers/generators.ts | 4 +++- src/compiler/transformers/module/module.ts | 1 + src/compiler/transformers/module/system.ts | 3 +++ src/compiler/transformers/ts.ts | 3 +++ src/compiler/visitor.ts | 3 ++- 8 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index d873c3ef87..519269ccfd 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -524,9 +524,9 @@ namespace ts { return node; } - export function createFunctionExpression(asteriskToken: Node, name: string | Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) { + export function createFunctionExpression(modifiers: Modifier[], asteriskToken: Node, name: string | Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block, location?: TextRange, flags?: NodeFlags) { const node = createNode(SyntaxKind.FunctionExpression, location, flags); - node.modifiers = undefined; + node.modifiers = modifiers ? createNodeArray(modifiers) : undefined; node.asteriskToken = asteriskToken; node.name = typeof name === "string" ? createIdentifier(name) : name; node.typeParameters = typeParameters ? createNodeArray(typeParameters) : undefined; @@ -536,9 +536,9 @@ namespace ts { return node; } - export function updateFunctionExpression(node: FunctionExpression, name: Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block) { - if (node.name !== name || node.typeParameters !== typeParameters || node.parameters !== parameters || node.type !== type || node.body !== body) { - return updateNode(createFunctionExpression(node.asteriskToken, name, typeParameters, parameters, type, body, /*location*/ node, node.flags), node); + export function updateFunctionExpression(node: FunctionExpression, modifiers: Modifier[], name: Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block) { + if (node.name !== name || node.modifiers !== modifiers || node.typeParameters !== typeParameters || node.parameters !== parameters || node.type !== type || node.body !== body) { + return updateNode(createFunctionExpression(modifiers, node.asteriskToken, name, typeParameters, parameters, type, body, /*location*/ node, node.flags), node); } return node; } @@ -1735,6 +1735,7 @@ namespace ts { export function createAwaiterHelper(externalHelpersModuleName: Identifier | undefined, hasLexicalArguments: boolean, promiseConstructor: EntityName | Expression, body: Block) { const generatorFunc = createFunctionExpression( + /*modifiers*/ undefined, createNode(SyntaxKind.AsteriskToken), /*name*/ undefined, /*typeParameters*/ undefined, @@ -1908,6 +1909,7 @@ namespace ts { createCall( createParen( createFunctionExpression( + /*modifiers*/ undefined, /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, @@ -2089,6 +2091,7 @@ namespace ts { const properties: ObjectLiteralElementLike[] = []; if (getAccessor) { const getterFunction = createFunctionExpression( + getAccessor.modifiers, /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, @@ -2104,6 +2107,7 @@ namespace ts { if (setAccessor) { const setterFunction = createFunctionExpression( + setAccessor.modifiers, /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, @@ -2170,6 +2174,7 @@ namespace ts { createMemberAccessForPropertyName(receiver, method.name, /*location*/ method.name), setOriginalNode( createFunctionExpression( + method.modifiers, method.asteriskToken, /*name*/ undefined, /*typeParameters*/ undefined, @@ -2909,4 +2914,4 @@ namespace ts { function tryGetModuleNameFromDeclaration(declaration: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration, host: EmitHost, resolver: EmitResolver, compilerOptions: CompilerOptions) { return tryGetModuleNameFromFile(resolver.getExternalModuleFileFromDeclaration(declaration), host, compilerOptions); } -} \ No newline at end of file +} diff --git a/src/compiler/transformers/es2017.ts b/src/compiler/transformers/es2017.ts index 7555c3bdd7..1d3c189110 100644 --- a/src/compiler/transformers/es2017.ts +++ b/src/compiler/transformers/es2017.ts @@ -202,6 +202,7 @@ namespace ts { } const func = createFunctionExpression( + /*modifiers*/ undefined, node.asteriskToken, node.name, /*typeParameters*/ undefined, @@ -211,8 +212,6 @@ namespace ts { /*location*/ node ); - node.modifiers = visitNodes(node.modifiers, visitor, isModifier); - setOriginalNode(func, node); return func; diff --git a/src/compiler/transformers/es6.ts b/src/compiler/transformers/es6.ts index 7fb0594a6c..ba5f8a3fb7 100644 --- a/src/compiler/transformers/es6.ts +++ b/src/compiler/transformers/es6.ts @@ -681,6 +681,7 @@ namespace ts { const extendsClauseElement = getClassExtendsHeritageClauseElement(node); const classFunction = createFunctionExpression( + /*modifiers*/ undefined, /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, @@ -1509,6 +1510,7 @@ namespace ts { const expression = setOriginalNode( createFunctionExpression( + /*modifiers*/ undefined, node.asteriskToken, name, /*typeParameters*/ undefined, @@ -2240,6 +2242,7 @@ namespace ts { /*type*/ undefined, setEmitFlags( createFunctionExpression( + /*modifiers*/ undefined, isAsyncBlockContainingAwait ? createToken(SyntaxKind.AsteriskToken) : undefined, /*name*/ undefined, /*typeParameters*/ undefined, @@ -3256,4 +3259,4 @@ namespace ts { return isIdentifier(expression) && expression === parameter.name; } } -} \ No newline at end of file +} diff --git a/src/compiler/transformers/generators.ts b/src/compiler/transformers/generators.ts index f3a47f037c..88788022ef 100644 --- a/src/compiler/transformers/generators.ts +++ b/src/compiler/transformers/generators.ts @@ -496,6 +496,7 @@ namespace ts { if (node.asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) { node = setOriginalNode( createFunctionExpression( + /*modifiers*/ undefined, /*asteriskToken*/ undefined, node.name, /*typeParameters*/ undefined, @@ -2591,6 +2592,7 @@ namespace ts { createThis(), setEmitFlags( createFunctionExpression( + /*modifiers*/ undefined, /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, @@ -3080,4 +3082,4 @@ namespace ts { ); } } -} \ No newline at end of file +} diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index 3877169e6c..9051f375bf 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -179,6 +179,7 @@ namespace ts { // // function (require, exports, module1, module2) ... createFunctionExpression( + /*modifiers*/ undefined, /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, diff --git a/src/compiler/transformers/module/system.ts b/src/compiler/transformers/module/system.ts index d4ee4f36b8..e7b441f4c9 100644 --- a/src/compiler/transformers/module/system.ts +++ b/src/compiler/transformers/module/system.ts @@ -110,6 +110,7 @@ namespace ts { const moduleName = tryGetModuleNameFromFile(node, host, compilerOptions); const dependencies = createArrayLiteral(map(dependencyGroups, getNameOfDependencyGroup)); const body = createFunctionExpression( + /*modifiers*/ undefined, /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, @@ -244,6 +245,7 @@ namespace ts { ), createPropertyAssignment("execute", createFunctionExpression( + /*modifiers*/ undefined, /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, @@ -430,6 +432,7 @@ namespace ts { setters.push( createFunctionExpression( + /*modifiers*/ undefined, /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 61f40e1ed8..77ab6a6ca0 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -2197,6 +2197,7 @@ namespace ts { } const func = createFunctionExpression( + visitNodes(node.modifiers, visitor, isModifier), node.asteriskToken, node.name, /*typeParameters*/ undefined, @@ -2477,6 +2478,7 @@ namespace ts { const enumStatement = createStatement( createCall( createFunctionExpression( + /*modifiers*/ undefined, /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, @@ -2748,6 +2750,7 @@ namespace ts { const moduleStatement = createStatement( createCall( createFunctionExpression( + /*modifiers*/ undefined, /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index e147eda853..6910f5aac4 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -807,6 +807,7 @@ namespace ts { case SyntaxKind.FunctionExpression: return updateFunctionExpression(node, + visitNodes((node).modifiers, visitor, isModifier), visitNode((node).name, visitor, isPropertyName), visitNodes((node).typeParameters, visitor, isTypeParameter), (context.startLexicalEnvironment(), visitNodes((node).parameters, visitor, isParameter)), @@ -1357,4 +1358,4 @@ namespace ts { } } } -} \ No newline at end of file +} From c5ddf27dc68d6dc49a3d6f01e1db35fa6b455b79 Mon Sep 17 00:00:00 2001 From: Andrej Baran Date: Thu, 13 Oct 2016 12:04:36 +0200 Subject: [PATCH 32/80] Remove constant substitution from ES2017 transformer --- src/compiler/transformers/es2017.ts | 32 +---------------------------- 1 file changed, 1 insertion(+), 31 deletions(-) diff --git a/src/compiler/transformers/es2017.ts b/src/compiler/transformers/es2017.ts index 1d3c189110..f9e8b539c6 100644 --- a/src/compiler/transformers/es2017.ts +++ b/src/compiler/transformers/es2017.ts @@ -395,7 +395,7 @@ namespace ts { } } - return substituteConstantValue(node); + return node; } function substituteElementAccessExpression(node: ElementAccessExpression) { @@ -410,39 +410,9 @@ namespace ts { } } - return substituteConstantValue(node); - } - - function substituteConstantValue(node: PropertyAccessExpression | ElementAccessExpression): LeftHandSideExpression { - const constantValue = tryGetConstEnumValue(node); - if (constantValue !== undefined) { - const substitute = createLiteral(constantValue); - setSourceMapRange(substitute, node); - setCommentRange(substitute, node); - if (!compilerOptions.removeComments) { - const propertyName = isPropertyAccessExpression(node) - ? declarationNameToString(node.name) - : getTextOfNode(node.argumentExpression); - substitute.trailingComment = ` ${propertyName} `; - } - - setConstantValue(node, constantValue); - return substitute; - } - return node; } - function tryGetConstEnumValue(node: Node): number { - if (compilerOptions.isolatedModules) { - return undefined; - } - - return isPropertyAccessExpression(node) || isElementAccessExpression(node) - ? resolver.getConstantValue(node) - : undefined; - } - function substituteCallExpression(node: CallExpression): Expression { const expression = node.expression; if (isSuperProperty(expression)) { From b871b5353c8a9ca6dedd6bc84706fd75ed86bae4 Mon Sep 17 00:00:00 2001 From: Andrej Baran Date: Thu, 13 Oct 2016 13:32:00 +0200 Subject: [PATCH 33/80] Favor use of ES2015 instead of ES6 --- Jakefile.js | 8 +-- src/compiler/binder.ts | 62 +++++++++---------- src/compiler/checker.ts | 42 ++++++------- src/compiler/core.ts | 2 +- src/compiler/emitter.ts | 4 +- src/compiler/factory.ts | 2 +- src/compiler/program.ts | 4 +- src/compiler/transformer.ts | 10 +-- .../transformers/{es6.ts => es2015.ts} | 26 ++++---- src/compiler/transformers/es2017.ts | 4 +- .../transformers/module/{es6.ts => es2015.ts} | 4 +- src/compiler/transformers/module/module.ts | 2 +- src/compiler/transformers/ts.ts | 6 +- src/compiler/tsconfig.json | 4 +- src/compiler/types.ts | 10 +-- src/compiler/utilities.ts | 6 +- src/harness/harness.ts | 2 +- src/harness/tsconfig.json | 4 +- src/harness/unittests/moduleResolution.ts | 2 +- src/services/tsconfig.json | 4 +- src/services/utilities.ts | 2 +- 21 files changed, 105 insertions(+), 105 deletions(-) rename src/compiler/transformers/{es6.ts => es2015.ts} (97%) rename src/compiler/transformers/module/{es6.ts => es2015.ts} (96%) diff --git a/Jakefile.js b/Jakefile.js index 8d46368653..6f86ef35b0 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -70,14 +70,14 @@ var compilerSources = [ "visitor.ts", "transformers/destructuring.ts", "transformers/ts.ts", - "transformers/module/es6.ts", + "transformers/module/es2015.ts", "transformers/module/system.ts", "transformers/module/module.ts", "transformers/jsx.ts", "transformers/es2017.ts", "transformers/es2016.ts", + "transformers/es2015.ts", "transformers/generators.ts", - "transformers/es6.ts", "transformer.ts", "sourcemap.ts", "comments.ts", @@ -105,14 +105,14 @@ var servicesSources = [ "visitor.ts", "transformers/destructuring.ts", "transformers/ts.ts", - "transformers/module/es6.ts", + "transformers/module/es2015.ts", "transformers/module/system.ts", "transformers/module/module.ts", "transformers/jsx.ts", "transformers/es2017.ts", "transformers/es2016.ts", + "transformers/es2015.ts", "transformers/generators.ts", - "transformers/es6.ts", "transformer.ts", "sourcemap.ts", "comments.ts", diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 3f5db2ae7c..970e481faa 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1636,7 +1636,7 @@ namespace ts { } function checkStrictModeFunctionDeclaration(node: FunctionDeclaration) { - if (languageVersion < ScriptTarget.ES6) { + if (languageVersion < ScriptTarget.ES2015) { // Report error if function is not top level function declaration if (blockScopeContainer.kind !== SyntaxKind.SourceFile && blockScopeContainer.kind !== SyntaxKind.ModuleDeclaration && @@ -2376,7 +2376,7 @@ namespace ts { || isSuperOrSuperProperty(expression, expressionKind)) { // If the this node contains a SpreadElementExpression, or is a super call, then it is an ES6 // node. - transformFlags |= TransformFlags.AssertES6; + transformFlags |= TransformFlags.AssertES2015; } node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; @@ -2407,7 +2407,7 @@ namespace ts { && (leftKind === SyntaxKind.ObjectLiteralExpression || leftKind === SyntaxKind.ArrayLiteralExpression)) { // Destructuring assignments are ES6 syntax. - transformFlags |= TransformFlags.AssertES6 | TransformFlags.DestructuringAssignment; + transformFlags |= TransformFlags.AssertES2015 | TransformFlags.DestructuringAssignment; } else if (operatorTokenKind === SyntaxKind.AsteriskAsteriskToken || operatorTokenKind === SyntaxKind.AsteriskAsteriskEqualsToken) { @@ -2445,7 +2445,7 @@ namespace ts { // If a parameter has an initializer, a binding pattern or a dotDotDot token, then // it is ES6 syntax and its container must emit default value assignments or parameter destructuring downlevel. if (subtreeFlags & TransformFlags.ContainsBindingPattern || initializer || dotDotDotToken) { - transformFlags |= TransformFlags.AssertES6 | TransformFlags.ContainsDefaultValueAssignments; + transformFlags |= TransformFlags.AssertES2015 | TransformFlags.ContainsDefaultValueAssignments; } node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; @@ -2486,7 +2486,7 @@ namespace ts { } else { // A ClassDeclaration is ES6 syntax. - transformFlags = subtreeFlags | TransformFlags.AssertES6; + transformFlags = subtreeFlags | TransformFlags.AssertES2015; // A class with a parameter property assignment, property initializer, or decorator is // TypeScript syntax. @@ -2509,7 +2509,7 @@ namespace ts { function computeClassExpression(node: ClassExpression, subtreeFlags: TransformFlags) { // A ClassExpression is ES6 syntax. - let transformFlags = subtreeFlags | TransformFlags.AssertES6; + let transformFlags = subtreeFlags | TransformFlags.AssertES2015; // A class with a parameter property assignment, property initializer, or decorator is // TypeScript syntax. @@ -2533,7 +2533,7 @@ namespace ts { switch (node.token) { case SyntaxKind.ExtendsKeyword: // An `extends` HeritageClause is ES6 syntax. - transformFlags |= TransformFlags.AssertES6; + transformFlags |= TransformFlags.AssertES2015; break; case SyntaxKind.ImplementsKeyword: @@ -2553,7 +2553,7 @@ namespace ts { function computeExpressionWithTypeArguments(node: ExpressionWithTypeArguments, subtreeFlags: TransformFlags) { // An ExpressionWithTypeArguments is ES6 syntax, as it is used in the // extends clause of a class. - let transformFlags = subtreeFlags | TransformFlags.AssertES6; + let transformFlags = subtreeFlags | TransformFlags.AssertES2015; // If an ExpressionWithTypeArguments contains type arguments, then it // is TypeScript syntax. @@ -2580,7 +2580,7 @@ namespace ts { function computeMethod(node: MethodDeclaration, subtreeFlags: TransformFlags) { // A MethodDeclaration is ES6 syntax. - let transformFlags = subtreeFlags | TransformFlags.AssertES6; + let transformFlags = subtreeFlags | TransformFlags.AssertES2015; const modifierFlags = getModifierFlags(node); const body = node.body; const typeParameters = node.typeParameters; @@ -2656,7 +2656,7 @@ namespace ts { // If a FunctionDeclaration is exported, then it is either ES6 or TypeScript syntax. if (modifierFlags & ModifierFlags.Export) { - transformFlags |= TransformFlags.AssertTypeScript | TransformFlags.AssertES6; + transformFlags |= TransformFlags.AssertTypeScript | TransformFlags.AssertES2015; } // An async function declaration is ES2017 syntax. @@ -2667,8 +2667,8 @@ namespace ts { // If a FunctionDeclaration's subtree has marked the container as needing to capture the // lexical this, or the function contains parameters with initializers, then this node is // ES6 syntax. - if (subtreeFlags & TransformFlags.ES6FunctionSyntaxMask) { - transformFlags |= TransformFlags.AssertES6; + if (subtreeFlags & TransformFlags.ES2015FunctionSyntaxMask) { + transformFlags |= TransformFlags.AssertES2015; } // If a FunctionDeclaration is generator function and is the body of a @@ -2698,8 +2698,8 @@ namespace ts { // If a FunctionExpression's subtree has marked the container as needing to capture the // lexical this, or the function contains parameters with initializers, then this node is // ES6 syntax. - if (subtreeFlags & TransformFlags.ES6FunctionSyntaxMask) { - transformFlags |= TransformFlags.AssertES6; + if (subtreeFlags & TransformFlags.ES2015FunctionSyntaxMask) { + transformFlags |= TransformFlags.AssertES2015; } // If a FunctionExpression is generator function and is the body of a @@ -2717,7 +2717,7 @@ namespace ts { function computeArrowFunction(node: ArrowFunction, subtreeFlags: TransformFlags) { // An ArrowFunction is ES6 syntax, and excludes markers that should not escape the scope of an ArrowFunction. - let transformFlags = subtreeFlags | TransformFlags.AssertES6; + let transformFlags = subtreeFlags | TransformFlags.AssertES2015; const modifierFlags = getModifierFlags(node); // An async arrow function is ES2017 syntax. @@ -2755,7 +2755,7 @@ namespace ts { // A VariableDeclaration with a binding pattern is ES6 syntax. if (nameKind === SyntaxKind.ObjectBindingPattern || nameKind === SyntaxKind.ArrayBindingPattern) { - transformFlags |= TransformFlags.AssertES6 | TransformFlags.ContainsBindingPattern; + transformFlags |= TransformFlags.AssertES2015 | TransformFlags.ContainsBindingPattern; } node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; @@ -2776,11 +2776,11 @@ namespace ts { // If a VariableStatement is exported, then it is either ES6 or TypeScript syntax. if (modifierFlags & ModifierFlags.Export) { - transformFlags |= TransformFlags.AssertES6 | TransformFlags.AssertTypeScript; + transformFlags |= TransformFlags.AssertES2015 | TransformFlags.AssertTypeScript; } if (declarationListTransformFlags & TransformFlags.ContainsBindingPattern) { - transformFlags |= TransformFlags.AssertES6; + transformFlags |= TransformFlags.AssertES2015; } } @@ -2794,7 +2794,7 @@ namespace ts { // A labeled statement containing a block scoped binding *may* need to be transformed from ES6. if (subtreeFlags & TransformFlags.ContainsBlockScopedBinding && isIterationStatement(node, /*lookInLabeledStatements*/ true)) { - transformFlags |= TransformFlags.AssertES6; + transformFlags |= TransformFlags.AssertES2015; } node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; @@ -2820,7 +2820,7 @@ namespace ts { // then we treat the statement as ES6 so that we can indicate that we do not // need to hold on to the right-hand side. if (node.expression.transformFlags & TransformFlags.DestructuringAssignment) { - transformFlags |= TransformFlags.AssertES6; + transformFlags |= TransformFlags.AssertES2015; } node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; @@ -2843,12 +2843,12 @@ namespace ts { let transformFlags = subtreeFlags | TransformFlags.ContainsHoistedDeclarationOrCompletion; if (subtreeFlags & TransformFlags.ContainsBindingPattern) { - transformFlags |= TransformFlags.AssertES6; + transformFlags |= TransformFlags.AssertES2015; } // If a VariableDeclarationList is `let` or `const`, then it is ES6 syntax. if (node.flags & NodeFlags.BlockScoped) { - transformFlags |= TransformFlags.AssertES6 | TransformFlags.ContainsBlockScopedBinding; + transformFlags |= TransformFlags.AssertES2015 | TransformFlags.ContainsBlockScopedBinding; } node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; @@ -2897,7 +2897,7 @@ namespace ts { case SyntaxKind.ExportKeyword: // This node is both ES6 and TypeScript syntax. - transformFlags |= TransformFlags.AssertES6 | TransformFlags.AssertTypeScript; + transformFlags |= TransformFlags.AssertES2015 | TransformFlags.AssertTypeScript; break; case SyntaxKind.DefaultKeyword: @@ -2910,12 +2910,12 @@ namespace ts { case SyntaxKind.ShorthandPropertyAssignment: case SyntaxKind.ForOfStatement: // These nodes are ES6 syntax. - transformFlags |= TransformFlags.AssertES6; + transformFlags |= TransformFlags.AssertES2015; break; case SyntaxKind.YieldExpression: // This node is ES6 syntax. - transformFlags |= TransformFlags.AssertES6 | TransformFlags.ContainsYield; + transformFlags |= TransformFlags.AssertES2015 | TransformFlags.ContainsYield; break; case SyntaxKind.AnyKeyword: @@ -2976,7 +2976,7 @@ namespace ts { case SyntaxKind.SuperKeyword: // This node is ES6 syntax. - transformFlags |= TransformFlags.AssertES6; + transformFlags |= TransformFlags.AssertES2015; break; case SyntaxKind.ThisKeyword: @@ -2987,7 +2987,7 @@ namespace ts { case SyntaxKind.ObjectBindingPattern: case SyntaxKind.ArrayBindingPattern: // These nodes are ES6 syntax. - transformFlags |= TransformFlags.AssertES6 | TransformFlags.ContainsBindingPattern; + transformFlags |= TransformFlags.AssertES2015 | TransformFlags.ContainsBindingPattern; break; case SyntaxKind.Decorator: @@ -3000,7 +3000,7 @@ namespace ts { if (subtreeFlags & TransformFlags.ContainsComputedPropertyName) { // If an ObjectLiteralExpression contains a ComputedPropertyName, then it // is an ES6 node. - transformFlags |= TransformFlags.AssertES6; + transformFlags |= TransformFlags.AssertES2015; } if (subtreeFlags & TransformFlags.ContainsLexicalThisInComputedPropertyName) { @@ -3017,7 +3017,7 @@ namespace ts { if (subtreeFlags & TransformFlags.ContainsSpreadElementExpression) { // If the this node contains a SpreadElementExpression, then it is an ES6 // node. - transformFlags |= TransformFlags.AssertES6; + transformFlags |= TransformFlags.AssertES2015; } break; @@ -3028,14 +3028,14 @@ namespace ts { case SyntaxKind.ForInStatement: // A loop containing a block scoped binding *may* need to be transformed from ES6. if (subtreeFlags & TransformFlags.ContainsBlockScopedBinding) { - transformFlags |= TransformFlags.AssertES6; + transformFlags |= TransformFlags.AssertES2015; } break; case SyntaxKind.SourceFile: if (subtreeFlags & TransformFlags.ContainsCapturedLexicalThis) { - transformFlags |= TransformFlags.AssertES6; + transformFlags |= TransformFlags.AssertES2015; } break; diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0b5c396307..cecf2964f3 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3189,7 +3189,7 @@ namespace ts { const elements = pattern.elements; const lastElement = lastOrUndefined(elements); if (elements.length === 0 || (!isOmittedExpression(lastElement) && lastElement.dotDotDotToken)) { - return languageVersion >= ScriptTarget.ES6 ? createIterableType(anyType) : anyArrayType; + return languageVersion >= ScriptTarget.ES2015 ? createIterableType(anyType) : anyArrayType; } // If the pattern has at least one element, and no rest element, then it should imply a tuple type. const elementTypes = map(elements, e => isOmittedExpression(e) ? anyType : getTypeFromBindingElement(e, includePatternInType, reportErrors)); @@ -9059,7 +9059,7 @@ namespace ts { // can explicitly bound arguments objects if (symbol === argumentsSymbol) { const container = getContainingFunction(node); - if (languageVersion < ScriptTarget.ES6) { + if (languageVersion < ScriptTarget.ES2015) { if (container.kind === SyntaxKind.ArrowFunction) { error(node, Diagnostics.The_arguments_object_cannot_be_referenced_in_an_arrow_function_in_ES3_and_ES5_Consider_using_a_standard_function_expression); } @@ -9084,7 +9084,7 @@ namespace ts { // Due to the emit for class decorators, any reference to the class from inside of the class body // must instead be rewritten to point to a temporary variable to avoid issues with the double-bind // behavior of class names in ES6. - if (languageVersion === ScriptTarget.ES6 + if (languageVersion === ScriptTarget.ES2015 && declaration.kind === SyntaxKind.ClassDeclaration && nodeIsDecorated(declaration)) { let container = getContainingClass(node); @@ -9173,7 +9173,7 @@ namespace ts { } function checkNestedBlockScopedBinding(node: Identifier, symbol: Symbol): void { - if (languageVersion >= ScriptTarget.ES6 || + if (languageVersion >= ScriptTarget.ES2015 || (symbol.flags & (SymbolFlags.BlockScopedVariable | SymbolFlags.Class)) === 0 || symbol.valueDeclaration.parent.kind === SyntaxKind.CatchClause) { return; @@ -9339,7 +9339,7 @@ namespace ts { container = getThisContainer(container, /* includeArrowFunctions */ false); // When targeting es6, arrow function lexically bind "this" so we do not need to do the work of binding "this" in emitted code - needToCaptureLexicalThis = (languageVersion < ScriptTarget.ES6); + needToCaptureLexicalThis = (languageVersion < ScriptTarget.ES2015); } switch (container.kind) { @@ -9447,7 +9447,7 @@ namespace ts { if (!isCallExpression) { while (container && container.kind === SyntaxKind.ArrowFunction) { container = getSuperContainer(container, /*stopOnFunctions*/ true); - needToCaptureLexicalThis = languageVersion < ScriptTarget.ES6; + needToCaptureLexicalThis = languageVersion < ScriptTarget.ES2015; } } @@ -9561,7 +9561,7 @@ namespace ts { } if (container.parent.kind === SyntaxKind.ObjectLiteralExpression) { - if (languageVersion < ScriptTarget.ES6) { + if (languageVersion < ScriptTarget.ES2015) { error(node, Diagnostics.super_is_only_allowed_in_members_of_object_literal_expressions_when_option_target_is_ES2015_or_higher); return unknownType; } @@ -9929,7 +9929,7 @@ namespace ts { const index = indexOf(arrayLiteral.elements, node); return getTypeOfPropertyOfContextualType(type, "" + index) || getIndexTypeOfContextualType(type, IndexKind.Number) - || (languageVersion >= ScriptTarget.ES6 ? getElementTypeOfIterable(type, /*errorNode*/ undefined) : undefined); + || (languageVersion >= ScriptTarget.ES2015 ? getElementTypeOfIterable(type, /*errorNode*/ undefined) : undefined); } return undefined; } @@ -10162,7 +10162,7 @@ namespace ts { // if there is no index type / iterated type. const restArrayType = checkExpression((e).expression, contextualMapper); const restElementType = getIndexTypeOfType(restArrayType, IndexKind.Number) || - (languageVersion >= ScriptTarget.ES6 ? getElementTypeOfIterable(restArrayType, /*errorNode*/ undefined) : undefined); + (languageVersion >= ScriptTarget.ES2015 ? getElementTypeOfIterable(restArrayType, /*errorNode*/ undefined) : undefined); if (restElementType) { elementTypes.push(restElementType); } @@ -10909,7 +10909,7 @@ namespace ts { // - In a static member function or static member accessor // where this references the constructor function object of a derived class, // a super property access is permitted and must specify a public static member function of the base class. - if (languageVersion < ScriptTarget.ES6 && getDeclarationKindFromSymbol(prop) !== SyntaxKind.MethodDeclaration) { + if (languageVersion < ScriptTarget.ES2015 && getDeclarationKindFromSymbol(prop) !== SyntaxKind.MethodDeclaration) { // `prop` refers to a *property* declared in the super class // rather than a *method*, so it does not satisfy the above criteria. @@ -14228,7 +14228,7 @@ namespace ts { } if (node.type) { - if (languageVersion >= ScriptTarget.ES6 && isSyntacticallyValidGenerator(node)) { + if (languageVersion >= ScriptTarget.ES2015 && isSyntacticallyValidGenerator(node)) { const returnType = getTypeFromTypeNode(node.type); if (returnType === voidType) { error(node.type, Diagnostics.A_generator_cannot_have_a_void_type_annotation); @@ -15189,7 +15189,7 @@ namespace ts { * callable `then` signature. */ function checkAsyncFunctionReturnType(node: FunctionLikeDeclaration): Type { - if (languageVersion >= ScriptTarget.ES6) { + if (languageVersion >= ScriptTarget.ES2015) { const returnType = getTypeFromTypeNode(node.type); return checkCorrectPromiseType(returnType, node.type, Diagnostics.The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type); } @@ -15722,7 +15722,7 @@ namespace ts { function checkCollisionWithRequireExportsInGeneratedCode(node: Node, name: Identifier) { // No need to check for require or exports for ES6 modules and later - if (modulekind >= ModuleKind.ES6) { + if (modulekind >= ModuleKind.ES2015) { return; } @@ -16214,7 +16214,7 @@ namespace ts { if (isTypeAny(inputType)) { return inputType; } - if (languageVersion >= ScriptTarget.ES6) { + if (languageVersion >= ScriptTarget.ES2015) { return checkElementTypeOfIterable(inputType, errorNode); } if (allowStringInput) { @@ -16392,7 +16392,7 @@ namespace ts { * 2. Some constituent is a string and target is less than ES5 (because in ES3 string is not indexable). */ function checkElementTypeOfArrayOrString(arrayOrStringType: Type, errorNode: Node): Type { - Debug.assert(languageVersion < ScriptTarget.ES6); + Debug.assert(languageVersion < ScriptTarget.ES2015); // After we remove all types that are StringLike, we will know if there was a string constituent // based on whether the remaining type is the same as the initial type. @@ -17700,7 +17700,7 @@ namespace ts { } } else { - if (modulekind === ModuleKind.ES6 && !isInAmbientContext(node)) { + if (modulekind === ModuleKind.ES2015 && !isInAmbientContext(node)) { // Import equals declaration is deprecated in es6 or above grammarErrorOnNode(node, Diagnostics.Import_assignment_cannot_be_used_when_targeting_ECMAScript_2015_modules_Consider_using_import_Asterisk_as_ns_from_mod_import_a_from_mod_import_d_from_mod_or_another_module_format_instead); } @@ -17788,7 +17788,7 @@ namespace ts { checkExternalModuleExports(container); if (node.isExportEquals && !isInAmbientContext(node)) { - if (modulekind === ModuleKind.ES6) { + if (modulekind === ModuleKind.ES2015) { // export assignment is not supported in es6 modules grammarErrorOnNode(node, Diagnostics.Export_assignment_cannot_be_used_when_targeting_ECMAScript_2015_modules_Consider_using_export_default_or_another_module_format_instead); } @@ -19296,7 +19296,7 @@ namespace ts { getGlobalTemplateStringsArrayType = memoize(() => getGlobalType("TemplateStringsArray")); - if (languageVersion >= ScriptTarget.ES6) { + if (languageVersion >= ScriptTarget.ES2015) { getGlobalESSymbolType = memoize(() => getGlobalType("Symbol")); getGlobalIterableType = memoize(() => getGlobalType("Iterable", /*arity*/ 1)); getGlobalIteratorType = memoize(() => getGlobalType("Iterator", /*arity*/ 1)); @@ -19329,7 +19329,7 @@ namespace ts { // If we found the module, report errors if it does not have the necessary exports. if (helpersModule) { const exports = helpersModule.exports; - if (requestedExternalEmitHelpers & NodeFlags.HasClassExtends && languageVersion < ScriptTarget.ES6) { + if (requestedExternalEmitHelpers & NodeFlags.HasClassExtends && languageVersion < ScriptTarget.ES2015) { verifyHelperSymbol(exports, "__extends", SymbolFlags.Value); } if (requestedExternalEmitHelpers & NodeFlags.HasJsxSpreadAttributes && compilerOptions.jsx !== JsxEmit.Preserve) { @@ -19346,7 +19346,7 @@ namespace ts { } if (requestedExternalEmitHelpers & NodeFlags.HasAsyncFunctions) { verifyHelperSymbol(exports, "__awaiter", SymbolFlags.Value); - if (languageVersion < ScriptTarget.ES6) { + if (languageVersion < ScriptTarget.ES2015) { verifyHelperSymbol(exports, "__generator", SymbolFlags.Value); } } @@ -19923,7 +19923,7 @@ namespace ts { if (!node.body) { return grammarErrorOnNode(node.asteriskToken, Diagnostics.An_overload_signature_cannot_be_declared_as_a_generator); } - if (languageVersion < ScriptTarget.ES6) { + if (languageVersion < ScriptTarget.ES2015) { return grammarErrorOnNode(node.asteriskToken, Diagnostics.Generators_are_only_available_when_targeting_ECMAScript_2015_or_higher); } } diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 3f2cc619cb..3f60ec62c2 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1191,7 +1191,7 @@ namespace ts { export function getEmitModuleKind(compilerOptions: CompilerOptions) { return typeof compilerOptions.module === "number" ? compilerOptions.module : - getEmitScriptTarget(compilerOptions) >= ScriptTarget.ES6 ? ModuleKind.ES6 : ModuleKind.CommonJS; + getEmitScriptTarget(compilerOptions) >= ScriptTarget.ES2015 ? ModuleKind.ES2015 : ModuleKind.CommonJS; } /* @internal */ diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index a3f69e2fd4..734fe2778e 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -2165,7 +2165,7 @@ const _super = (function (geti, seti) { // Only Emit __extends function when target ES5. // For target ES6 and above, we can emit classDeclaration as is. - if ((languageVersion < ScriptTarget.ES6) && (!extendsEmitted && node.flags & NodeFlags.HasClassExtends)) { + if ((languageVersion < ScriptTarget.ES2015) && (!extendsEmitted && node.flags & NodeFlags.HasClassExtends)) { writeLines(extendsHelper); extendsEmitted = true; helpersEmitted = true; @@ -2197,7 +2197,7 @@ const _super = (function (geti, seti) { // For target ES2017 and above, we can emit async/await as is. if ((languageVersion < ScriptTarget.ES2017) && (!awaiterEmitted && node.flags & NodeFlags.HasAsyncFunctions)) { writeLines(awaiterHelper); - if (languageVersion < ScriptTarget.ES6) { + if (languageVersion < ScriptTarget.ES2015) { writeLines(generatorHelper); } diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 519269ccfd..57007619c6 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -1985,7 +1985,7 @@ namespace ts { } else if (callee.kind === SyntaxKind.SuperKeyword) { thisArg = createThis(); - target = languageVersion < ScriptTarget.ES6 ? createIdentifier("_super", /*location*/ callee) : callee; + target = languageVersion < ScriptTarget.ES2015 ? createIdentifier("_super", /*location*/ callee) : callee; } else { switch (callee.kind) { diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 5d46038b2b..dfe65fc086 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1478,7 +1478,7 @@ namespace ts { const firstNonAmbientExternalModuleSourceFile = forEach(files, f => isExternalModule(f) && !isDeclarationFile(f) ? f : undefined); if (options.isolatedModules) { - if (options.module === ModuleKind.None && languageVersion < ScriptTarget.ES6) { + if (options.module === ModuleKind.None && languageVersion < ScriptTarget.ES2015) { programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES2015_or_higher)); } @@ -1488,7 +1488,7 @@ namespace ts { programDiagnostics.add(createFileDiagnostic(firstNonExternalModuleSourceFile, span.start, span.length, Diagnostics.Cannot_compile_namespaces_when_the_isolatedModules_flag_is_provided)); } } - else if (firstNonAmbientExternalModuleSourceFile && languageVersion < ScriptTarget.ES6 && options.module === ModuleKind.None) { + else if (firstNonAmbientExternalModuleSourceFile && languageVersion < ScriptTarget.ES2015 && options.module === ModuleKind.None) { // We cannot use createDiagnosticFromNode because nodes do not have parents yet const span = getErrorSpanForNode(firstNonAmbientExternalModuleSourceFile, firstNonAmbientExternalModuleSourceFile.externalModuleIndicator); programDiagnostics.add(createFileDiagnostic(firstNonAmbientExternalModuleSourceFile, span.start, span.length, Diagnostics.Cannot_use_imports_exports_or_module_augmentations_when_module_is_none)); diff --git a/src/compiler/transformer.ts b/src/compiler/transformer.ts index 55b83ea669..fc656e08bf 100644 --- a/src/compiler/transformer.ts +++ b/src/compiler/transformer.ts @@ -3,16 +3,16 @@ /// /// /// -/// +/// /// /// /// -/// +/// /* @internal */ namespace ts { const moduleTransformerMap = createMap({ - [ModuleKind.ES6]: transformES6Module, + [ModuleKind.ES2015]: transformES2015Module, [ModuleKind.System]: transformSystemModule, [ModuleKind.AMD]: transformModule, [ModuleKind.CommonJS]: transformModule, @@ -124,8 +124,8 @@ namespace ts { transformers.push(transformES2016); } - if (languageVersion < ScriptTarget.ES6) { - transformers.push(transformES6); + if (languageVersion < ScriptTarget.ES2015) { + transformers.push(transformES2015); transformers.push(transformGenerators); } diff --git a/src/compiler/transformers/es6.ts b/src/compiler/transformers/es2015.ts similarity index 97% rename from src/compiler/transformers/es6.ts rename to src/compiler/transformers/es2015.ts index ba5f8a3fb7..101c34a819 100644 --- a/src/compiler/transformers/es6.ts +++ b/src/compiler/transformers/es2015.ts @@ -4,7 +4,7 @@ /*@internal*/ namespace ts { - const enum ES6SubstitutionFlags { + const enum ES2015SubstitutionFlags { /** Enables substitutions for captured `this` */ CapturedThis = 1 << 0, /** Enables substitutions for block-scoped bindings. */ @@ -163,7 +163,7 @@ namespace ts { ReplaceWithReturn, } - export function transformES6(context: TransformationContext) { + export function transformES2015(context: TransformationContext) { const { startLexicalEnvironment, endLexicalEnvironment, @@ -197,7 +197,7 @@ namespace ts { * They are persisted between each SourceFile transformation and should not * be reset. */ - let enabledSubstitutions: ES6SubstitutionFlags; + let enabledSubstitutions: ES2015SubstitutionFlags; return transformSourceFile; @@ -252,7 +252,7 @@ namespace ts { } function shouldCheckNode(node: Node): boolean { - return (node.transformFlags & TransformFlags.ES6) !== 0 || + return (node.transformFlags & TransformFlags.ES2015) !== 0 || node.kind === SyntaxKind.LabeledStatement || (isIterationStatement(node, /*lookInLabeledStatements*/ false) && shouldConvertIterationStatementBody(node)); } @@ -261,7 +261,7 @@ namespace ts { if (shouldCheckNode(node)) { return visitJavaScript(node); } - else if (node.transformFlags & TransformFlags.ContainsES6) { + else if (node.transformFlags & TransformFlags.ContainsES2015) { return visitEachChild(node, visitor, context); } else { @@ -3037,7 +3037,7 @@ namespace ts { function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) { const savedEnclosingFunction = enclosingFunction; - if (enabledSubstitutions & ES6SubstitutionFlags.CapturedThis && isFunctionLike(node)) { + if (enabledSubstitutions & ES2015SubstitutionFlags.CapturedThis && isFunctionLike(node)) { // If we are tracking a captured `this`, keep track of the enclosing function. enclosingFunction = node; } @@ -3052,8 +3052,8 @@ namespace ts { * contains block-scoped bindings (e.g. `let` or `const`). */ function enableSubstitutionsForBlockScopedBindings() { - if ((enabledSubstitutions & ES6SubstitutionFlags.BlockScopedBindings) === 0) { - enabledSubstitutions |= ES6SubstitutionFlags.BlockScopedBindings; + if ((enabledSubstitutions & ES2015SubstitutionFlags.BlockScopedBindings) === 0) { + enabledSubstitutions |= ES2015SubstitutionFlags.BlockScopedBindings; context.enableSubstitution(SyntaxKind.Identifier); } } @@ -3063,8 +3063,8 @@ namespace ts { * contains a captured `this`. */ function enableSubstitutionsForCapturedThis() { - if ((enabledSubstitutions & ES6SubstitutionFlags.CapturedThis) === 0) { - enabledSubstitutions |= ES6SubstitutionFlags.CapturedThis; + if ((enabledSubstitutions & ES2015SubstitutionFlags.CapturedThis) === 0) { + enabledSubstitutions |= ES2015SubstitutionFlags.CapturedThis; context.enableSubstitution(SyntaxKind.ThisKeyword); context.enableEmitNotification(SyntaxKind.Constructor); context.enableEmitNotification(SyntaxKind.MethodDeclaration); @@ -3103,7 +3103,7 @@ namespace ts { function substituteIdentifier(node: Identifier) { // Only substitute the identifier if we have enabled substitutions for block-scoped // bindings. - if (enabledSubstitutions & ES6SubstitutionFlags.BlockScopedBindings) { + if (enabledSubstitutions & ES2015SubstitutionFlags.BlockScopedBindings) { const original = getParseTreeNode(node, isIdentifier); if (original && isNameOfDeclarationWithCollidingName(original)) { return getGeneratedNameForNode(original); @@ -3156,7 +3156,7 @@ namespace ts { * @param node An Identifier node. */ function substituteExpressionIdentifier(node: Identifier): Identifier { - if (enabledSubstitutions & ES6SubstitutionFlags.BlockScopedBindings) { + if (enabledSubstitutions & ES2015SubstitutionFlags.BlockScopedBindings) { const declaration = resolver.getReferencedDeclarationWithCollidingName(node); if (declaration) { return getGeneratedNameForNode(declaration.name); @@ -3172,7 +3172,7 @@ namespace ts { * @param node The ThisKeyword node. */ function substituteThisKeyword(node: PrimaryExpression): PrimaryExpression { - if (enabledSubstitutions & ES6SubstitutionFlags.CapturedThis + if (enabledSubstitutions & ES2015SubstitutionFlags.CapturedThis && enclosingFunction && getEmitFlags(enclosingFunction) & EmitFlags.CapturesThis) { return createIdentifier("_this", /*location*/ node); diff --git a/src/compiler/transformers/es2017.ts b/src/compiler/transformers/es2017.ts index f9e8b539c6..7800a41e14 100644 --- a/src/compiler/transformers/es2017.ts +++ b/src/compiler/transformers/es2017.ts @@ -263,7 +263,7 @@ namespace ts { function transformAsyncFunctionBody(node: FunctionLikeDeclaration): ConciseBody | FunctionBody { const nodeType = node.original ? (node.original).type : node.type; - const promiseConstructor = languageVersion < ScriptTarget.ES6 ? getPromiseConstructor(nodeType) : undefined; + const promiseConstructor = languageVersion < ScriptTarget.ES2015 ? getPromiseConstructor(nodeType) : undefined; const isArrowFunction = node.kind === SyntaxKind.ArrowFunction; const hasLexicalArguments = (resolver.getNodeCheckFlags(node) & NodeCheckFlags.CaptureArguments) !== 0; @@ -292,7 +292,7 @@ namespace ts { // Minor optimization, emit `_super` helper to capture `super` access in an arrow. // This step isn't needed if we eventually transform this to ES5. - if (languageVersion >= ScriptTarget.ES6) { + if (languageVersion >= ScriptTarget.ES2015) { if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.AsyncMethodWithSuperBinding) { enableSubstitutionForAsyncMethodsWithSuper(); setEmitFlags(block, EmitFlags.EmitAdvancedSuperHelper); diff --git a/src/compiler/transformers/module/es6.ts b/src/compiler/transformers/module/es2015.ts similarity index 96% rename from src/compiler/transformers/module/es6.ts rename to src/compiler/transformers/module/es2015.ts index 09a2890727..b06acd2d09 100644 --- a/src/compiler/transformers/module/es6.ts +++ b/src/compiler/transformers/module/es2015.ts @@ -3,7 +3,7 @@ /*@internal*/ namespace ts { - export function transformES6Module(context: TransformationContext) { + export function transformES2015Module(context: TransformationContext) { const compilerOptions = context.getCompilerOptions(); const resolver = context.getEmitResolver(); @@ -141,4 +141,4 @@ namespace ts { return resolver.isReferencedAliasDeclaration(node) ? node : undefined; } } -} \ No newline at end of file +} diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index 9051f375bf..989efbfd53 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -416,7 +416,7 @@ namespace ts { ) ], /*location*/ undefined, - /*flags*/ languageVersion >= ScriptTarget.ES6 ? NodeFlags.Const : NodeFlags.None), + /*flags*/ languageVersion >= ScriptTarget.ES2015 ? NodeFlags.Const : NodeFlags.None), /*location*/ node ) ); diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 77ab6a6ca0..868c371e00 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -1777,7 +1777,7 @@ namespace ts { return createIdentifier("Number"); case SyntaxKind.SymbolKeyword: - return languageVersion < ScriptTarget.ES6 + return languageVersion < ScriptTarget.ES2015 ? getGlobalSymbolNameWithFallback() : createIdentifier("Symbol"); @@ -1843,7 +1843,7 @@ namespace ts { return createIdentifier("Array"); case TypeReferenceSerializationKind.ESSymbolType: - return languageVersion < ScriptTarget.ES6 + return languageVersion < ScriptTarget.ES2015 ? getGlobalSymbolNameWithFallback() : createIdentifier("Symbol"); @@ -2592,7 +2592,7 @@ namespace ts { function isES6ExportedDeclaration(node: Node) { return isExternalModuleExport(node) - && moduleKind === ModuleKind.ES6; + && moduleKind === ModuleKind.ES2015; } /** diff --git a/src/compiler/tsconfig.json b/src/compiler/tsconfig.json index de710e74a4..da356c0b4d 100644 --- a/src/compiler/tsconfig.json +++ b/src/compiler/tsconfig.json @@ -26,12 +26,12 @@ "transformers/jsx.ts", "transformers/es2017.ts", "transformers/es2016.ts", - "transformers/es6.ts", + "transformers/es2015.ts", "transformers/generators.ts", "transformers/destructuring.ts", "transformers/module/module.ts", "transformers/module/system.ts", - "transformers/module/es6.ts", + "transformers/module/es2015.ts", "transformer.ts", "comments.ts", "sourcemap.ts", diff --git a/src/compiler/types.ts b/src/compiler/types.ts index b89887cafa..55200b2967 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3123,8 +3123,8 @@ namespace ts { ContainsES2017 = 1 << 5, ES2016 = 1 << 6, ContainsES2016 = 1 << 7, - ES6 = 1 << 8, - ContainsES6 = 1 << 9, + ES2015 = 1 << 8, + ContainsES2015 = 1 << 9, DestructuringAssignment = 1 << 10, Generator = 1 << 11, ContainsGenerator = 1 << 12, @@ -3153,13 +3153,13 @@ namespace ts { AssertJsx = Jsx | ContainsJsx, AssertES2017 = ES2017 | ContainsES2017, AssertES2016 = ES2016 | ContainsES2016, - AssertES6 = ES6 | ContainsES6, + AssertES2015 = ES2015 | ContainsES2015, AssertGenerator = Generator | ContainsGenerator, // Scope Exclusions // - Bitmasks that exclude flags from propagating out of a specific context // into the subtree flags of their container. - NodeExcludes = TypeScript | Jsx | ES2017 | ES2016 | ES6 | DestructuringAssignment | Generator | HasComputedFlags, + NodeExcludes = TypeScript | Jsx | ES2017 | ES2016 | ES2015 | DestructuringAssignment | Generator | HasComputedFlags, ArrowFunctionExcludes = NodeExcludes | ContainsDecorators | ContainsDefaultValueAssignments | ContainsLexicalThis | ContainsParameterPropertyAssignments | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion, FunctionExcludes = NodeExcludes | ContainsDecorators | ContainsDefaultValueAssignments | ContainsCapturedLexicalThis | ContainsLexicalThis | ContainsParameterPropertyAssignments | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion, ConstructorExcludes = NodeExcludes | ContainsDefaultValueAssignments | ContainsLexicalThis | ContainsCapturedLexicalThis | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion, @@ -3175,7 +3175,7 @@ namespace ts { // Masks // - Additional bitmasks TypeScriptClassSyntaxMask = ContainsParameterPropertyAssignments | ContainsPropertyInitializer | ContainsDecorators, - ES6FunctionSyntaxMask = ContainsCapturedLexicalThis | ContainsDefaultValueAssignments, + ES2015FunctionSyntaxMask = ContainsCapturedLexicalThis | ContainsDefaultValueAssignments, } /* @internal */ diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 92ce6ecc6a..e10ab6a8ad 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -337,7 +337,7 @@ namespace ts { export function getLiteralText(node: LiteralLikeNode, sourceFile: SourceFile, languageVersion: ScriptTarget) { // Any template literal or string literal with an extended escape // (e.g. "\u{0067}") will need to be downleveled as a escaped string literal. - if (languageVersion < ScriptTarget.ES6 && (isTemplateLiteralKind(node.kind) || node.hasExtendedUnicodeEscape)) { + if (languageVersion < ScriptTarget.ES2015 && (isTemplateLiteralKind(node.kind) || node.hasExtendedUnicodeEscape)) { return getQuotedEscapedLiteralText('"', node.text, '"'); } @@ -345,7 +345,7 @@ namespace ts { // the node's parent reference, then simply get the text as it was originally written. if (!nodeIsSynthesized(node) && node.parent) { const text = getSourceTextOfNodeFromSourceFile(sourceFile, node); - if (languageVersion < ScriptTarget.ES6 && isBinaryOrOctalIntegerLiteral(node, text)) { + if (languageVersion < ScriptTarget.ES2015 && isBinaryOrOctalIntegerLiteral(node, text)) { return node.text; } return text; @@ -4146,7 +4146,7 @@ namespace ts { return "lib.es2017.d.ts"; case ScriptTarget.ES2016: return "lib.es2016.d.ts"; - case ScriptTarget.ES6: + case ScriptTarget.ES2015: return "lib.es2015.d.ts"; default: diff --git a/src/harness/harness.ts b/src/harness/harness.ts index c50f33a74c..3b45d6d61e 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -946,7 +946,7 @@ namespace Harness { return "lib.es2017.d.ts"; case ts.ScriptTarget.ES2016: return "lib.es2016.d.ts"; - case ts.ScriptTarget.ES6: + case ts.ScriptTarget.ES2015: return es2015DefaultLibFileName; default: diff --git a/src/harness/tsconfig.json b/src/harness/tsconfig.json index c8b90645ce..5d7a81d1a7 100644 --- a/src/harness/tsconfig.json +++ b/src/harness/tsconfig.json @@ -28,12 +28,12 @@ "../compiler/transformers/jsx.ts", "../compiler/transformers/es2017.ts", "../compiler/transformers/es2016.ts", - "../compiler/transformers/es6.ts", + "../compiler/transformers/es2015.ts", "../compiler/transformers/generators.ts", "../compiler/transformers/destructuring.ts", "../compiler/transformers/module/module.ts", "../compiler/transformers/module/system.ts", - "../compiler/transformers/module/es6.ts", + "../compiler/transformers/module/es2015.ts", "../compiler/transformer.ts", "../compiler/comments.ts", "../compiler/sourcemap.ts", diff --git a/src/harness/unittests/moduleResolution.ts b/src/harness/unittests/moduleResolution.ts index 3e1ac17121..b2f7d0c224 100644 --- a/src/harness/unittests/moduleResolution.ts +++ b/src/harness/unittests/moduleResolution.ts @@ -1017,7 +1017,7 @@ import b = require("./moduleB"); const files = [f1, f2, f3, f4]; const names = map(files, f => f.name); - const sourceFiles = arrayToMap(map(files, f => createSourceFile(f.name, f.content, ScriptTarget.ES6)), f => f.fileName); + const sourceFiles = arrayToMap(map(files, f => createSourceFile(f.name, f.content, ScriptTarget.ES2015)), f => f.fileName); const compilerHost: CompilerHost = { fileExists : fileName => fileName in sourceFiles, getSourceFile: fileName => sourceFiles[fileName], diff --git a/src/services/tsconfig.json b/src/services/tsconfig.json index 45e3c9036e..c9428d9a08 100644 --- a/src/services/tsconfig.json +++ b/src/services/tsconfig.json @@ -27,12 +27,12 @@ "../compiler/transformers/jsx.ts", "../compiler/transformers/es2017.ts", "../compiler/transformers/es2016.ts", - "../compiler/transformers/es6.ts", + "../compiler/transformers/es2015.ts", "../compiler/transformers/generators.ts", "../compiler/transformers/destructuring.ts", "../compiler/transformers/module/module.ts", "../compiler/transformers/module/system.ts", - "../compiler/transformers/module/es6.ts", + "../compiler/transformers/module/es2015.ts", "../compiler/transformer.ts", "../compiler/comments.ts", "../compiler/sourcemap.ts", diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 829048fc08..e61906b4f0 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1339,7 +1339,7 @@ namespace ts { const options: TranspileOptions = { fileName: "config.js", compilerOptions: { - target: ScriptTarget.ES6, + target: ScriptTarget.ES2015, removeComments: true }, reportDiagnostics: true From 1dedca73d120e396fa710c782d2a3bf59252d732 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 13 Oct 2016 09:43:55 -0700 Subject: [PATCH 34/80] Support 'unshift' and fix typo --- src/compiler/binder.ts | 2 +- src/compiler/checker.ts | 18 ++++++++++-------- src/compiler/types.ts | 2 +- src/compiler/utilities.ts | 4 ++++ 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 6926403d9b..65d620f923 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1217,7 +1217,7 @@ namespace ts { } if (node.expression.kind === SyntaxKind.PropertyAccessExpression) { const propertyAccess = node.expression; - if (isNarrowableOperand(propertyAccess.expression) && propertyAccess.name.text === "push") { + if (isNarrowableOperand(propertyAccess.expression) && isPushOrUnshiftIdentifier(propertyAccess.name)) { currentFlow = createFlowArrayMutation(currentFlow, node); } } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9e2b7a3174..7bec343c91 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8405,8 +8405,10 @@ namespace ts { } function isEmptyArrayAssignment(node: VariableDeclaration | BindingElement | Expression) { - return node.kind === SyntaxKind.VariableDeclaration && (node).initializer && isEmptyArrayLiteral((node).initializer) || - node.kind !== SyntaxKind.BindingElement && node.parent.kind === SyntaxKind.BinaryExpression && isEmptyArrayLiteral((node.parent).right); + return node.kind === SyntaxKind.VariableDeclaration && (node).initializer && + isEmptyArrayLiteral((node).initializer) || + node.kind !== SyntaxKind.BindingElement && node.parent.kind === SyntaxKind.BinaryExpression && + isEmptyArrayLiteral((node.parent).right); } function getReferenceCandidate(node: Expression): Expression { @@ -8562,12 +8564,12 @@ namespace ts { getUnionType(sameMap(types, finalizeEvolvingArrayType), subtypeReduction); } - // Return true if the given node is 'x' in an 'x.push(value)' operation. - function isPushCallTarget(node: Node) { + // Return true if the given node is 'x' in an 'x.push(value)' or 'x.unshift(value)' operation. + function isPushOrUnshiftCallTarget(node: Node) { const parent = getReferenceRoot(node).parent; return parent.kind === SyntaxKind.PropertyAccessExpression && - (parent).name.text === "push" && - parent.parent.kind === SyntaxKind.CallExpression; + parent.parent.kind === SyntaxKind.CallExpression && + isPushOrUnshiftIdentifier((parent).name); } // Return true if the given node is 'x' in an 'x[n] = value' operation, where 'n' is an @@ -8596,9 +8598,9 @@ namespace ts { const evolvedType = getTypeFromFlowType(getTypeAtFlowNode(reference.flowNode)); visitedFlowCount = visitedFlowStart; // When the reference is 'x' in an 'x.push(value)' or 'x[n] = value' operation, we give type - // 'any[]' to 'x' instead of using the type determed by control flow analysis such that new + // 'any[]' to 'x' instead of using the type determined by control flow analysis such that new // element types are not considered errors. - const isEvolvingArrayInferenceTarget = isEvolvingArrayType(evolvedType) && (isPushCallTarget(reference) || isElementAssignmentTarget(reference)); + const isEvolvingArrayInferenceTarget = isEvolvingArrayType(evolvedType) && (isPushOrUnshiftCallTarget(reference) || isElementAssignmentTarget(reference)); const resultType = isEvolvingArrayInferenceTarget ? anyArrayType : finalizeEvolvingArrayType(evolvedType); if (reference.parent.kind === SyntaxKind.NonNullExpression && getTypeWithFacts(resultType, TypeFacts.NEUndefinedOrNull).flags & TypeFlags.Never) { return declaredType; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 5c32649d97..ff7618c8e3 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1953,7 +1953,7 @@ namespace ts { } // FlowArrayMutation represents a node potentially mutates an array, i.e. an - // operation of the form 'x.push(value)' or 'x[n] = value'. + // operation of the form 'x.push(value)', 'x.unshift(value)' or 'x[n] = value'. export interface FlowArrayMutation extends FlowNode { node: CallExpression | BinaryExpression; antecedent: FlowNode; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 558015bb0e..6e7dd8702f 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1895,6 +1895,10 @@ namespace ts { return node.kind === SyntaxKind.Identifier && (node).text === "Symbol"; } + export function isPushOrUnshiftIdentifier(node: Identifier) { + return node.text === "push" || node.text === "unshift"; + } + export function isModifierKind(token: SyntaxKind): boolean { switch (token) { case SyntaxKind.AbstractKeyword: From 620b3f91e11e00a65ad024127d8964988875922a Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 13 Oct 2016 09:44:37 -0700 Subject: [PATCH 35/80] Fix test --- tests/baselines/reference/implicitAnyWidenToAny.errors.txt | 2 +- tests/baselines/reference/implicitAnyWidenToAny.js | 4 ++-- tests/cases/compiler/implicitAnyWidenToAny.ts | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/baselines/reference/implicitAnyWidenToAny.errors.txt b/tests/baselines/reference/implicitAnyWidenToAny.errors.txt index 7a9314d982..4302211d9a 100644 --- a/tests/baselines/reference/implicitAnyWidenToAny.errors.txt +++ b/tests/baselines/reference/implicitAnyWidenToAny.errors.txt @@ -8,7 +8,7 @@ tests/cases/compiler/implicitAnyWidenToAny.ts(4,5): error TS7005: Variable 'wide var widenArray = [null, undefined]; // error at "widenArray" ~~~~~~~~~~ !!! error TS7005: Variable 'widenArray' implicitly has an 'any[]' type. - var emptyArray = []; // error at "emptyArray" + var emptyArray = []; // these should not be error class AnimalObj { diff --git a/tests/baselines/reference/implicitAnyWidenToAny.js b/tests/baselines/reference/implicitAnyWidenToAny.js index 0779a16674..0d1c42ad9d 100644 --- a/tests/baselines/reference/implicitAnyWidenToAny.js +++ b/tests/baselines/reference/implicitAnyWidenToAny.js @@ -3,7 +3,7 @@ var x = null; // error at "x" var x1 = undefined; // error at "x1" var widenArray = [null, undefined]; // error at "widenArray" -var emptyArray = []; // error at "emptyArray" +var emptyArray = []; // these should not be error class AnimalObj { @@ -32,7 +32,7 @@ var obj1 = anyReturnFunc(); var x = null; // error at "x" var x1 = undefined; // error at "x1" var widenArray = [null, undefined]; // error at "widenArray" -var emptyArray = []; // error at "emptyArray" +var emptyArray = []; // these should not be error var AnimalObj = (function () { function AnimalObj() { diff --git a/tests/cases/compiler/implicitAnyWidenToAny.ts b/tests/cases/compiler/implicitAnyWidenToAny.ts index b4f4b5eb31..dcbabd38b4 100644 --- a/tests/cases/compiler/implicitAnyWidenToAny.ts +++ b/tests/cases/compiler/implicitAnyWidenToAny.ts @@ -3,7 +3,7 @@ var x = null; // error at "x" var x1 = undefined; // error at "x1" var widenArray = [null, undefined]; // error at "widenArray" -var emptyArray = []; // error at "emptyArray" +var emptyArray = []; // these should not be error class AnimalObj { From a27a68f8eb67557a9a2eda50501aa0c40c20699f Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 13 Oct 2016 09:44:50 -0700 Subject: [PATCH 36/80] Add additional tests --- .../baselines/reference/controlFlowArrays.js | 30 +++++++++ .../reference/controlFlowArrays.symbols | 48 ++++++++++++++ .../reference/controlFlowArrays.types | 64 +++++++++++++++++++ tests/cases/compiler/controlFlowArrays.ts | 16 +++++ 4 files changed, 158 insertions(+) diff --git a/tests/baselines/reference/controlFlowArrays.js b/tests/baselines/reference/controlFlowArrays.js index d6f387ab98..b2d3fa8a2f 100644 --- a/tests/baselines/reference/controlFlowArrays.js +++ b/tests/baselines/reference/controlFlowArrays.js @@ -155,6 +155,22 @@ function f16() { (x.push("hello"), x).push(true); ((x))[3] = { a: 1 }; return x; // (string | number | boolean | { a: number })[] +} + +function f17() { + let x = []; + x.unshift(5); + x.unshift("hello"); + x.unshift(true); + return x; // (string | number | boolean)[] +} + +function f18() { + let x = []; + x.push(5); + x.unshift("hello"); + x[2] = true; + return x; // (string | number | boolean)[] } //// [controlFlowArrays.js] @@ -299,3 +315,17 @@ function f16() { ((x))[3] = { a: 1 }; return x; // (string | number | boolean | { a: number })[] } +function f17() { + var x = []; + x.unshift(5); + x.unshift("hello"); + x.unshift(true); + return x; // (string | number | boolean)[] +} +function f18() { + var x = []; + x.push(5); + x.unshift("hello"); + x[2] = true; + return x; // (string | number | boolean)[] +} diff --git a/tests/baselines/reference/controlFlowArrays.symbols b/tests/baselines/reference/controlFlowArrays.symbols index 204a217199..463fb52258 100644 --- a/tests/baselines/reference/controlFlowArrays.symbols +++ b/tests/baselines/reference/controlFlowArrays.symbols @@ -400,3 +400,51 @@ function f16() { return x; // (string | number | boolean | { a: number })[] >x : Symbol(x, Decl(controlFlowArrays.ts, 150, 7)) } + +function f17() { +>f17 : Symbol(f17, Decl(controlFlowArrays.ts, 156, 1)) + + let x = []; +>x : Symbol(x, Decl(controlFlowArrays.ts, 159, 7)) + + x.unshift(5); +>x.unshift : Symbol(Array.unshift, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 159, 7)) +>unshift : Symbol(Array.unshift, Decl(lib.d.ts, --, --)) + + x.unshift("hello"); +>x.unshift : Symbol(Array.unshift, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 159, 7)) +>unshift : Symbol(Array.unshift, Decl(lib.d.ts, --, --)) + + x.unshift(true); +>x.unshift : Symbol(Array.unshift, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 159, 7)) +>unshift : Symbol(Array.unshift, Decl(lib.d.ts, --, --)) + + return x; // (string | number | boolean)[] +>x : Symbol(x, Decl(controlFlowArrays.ts, 159, 7)) +} + +function f18() { +>f18 : Symbol(f18, Decl(controlFlowArrays.ts, 164, 1)) + + let x = []; +>x : Symbol(x, Decl(controlFlowArrays.ts, 167, 7)) + + x.push(5); +>x.push : Symbol(Array.push, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 167, 7)) +>push : Symbol(Array.push, Decl(lib.d.ts, --, --)) + + x.unshift("hello"); +>x.unshift : Symbol(Array.unshift, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 167, 7)) +>unshift : Symbol(Array.unshift, Decl(lib.d.ts, --, --)) + + x[2] = true; +>x : Symbol(x, Decl(controlFlowArrays.ts, 167, 7)) + + return x; // (string | number | boolean)[] +>x : Symbol(x, Decl(controlFlowArrays.ts, 167, 7)) +} diff --git a/tests/baselines/reference/controlFlowArrays.types b/tests/baselines/reference/controlFlowArrays.types index 3a91ce7e19..2299afd7d2 100644 --- a/tests/baselines/reference/controlFlowArrays.types +++ b/tests/baselines/reference/controlFlowArrays.types @@ -521,3 +521,67 @@ function f16() { return x; // (string | number | boolean | { a: number })[] >x : (string | number | boolean | { a: number; })[] } + +function f17() { +>f17 : () => (string | number | boolean)[] + + let x = []; +>x : any[] +>[] : never[] + + x.unshift(5); +>x.unshift(5) : number +>x.unshift : (...items: any[]) => number +>x : any[] +>unshift : (...items: any[]) => number +>5 : 5 + + x.unshift("hello"); +>x.unshift("hello") : number +>x.unshift : (...items: any[]) => number +>x : any[] +>unshift : (...items: any[]) => number +>"hello" : "hello" + + x.unshift(true); +>x.unshift(true) : number +>x.unshift : (...items: any[]) => number +>x : any[] +>unshift : (...items: any[]) => number +>true : true + + return x; // (string | number | boolean)[] +>x : (string | number | boolean)[] +} + +function f18() { +>f18 : () => (string | number | boolean)[] + + let x = []; +>x : any[] +>[] : never[] + + x.push(5); +>x.push(5) : number +>x.push : (...items: any[]) => number +>x : any[] +>push : (...items: any[]) => number +>5 : 5 + + x.unshift("hello"); +>x.unshift("hello") : number +>x.unshift : (...items: any[]) => number +>x : any[] +>unshift : (...items: any[]) => number +>"hello" : "hello" + + x[2] = true; +>x[2] = true : true +>x[2] : any +>x : any[] +>2 : 2 +>true : true + + return x; // (string | number | boolean)[] +>x : (string | number | boolean)[] +} diff --git a/tests/cases/compiler/controlFlowArrays.ts b/tests/cases/compiler/controlFlowArrays.ts index e89a244375..160f0efed1 100644 --- a/tests/cases/compiler/controlFlowArrays.ts +++ b/tests/cases/compiler/controlFlowArrays.ts @@ -156,4 +156,20 @@ function f16() { (x.push("hello"), x).push(true); ((x))[3] = { a: 1 }; return x; // (string | number | boolean | { a: number })[] +} + +function f17() { + let x = []; + x.unshift(5); + x.unshift("hello"); + x.unshift(true); + return x; // (string | number | boolean)[] +} + +function f18() { + let x = []; + x.push(5); + x.unshift("hello"); + x[2] = true; + return x; // (string | number | boolean)[] } \ No newline at end of file From 1c6fde67567b9d79d4ba51c68c3a8c12a22e3870 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Thu, 13 Oct 2016 13:03:25 -0700 Subject: [PATCH 37/80] Update issue template --- issue_template.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/issue_template.md b/issue_template.md index 7799960ec7..fcd995317f 100644 --- a/issue_template.md +++ b/issue_template.md @@ -2,7 +2,7 @@ -**TypeScript Version:** 1.8.0 / nightly (2.0.0-dev.201xxxxx) +**TypeScript Version:** 2.0.3 / nightly (2.1.0-dev.201xxxxx) **Code** From 5b4dfcc18f441f6af1bcd5485b86e9a3429019c1 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Thu, 13 Oct 2016 13:22:58 -0700 Subject: [PATCH 38/80] Address PR: remove locales and options; use accent as default --- src/compiler/core.ts | 19 +++++++------------ src/services/navigateTo.ts | 5 +---- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 47eb66db07..e8fadbff6e 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -23,10 +23,6 @@ namespace ts { // More efficient to create a collator once and use its `compare` than to call `a.localeCompare(b)` many times. export const collator: { compare(a: string, b: string): number } = typeof Intl === "object" && typeof Intl.Collator === "function" ? new Intl.Collator() : undefined; - // This means "compare in a case insensitive manner but consider accentsor other diacritic marks" - // (e.g. a ≠ b, a ≠ á, a = A) - const accentSensitivity: Intl.CollatorOptions = { usage: "sort", sensitivity: "accent" }; - /** * Use this function instead of calling "String.prototype.localeCompre". This function will preform appropriate check to make sure that * "typeof Intl" is correct as there are reported issues #11110 nad #11339. @@ -1033,13 +1029,14 @@ namespace ts { return a < b ? Comparison.LessThan : Comparison.GreaterThan; } - export function compareStrings(a: string, b: string, locales?: string | string[], options?: Intl.CollatorOptions): Comparison { + export function compareStrings(a: string, b: string, ignoreCase?: boolean): Comparison { if (a === b) return Comparison.EqualTo; if (a === undefined) return Comparison.LessThan; if (b === undefined) return Comparison.GreaterThan; - if (options) { + if (ignoreCase) { if (collator && String.prototype.localeCompare) { - const result = a.localeCompare(b, locales, options); + // accent means a ≠ b, a ≠ á, a = A + const result = a.localeCompare(b, /*locales*/ undefined, { usage: "sort", sensitivity: "accent" }); return result < 0 ? Comparison.LessThan : result > 0 ? Comparison.GreaterThan : Comparison.EqualTo; } @@ -1052,7 +1049,7 @@ namespace ts { } export function compareStringsCaseInsensitive(a: string, b: string) { - return compareStrings(a, b, /*locales*/ undefined, accentSensitivity); + return compareStrings(a, b, /*ignoreCase*/ true); } function getDiagnosticFileName(diagnostic: Diagnostic): string { @@ -1422,8 +1419,7 @@ namespace ts { const bComponents = getNormalizedPathComponents(b, currentDirectory); const sharedLength = Math.min(aComponents.length, bComponents.length); for (let i = 0; i < sharedLength; i++) { - const result = compareStrings(aComponents[i], bComponents[i], - /*locales*/ undefined, /*options*/ ignoreCase ? accentSensitivity : undefined); + const result = compareStrings(aComponents[i], bComponents[i], ignoreCase); if (result !== Comparison.EqualTo) { return result; } @@ -1445,8 +1441,7 @@ namespace ts { } for (let i = 0; i < parentComponents.length; i++) { - const result = compareStrings(parentComponents[i], childComponents[i], - /*locales*/ undefined, /*options*/ ignoreCase ? accentSensitivity : undefined); + const result = compareStrings(parentComponents[i], childComponents[i], ignoreCase); if (result !== Comparison.EqualTo) { return false; } diff --git a/src/services/navigateTo.ts b/src/services/navigateTo.ts index 2433dbe979..82f4dd49f2 100644 --- a/src/services/navigateTo.ts +++ b/src/services/navigateTo.ts @@ -6,9 +6,6 @@ namespace ts.NavigateTo { const patternMatcher = createPatternMatcher(searchValue); let rawItems: RawNavigateToItem[] = []; - // This means "compare in a case insensitive manner." - const baseSensitivity: Intl.CollatorOptions = { sensitivity: "base" }; - // Search the declarations in all files and output matched NavigateToItem into array of NavigateToItem[] forEach(sourceFiles, sourceFile => { cancellationToken.throwIfCancellationRequested(); @@ -188,7 +185,7 @@ namespace ts.NavigateTo { // We first sort case insensitively. So "Aaa" will come before "bar". // Then we sort case sensitively, so "aaa" will come before "Aaa". return i1.matchKind - i2.matchKind || - ts.compareStrings(i1.name, i2.name, /*locales*/ undefined, /*options*/ baseSensitivity) || + ts.compareStringsCaseInsensitive(i1.name, i2.name) || ts.compareStrings(i1.name, i2.name); } From bf301e9ccce09f7dcd36944d8941e2c26e5c73f7 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 13 Oct 2016 13:28:58 -0700 Subject: [PATCH 39/80] Treat reference to empty evolving array as an implicit any[] --- src/compiler/checker.ts | 46 ++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7bec343c91..9b2679adc5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8524,9 +8524,11 @@ namespace ts { } function createFinalArrayType(elementType: Type) { - return createArrayType(elementType !== neverType ? - elementType.flags & TypeFlags.Union ? getUnionType((elementType).types, /*subtypeReduction*/ true) : elementType : - strictNullChecks ? neverType : undefinedWideningType); + return elementType.flags & TypeFlags.Never ? + autoArrayType : + createArrayType(elementType.flags & TypeFlags.Union ? + getUnionType((elementType).types, /*subtypeReduction*/ true) : + elementType); } // We perform subtype reduction upon obtaining the final array type from an evolving array type. @@ -8564,26 +8566,22 @@ namespace ts { getUnionType(sameMap(types, finalizeEvolvingArrayType), subtypeReduction); } - // Return true if the given node is 'x' in an 'x.push(value)' or 'x.unshift(value)' operation. - function isPushOrUnshiftCallTarget(node: Node) { - const parent = getReferenceRoot(node).parent; - return parent.kind === SyntaxKind.PropertyAccessExpression && - parent.parent.kind === SyntaxKind.CallExpression && - isPushOrUnshiftIdentifier((parent).name); - } - - // Return true if the given node is 'x' in an 'x[n] = value' operation, where 'n' is an - // expression of type any, undefined, or a number-like type. - function isElementAssignmentTarget(node: Node) { + // Return true if the given node is 'x' in an 'x.length', x.push(value)', 'x.unshift(value)' or + // 'x[n] = value' operation, where 'n' is an expression of type any, undefined, or a number-like type. + function isEvolvingArrayOperationTarget(node: Node) { const root = getReferenceRoot(node); const parent = root.parent; - return parent.kind === SyntaxKind.ElementAccessExpression && + const isLengthPushOrUnshift = parent.kind === SyntaxKind.PropertyAccessExpression && ( + (parent).name.text === "length" || + parent.parent.kind === SyntaxKind.CallExpression && isPushOrUnshiftIdentifier((parent).name)); + const isElementAssignment = parent.kind === SyntaxKind.ElementAccessExpression && (parent).expression === root && parent.parent.kind === SyntaxKind.BinaryExpression && (parent.parent).operatorToken.kind === SyntaxKind.EqualsToken && (parent.parent).left === parent && !isAssignmentTarget(parent.parent) && isTypeAnyOrAllConstituentTypesHaveKind(checkExpression((parent).argumentExpression), TypeFlags.NumberLike | TypeFlags.Undefined); + return isLengthPushOrUnshift || isElementAssignment; } function getFlowTypeOfReference(reference: Node, declaredType: Type, assumeInitialized: boolean, flowContainer: Node) { @@ -8597,11 +8595,11 @@ namespace ts { const visitedFlowStart = visitedFlowCount; const evolvedType = getTypeFromFlowType(getTypeAtFlowNode(reference.flowNode)); visitedFlowCount = visitedFlowStart; - // When the reference is 'x' in an 'x.push(value)' or 'x[n] = value' operation, we give type - // 'any[]' to 'x' instead of using the type determined by control flow analysis such that new - // element types are not considered errors. - const isEvolvingArrayInferenceTarget = isEvolvingArrayType(evolvedType) && (isPushOrUnshiftCallTarget(reference) || isElementAssignmentTarget(reference)); - const resultType = isEvolvingArrayInferenceTarget ? anyArrayType : finalizeEvolvingArrayType(evolvedType); + // When the reference is 'x' in an 'x.length', 'x.push(value)', 'x.unshift(value)' or x[n] = value' operation, + // we give type 'any[]' to 'x' instead of using the type determined by control flow analysis such that operations + // on empty arrays are possible without implicit any errors and new element types can be inferred without + // type mismatch errors. + const resultType = isEvolvingArrayType(evolvedType) && isEvolvingArrayOperationTarget(reference) ? anyArrayType : finalizeEvolvingArrayType(evolvedType); if (reference.parent.kind === SyntaxKind.NonNullExpression && getTypeWithFacts(resultType, TypeFacts.NEUndefinedOrNull).flags & TypeFlags.Never) { return declaredType; } @@ -9355,12 +9353,12 @@ namespace ts { // from declaration to use, and when the variable's declared type doesn't include undefined but the // control flow based type does include undefined. if (type === autoType || type === autoArrayType) { - if (flowType === type) { + if (flowType === autoType || flowType === autoArrayType) { if (compilerOptions.noImplicitAny) { - error(declaration.name, Diagnostics.Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined, symbolToString(symbol), typeToString(type)); - error(node, Diagnostics.Variable_0_implicitly_has_an_1_type, symbolToString(symbol), typeToString(type)); + error(declaration.name, Diagnostics.Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined, symbolToString(symbol), typeToString(flowType)); + error(node, Diagnostics.Variable_0_implicitly_has_an_1_type, symbolToString(symbol), typeToString(flowType)); } - return convertAutoToAny(type); + return convertAutoToAny(flowType); } } else if (!assumeInitialized && !(getFalsyFlags(type) & TypeFlags.Undefined) && getFalsyFlags(flowType) & TypeFlags.Undefined) { From bfa4197ffe610354efb382a5ef772ed3bf70c3c1 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 13 Oct 2016 13:29:08 -0700 Subject: [PATCH 40/80] Update tests --- tests/cases/compiler/controlFlowArrayErrors.ts | 10 +++++----- tests/cases/compiler/controlFlowArrays.ts | 10 ++++++++-- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/tests/cases/compiler/controlFlowArrayErrors.ts b/tests/cases/compiler/controlFlowArrayErrors.ts index aab3a974cd..08107ff365 100644 --- a/tests/cases/compiler/controlFlowArrayErrors.ts +++ b/tests/cases/compiler/controlFlowArrayErrors.ts @@ -3,16 +3,16 @@ declare function cond(): boolean; function f1() { - let x = []; - let y = x; // Implicit any[] error + let x = []; // Implicit any[] error in some locations + let y = x; // Implicit any[] error x.push(5); let z = x; } function f2() { - let x; + let x; // Implicit any[] error in some locations x = []; - let y = x; // Implicit any[] error + let y = x; // Implicit any[] error x.push(5); let z = x; } @@ -21,7 +21,7 @@ function f3() { let x = []; // Implicit any[] error in some locations x.push(5); function g() { - x; // Implicit any[] error + x; // Implicit any[] error } } diff --git a/tests/cases/compiler/controlFlowArrays.ts b/tests/cases/compiler/controlFlowArrays.ts index 160f0efed1..646c85f069 100644 --- a/tests/cases/compiler/controlFlowArrays.ts +++ b/tests/cases/compiler/controlFlowArrays.ts @@ -115,13 +115,19 @@ function f10() { function f11() { let x = []; - return x; // never[] + if (x.length === 0) { // x.length ok on implicit any[] + x.push("hello"); + } + return x; } function f12() { let x; x = []; - return x; // never[] + if (x.length === 0) { // x.length ok on implicit any[] + x.push("hello"); + } + return x; } function f13() { From 79ed3a7ed83605f0230df160d8472de1b372d4f3 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 13 Oct 2016 13:29:42 -0700 Subject: [PATCH 41/80] Accept new baselines --- .../reference/arrayLiterals2ES5.types | 6 +- .../controlFlowArrayErrors.errors.txt | 28 +++-- .../reference/controlFlowArrayErrors.js | 14 +-- .../baselines/reference/controlFlowArrays.js | 20 +++- .../reference/controlFlowArrays.symbols | 108 +++++++++++------- .../reference/controlFlowArrays.types | 40 ++++++- .../genericTypeParameterEquivalence2.types | 2 +- .../reference/globalThisCapture.types | 4 +- 8 files changed, 144 insertions(+), 78 deletions(-) diff --git a/tests/baselines/reference/arrayLiterals2ES5.types b/tests/baselines/reference/arrayLiterals2ES5.types index 833966a6e4..c3256db925 100644 --- a/tests/baselines/reference/arrayLiterals2ES5.types +++ b/tests/baselines/reference/arrayLiterals2ES5.types @@ -194,9 +194,9 @@ var d5 = [...temp3]; var d6 = [...temp4]; >d6 : any[] ->[...temp4] : undefined[] ->...temp4 : undefined ->temp4 : undefined[] +>[...temp4] : any[] +>...temp4 : any +>temp4 : any[] var d7 = [...[...temp1]]; >d7 : number[] diff --git a/tests/baselines/reference/controlFlowArrayErrors.errors.txt b/tests/baselines/reference/controlFlowArrayErrors.errors.txt index bc13de261e..2ef009dc0e 100644 --- a/tests/baselines/reference/controlFlowArrayErrors.errors.txt +++ b/tests/baselines/reference/controlFlowArrayErrors.errors.txt @@ -1,5 +1,7 @@ -tests/cases/compiler/controlFlowArrayErrors.ts(6,9): error TS7005: Variable 'y' implicitly has an 'any[]' type. -tests/cases/compiler/controlFlowArrayErrors.ts(14,9): error TS7005: Variable 'y' implicitly has an 'any[]' type. +tests/cases/compiler/controlFlowArrayErrors.ts(5,9): error TS7034: Variable 'x' implicitly has type 'any[]' in some locations where its type cannot be determined. +tests/cases/compiler/controlFlowArrayErrors.ts(6,13): error TS7005: Variable 'x' implicitly has an 'any[]' type. +tests/cases/compiler/controlFlowArrayErrors.ts(12,9): error TS7034: Variable 'x' implicitly has type 'any[]' in some locations where its type cannot be determined. +tests/cases/compiler/controlFlowArrayErrors.ts(14,13): error TS7005: Variable 'x' implicitly has an 'any[]' type. tests/cases/compiler/controlFlowArrayErrors.ts(20,9): error TS7034: Variable 'x' implicitly has type 'any[]' in some locations where its type cannot be determined. tests/cases/compiler/controlFlowArrayErrors.ts(23,9): error TS7005: Variable 'x' implicitly has an 'any[]' type. tests/cases/compiler/controlFlowArrayErrors.ts(30,12): error TS2345: Argument of type 'true' is not assignable to parameter of type 'string | number'. @@ -10,25 +12,29 @@ tests/cases/compiler/controlFlowArrayErrors.ts(61,11): error TS7034: Variable 'x tests/cases/compiler/controlFlowArrayErrors.ts(64,9): error TS7005: Variable 'x' implicitly has an 'any[]' type. -==== tests/cases/compiler/controlFlowArrayErrors.ts (10 errors) ==== +==== tests/cases/compiler/controlFlowArrayErrors.ts (12 errors) ==== declare function cond(): boolean; function f1() { - let x = []; - let y = x; // Implicit any[] error + let x = []; // Implicit any[] error in some locations ~ -!!! error TS7005: Variable 'y' implicitly has an 'any[]' type. +!!! error TS7034: Variable 'x' implicitly has type 'any[]' in some locations where its type cannot be determined. + let y = x; // Implicit any[] error + ~ +!!! error TS7005: Variable 'x' implicitly has an 'any[]' type. x.push(5); let z = x; } function f2() { - let x; - x = []; - let y = x; // Implicit any[] error + let x; // Implicit any[] error in some locations ~ -!!! error TS7005: Variable 'y' implicitly has an 'any[]' type. +!!! error TS7034: Variable 'x' implicitly has type 'any[]' in some locations where its type cannot be determined. + x = []; + let y = x; // Implicit any[] error + ~ +!!! error TS7005: Variable 'x' implicitly has an 'any[]' type. x.push(5); let z = x; } @@ -39,7 +45,7 @@ tests/cases/compiler/controlFlowArrayErrors.ts(64,9): error TS7005: Variable 'x' !!! error TS7034: Variable 'x' implicitly has type 'any[]' in some locations where its type cannot be determined. x.push(5); function g() { - x; // Implicit any[] error + x; // Implicit any[] error ~ !!! error TS7005: Variable 'x' implicitly has an 'any[]' type. } diff --git a/tests/baselines/reference/controlFlowArrayErrors.js b/tests/baselines/reference/controlFlowArrayErrors.js index 538addc31c..59995eb309 100644 --- a/tests/baselines/reference/controlFlowArrayErrors.js +++ b/tests/baselines/reference/controlFlowArrayErrors.js @@ -3,16 +3,16 @@ declare function cond(): boolean; function f1() { - let x = []; - let y = x; // Implicit any[] error + let x = []; // Implicit any[] error in some locations + let y = x; // Implicit any[] error x.push(5); let z = x; } function f2() { - let x; + let x; // Implicit any[] error in some locations x = []; - let y = x; // Implicit any[] error + let y = x; // Implicit any[] error x.push(5); let z = x; } @@ -21,7 +21,7 @@ function f3() { let x = []; // Implicit any[] error in some locations x.push(5); function g() { - x; // Implicit any[] error + x; // Implicit any[] error } } @@ -68,13 +68,13 @@ function f8() { //// [controlFlowArrayErrors.js] function f1() { - var x = []; + var x = []; // Implicit any[] error in some locations var y = x; // Implicit any[] error x.push(5); var z = x; } function f2() { - var x; + var x; // Implicit any[] error in some locations x = []; var y = x; // Implicit any[] error x.push(5); diff --git a/tests/baselines/reference/controlFlowArrays.js b/tests/baselines/reference/controlFlowArrays.js index b2d3fa8a2f..3f11959949 100644 --- a/tests/baselines/reference/controlFlowArrays.js +++ b/tests/baselines/reference/controlFlowArrays.js @@ -114,13 +114,19 @@ function f10() { function f11() { let x = []; - return x; // never[] + if (x.length === 0) { // x.length ok on implicit any[] + x.push("hello"); + } + return x; } function f12() { let x; x = []; - return x; // never[] + if (x.length === 0) { // x.length ok on implicit any[] + x.push("hello"); + } + return x; } function f13() { @@ -278,12 +284,18 @@ function f10() { } function f11() { var x = []; - return x; // never[] + if (x.length === 0) { + x.push("hello"); + } + return x; } function f12() { var x; x = []; - return x; // never[] + if (x.length === 0) { + x.push("hello"); + } + return x; } function f13() { var x = []; diff --git a/tests/baselines/reference/controlFlowArrays.symbols b/tests/baselines/reference/controlFlowArrays.symbols index 463fb52258..184a813a05 100644 --- a/tests/baselines/reference/controlFlowArrays.symbols +++ b/tests/baselines/reference/controlFlowArrays.symbols @@ -282,78 +282,98 @@ function f11() { let x = []; >x : Symbol(x, Decl(controlFlowArrays.ts, 114, 7)) - return x; // never[] + if (x.length === 0) { // x.length ok on implicit any[] +>x.length : Symbol(Array.length, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 114, 7)) +>length : Symbol(Array.length, Decl(lib.d.ts, --, --)) + + x.push("hello"); +>x.push : Symbol(Array.push, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 114, 7)) +>push : Symbol(Array.push, Decl(lib.d.ts, --, --)) + } + return x; >x : Symbol(x, Decl(controlFlowArrays.ts, 114, 7)) } function f12() { ->f12 : Symbol(f12, Decl(controlFlowArrays.ts, 116, 1)) +>f12 : Symbol(f12, Decl(controlFlowArrays.ts, 119, 1)) let x; ->x : Symbol(x, Decl(controlFlowArrays.ts, 119, 7)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 122, 7)) x = []; ->x : Symbol(x, Decl(controlFlowArrays.ts, 119, 7)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 122, 7)) - return x; // never[] ->x : Symbol(x, Decl(controlFlowArrays.ts, 119, 7)) + if (x.length === 0) { // x.length ok on implicit any[] +>x.length : Symbol(Array.length, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 122, 7)) +>length : Symbol(Array.length, Decl(lib.d.ts, --, --)) + + x.push("hello"); +>x.push : Symbol(Array.push, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 122, 7)) +>push : Symbol(Array.push, Decl(lib.d.ts, --, --)) + } + return x; +>x : Symbol(x, Decl(controlFlowArrays.ts, 122, 7)) } function f13() { ->f13 : Symbol(f13, Decl(controlFlowArrays.ts, 122, 1)) +>f13 : Symbol(f13, Decl(controlFlowArrays.ts, 128, 1)) var x = []; ->x : Symbol(x, Decl(controlFlowArrays.ts, 125, 7)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 131, 7)) x.push(5); >x.push : Symbol(Array.push, Decl(lib.d.ts, --, --)) ->x : Symbol(x, Decl(controlFlowArrays.ts, 125, 7)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 131, 7)) >push : Symbol(Array.push, Decl(lib.d.ts, --, --)) x.push("hello"); >x.push : Symbol(Array.push, Decl(lib.d.ts, --, --)) ->x : Symbol(x, Decl(controlFlowArrays.ts, 125, 7)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 131, 7)) >push : Symbol(Array.push, Decl(lib.d.ts, --, --)) x.push(true); >x.push : Symbol(Array.push, Decl(lib.d.ts, --, --)) ->x : Symbol(x, Decl(controlFlowArrays.ts, 125, 7)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 131, 7)) >push : Symbol(Array.push, Decl(lib.d.ts, --, --)) return x; // (string | number | boolean)[] ->x : Symbol(x, Decl(controlFlowArrays.ts, 125, 7)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 131, 7)) } function f14() { ->f14 : Symbol(f14, Decl(controlFlowArrays.ts, 130, 1)) +>f14 : Symbol(f14, Decl(controlFlowArrays.ts, 136, 1)) const x = []; ->x : Symbol(x, Decl(controlFlowArrays.ts, 133, 9)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 139, 9)) x.push(5); >x.push : Symbol(Array.push, Decl(lib.d.ts, --, --)) ->x : Symbol(x, Decl(controlFlowArrays.ts, 133, 9)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 139, 9)) >push : Symbol(Array.push, Decl(lib.d.ts, --, --)) x.push("hello"); >x.push : Symbol(Array.push, Decl(lib.d.ts, --, --)) ->x : Symbol(x, Decl(controlFlowArrays.ts, 133, 9)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 139, 9)) >push : Symbol(Array.push, Decl(lib.d.ts, --, --)) x.push(true); >x.push : Symbol(Array.push, Decl(lib.d.ts, --, --)) ->x : Symbol(x, Decl(controlFlowArrays.ts, 133, 9)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 139, 9)) >push : Symbol(Array.push, Decl(lib.d.ts, --, --)) return x; // (string | number | boolean)[] ->x : Symbol(x, Decl(controlFlowArrays.ts, 133, 9)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 139, 9)) } function f15() { ->f15 : Symbol(f15, Decl(controlFlowArrays.ts, 138, 1)) +>f15 : Symbol(f15, Decl(controlFlowArrays.ts, 144, 1)) let x = []; ->x : Symbol(x, Decl(controlFlowArrays.ts, 141, 7)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 147, 7)) while (cond()) { >cond : Symbol(cond, Decl(controlFlowArrays.ts, 0, 0)) @@ -363,88 +383,88 @@ function f15() { x.push("hello"); >x.push : Symbol(Array.push, Decl(lib.d.ts, --, --)) ->x : Symbol(x, Decl(controlFlowArrays.ts, 141, 7)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 147, 7)) >push : Symbol(Array.push, Decl(lib.d.ts, --, --)) } return x; // string[] ->x : Symbol(x, Decl(controlFlowArrays.ts, 141, 7)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 147, 7)) } function f16() { ->f16 : Symbol(f16, Decl(controlFlowArrays.ts, 147, 1)) +>f16 : Symbol(f16, Decl(controlFlowArrays.ts, 153, 1)) let x; ->x : Symbol(x, Decl(controlFlowArrays.ts, 150, 7)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 156, 7)) let y; ->y : Symbol(y, Decl(controlFlowArrays.ts, 151, 7)) +>y : Symbol(y, Decl(controlFlowArrays.ts, 157, 7)) (x = [], x).push(5); >(x = [], x).push : Symbol(Array.push, Decl(lib.d.ts, --, --)) ->x : Symbol(x, Decl(controlFlowArrays.ts, 150, 7)) ->x : Symbol(x, Decl(controlFlowArrays.ts, 150, 7)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 156, 7)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 156, 7)) >push : Symbol(Array.push, Decl(lib.d.ts, --, --)) (x.push("hello"), x).push(true); >(x.push("hello"), x).push : Symbol(Array.push, Decl(lib.d.ts, --, --)) >x.push : Symbol(Array.push, Decl(lib.d.ts, --, --)) ->x : Symbol(x, Decl(controlFlowArrays.ts, 150, 7)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 156, 7)) >push : Symbol(Array.push, Decl(lib.d.ts, --, --)) ->x : Symbol(x, Decl(controlFlowArrays.ts, 150, 7)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 156, 7)) >push : Symbol(Array.push, Decl(lib.d.ts, --, --)) ((x))[3] = { a: 1 }; ->x : Symbol(x, Decl(controlFlowArrays.ts, 150, 7)) ->a : Symbol(a, Decl(controlFlowArrays.ts, 154, 16)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 156, 7)) +>a : Symbol(a, Decl(controlFlowArrays.ts, 160, 16)) return x; // (string | number | boolean | { a: number })[] ->x : Symbol(x, Decl(controlFlowArrays.ts, 150, 7)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 156, 7)) } function f17() { ->f17 : Symbol(f17, Decl(controlFlowArrays.ts, 156, 1)) +>f17 : Symbol(f17, Decl(controlFlowArrays.ts, 162, 1)) let x = []; ->x : Symbol(x, Decl(controlFlowArrays.ts, 159, 7)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 165, 7)) x.unshift(5); >x.unshift : Symbol(Array.unshift, Decl(lib.d.ts, --, --)) ->x : Symbol(x, Decl(controlFlowArrays.ts, 159, 7)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 165, 7)) >unshift : Symbol(Array.unshift, Decl(lib.d.ts, --, --)) x.unshift("hello"); >x.unshift : Symbol(Array.unshift, Decl(lib.d.ts, --, --)) ->x : Symbol(x, Decl(controlFlowArrays.ts, 159, 7)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 165, 7)) >unshift : Symbol(Array.unshift, Decl(lib.d.ts, --, --)) x.unshift(true); >x.unshift : Symbol(Array.unshift, Decl(lib.d.ts, --, --)) ->x : Symbol(x, Decl(controlFlowArrays.ts, 159, 7)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 165, 7)) >unshift : Symbol(Array.unshift, Decl(lib.d.ts, --, --)) return x; // (string | number | boolean)[] ->x : Symbol(x, Decl(controlFlowArrays.ts, 159, 7)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 165, 7)) } function f18() { ->f18 : Symbol(f18, Decl(controlFlowArrays.ts, 164, 1)) +>f18 : Symbol(f18, Decl(controlFlowArrays.ts, 170, 1)) let x = []; ->x : Symbol(x, Decl(controlFlowArrays.ts, 167, 7)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 173, 7)) x.push(5); >x.push : Symbol(Array.push, Decl(lib.d.ts, --, --)) ->x : Symbol(x, Decl(controlFlowArrays.ts, 167, 7)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 173, 7)) >push : Symbol(Array.push, Decl(lib.d.ts, --, --)) x.unshift("hello"); >x.unshift : Symbol(Array.unshift, Decl(lib.d.ts, --, --)) ->x : Symbol(x, Decl(controlFlowArrays.ts, 167, 7)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 173, 7)) >unshift : Symbol(Array.unshift, Decl(lib.d.ts, --, --)) x[2] = true; ->x : Symbol(x, Decl(controlFlowArrays.ts, 167, 7)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 173, 7)) return x; // (string | number | boolean)[] ->x : Symbol(x, Decl(controlFlowArrays.ts, 167, 7)) +>x : Symbol(x, Decl(controlFlowArrays.ts, 173, 7)) } diff --git a/tests/baselines/reference/controlFlowArrays.types b/tests/baselines/reference/controlFlowArrays.types index 2299afd7d2..2a27bbf10d 100644 --- a/tests/baselines/reference/controlFlowArrays.types +++ b/tests/baselines/reference/controlFlowArrays.types @@ -357,18 +357,32 @@ function f10() { } function f11() { ->f11 : () => never[] +>f11 : () => string[] let x = []; >x : any[] >[] : never[] - return x; // never[] ->x : never[] + if (x.length === 0) { // x.length ok on implicit any[] +>x.length === 0 : boolean +>x.length : number +>x : any[] +>length : number +>0 : 0 + + x.push("hello"); +>x.push("hello") : number +>x.push : (...items: any[]) => number +>x : any[] +>push : (...items: any[]) => number +>"hello" : "hello" + } + return x; +>x : string[] } function f12() { ->f12 : () => never[] +>f12 : () => string[] let x; >x : any @@ -378,8 +392,22 @@ function f12() { >x : any >[] : never[] - return x; // never[] ->x : never[] + if (x.length === 0) { // x.length ok on implicit any[] +>x.length === 0 : boolean +>x.length : number +>x : any[] +>length : number +>0 : 0 + + x.push("hello"); +>x.push("hello") : number +>x.push : (...items: any[]) => number +>x : any[] +>push : (...items: any[]) => number +>"hello" : "hello" + } + return x; +>x : string[] } function f13() { diff --git a/tests/baselines/reference/genericTypeParameterEquivalence2.types b/tests/baselines/reference/genericTypeParameterEquivalence2.types index 5125376457..6ab297fe32 100644 --- a/tests/baselines/reference/genericTypeParameterEquivalence2.types +++ b/tests/baselines/reference/genericTypeParameterEquivalence2.types @@ -105,7 +105,7 @@ function filter(f: (a: A) => boolean, ar: A[]): A[] { } ); return ret; ->ret : undefined[] +>ret : any[] } // length :: [a] -> Num diff --git a/tests/baselines/reference/globalThisCapture.types b/tests/baselines/reference/globalThisCapture.types index d17c899d1e..063100ff78 100644 --- a/tests/baselines/reference/globalThisCapture.types +++ b/tests/baselines/reference/globalThisCapture.types @@ -13,7 +13,7 @@ var parts = []; // Ensure that the generated code is correct parts[0]; ->parts[0] : undefined ->parts : undefined[] +>parts[0] : any +>parts : any[] >0 : 0 From 99e2219c4ef8c1f5580d873074aa17cdbedf2cac Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Thu, 13 Oct 2016 15:09:26 -0700 Subject: [PATCH 42/80] Remove unused function --- src/compiler/core.ts | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index e8fadbff6e..3ca4abc69d 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -23,21 +23,6 @@ namespace ts { // More efficient to create a collator once and use its `compare` than to call `a.localeCompare(b)` many times. export const collator: { compare(a: string, b: string): number } = typeof Intl === "object" && typeof Intl.Collator === "function" ? new Intl.Collator() : undefined; - /** - * Use this function instead of calling "String.prototype.localeCompre". This function will preform appropriate check to make sure that - * "typeof Intl" is correct as there are reported issues #11110 nad #11339. - * @param a reference string to compare - * @param b string to compare against - * @param locales string of BCP 47 language tag or an array of string of BCP 47 language tag - * @param options an object of Intl.CollatorOptions to specify localeCompare properties - */ - export function localeCompare(a: string, b: string, locales?: string | string[], options?: Intl.CollatorOptions): number | undefined { - if (collator && String.prototype.localeCompare) { - return a.localeCompare(b, locales, options); - } - return undefined; - } - export function createMap(template?: MapLike): Map { const map: Map = createObject(null); // tslint:disable-line:no-null-keyword From c4300e017f8b2f05e591af8f6c65c43dffa96403 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Thu, 13 Oct 2016 17:53:44 -0700 Subject: [PATCH 43/80] Adds ES5 to ES3 transformer for reserved words --- Jakefile.js | 18 ++- src/compiler/transformer.ts | 5 + src/compiler/transformers/es5.ts | 83 ++++++++++ src/compiler/transformers/module/module.ts | 53 ++----- src/compiler/transformers/module/system.ts | 8 +- src/compiler/tsconfig.json | 1 + src/harness/tsconfig.json | 1 + src/services/tsconfig.json | 1 + .../allowSyntheticDefaultImports10.js | 4 +- .../baselines/reference/bluebirdStaticThis.js | 6 +- .../reference/classMethodWithKeywordName1.js | 2 +- ...constructorWithIncompleteTypeAnnotation.js | 10 +- .../baselines/reference/convertKeywordsYes.js | 144 +++++++++--------- .../destructuringParameterDeclaration6.js | 8 +- tests/baselines/reference/es6ClassTest5.js | 2 +- .../reference/fatarrowfunctionsErrors.js | 2 +- tests/baselines/reference/keywordField.js | 6 +- .../reference/keywordInJsxIdentifier.js | 4 +- .../reference/nestedClassDeclaration.js | 2 +- ...bjectBindingPatternKeywordIdentifiers01.js | 2 +- ...bjectBindingPatternKeywordIdentifiers02.js | 2 +- ...bjectBindingPatternKeywordIdentifiers03.js | 2 +- ...bjectBindingPatternKeywordIdentifiers04.js | 2 +- ...ndPropertiesErrorFromNotUsingIdentifier.js | 12 +- ...ctTypesIdentityWithConstructSignatures2.js | 2 +- ...ConstructSignaturesDifferingParamCounts.js | 2 +- ...nstructSignaturesDifferingByConstraints.js | 2 +- ...structSignaturesDifferingByConstraints2.js | 2 +- ...structSignaturesDifferingByConstraints3.js | 2 +- ...onstructSignaturesDifferingByReturnType.js | 2 +- ...nstructSignaturesDifferingByReturnType2.js | 2 +- ...tSignaturesDifferingTypeParameterCounts.js | 2 +- ...ctSignaturesDifferingTypeParameterNames.js | 2 +- ...enericConstructSignaturesOptionalParams.js | 2 +- ...nericConstructSignaturesOptionalParams2.js | 2 +- ...nericConstructSignaturesOptionalParams3.js | 2 +- .../parserErrorRecovery_ObjectLiteral2.js | 2 +- .../parserErrorRecovery_ObjectLiteral3.js | 2 +- .../parserErrorRecovery_ObjectLiteral4.js | 2 +- .../parserErrorRecovery_ObjectLiteral5.js | 2 +- .../parserExportAsFunctionIdentifier.js | 2 +- .../parserKeywordsAsIdentifierName1.js | 6 +- .../parserShorthandPropertyAssignment2.js | 2 +- .../reference/parserSuperExpression3.js | 2 +- .../prototypeOnConstructorFunctions.js | 2 +- tests/baselines/reference/reservedWords.js | 18 +-- tests/baselines/reference/reservedWords2.js | 4 +- tests/baselines/reference/super1.js | 2 +- .../reference/tsxReactEmitNesting.js | 24 +-- .../reference/typeQueryWithReservedWords.js | 4 +- 50 files changed, 270 insertions(+), 208 deletions(-) create mode 100644 src/compiler/transformers/es5.ts diff --git a/Jakefile.js b/Jakefile.js index 64a8553ef3..ff6a9f1bd1 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -70,13 +70,14 @@ var compilerSources = [ "visitor.ts", "transformers/destructuring.ts", "transformers/ts.ts", + "transformers/jsx.ts", + "transformers/es7.ts", + "transformers/es6.ts", + "transformers/es5.ts", + "transformers/generators.ts", "transformers/module/es6.ts", "transformers/module/system.ts", "transformers/module/module.ts", - "transformers/jsx.ts", - "transformers/es7.ts", - "transformers/generators.ts", - "transformers/es6.ts", "transformer.ts", "sourcemap.ts", "comments.ts", @@ -104,13 +105,14 @@ var servicesSources = [ "visitor.ts", "transformers/destructuring.ts", "transformers/ts.ts", + "transformers/jsx.ts", + "transformers/es7.ts", + "transformers/es6.ts", + "transformers/es5.ts", + "transformers/generators.ts", "transformers/module/es6.ts", "transformers/module/system.ts", "transformers/module/module.ts", - "transformers/jsx.ts", - "transformers/es7.ts", - "transformers/generators.ts", - "transformers/es6.ts", "transformer.ts", "sourcemap.ts", "comments.ts", diff --git a/src/compiler/transformer.ts b/src/compiler/transformer.ts index 92407af2bb..1d2df00286 100644 --- a/src/compiler/transformer.ts +++ b/src/compiler/transformer.ts @@ -3,6 +3,7 @@ /// /// /// +/// /// /// /// @@ -122,6 +123,10 @@ namespace ts { transformers.push(transformGenerators); } + if (languageVersion < ScriptTarget.ES5) { + transformers.push(transformES5); + } + return transformers; } diff --git a/src/compiler/transformers/es5.ts b/src/compiler/transformers/es5.ts new file mode 100644 index 0000000000..9e5a72c2ba --- /dev/null +++ b/src/compiler/transformers/es5.ts @@ -0,0 +1,83 @@ +/// +/// + +/*@internal*/ +namespace ts { + /** + * Transforms ES5 syntax into ES3 syntax. + * + * @param context Context and state information for the transformation. + */ + export function transformES5(context: TransformationContext) { + const previousOnSubstituteNode = context.onSubstituteNode; + context.onSubstituteNode = onSubstituteNode; + context.enableSubstitution(SyntaxKind.PropertyAccessExpression); + context.enableSubstitution(SyntaxKind.PropertyAssignment); + return transformSourceFile; + + /** + * Transforms an ES5 source file to ES3. + * + * @param node A SourceFile + */ + function transformSourceFile(node: SourceFile) { + return node; + } + + /** + * Hooks node substitutions. + * + * @param emitContext The context for the emitter. + * @param node The node to substitute. + */ + function onSubstituteNode(emitContext: EmitContext, node: Node) { + node = previousOnSubstituteNode(emitContext, node); + if (isPropertyAccessExpression(node)) { + return substitutePropertyAccessExpression(node); + } + else if (isPropertyAssignment(node)) { + return substitutePropertyAssignment(node); + } + return node; + } + + /** + * Substitutes a PropertyAccessExpression whose name is a reserved word. + * + * @param node A PropertyAccessExpression + */ + function substitutePropertyAccessExpression(node: PropertyAccessExpression): Expression { + const literalName = trySubstituteReservedName(node.name); + if (literalName) { + return createElementAccess(node.expression, literalName, /*location*/ node); + } + return node; + } + + /** + * Substitutes a PropertyAssignment whose name is a reserved word. + * + * @param node A PropertyAssignment + */ + function substitutePropertyAssignment(node: PropertyAssignment): PropertyAssignment { + const literalName = isIdentifier(node.name) && trySubstituteReservedName(node.name); + if (literalName) { + return updatePropertyAssignment(node, literalName, node.initializer); + } + return node; + } + + /** + * If an identifier name is a reserved word, returns a string literal for the name. + * + * @param name An Identifier + */ + function trySubstituteReservedName(name: Identifier) { + const token = name.originalKeywordKind || (nodeIsSynthesized(name) ? stringToToken(name.text) : undefined); + if (token >= SyntaxKind.FirstReservedWord && token <= SyntaxKind.LastReservedWord) { + return createLiteral(name, /*location*/ name); + } + return undefined; + } + } +} \ No newline at end of file diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index 9485261603..edbc0f43a6 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -955,39 +955,19 @@ namespace ts { const declaration = resolver.getReferencedImportDeclaration(node); if (declaration) { if (isImportClause(declaration)) { - if (languageVersion >= ScriptTarget.ES5) { - return createPropertyAccess( - getGeneratedNameForNode(declaration.parent), - createIdentifier("default"), - /*location*/ node - ); - } - else { - // TODO: ES3 transform to handle x.default -> x["default"] - return createElementAccess( - getGeneratedNameForNode(declaration.parent), - createLiteral("default"), - /*location*/ node - ); - } + return createPropertyAccess( + getGeneratedNameForNode(declaration.parent), + createIdentifier("default"), + /*location*/ node + ); } else if (isImportSpecifier(declaration)) { const name = declaration.propertyName || declaration.name; - if (name.originalKeywordKind === SyntaxKind.DefaultKeyword && languageVersion <= ScriptTarget.ES3) { - // TODO: ES3 transform to handle x.default -> x["default"] - return createElementAccess( - getGeneratedNameForNode(declaration.parent.parent.parent), - createLiteral(name.text), - /*location*/ node - ); - } - else { - return createPropertyAccess( - getGeneratedNameForNode(declaration.parent.parent.parent), - getSynthesizedClone(name), - /*location*/ node - ); - } + return createPropertyAccess( + getGeneratedNameForNode(declaration.parent.parent.parent), + getSynthesizedClone(name), + /*location*/ node + ); } } } @@ -1024,15 +1004,10 @@ namespace ts { function createExportAssignment(name: Identifier, value: Expression) { return createAssignment( - name.originalKeywordKind === SyntaxKind.DefaultKeyword && languageVersion === ScriptTarget.ES3 - ? createElementAccess( - createIdentifier("exports"), - createLiteral(name.text) - ) - : createPropertyAccess( - createIdentifier("exports"), - getSynthesizedClone(name) - ), + createPropertyAccess( + createIdentifier("exports"), + getSynthesizedClone(name) + ), value ); } diff --git a/src/compiler/transformers/module/system.ts b/src/compiler/transformers/module/system.ts index 0bb188eb39..349d035f45 100644 --- a/src/compiler/transformers/module/system.ts +++ b/src/compiler/transformers/module/system.ts @@ -19,7 +19,6 @@ namespace ts { const compilerOptions = context.getCompilerOptions(); const resolver = context.getEmitResolver(); const host = context.getEmitHost(); - const languageVersion = getEmitScriptTarget(compilerOptions); const previousOnSubstituteNode = context.onSubstituteNode; const previousOnEmitNode = context.onEmitNode; context.onSubstituteNode = onSubstituteNode; @@ -1312,12 +1311,7 @@ namespace ts { return undefined; } - if (name.originalKeywordKind && languageVersion === ScriptTarget.ES3) { - return createElementAccess(importAlias, createLiteral(name.text)); - } - else { - return createPropertyAccess(importAlias, getSynthesizedClone(name)); - } + return createPropertyAccess(importAlias, getSynthesizedClone(name)); } function collectDependencyGroups(externalImports: (ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration)[]) { diff --git a/src/compiler/tsconfig.json b/src/compiler/tsconfig.json index f128c994af..894ad9683f 100644 --- a/src/compiler/tsconfig.json +++ b/src/compiler/tsconfig.json @@ -26,6 +26,7 @@ "transformers/jsx.ts", "transformers/es7.ts", "transformers/es6.ts", + "transformers/es5.ts", "transformers/generators.ts", "transformers/destructuring.ts", "transformers/module/module.ts", diff --git a/src/harness/tsconfig.json b/src/harness/tsconfig.json index f9d302ace8..ffd3f30e29 100644 --- a/src/harness/tsconfig.json +++ b/src/harness/tsconfig.json @@ -28,6 +28,7 @@ "../compiler/transformers/jsx.ts", "../compiler/transformers/es7.ts", "../compiler/transformers/es6.ts", + "../compiler/transformers/es5.ts", "../compiler/transformers/generators.ts", "../compiler/transformers/destructuring.ts", "../compiler/transformers/module/module.ts", diff --git a/src/services/tsconfig.json b/src/services/tsconfig.json index 58312c6f38..cfad296aba 100644 --- a/src/services/tsconfig.json +++ b/src/services/tsconfig.json @@ -27,6 +27,7 @@ "../compiler/transformers/jsx.ts", "../compiler/transformers/es7.ts", "../compiler/transformers/es6.ts", + "../compiler/transformers/es5.ts", "../compiler/transformers/generators.ts", "../compiler/transformers/destructuring.ts", "../compiler/transformers/module/module.ts", diff --git a/tests/baselines/reference/allowSyntheticDefaultImports10.js b/tests/baselines/reference/allowSyntheticDefaultImports10.js index 746997c4c8..396cd75b57 100644 --- a/tests/baselines/reference/allowSyntheticDefaultImports10.js +++ b/tests/baselines/reference/allowSyntheticDefaultImports10.js @@ -13,5 +13,5 @@ Foo.default.default.foo(); //// [a.js] "use strict"; var Foo = require("./b"); -Foo.default.bar(); -Foo.default.default.foo(); +Foo["default"].bar(); +Foo["default"]["default"].foo(); diff --git a/tests/baselines/reference/bluebirdStaticThis.js b/tests/baselines/reference/bluebirdStaticThis.js index 301f32319a..606f778323 100644 --- a/tests/baselines/reference/bluebirdStaticThis.js +++ b/tests/baselines/reference/bluebirdStaticThis.js @@ -146,12 +146,12 @@ var x; var arr; var foo; var fooProm; -fooProm = Promise.try(Promise, function () { +fooProm = Promise["try"](Promise, function () { return foo; }); -fooProm = Promise.try(Promise, function () { +fooProm = Promise["try"](Promise, function () { return foo; }, arr); -fooProm = Promise.try(Promise, function () { +fooProm = Promise["try"](Promise, function () { return foo; }, arr, x); diff --git a/tests/baselines/reference/classMethodWithKeywordName1.js b/tests/baselines/reference/classMethodWithKeywordName1.js index 6e1faee005..a7cb994bfb 100644 --- a/tests/baselines/reference/classMethodWithKeywordName1.js +++ b/tests/baselines/reference/classMethodWithKeywordName1.js @@ -7,6 +7,6 @@ class C { var C = (function () { function C() { } - C.try = function () { }; + C["try"] = function () { }; return C; }()); diff --git a/tests/baselines/reference/constructorWithIncompleteTypeAnnotation.js b/tests/baselines/reference/constructorWithIncompleteTypeAnnotation.js index 2e3190c15c..1ee309b0eb 100644 --- a/tests/baselines/reference/constructorWithIncompleteTypeAnnotation.js +++ b/tests/baselines/reference/constructorWithIncompleteTypeAnnotation.js @@ -292,7 +292,7 @@ var TypeScriptAllInOne; (function (TypeScriptAllInOne) { var Program = (function () { function Program() { - this.case = bfs.STATEMENTS(4); + this["case"] = bfs.STATEMENTS(4); } Program.Main = function () { var args = []; @@ -305,13 +305,13 @@ var TypeScriptAllInOne; retValue = bfs.VARIABLES(); if (retValue != 0) ^= { - return: 1 + "return": 1 }; } finally { } }; - Program.prototype.if = function (retValue) { + Program.prototype["if"] = function (retValue) { if (retValue === void 0) { retValue = != 0; } return 1; ^ @@ -327,7 +327,7 @@ var TypeScriptAllInOne; return 1; } }; - Program.prototype.catch = function (e) { + Program.prototype["catch"] = function (e) { console.log(e); }; return Program; @@ -364,7 +364,7 @@ var BasicFeatures = (function () { ; var quoted = '"', quoted2 = "'"; var reg = /\w*/; - var objLit = { "var": number = 42, equals: function (x) { return x["var"] === 42; }, instanceof: function () { return 'objLit{42}'; } }; + var objLit = { "var": number = 42, equals: function (x) { return x["var"] === 42; }, "instanceof": function () { return 'objLit{42}'; } }; var weekday = Weekdays.Monday; var con = char + f + hexchar + float.toString() + float2.toString() + reg.toString() + objLit + weekday; // diff --git a/tests/baselines/reference/convertKeywordsYes.js b/tests/baselines/reference/convertKeywordsYes.js index ba3c661d1d..b7bd60e4a9 100644 --- a/tests/baselines/reference/convertKeywordsYes.js +++ b/tests/baselines/reference/convertKeywordsYes.js @@ -344,43 +344,43 @@ var bigObject = { string: 0, get: 0, yield: 0, - break: 0, - case: 0, - catch: 0, - class: 0, - continue: 0, - const: 0, - debugger: 0, + "break": 0, + "case": 0, + "catch": 0, + "class": 0, + "continue": 0, + "const": 0, + "debugger": 0, declare: 0, - default: 0, - delete: 0, - do: 0, - else: 0, - enum: 0, - export: 0, - extends: 0, - false: 0, - finally: 0, - for: 0, - function: 0, - if: 0, - import: 0, - in: 0, - instanceof: 0, - new: 0, - null: 0, - return: 0, - super: 0, - switch: 0, - this: 0, - throw: 0, - true: 0, - try: 0, - typeof: 0, - var: 0, - void: 0, - while: 0, - with: 0 + "default": 0, + "delete": 0, + "do": 0, + "else": 0, + "enum": 0, + "export": 0, + "extends": 0, + "false": 0, + "finally": 0, + "for": 0, + "function": 0, + "if": 0, + "import": 0, + "in": 0, + "instanceof": 0, + "new": 0, + "null": 0, + "return": 0, + "super": 0, + "switch": 0, + "this": 0, + "throw": 0, + "true": 0, + "try": 0, + "typeof": 0, + "var": 0, + "void": 0, + "while": 0, + "with": 0 }; var bigClass = (function () { function bigClass() { @@ -401,43 +401,43 @@ var bigClass = (function () { this.string = 0; this.get = 0; this.yield = 0; - this.break = 0; - this.case = 0; - this.catch = 0; - this.class = 0; - this.continue = 0; - this.const = 0; - this.debugger = 0; + this["break"] = 0; + this["case"] = 0; + this["catch"] = 0; + this["class"] = 0; + this["continue"] = 0; + this["const"] = 0; + this["debugger"] = 0; this.declare = 0; - this.default = 0; - this.delete = 0; - this.do = 0; - this.else = 0; - this.enum = 0; - this.export = 0; - this.extends = 0; - this.false = 0; - this.finally = 0; - this.for = 0; - this.function = 0; - this.if = 0; - this.import = 0; - this.in = 0; - this.instanceof = 0; - this.new = 0; - this.null = 0; - this.return = 0; - this.super = 0; - this.switch = 0; - this.this = 0; - this.throw = 0; - this.true = 0; - this.try = 0; - this.typeof = 0; - this.var = 0; - this.void = 0; - this.while = 0; - this.with = 0; + this["default"] = 0; + this["delete"] = 0; + this["do"] = 0; + this["else"] = 0; + this["enum"] = 0; + this["export"] = 0; + this["extends"] = 0; + this["false"] = 0; + this["finally"] = 0; + this["for"] = 0; + this["function"] = 0; + this["if"] = 0; + this["import"] = 0; + this["in"] = 0; + this["instanceof"] = 0; + this["new"] = 0; + this["null"] = 0; + this["return"] = 0; + this["super"] = 0; + this["switch"] = 0; + this["this"] = 0; + this["throw"] = 0; + this["true"] = 0; + this["try"] = 0; + this["typeof"] = 0; + this["var"] = 0; + this["void"] = 0; + this["while"] = 0; + this["with"] = 0; } return bigClass; }()); diff --git a/tests/baselines/reference/destructuringParameterDeclaration6.js b/tests/baselines/reference/destructuringParameterDeclaration6.js index ad86b2983b..03307415b6 100644 --- a/tests/baselines/reference/destructuringParameterDeclaration6.js +++ b/tests/baselines/reference/destructuringParameterDeclaration6.js @@ -27,7 +27,7 @@ b2({ while: 1 }); "use strict"; // Error function a(_a) { - var = _a.while; + var = _a["while"]; } function a1(_a) { var public = _a.public; @@ -56,13 +56,13 @@ function a7() { a[_i - 0] = arguments[_i]; } } -a({ while: 1 }); +a({ "while": 1 }); // No Error function b1(_a) { var x = _a.public; } function b2(_a) { - var y = _a.while; + var y = _a["while"]; } b1({ public: 1 }); -b2({ while: 1 }); +b2({ "while": 1 }); diff --git a/tests/baselines/reference/es6ClassTest5.js b/tests/baselines/reference/es6ClassTest5.js index b909fac58b..7d4238fda6 100644 --- a/tests/baselines/reference/es6ClassTest5.js +++ b/tests/baselines/reference/es6ClassTest5.js @@ -23,7 +23,7 @@ var C1T5 = (function () { }()); var bigClass = (function () { function bigClass() { - this.break = 1; + this["break"] = 1; } return bigClass; }()); diff --git a/tests/baselines/reference/fatarrowfunctionsErrors.js b/tests/baselines/reference/fatarrowfunctionsErrors.js index 2ac20f1966..ced4660d8d 100644 --- a/tests/baselines/reference/fatarrowfunctionsErrors.js +++ b/tests/baselines/reference/fatarrowfunctionsErrors.js @@ -20,7 +20,7 @@ foo(function () { } return 0; }); -foo((1), { return: 0 }); +foo((1), { "return": 0 }); foo(function (x) { return x; }); foo(function (x) { if (x === void 0) { x = 0; } diff --git a/tests/baselines/reference/keywordField.js b/tests/baselines/reference/keywordField.js index 581d5afa14..a146cffade 100644 --- a/tests/baselines/reference/keywordField.js +++ b/tests/baselines/reference/keywordField.js @@ -12,7 +12,7 @@ var q = a["if"]; //// [keywordField.js] var obj = {}; -obj.if = 1; -var a = { if: "test" }; -var n = a.if; +obj["if"] = 1; +var a = { "if": "test" }; +var n = a["if"]; var q = a["if"]; diff --git a/tests/baselines/reference/keywordInJsxIdentifier.js b/tests/baselines/reference/keywordInJsxIdentifier.js index 6009e1980e..d9c3b51e9a 100644 --- a/tests/baselines/reference/keywordInJsxIdentifier.js +++ b/tests/baselines/reference/keywordInJsxIdentifier.js @@ -9,6 +9,6 @@ declare var React: any; //// [keywordInJsxIdentifier.js] React.createElement("foo", { "class-id": true }); -React.createElement("foo", { class: true }); +React.createElement("foo", { "class": true }); React.createElement("foo", { "class-id": "1" }); -React.createElement("foo", { class: "1" }); +React.createElement("foo", { "class": "1" }); diff --git a/tests/baselines/reference/nestedClassDeclaration.js b/tests/baselines/reference/nestedClassDeclaration.js index 04e2f6348e..cc300ec75a 100644 --- a/tests/baselines/reference/nestedClassDeclaration.js +++ b/tests/baselines/reference/nestedClassDeclaration.js @@ -38,5 +38,5 @@ function foo() { }()); } var x = { - class: C4 + "class": C4 }, _a = void 0; diff --git a/tests/baselines/reference/objectBindingPatternKeywordIdentifiers01.js b/tests/baselines/reference/objectBindingPatternKeywordIdentifiers01.js index cd339bb590..a905e53f22 100644 --- a/tests/baselines/reference/objectBindingPatternKeywordIdentifiers01.js +++ b/tests/baselines/reference/objectBindingPatternKeywordIdentifiers01.js @@ -3,4 +3,4 @@ var { while } = { while: 1 } //// [objectBindingPatternKeywordIdentifiers01.js] -var = { while: 1 }.while; +var = { "while": 1 }["while"]; diff --git a/tests/baselines/reference/objectBindingPatternKeywordIdentifiers02.js b/tests/baselines/reference/objectBindingPatternKeywordIdentifiers02.js index 0286a78ba8..5bc6e1f996 100644 --- a/tests/baselines/reference/objectBindingPatternKeywordIdentifiers02.js +++ b/tests/baselines/reference/objectBindingPatternKeywordIdentifiers02.js @@ -3,4 +3,4 @@ var { while: while } = { while: 1 } //// [objectBindingPatternKeywordIdentifiers02.js] -var _a = { while: 1 }, = _a.while, = _a.while; +var _a = { "while": 1 }, = _a["while"], = _a["while"]; diff --git a/tests/baselines/reference/objectBindingPatternKeywordIdentifiers03.js b/tests/baselines/reference/objectBindingPatternKeywordIdentifiers03.js index 4bbb1afb4c..3d8643d63c 100644 --- a/tests/baselines/reference/objectBindingPatternKeywordIdentifiers03.js +++ b/tests/baselines/reference/objectBindingPatternKeywordIdentifiers03.js @@ -3,4 +3,4 @@ var { "while" } = { while: 1 } //// [objectBindingPatternKeywordIdentifiers03.js] -var = { while: 1 }["while"]; +var = { "while": 1 }["while"]; diff --git a/tests/baselines/reference/objectBindingPatternKeywordIdentifiers04.js b/tests/baselines/reference/objectBindingPatternKeywordIdentifiers04.js index 4e53b13c0a..de7608a77d 100644 --- a/tests/baselines/reference/objectBindingPatternKeywordIdentifiers04.js +++ b/tests/baselines/reference/objectBindingPatternKeywordIdentifiers04.js @@ -3,4 +3,4 @@ var { "while": while } = { while: 1 } //// [objectBindingPatternKeywordIdentifiers04.js] -var _a = { while: 1 }, = _a["while"], = _a.while; +var _a = { "while": 1 }, = _a["while"], = _a["while"]; diff --git a/tests/baselines/reference/objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.js b/tests/baselines/reference/objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.js index b72f0351b9..7b9c9f5d32 100644 --- a/tests/baselines/reference/objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.js +++ b/tests/baselines/reference/objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.js @@ -27,15 +27,15 @@ var y = { 42: , get e() { }, set f() { }, - this: , - super: , - var: , - class: , - typeof: + "this": , + "super": , + "var": , + "class": , + "typeof": }; var x = { a: .b, a: ["ss"], a: [1] }; -var v = { class: }; // error +var v = { "class": }; // error diff --git a/tests/baselines/reference/objectTypesIdentityWithConstructSignatures2.js b/tests/baselines/reference/objectTypesIdentityWithConstructSignatures2.js index 315e079d42..0a422dbda6 100644 --- a/tests/baselines/reference/objectTypesIdentityWithConstructSignatures2.js +++ b/tests/baselines/reference/objectTypesIdentityWithConstructSignatures2.js @@ -91,7 +91,7 @@ var C = (function () { return C; }()); var a; -var b = { new: function (x) { return ''; } }; // not a construct signature, function called new +var b = { "new": function (x) { return ''; } }; // not a construct signature, function called new function foo1b(x) { } function foo1c(x) { } function foo2(x) { } diff --git a/tests/baselines/reference/objectTypesIdentityWithConstructSignaturesDifferingParamCounts.js b/tests/baselines/reference/objectTypesIdentityWithConstructSignaturesDifferingParamCounts.js index a61bedfd52..5fa148b541 100644 --- a/tests/baselines/reference/objectTypesIdentityWithConstructSignaturesDifferingParamCounts.js +++ b/tests/baselines/reference/objectTypesIdentityWithConstructSignaturesDifferingParamCounts.js @@ -91,7 +91,7 @@ var C = (function () { return C; }()); var a; -var b = { new: function (x) { return ''; } }; // not a construct signature, function called new +var b = { "new": function (x) { return ''; } }; // not a construct signature, function called new function foo1b(x) { } function foo1c(x) { } function foo2(x) { } diff --git a/tests/baselines/reference/objectTypesIdentityWithGenericConstructSignaturesDifferingByConstraints.js b/tests/baselines/reference/objectTypesIdentityWithGenericConstructSignaturesDifferingByConstraints.js index c15c53b9bf..6a66e8bbda 100644 --- a/tests/baselines/reference/objectTypesIdentityWithGenericConstructSignaturesDifferingByConstraints.js +++ b/tests/baselines/reference/objectTypesIdentityWithGenericConstructSignaturesDifferingByConstraints.js @@ -92,7 +92,7 @@ var C = (function () { return C; }()); var a; -var b = { new: function (x) { return ''; } }; // not a construct signature, function called new +var b = { "new": function (x) { return ''; } }; // not a construct signature, function called new function foo1b(x) { } function foo1c(x) { } function foo2(x) { } diff --git a/tests/baselines/reference/objectTypesIdentityWithGenericConstructSignaturesDifferingByConstraints2.js b/tests/baselines/reference/objectTypesIdentityWithGenericConstructSignaturesDifferingByConstraints2.js index f8aff596dc..e19837a9f7 100644 --- a/tests/baselines/reference/objectTypesIdentityWithGenericConstructSignaturesDifferingByConstraints2.js +++ b/tests/baselines/reference/objectTypesIdentityWithGenericConstructSignaturesDifferingByConstraints2.js @@ -109,7 +109,7 @@ var D = (function () { return D; }()); var a; -var b = { new: function (x, y) { return ''; } }; // not a construct signature, function called new +var b = { "new": function (x, y) { return ''; } }; // not a construct signature, function called new function foo1b(x) { } function foo1c(x) { } function foo2(x) { } diff --git a/tests/baselines/reference/objectTypesIdentityWithGenericConstructSignaturesDifferingByConstraints3.js b/tests/baselines/reference/objectTypesIdentityWithGenericConstructSignaturesDifferingByConstraints3.js index 141aa86823..735c5bdc2d 100644 --- a/tests/baselines/reference/objectTypesIdentityWithGenericConstructSignaturesDifferingByConstraints3.js +++ b/tests/baselines/reference/objectTypesIdentityWithGenericConstructSignaturesDifferingByConstraints3.js @@ -128,7 +128,7 @@ var D = (function () { return D; }()); var a; -var b = { new: function (x, y) { return ''; } }; // not a construct signature, function called new +var b = { "new": function (x, y) { return ''; } }; // not a construct signature, function called new function foo1b(x) { } function foo1c(x) { } function foo2(x) { } diff --git a/tests/baselines/reference/objectTypesIdentityWithGenericConstructSignaturesDifferingByReturnType.js b/tests/baselines/reference/objectTypesIdentityWithGenericConstructSignaturesDifferingByReturnType.js index b651d368f3..6eab84a49d 100644 --- a/tests/baselines/reference/objectTypesIdentityWithGenericConstructSignaturesDifferingByReturnType.js +++ b/tests/baselines/reference/objectTypesIdentityWithGenericConstructSignaturesDifferingByReturnType.js @@ -99,7 +99,7 @@ var C = (function () { return C; }()); var a; -var b = { new: function (x) { return null; } }; // not a construct signature, function called new +var b = { "new": function (x) { return null; } }; // not a construct signature, function called new function foo1b(x) { } function foo1c(x) { } function foo2(x) { } diff --git a/tests/baselines/reference/objectTypesIdentityWithGenericConstructSignaturesDifferingByReturnType2.js b/tests/baselines/reference/objectTypesIdentityWithGenericConstructSignaturesDifferingByReturnType2.js index ff7095c4ea..d927a8e082 100644 --- a/tests/baselines/reference/objectTypesIdentityWithGenericConstructSignaturesDifferingByReturnType2.js +++ b/tests/baselines/reference/objectTypesIdentityWithGenericConstructSignaturesDifferingByReturnType2.js @@ -95,7 +95,7 @@ var C = (function () { return C; }()); var a; -var b = { new: function (x) { return null; } }; // not a construct signature, function called new +var b = { "new": function (x) { return null; } }; // not a construct signature, function called new function foo1b(x) { } function foo1c(x) { } function foo2(x) { } diff --git a/tests/baselines/reference/objectTypesIdentityWithGenericConstructSignaturesDifferingTypeParameterCounts.js b/tests/baselines/reference/objectTypesIdentityWithGenericConstructSignaturesDifferingTypeParameterCounts.js index 314eb700c4..512bebb3b0 100644 --- a/tests/baselines/reference/objectTypesIdentityWithGenericConstructSignaturesDifferingTypeParameterCounts.js +++ b/tests/baselines/reference/objectTypesIdentityWithGenericConstructSignaturesDifferingTypeParameterCounts.js @@ -87,7 +87,7 @@ var C = (function () { return C; }()); var a; -var b = { new: function (x) { return x; } }; +var b = { "new": function (x) { return x; } }; function foo1b(x) { } function foo1c(x) { } function foo2(x) { } diff --git a/tests/baselines/reference/objectTypesIdentityWithGenericConstructSignaturesDifferingTypeParameterNames.js b/tests/baselines/reference/objectTypesIdentityWithGenericConstructSignaturesDifferingTypeParameterNames.js index 182cf8263b..80cfcd23ec 100644 --- a/tests/baselines/reference/objectTypesIdentityWithGenericConstructSignaturesDifferingTypeParameterNames.js +++ b/tests/baselines/reference/objectTypesIdentityWithGenericConstructSignaturesDifferingTypeParameterNames.js @@ -87,7 +87,7 @@ var C = (function () { return C; }()); var a; -var b = { new: function (x) { return new C(x); } }; +var b = { "new": function (x) { return new C(x); } }; function foo1b(x) { } function foo1c(x) { } function foo2(x) { } diff --git a/tests/baselines/reference/objectTypesIdentityWithGenericConstructSignaturesOptionalParams.js b/tests/baselines/reference/objectTypesIdentityWithGenericConstructSignaturesOptionalParams.js index 5c5dd26c33..87cb0b3353 100644 --- a/tests/baselines/reference/objectTypesIdentityWithGenericConstructSignaturesOptionalParams.js +++ b/tests/baselines/reference/objectTypesIdentityWithGenericConstructSignaturesOptionalParams.js @@ -91,7 +91,7 @@ var C = (function () { return C; }()); var a; -var b = { new: function (x, y) { return new C(x, y); } }; // not a construct signature, function called new +var b = { "new": function (x, y) { return new C(x, y); } }; // not a construct signature, function called new function foo1b(x) { } function foo1c(x) { } function foo2(x) { } diff --git a/tests/baselines/reference/objectTypesIdentityWithGenericConstructSignaturesOptionalParams2.js b/tests/baselines/reference/objectTypesIdentityWithGenericConstructSignaturesOptionalParams2.js index 14b2ec3c0c..6b0e91f817 100644 --- a/tests/baselines/reference/objectTypesIdentityWithGenericConstructSignaturesOptionalParams2.js +++ b/tests/baselines/reference/objectTypesIdentityWithGenericConstructSignaturesOptionalParams2.js @@ -91,7 +91,7 @@ var C = (function () { return C; }()); var a; -var b = { new: function (x, y) { return new C(x, y); } }; // not a construct signature, function called new +var b = { "new": function (x, y) { return new C(x, y); } }; // not a construct signature, function called new function foo1b(x) { } function foo1c(x) { } function foo2(x) { } diff --git a/tests/baselines/reference/objectTypesIdentityWithGenericConstructSignaturesOptionalParams3.js b/tests/baselines/reference/objectTypesIdentityWithGenericConstructSignaturesOptionalParams3.js index ffc238caca..55f2a0217e 100644 --- a/tests/baselines/reference/objectTypesIdentityWithGenericConstructSignaturesOptionalParams3.js +++ b/tests/baselines/reference/objectTypesIdentityWithGenericConstructSignaturesOptionalParams3.js @@ -91,7 +91,7 @@ var C = (function () { return C; }()); var a; -var b = { new: function (x, y) { return new C(x, y); } }; // not a construct signature, function called new +var b = { "new": function (x, y) { return new C(x, y); } }; // not a construct signature, function called new function foo1b(x) { } function foo1c(x) { } function foo2(x) { } diff --git a/tests/baselines/reference/parserErrorRecovery_ObjectLiteral2.js b/tests/baselines/reference/parserErrorRecovery_ObjectLiteral2.js index 6a703759ff..c206a30237 100644 --- a/tests/baselines/reference/parserErrorRecovery_ObjectLiteral2.js +++ b/tests/baselines/reference/parserErrorRecovery_ObjectLiteral2.js @@ -4,4 +4,4 @@ return; //// [parserErrorRecovery_ObjectLiteral2.js] var v = { a: , - return: }; + "return": }; diff --git a/tests/baselines/reference/parserErrorRecovery_ObjectLiteral3.js b/tests/baselines/reference/parserErrorRecovery_ObjectLiteral3.js index eecf45fea4..6cee2b4272 100644 --- a/tests/baselines/reference/parserErrorRecovery_ObjectLiteral3.js +++ b/tests/baselines/reference/parserErrorRecovery_ObjectLiteral3.js @@ -4,4 +4,4 @@ return; //// [parserErrorRecovery_ObjectLiteral3.js] var v = { a: , - return: }; + "return": }; diff --git a/tests/baselines/reference/parserErrorRecovery_ObjectLiteral4.js b/tests/baselines/reference/parserErrorRecovery_ObjectLiteral4.js index 87a1a31437..23d17c8047 100644 --- a/tests/baselines/reference/parserErrorRecovery_ObjectLiteral4.js +++ b/tests/baselines/reference/parserErrorRecovery_ObjectLiteral4.js @@ -4,4 +4,4 @@ return; //// [parserErrorRecovery_ObjectLiteral4.js] var v = { a: 1, - return: }; + "return": }; diff --git a/tests/baselines/reference/parserErrorRecovery_ObjectLiteral5.js b/tests/baselines/reference/parserErrorRecovery_ObjectLiteral5.js index 97e618946a..7b83132bf0 100644 --- a/tests/baselines/reference/parserErrorRecovery_ObjectLiteral5.js +++ b/tests/baselines/reference/parserErrorRecovery_ObjectLiteral5.js @@ -4,4 +4,4 @@ return; //// [parserErrorRecovery_ObjectLiteral5.js] var v = { a: 1, - return: }; + "return": }; diff --git a/tests/baselines/reference/parserExportAsFunctionIdentifier.js b/tests/baselines/reference/parserExportAsFunctionIdentifier.js index 7ed76bb87d..62429c7685 100644 --- a/tests/baselines/reference/parserExportAsFunctionIdentifier.js +++ b/tests/baselines/reference/parserExportAsFunctionIdentifier.js @@ -9,4 +9,4 @@ var x = f.export(); //// [parserExportAsFunctionIdentifier.js] var f; -var x = f.export(); +var x = f["export"](); diff --git a/tests/baselines/reference/parserKeywordsAsIdentifierName1.js b/tests/baselines/reference/parserKeywordsAsIdentifierName1.js index c0c8c84436..a717abcc08 100644 --- a/tests/baselines/reference/parserKeywordsAsIdentifierName1.js +++ b/tests/baselines/reference/parserKeywordsAsIdentifierName1.js @@ -8,7 +8,7 @@ var big = { //// [parserKeywordsAsIdentifierName1.js] var big = { - break: 0, - super: 0, - const: 0 + "break": 0, + "super": 0, + "const": 0 }; diff --git a/tests/baselines/reference/parserShorthandPropertyAssignment2.js b/tests/baselines/reference/parserShorthandPropertyAssignment2.js index 0de0fa3829..95d2f32ffa 100644 --- a/tests/baselines/reference/parserShorthandPropertyAssignment2.js +++ b/tests/baselines/reference/parserShorthandPropertyAssignment2.js @@ -2,4 +2,4 @@ var v = { class }; //// [parserShorthandPropertyAssignment2.js] -var v = { class: }; +var v = { "class": }; diff --git a/tests/baselines/reference/parserSuperExpression3.js b/tests/baselines/reference/parserSuperExpression3.js index f311efcd0f..064353669c 100644 --- a/tests/baselines/reference/parserSuperExpression3.js +++ b/tests/baselines/reference/parserSuperExpression3.js @@ -10,7 +10,7 @@ var C = (function () { function C() { } C.prototype.M = function () { - this.super(0); + this["super"](0); }; return C; }()); diff --git a/tests/baselines/reference/prototypeOnConstructorFunctions.js b/tests/baselines/reference/prototypeOnConstructorFunctions.js index d2e5ddde92..de1fec1f7e 100644 --- a/tests/baselines/reference/prototypeOnConstructorFunctions.js +++ b/tests/baselines/reference/prototypeOnConstructorFunctions.js @@ -12,4 +12,4 @@ i.const.prototype.prop = "yo"; //// [prototypeOnConstructorFunctions.js] var i; -i.const.prototype.prop = "yo"; +i["const"].prototype.prop = "yo"; diff --git a/tests/baselines/reference/reservedWords.js b/tests/baselines/reference/reservedWords.js index 12fbcae0c6..3424c05418 100644 --- a/tests/baselines/reference/reservedWords.js +++ b/tests/baselines/reference/reservedWords.js @@ -19,16 +19,16 @@ var obj2 = { //// [reservedWords.js] var obj = { - if: 0, - debugger: 2, - break: 3, - function: 4 + "if": 0, + "debugger": 2, + "break": 3, + "function": 4 }; //This compiles. var obj2 = { - if: 0, - while: 1, - debugger: 2, - break: 3, - function: 4 + "if": 0, + "while": 1, + "debugger": 2, + "break": 3, + "function": 4 }; diff --git a/tests/baselines/reference/reservedWords2.js b/tests/baselines/reference/reservedWords2.js index a79a0564c7..d9c8105c35 100644 --- a/tests/baselines/reference/reservedWords2.js +++ b/tests/baselines/reference/reservedWords2.js @@ -27,8 +27,8 @@ function () { } throw function () { }; module; void {}; -var _a = { while: 1, return: 2 }, = _a.while, = _a.return; -var _b = { this: 1, switch: { continue: 2 } }, = _b.this, = _b.switch.continue; +var _a = { "while": 1, "return": 2 }, = _a["while"], = _a["return"]; +var _b = { "this": 1, "switch": { "continue": 2 } }, = _b["this"], = _b["switch"]["continue"]; var _c = void 0; debugger; if () diff --git a/tests/baselines/reference/super1.js b/tests/baselines/reference/super1.js index 9f1289dce5..0094f696fa 100644 --- a/tests/baselines/reference/super1.js +++ b/tests/baselines/reference/super1.js @@ -97,7 +97,7 @@ var SubSub1 = (function (_super) { return _super.apply(this, arguments) || this; } SubSub1.prototype.bar = function () { - return _super.prototype.super.foo; + return _super.prototype["super"].foo; }; return SubSub1; }(Sub1)); diff --git a/tests/baselines/reference/tsxReactEmitNesting.js b/tests/baselines/reference/tsxReactEmitNesting.js index 29e948f687..eaee315c34 100644 --- a/tests/baselines/reference/tsxReactEmitNesting.js +++ b/tests/baselines/reference/tsxReactEmitNesting.js @@ -38,21 +38,21 @@ let render = (ctrl, model) => //// [file.js] // A simple render function with nesting and control statements var render = function (ctrl, model) { - return vdom.createElement("section", { class: "todoapp" }, - vdom.createElement("header", { class: "header" }, + return vdom.createElement("section", { "class": "todoapp" }, + vdom.createElement("header", { "class": "header" }, vdom.createElement("h1", null, "todos "), - vdom.createElement("input", { class: "new-todo", autofocus: true, autocomplete: "off", placeholder: "What needs to be done?", value: model.newTodo, onKeyup: ctrl.addTodo.bind(ctrl, model) })), - vdom.createElement("section", { class: "main", style: { display: (model.todos && model.todos.length) ? "block" : "none" } }, - vdom.createElement("input", { class: "toggle-all", type: "checkbox", onChange: ctrl.toggleAll.bind(ctrl) }), - vdom.createElement("ul", { class: "todo-list" }, model.filteredTodos.map(function (todo) { - return vdom.createElement("li", { class: { todo: true, completed: todo.completed, editing: todo == model.editedTodo } }, - vdom.createElement("div", { class: "view" }, + vdom.createElement("input", { "class": "new-todo", autofocus: true, autocomplete: "off", placeholder: "What needs to be done?", value: model.newTodo, onKeyup: ctrl.addTodo.bind(ctrl, model) })), + vdom.createElement("section", { "class": "main", style: { display: (model.todos && model.todos.length) ? "block" : "none" } }, + vdom.createElement("input", { "class": "toggle-all", type: "checkbox", onChange: ctrl.toggleAll.bind(ctrl) }), + vdom.createElement("ul", { "class": "todo-list" }, model.filteredTodos.map(function (todo) { + return vdom.createElement("li", { "class": { todo: true, completed: todo.completed, editing: todo == model.editedTodo } }, + vdom.createElement("div", { "class": "view" }, (!todo.editable) ? - vdom.createElement("input", { class: "toggle", type: "checkbox" }) + vdom.createElement("input", { "class": "toggle", type: "checkbox" }) : null, vdom.createElement("label", { onDoubleClick: function () { ctrl.editTodo(todo); } }, todo.title), - vdom.createElement("button", { class: "destroy", onClick: ctrl.removeTodo.bind(ctrl, todo) }), - vdom.createElement("div", { class: "iconBorder" }, - vdom.createElement("div", { class: "icon" })))); + vdom.createElement("button", { "class": "destroy", onClick: ctrl.removeTodo.bind(ctrl, todo) }), + vdom.createElement("div", { "class": "iconBorder" }, + vdom.createElement("div", { "class": "icon" })))); })))); }; diff --git a/tests/baselines/reference/typeQueryWithReservedWords.js b/tests/baselines/reference/typeQueryWithReservedWords.js index 7561eeddb7..09c3b642a3 100644 --- a/tests/baselines/reference/typeQueryWithReservedWords.js +++ b/tests/baselines/reference/typeQueryWithReservedWords.js @@ -21,9 +21,9 @@ var Controller = (function () { } Controller.prototype.create = function () { }; - Controller.prototype.delete = function () { + Controller.prototype["delete"] = function () { }; - Controller.prototype.var = function () { + Controller.prototype["var"] = function () { }; return Controller; }()); From 86784a5eef6c9d4e5fbb68e5c7a1eedfc23ed8a8 Mon Sep 17 00:00:00 2001 From: Andrej Baran Date: Fri, 14 Oct 2016 10:54:54 +0200 Subject: [PATCH 44/80] Get rid of ES6 completely --- src/compiler/commandLineParser.ts | 4 ++-- src/compiler/types.ts | 6 ++---- tests/baselines/reference/APISample_linter.js | 4 ++-- tests/cases/compiler/APISample_linter.ts | 2 +- 4 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 553efa9e3a..545c7f3e70 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -101,7 +101,7 @@ namespace ts { "amd": ModuleKind.AMD, "system": ModuleKind.System, "umd": ModuleKind.UMD, - "es6": ModuleKind.ES6, + "es6": ModuleKind.ES2015, "es2015": ModuleKind.ES2015, }), description: Diagnostics.Specify_module_code_generation_Colon_commonjs_amd_system_umd_or_es2015, @@ -261,7 +261,7 @@ namespace ts { type: createMap({ "es3": ScriptTarget.ES3, "es5": ScriptTarget.ES5, - "es6": ScriptTarget.ES6, + "es6": ScriptTarget.ES2015, "es2015": ScriptTarget.ES2015, "es2016": ScriptTarget.ES2016, "es2017": ScriptTarget.ES2017, diff --git a/src/compiler/types.ts b/src/compiler/types.ts index ae9502c21d..68bda60823 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3019,8 +3019,7 @@ namespace ts { AMD = 2, UMD = 3, System = 4, - ES6 = 5, - ES2015 = ES6, + ES2015 = 5, } export const enum JsxEmit { @@ -3053,8 +3052,7 @@ namespace ts { export const enum ScriptTarget { ES3 = 0, ES5 = 1, - ES6 = 2, - ES2015 = ES6, + ES2015 = 2, ES2016 = 3, ES2017 = 4, Latest = ES2017, diff --git a/tests/baselines/reference/APISample_linter.js b/tests/baselines/reference/APISample_linter.js index 4e563c7cac..1421b53a00 100644 --- a/tests/baselines/reference/APISample_linter.js +++ b/tests/baselines/reference/APISample_linter.js @@ -58,7 +58,7 @@ export function delint(sourceFile: ts.SourceFile) { const fileNames: string[] = process.argv.slice(2); fileNames.forEach(fileName => { // Parse a file - let sourceFile = ts.createSourceFile(fileName, readFileSync(fileName).toString(), ts.ScriptTarget.ES6, /*setParentNodes */ true); + let sourceFile = ts.createSourceFile(fileName, readFileSync(fileName).toString(), ts.ScriptTarget.ES2015, /*setParentNodes */ true); // delint it delint(sourceFile); @@ -113,7 +113,7 @@ exports.delint = delint; var fileNames = process.argv.slice(2); fileNames.forEach(function (fileName) { // Parse a file - var sourceFile = ts.createSourceFile(fileName, readFileSync(fileName).toString(), ts.ScriptTarget.ES6, /*setParentNodes */ true); + var sourceFile = ts.createSourceFile(fileName, readFileSync(fileName).toString(), ts.ScriptTarget.ES2015, /*setParentNodes */ true); // delint it delint(sourceFile); }); diff --git a/tests/cases/compiler/APISample_linter.ts b/tests/cases/compiler/APISample_linter.ts index 89f0be7a0f..dc5e2644b4 100644 --- a/tests/cases/compiler/APISample_linter.ts +++ b/tests/cases/compiler/APISample_linter.ts @@ -61,7 +61,7 @@ export function delint(sourceFile: ts.SourceFile) { const fileNames: string[] = process.argv.slice(2); fileNames.forEach(fileName => { // Parse a file - let sourceFile = ts.createSourceFile(fileName, readFileSync(fileName).toString(), ts.ScriptTarget.ES6, /*setParentNodes */ true); + let sourceFile = ts.createSourceFile(fileName, readFileSync(fileName).toString(), ts.ScriptTarget.ES2015, /*setParentNodes */ true); // delint it delint(sourceFile); From 6417dab60bfb5f3775d82487979d940376b5d24a Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Fri, 14 Oct 2016 08:11:23 -0700 Subject: [PATCH 45/80] Merge pull request #11605 from Microsoft/vladima/convert-enums-to-const convert all enums to const enums when building protocol.d.ts --- .gitignore | 1 + scripts/buildProtocol.ts | 9 ++++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 5e4bc0af5e..f1ea04e3ef 100644 --- a/.gitignore +++ b/.gitignore @@ -41,6 +41,7 @@ tests/cases/**/*.js.map scripts/debug.bat scripts/run.bat scripts/word2md.js +scripts/buildProtocol.js scripts/ior.js scripts/buildProtocol.js scripts/*.js.map diff --git a/scripts/buildProtocol.ts b/scripts/buildProtocol.ts index 8d49262a47..55ad086815 100644 --- a/scripts/buildProtocol.ts +++ b/scripts/buildProtocol.ts @@ -42,7 +42,14 @@ class DeclarationsWalker { return; } // splice declaration in final d.ts file - const text = decl.getFullText(); + let text = decl.getFullText(); + if (decl.kind === ts.SyntaxKind.EnumDeclaration && !(decl.flags & ts.NodeFlags.Const)) { + // patch enum declaration to make them constan + const declStart = decl.getStart() - decl.getFullStart(); + const prefix = text.substring(0, declStart); + const suffix = text.substring(declStart + "enum".length, decl.getEnd() - decl.getFullStart()); + text = prefix + "const enum" + suffix; + } this.text += `${text}\n`; // recursively pull all dependencies into result dts file From 4304eab6549720cdca02376d841446372126c038 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Fri, 14 Oct 2016 11:12:47 -0700 Subject: [PATCH 46/80] JSX Text belongs with its other token friends --- src/compiler/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 638504e613..138e609729 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -45,6 +45,7 @@ namespace ts { // Literals NumericLiteral, StringLiteral, + JsxText, RegularExpressionLiteral, NoSubstitutionTemplateLiteral, // Pseudo-literals @@ -302,7 +303,6 @@ namespace ts { JsxElement, JsxSelfClosingElement, JsxOpeningElement, - JsxText, JsxClosingElement, JsxAttribute, JsxSpreadAttribute, From eb4bb4a9e0f7b1e63ac8957239b7d15cfdfd9b6e Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Fri, 14 Oct 2016 12:08:41 -0700 Subject: [PATCH 47/80] Fix-ups around formatting and assertions --- src/services/formatting/formatting.ts | 5 +++-- src/services/formatting/formattingScanner.ts | 4 ++-- src/services/formatting/rulesMap.ts | 2 +- src/services/utilities.ts | 4 ++-- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index 16108450d2..2b7d0f8d68 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -624,10 +624,11 @@ namespace ts.formatting { return inheritedIndentation; } - if (isToken(child)) { + // JSX text shouldn't affect indenting + if (isToken(child) && child.kind !== SyntaxKind.JsxText) { // if child node is a token, it does not impact indentation, proceed it using parent indentation scope rules const tokenInfo = formattingScanner.readTokenInfo(child); - Debug.assert(tokenInfo.token.end === child.end); + Debug.assert(tokenInfo.token.end === child.end, "Token end is child end"); consumeTokenAndAdvanceScanner(tokenInfo, node, parentDynamicIndentation, child); return inheritedIndentation; } diff --git a/src/services/formatting/formattingScanner.ts b/src/services/formatting/formattingScanner.ts index 7822e4a72f..2020352f86 100644 --- a/src/services/formatting/formattingScanner.ts +++ b/src/services/formatting/formattingScanner.ts @@ -31,7 +31,7 @@ namespace ts.formatting { } export function getFormattingScanner(sourceFile: SourceFile, startPos: number, endPos: number): FormattingScanner { - Debug.assert(scanner === undefined); + Debug.assert(scanner === undefined, "Scanner should be undefined"); scanner = sourceFile.languageVariant === LanguageVariant.JSX ? jsxScanner : standardScanner; scanner.setText(sourceFile.text); @@ -62,7 +62,7 @@ namespace ts.formatting { }; function advance(): void { - Debug.assert(scanner !== undefined); + Debug.assert(scanner !== undefined, "Scanner should be present"); lastTokenInfo = undefined; const isStarted = scanner.getStartPos() !== startPos; diff --git a/src/services/formatting/rulesMap.ts b/src/services/formatting/rulesMap.ts index 65c3090886..cd6f2e539d 100644 --- a/src/services/formatting/rulesMap.ts +++ b/src/services/formatting/rulesMap.ts @@ -35,8 +35,8 @@ namespace ts.formatting { } private GetRuleBucketIndex(row: number, column: number): number { + Debug.assert(row <= SyntaxKind.LastKeyword && column <= SyntaxKind.LastKeyword, "Must compute formatting context from tokens"); const rulesBucketIndex = (row * this.mapRowLength) + column; - // Debug.Assert(rulesBucketIndex < this.map.Length, "Trying to access an index outside the array."); return rulesBucketIndex; } diff --git a/src/services/utilities.ts b/src/services/utilities.ts index b58c4188e0..936abfbb2e 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -750,7 +750,7 @@ namespace ts { return find(startNode || sourceFile); function findRightmostToken(n: Node): Node { - if (isToken(n) || n.kind === SyntaxKind.JsxText) { + if (isToken(n)) { return n; } @@ -761,7 +761,7 @@ namespace ts { } function find(n: Node): Node { - if (isToken(n) || n.kind === SyntaxKind.JsxText) { + if (isToken(n)) { return n; } From a69fc67986dc87406ea4ed2f69ea2118a15e75b9 Mon Sep 17 00:00:00 2001 From: Jason Ramsay Date: Fri, 14 Oct 2016 16:04:51 -0700 Subject: [PATCH 48/80] Restrict IsGlobalCompletion to: - SourceFile - Template Expression - Statements --- src/services/completions.ts | 11 ++-- .../completionListIsGlobalCompletion.ts | 51 +++++++++++++------ 2 files changed, 43 insertions(+), 19 deletions(-) diff --git a/src/services/completions.ts b/src/services/completions.ts index c8d7c019e5..cd4d64b3b0 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -1,3 +1,5 @@ +/// + /* @internal */ namespace ts.Completions { export function getCompletionsAtPosition(host: LanguageServiceHost, typeChecker: TypeChecker, log: (message: string) => void, compilerOptions: CompilerOptions, sourceFile: SourceFile, position: number): CompletionInfo { @@ -951,7 +953,6 @@ namespace ts.Completions { if (!tryGetGlobalSymbols()) { return undefined; } - isGlobalCompletion = true; } log("getCompletionData: Semantic work: " + (timestamp() - semanticStart)); @@ -1030,7 +1031,6 @@ namespace ts.Completions { if ((jsxContainer.kind === SyntaxKind.JsxSelfClosingElement) || (jsxContainer.kind === SyntaxKind.JsxOpeningElement)) { // Cursor is inside a JSX self-closing element or opening element attrsType = typeChecker.getJsxElementAttributesType(jsxContainer); - isGlobalCompletion = false; if (attrsType) { symbols = filterJsxAttributes(typeChecker.getPropertiesOfType(attrsType), (jsxContainer).attributes); @@ -1038,7 +1038,6 @@ namespace ts.Completions { isNewIdentifierLocation = false; return true; } - } } @@ -1079,6 +1078,12 @@ namespace ts.Completions { position; const scopeNode = getScopeNode(contextToken, adjustedPosition, sourceFile) || sourceFile; + if (scopeNode) { + isGlobalCompletion = + scopeNode.kind === SyntaxKind.SourceFile || + scopeNode.kind === SyntaxKind.TemplateExpression || + isStatement(scopeNode); + } /// TODO filter meaning based on the current context const symbolMeanings = SymbolFlags.Type | SymbolFlags.Value | SymbolFlags.Namespace | SymbolFlags.Alias; diff --git a/tests/cases/fourslash/completionListIsGlobalCompletion.ts b/tests/cases/fourslash/completionListIsGlobalCompletion.ts index 73cb6bb217..3961f4fada 100644 --- a/tests/cases/fourslash/completionListIsGlobalCompletion.ts +++ b/tests/cases/fourslash/completionListIsGlobalCompletion.ts @@ -1,27 +1,38 @@ /// +// @Filename: file.ts +////export var x = 10; +////export var y = 10; +////export default class C { +////} + +// @Filename: a.ts +////import { /*1*/ } from "./file.ts"; // no globals in imports - export found + //@Filename: file.tsx -/////// // no globals in reference paths -////import { /*2*/ } from "./file.ts"; // no globals in imports -////var test = "/*3*/"; // no globals in strings -/////*4*/class A { // insert globals +/////// // no globals in reference paths +////import { /*3*/ } from "./file1.ts"; // no globals in imports - export not found +////var test = "/*4*/"; // no globals in strings +/////*5*/class A { // insert globals //// foo(): string { return ''; } ////} //// -////class /*5*/B extends A { // no globals after class keyword +////class /*6*/B extends A { // no globals after class keyword //// bar(): string { -//// /*6*/ // insert globals +//// /*7*/ // insert globals //// return ''; //// } ////} //// -////class C { // no globals at beginning of generics +////class C { // no globals at beginning of generics //// x: U; -//// y = this./*8*/x; // no globals inserted for member completions -//// /*9*/ // insert globals +//// y = this./*9*/x; // no globals inserted for member completions +//// /*10*/ // insert globals ////} -/////*10*/ // insert globals -////const y =
; +/////*11*/ // insert globals +////const y =
; // no globals in jsx attribute found +////const z =
; // no globals in jsx attribute with syntax error +////const x = `/*14*/ ${/*15*/}`; // globals only in template expression goTo.marker("1"); verify.completionListIsGlobal(false); goTo.marker("2"); @@ -29,18 +40,26 @@ verify.completionListIsGlobal(false); goTo.marker("3"); verify.completionListIsGlobal(false); goTo.marker("4"); -verify.completionListIsGlobal(true); +verify.completionListIsGlobal(false); goTo.marker("5"); -verify.completionListIsGlobal(false); -goTo.marker("6"); verify.completionListIsGlobal(true); -goTo.marker("7"); +goTo.marker("6"); verify.completionListIsGlobal(false); +goTo.marker("7"); +verify.completionListIsGlobal(true); goTo.marker("8"); verify.completionListIsGlobal(false); goTo.marker("9"); -verify.completionListIsGlobal(true); +verify.completionListIsGlobal(false); goTo.marker("10"); verify.completionListIsGlobal(true); goTo.marker("11"); +verify.completionListIsGlobal(true); +goTo.marker("12"); verify.completionListIsGlobal(false); +goTo.marker("13"); +verify.completionListIsGlobal(false); +goTo.marker("14"); +verify.completionListIsGlobal(false); +goTo.marker("15"); +verify.completionListIsGlobal(true); \ No newline at end of file From 7352e971215a07026c8f7ab7786ed2c9a900e70b Mon Sep 17 00:00:00 2001 From: Andrej Baran Date: Sat, 15 Oct 2016 01:16:11 +0200 Subject: [PATCH 49/80] Cleanup ES2017 async tests --- .../reference/asyncAliasReturnType_es2017.js | 9 --- .../asyncAliasReturnType_es2017.symbols | 11 ---- .../asyncAliasReturnType_es2017.types | 11 ---- .../reference/asyncClass_es2017.errors.txt | 8 --- .../baselines/reference/asyncClass_es2017.js | 7 -- .../asyncConstructor_es2017.errors.txt | 10 --- .../reference/asyncConstructor_es2017.js | 11 ---- .../reference/asyncDeclare_es2017.errors.txt | 7 -- .../reference/asyncDeclare_es2017.js | 4 -- .../reference/asyncEnum_es2017.errors.txt | 9 --- tests/baselines/reference/asyncEnum_es2017.js | 10 --- ...yncFunctionDeclaration15_es2017.errors.txt | 48 -------------- .../asyncFunctionDeclaration15_es2017.js | 64 ------------------- .../reference/asyncGetter_es2017.errors.txt | 13 ---- .../baselines/reference/asyncGetter_es2017.js | 11 ---- .../asyncImportedPromise_es2017.errors.txt | 13 ---- .../reference/asyncImportedPromise_es2017.js | 21 ------ .../asyncInterface_es2017.errors.txt | 8 --- .../reference/asyncInterface_es2017.js | 5 -- .../reference/asyncModule_es2017.errors.txt | 8 --- .../baselines/reference/asyncModule_es2017.js | 5 -- .../reference/asyncMultiFile_es2017.js | 11 ---- .../reference/asyncMultiFile_es2017.symbols | 8 --- .../reference/asyncMultiFile_es2017.types | 8 --- ...asyncQualifiedReturnType_es2017.errors.txt | 13 ---- .../asyncQualifiedReturnType_es2017.js | 18 ------ .../reference/asyncSetter_es2017.errors.txt | 10 --- .../baselines/reference/asyncSetter_es2017.js | 11 ---- .../baselines/reference/awaitUnion_es2017.js | 22 ------- .../reference/awaitUnion_es2017.symbols | 44 ------------- .../reference/awaitUnion_es2017.types | 49 -------------- tests/baselines/reference/es2017basicAsync.js | 4 +- .../reference/es2017basicAsync.symbols | 4 +- .../reference/es2017basicAsync.types | 4 +- tests/cases/compiler/es2017basicAsync.ts | 2 +- .../es2017/asyncAliasReturnType_es2017.ts | 6 -- .../async/es2017/asyncClass_es2017.ts | 4 -- .../async/es2017/asyncConstructor_es2017.ts | 6 -- .../async/es2017/asyncDeclare_es2017.ts | 3 - .../async/es2017/asyncEnum_es2017.ts | 5 -- .../async/es2017/asyncGetter_es2017.ts | 6 -- .../es2017/asyncImportedPromise_es2017.ts | 10 --- .../async/es2017/asyncInterface_es2017.ts | 4 -- .../async/es2017/asyncModule_es2017.ts | 4 -- .../async/es2017/asyncMultiFile_es2017.ts | 5 -- .../es2017/asyncQualifiedReturnType_es2017.ts | 9 --- .../async/es2017/asyncSetter_es2017.ts | 6 -- .../async/es2017/awaitUnion_es2017.ts | 14 ---- .../asyncFunctionDeclaration15_es2017.ts | 25 -------- 49 files changed, 7 insertions(+), 601 deletions(-) delete mode 100644 tests/baselines/reference/asyncAliasReturnType_es2017.js delete mode 100644 tests/baselines/reference/asyncAliasReturnType_es2017.symbols delete mode 100644 tests/baselines/reference/asyncAliasReturnType_es2017.types delete mode 100644 tests/baselines/reference/asyncClass_es2017.errors.txt delete mode 100644 tests/baselines/reference/asyncClass_es2017.js delete mode 100644 tests/baselines/reference/asyncConstructor_es2017.errors.txt delete mode 100644 tests/baselines/reference/asyncConstructor_es2017.js delete mode 100644 tests/baselines/reference/asyncDeclare_es2017.errors.txt delete mode 100644 tests/baselines/reference/asyncDeclare_es2017.js delete mode 100644 tests/baselines/reference/asyncEnum_es2017.errors.txt delete mode 100644 tests/baselines/reference/asyncEnum_es2017.js delete mode 100644 tests/baselines/reference/asyncFunctionDeclaration15_es2017.errors.txt delete mode 100644 tests/baselines/reference/asyncFunctionDeclaration15_es2017.js delete mode 100644 tests/baselines/reference/asyncGetter_es2017.errors.txt delete mode 100644 tests/baselines/reference/asyncGetter_es2017.js delete mode 100644 tests/baselines/reference/asyncImportedPromise_es2017.errors.txt delete mode 100644 tests/baselines/reference/asyncImportedPromise_es2017.js delete mode 100644 tests/baselines/reference/asyncInterface_es2017.errors.txt delete mode 100644 tests/baselines/reference/asyncInterface_es2017.js delete mode 100644 tests/baselines/reference/asyncModule_es2017.errors.txt delete mode 100644 tests/baselines/reference/asyncModule_es2017.js delete mode 100644 tests/baselines/reference/asyncMultiFile_es2017.js delete mode 100644 tests/baselines/reference/asyncMultiFile_es2017.symbols delete mode 100644 tests/baselines/reference/asyncMultiFile_es2017.types delete mode 100644 tests/baselines/reference/asyncQualifiedReturnType_es2017.errors.txt delete mode 100644 tests/baselines/reference/asyncQualifiedReturnType_es2017.js delete mode 100644 tests/baselines/reference/asyncSetter_es2017.errors.txt delete mode 100644 tests/baselines/reference/asyncSetter_es2017.js delete mode 100644 tests/baselines/reference/awaitUnion_es2017.js delete mode 100644 tests/baselines/reference/awaitUnion_es2017.symbols delete mode 100644 tests/baselines/reference/awaitUnion_es2017.types delete mode 100644 tests/cases/conformance/async/es2017/asyncAliasReturnType_es2017.ts delete mode 100644 tests/cases/conformance/async/es2017/asyncClass_es2017.ts delete mode 100644 tests/cases/conformance/async/es2017/asyncConstructor_es2017.ts delete mode 100644 tests/cases/conformance/async/es2017/asyncDeclare_es2017.ts delete mode 100644 tests/cases/conformance/async/es2017/asyncEnum_es2017.ts delete mode 100644 tests/cases/conformance/async/es2017/asyncGetter_es2017.ts delete mode 100644 tests/cases/conformance/async/es2017/asyncImportedPromise_es2017.ts delete mode 100644 tests/cases/conformance/async/es2017/asyncInterface_es2017.ts delete mode 100644 tests/cases/conformance/async/es2017/asyncModule_es2017.ts delete mode 100644 tests/cases/conformance/async/es2017/asyncMultiFile_es2017.ts delete mode 100644 tests/cases/conformance/async/es2017/asyncQualifiedReturnType_es2017.ts delete mode 100644 tests/cases/conformance/async/es2017/asyncSetter_es2017.ts delete mode 100644 tests/cases/conformance/async/es2017/awaitUnion_es2017.ts delete mode 100644 tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration15_es2017.ts diff --git a/tests/baselines/reference/asyncAliasReturnType_es2017.js b/tests/baselines/reference/asyncAliasReturnType_es2017.js deleted file mode 100644 index f76f2b13b4..0000000000 --- a/tests/baselines/reference/asyncAliasReturnType_es2017.js +++ /dev/null @@ -1,9 +0,0 @@ -//// [asyncAliasReturnType_es2017.ts] -type PromiseAlias = Promise; - -async function f(): PromiseAlias { -} - -//// [asyncAliasReturnType_es2017.js] -async function f() { -} diff --git a/tests/baselines/reference/asyncAliasReturnType_es2017.symbols b/tests/baselines/reference/asyncAliasReturnType_es2017.symbols deleted file mode 100644 index cc4fc5b809..0000000000 --- a/tests/baselines/reference/asyncAliasReturnType_es2017.symbols +++ /dev/null @@ -1,11 +0,0 @@ -=== tests/cases/conformance/async/es2017/asyncAliasReturnType_es2017.ts === -type PromiseAlias = Promise; ->PromiseAlias : Symbol(PromiseAlias, Decl(asyncAliasReturnType_es2017.ts, 0, 0)) ->T : Symbol(T, Decl(asyncAliasReturnType_es2017.ts, 0, 18)) ->Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) ->T : Symbol(T, Decl(asyncAliasReturnType_es2017.ts, 0, 18)) - -async function f(): PromiseAlias { ->f : Symbol(f, Decl(asyncAliasReturnType_es2017.ts, 0, 34)) ->PromiseAlias : Symbol(PromiseAlias, Decl(asyncAliasReturnType_es2017.ts, 0, 0)) -} diff --git a/tests/baselines/reference/asyncAliasReturnType_es2017.types b/tests/baselines/reference/asyncAliasReturnType_es2017.types deleted file mode 100644 index 67c521b77f..0000000000 --- a/tests/baselines/reference/asyncAliasReturnType_es2017.types +++ /dev/null @@ -1,11 +0,0 @@ -=== tests/cases/conformance/async/es2017/asyncAliasReturnType_es2017.ts === -type PromiseAlias = Promise; ->PromiseAlias : Promise ->T : T ->Promise : Promise ->T : T - -async function f(): PromiseAlias { ->f : () => Promise ->PromiseAlias : Promise -} diff --git a/tests/baselines/reference/asyncClass_es2017.errors.txt b/tests/baselines/reference/asyncClass_es2017.errors.txt deleted file mode 100644 index 37612b0b0f..0000000000 --- a/tests/baselines/reference/asyncClass_es2017.errors.txt +++ /dev/null @@ -1,8 +0,0 @@ -tests/cases/conformance/async/es2017/asyncClass_es2017.ts(1,1): error TS1042: 'async' modifier cannot be used here. - - -==== tests/cases/conformance/async/es2017/asyncClass_es2017.ts (1 errors) ==== - async class C { - ~~~~~ -!!! error TS1042: 'async' modifier cannot be used here. - } \ No newline at end of file diff --git a/tests/baselines/reference/asyncClass_es2017.js b/tests/baselines/reference/asyncClass_es2017.js deleted file mode 100644 index e619bd50b9..0000000000 --- a/tests/baselines/reference/asyncClass_es2017.js +++ /dev/null @@ -1,7 +0,0 @@ -//// [asyncClass_es2017.ts] -async class C { -} - -//// [asyncClass_es2017.js] -async class C { -} diff --git a/tests/baselines/reference/asyncConstructor_es2017.errors.txt b/tests/baselines/reference/asyncConstructor_es2017.errors.txt deleted file mode 100644 index 3b0c1b42fa..0000000000 --- a/tests/baselines/reference/asyncConstructor_es2017.errors.txt +++ /dev/null @@ -1,10 +0,0 @@ -tests/cases/conformance/async/es2017/asyncConstructor_es2017.ts(2,3): error TS1089: 'async' modifier cannot appear on a constructor declaration. - - -==== tests/cases/conformance/async/es2017/asyncConstructor_es2017.ts (1 errors) ==== - class C { - async constructor() { - ~~~~~ -!!! error TS1089: 'async' modifier cannot appear on a constructor declaration. - } - } \ No newline at end of file diff --git a/tests/baselines/reference/asyncConstructor_es2017.js b/tests/baselines/reference/asyncConstructor_es2017.js deleted file mode 100644 index 7dcd6ec694..0000000000 --- a/tests/baselines/reference/asyncConstructor_es2017.js +++ /dev/null @@ -1,11 +0,0 @@ -//// [asyncConstructor_es2017.ts] -class C { - async constructor() { - } -} - -//// [asyncConstructor_es2017.js] -class C { - async constructor() { - } -} diff --git a/tests/baselines/reference/asyncDeclare_es2017.errors.txt b/tests/baselines/reference/asyncDeclare_es2017.errors.txt deleted file mode 100644 index bb74a3865d..0000000000 --- a/tests/baselines/reference/asyncDeclare_es2017.errors.txt +++ /dev/null @@ -1,7 +0,0 @@ -tests/cases/conformance/async/es2017/asyncDeclare_es2017.ts(1,9): error TS1040: 'async' modifier cannot be used in an ambient context. - - -==== tests/cases/conformance/async/es2017/asyncDeclare_es2017.ts (1 errors) ==== - declare async function foo(): Promise; - ~~~~~ -!!! error TS1040: 'async' modifier cannot be used in an ambient context. \ No newline at end of file diff --git a/tests/baselines/reference/asyncDeclare_es2017.js b/tests/baselines/reference/asyncDeclare_es2017.js deleted file mode 100644 index 2ff588b285..0000000000 --- a/tests/baselines/reference/asyncDeclare_es2017.js +++ /dev/null @@ -1,4 +0,0 @@ -//// [asyncDeclare_es2017.ts] -declare async function foo(): Promise; - -//// [asyncDeclare_es2017.js] diff --git a/tests/baselines/reference/asyncEnum_es2017.errors.txt b/tests/baselines/reference/asyncEnum_es2017.errors.txt deleted file mode 100644 index 8e0015d0b2..0000000000 --- a/tests/baselines/reference/asyncEnum_es2017.errors.txt +++ /dev/null @@ -1,9 +0,0 @@ -tests/cases/conformance/async/es2017/asyncEnum_es2017.ts(1,1): error TS1042: 'async' modifier cannot be used here. - - -==== tests/cases/conformance/async/es2017/asyncEnum_es2017.ts (1 errors) ==== - async enum E { - ~~~~~ -!!! error TS1042: 'async' modifier cannot be used here. - Value - } \ No newline at end of file diff --git a/tests/baselines/reference/asyncEnum_es2017.js b/tests/baselines/reference/asyncEnum_es2017.js deleted file mode 100644 index df1f846c2f..0000000000 --- a/tests/baselines/reference/asyncEnum_es2017.js +++ /dev/null @@ -1,10 +0,0 @@ -//// [asyncEnum_es2017.ts] -async enum E { - Value -} - -//// [asyncEnum_es2017.js] -var E; -(function (E) { - E[E["Value"] = 0] = "Value"; -})(E || (E = {})); diff --git a/tests/baselines/reference/asyncFunctionDeclaration15_es2017.errors.txt b/tests/baselines/reference/asyncFunctionDeclaration15_es2017.errors.txt deleted file mode 100644 index efc1e2440b..0000000000 --- a/tests/baselines/reference/asyncFunctionDeclaration15_es2017.errors.txt +++ /dev/null @@ -1,48 +0,0 @@ -tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration15_es2017.ts(6,23): error TS1064: The return type of an async function or method must be the global Promise type. -tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration15_es2017.ts(7,23): error TS1064: The return type of an async function or method must be the global Promise type. -tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration15_es2017.ts(8,23): error TS1064: The return type of an async function or method must be the global Promise type. -tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration15_es2017.ts(9,23): error TS1064: The return type of an async function or method must be the global Promise type. -tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration15_es2017.ts(10,23): error TS1064: The return type of an async function or method must be the global Promise type. -tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration15_es2017.ts(17,16): error TS1059: Return expression in async function does not have a valid callable 'then' member. -tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration15_es2017.ts(23,25): error TS1058: Operand for 'await' does not have a valid callable 'then' member. - - -==== tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration15_es2017.ts (7 errors) ==== - declare class Thenable { then(): void; } - declare let a: any; - declare let obj: { then: string; }; - declare let thenable: Thenable; - async function fn1() { } // valid: Promise - async function fn2(): { } { } // error - ~~~ -!!! error TS1064: The return type of an async function or method must be the global Promise type. - async function fn3(): any { } // error - ~~~ -!!! error TS1064: The return type of an async function or method must be the global Promise type. - async function fn4(): number { } // error - ~~~~~~ -!!! error TS1064: The return type of an async function or method must be the global Promise type. - async function fn5(): PromiseLike { } // error - ~~~~~~~~~~~~~~~~~ -!!! error TS1064: The return type of an async function or method must be the global Promise type. - async function fn6(): Thenable { } // error - ~~~~~~~~ -!!! error TS1064: The return type of an async function or method must be the global Promise type. - async function fn7() { return; } // valid: Promise - async function fn8() { return 1; } // valid: Promise - async function fn9() { return null; } // valid: Promise - async function fn10() { return undefined; } // valid: Promise - async function fn11() { return a; } // valid: Promise - async function fn12() { return obj; } // valid: Promise<{ then: string; }> - async function fn13() { return thenable; } // error - ~~~~ -!!! error TS1059: Return expression in async function does not have a valid callable 'then' member. - async function fn14() { await 1; } // valid: Promise - async function fn15() { await null; } // valid: Promise - async function fn16() { await undefined; } // valid: Promise - async function fn17() { await a; } // valid: Promise - async function fn18() { await obj; } // valid: Promise - async function fn19() { await thenable; } // error - ~~~~~~~~~~~~~~ -!!! error TS1058: Operand for 'await' does not have a valid callable 'then' member. - \ No newline at end of file diff --git a/tests/baselines/reference/asyncFunctionDeclaration15_es2017.js b/tests/baselines/reference/asyncFunctionDeclaration15_es2017.js deleted file mode 100644 index 5704366025..0000000000 --- a/tests/baselines/reference/asyncFunctionDeclaration15_es2017.js +++ /dev/null @@ -1,64 +0,0 @@ -//// [asyncFunctionDeclaration15_es2017.ts] -declare class Thenable { then(): void; } -declare let a: any; -declare let obj: { then: string; }; -declare let thenable: Thenable; -async function fn1() { } // valid: Promise -async function fn2(): { } { } // error -async function fn3(): any { } // error -async function fn4(): number { } // error -async function fn5(): PromiseLike { } // error -async function fn6(): Thenable { } // error -async function fn7() { return; } // valid: Promise -async function fn8() { return 1; } // valid: Promise -async function fn9() { return null; } // valid: Promise -async function fn10() { return undefined; } // valid: Promise -async function fn11() { return a; } // valid: Promise -async function fn12() { return obj; } // valid: Promise<{ then: string; }> -async function fn13() { return thenable; } // error -async function fn14() { await 1; } // valid: Promise -async function fn15() { await null; } // valid: Promise -async function fn16() { await undefined; } // valid: Promise -async function fn17() { await a; } // valid: Promise -async function fn18() { await obj; } // valid: Promise -async function fn19() { await thenable; } // error - - -//// [asyncFunctionDeclaration15_es2017.js] -async function fn1() { } // valid: Promise -// valid: Promise -async function fn2() { } // error -// error -async function fn3() { } // error -// error -async function fn4() { } // error -// error -async function fn5() { } // error -// error -async function fn6() { } // error -// error -async function fn7() { return; } // valid: Promise -// valid: Promise -async function fn8() { return 1; } // valid: Promise -// valid: Promise -async function fn9() { return null; } // valid: Promise -// valid: Promise -async function fn10() { return undefined; } // valid: Promise -// valid: Promise -async function fn11() { return a; } // valid: Promise -// valid: Promise -async function fn12() { return obj; } // valid: Promise<{ then: string; }> -// valid: Promise<{ then: string; }> -async function fn13() { return thenable; } // error -// error -async function fn14() { await 1; } // valid: Promise -// valid: Promise -async function fn15() { await null; } // valid: Promise -// valid: Promise -async function fn16() { await undefined; } // valid: Promise -// valid: Promise -async function fn17() { await a; } // valid: Promise -// valid: Promise -async function fn18() { await obj; } // valid: Promise -// valid: Promise -async function fn19() { await thenable; } // error diff --git a/tests/baselines/reference/asyncGetter_es2017.errors.txt b/tests/baselines/reference/asyncGetter_es2017.errors.txt deleted file mode 100644 index 386e95d597..0000000000 --- a/tests/baselines/reference/asyncGetter_es2017.errors.txt +++ /dev/null @@ -1,13 +0,0 @@ -tests/cases/conformance/async/es2017/asyncGetter_es2017.ts(2,3): error TS1042: 'async' modifier cannot be used here. -tests/cases/conformance/async/es2017/asyncGetter_es2017.ts(2,13): error TS2378: A 'get' accessor must return a value. - - -==== tests/cases/conformance/async/es2017/asyncGetter_es2017.ts (2 errors) ==== - class C { - async get foo() { - ~~~~~ -!!! error TS1042: 'async' modifier cannot be used here. - ~~~ -!!! error TS2378: A 'get' accessor must return a value. - } - } \ No newline at end of file diff --git a/tests/baselines/reference/asyncGetter_es2017.js b/tests/baselines/reference/asyncGetter_es2017.js deleted file mode 100644 index ad8fa347cb..0000000000 --- a/tests/baselines/reference/asyncGetter_es2017.js +++ /dev/null @@ -1,11 +0,0 @@ -//// [asyncGetter_es2017.ts] -class C { - async get foo() { - } -} - -//// [asyncGetter_es2017.js] -class C { - async get foo() { - } -} diff --git a/tests/baselines/reference/asyncImportedPromise_es2017.errors.txt b/tests/baselines/reference/asyncImportedPromise_es2017.errors.txt deleted file mode 100644 index a0348b2e69..0000000000 --- a/tests/baselines/reference/asyncImportedPromise_es2017.errors.txt +++ /dev/null @@ -1,13 +0,0 @@ -tests/cases/conformance/async/es2017/test.ts(3,25): error TS1064: The return type of an async function or method must be the global Promise type. - - -==== tests/cases/conformance/async/es2017/task.ts (0 errors) ==== - export class Task extends Promise { } - -==== tests/cases/conformance/async/es2017/test.ts (1 errors) ==== - import { Task } from "./task"; - class Test { - async example(): Task { return; } - ~~~~~~~ -!!! error TS1064: The return type of an async function or method must be the global Promise type. - } \ No newline at end of file diff --git a/tests/baselines/reference/asyncImportedPromise_es2017.js b/tests/baselines/reference/asyncImportedPromise_es2017.js deleted file mode 100644 index a48c58c170..0000000000 --- a/tests/baselines/reference/asyncImportedPromise_es2017.js +++ /dev/null @@ -1,21 +0,0 @@ -//// [tests/cases/conformance/async/es2017/asyncImportedPromise_es2017.ts] //// - -//// [task.ts] -export class Task extends Promise { } - -//// [test.ts] -import { Task } from "./task"; -class Test { - async example(): Task { return; } -} - -//// [task.js] -"use strict"; -class Task extends Promise { -} -exports.Task = Task; -//// [test.js] -"use strict"; -class Test { - async example() { return; } -} diff --git a/tests/baselines/reference/asyncInterface_es2017.errors.txt b/tests/baselines/reference/asyncInterface_es2017.errors.txt deleted file mode 100644 index dfbc878979..0000000000 --- a/tests/baselines/reference/asyncInterface_es2017.errors.txt +++ /dev/null @@ -1,8 +0,0 @@ -tests/cases/conformance/async/es2017/asyncInterface_es2017.ts(1,1): error TS1042: 'async' modifier cannot be used here. - - -==== tests/cases/conformance/async/es2017/asyncInterface_es2017.ts (1 errors) ==== - async interface I { - ~~~~~ -!!! error TS1042: 'async' modifier cannot be used here. - } \ No newline at end of file diff --git a/tests/baselines/reference/asyncInterface_es2017.js b/tests/baselines/reference/asyncInterface_es2017.js deleted file mode 100644 index 4d89738953..0000000000 --- a/tests/baselines/reference/asyncInterface_es2017.js +++ /dev/null @@ -1,5 +0,0 @@ -//// [asyncInterface_es2017.ts] -async interface I { -} - -//// [asyncInterface_es2017.js] diff --git a/tests/baselines/reference/asyncModule_es2017.errors.txt b/tests/baselines/reference/asyncModule_es2017.errors.txt deleted file mode 100644 index 8b6a4c3dc6..0000000000 --- a/tests/baselines/reference/asyncModule_es2017.errors.txt +++ /dev/null @@ -1,8 +0,0 @@ -tests/cases/conformance/async/es2017/asyncModule_es2017.ts(1,1): error TS1042: 'async' modifier cannot be used here. - - -==== tests/cases/conformance/async/es2017/asyncModule_es2017.ts (1 errors) ==== - async module M { - ~~~~~ -!!! error TS1042: 'async' modifier cannot be used here. - } \ No newline at end of file diff --git a/tests/baselines/reference/asyncModule_es2017.js b/tests/baselines/reference/asyncModule_es2017.js deleted file mode 100644 index fe3e17d5e7..0000000000 --- a/tests/baselines/reference/asyncModule_es2017.js +++ /dev/null @@ -1,5 +0,0 @@ -//// [asyncModule_es2017.ts] -async module M { -} - -//// [asyncModule_es2017.js] diff --git a/tests/baselines/reference/asyncMultiFile_es2017.js b/tests/baselines/reference/asyncMultiFile_es2017.js deleted file mode 100644 index 804a58e4b4..0000000000 --- a/tests/baselines/reference/asyncMultiFile_es2017.js +++ /dev/null @@ -1,11 +0,0 @@ -//// [tests/cases/conformance/async/es2017/asyncMultiFile_es2017.ts] //// - -//// [a.ts] -async function f() {} -//// [b.ts] -function g() { } - -//// [a.js] -async function f() { } -//// [b.js] -function g() { } diff --git a/tests/baselines/reference/asyncMultiFile_es2017.symbols b/tests/baselines/reference/asyncMultiFile_es2017.symbols deleted file mode 100644 index 9d8ff6dbe8..0000000000 --- a/tests/baselines/reference/asyncMultiFile_es2017.symbols +++ /dev/null @@ -1,8 +0,0 @@ -=== tests/cases/conformance/async/es2017/a.ts === -async function f() {} ->f : Symbol(f, Decl(a.ts, 0, 0)) - -=== tests/cases/conformance/async/es2017/b.ts === -function g() { } ->g : Symbol(g, Decl(b.ts, 0, 0)) - diff --git a/tests/baselines/reference/asyncMultiFile_es2017.types b/tests/baselines/reference/asyncMultiFile_es2017.types deleted file mode 100644 index e1f8da34c9..0000000000 --- a/tests/baselines/reference/asyncMultiFile_es2017.types +++ /dev/null @@ -1,8 +0,0 @@ -=== tests/cases/conformance/async/es2017/a.ts === -async function f() {} ->f : () => Promise - -=== tests/cases/conformance/async/es2017/b.ts === -function g() { } ->g : () => void - diff --git a/tests/baselines/reference/asyncQualifiedReturnType_es2017.errors.txt b/tests/baselines/reference/asyncQualifiedReturnType_es2017.errors.txt deleted file mode 100644 index b9027c3653..0000000000 --- a/tests/baselines/reference/asyncQualifiedReturnType_es2017.errors.txt +++ /dev/null @@ -1,13 +0,0 @@ -tests/cases/conformance/async/es2017/asyncQualifiedReturnType_es2017.ts(6,21): error TS1064: The return type of an async function or method must be the global Promise type. - - -==== tests/cases/conformance/async/es2017/asyncQualifiedReturnType_es2017.ts (1 errors) ==== - namespace X { - export class MyPromise extends Promise { - } - } - - async function f(): X.MyPromise { - ~~~~~~~~~~~~~~~~~ -!!! error TS1064: The return type of an async function or method must be the global Promise type. - } \ No newline at end of file diff --git a/tests/baselines/reference/asyncQualifiedReturnType_es2017.js b/tests/baselines/reference/asyncQualifiedReturnType_es2017.js deleted file mode 100644 index 164a4fef61..0000000000 --- a/tests/baselines/reference/asyncQualifiedReturnType_es2017.js +++ /dev/null @@ -1,18 +0,0 @@ -//// [asyncQualifiedReturnType_es2017.ts] -namespace X { - export class MyPromise extends Promise { - } -} - -async function f(): X.MyPromise { -} - -//// [asyncQualifiedReturnType_es2017.js] -var X; -(function (X) { - class MyPromise extends Promise { - } - X.MyPromise = MyPromise; -})(X || (X = {})); -async function f() { -} diff --git a/tests/baselines/reference/asyncSetter_es2017.errors.txt b/tests/baselines/reference/asyncSetter_es2017.errors.txt deleted file mode 100644 index 0acd8538f2..0000000000 --- a/tests/baselines/reference/asyncSetter_es2017.errors.txt +++ /dev/null @@ -1,10 +0,0 @@ -tests/cases/conformance/async/es2017/asyncSetter_es2017.ts(2,3): error TS1042: 'async' modifier cannot be used here. - - -==== tests/cases/conformance/async/es2017/asyncSetter_es2017.ts (1 errors) ==== - class C { - async set foo(value) { - ~~~~~ -!!! error TS1042: 'async' modifier cannot be used here. - } - } \ No newline at end of file diff --git a/tests/baselines/reference/asyncSetter_es2017.js b/tests/baselines/reference/asyncSetter_es2017.js deleted file mode 100644 index 8260c5232a..0000000000 --- a/tests/baselines/reference/asyncSetter_es2017.js +++ /dev/null @@ -1,11 +0,0 @@ -//// [asyncSetter_es2017.ts] -class C { - async set foo(value) { - } -} - -//// [asyncSetter_es2017.js] -class C { - async set foo(value) { - } -} diff --git a/tests/baselines/reference/awaitUnion_es2017.js b/tests/baselines/reference/awaitUnion_es2017.js deleted file mode 100644 index 12f8b95a65..0000000000 --- a/tests/baselines/reference/awaitUnion_es2017.js +++ /dev/null @@ -1,22 +0,0 @@ -//// [awaitUnion_es2017.ts] -declare let a: number | string; -declare let b: PromiseLike | PromiseLike; -declare let c: PromiseLike; -declare let d: number | PromiseLike; -declare let e: number | PromiseLike; -async function f() { - let await_a = await a; - let await_b = await b; - let await_c = await c; - let await_d = await d; - let await_e = await e; -} - -//// [awaitUnion_es2017.js] -async function f() { - let await_a = await a; - let await_b = await b; - let await_c = await c; - let await_d = await d; - let await_e = await e; -} diff --git a/tests/baselines/reference/awaitUnion_es2017.symbols b/tests/baselines/reference/awaitUnion_es2017.symbols deleted file mode 100644 index e70abce4f0..0000000000 --- a/tests/baselines/reference/awaitUnion_es2017.symbols +++ /dev/null @@ -1,44 +0,0 @@ -=== tests/cases/conformance/async/es2017/awaitUnion_es2017.ts === -declare let a: number | string; ->a : Symbol(a, Decl(awaitUnion_es2017.ts, 0, 11)) - -declare let b: PromiseLike | PromiseLike; ->b : Symbol(b, Decl(awaitUnion_es2017.ts, 1, 11)) ->PromiseLike : Symbol(PromiseLike, Decl(lib.es5.d.ts, --, --)) ->PromiseLike : Symbol(PromiseLike, Decl(lib.es5.d.ts, --, --)) - -declare let c: PromiseLike; ->c : Symbol(c, Decl(awaitUnion_es2017.ts, 2, 11)) ->PromiseLike : Symbol(PromiseLike, Decl(lib.es5.d.ts, --, --)) - -declare let d: number | PromiseLike; ->d : Symbol(d, Decl(awaitUnion_es2017.ts, 3, 11)) ->PromiseLike : Symbol(PromiseLike, Decl(lib.es5.d.ts, --, --)) - -declare let e: number | PromiseLike; ->e : Symbol(e, Decl(awaitUnion_es2017.ts, 4, 11)) ->PromiseLike : Symbol(PromiseLike, Decl(lib.es5.d.ts, --, --)) - -async function f() { ->f : Symbol(f, Decl(awaitUnion_es2017.ts, 4, 53)) - - let await_a = await a; ->await_a : Symbol(await_a, Decl(awaitUnion_es2017.ts, 6, 4)) ->a : Symbol(a, Decl(awaitUnion_es2017.ts, 0, 11)) - - let await_b = await b; ->await_b : Symbol(await_b, Decl(awaitUnion_es2017.ts, 7, 4)) ->b : Symbol(b, Decl(awaitUnion_es2017.ts, 1, 11)) - - let await_c = await c; ->await_c : Symbol(await_c, Decl(awaitUnion_es2017.ts, 8, 4)) ->c : Symbol(c, Decl(awaitUnion_es2017.ts, 2, 11)) - - let await_d = await d; ->await_d : Symbol(await_d, Decl(awaitUnion_es2017.ts, 9, 4)) ->d : Symbol(d, Decl(awaitUnion_es2017.ts, 3, 11)) - - let await_e = await e; ->await_e : Symbol(await_e, Decl(awaitUnion_es2017.ts, 10, 4)) ->e : Symbol(e, Decl(awaitUnion_es2017.ts, 4, 11)) -} diff --git a/tests/baselines/reference/awaitUnion_es2017.types b/tests/baselines/reference/awaitUnion_es2017.types deleted file mode 100644 index 58f8a4ec4b..0000000000 --- a/tests/baselines/reference/awaitUnion_es2017.types +++ /dev/null @@ -1,49 +0,0 @@ -=== tests/cases/conformance/async/es2017/awaitUnion_es2017.ts === -declare let a: number | string; ->a : string | number - -declare let b: PromiseLike | PromiseLike; ->b : PromiseLike | PromiseLike ->PromiseLike : PromiseLike ->PromiseLike : PromiseLike - -declare let c: PromiseLike; ->c : PromiseLike ->PromiseLike : PromiseLike - -declare let d: number | PromiseLike; ->d : number | PromiseLike ->PromiseLike : PromiseLike - -declare let e: number | PromiseLike; ->e : number | PromiseLike ->PromiseLike : PromiseLike - -async function f() { ->f : () => Promise - - let await_a = await a; ->await_a : string | number ->await a : string | number ->a : string | number - - let await_b = await b; ->await_b : string | number ->await b : string | number ->b : PromiseLike | PromiseLike - - let await_c = await c; ->await_c : string | number ->await c : string | number ->c : PromiseLike - - let await_d = await d; ->await_d : string | number ->await d : string | number ->d : number | PromiseLike - - let await_e = await e; ->await_e : string | number ->await e : string | number ->e : number | PromiseLike -} diff --git a/tests/baselines/reference/es2017basicAsync.js b/tests/baselines/reference/es2017basicAsync.js index b19eaa4b0b..d0443c1899 100644 --- a/tests/baselines/reference/es2017basicAsync.js +++ b/tests/baselines/reference/es2017basicAsync.js @@ -8,7 +8,7 @@ async function asyncFunc() { await 0; } -const asycnArrowFunc = async (): Promise => { +const asyncArrowFunc = async (): Promise => { await 0; } @@ -54,7 +54,7 @@ async () => { async function asyncFunc() { await 0; } -const asycnArrowFunc = async () => { +const asyncArrowFunc = async () => { await 0; }; async function asyncIIFE() { diff --git a/tests/baselines/reference/es2017basicAsync.symbols b/tests/baselines/reference/es2017basicAsync.symbols index 75f4d2cfa7..d79faf1502 100644 --- a/tests/baselines/reference/es2017basicAsync.symbols +++ b/tests/baselines/reference/es2017basicAsync.symbols @@ -12,8 +12,8 @@ async function asyncFunc() { await 0; } -const asycnArrowFunc = async (): Promise => { ->asycnArrowFunc : Symbol(asycnArrowFunc, Decl(es2017basicAsync.ts, 9, 5)) +const asyncArrowFunc = async (): Promise => { +>asyncArrowFunc : Symbol(asyncArrowFunc, Decl(es2017basicAsync.ts, 9, 5)) >Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) await 0; diff --git a/tests/baselines/reference/es2017basicAsync.types b/tests/baselines/reference/es2017basicAsync.types index 71c2dbe50f..30d19cb4df 100644 --- a/tests/baselines/reference/es2017basicAsync.types +++ b/tests/baselines/reference/es2017basicAsync.types @@ -17,8 +17,8 @@ async function asyncFunc() { >0 : 0 } -const asycnArrowFunc = async (): Promise => { ->asycnArrowFunc : () => Promise +const asyncArrowFunc = async (): Promise => { +>asyncArrowFunc : () => Promise >async (): Promise => { await 0;} : () => Promise >Promise : Promise diff --git a/tests/cases/compiler/es2017basicAsync.ts b/tests/cases/compiler/es2017basicAsync.ts index b13a5d29bc..b08ee6a18a 100644 --- a/tests/cases/compiler/es2017basicAsync.ts +++ b/tests/cases/compiler/es2017basicAsync.ts @@ -10,7 +10,7 @@ async function asyncFunc() { await 0; } -const asycnArrowFunc = async (): Promise => { +const asyncArrowFunc = async (): Promise => { await 0; } diff --git a/tests/cases/conformance/async/es2017/asyncAliasReturnType_es2017.ts b/tests/cases/conformance/async/es2017/asyncAliasReturnType_es2017.ts deleted file mode 100644 index 87bbc42e16..0000000000 --- a/tests/cases/conformance/async/es2017/asyncAliasReturnType_es2017.ts +++ /dev/null @@ -1,6 +0,0 @@ -// @target: es2017 -// @noEmitHelpers: true -type PromiseAlias = Promise; - -async function f(): PromiseAlias { -} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/asyncClass_es2017.ts b/tests/cases/conformance/async/es2017/asyncClass_es2017.ts deleted file mode 100644 index 78746c972d..0000000000 --- a/tests/cases/conformance/async/es2017/asyncClass_es2017.ts +++ /dev/null @@ -1,4 +0,0 @@ -// @target: es2017 -// @noEmitHelpers: true -async class C { -} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/asyncConstructor_es2017.ts b/tests/cases/conformance/async/es2017/asyncConstructor_es2017.ts deleted file mode 100644 index 874c0b9923..0000000000 --- a/tests/cases/conformance/async/es2017/asyncConstructor_es2017.ts +++ /dev/null @@ -1,6 +0,0 @@ -// @target: es2017 -// @noEmitHelpers: true -class C { - async constructor() { - } -} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/asyncDeclare_es2017.ts b/tests/cases/conformance/async/es2017/asyncDeclare_es2017.ts deleted file mode 100644 index d7fd4888fe..0000000000 --- a/tests/cases/conformance/async/es2017/asyncDeclare_es2017.ts +++ /dev/null @@ -1,3 +0,0 @@ -// @target: es2017 -// @noEmitHelpers: true -declare async function foo(): Promise; \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/asyncEnum_es2017.ts b/tests/cases/conformance/async/es2017/asyncEnum_es2017.ts deleted file mode 100644 index dc995206e8..0000000000 --- a/tests/cases/conformance/async/es2017/asyncEnum_es2017.ts +++ /dev/null @@ -1,5 +0,0 @@ -// @target: es2017 -// @noEmitHelpers: true -async enum E { - Value -} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/asyncGetter_es2017.ts b/tests/cases/conformance/async/es2017/asyncGetter_es2017.ts deleted file mode 100644 index 340c33138c..0000000000 --- a/tests/cases/conformance/async/es2017/asyncGetter_es2017.ts +++ /dev/null @@ -1,6 +0,0 @@ -// @target: es2017 -// @noEmitHelpers: true -class C { - async get foo() { - } -} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/asyncImportedPromise_es2017.ts b/tests/cases/conformance/async/es2017/asyncImportedPromise_es2017.ts deleted file mode 100644 index 81f5b690ed..0000000000 --- a/tests/cases/conformance/async/es2017/asyncImportedPromise_es2017.ts +++ /dev/null @@ -1,10 +0,0 @@ -// @target: es2017 -// @module: commonjs -// @filename: task.ts -export class Task extends Promise { } - -// @filename: test.ts -import { Task } from "./task"; -class Test { - async example(): Task { return; } -} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/asyncInterface_es2017.ts b/tests/cases/conformance/async/es2017/asyncInterface_es2017.ts deleted file mode 100644 index 252730f9ff..0000000000 --- a/tests/cases/conformance/async/es2017/asyncInterface_es2017.ts +++ /dev/null @@ -1,4 +0,0 @@ -// @target: es2017 -// @noEmitHelpers: true -async interface I { -} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/asyncModule_es2017.ts b/tests/cases/conformance/async/es2017/asyncModule_es2017.ts deleted file mode 100644 index 7c577e27fb..0000000000 --- a/tests/cases/conformance/async/es2017/asyncModule_es2017.ts +++ /dev/null @@ -1,4 +0,0 @@ -// @target: es2017 -// @noEmitHelpers: true -async module M { -} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/asyncMultiFile_es2017.ts b/tests/cases/conformance/async/es2017/asyncMultiFile_es2017.ts deleted file mode 100644 index 920bdfb8bd..0000000000 --- a/tests/cases/conformance/async/es2017/asyncMultiFile_es2017.ts +++ /dev/null @@ -1,5 +0,0 @@ -// @target: es2017 -// @filename: a.ts -async function f() {} -// @filename: b.ts -function g() { } \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/asyncQualifiedReturnType_es2017.ts b/tests/cases/conformance/async/es2017/asyncQualifiedReturnType_es2017.ts deleted file mode 100644 index 95695168ce..0000000000 --- a/tests/cases/conformance/async/es2017/asyncQualifiedReturnType_es2017.ts +++ /dev/null @@ -1,9 +0,0 @@ -// @target: es2017 -// @noEmitHelpers: true -namespace X { - export class MyPromise extends Promise { - } -} - -async function f(): X.MyPromise { -} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/asyncSetter_es2017.ts b/tests/cases/conformance/async/es2017/asyncSetter_es2017.ts deleted file mode 100644 index 658c07d42e..0000000000 --- a/tests/cases/conformance/async/es2017/asyncSetter_es2017.ts +++ /dev/null @@ -1,6 +0,0 @@ -// @target: es2017 -// @noEmitHelpers: true -class C { - async set foo(value) { - } -} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/awaitUnion_es2017.ts b/tests/cases/conformance/async/es2017/awaitUnion_es2017.ts deleted file mode 100644 index 493aa838ff..0000000000 --- a/tests/cases/conformance/async/es2017/awaitUnion_es2017.ts +++ /dev/null @@ -1,14 +0,0 @@ -// @target: es2017 -// @noEmitHelpers: true -declare let a: number | string; -declare let b: PromiseLike | PromiseLike; -declare let c: PromiseLike; -declare let d: number | PromiseLike; -declare let e: number | PromiseLike; -async function f() { - let await_a = await a; - let await_b = await b; - let await_c = await c; - let await_d = await d; - let await_e = await e; -} \ No newline at end of file diff --git a/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration15_es2017.ts b/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration15_es2017.ts deleted file mode 100644 index 2585dc666f..0000000000 --- a/tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration15_es2017.ts +++ /dev/null @@ -1,25 +0,0 @@ -// @target: es2017 -// @noEmitHelpers: true -declare class Thenable { then(): void; } -declare let a: any; -declare let obj: { then: string; }; -declare let thenable: Thenable; -async function fn1() { } // valid: Promise -async function fn2(): { } { } // error -async function fn3(): any { } // error -async function fn4(): number { } // error -async function fn5(): PromiseLike { } // error -async function fn6(): Thenable { } // error -async function fn7() { return; } // valid: Promise -async function fn8() { return 1; } // valid: Promise -async function fn9() { return null; } // valid: Promise -async function fn10() { return undefined; } // valid: Promise -async function fn11() { return a; } // valid: Promise -async function fn12() { return obj; } // valid: Promise<{ then: string; }> -async function fn13() { return thenable; } // error -async function fn14() { await 1; } // valid: Promise -async function fn15() { await null; } // valid: Promise -async function fn16() { await undefined; } // valid: Promise -async function fn17() { await a; } // valid: Promise -async function fn18() { await obj; } // valid: Promise -async function fn19() { await thenable; } // error From 980a8947875fdf78231ea546767dee47393fabfa Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Fri, 14 Oct 2016 18:10:34 -0700 Subject: [PATCH 50/80] Fix emit issue regarding null/undefined in type annotations --- src/compiler/binder.ts | 113 +++++++++++------- src/compiler/emitter.ts | 19 ++- src/compiler/transformers/es6.ts | 2 + src/compiler/transformers/ts.ts | 46 ++++++- src/compiler/types.ts | 2 + .../reference/constructorArgsErrors1.js | 2 +- .../reference/constructorArgsErrors5.js | 2 +- .../parserErrorRecovery_ParameterList6.js | 1 - .../transformsElideNullUndefinedType.js | 54 +++++++++ .../transformsElideNullUndefinedType.symbols | 72 +++++++++++ .../transformsElideNullUndefinedType.types | 94 +++++++++++++++ .../reference/typeGuardFunctionErrors.js | 2 - .../transformsElideNullUndefinedType.ts | 32 +++++ 13 files changed, 392 insertions(+), 49 deletions(-) create mode 100644 tests/baselines/reference/transformsElideNullUndefinedType.js create mode 100644 tests/baselines/reference/transformsElideNullUndefinedType.symbols create mode 100644 tests/baselines/reference/transformsElideNullUndefinedType.types create mode 100644 tests/cases/compiler/transformsElideNullUndefinedType.ts diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index b9e26e4f38..4f01607289 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -2330,6 +2330,9 @@ namespace ts { case SyntaxKind.CallExpression: return computeCallExpression(node, subtreeFlags); + case SyntaxKind.NewExpression: + return computeNewExpression(node, subtreeFlags); + case SyntaxKind.ModuleDeclaration: return computeModuleDeclaration(node, subtreeFlags); @@ -2407,6 +2410,10 @@ namespace ts { const expression = node.expression; const expressionKind = expression.kind; + if (node.typeArguments) { + transformFlags |= TransformFlags.AssertTypeScript; + } + if (subtreeFlags & TransformFlags.ContainsSpreadElementExpression || isSuperOrSuperProperty(expression, expressionKind)) { // If the this node contains a SpreadElementExpression, or is a super call, then it is an ES6 @@ -2433,6 +2440,21 @@ namespace ts { return false; } + function computeNewExpression(node: NewExpression, subtreeFlags: TransformFlags) { + let transformFlags = subtreeFlags; + if (node.typeArguments) { + transformFlags |= TransformFlags.AssertTypeScript; + } + if (subtreeFlags & TransformFlags.ContainsSpreadElementExpression) { + // If the this node contains a SpreadElementExpression then it is an ES6 + // node. + transformFlags |= TransformFlags.AssertES6; + } + node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; + return transformFlags & ~TransformFlags.ArrayLiteralOrCallOrNewExcludes; + } + + function computeBinaryExpression(node: BinaryExpression, subtreeFlags: TransformFlags) { let transformFlags = subtreeFlags; const operatorTokenKind = node.operatorToken.kind; @@ -2461,13 +2483,12 @@ namespace ts { const initializer = node.initializer; const dotDotDotToken = node.dotDotDotToken; - // If the parameter has a question token, then it is TypeScript syntax. - if (node.questionToken) { - transformFlags |= TransformFlags.AssertTypeScript; - } - - // If the parameter's name is 'this', then it is TypeScript syntax. - if (subtreeFlags & TransformFlags.ContainsDecorators || isThisIdentifier(name)) { + // The '?' token, type annotations, decorators, and 'this' parameters are TypeSCript + // syntax. + if (node.questionToken + || node.type + || subtreeFlags & TransformFlags.ContainsDecorators + || isThisIdentifier(name)) { transformFlags |= TransformFlags.AssertTypeScript; } @@ -2526,7 +2547,8 @@ namespace ts { // TypeScript syntax. // An exported declaration may be TypeScript syntax. if ((subtreeFlags & TransformFlags.TypeScriptClassSyntaxMask) - || (modifierFlags & ModifierFlags.Export)) { + || (modifierFlags & ModifierFlags.Export) + || node.typeParameters) { transformFlags |= TransformFlags.AssertTypeScript; } @@ -2547,7 +2569,8 @@ namespace ts { // A class with a parameter property assignment, property initializer, or decorator is // TypeScript syntax. - if (subtreeFlags & TransformFlags.TypeScriptClassSyntaxMask) { + if (subtreeFlags & TransformFlags.TypeScriptClassSyntaxMask + || node.typeParameters) { transformFlags |= TransformFlags.AssertTypeScript; } @@ -2601,10 +2624,10 @@ namespace ts { function computeConstructor(node: ConstructorDeclaration, subtreeFlags: TransformFlags) { let transformFlags = subtreeFlags; - const body = node.body; - if (body === undefined) { - // An overload constructor is TypeScript syntax. + // TypeScript-specific modifiers and overloads are TypeScript syntax + if (hasModifier(node, ModifierFlags.TypeScriptModifier) + || !node.body) { transformFlags |= TransformFlags.AssertTypeScript; } @@ -2615,22 +2638,19 @@ namespace ts { function computeMethod(node: MethodDeclaration, subtreeFlags: TransformFlags) { // A MethodDeclaration is ES6 syntax. let transformFlags = subtreeFlags | TransformFlags.AssertES6; - const modifierFlags = getModifierFlags(node); - const body = node.body; - const typeParameters = node.typeParameters; - const asteriskToken = node.asteriskToken; - // A MethodDeclaration is TypeScript syntax if it is either async, abstract, overloaded, - // generic, or has a decorator. - if (!body - || typeParameters - || (modifierFlags & (ModifierFlags.Async | ModifierFlags.Abstract)) - || (subtreeFlags & TransformFlags.ContainsDecorators)) { + // Decorators, TypeScript-specific modifiers, type parameters, type annotations, and + // overloads are TypeScript syntax. + if (node.decorators + || hasModifier(node, ModifierFlags.TypeScriptModifier) + || node.typeParameters + || node.type + || !node.body) { transformFlags |= TransformFlags.AssertTypeScript; } // Currently, we only support generators that were originally async function bodies. - if (asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) { + if (node.asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) { transformFlags |= TransformFlags.AssertGenerator; } @@ -2640,14 +2660,13 @@ namespace ts { function computeAccessor(node: AccessorDeclaration, subtreeFlags: TransformFlags) { let transformFlags = subtreeFlags; - const modifierFlags = getModifierFlags(node); - const body = node.body; - // A MethodDeclaration is TypeScript syntax if it is either async, abstract, overloaded, - // generic, or has a decorator. - if (!body - || (modifierFlags & (ModifierFlags.Async | ModifierFlags.Abstract)) - || (subtreeFlags & TransformFlags.ContainsDecorators)) { + // Decorators, TypeScript-specific modifiers, type annotations, and overloads are + // TypeScript syntax. + if (node.decorators + || hasModifier(node, ModifierFlags.TypeScriptModifier) + || node.type + || !node.body) { transformFlags |= TransformFlags.AssertTypeScript; } @@ -2673,7 +2692,6 @@ namespace ts { let transformFlags: TransformFlags; const modifierFlags = getModifierFlags(node); const body = node.body; - const asteriskToken = node.asteriskToken; if (!body || (modifierFlags & ModifierFlags.Ambient)) { // An ambient declaration is TypeScript syntax. @@ -2688,8 +2706,11 @@ namespace ts { transformFlags |= TransformFlags.AssertTypeScript | TransformFlags.AssertES6; } - // If a FunctionDeclaration is async, then it is TypeScript syntax. - if (modifierFlags & ModifierFlags.Async) { + // TypeScript-specific modifiers, type parameters, and type annotations are TypeScript + // syntax. + if (modifierFlags & ModifierFlags.TypeScriptModifier + || node.typeParameters + || node.type) { transformFlags |= TransformFlags.AssertTypeScript; } @@ -2705,7 +2726,7 @@ namespace ts { // down-level generator. // Currently we do not support transforming any other generator fucntions // down level. - if (asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) { + if (node.asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) { transformFlags |= TransformFlags.AssertGenerator; } } @@ -2716,11 +2737,12 @@ namespace ts { function computeFunctionExpression(node: FunctionExpression, subtreeFlags: TransformFlags) { let transformFlags = subtreeFlags; - const modifierFlags = getModifierFlags(node); - const asteriskToken = node.asteriskToken; - // An async function expression is TypeScript syntax. - if (modifierFlags & ModifierFlags.Async) { + // TypeScript-specific modifiers, type parameters, and type annotations are TypeScript + // syntax. + if (hasModifier(node, ModifierFlags.TypeScriptModifier) + || node.typeParameters + || node.type) { transformFlags |= TransformFlags.AssertTypeScript; } @@ -2736,7 +2758,7 @@ namespace ts { // down-level generator. // Currently we do not support transforming any other generator fucntions // down level. - if (asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) { + if (node.asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) { transformFlags |= TransformFlags.AssertGenerator; } @@ -2747,10 +2769,12 @@ namespace ts { function computeArrowFunction(node: ArrowFunction, subtreeFlags: TransformFlags) { // An ArrowFunction is ES6 syntax, and excludes markers that should not escape the scope of an ArrowFunction. let transformFlags = subtreeFlags | TransformFlags.AssertES6; - const modifierFlags = getModifierFlags(node); - // An async arrow function is TypeScript syntax. - if (modifierFlags & ModifierFlags.Async) { + // TypeScript-specific modifiers, type parameters, and type annotations are TypeScript + // syntax. + if (hasModifier(node, ModifierFlags.TypeScriptModifier) + || node.typeParameters + || node.type) { transformFlags |= TransformFlags.AssertTypeScript; } @@ -2787,6 +2811,11 @@ namespace ts { transformFlags |= TransformFlags.AssertES6 | TransformFlags.ContainsBindingPattern; } + // Type annotations are TypeScript syntax. + if (node.type) { + transformFlags |= TransformFlags.AssertTypeScript; + } + node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; return transformFlags & ~TransformFlags.NodeExcludes; } diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 270fb0ca62..a77096618d 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -504,15 +504,29 @@ const _super = (function (geti, seti) { // Contextual keywords case SyntaxKind.AbstractKeyword: + case SyntaxKind.AsKeyword: case SyntaxKind.AnyKeyword: case SyntaxKind.AsyncKeyword: + case SyntaxKind.AwaitKeyword: case SyntaxKind.BooleanKeyword: + case SyntaxKind.ConstructorKeyword: case SyntaxKind.DeclareKeyword: - case SyntaxKind.NumberKeyword: + case SyntaxKind.GetKeyword: + case SyntaxKind.IsKeyword: + case SyntaxKind.ModuleKeyword: + case SyntaxKind.NamespaceKeyword: + case SyntaxKind.NeverKeyword: case SyntaxKind.ReadonlyKeyword: + case SyntaxKind.RequireKeyword: + case SyntaxKind.NumberKeyword: + case SyntaxKind.SetKeyword: case SyntaxKind.StringKeyword: case SyntaxKind.SymbolKeyword: + case SyntaxKind.TypeKeyword: + case SyntaxKind.UndefinedKeyword: + case SyntaxKind.FromKeyword: case SyntaxKind.GlobalKeyword: + case SyntaxKind.OfKeyword: writeTokenText(kind); return; @@ -1198,12 +1212,14 @@ const _super = (function (geti, seti) { function emitCallExpression(node: CallExpression) { emitExpression(node.expression); + emitTypeArguments(node, node.typeArguments); emitExpressionList(node, node.arguments, ListFormat.CallExpressionArguments); } function emitNewExpression(node: NewExpression) { write("new "); emitExpression(node.expression); + emitTypeArguments(node, node.typeArguments); emitExpressionList(node, node.arguments, ListFormat.NewExpressionArguments); } @@ -1575,6 +1591,7 @@ const _super = (function (geti, seti) { function emitVariableDeclaration(node: VariableDeclaration) { emit(node.name); + emitWithPrefix(": ", node.type); emitExpressionWithPrefix(" = ", node.initializer); } diff --git a/src/compiler/transformers/es6.ts b/src/compiler/transformers/es6.ts index 8d8a817c18..fd9f7d2406 100644 --- a/src/compiler/transformers/es6.ts +++ b/src/compiler/transformers/es6.ts @@ -1416,6 +1416,7 @@ namespace ts { if (getAccessor) { const getterFunction = transformFunctionLikeToExpression(getAccessor, /*location*/ undefined, /*name*/ undefined); setSourceMapRange(getterFunction, getSourceMapRange(getAccessor)); + setEmitFlags(getterFunction, EmitFlags.NoLeadingComments); const getter = createPropertyAssignment("get", getterFunction); setCommentRange(getter, getCommentRange(getAccessor)); properties.push(getter); @@ -1424,6 +1425,7 @@ namespace ts { if (setAccessor) { const setterFunction = transformFunctionLikeToExpression(setAccessor, /*location*/ undefined, /*name*/ undefined); setSourceMapRange(setterFunction, getSourceMapRange(setAccessor)); + setEmitFlags(setterFunction, EmitFlags.NoLeadingComments); const setter = createPropertyAssignment("set", setterFunction); setCommentRange(setter, getCommentRange(setAccessor)); properties.push(setter); diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 2c146c91bc..f1ff9856ba 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -287,7 +287,7 @@ namespace ts { case SyntaxKind.Constructor: // TypeScript constructors are transformed in `visitClassDeclaration`. - return undefined; + return visitConstructor(node); case SyntaxKind.InterfaceDeclaration: // TypeScript interfaces are elided, but some comments may be preserved. @@ -377,6 +377,12 @@ namespace ts { // TypeScript type assertions are removed, but their subtrees are preserved. return visitAssertionExpression(node); + case SyntaxKind.CallExpression: + return visitCallExpression(node); + + case SyntaxKind.NewExpression: + return visitNewExpression(node); + case SyntaxKind.NonNullExpression: // TypeScript non-null expressions are removed, but their subtrees are preserved. return visitNonNullExpression(node); @@ -393,6 +399,9 @@ namespace ts { // TypeScript namespace exports for variable statements must be transformed. return visitVariableStatement(node); + case SyntaxKind.VariableDeclaration: + return visitVariableDeclaration(node); + case SyntaxKind.ModuleDeclaration: // TypeScript namespace declarations must be transformed. return visitModuleDeclaration(node); @@ -2088,6 +2097,14 @@ namespace ts { return !nodeIsMissing(node.body); } + function visitConstructor(node: ConstructorDeclaration) { + if (!shouldEmitFunctionLikeDeclaration(node)) { + return undefined; + } + + return visitEachChild(node, visitor, context); + } + /** * Visits a method declaration of a class. * @@ -2295,13 +2312,16 @@ namespace ts { function transformFunctionBodyWorker(body: Block, start = 0) { const savedCurrentScope = currentScope; + const savedCurrentScopeFirstDeclarationsOfName = currentScopeFirstDeclarationsOfName; currentScope = body; + currentScopeFirstDeclarationsOfName = createMap(); startLexicalEnvironment(); const statements = visitNodes(body.statements, visitor, isStatement, start); const visited = updateBlock(body, statements); const declarations = endLexicalEnvironment(); currentScope = savedCurrentScope; + currentScopeFirstDeclarationsOfName = savedCurrentScopeFirstDeclarationsOfName; return mergeFunctionBodyLexicalEnvironment(visited, declarations); } @@ -2481,6 +2501,14 @@ namespace ts { } } + function visitVariableDeclaration(node: VariableDeclaration) { + return updateVariableDeclaration( + node, + visitNode(node.name, visitor, isBindingName), + /*type*/ undefined, + visitNode(node.initializer, visitor, isExpression)); + } + /** * Visits an await expression. * @@ -2541,6 +2569,22 @@ namespace ts { return createPartiallyEmittedExpression(expression, node); } + function visitCallExpression(node: CallExpression) { + return updateCall( + node, + visitNode(node.expression, visitor, isExpression), + /*typeArguments*/ undefined, + visitNodes(node.arguments, visitor, isExpression)); + } + + function visitNewExpression(node: NewExpression) { + return updateNew( + node, + visitNode(node.expression, visitor, isExpression), + /*typeArguments*/ undefined, + visitNodes(node.arguments, visitor, isExpression)); + } + /** * Determines whether to emit an enum declaration. * diff --git a/src/compiler/types.ts b/src/compiler/types.ts index e87fa3e786..d66677910f 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -456,6 +456,8 @@ namespace ts { // Accessibility modifiers and 'readonly' can be attached to a parameter in a constructor to make it a property. ParameterPropertyModifier = AccessibilityModifier | Readonly, NonPublicAccessibilityModifier = Private | Protected, + + TypeScriptModifier = Ambient | Public | Private | Protected | Readonly | Abstract | Async | Const } export const enum JsxFlags { diff --git a/tests/baselines/reference/constructorArgsErrors1.js b/tests/baselines/reference/constructorArgsErrors1.js index 15c5e64952..bb0725ab8b 100644 --- a/tests/baselines/reference/constructorArgsErrors1.js +++ b/tests/baselines/reference/constructorArgsErrors1.js @@ -6,7 +6,7 @@ class foo { //// [constructorArgsErrors1.js] var foo = (function () { - function foo(static a) { + function foo(a) { } return foo; }()); diff --git a/tests/baselines/reference/constructorArgsErrors5.js b/tests/baselines/reference/constructorArgsErrors5.js index 6ba68cb88b..c481d6f323 100644 --- a/tests/baselines/reference/constructorArgsErrors5.js +++ b/tests/baselines/reference/constructorArgsErrors5.js @@ -7,7 +7,7 @@ class foo { //// [constructorArgsErrors5.js] var foo = (function () { - function foo(export a) { + function foo(a) { } return foo; }()); diff --git a/tests/baselines/reference/parserErrorRecovery_ParameterList6.js b/tests/baselines/reference/parserErrorRecovery_ParameterList6.js index c3d5a838f8..7c221aaa20 100644 --- a/tests/baselines/reference/parserErrorRecovery_ParameterList6.js +++ b/tests/baselines/reference/parserErrorRecovery_ParameterList6.js @@ -7,7 +7,6 @@ class Foo { var Foo = (function () { function Foo() { } - Foo.prototype.banana = function (x) { }; return Foo; }()); break ; diff --git a/tests/baselines/reference/transformsElideNullUndefinedType.js b/tests/baselines/reference/transformsElideNullUndefinedType.js new file mode 100644 index 0000000000..a5e27eee08 --- /dev/null +++ b/tests/baselines/reference/transformsElideNullUndefinedType.js @@ -0,0 +1,54 @@ +//// [transformsElideNullUndefinedType.ts] + +var v0: null; +var v1: undefined; + +function f0(): null { return null; } +function f1(): undefined { return undefined; } + +var f2 = function (): null { return null; } +var f3 = function (): undefined { return undefined; } + +var f4 = (): null => null; +var f5 = (): undefined => undefined; + +function f6(p0: null) { } +function f7(p1: undefined) { } + +class C { + m0(): null { return null; } + m1(): undefined { return undefined; } + + get a0(): null { return null; } + get a1(): undefined { return undefined; } +} + +declare function fn(); + +fn(); +fn(); + +new C(); +new C(); + +//// [transformsElideNullUndefinedType.js] +var v0; +var v1; +function f0() { return null; } +function f1() { return undefined; } +var f2 = function () { return null; }; +var f3 = function () { return undefined; }; +var f4 = () => null; +var f5 = () => undefined; +function f6(p0) { } +function f7(p1) { } +class C { + m0() { return null; } + m1() { return undefined; } + get a0() { return null; } + get a1() { return undefined; } +} +fn(); +fn(); +new C(); +new C(); diff --git a/tests/baselines/reference/transformsElideNullUndefinedType.symbols b/tests/baselines/reference/transformsElideNullUndefinedType.symbols new file mode 100644 index 0000000000..0c9333d982 --- /dev/null +++ b/tests/baselines/reference/transformsElideNullUndefinedType.symbols @@ -0,0 +1,72 @@ +=== tests/cases/compiler/transformsElideNullUndefinedType.ts === + +var v0: null; +>v0 : Symbol(v0, Decl(transformsElideNullUndefinedType.ts, 1, 3)) + +var v1: undefined; +>v1 : Symbol(v1, Decl(transformsElideNullUndefinedType.ts, 2, 3)) + +function f0(): null { return null; } +>f0 : Symbol(f0, Decl(transformsElideNullUndefinedType.ts, 2, 18)) + +function f1(): undefined { return undefined; } +>f1 : Symbol(f1, Decl(transformsElideNullUndefinedType.ts, 4, 36)) +>undefined : Symbol(undefined) + +var f2 = function (): null { return null; } +>f2 : Symbol(f2, Decl(transformsElideNullUndefinedType.ts, 7, 3)) + +var f3 = function (): undefined { return undefined; } +>f3 : Symbol(f3, Decl(transformsElideNullUndefinedType.ts, 8, 3)) +>undefined : Symbol(undefined) + +var f4 = (): null => null; +>f4 : Symbol(f4, Decl(transformsElideNullUndefinedType.ts, 10, 3)) + +var f5 = (): undefined => undefined; +>f5 : Symbol(f5, Decl(transformsElideNullUndefinedType.ts, 11, 3)) +>undefined : Symbol(undefined) + +function f6(p0: null) { } +>f6 : Symbol(f6, Decl(transformsElideNullUndefinedType.ts, 11, 36)) +>p0 : Symbol(p0, Decl(transformsElideNullUndefinedType.ts, 13, 12)) + +function f7(p1: undefined) { } +>f7 : Symbol(f7, Decl(transformsElideNullUndefinedType.ts, 13, 25)) +>p1 : Symbol(p1, Decl(transformsElideNullUndefinedType.ts, 14, 12)) + +class C { +>C : Symbol(C, Decl(transformsElideNullUndefinedType.ts, 14, 30)) +>T : Symbol(T, Decl(transformsElideNullUndefinedType.ts, 16, 8)) + + m0(): null { return null; } +>m0 : Symbol(C.m0, Decl(transformsElideNullUndefinedType.ts, 16, 12)) + + m1(): undefined { return undefined; } +>m1 : Symbol(C.m1, Decl(transformsElideNullUndefinedType.ts, 17, 31)) +>undefined : Symbol(undefined) + + get a0(): null { return null; } +>a0 : Symbol(C.a0, Decl(transformsElideNullUndefinedType.ts, 18, 41)) + + get a1(): undefined { return undefined; } +>a1 : Symbol(C.a1, Decl(transformsElideNullUndefinedType.ts, 20, 35)) +>undefined : Symbol(undefined) +} + +declare function fn(); +>fn : Symbol(fn, Decl(transformsElideNullUndefinedType.ts, 22, 1)) +>T : Symbol(T, Decl(transformsElideNullUndefinedType.ts, 24, 20)) + +fn(); +>fn : Symbol(fn, Decl(transformsElideNullUndefinedType.ts, 22, 1)) + +fn(); +>fn : Symbol(fn, Decl(transformsElideNullUndefinedType.ts, 22, 1)) + +new C(); +>C : Symbol(C, Decl(transformsElideNullUndefinedType.ts, 14, 30)) + +new C(); +>C : Symbol(C, Decl(transformsElideNullUndefinedType.ts, 14, 30)) + diff --git a/tests/baselines/reference/transformsElideNullUndefinedType.types b/tests/baselines/reference/transformsElideNullUndefinedType.types new file mode 100644 index 0000000000..66a73c8314 --- /dev/null +++ b/tests/baselines/reference/transformsElideNullUndefinedType.types @@ -0,0 +1,94 @@ +=== tests/cases/compiler/transformsElideNullUndefinedType.ts === + +var v0: null; +>v0 : null +>null : null + +var v1: undefined; +>v1 : undefined + +function f0(): null { return null; } +>f0 : () => null +>null : null +>null : null + +function f1(): undefined { return undefined; } +>f1 : () => undefined +>undefined : undefined + +var f2 = function (): null { return null; } +>f2 : () => null +>function (): null { return null; } : () => null +>null : null +>null : null + +var f3 = function (): undefined { return undefined; } +>f3 : () => undefined +>function (): undefined { return undefined; } : () => undefined +>undefined : undefined + +var f4 = (): null => null; +>f4 : () => null +>(): null => null : () => null +>null : null +>null : null + +var f5 = (): undefined => undefined; +>f5 : () => undefined +>(): undefined => undefined : () => undefined +>undefined : undefined + +function f6(p0: null) { } +>f6 : (p0: null) => void +>p0 : null +>null : null + +function f7(p1: undefined) { } +>f7 : (p1: undefined) => void +>p1 : undefined + +class C { +>C : C +>T : T + + m0(): null { return null; } +>m0 : () => null +>null : null +>null : null + + m1(): undefined { return undefined; } +>m1 : () => undefined +>undefined : undefined + + get a0(): null { return null; } +>a0 : null +>null : null +>null : null + + get a1(): undefined { return undefined; } +>a1 : undefined +>undefined : undefined +} + +declare function fn(); +>fn : () => any +>T : T + +fn(); +>fn() : any +>fn : () => any +>null : null + +fn(); +>fn() : any +>fn : () => any + +new C(); +>new C() : C +>C : typeof C +>null : null + +new C(); +>new C() : C +>C : typeof C + diff --git a/tests/baselines/reference/typeGuardFunctionErrors.js b/tests/baselines/reference/typeGuardFunctionErrors.js index 6f0880ad7f..244b0df333 100644 --- a/tests/baselines/reference/typeGuardFunctionErrors.js +++ b/tests/baselines/reference/typeGuardFunctionErrors.js @@ -171,7 +171,6 @@ var C = (function (_super) { function hasANonBooleanReturnStatement(x) { return ''; } -function hasTypeGuardTypeInsideTypeGuardType(x) { } is; A; { @@ -232,7 +231,6 @@ function b2(a, A) { if (a === void 0) { a = is; } } ; -function b3() { } is; A; { diff --git a/tests/cases/compiler/transformsElideNullUndefinedType.ts b/tests/cases/compiler/transformsElideNullUndefinedType.ts new file mode 100644 index 0000000000..244f2ea9c7 --- /dev/null +++ b/tests/cases/compiler/transformsElideNullUndefinedType.ts @@ -0,0 +1,32 @@ +// @target: es6 + +var v0: null; +var v1: undefined; + +function f0(): null { return null; } +function f1(): undefined { return undefined; } + +var f2 = function (): null { return null; } +var f3 = function (): undefined { return undefined; } + +var f4 = (): null => null; +var f5 = (): undefined => undefined; + +function f6(p0: null) { } +function f7(p1: undefined) { } + +class C { + m0(): null { return null; } + m1(): undefined { return undefined; } + + get a0(): null { return null; } + get a1(): undefined { return undefined; } +} + +declare function fn(); + +fn(); +fn(); + +new C(); +new C(); \ No newline at end of file From a1cbfcae4b2560f2709a88e4d41185ac548c5e5c Mon Sep 17 00:00:00 2001 From: Zhengbo Li Date: Fri, 14 Oct 2016 20:50:12 -0700 Subject: [PATCH 51/80] Add missing trigger file (#11641) * Add missing trigger file property for config file diags * Add test --- src/harness/unittests/tsserverProjectSystem.ts | 10 +++++++++- src/server/editorServices.ts | 12 ++++++------ src/server/session.ts | 2 +- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 468d6aac14..9d086e4549 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -135,7 +135,7 @@ namespace ts.projectSystem { } export class TestServerEventManager { - private events: server.ProjectServiceEvent[] = []; + public events: server.ProjectServiceEvent[] = []; handler: server.ProjectServiceEventHandler = (event: server.ProjectServiceEvent) => { this.events.push(event); @@ -2286,6 +2286,14 @@ namespace ts.projectSystem { const session = createSession(host, /*typingsInstaller*/ undefined, serverEventManager.handler); openFilesForSession([file], session); serverEventManager.checkEventCountOfType("configFileDiag", 1); + + for (const event of serverEventManager.events) { + if (event.eventName === "configFileDiag") { + assert.equal(event.data.configFileName, configFile.path); + assert.equal(event.data.triggerFile, file.path); + return; + } + } }); it("are generated when the config file doesn't have errors", () => { diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 91b9f90c88..54b257242f 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -11,7 +11,7 @@ namespace ts.server { export const maxProgramSizeForNonTsFiles = 20 * 1024 * 1024; export type ProjectServiceEvent = - { eventName: "context", data: { project: Project, fileName: NormalizedPath } } | { eventName: "configFileDiag", data: { triggerFile?: string, configFileName: string, diagnostics: Diagnostic[] } }; + { eventName: "context", data: { project: Project, fileName: NormalizedPath } } | { eventName: "configFileDiag", data: { triggerFile: string, configFileName: string, diagnostics: Diagnostic[] } }; export interface ProjectServiceEventHandler { (event: ProjectServiceEvent): void; @@ -392,12 +392,12 @@ namespace ts.server { this.throttledOperations.schedule( project.configFileName, /*delay*/250, - () => this.handleChangeInSourceFileForConfiguredProject(project)); + () => this.handleChangeInSourceFileForConfiguredProject(project, fileName)); } - private handleChangeInSourceFileForConfiguredProject(project: ConfiguredProject) { + private handleChangeInSourceFileForConfiguredProject(project: ConfiguredProject, triggerFile: string) { const { projectOptions, configFileErrors } = this.convertConfigFileContentToProjectOptions(project.configFileName); - this.reportConfigFileDiagnostics(project.getProjectName(), configFileErrors); + this.reportConfigFileDiagnostics(project.getProjectName(), configFileErrors, triggerFile); const newRootFiles = projectOptions.files.map((f => this.getCanonicalFileName(f))); const currentRootFiles = project.getRootFiles().map((f => this.getCanonicalFileName(f))); @@ -434,7 +434,7 @@ namespace ts.server { } const { configFileErrors } = this.convertConfigFileContentToProjectOptions(fileName); - this.reportConfigFileDiagnostics(fileName, configFileErrors); + this.reportConfigFileDiagnostics(fileName, configFileErrors, fileName); this.logger.info(`Detected newly added tsconfig file: ${fileName}`); this.reloadProjects(); @@ -757,7 +757,7 @@ namespace ts.server { return project; } - private reportConfigFileDiagnostics(configFileName: string, diagnostics: Diagnostic[], triggerFile?: string) { + private reportConfigFileDiagnostics(configFileName: string, diagnostics: Diagnostic[], triggerFile: string) { if (!this.eventHandler) { return; } diff --git a/src/server/session.ts b/src/server/session.ts index 539142eff1..3df6a1acb5 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -761,7 +761,7 @@ namespace ts.server { if (this.eventHander) { this.eventHander({ eventName: "configFileDiag", - data: { fileName, configFileName, diagnostics: configFileErrors || [] } + data: { triggerFile: fileName, configFileName, diagnostics: configFileErrors || [] } }); } } From 40e99e7f6691b356c3a4d1da873cd799812d29d4 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Fri, 14 Oct 2016 21:34:59 -0700 Subject: [PATCH 52/80] Updated comment --- src/compiler/transformers/ts.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index f1ff9856ba..1189c1380a 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -286,7 +286,6 @@ namespace ts { // TypeScript property declarations are elided. case SyntaxKind.Constructor: - // TypeScript constructors are transformed in `visitClassDeclaration`. return visitConstructor(node); case SyntaxKind.InterfaceDeclaration: From a4a7c237b3b55ad250fa2c55a66fd1cce4c3f071 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Sat, 15 Oct 2016 15:18:32 -0700 Subject: [PATCH 53/80] Fix issues from merge --- src/compiler/binder.ts | 8 +- src/compiler/binder.ts.orig | 3181 ----------------------------------- 2 files changed, 4 insertions(+), 3185 deletions(-) delete mode 100644 src/compiler/binder.ts.orig diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index d71e6ea2c8..4711d54e0b 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -2469,7 +2469,7 @@ namespace ts { if (subtreeFlags & TransformFlags.ContainsSpreadElementExpression) { // If the this node contains a SpreadElementExpression then it is an ES6 // node. - transformFlags |= TransformFlags.AssertES6; + transformFlags |= TransformFlags.AssertES2015; } node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; return transformFlags & ~TransformFlags.ArrayLiteralOrCallOrNewExcludes; @@ -2671,7 +2671,7 @@ namespace ts { } // An async method declaration is ES2017 syntax. - if (modifierFlags & ModifierFlags.Async) { + if (hasModifier(node, ModifierFlags.Async)) { transformFlags |= TransformFlags.AssertES2017; } @@ -2778,7 +2778,7 @@ namespace ts { } // An async function expression is ES2017 syntax. - if (modifierFlags & ModifierFlags.Async) { + if (hasModifier(node, ModifierFlags.Async)) { transformFlags |= TransformFlags.AssertES2017; } @@ -2815,7 +2815,7 @@ namespace ts { } // An async arrow function is ES2017 syntax. - if (modifierFlags & ModifierFlags.Async) { + if (hasModifier(node, ModifierFlags.Async)) { transformFlags |= TransformFlags.AssertES2017; } diff --git a/src/compiler/binder.ts.orig b/src/compiler/binder.ts.orig deleted file mode 100644 index 6cbd7d746d..0000000000 --- a/src/compiler/binder.ts.orig +++ /dev/null @@ -1,3181 +0,0 @@ -/// -/// - -/* @internal */ -namespace ts { - export const enum ModuleInstanceState { - NonInstantiated = 0, - Instantiated = 1, - ConstEnumOnly = 2 - } - - interface ActiveLabel { - name: string; - breakTarget: FlowLabel; - continueTarget: FlowLabel; - referenced: boolean; - } - - export function getModuleInstanceState(node: Node): ModuleInstanceState { - // A module is uninstantiated if it contains only - // 1. interface declarations, type alias declarations - if (node.kind === SyntaxKind.InterfaceDeclaration || node.kind === SyntaxKind.TypeAliasDeclaration) { - return ModuleInstanceState.NonInstantiated; - } - // 2. const enum declarations - else if (isConstEnumDeclaration(node)) { - return ModuleInstanceState.ConstEnumOnly; - } - // 3. non-exported import declarations - else if ((node.kind === SyntaxKind.ImportDeclaration || node.kind === SyntaxKind.ImportEqualsDeclaration) && !(hasModifier(node, ModifierFlags.Export))) { - return ModuleInstanceState.NonInstantiated; - } - // 4. other uninstantiated module declarations. - else if (node.kind === SyntaxKind.ModuleBlock) { - let state = ModuleInstanceState.NonInstantiated; - forEachChild(node, n => { - switch (getModuleInstanceState(n)) { - case ModuleInstanceState.NonInstantiated: - // child is non-instantiated - continue searching - return false; - case ModuleInstanceState.ConstEnumOnly: - // child is const enum only - record state and continue searching - state = ModuleInstanceState.ConstEnumOnly; - return false; - case ModuleInstanceState.Instantiated: - // child is instantiated - record state and stop - state = ModuleInstanceState.Instantiated; - return true; - } - }); - return state; - } - else if (node.kind === SyntaxKind.ModuleDeclaration) { - const body = (node).body; - return body ? getModuleInstanceState(body) : ModuleInstanceState.Instantiated; - } - else { - return ModuleInstanceState.Instantiated; - } - } - - const enum ContainerFlags { - // The current node is not a container, and no container manipulation should happen before - // recursing into it. - None = 0, - - // The current node is a container. It should be set as the current container (and block- - // container) before recursing into it. The current node does not have locals. Examples: - // - // Classes, ObjectLiterals, TypeLiterals, Interfaces... - IsContainer = 1 << 0, - - // The current node is a block-scoped-container. It should be set as the current block- - // container before recursing into it. Examples: - // - // Blocks (when not parented by functions), Catch clauses, For/For-in/For-of statements... - IsBlockScopedContainer = 1 << 1, - - // The current node is the container of a control flow path. The current control flow should - // be saved and restored, and a new control flow initialized within the container. - IsControlFlowContainer = 1 << 2, - - IsFunctionLike = 1 << 3, - IsFunctionExpression = 1 << 4, - HasLocals = 1 << 5, - IsInterface = 1 << 6, - IsObjectLiteralOrClassExpressionMethod = 1 << 7, - } - - const binder = createBinder(); - - export function bindSourceFile(file: SourceFile, options: CompilerOptions) { - performance.mark("beforeBind"); - binder(file, options); - performance.mark("afterBind"); - performance.measure("Bind", "beforeBind", "afterBind"); - } - - function createBinder(): (file: SourceFile, options: CompilerOptions) => void { - let file: SourceFile; - let options: CompilerOptions; - let languageVersion: ScriptTarget; - let parent: Node; - let container: Node; - let blockScopeContainer: Node; - let lastContainer: Node; - let seenThisKeyword: boolean; - - // state used by control flow analysis - let currentFlow: FlowNode; - let currentBreakTarget: FlowLabel; - let currentContinueTarget: FlowLabel; - let currentReturnTarget: FlowLabel; - let currentTrueTarget: FlowLabel; - let currentFalseTarget: FlowLabel; - let preSwitchCaseFlow: FlowNode; - let activeLabels: ActiveLabel[]; - let hasExplicitReturn: boolean; - - // state used for emit helpers - let emitFlags: NodeFlags; - - // If this file is an external module, then it is automatically in strict-mode according to - // ES6. If it is not an external module, then we'll determine if it is in strict mode or - // not depending on if we see "use strict" in certain places or if we hit a class/namespace - // or if compiler options contain alwaysStrict. - let inStrictMode: boolean; - - let symbolCount = 0; - let Symbol: { new (flags: SymbolFlags, name: string): Symbol }; - let classifiableNames: Map; - - const unreachableFlow: FlowNode = { flags: FlowFlags.Unreachable }; - const reportedUnreachableFlow: FlowNode = { flags: FlowFlags.Unreachable }; - - // state used to aggregate transform flags during bind. - let subtreeTransformFlags: TransformFlags = TransformFlags.None; - let skipTransformFlagAggregation: boolean; - - function bindSourceFile(f: SourceFile, opts: CompilerOptions) { - file = f; - options = opts; - languageVersion = getEmitScriptTarget(options); - inStrictMode = bindInStrictMode(file, opts); - classifiableNames = createMap(); - symbolCount = 0; - skipTransformFlagAggregation = isDeclarationFile(file); - - Symbol = objectAllocator.getSymbolConstructor(); - - if (!file.locals) { - bind(file); - file.symbolCount = symbolCount; - file.classifiableNames = classifiableNames; - } - - file = undefined; - options = undefined; - languageVersion = undefined; - parent = undefined; - container = undefined; - blockScopeContainer = undefined; - lastContainer = undefined; - seenThisKeyword = false; - currentFlow = undefined; - currentBreakTarget = undefined; - currentContinueTarget = undefined; - currentReturnTarget = undefined; - currentTrueTarget = undefined; - currentFalseTarget = undefined; - activeLabels = undefined; - hasExplicitReturn = false; - emitFlags = NodeFlags.None; - subtreeTransformFlags = TransformFlags.None; - } - - return bindSourceFile; - - function bindInStrictMode(file: SourceFile, opts: CompilerOptions): boolean { - if (opts.alwaysStrict && !isDeclarationFile(file)) { - // bind in strict mode source files with alwaysStrict option - return true; - } - else { - return !!file.externalModuleIndicator; - } - } - - function createSymbol(flags: SymbolFlags, name: string): Symbol { - symbolCount++; - return new Symbol(flags, name); - } - - function addDeclarationToSymbol(symbol: Symbol, node: Declaration, symbolFlags: SymbolFlags) { - symbol.flags |= symbolFlags; - - node.symbol = symbol; - - if (!symbol.declarations) { - symbol.declarations = []; - } - symbol.declarations.push(node); - - if (symbolFlags & SymbolFlags.HasExports && !symbol.exports) { - symbol.exports = createMap(); - } - - if (symbolFlags & SymbolFlags.HasMembers && !symbol.members) { - symbol.members = createMap(); - } - - if (symbolFlags & SymbolFlags.Value) { - const valueDeclaration = symbol.valueDeclaration; - if (!valueDeclaration || - (valueDeclaration.kind !== node.kind && valueDeclaration.kind === SyntaxKind.ModuleDeclaration)) { - // other kinds of value declarations take precedence over modules - symbol.valueDeclaration = node; - } - } - } - - // Should not be called on a declaration with a computed property name, - // unless it is a well known Symbol. - function getDeclarationName(node: Declaration): string { - if (node.name) { - if (isAmbientModule(node)) { - return isGlobalScopeAugmentation(node) ? "__global" : `"${(node.name).text}"`; - } - if (node.name.kind === SyntaxKind.ComputedPropertyName) { - const nameExpression = (node.name).expression; - // treat computed property names where expression is string/numeric literal as just string/numeric literal - if (isStringOrNumericLiteral(nameExpression.kind)) { - return (nameExpression).text; - } - - Debug.assert(isWellKnownSymbolSyntactically(nameExpression)); - return getPropertyNameForKnownSymbolName((nameExpression).name.text); - } - return (node.name).text; - } - switch (node.kind) { - case SyntaxKind.Constructor: - return "__constructor"; - case SyntaxKind.FunctionType: - case SyntaxKind.CallSignature: - return "__call"; - case SyntaxKind.ConstructorType: - case SyntaxKind.ConstructSignature: - return "__new"; - case SyntaxKind.IndexSignature: - return "__index"; - case SyntaxKind.ExportDeclaration: - return "__export"; - case SyntaxKind.ExportAssignment: - return (node).isExportEquals ? "export=" : "default"; - case SyntaxKind.BinaryExpression: - switch (getSpecialPropertyAssignmentKind(node)) { - case SpecialPropertyAssignmentKind.ModuleExports: - // module.exports = ... - return "export="; - case SpecialPropertyAssignmentKind.ExportsProperty: - case SpecialPropertyAssignmentKind.ThisProperty: - // exports.x = ... or this.y = ... - return ((node as BinaryExpression).left as PropertyAccessExpression).name.text; - case SpecialPropertyAssignmentKind.PrototypeProperty: - // className.prototype.methodName = ... - return (((node as BinaryExpression).left as PropertyAccessExpression).expression as PropertyAccessExpression).name.text; - } - Debug.fail("Unknown binary declaration kind"); - break; - - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.ClassDeclaration: - return hasModifier(node, ModifierFlags.Default) ? "default" : undefined; - case SyntaxKind.JSDocFunctionType: - return isJSDocConstructSignature(node) ? "__new" : "__call"; - case SyntaxKind.Parameter: - // Parameters with names are handled at the top of this function. Parameters - // without names can only come from JSDocFunctionTypes. - Debug.assert(node.parent.kind === SyntaxKind.JSDocFunctionType); - let functionType = node.parent; - let index = indexOf(functionType.parameters, node); - return "arg" + index; - case SyntaxKind.JSDocTypedefTag: - const parentNode = node.parent && node.parent.parent; - let nameFromParentNode: string; - if (parentNode && parentNode.kind === SyntaxKind.VariableStatement) { - if ((parentNode).declarationList.declarations.length > 0) { - const nameIdentifier = (parentNode).declarationList.declarations[0].name; - if (nameIdentifier.kind === SyntaxKind.Identifier) { - nameFromParentNode = (nameIdentifier).text; - } - } - } - return nameFromParentNode; - } - } - - function getDisplayName(node: Declaration): string { - return node.name ? declarationNameToString(node.name) : getDeclarationName(node); - } - - /** - * Declares a Symbol for the node and adds it to symbols. Reports errors for conflicting identifier names. - * @param symbolTable - The symbol table which node will be added to. - * @param parent - node's parent declaration. - * @param node - The declaration to be added to the symbol table - * @param includes - The SymbolFlags that node has in addition to its declaration type (eg: export, ambient, etc.) - * @param excludes - The flags which node cannot be declared alongside in a symbol table. Used to report forbidden declarations. - */ - function declareSymbol(symbolTable: SymbolTable, parent: Symbol, node: Declaration, includes: SymbolFlags, excludes: SymbolFlags): Symbol { - Debug.assert(!hasDynamicName(node)); - - const isDefaultExport = hasModifier(node, ModifierFlags.Default); - - // The exported symbol for an export default function/class node is always named "default" - const name = isDefaultExport && parent ? "default" : getDeclarationName(node); - - let symbol: Symbol; - if (name === undefined) { - symbol = createSymbol(SymbolFlags.None, "__missing"); - } - else { - // Check and see if the symbol table already has a symbol with this name. If not, - // create a new symbol with this name and add it to the table. Note that we don't - // give the new symbol any flags *yet*. This ensures that it will not conflict - // with the 'excludes' flags we pass in. - // - // If we do get an existing symbol, see if it conflicts with the new symbol we're - // creating. For example, a 'var' symbol and a 'class' symbol will conflict within - // the same symbol table. If we have a conflict, report the issue on each - // declaration we have for this symbol, and then create a new symbol for this - // declaration. - // - // Note that when properties declared in Javascript constructors - // (marked by isReplaceableByMethod) conflict with another symbol, the property loses. - // Always. This allows the common Javascript pattern of overwriting a prototype method - // with an bound instance method of the same type: `this.method = this.method.bind(this)` - // - // If we created a new symbol, either because we didn't have a symbol with this name - // in the symbol table, or we conflicted with an existing symbol, then just add this - // node as the sole declaration of the new symbol. - // - // Otherwise, we'll be merging into a compatible existing symbol (for example when - // you have multiple 'vars' with the same name in the same container). In this case - // just add this node into the declarations list of the symbol. - symbol = symbolTable[name] || (symbolTable[name] = createSymbol(SymbolFlags.None, name)); - - if (name && (includes & SymbolFlags.Classifiable)) { - classifiableNames[name] = name; - } - - if (symbol.flags & excludes) { - if (symbol.isReplaceableByMethod) { - // Javascript constructor-declared symbols can be discarded in favor of - // prototype symbols like methods. - symbol = symbolTable[name] = createSymbol(SymbolFlags.None, name); - } - else { - if (node.name) { - node.name.parent = node; - } - - // Report errors every position with duplicate declaration - // Report errors on previous encountered declarations - let message = symbol.flags & SymbolFlags.BlockScopedVariable - ? Diagnostics.Cannot_redeclare_block_scoped_variable_0 - : Diagnostics.Duplicate_identifier_0; - - if (symbol.declarations && symbol.declarations.length) { - // If the current node is a default export of some sort, then check if - // there are any other default exports that we need to error on. - // We'll know whether we have other default exports depending on if `symbol` already has a declaration list set. - if (isDefaultExport) { - message = Diagnostics.A_module_cannot_have_multiple_default_exports; - } - else { - // This is to properly report an error in the case "export default { }" is after export default of class declaration or function declaration. - // Error on multiple export default in the following case: - // 1. multiple export default of class declaration or function declaration by checking NodeFlags.Default - // 2. multiple export default of export assignment. This one doesn't have NodeFlags.Default on (as export default doesn't considered as modifiers) - if (symbol.declarations && symbol.declarations.length && - (isDefaultExport || (node.kind === SyntaxKind.ExportAssignment && !(node).isExportEquals))) { - message = Diagnostics.A_module_cannot_have_multiple_default_exports; - } - } - } - - forEach(symbol.declarations, declaration => { - file.bindDiagnostics.push(createDiagnosticForNode(declaration.name || declaration, message, getDisplayName(declaration))); - }); - file.bindDiagnostics.push(createDiagnosticForNode(node.name || node, message, getDisplayName(node))); - - symbol = createSymbol(SymbolFlags.None, name); - } - } - } - - addDeclarationToSymbol(symbol, node, includes); - symbol.parent = parent; - - return symbol; - } - - function declareModuleMember(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): Symbol { - const hasExportModifier = getCombinedModifierFlags(node) & ModifierFlags.Export; - if (symbolFlags & SymbolFlags.Alias) { - if (node.kind === SyntaxKind.ExportSpecifier || (node.kind === SyntaxKind.ImportEqualsDeclaration && hasExportModifier)) { - return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes); - } - else { - return declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes); - } - } - else { - // Exported module members are given 2 symbols: A local symbol that is classified with an ExportValue, - // ExportType, or ExportContainer flag, and an associated export symbol with all the correct flags set - // on it. There are 2 main reasons: - // - // 1. We treat locals and exports of the same name as mutually exclusive within a container. - // That means the binder will issue a Duplicate Identifier error if you mix locals and exports - // with the same name in the same container. - // TODO: Make this a more specific error and decouple it from the exclusion logic. - // 2. When we checkIdentifier in the checker, we set its resolved symbol to the local symbol, - // but return the export symbol (by calling getExportSymbolOfValueSymbolIfExported). That way - // when the emitter comes back to it, it knows not to qualify the name if it was found in a containing scope. - - // NOTE: Nested ambient modules always should go to to 'locals' table to prevent their automatic merge - // during global merging in the checker. Why? The only case when ambient module is permitted inside another module is module augmentation - // and this case is specially handled. Module augmentations should only be merged with original module definition - // and should never be merged directly with other augmentation, and the latter case would be possible if automatic merge is allowed. - if (!isAmbientModule(node) && (hasExportModifier || container.flags & NodeFlags.ExportContext)) { - const exportKind = - (symbolFlags & SymbolFlags.Value ? SymbolFlags.ExportValue : 0) | - (symbolFlags & SymbolFlags.Type ? SymbolFlags.ExportType : 0) | - (symbolFlags & SymbolFlags.Namespace ? SymbolFlags.ExportNamespace : 0); - const local = declareSymbol(container.locals, undefined, node, exportKind, symbolExcludes); - local.exportSymbol = declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes); - node.localSymbol = local; - return local; - } - else { - return declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes); - } - } - } - - // All container nodes are kept on a linked list in declaration order. This list is used by - // the getLocalNameOfContainer function in the type checker to validate that the local name - // used for a container is unique. - function bindContainer(node: Node, containerFlags: ContainerFlags) { - // Before we recurse into a node's children, we first save the existing parent, container - // and block-container. Then after we pop out of processing the children, we restore - // these saved values. - const saveContainer = container; - const savedBlockScopeContainer = blockScopeContainer; - - // Depending on what kind of node this is, we may have to adjust the current container - // and block-container. If the current node is a container, then it is automatically - // considered the current block-container as well. Also, for containers that we know - // may contain locals, we proactively initialize the .locals field. We do this because - // it's highly likely that the .locals will be needed to place some child in (for example, - // a parameter, or variable declaration). - // - // However, we do not proactively create the .locals for block-containers because it's - // totally normal and common for block-containers to never actually have a block-scoped - // variable in them. We don't want to end up allocating an object for every 'block' we - // run into when most of them won't be necessary. - // - // Finally, if this is a block-container, then we clear out any existing .locals object - // it may contain within it. This happens in incremental scenarios. Because we can be - // reusing a node from a previous compilation, that node may have had 'locals' created - // for it. We must clear this so we don't accidentally move any stale data forward from - // a previous compilation. - if (containerFlags & ContainerFlags.IsContainer) { - container = blockScopeContainer = node; - if (containerFlags & ContainerFlags.HasLocals) { - container.locals = createMap(); - } - addToContainerChain(container); - } - else if (containerFlags & ContainerFlags.IsBlockScopedContainer) { - blockScopeContainer = node; - blockScopeContainer.locals = undefined; - } - if (containerFlags & ContainerFlags.IsControlFlowContainer) { - const saveCurrentFlow = currentFlow; - const saveBreakTarget = currentBreakTarget; - const saveContinueTarget = currentContinueTarget; - const saveReturnTarget = currentReturnTarget; - const saveActiveLabels = activeLabels; - const saveHasExplicitReturn = hasExplicitReturn; - const isIIFE = containerFlags & ContainerFlags.IsFunctionExpression && !!getImmediatelyInvokedFunctionExpression(node); - // An IIFE is considered part of the containing control flow. Return statements behave - // similarly to break statements that exit to a label just past the statement body. - if (isIIFE) { - currentReturnTarget = createBranchLabel(); - } - else { - currentFlow = { flags: FlowFlags.Start }; - if (containerFlags & (ContainerFlags.IsFunctionExpression | ContainerFlags.IsObjectLiteralOrClassExpressionMethod)) { - (currentFlow).container = node; - } - currentReturnTarget = undefined; - } - currentBreakTarget = undefined; - currentContinueTarget = undefined; - activeLabels = undefined; - hasExplicitReturn = false; - bindChildren(node); - // Reset all reachability check related flags on node (for incremental scenarios) - // Reset all emit helper flags on node (for incremental scenarios) - node.flags &= ~NodeFlags.ReachabilityAndEmitFlags; - if (!(currentFlow.flags & FlowFlags.Unreachable) && containerFlags & ContainerFlags.IsFunctionLike && nodeIsPresent((node).body)) { - node.flags |= NodeFlags.HasImplicitReturn; - if (hasExplicitReturn) node.flags |= NodeFlags.HasExplicitReturn; - } - if (node.kind === SyntaxKind.SourceFile) { - node.flags |= emitFlags; - } - if (isIIFE) { - addAntecedent(currentReturnTarget, currentFlow); - currentFlow = finishFlowLabel(currentReturnTarget); - } - else { - currentFlow = saveCurrentFlow; - } - currentBreakTarget = saveBreakTarget; - currentContinueTarget = saveContinueTarget; - currentReturnTarget = saveReturnTarget; - activeLabels = saveActiveLabels; - hasExplicitReturn = saveHasExplicitReturn; - } - else if (containerFlags & ContainerFlags.IsInterface) { - seenThisKeyword = false; - bindChildren(node); - node.flags = seenThisKeyword ? node.flags | NodeFlags.ContainsThis : node.flags & ~NodeFlags.ContainsThis; - } - else { - bindChildren(node); - } - container = saveContainer; - blockScopeContainer = savedBlockScopeContainer; - } - - function bindChildren(node: Node): void { - if (skipTransformFlagAggregation) { - bindChildrenWorker(node); - } - else if (node.transformFlags & TransformFlags.HasComputedFlags) { - skipTransformFlagAggregation = true; - bindChildrenWorker(node); - skipTransformFlagAggregation = false; - } - else { - const savedSubtreeTransformFlags = subtreeTransformFlags; - subtreeTransformFlags = 0; - bindChildrenWorker(node); - subtreeTransformFlags = savedSubtreeTransformFlags | computeTransformFlagsForNode(node, subtreeTransformFlags); - } - } - - function bindChildrenWorker(node: Node): void { - // Binding of JsDocComment should be done before the current block scope container changes. - // because the scope of JsDocComment should not be affected by whether the current node is a - // container or not. - if (isInJavaScriptFile(node) && node.jsDocComments) { - forEach(node.jsDocComments, bind); - } - if (checkUnreachable(node)) { - forEachChild(node, bind); - return; - } - switch (node.kind) { - case SyntaxKind.WhileStatement: - bindWhileStatement(node); - break; - case SyntaxKind.DoStatement: - bindDoStatement(node); - break; - case SyntaxKind.ForStatement: - bindForStatement(node); - break; - case SyntaxKind.ForInStatement: - case SyntaxKind.ForOfStatement: - bindForInOrForOfStatement(node); - break; - case SyntaxKind.IfStatement: - bindIfStatement(node); - break; - case SyntaxKind.ReturnStatement: - case SyntaxKind.ThrowStatement: - bindReturnOrThrow(node); - break; - case SyntaxKind.BreakStatement: - case SyntaxKind.ContinueStatement: - bindBreakOrContinueStatement(node); - break; - case SyntaxKind.TryStatement: - bindTryStatement(node); - break; - case SyntaxKind.SwitchStatement: - bindSwitchStatement(node); - break; - case SyntaxKind.CaseBlock: - bindCaseBlock(node); - break; - case SyntaxKind.CaseClause: - bindCaseClause(node); - break; - case SyntaxKind.LabeledStatement: - bindLabeledStatement(node); - break; - case SyntaxKind.PrefixUnaryExpression: - bindPrefixUnaryExpressionFlow(node); - break; - case SyntaxKind.PostfixUnaryExpression: - bindPostfixUnaryExpressionFlow(node); - break; - case SyntaxKind.BinaryExpression: - bindBinaryExpressionFlow(node); - break; - case SyntaxKind.DeleteExpression: - bindDeleteExpressionFlow(node); - break; - case SyntaxKind.ConditionalExpression: - bindConditionalExpressionFlow(node); - break; - case SyntaxKind.VariableDeclaration: - bindVariableDeclarationFlow(node); - break; - case SyntaxKind.CallExpression: - bindCallExpressionFlow(node); - break; - default: - forEachChild(node, bind); - break; - } - } - - function isNarrowingExpression(expr: Expression): boolean { - switch (expr.kind) { - case SyntaxKind.Identifier: - case SyntaxKind.ThisKeyword: - case SyntaxKind.PropertyAccessExpression: - return isNarrowableReference(expr); - case SyntaxKind.CallExpression: - return hasNarrowableArgument(expr); - case SyntaxKind.ParenthesizedExpression: - return isNarrowingExpression((expr).expression); - case SyntaxKind.BinaryExpression: - return isNarrowingBinaryExpression(expr); - case SyntaxKind.PrefixUnaryExpression: - return (expr).operator === SyntaxKind.ExclamationToken && isNarrowingExpression((expr).operand); - } - return false; - } - - function isNarrowableReference(expr: Expression): boolean { - return expr.kind === SyntaxKind.Identifier || - expr.kind === SyntaxKind.ThisKeyword || - expr.kind === SyntaxKind.PropertyAccessExpression && isNarrowableReference((expr).expression); - } - - function hasNarrowableArgument(expr: CallExpression) { - if (expr.arguments) { - for (const argument of expr.arguments) { - if (isNarrowableReference(argument)) { - return true; - } - } - } - if (expr.expression.kind === SyntaxKind.PropertyAccessExpression && - isNarrowableReference((expr.expression).expression)) { - return true; - } - return false; - } - - function isNarrowingTypeofOperands(expr1: Expression, expr2: Expression) { - return expr1.kind === SyntaxKind.TypeOfExpression && isNarrowableOperand((expr1).expression) && expr2.kind === SyntaxKind.StringLiteral; - } - - function isNarrowingBinaryExpression(expr: BinaryExpression) { - switch (expr.operatorToken.kind) { - case SyntaxKind.EqualsToken: - return isNarrowableReference(expr.left); - case SyntaxKind.EqualsEqualsToken: - case SyntaxKind.ExclamationEqualsToken: - case SyntaxKind.EqualsEqualsEqualsToken: - case SyntaxKind.ExclamationEqualsEqualsToken: - return isNarrowableOperand(expr.left) || isNarrowableOperand(expr.right) || - isNarrowingTypeofOperands(expr.right, expr.left) || isNarrowingTypeofOperands(expr.left, expr.right); - case SyntaxKind.InstanceOfKeyword: - return isNarrowableOperand(expr.left); - case SyntaxKind.CommaToken: - return isNarrowingExpression(expr.right); - } - return false; - } - - function isNarrowableOperand(expr: Expression): boolean { - switch (expr.kind) { - case SyntaxKind.ParenthesizedExpression: - return isNarrowableOperand((expr).expression); - case SyntaxKind.BinaryExpression: - switch ((expr).operatorToken.kind) { - case SyntaxKind.EqualsToken: - return isNarrowableOperand((expr).left); - case SyntaxKind.CommaToken: - return isNarrowableOperand((expr).right); - } - } - return isNarrowableReference(expr); - } - - function createBranchLabel(): FlowLabel { - return { - flags: FlowFlags.BranchLabel, - antecedents: undefined - }; - } - - function createLoopLabel(): FlowLabel { - return { - flags: FlowFlags.LoopLabel, - antecedents: undefined - }; - } - - function setFlowNodeReferenced(flow: FlowNode) { - // On first reference we set the Referenced flag, thereafter we set the Shared flag - flow.flags |= flow.flags & FlowFlags.Referenced ? FlowFlags.Shared : FlowFlags.Referenced; - } - - function addAntecedent(label: FlowLabel, antecedent: FlowNode): void { - if (!(antecedent.flags & FlowFlags.Unreachable) && !contains(label.antecedents, antecedent)) { - (label.antecedents || (label.antecedents = [])).push(antecedent); - setFlowNodeReferenced(antecedent); - } - } - - function createFlowCondition(flags: FlowFlags, antecedent: FlowNode, expression: Expression): FlowNode { - if (antecedent.flags & FlowFlags.Unreachable) { - return antecedent; - } - if (!expression) { - return flags & FlowFlags.TrueCondition ? antecedent : unreachableFlow; - } - if (expression.kind === SyntaxKind.TrueKeyword && flags & FlowFlags.FalseCondition || - expression.kind === SyntaxKind.FalseKeyword && flags & FlowFlags.TrueCondition) { - return unreachableFlow; - } - if (!isNarrowingExpression(expression)) { - return antecedent; - } - setFlowNodeReferenced(antecedent); - return { - flags, - expression, - antecedent - }; - } - - function createFlowSwitchClause(antecedent: FlowNode, switchStatement: SwitchStatement, clauseStart: number, clauseEnd: number): FlowNode { - if (!isNarrowingExpression(switchStatement.expression)) { - return antecedent; - } - setFlowNodeReferenced(antecedent); - return { - flags: FlowFlags.SwitchClause, - switchStatement, - clauseStart, - clauseEnd, - antecedent - }; - } - - function createFlowAssignment(antecedent: FlowNode, node: Expression | VariableDeclaration | BindingElement): FlowNode { - setFlowNodeReferenced(antecedent); - return { - flags: FlowFlags.Assignment, - antecedent, - node - }; - } - - function createFlowArrayMutation(antecedent: FlowNode, node: CallExpression | BinaryExpression): FlowNode { - setFlowNodeReferenced(antecedent); - return { - flags: FlowFlags.ArrayMutation, - antecedent, - node - }; - } - - function finishFlowLabel(flow: FlowLabel): FlowNode { - const antecedents = flow.antecedents; - if (!antecedents) { - return unreachableFlow; - } - if (antecedents.length === 1) { - return antecedents[0]; - } - return flow; - } - - function isStatementCondition(node: Node) { - const parent = node.parent; - switch (parent.kind) { - case SyntaxKind.IfStatement: - case SyntaxKind.WhileStatement: - case SyntaxKind.DoStatement: - return (parent).expression === node; - case SyntaxKind.ForStatement: - case SyntaxKind.ConditionalExpression: - return (parent).condition === node; - } - return false; - } - - function isLogicalExpression(node: Node) { - while (true) { - if (node.kind === SyntaxKind.ParenthesizedExpression) { - node = (node).expression; - } - else if (node.kind === SyntaxKind.PrefixUnaryExpression && (node).operator === SyntaxKind.ExclamationToken) { - node = (node).operand; - } - else { - return node.kind === SyntaxKind.BinaryExpression && ( - (node).operatorToken.kind === SyntaxKind.AmpersandAmpersandToken || - (node).operatorToken.kind === SyntaxKind.BarBarToken); - } - } - } - - function isTopLevelLogicalExpression(node: Node): boolean { - while (node.parent.kind === SyntaxKind.ParenthesizedExpression || - node.parent.kind === SyntaxKind.PrefixUnaryExpression && - (node.parent).operator === SyntaxKind.ExclamationToken) { - node = node.parent; - } - return !isStatementCondition(node) && !isLogicalExpression(node.parent); - } - - function bindCondition(node: Expression, trueTarget: FlowLabel, falseTarget: FlowLabel) { - const saveTrueTarget = currentTrueTarget; - const saveFalseTarget = currentFalseTarget; - currentTrueTarget = trueTarget; - currentFalseTarget = falseTarget; - bind(node); - currentTrueTarget = saveTrueTarget; - currentFalseTarget = saveFalseTarget; - if (!node || !isLogicalExpression(node)) { - addAntecedent(trueTarget, createFlowCondition(FlowFlags.TrueCondition, currentFlow, node)); - addAntecedent(falseTarget, createFlowCondition(FlowFlags.FalseCondition, currentFlow, node)); - } - } - - function bindIterativeStatement(node: Statement, breakTarget: FlowLabel, continueTarget: FlowLabel): void { - const saveBreakTarget = currentBreakTarget; - const saveContinueTarget = currentContinueTarget; - currentBreakTarget = breakTarget; - currentContinueTarget = continueTarget; - bind(node); - currentBreakTarget = saveBreakTarget; - currentContinueTarget = saveContinueTarget; - } - - function bindWhileStatement(node: WhileStatement): void { - const preWhileLabel = createLoopLabel(); - const preBodyLabel = createBranchLabel(); - const postWhileLabel = createBranchLabel(); - addAntecedent(preWhileLabel, currentFlow); - currentFlow = preWhileLabel; - bindCondition(node.expression, preBodyLabel, postWhileLabel); - currentFlow = finishFlowLabel(preBodyLabel); - bindIterativeStatement(node.statement, postWhileLabel, preWhileLabel); - addAntecedent(preWhileLabel, currentFlow); - currentFlow = finishFlowLabel(postWhileLabel); - } - - function bindDoStatement(node: DoStatement): void { - const preDoLabel = createLoopLabel(); - const preConditionLabel = createBranchLabel(); - const postDoLabel = createBranchLabel(); - addAntecedent(preDoLabel, currentFlow); - currentFlow = preDoLabel; - bindIterativeStatement(node.statement, postDoLabel, preConditionLabel); - addAntecedent(preConditionLabel, currentFlow); - currentFlow = finishFlowLabel(preConditionLabel); - bindCondition(node.expression, preDoLabel, postDoLabel); - currentFlow = finishFlowLabel(postDoLabel); - } - - function bindForStatement(node: ForStatement): void { - const preLoopLabel = createLoopLabel(); - const preBodyLabel = createBranchLabel(); - const postLoopLabel = createBranchLabel(); - bind(node.initializer); - addAntecedent(preLoopLabel, currentFlow); - currentFlow = preLoopLabel; - bindCondition(node.condition, preBodyLabel, postLoopLabel); - currentFlow = finishFlowLabel(preBodyLabel); - bindIterativeStatement(node.statement, postLoopLabel, preLoopLabel); - bind(node.incrementor); - addAntecedent(preLoopLabel, currentFlow); - currentFlow = finishFlowLabel(postLoopLabel); - } - - function bindForInOrForOfStatement(node: ForInStatement | ForOfStatement): void { - const preLoopLabel = createLoopLabel(); - const postLoopLabel = createBranchLabel(); - addAntecedent(preLoopLabel, currentFlow); - currentFlow = preLoopLabel; - bind(node.expression); - addAntecedent(postLoopLabel, currentFlow); - bind(node.initializer); - if (node.initializer.kind !== SyntaxKind.VariableDeclarationList) { - bindAssignmentTargetFlow(node.initializer); - } - bindIterativeStatement(node.statement, postLoopLabel, preLoopLabel); - addAntecedent(preLoopLabel, currentFlow); - currentFlow = finishFlowLabel(postLoopLabel); - } - - function bindIfStatement(node: IfStatement): void { - const thenLabel = createBranchLabel(); - const elseLabel = createBranchLabel(); - const postIfLabel = createBranchLabel(); - bindCondition(node.expression, thenLabel, elseLabel); - currentFlow = finishFlowLabel(thenLabel); - bind(node.thenStatement); - addAntecedent(postIfLabel, currentFlow); - currentFlow = finishFlowLabel(elseLabel); - bind(node.elseStatement); - addAntecedent(postIfLabel, currentFlow); - currentFlow = finishFlowLabel(postIfLabel); - } - - function bindReturnOrThrow(node: ReturnStatement | ThrowStatement): void { - bind(node.expression); - if (node.kind === SyntaxKind.ReturnStatement) { - hasExplicitReturn = true; - if (currentReturnTarget) { - addAntecedent(currentReturnTarget, currentFlow); - } - } - currentFlow = unreachableFlow; - } - - function findActiveLabel(name: string) { - if (activeLabels) { - for (const label of activeLabels) { - if (label.name === name) { - return label; - } - } - } - return undefined; - } - - function bindbreakOrContinueFlow(node: BreakOrContinueStatement, breakTarget: FlowLabel, continueTarget: FlowLabel) { - const flowLabel = node.kind === SyntaxKind.BreakStatement ? breakTarget : continueTarget; - if (flowLabel) { - addAntecedent(flowLabel, currentFlow); - currentFlow = unreachableFlow; - } - } - - function bindBreakOrContinueStatement(node: BreakOrContinueStatement): void { - bind(node.label); - if (node.label) { - const activeLabel = findActiveLabel(node.label.text); - if (activeLabel) { - activeLabel.referenced = true; - bindbreakOrContinueFlow(node, activeLabel.breakTarget, activeLabel.continueTarget); - } - } - else { - bindbreakOrContinueFlow(node, currentBreakTarget, currentContinueTarget); - } - } - - function bindTryStatement(node: TryStatement): void { - const postFinallyLabel = createBranchLabel(); - const preTryFlow = currentFlow; - // TODO: Every statement in try block is potentially an exit point! - bind(node.tryBlock); - addAntecedent(postFinallyLabel, currentFlow); - if (node.catchClause) { - currentFlow = preTryFlow; - bind(node.catchClause); - addAntecedent(postFinallyLabel, currentFlow); - } - if (node.finallyBlock) { - currentFlow = preTryFlow; - bind(node.finallyBlock); - } - // if try statement has finally block and flow after finally block is unreachable - keep it - // otherwise use whatever flow was accumulated at postFinallyLabel - if (!node.finallyBlock || !(currentFlow.flags & FlowFlags.Unreachable)) { - currentFlow = finishFlowLabel(postFinallyLabel); - } - } - - function bindSwitchStatement(node: SwitchStatement): void { - const postSwitchLabel = createBranchLabel(); - bind(node.expression); - const saveBreakTarget = currentBreakTarget; - const savePreSwitchCaseFlow = preSwitchCaseFlow; - currentBreakTarget = postSwitchLabel; - preSwitchCaseFlow = currentFlow; - bind(node.caseBlock); - addAntecedent(postSwitchLabel, currentFlow); - const hasDefault = forEach(node.caseBlock.clauses, c => c.kind === SyntaxKind.DefaultClause); - // We mark a switch statement as possibly exhaustive if it has no default clause and if all - // case clauses have unreachable end points (e.g. they all return). - node.possiblyExhaustive = !hasDefault && !postSwitchLabel.antecedents; - if (!hasDefault) { - addAntecedent(postSwitchLabel, createFlowSwitchClause(preSwitchCaseFlow, node, 0, 0)); - } - currentBreakTarget = saveBreakTarget; - preSwitchCaseFlow = savePreSwitchCaseFlow; - currentFlow = finishFlowLabel(postSwitchLabel); - } - - function bindCaseBlock(node: CaseBlock): void { - const clauses = node.clauses; - let fallthroughFlow = unreachableFlow; - for (let i = 0; i < clauses.length; i++) { - const clauseStart = i; - while (!clauses[i].statements.length && i + 1 < clauses.length) { - bind(clauses[i]); - i++; - } - const preCaseLabel = createBranchLabel(); - addAntecedent(preCaseLabel, createFlowSwitchClause(preSwitchCaseFlow, node.parent, clauseStart, i + 1)); - addAntecedent(preCaseLabel, fallthroughFlow); - currentFlow = finishFlowLabel(preCaseLabel); - const clause = clauses[i]; - bind(clause); - fallthroughFlow = currentFlow; - if (!(currentFlow.flags & FlowFlags.Unreachable) && i !== clauses.length - 1 && options.noFallthroughCasesInSwitch) { - errorOnFirstToken(clause, Diagnostics.Fallthrough_case_in_switch); - } - } - } - - function bindCaseClause(node: CaseClause): void { - const saveCurrentFlow = currentFlow; - currentFlow = preSwitchCaseFlow; - bind(node.expression); - currentFlow = saveCurrentFlow; - forEach(node.statements, bind); - } - - function pushActiveLabel(name: string, breakTarget: FlowLabel, continueTarget: FlowLabel): ActiveLabel { - const activeLabel = { - name, - breakTarget, - continueTarget, - referenced: false - }; - (activeLabels || (activeLabels = [])).push(activeLabel); - return activeLabel; - } - - function popActiveLabel() { - activeLabels.pop(); - } - - function bindLabeledStatement(node: LabeledStatement): void { - const preStatementLabel = createLoopLabel(); - const postStatementLabel = createBranchLabel(); - bind(node.label); - addAntecedent(preStatementLabel, currentFlow); - const activeLabel = pushActiveLabel(node.label.text, postStatementLabel, preStatementLabel); - bind(node.statement); - popActiveLabel(); - if (!activeLabel.referenced && !options.allowUnusedLabels) { - file.bindDiagnostics.push(createDiagnosticForNode(node.label, Diagnostics.Unused_label)); - } - addAntecedent(postStatementLabel, currentFlow); - currentFlow = finishFlowLabel(postStatementLabel); - } - - function bindDestructuringTargetFlow(node: Expression) { - if (node.kind === SyntaxKind.BinaryExpression && (node).operatorToken.kind === SyntaxKind.EqualsToken) { - bindAssignmentTargetFlow((node).left); - } - else { - bindAssignmentTargetFlow(node); - } - } - - function bindAssignmentTargetFlow(node: Expression) { - if (isNarrowableReference(node)) { - currentFlow = createFlowAssignment(currentFlow, node); - } - else if (node.kind === SyntaxKind.ArrayLiteralExpression) { - for (const e of (node).elements) { - if (e.kind === SyntaxKind.SpreadElementExpression) { - bindAssignmentTargetFlow((e).expression); - } - else { - bindDestructuringTargetFlow(e); - } - } - } - else if (node.kind === SyntaxKind.ObjectLiteralExpression) { - for (const p of (node).properties) { - if (p.kind === SyntaxKind.PropertyAssignment) { - bindDestructuringTargetFlow((p).initializer); - } - else if (p.kind === SyntaxKind.ShorthandPropertyAssignment) { - bindAssignmentTargetFlow((p).name); - } - } - } - } - - function bindLogicalExpression(node: BinaryExpression, trueTarget: FlowLabel, falseTarget: FlowLabel) { - const preRightLabel = createBranchLabel(); - if (node.operatorToken.kind === SyntaxKind.AmpersandAmpersandToken) { - bindCondition(node.left, preRightLabel, falseTarget); - } - else { - bindCondition(node.left, trueTarget, preRightLabel); - } - currentFlow = finishFlowLabel(preRightLabel); - bind(node.operatorToken); - bindCondition(node.right, trueTarget, falseTarget); - } - - function bindPrefixUnaryExpressionFlow(node: PrefixUnaryExpression) { - if (node.operator === SyntaxKind.ExclamationToken) { - const saveTrueTarget = currentTrueTarget; - currentTrueTarget = currentFalseTarget; - currentFalseTarget = saveTrueTarget; - forEachChild(node, bind); - currentFalseTarget = currentTrueTarget; - currentTrueTarget = saveTrueTarget; - } - else { - forEachChild(node, bind); - if (node.operator === SyntaxKind.PlusPlusToken || node.operator === SyntaxKind.MinusMinusToken) { - bindAssignmentTargetFlow(node.operand); - } - } - } - - function bindPostfixUnaryExpressionFlow(node: PostfixUnaryExpression) { - forEachChild(node, bind); - if (node.operator === SyntaxKind.PlusPlusToken || node.operator === SyntaxKind.MinusMinusToken) { - bindAssignmentTargetFlow(node.operand); - } - } - - function bindBinaryExpressionFlow(node: BinaryExpression) { - const operator = node.operatorToken.kind; - if (operator === SyntaxKind.AmpersandAmpersandToken || operator === SyntaxKind.BarBarToken) { - if (isTopLevelLogicalExpression(node)) { - const postExpressionLabel = createBranchLabel(); - bindLogicalExpression(node, postExpressionLabel, postExpressionLabel); - currentFlow = finishFlowLabel(postExpressionLabel); - } - else { - bindLogicalExpression(node, currentTrueTarget, currentFalseTarget); - } - } - else { - forEachChild(node, bind); - if (operator === SyntaxKind.EqualsToken && !isAssignmentTarget(node)) { - bindAssignmentTargetFlow(node.left); - if (node.left.kind === SyntaxKind.ElementAccessExpression) { - const elementAccess = node.left; - if (isNarrowableOperand(elementAccess.expression)) { - currentFlow = createFlowArrayMutation(currentFlow, node); - } - } - } - } - } - - function bindDeleteExpressionFlow(node: DeleteExpression) { - forEachChild(node, bind); - if (node.expression.kind === SyntaxKind.PropertyAccessExpression) { - bindAssignmentTargetFlow(node.expression); - } - } - - function bindConditionalExpressionFlow(node: ConditionalExpression) { - const trueLabel = createBranchLabel(); - const falseLabel = createBranchLabel(); - const postExpressionLabel = createBranchLabel(); - bindCondition(node.condition, trueLabel, falseLabel); - currentFlow = finishFlowLabel(trueLabel); - bind(node.whenTrue); - addAntecedent(postExpressionLabel, currentFlow); - currentFlow = finishFlowLabel(falseLabel); - bind(node.whenFalse); - addAntecedent(postExpressionLabel, currentFlow); - currentFlow = finishFlowLabel(postExpressionLabel); - } - - function bindInitializedVariableFlow(node: VariableDeclaration | ArrayBindingElement) { - const name = !isOmittedExpression(node) ? node.name : undefined; - if (isBindingPattern(name)) { - for (const child of name.elements) { - bindInitializedVariableFlow(child); - } - } - else { - currentFlow = createFlowAssignment(currentFlow, node); - } - } - - function bindVariableDeclarationFlow(node: VariableDeclaration) { - forEachChild(node, bind); - if (node.initializer || node.parent.parent.kind === SyntaxKind.ForInStatement || node.parent.parent.kind === SyntaxKind.ForOfStatement) { - bindInitializedVariableFlow(node); - } - } - - function bindCallExpressionFlow(node: CallExpression) { - // If the target of the call expression is a function expression or arrow function we have - // an immediately invoked function expression (IIFE). Initialize the flowNode property to - // the current control flow (which includes evaluation of the IIFE arguments). - let expr: Expression = node.expression; - while (expr.kind === SyntaxKind.ParenthesizedExpression) { - expr = (expr).expression; - } - if (expr.kind === SyntaxKind.FunctionExpression || expr.kind === SyntaxKind.ArrowFunction) { - forEach(node.typeArguments, bind); - forEach(node.arguments, bind); - bind(node.expression); - } - else { - forEachChild(node, bind); - } - if (node.expression.kind === SyntaxKind.PropertyAccessExpression) { - const propertyAccess = node.expression; - if (isNarrowableOperand(propertyAccess.expression) && isPushOrUnshiftIdentifier(propertyAccess.name)) { - currentFlow = createFlowArrayMutation(currentFlow, node); - } - } - } - - function getContainerFlags(node: Node): ContainerFlags { - switch (node.kind) { - case SyntaxKind.ClassExpression: - case SyntaxKind.ClassDeclaration: - case SyntaxKind.EnumDeclaration: - case SyntaxKind.ObjectLiteralExpression: - case SyntaxKind.TypeLiteral: - case SyntaxKind.JSDocTypeLiteral: - case SyntaxKind.JSDocRecordType: - return ContainerFlags.IsContainer; - - case SyntaxKind.InterfaceDeclaration: - return ContainerFlags.IsContainer | ContainerFlags.IsInterface; - - case SyntaxKind.JSDocFunctionType: - case SyntaxKind.ModuleDeclaration: - case SyntaxKind.TypeAliasDeclaration: - return ContainerFlags.IsContainer | ContainerFlags.HasLocals; - - case SyntaxKind.SourceFile: - return ContainerFlags.IsContainer | ContainerFlags.IsControlFlowContainer | ContainerFlags.HasLocals; - - case SyntaxKind.MethodDeclaration: - if (isObjectLiteralOrClassExpressionMethod(node)) { - return ContainerFlags.IsContainer | ContainerFlags.IsControlFlowContainer | ContainerFlags.HasLocals | ContainerFlags.IsFunctionLike | ContainerFlags.IsObjectLiteralOrClassExpressionMethod; - } - case SyntaxKind.Constructor: - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.MethodSignature: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - case SyntaxKind.CallSignature: - case SyntaxKind.ConstructSignature: - case SyntaxKind.IndexSignature: - case SyntaxKind.FunctionType: - case SyntaxKind.ConstructorType: - return ContainerFlags.IsContainer | ContainerFlags.IsControlFlowContainer | ContainerFlags.HasLocals | ContainerFlags.IsFunctionLike; - - case SyntaxKind.FunctionExpression: - case SyntaxKind.ArrowFunction: - return ContainerFlags.IsContainer | ContainerFlags.IsControlFlowContainer | ContainerFlags.HasLocals | ContainerFlags.IsFunctionLike | ContainerFlags.IsFunctionExpression; - - case SyntaxKind.ModuleBlock: - return ContainerFlags.IsControlFlowContainer; - case SyntaxKind.PropertyDeclaration: - return (node).initializer ? ContainerFlags.IsControlFlowContainer : 0; - - case SyntaxKind.CatchClause: - case SyntaxKind.ForStatement: - case SyntaxKind.ForInStatement: - case SyntaxKind.ForOfStatement: - case SyntaxKind.CaseBlock: - return ContainerFlags.IsBlockScopedContainer; - - case SyntaxKind.Block: - // do not treat blocks directly inside a function as a block-scoped-container. - // Locals that reside in this block should go to the function locals. Otherwise 'x' - // would not appear to be a redeclaration of a block scoped local in the following - // example: - // - // function foo() { - // var x; - // let x; - // } - // - // If we placed 'var x' into the function locals and 'let x' into the locals of - // the block, then there would be no collision. - // - // By not creating a new block-scoped-container here, we ensure that both 'var x' - // and 'let x' go into the Function-container's locals, and we do get a collision - // conflict. - return isFunctionLike(node.parent) ? ContainerFlags.None : ContainerFlags.IsBlockScopedContainer; - } - - return ContainerFlags.None; - } - - function addToContainerChain(next: Node) { - if (lastContainer) { - lastContainer.nextContainer = next; - } - - lastContainer = next; - } - - function declareSymbolAndAddToSymbolTable(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): Symbol { - // Just call this directly so that the return type of this function stays "void". - return declareSymbolAndAddToSymbolTableWorker(node, symbolFlags, symbolExcludes); - } - - function declareSymbolAndAddToSymbolTableWorker(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): Symbol { - switch (container.kind) { - // Modules, source files, and classes need specialized handling for how their - // members are declared (for example, a member of a class will go into a specific - // symbol table depending on if it is static or not). We defer to specialized - // handlers to take care of declaring these child members. - case SyntaxKind.ModuleDeclaration: - return declareModuleMember(node, symbolFlags, symbolExcludes); - - case SyntaxKind.SourceFile: - return declareSourceFileMember(node, symbolFlags, symbolExcludes); - - case SyntaxKind.ClassExpression: - case SyntaxKind.ClassDeclaration: - return declareClassMember(node, symbolFlags, symbolExcludes); - - case SyntaxKind.EnumDeclaration: - return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes); - - case SyntaxKind.TypeLiteral: - case SyntaxKind.ObjectLiteralExpression: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.JSDocRecordType: - case SyntaxKind.JSDocTypeLiteral: - // Interface/Object-types always have their children added to the 'members' of - // their container. They are only accessible through an instance of their - // container, and are never in scope otherwise (even inside the body of the - // object / type / interface declaring them). An exception is type parameters, - // which are in scope without qualification (similar to 'locals'). - return declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes); - - case SyntaxKind.FunctionType: - case SyntaxKind.ConstructorType: - case SyntaxKind.CallSignature: - case SyntaxKind.ConstructSignature: - case SyntaxKind.IndexSignature: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.MethodSignature: - case SyntaxKind.Constructor: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.FunctionExpression: - case SyntaxKind.ArrowFunction: - case SyntaxKind.JSDocFunctionType: - case SyntaxKind.TypeAliasDeclaration: - // All the children of these container types are never visible through another - // symbol (i.e. through another symbol's 'exports' or 'members'). Instead, - // they're only accessed 'lexically' (i.e. from code that exists underneath - // their container in the tree. To accomplish this, we simply add their declared - // symbol to the 'locals' of the container. These symbols can then be found as - // the type checker walks up the containers, checking them for matching names. - return declareSymbol(container.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes); - } - } - - function declareClassMember(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) { - return hasModifier(node, ModifierFlags.Static) - ? declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes) - : declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes); - } - - function declareSourceFileMember(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) { - return isExternalModule(file) - ? declareModuleMember(node, symbolFlags, symbolExcludes) - : declareSymbol(file.locals, undefined, node, symbolFlags, symbolExcludes); - } - - function hasExportDeclarations(node: ModuleDeclaration | SourceFile): boolean { - const body = node.kind === SyntaxKind.SourceFile ? node : (node).body; - if (body && (body.kind === SyntaxKind.SourceFile || body.kind === SyntaxKind.ModuleBlock)) { - for (const stat of (body).statements) { - if (stat.kind === SyntaxKind.ExportDeclaration || stat.kind === SyntaxKind.ExportAssignment) { - return true; - } - } - } - return false; - } - - function setExportContextFlag(node: ModuleDeclaration | SourceFile) { - // A declaration source file or ambient module declaration that contains no export declarations (but possibly regular - // declarations with export modifiers) is an export context in which declarations are implicitly exported. - if (isInAmbientContext(node) && !hasExportDeclarations(node)) { - node.flags |= NodeFlags.ExportContext; - } - else { - node.flags &= ~NodeFlags.ExportContext; - } - } - - function bindModuleDeclaration(node: ModuleDeclaration) { - setExportContextFlag(node); - if (isAmbientModule(node)) { - if (hasModifier(node, ModifierFlags.Export)) { - errorOnFirstToken(node, Diagnostics.export_modifier_cannot_be_applied_to_ambient_modules_and_module_augmentations_since_they_are_always_visible); - } - if (isExternalModuleAugmentation(node)) { - declareSymbolAndAddToSymbolTable(node, SymbolFlags.NamespaceModule, SymbolFlags.NamespaceModuleExcludes); - } - else { - let pattern: Pattern | undefined; - if (node.name.kind === SyntaxKind.StringLiteral) { - const text = (node.name).text; - if (hasZeroOrOneAsteriskCharacter(text)) { - pattern = tryParsePattern(text); - } - else { - errorOnFirstToken(node.name, Diagnostics.Pattern_0_can_have_at_most_one_Asterisk_character, text); - } - } - - const symbol = declareSymbolAndAddToSymbolTable(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes); - - if (pattern) { - (file.patternAmbientModules || (file.patternAmbientModules = [])).push({ pattern, symbol }); - } - } - } - else { - const state = getModuleInstanceState(node); - if (state === ModuleInstanceState.NonInstantiated) { - declareSymbolAndAddToSymbolTable(node, SymbolFlags.NamespaceModule, SymbolFlags.NamespaceModuleExcludes); - } - else { - declareSymbolAndAddToSymbolTable(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes); - if (node.symbol.flags & (SymbolFlags.Function | SymbolFlags.Class | SymbolFlags.RegularEnum)) { - // if module was already merged with some function, class or non-const enum - // treat is a non-const-enum-only - node.symbol.constEnumOnlyModule = false; - } - else { - const currentModuleIsConstEnumOnly = state === ModuleInstanceState.ConstEnumOnly; - if (node.symbol.constEnumOnlyModule === undefined) { - // non-merged case - use the current state - node.symbol.constEnumOnlyModule = currentModuleIsConstEnumOnly; - } - else { - // merged case: module is const enum only if all its pieces are non-instantiated or const enum - node.symbol.constEnumOnlyModule = node.symbol.constEnumOnlyModule && currentModuleIsConstEnumOnly; - } - } - } - } - } - - function bindFunctionOrConstructorType(node: SignatureDeclaration): void { - // For a given function symbol "<...>(...) => T" we want to generate a symbol identical - // to the one we would get for: { <...>(...): T } - // - // We do that by making an anonymous type literal symbol, and then setting the function - // symbol as its sole member. To the rest of the system, this symbol will be indistinguishable - // from an actual type literal symbol you would have gotten had you used the long form. - const symbol = createSymbol(SymbolFlags.Signature, getDeclarationName(node)); - addDeclarationToSymbol(symbol, node, SymbolFlags.Signature); - - const typeLiteralSymbol = createSymbol(SymbolFlags.TypeLiteral, "__type"); - addDeclarationToSymbol(typeLiteralSymbol, node, SymbolFlags.TypeLiteral); - typeLiteralSymbol.members = createMap(); - typeLiteralSymbol.members[symbol.name] = symbol; - } - - function bindObjectLiteralExpression(node: ObjectLiteralExpression) { - const enum ElementKind { - Property = 1, - Accessor = 2 - } - - if (inStrictMode) { - const seen = createMap(); - - for (const prop of node.properties) { - if (prop.name.kind !== SyntaxKind.Identifier) { - continue; - } - - const identifier = prop.name; - - // ECMA-262 11.1.5 Object Initializer - // If previous is not undefined then throw a SyntaxError exception if any of the following conditions are true - // a.This production is contained in strict code and IsDataDescriptor(previous) is true and - // IsDataDescriptor(propId.descriptor) is true. - // b.IsDataDescriptor(previous) is true and IsAccessorDescriptor(propId.descriptor) is true. - // c.IsAccessorDescriptor(previous) is true and IsDataDescriptor(propId.descriptor) is true. - // d.IsAccessorDescriptor(previous) is true and IsAccessorDescriptor(propId.descriptor) is true - // and either both previous and propId.descriptor have[[Get]] fields or both previous and propId.descriptor have[[Set]] fields - const currentKind = prop.kind === SyntaxKind.PropertyAssignment || prop.kind === SyntaxKind.ShorthandPropertyAssignment || prop.kind === SyntaxKind.MethodDeclaration - ? ElementKind.Property - : ElementKind.Accessor; - - const existingKind = seen[identifier.text]; - if (!existingKind) { - seen[identifier.text] = currentKind; - continue; - } - - if (currentKind === ElementKind.Property && existingKind === ElementKind.Property) { - const span = getErrorSpanForNode(file, identifier); - file.bindDiagnostics.push(createFileDiagnostic(file, span.start, span.length, - Diagnostics.An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode)); - } - } - } - - return bindAnonymousDeclaration(node, SymbolFlags.ObjectLiteral, "__object"); - } - - function bindAnonymousDeclaration(node: Declaration, symbolFlags: SymbolFlags, name: string) { - const symbol = createSymbol(symbolFlags, name); - addDeclarationToSymbol(symbol, node, symbolFlags); - } - - function bindBlockScopedDeclaration(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) { - switch (blockScopeContainer.kind) { - case SyntaxKind.ModuleDeclaration: - declareModuleMember(node, symbolFlags, symbolExcludes); - break; - case SyntaxKind.SourceFile: - if (isExternalModule(container)) { - declareModuleMember(node, symbolFlags, symbolExcludes); - break; - } - // fall through. - default: - if (!blockScopeContainer.locals) { - blockScopeContainer.locals = createMap(); - addToContainerChain(blockScopeContainer); - } - declareSymbol(blockScopeContainer.locals, undefined, node, symbolFlags, symbolExcludes); - } - } - - function bindBlockScopedVariableDeclaration(node: Declaration) { - bindBlockScopedDeclaration(node, SymbolFlags.BlockScopedVariable, SymbolFlags.BlockScopedVariableExcludes); - } - - // The binder visits every node in the syntax tree so it is a convenient place to perform a single localized - // check for reserved words used as identifiers in strict mode code. - function checkStrictModeIdentifier(node: Identifier) { - if (inStrictMode && - node.originalKeywordKind >= SyntaxKind.FirstFutureReservedWord && - node.originalKeywordKind <= SyntaxKind.LastFutureReservedWord && - !isIdentifierName(node) && - !isInAmbientContext(node)) { - - // Report error only if there are no parse errors in file - if (!file.parseDiagnostics.length) { - file.bindDiagnostics.push(createDiagnosticForNode(node, - getStrictModeIdentifierMessage(node), declarationNameToString(node))); - } - } - } - - function getStrictModeIdentifierMessage(node: Node) { - // Provide specialized messages to help the user understand why we think they're in - // strict mode. - if (getContainingClass(node)) { - return Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode; - } - - if (file.externalModuleIndicator) { - return Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Modules_are_automatically_in_strict_mode; - } - - return Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode; - } - - function checkStrictModeBinaryExpression(node: BinaryExpression) { - if (inStrictMode && isLeftHandSideExpression(node.left) && isAssignmentOperator(node.operatorToken.kind)) { - // ECMA 262 (Annex C) The identifier eval or arguments may not appear as the LeftHandSideExpression of an - // Assignment operator(11.13) or of a PostfixExpression(11.3) - checkStrictModeEvalOrArguments(node, node.left); - } - } - - function checkStrictModeCatchClause(node: CatchClause) { - // It is a SyntaxError if a TryStatement with a Catch occurs within strict code and the Identifier of the - // Catch production is eval or arguments - if (inStrictMode && node.variableDeclaration) { - checkStrictModeEvalOrArguments(node, node.variableDeclaration.name); - } - } - - function checkStrictModeDeleteExpression(node: DeleteExpression) { - // Grammar checking - if (inStrictMode && node.expression.kind === SyntaxKind.Identifier) { - // When a delete operator occurs within strict mode code, a SyntaxError is thrown if its - // UnaryExpression is a direct reference to a variable, function argument, or function name - const span = getErrorSpanForNode(file, node.expression); - file.bindDiagnostics.push(createFileDiagnostic(file, span.start, span.length, Diagnostics.delete_cannot_be_called_on_an_identifier_in_strict_mode)); - } - } - - function isEvalOrArgumentsIdentifier(node: Node): boolean { - return node.kind === SyntaxKind.Identifier && - ((node).text === "eval" || (node).text === "arguments"); - } - - function checkStrictModeEvalOrArguments(contextNode: Node, name: Node) { - if (name && name.kind === SyntaxKind.Identifier) { - const identifier = name; - if (isEvalOrArgumentsIdentifier(identifier)) { - // We check first if the name is inside class declaration or class expression; if so give explicit message - // otherwise report generic error message. - const span = getErrorSpanForNode(file, name); - file.bindDiagnostics.push(createFileDiagnostic(file, span.start, span.length, - getStrictModeEvalOrArgumentsMessage(contextNode), identifier.text)); - } - } - } - - function getStrictModeEvalOrArgumentsMessage(node: Node) { - // Provide specialized messages to help the user understand why we think they're in - // strict mode. - if (getContainingClass(node)) { - return Diagnostics.Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode; - } - - if (file.externalModuleIndicator) { - return Diagnostics.Invalid_use_of_0_Modules_are_automatically_in_strict_mode; - } - - return Diagnostics.Invalid_use_of_0_in_strict_mode; - } - - function checkStrictModeFunctionName(node: FunctionLikeDeclaration) { - if (inStrictMode) { - // It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a strict mode FunctionDeclaration or FunctionExpression (13.1)) - checkStrictModeEvalOrArguments(node, node.name); - } - } - - function getStrictModeBlockScopeFunctionDeclarationMessage(node: Node) { - // Provide specialized messages to help the user understand why we think they're in - // strict mode. - if (getContainingClass(node)) { - return Diagnostics.Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_Class_definitions_are_automatically_in_strict_mode; - } - - if (file.externalModuleIndicator) { - return Diagnostics.Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_Modules_are_automatically_in_strict_mode; - } - - return Diagnostics.Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5; - } - - function checkStrictModeFunctionDeclaration(node: FunctionDeclaration) { - if (languageVersion < ScriptTarget.ES2015) { - // Report error if function is not top level function declaration - if (blockScopeContainer.kind !== SyntaxKind.SourceFile && - blockScopeContainer.kind !== SyntaxKind.ModuleDeclaration && - !isFunctionLike(blockScopeContainer)) { - // We check first if the name is inside class declaration or class expression; if so give explicit message - // otherwise report generic error message. - const errorSpan = getErrorSpanForNode(file, node); - file.bindDiagnostics.push(createFileDiagnostic(file, errorSpan.start, errorSpan.length, - getStrictModeBlockScopeFunctionDeclarationMessage(node))); - } - } - } - - function checkStrictModeNumericLiteral(node: NumericLiteral) { - if (inStrictMode && node.isOctalLiteral) { - file.bindDiagnostics.push(createDiagnosticForNode(node, Diagnostics.Octal_literals_are_not_allowed_in_strict_mode)); - } - } - - function checkStrictModePostfixUnaryExpression(node: PostfixUnaryExpression) { - // Grammar checking - // The identifier eval or arguments may not appear as the LeftHandSideExpression of an - // Assignment operator(11.13) or of a PostfixExpression(11.3) or as the UnaryExpression - // operated upon by a Prefix Increment(11.4.4) or a Prefix Decrement(11.4.5) operator. - if (inStrictMode) { - checkStrictModeEvalOrArguments(node, node.operand); - } - } - - function checkStrictModePrefixUnaryExpression(node: PrefixUnaryExpression) { - // Grammar checking - if (inStrictMode) { - if (node.operator === SyntaxKind.PlusPlusToken || node.operator === SyntaxKind.MinusMinusToken) { - checkStrictModeEvalOrArguments(node, node.operand); - } - } - } - - function checkStrictModeWithStatement(node: WithStatement) { - // Grammar checking for withStatement - if (inStrictMode) { - errorOnFirstToken(node, Diagnostics.with_statements_are_not_allowed_in_strict_mode); - } - } - - function errorOnFirstToken(node: Node, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any) { - const span = getSpanOfTokenAtPosition(file, node.pos); - file.bindDiagnostics.push(createFileDiagnostic(file, span.start, span.length, message, arg0, arg1, arg2)); - } - - function getDestructuringParameterName(node: Declaration) { - return "__" + indexOf((node.parent).parameters, node); - } - - function bind(node: Node): void { - if (!node) { - return; - } - node.parent = parent; - const saveInStrictMode = inStrictMode; - // First we bind declaration nodes to a symbol if possible. We'll both create a symbol - // and then potentially add the symbol to an appropriate symbol table. Possible - // destination symbol tables are: - // - // 1) The 'exports' table of the current container's symbol. - // 2) The 'members' table of the current container's symbol. - // 3) The 'locals' table of the current container. - // - // However, not all symbols will end up in any of these tables. 'Anonymous' symbols - // (like TypeLiterals for example) will not be put in any table. - bindWorker(node); - // Then we recurse into the children of the node to bind them as well. For certain - // symbols we do specialized work when we recurse. For example, we'll keep track of - // the current 'container' node when it changes. This helps us know which symbol table - // a local should go into for example. Since terminal nodes are known not to have - // children, as an optimization we don't process those. - if (node.kind > SyntaxKind.LastToken) { - const saveParent = parent; - parent = node; - const containerFlags = getContainerFlags(node); - if (containerFlags === ContainerFlags.None) { - bindChildren(node); - } - else { - bindContainer(node, containerFlags); - } - parent = saveParent; - } - else if (!skipTransformFlagAggregation && (node.transformFlags & TransformFlags.HasComputedFlags) === 0) { - subtreeTransformFlags |= computeTransformFlagsForNode(node, 0); - } - inStrictMode = saveInStrictMode; - } - - function updateStrictModeStatementList(statements: NodeArray) { - if (!inStrictMode) { - for (const statement of statements) { - if (!isPrologueDirective(statement)) { - return; - } - - if (isUseStrictPrologueDirective(statement)) { - inStrictMode = true; - return; - } - } - } - } - - /// Should be called only on prologue directives (isPrologueDirective(node) should be true) - function isUseStrictPrologueDirective(node: ExpressionStatement): boolean { - const nodeText = getTextOfNodeFromSourceText(file.text, node.expression); - - // Note: the node text must be exactly "use strict" or 'use strict'. It is not ok for the - // string to contain unicode escapes (as per ES5). - return nodeText === '"use strict"' || nodeText === "'use strict'"; - } - - function bindWorker(node: Node) { - switch (node.kind) { - /* Strict mode checks */ - case SyntaxKind.Identifier: - case SyntaxKind.ThisKeyword: - if (currentFlow && (isExpression(node) || parent.kind === SyntaxKind.ShorthandPropertyAssignment)) { - node.flowNode = currentFlow; - } - return checkStrictModeIdentifier(node); - case SyntaxKind.PropertyAccessExpression: - if (currentFlow && isNarrowableReference(node)) { - node.flowNode = currentFlow; - } - break; - case SyntaxKind.BinaryExpression: - if (isInJavaScriptFile(node)) { - const specialKind = getSpecialPropertyAssignmentKind(node); - switch (specialKind) { - case SpecialPropertyAssignmentKind.ExportsProperty: - bindExportsPropertyAssignment(node); - break; - case SpecialPropertyAssignmentKind.ModuleExports: - bindModuleExportsAssignment(node); - break; - case SpecialPropertyAssignmentKind.PrototypeProperty: - bindPrototypePropertyAssignment(node); - break; - case SpecialPropertyAssignmentKind.ThisProperty: - bindThisPropertyAssignment(node); - break; - case SpecialPropertyAssignmentKind.None: - // Nothing to do - break; - default: - Debug.fail("Unknown special property assignment kind"); - } - } - return checkStrictModeBinaryExpression(node); - case SyntaxKind.CatchClause: - return checkStrictModeCatchClause(node); - case SyntaxKind.DeleteExpression: - return checkStrictModeDeleteExpression(node); - case SyntaxKind.NumericLiteral: - return checkStrictModeNumericLiteral(node); - case SyntaxKind.PostfixUnaryExpression: - return checkStrictModePostfixUnaryExpression(node); - case SyntaxKind.PrefixUnaryExpression: - return checkStrictModePrefixUnaryExpression(node); - case SyntaxKind.WithStatement: - return checkStrictModeWithStatement(node); - case SyntaxKind.ThisType: - seenThisKeyword = true; - return; - case SyntaxKind.TypePredicate: - return checkTypePredicate(node as TypePredicateNode); - case SyntaxKind.TypeParameter: - return declareSymbolAndAddToSymbolTable(node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes); - case SyntaxKind.Parameter: - return bindParameter(node); - case SyntaxKind.VariableDeclaration: - case SyntaxKind.BindingElement: - return bindVariableDeclarationOrBindingElement(node); - case SyntaxKind.PropertyDeclaration: - case SyntaxKind.PropertySignature: - case SyntaxKind.JSDocRecordMember: - return bindPropertyOrMethodOrAccessor(node, SymbolFlags.Property | ((node).questionToken ? SymbolFlags.Optional : SymbolFlags.None), SymbolFlags.PropertyExcludes); - case SyntaxKind.JSDocPropertyTag: - return bindJSDocProperty(node); - case SyntaxKind.PropertyAssignment: - case SyntaxKind.ShorthandPropertyAssignment: - return bindPropertyOrMethodOrAccessor(node, SymbolFlags.Property, SymbolFlags.PropertyExcludes); - case SyntaxKind.EnumMember: - return bindPropertyOrMethodOrAccessor(node, SymbolFlags.EnumMember, SymbolFlags.EnumMemberExcludes); - - case SyntaxKind.JsxSpreadAttribute: - emitFlags |= NodeFlags.HasJsxSpreadAttributes; - return; - - case SyntaxKind.CallSignature: - case SyntaxKind.ConstructSignature: - case SyntaxKind.IndexSignature: - return declareSymbolAndAddToSymbolTable(node, SymbolFlags.Signature, SymbolFlags.None); - case SyntaxKind.MethodDeclaration: - case SyntaxKind.MethodSignature: - // If this is an ObjectLiteralExpression method, then it sits in the same space - // as other properties in the object literal. So we use SymbolFlags.PropertyExcludes - // so that it will conflict with any other object literal members with the same - // name. - return bindPropertyOrMethodOrAccessor(node, SymbolFlags.Method | ((node).questionToken ? SymbolFlags.Optional : SymbolFlags.None), - isObjectLiteralMethod(node) ? SymbolFlags.PropertyExcludes : SymbolFlags.MethodExcludes); - case SyntaxKind.FunctionDeclaration: - return bindFunctionDeclaration(node); - case SyntaxKind.Constructor: - return declareSymbolAndAddToSymbolTable(node, SymbolFlags.Constructor, /*symbolExcludes:*/ SymbolFlags.None); - case SyntaxKind.GetAccessor: - return bindPropertyOrMethodOrAccessor(node, SymbolFlags.GetAccessor, SymbolFlags.GetAccessorExcludes); - case SyntaxKind.SetAccessor: - return bindPropertyOrMethodOrAccessor(node, SymbolFlags.SetAccessor, SymbolFlags.SetAccessorExcludes); - case SyntaxKind.FunctionType: - case SyntaxKind.ConstructorType: - case SyntaxKind.JSDocFunctionType: - return bindFunctionOrConstructorType(node); - case SyntaxKind.TypeLiteral: - case SyntaxKind.JSDocTypeLiteral: - case SyntaxKind.JSDocRecordType: - return bindAnonymousDeclaration(node, SymbolFlags.TypeLiteral, "__type"); - case SyntaxKind.ObjectLiteralExpression: - return bindObjectLiteralExpression(node); - case SyntaxKind.FunctionExpression: - case SyntaxKind.ArrowFunction: - return bindFunctionExpression(node); - - case SyntaxKind.CallExpression: - if (isInJavaScriptFile(node)) { - bindCallExpression(node); - } - break; - - // Members of classes, interfaces, and modules - case SyntaxKind.ClassExpression: - case SyntaxKind.ClassDeclaration: - // All classes are automatically in strict mode in ES6. - inStrictMode = true; - return bindClassLikeDeclaration(node); - case SyntaxKind.InterfaceDeclaration: - return bindBlockScopedDeclaration(node, SymbolFlags.Interface, SymbolFlags.InterfaceExcludes); - case SyntaxKind.JSDocTypedefTag: - case SyntaxKind.TypeAliasDeclaration: - return bindBlockScopedDeclaration(node, SymbolFlags.TypeAlias, SymbolFlags.TypeAliasExcludes); - case SyntaxKind.EnumDeclaration: - return bindEnumDeclaration(node); - case SyntaxKind.ModuleDeclaration: - return bindModuleDeclaration(node); - - // Imports and exports - case SyntaxKind.ImportEqualsDeclaration: - case SyntaxKind.NamespaceImport: - case SyntaxKind.ImportSpecifier: - case SyntaxKind.ExportSpecifier: - return declareSymbolAndAddToSymbolTable(node, SymbolFlags.Alias, SymbolFlags.AliasExcludes); - case SyntaxKind.NamespaceExportDeclaration: - return bindNamespaceExportDeclaration(node); - case SyntaxKind.ImportClause: - return bindImportClause(node); - case SyntaxKind.ExportDeclaration: - return bindExportDeclaration(node); - case SyntaxKind.ExportAssignment: - return bindExportAssignment(node); - case SyntaxKind.SourceFile: - updateStrictModeStatementList((node).statements); - return bindSourceFileIfExternalModule(); - case SyntaxKind.Block: - if (!isFunctionLike(node.parent)) { - return; - } - // Fall through - case SyntaxKind.ModuleBlock: - return updateStrictModeStatementList((node).statements); - } - } - - function checkTypePredicate(node: TypePredicateNode) { - const { parameterName, type } = node; - if (parameterName && parameterName.kind === SyntaxKind.Identifier) { - checkStrictModeIdentifier(parameterName as Identifier); - } - if (parameterName && parameterName.kind === SyntaxKind.ThisType) { - seenThisKeyword = true; - } - bind(type); - } - - function bindSourceFileIfExternalModule() { - setExportContextFlag(file); - if (isExternalModule(file)) { - bindSourceFileAsExternalModule(); - } - } - - function bindSourceFileAsExternalModule() { - bindAnonymousDeclaration(file, SymbolFlags.ValueModule, `"${removeFileExtension(file.fileName) }"`); - } - - function bindExportAssignment(node: ExportAssignment | BinaryExpression) { - if (!container.symbol || !container.symbol.exports) { - // Export assignment in some sort of block construct - bindAnonymousDeclaration(node, SymbolFlags.Alias, getDeclarationName(node)); - } - else { - // An export default clause with an expression exports a value - // We want to exclude both class and function here, this is necessary to issue an error when there are both - // default export-assignment and default export function and class declaration. - const flags = node.kind === SyntaxKind.ExportAssignment && exportAssignmentIsAlias(node) - // An export default clause with an EntityNameExpression exports all meanings of that identifier - ? SymbolFlags.Alias - // An export default clause with any other expression exports a value - : SymbolFlags.Property; - declareSymbol(container.symbol.exports, container.symbol, node, flags, SymbolFlags.Property | SymbolFlags.AliasExcludes | SymbolFlags.Class | SymbolFlags.Function); - } - } - - function bindNamespaceExportDeclaration(node: NamespaceExportDeclaration) { - if (node.modifiers && node.modifiers.length) { - file.bindDiagnostics.push(createDiagnosticForNode(node, Diagnostics.Modifiers_cannot_appear_here)); - } - - if (node.parent.kind !== SyntaxKind.SourceFile) { - file.bindDiagnostics.push(createDiagnosticForNode(node, Diagnostics.Global_module_exports_may_only_appear_at_top_level)); - return; - } - else { - const parent = node.parent as SourceFile; - - if (!isExternalModule(parent)) { - file.bindDiagnostics.push(createDiagnosticForNode(node, Diagnostics.Global_module_exports_may_only_appear_in_module_files)); - return; - } - - if (!parent.isDeclarationFile) { - file.bindDiagnostics.push(createDiagnosticForNode(node, Diagnostics.Global_module_exports_may_only_appear_in_declaration_files)); - return; - } - } - - file.symbol.globalExports = file.symbol.globalExports || createMap(); - declareSymbol(file.symbol.globalExports, file.symbol, node, SymbolFlags.Alias, SymbolFlags.AliasExcludes); - } - - function bindExportDeclaration(node: ExportDeclaration) { - if (!container.symbol || !container.symbol.exports) { - // Export * in some sort of block construct - bindAnonymousDeclaration(node, SymbolFlags.ExportStar, getDeclarationName(node)); - } - else if (!node.exportClause) { - // All export * declarations are collected in an __export symbol - declareSymbol(container.symbol.exports, container.symbol, node, SymbolFlags.ExportStar, SymbolFlags.None); - } - } - - function bindImportClause(node: ImportClause) { - if (node.name) { - declareSymbolAndAddToSymbolTable(node, SymbolFlags.Alias, SymbolFlags.AliasExcludes); - } - } - - function setCommonJsModuleIndicator(node: Node) { - if (!file.commonJsModuleIndicator) { - file.commonJsModuleIndicator = node; - bindSourceFileAsExternalModule(); - } - } - - function bindExportsPropertyAssignment(node: BinaryExpression) { - // When we create a property via 'exports.foo = bar', the 'exports.foo' property access - // expression is the declaration - setCommonJsModuleIndicator(node); - declareSymbol(file.symbol.exports, file.symbol, node.left, SymbolFlags.Property | SymbolFlags.Export, SymbolFlags.None); - } - - function bindModuleExportsAssignment(node: BinaryExpression) { - // 'module.exports = expr' assignment - setCommonJsModuleIndicator(node); - declareSymbol(file.symbol.exports, file.symbol, node, SymbolFlags.Property | SymbolFlags.Export | SymbolFlags.ValueModule, SymbolFlags.None); - } - - function bindThisPropertyAssignment(node: BinaryExpression) { - Debug.assert(isInJavaScriptFile(node)); - // Declare a 'member' if the container is an ES5 class or ES6 constructor - if (container.kind === SyntaxKind.FunctionDeclaration || container.kind === SyntaxKind.FunctionExpression) { - container.symbol.members = container.symbol.members || createMap(); - // It's acceptable for multiple 'this' assignments of the same identifier to occur - declareSymbol(container.symbol.members, container.symbol, node, SymbolFlags.Property, SymbolFlags.PropertyExcludes & ~SymbolFlags.Property); - } - else if (container.kind === SyntaxKind.Constructor) { - // this.foo assignment in a JavaScript class - // Bind this property to the containing class - const saveContainer = container; - container = container.parent; - const symbol = bindPropertyOrMethodOrAccessor(node, SymbolFlags.Property, SymbolFlags.None); - if (symbol) { - // constructor-declared symbols can be overwritten by subsequent method declarations - (symbol as Symbol).isReplaceableByMethod = true; - } - container = saveContainer; - } - } - - function bindPrototypePropertyAssignment(node: BinaryExpression) { - // We saw a node of the form 'x.prototype.y = z'. Declare a 'member' y on x if x was a function. - - // Look up the function in the local scope, since prototype assignments should - // follow the function declaration - const leftSideOfAssignment = node.left as PropertyAccessExpression; - const classPrototype = leftSideOfAssignment.expression as PropertyAccessExpression; - const constructorFunction = classPrototype.expression as Identifier; - - // Fix up parent pointers since we're going to use these nodes before we bind into them - leftSideOfAssignment.parent = node; - constructorFunction.parent = classPrototype; - classPrototype.parent = leftSideOfAssignment; - - const funcSymbol = container.locals[constructorFunction.text]; - if (!funcSymbol || !(funcSymbol.flags & SymbolFlags.Function || isDeclarationOfFunctionExpression(funcSymbol))) { - return; - } - - // Set up the members collection if it doesn't exist already - if (!funcSymbol.members) { - funcSymbol.members = createMap(); - } - - // Declare the method/property - declareSymbol(funcSymbol.members, funcSymbol, leftSideOfAssignment, SymbolFlags.Property, SymbolFlags.PropertyExcludes); - } - - function bindCallExpression(node: CallExpression) { - // We're only inspecting call expressions to detect CommonJS modules, so we can skip - // this check if we've already seen the module indicator - if (!file.commonJsModuleIndicator && isRequireCall(node, /*checkArgumentIsStringLiteral*/false)) { - setCommonJsModuleIndicator(node); - } - } - - function bindClassLikeDeclaration(node: ClassLikeDeclaration) { - if (!isDeclarationFile(file) && !isInAmbientContext(node)) { - if (getClassExtendsHeritageClauseElement(node) !== undefined) { - emitFlags |= NodeFlags.HasClassExtends; - } - if (nodeIsDecorated(node)) { - emitFlags |= NodeFlags.HasDecorators; - } - } - - if (node.kind === SyntaxKind.ClassDeclaration) { - bindBlockScopedDeclaration(node, SymbolFlags.Class, SymbolFlags.ClassExcludes); - } - else { - const bindingName = node.name ? node.name.text : "__class"; - bindAnonymousDeclaration(node, SymbolFlags.Class, bindingName); - // Add name of class expression into the map for semantic classifier - if (node.name) { - classifiableNames[node.name.text] = node.name.text; - } - } - - const symbol = node.symbol; - - // TypeScript 1.0 spec (April 2014): 8.4 - // Every class automatically contains a static property member named 'prototype', the - // type of which is an instantiation of the class type with type Any supplied as a type - // argument for each type parameter. It is an error to explicitly declare a static - // property member with the name 'prototype'. - // - // Note: we check for this here because this class may be merging into a module. The - // module might have an exported variable called 'prototype'. We can't allow that as - // that would clash with the built-in 'prototype' for the class. - const prototypeSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Prototype, "prototype"); - if (symbol.exports[prototypeSymbol.name]) { - if (node.name) { - node.name.parent = node; - } - file.bindDiagnostics.push(createDiagnosticForNode(symbol.exports[prototypeSymbol.name].declarations[0], - Diagnostics.Duplicate_identifier_0, prototypeSymbol.name)); - } - symbol.exports[prototypeSymbol.name] = prototypeSymbol; - prototypeSymbol.parent = symbol; - } - - function bindEnumDeclaration(node: EnumDeclaration) { - return isConst(node) - ? bindBlockScopedDeclaration(node, SymbolFlags.ConstEnum, SymbolFlags.ConstEnumExcludes) - : bindBlockScopedDeclaration(node, SymbolFlags.RegularEnum, SymbolFlags.RegularEnumExcludes); - } - - function bindVariableDeclarationOrBindingElement(node: VariableDeclaration | BindingElement) { - if (inStrictMode) { - checkStrictModeEvalOrArguments(node, node.name); - } - - if (!isBindingPattern(node.name)) { - if (isBlockOrCatchScoped(node)) { - bindBlockScopedVariableDeclaration(node); - } - else if (isParameterDeclaration(node)) { - // It is safe to walk up parent chain to find whether the node is a destructing parameter declaration - // because its parent chain has already been set up, since parents are set before descending into children. - // - // If node is a binding element in parameter declaration, we need to use ParameterExcludes. - // Using ParameterExcludes flag allows the compiler to report an error on duplicate identifiers in Parameter Declaration - // For example: - // function foo([a,a]) {} // Duplicate Identifier error - // function bar(a,a) {} // Duplicate Identifier error, parameter declaration in this case is handled in bindParameter - // // which correctly set excluded symbols - declareSymbolAndAddToSymbolTable(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes); - } - else { - declareSymbolAndAddToSymbolTable(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.FunctionScopedVariableExcludes); - } - } - } - - function bindParameter(node: ParameterDeclaration) { - if (!isDeclarationFile(file) && - !isInAmbientContext(node) && - nodeIsDecorated(node)) { - emitFlags |= (NodeFlags.HasDecorators | NodeFlags.HasParamDecorators); - } - - if (inStrictMode) { - // It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a - // strict mode FunctionLikeDeclaration or FunctionExpression(13.1) - checkStrictModeEvalOrArguments(node, node.name); - } - - if (isBindingPattern(node.name)) { - bindAnonymousDeclaration(node, SymbolFlags.FunctionScopedVariable, getDestructuringParameterName(node)); - } - else { - declareSymbolAndAddToSymbolTable(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes); - } - - // If this is a property-parameter, then also declare the property symbol into the - // containing class. - if (isParameterPropertyDeclaration(node)) { - const classDeclaration = node.parent.parent; - declareSymbol(classDeclaration.symbol.members, classDeclaration.symbol, node, SymbolFlags.Property | (node.questionToken ? SymbolFlags.Optional : SymbolFlags.None), SymbolFlags.PropertyExcludes); - } - } - - function bindFunctionDeclaration(node: FunctionDeclaration) { - if (!isDeclarationFile(file) && !isInAmbientContext(node)) { - if (isAsyncFunctionLike(node)) { - emitFlags |= NodeFlags.HasAsyncFunctions; - } - } - - checkStrictModeFunctionName(node); - if (inStrictMode) { - checkStrictModeFunctionDeclaration(node); - bindBlockScopedDeclaration(node, SymbolFlags.Function, SymbolFlags.FunctionExcludes); - } - else { - declareSymbolAndAddToSymbolTable(node, SymbolFlags.Function, SymbolFlags.FunctionExcludes); - } - } - - function bindFunctionExpression(node: FunctionExpression) { - if (!isDeclarationFile(file) && !isInAmbientContext(node)) { - if (isAsyncFunctionLike(node)) { - emitFlags |= NodeFlags.HasAsyncFunctions; - } - } - if (currentFlow) { - node.flowNode = currentFlow; - } - checkStrictModeFunctionName(node); - const bindingName = node.name ? node.name.text : "__function"; - return bindAnonymousDeclaration(node, SymbolFlags.Function, bindingName); - } - - function bindPropertyOrMethodOrAccessor(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) { - if (!isDeclarationFile(file) && !isInAmbientContext(node)) { - if (isAsyncFunctionLike(node)) { - emitFlags |= NodeFlags.HasAsyncFunctions; - } - if (nodeIsDecorated(node)) { - emitFlags |= NodeFlags.HasDecorators; - } - } - - if (currentFlow && isObjectLiteralOrClassExpressionMethod(node)) { - node.flowNode = currentFlow; - } - - return hasDynamicName(node) - ? bindAnonymousDeclaration(node, symbolFlags, "__computed") - : declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes); - } - - function bindJSDocProperty(node: JSDocPropertyTag) { - return declareSymbolAndAddToSymbolTable(node, SymbolFlags.Property, SymbolFlags.PropertyExcludes); - } - - // reachability checks - - function shouldReportErrorOnModuleDeclaration(node: ModuleDeclaration): boolean { - const instanceState = getModuleInstanceState(node); - return instanceState === ModuleInstanceState.Instantiated || (instanceState === ModuleInstanceState.ConstEnumOnly && options.preserveConstEnums); - } - - function checkUnreachable(node: Node): boolean { - if (!(currentFlow.flags & FlowFlags.Unreachable)) { - return false; - } - if (currentFlow === unreachableFlow) { - const reportError = - // report error on all statements except empty ones - (isStatementButNotDeclaration(node) && node.kind !== SyntaxKind.EmptyStatement) || - // report error on class declarations - node.kind === SyntaxKind.ClassDeclaration || - // report error on instantiated modules or const-enums only modules if preserveConstEnums is set - (node.kind === SyntaxKind.ModuleDeclaration && shouldReportErrorOnModuleDeclaration(node)) || - // report error on regular enums and const enums if preserveConstEnums is set - (node.kind === SyntaxKind.EnumDeclaration && (!isConstEnumDeclaration(node) || options.preserveConstEnums)); - - if (reportError) { - currentFlow = reportedUnreachableFlow; - - // unreachable code is reported if - // - user has explicitly asked about it AND - // - statement is in not ambient context (statements in ambient context is already an error - // so we should not report extras) AND - // - node is not variable statement OR - // - node is block scoped variable statement OR - // - node is not block scoped variable statement and at least one variable declaration has initializer - // Rationale: we don't want to report errors on non-initialized var's since they are hoisted - // On the other side we do want to report errors on non-initialized 'lets' because of TDZ - const reportUnreachableCode = - !options.allowUnreachableCode && - !isInAmbientContext(node) && - ( - node.kind !== SyntaxKind.VariableStatement || - getCombinedNodeFlags((node).declarationList) & NodeFlags.BlockScoped || - forEach((node).declarationList.declarations, d => d.initializer) - ); - - if (reportUnreachableCode) { - errorOnFirstToken(node, Diagnostics.Unreachable_code_detected); - } - } - } - return true; - } - } - - /** - * Computes the transform flags for a node, given the transform flags of its subtree - * - * @param node The node to analyze - * @param subtreeFlags Transform flags computed for this node's subtree - */ - export function computeTransformFlagsForNode(node: Node, subtreeFlags: TransformFlags): TransformFlags { - const kind = node.kind; - switch (kind) { - case SyntaxKind.CallExpression: - return computeCallExpression(node, subtreeFlags); - - case SyntaxKind.NewExpression: - return computeNewExpression(node, subtreeFlags); - - case SyntaxKind.ModuleDeclaration: - return computeModuleDeclaration(node, subtreeFlags); - - case SyntaxKind.ParenthesizedExpression: - return computeParenthesizedExpression(node, subtreeFlags); - - case SyntaxKind.BinaryExpression: - return computeBinaryExpression(node, subtreeFlags); - - case SyntaxKind.ExpressionStatement: - return computeExpressionStatement(node, subtreeFlags); - - case SyntaxKind.Parameter: - return computeParameter(node, subtreeFlags); - - case SyntaxKind.ArrowFunction: - return computeArrowFunction(node, subtreeFlags); - - case SyntaxKind.FunctionExpression: - return computeFunctionExpression(node, subtreeFlags); - - case SyntaxKind.FunctionDeclaration: - return computeFunctionDeclaration(node, subtreeFlags); - - case SyntaxKind.VariableDeclaration: - return computeVariableDeclaration(node, subtreeFlags); - - case SyntaxKind.VariableDeclarationList: - return computeVariableDeclarationList(node, subtreeFlags); - - case SyntaxKind.VariableStatement: - return computeVariableStatement(node, subtreeFlags); - - case SyntaxKind.LabeledStatement: - return computeLabeledStatement(node, subtreeFlags); - - case SyntaxKind.ClassDeclaration: - return computeClassDeclaration(node, subtreeFlags); - - case SyntaxKind.ClassExpression: - return computeClassExpression(node, subtreeFlags); - - case SyntaxKind.HeritageClause: - return computeHeritageClause(node, subtreeFlags); - - case SyntaxKind.ExpressionWithTypeArguments: - return computeExpressionWithTypeArguments(node, subtreeFlags); - - case SyntaxKind.Constructor: - return computeConstructor(node, subtreeFlags); - - case SyntaxKind.PropertyDeclaration: - return computePropertyDeclaration(node, subtreeFlags); - - case SyntaxKind.MethodDeclaration: - return computeMethod(node, subtreeFlags); - - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - return computeAccessor(node, subtreeFlags); - - case SyntaxKind.ImportEqualsDeclaration: - return computeImportEquals(node, subtreeFlags); - - case SyntaxKind.PropertyAccessExpression: - return computePropertyAccess(node, subtreeFlags); - - default: - return computeOther(node, kind, subtreeFlags); - } - } - - function computeCallExpression(node: CallExpression, subtreeFlags: TransformFlags) { - let transformFlags = subtreeFlags; - const expression = node.expression; - const expressionKind = expression.kind; - - if (node.typeArguments) { - transformFlags |= TransformFlags.AssertTypeScript; - } - - if (subtreeFlags & TransformFlags.ContainsSpreadElementExpression - || isSuperOrSuperProperty(expression, expressionKind)) { - // If the this node contains a SpreadElementExpression, or is a super call, then it is an ES6 - // node. - transformFlags |= TransformFlags.AssertES2015; - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.ArrayLiteralOrCallOrNewExcludes; - } - - function isSuperOrSuperProperty(node: Node, kind: SyntaxKind) { - switch (kind) { - case SyntaxKind.SuperKeyword: - return true; - - case SyntaxKind.PropertyAccessExpression: - case SyntaxKind.ElementAccessExpression: - const expression = (node).expression; - const expressionKind = expression.kind; - return expressionKind === SyntaxKind.SuperKeyword; - } - - return false; - } - - function computeNewExpression(node: NewExpression, subtreeFlags: TransformFlags) { - let transformFlags = subtreeFlags; - if (node.typeArguments) { - transformFlags |= TransformFlags.AssertTypeScript; - } - if (subtreeFlags & TransformFlags.ContainsSpreadElementExpression) { - // If the this node contains a SpreadElementExpression then it is an ES6 - // node. - transformFlags |= TransformFlags.AssertES6; - } - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.ArrayLiteralOrCallOrNewExcludes; - } - - - function computeBinaryExpression(node: BinaryExpression, subtreeFlags: TransformFlags) { - let transformFlags = subtreeFlags; - const operatorTokenKind = node.operatorToken.kind; - const leftKind = node.left.kind; - - if (operatorTokenKind === SyntaxKind.EqualsToken - && (leftKind === SyntaxKind.ObjectLiteralExpression - || leftKind === SyntaxKind.ArrayLiteralExpression)) { - // Destructuring assignments are ES6 syntax. - transformFlags |= TransformFlags.AssertES2015 | TransformFlags.DestructuringAssignment; - } - else if (operatorTokenKind === SyntaxKind.AsteriskAsteriskToken - || operatorTokenKind === SyntaxKind.AsteriskAsteriskEqualsToken) { - // Exponentiation is ES2016 syntax. - transformFlags |= TransformFlags.AssertES2016; - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.NodeExcludes; - } - - function computeParameter(node: ParameterDeclaration, subtreeFlags: TransformFlags) { - let transformFlags = subtreeFlags; - const modifierFlags = getModifierFlags(node); - const name = node.name; - const initializer = node.initializer; - const dotDotDotToken = node.dotDotDotToken; - - // The '?' token, type annotations, decorators, and 'this' parameters are TypeSCript - // syntax. - if (node.questionToken - || node.type - || subtreeFlags & TransformFlags.ContainsDecorators - || isThisIdentifier(name)) { - transformFlags |= TransformFlags.AssertTypeScript; - } - - // If a parameter has an accessibility modifier, then it is TypeScript syntax. - if (modifierFlags & ModifierFlags.ParameterPropertyModifier) { - transformFlags |= TransformFlags.AssertTypeScript | TransformFlags.ContainsParameterPropertyAssignments; - } - - // If a parameter has an initializer, a binding pattern or a dotDotDot token, then - // it is ES6 syntax and its container must emit default value assignments or parameter destructuring downlevel. - if (subtreeFlags & TransformFlags.ContainsBindingPattern || initializer || dotDotDotToken) { - transformFlags |= TransformFlags.AssertES2015 | TransformFlags.ContainsDefaultValueAssignments; - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.ParameterExcludes; - } - - function computeParenthesizedExpression(node: ParenthesizedExpression, subtreeFlags: TransformFlags) { - let transformFlags = subtreeFlags; - const expression = node.expression; - const expressionKind = expression.kind; - const expressionTransformFlags = expression.transformFlags; - - // If the node is synthesized, it means the emitter put the parentheses there, - // not the user. If we didn't want them, the emitter would not have put them - // there. - if (expressionKind === SyntaxKind.AsExpression - || expressionKind === SyntaxKind.TypeAssertionExpression) { - transformFlags |= TransformFlags.AssertTypeScript; - } - - // If the expression of a ParenthesizedExpression is a destructuring assignment, - // then the ParenthesizedExpression is a destructuring assignment. - if (expressionTransformFlags & TransformFlags.DestructuringAssignment) { - transformFlags |= TransformFlags.DestructuringAssignment; - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.NodeExcludes; - } - - function computeClassDeclaration(node: ClassDeclaration, subtreeFlags: TransformFlags) { - let transformFlags: TransformFlags; - const modifierFlags = getModifierFlags(node); - - if (modifierFlags & ModifierFlags.Ambient) { - // An ambient declaration is TypeScript syntax. - transformFlags = TransformFlags.AssertTypeScript; - } - else { - // A ClassDeclaration is ES6 syntax. - transformFlags = subtreeFlags | TransformFlags.AssertES2015; - - // A class with a parameter property assignment, property initializer, or decorator is - // TypeScript syntax. - // An exported declaration may be TypeScript syntax. - if ((subtreeFlags & TransformFlags.TypeScriptClassSyntaxMask) - || (modifierFlags & ModifierFlags.Export) - || node.typeParameters) { - transformFlags |= TransformFlags.AssertTypeScript; - } - - if (subtreeFlags & TransformFlags.ContainsLexicalThisInComputedPropertyName) { - // A computed property name containing `this` might need to be rewritten, - // so propagate the ContainsLexicalThis flag upward. - transformFlags |= TransformFlags.ContainsLexicalThis; - } - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.ClassExcludes; - } - - function computeClassExpression(node: ClassExpression, subtreeFlags: TransformFlags) { - // A ClassExpression is ES6 syntax. - let transformFlags = subtreeFlags | TransformFlags.AssertES2015; - - // A class with a parameter property assignment, property initializer, or decorator is - // TypeScript syntax. - if (subtreeFlags & TransformFlags.TypeScriptClassSyntaxMask - || node.typeParameters) { - transformFlags |= TransformFlags.AssertTypeScript; - } - - if (subtreeFlags & TransformFlags.ContainsLexicalThisInComputedPropertyName) { - // A computed property name containing `this` might need to be rewritten, - // so propagate the ContainsLexicalThis flag upward. - transformFlags |= TransformFlags.ContainsLexicalThis; - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.ClassExcludes; - } - - function computeHeritageClause(node: HeritageClause, subtreeFlags: TransformFlags) { - let transformFlags = subtreeFlags; - - switch (node.token) { - case SyntaxKind.ExtendsKeyword: - // An `extends` HeritageClause is ES6 syntax. - transformFlags |= TransformFlags.AssertES2015; - break; - - case SyntaxKind.ImplementsKeyword: - // An `implements` HeritageClause is TypeScript syntax. - transformFlags |= TransformFlags.AssertTypeScript; - break; - - default: - Debug.fail("Unexpected token for heritage clause"); - break; - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.NodeExcludes; - } - - function computeExpressionWithTypeArguments(node: ExpressionWithTypeArguments, subtreeFlags: TransformFlags) { - // An ExpressionWithTypeArguments is ES6 syntax, as it is used in the - // extends clause of a class. - let transformFlags = subtreeFlags | TransformFlags.AssertES2015; - - // If an ExpressionWithTypeArguments contains type arguments, then it - // is TypeScript syntax. - if (node.typeArguments) { - transformFlags |= TransformFlags.AssertTypeScript; - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.NodeExcludes; - } - - function computeConstructor(node: ConstructorDeclaration, subtreeFlags: TransformFlags) { - let transformFlags = subtreeFlags; - - // TypeScript-specific modifiers and overloads are TypeScript syntax - if (hasModifier(node, ModifierFlags.TypeScriptModifier) - || !node.body) { - transformFlags |= TransformFlags.AssertTypeScript; - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.ConstructorExcludes; - } - - function computeMethod(node: MethodDeclaration, subtreeFlags: TransformFlags) { - // A MethodDeclaration is ES6 syntax. -<<<<<<< HEAD - let transformFlags = subtreeFlags | TransformFlags.AssertES6; - - // Decorators, TypeScript-specific modifiers, type parameters, type annotations, and - // overloads are TypeScript syntax. - if (node.decorators - || hasModifier(node, ModifierFlags.TypeScriptModifier) - || node.typeParameters - || node.type - || !node.body) { -======= - let transformFlags = subtreeFlags | TransformFlags.AssertES2015; - const modifierFlags = getModifierFlags(node); - const body = node.body; - const typeParameters = node.typeParameters; - const asteriskToken = node.asteriskToken; - - // A MethodDeclaration is TypeScript syntax if it is either abstract, overloaded, - // generic, or has a decorator. - if (!body - || typeParameters - || (modifierFlags & ModifierFlags.Abstract) - || (subtreeFlags & TransformFlags.ContainsDecorators)) { ->>>>>>> master - transformFlags |= TransformFlags.AssertTypeScript; - } - - // An async method declaration is ES2017 syntax. - if (modifierFlags & ModifierFlags.Async) { - transformFlags |= TransformFlags.AssertES2017; - } - - // Currently, we only support generators that were originally async function bodies. - if (node.asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) { - transformFlags |= TransformFlags.AssertGenerator; - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.MethodOrAccessorExcludes; - } - - function computeAccessor(node: AccessorDeclaration, subtreeFlags: TransformFlags) { - let transformFlags = subtreeFlags; - -<<<<<<< HEAD - // Decorators, TypeScript-specific modifiers, type annotations, and overloads are - // TypeScript syntax. - if (node.decorators - || hasModifier(node, ModifierFlags.TypeScriptModifier) - || node.type - || !node.body) { -======= - // An accessor is TypeScript syntax if it is either abstract, overloaded, - // generic, or has a decorator. - if (!body - || (modifierFlags & ModifierFlags.Abstract) - || (subtreeFlags & TransformFlags.ContainsDecorators)) { ->>>>>>> master - transformFlags |= TransformFlags.AssertTypeScript; - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.MethodOrAccessorExcludes; - } - - function computePropertyDeclaration(node: PropertyDeclaration, subtreeFlags: TransformFlags) { - // A PropertyDeclaration is TypeScript syntax. - let transformFlags = subtreeFlags | TransformFlags.AssertTypeScript; - - // If the PropertyDeclaration has an initializer, we need to inform its ancestor - // so that it handle the transformation. - if (node.initializer) { - transformFlags |= TransformFlags.ContainsPropertyInitializer; - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.NodeExcludes; - } - - function computeFunctionDeclaration(node: FunctionDeclaration, subtreeFlags: TransformFlags) { - let transformFlags: TransformFlags; - const modifierFlags = getModifierFlags(node); - const body = node.body; - - if (!body || (modifierFlags & ModifierFlags.Ambient)) { - // An ambient declaration is TypeScript syntax. - // A FunctionDeclaration without a body is an overload and is TypeScript syntax. - transformFlags = TransformFlags.AssertTypeScript; - } - else { - transformFlags = subtreeFlags | TransformFlags.ContainsHoistedDeclarationOrCompletion; - - // If a FunctionDeclaration is exported, then it is either ES6 or TypeScript syntax. - if (modifierFlags & ModifierFlags.Export) { - transformFlags |= TransformFlags.AssertTypeScript | TransformFlags.AssertES2015; - } - -<<<<<<< HEAD - // TypeScript-specific modifiers, type parameters, and type annotations are TypeScript - // syntax. - if (modifierFlags & ModifierFlags.TypeScriptModifier - || node.typeParameters - || node.type) { - transformFlags |= TransformFlags.AssertTypeScript; -======= - // An async function declaration is ES2017 syntax. - if (modifierFlags & ModifierFlags.Async) { - transformFlags |= TransformFlags.AssertES2017; ->>>>>>> master - } - - // If a FunctionDeclaration's subtree has marked the container as needing to capture the - // lexical this, or the function contains parameters with initializers, then this node is - // ES6 syntax. - if (subtreeFlags & TransformFlags.ES2015FunctionSyntaxMask) { - transformFlags |= TransformFlags.AssertES2015; - } - - // If a FunctionDeclaration is generator function and is the body of a - // transformed async function, then this node can be transformed to a - // down-level generator. - // Currently we do not support transforming any other generator fucntions - // down level. - if (node.asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) { - transformFlags |= TransformFlags.AssertGenerator; - } - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.FunctionExcludes; - } - - function computeFunctionExpression(node: FunctionExpression, subtreeFlags: TransformFlags) { - let transformFlags = subtreeFlags; - -<<<<<<< HEAD - // TypeScript-specific modifiers, type parameters, and type annotations are TypeScript - // syntax. - if (hasModifier(node, ModifierFlags.TypeScriptModifier) - || node.typeParameters - || node.type) { - transformFlags |= TransformFlags.AssertTypeScript; -======= - // An async function expression is ES2017 syntax. - if (modifierFlags & ModifierFlags.Async) { - transformFlags |= TransformFlags.AssertES2017; ->>>>>>> master - } - - // If a FunctionExpression's subtree has marked the container as needing to capture the - // lexical this, or the function contains parameters with initializers, then this node is - // ES6 syntax. - if (subtreeFlags & TransformFlags.ES2015FunctionSyntaxMask) { - transformFlags |= TransformFlags.AssertES2015; - } - - // If a FunctionExpression is generator function and is the body of a - // transformed async function, then this node can be transformed to a - // down-level generator. - // Currently we do not support transforming any other generator fucntions - // down level. - if (node.asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) { - transformFlags |= TransformFlags.AssertGenerator; - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.FunctionExcludes; - } - - function computeArrowFunction(node: ArrowFunction, subtreeFlags: TransformFlags) { - // An ArrowFunction is ES6 syntax, and excludes markers that should not escape the scope of an ArrowFunction. -<<<<<<< HEAD - let transformFlags = subtreeFlags | TransformFlags.AssertES6; - - // TypeScript-specific modifiers, type parameters, and type annotations are TypeScript - // syntax. - if (hasModifier(node, ModifierFlags.TypeScriptModifier) - || node.typeParameters - || node.type) { - transformFlags |= TransformFlags.AssertTypeScript; -======= - let transformFlags = subtreeFlags | TransformFlags.AssertES2015; - const modifierFlags = getModifierFlags(node); - - // An async arrow function is ES2017 syntax. - if (modifierFlags & ModifierFlags.Async) { - transformFlags |= TransformFlags.AssertES2017; ->>>>>>> master - } - - // If an ArrowFunction contains a lexical this, its container must capture the lexical this. - if (subtreeFlags & TransformFlags.ContainsLexicalThis) { - transformFlags |= TransformFlags.ContainsCapturedLexicalThis; - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.ArrowFunctionExcludes; - } - - function computePropertyAccess(node: PropertyAccessExpression, subtreeFlags: TransformFlags) { - let transformFlags = subtreeFlags; - const expression = node.expression; - const expressionKind = expression.kind; - - // If a PropertyAccessExpression starts with a super keyword, then it is - // ES6 syntax, and requires a lexical `this` binding. - if (expressionKind === SyntaxKind.SuperKeyword) { - transformFlags |= TransformFlags.ContainsLexicalThis; - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.NodeExcludes; - } - - function computeVariableDeclaration(node: VariableDeclaration, subtreeFlags: TransformFlags) { - let transformFlags = subtreeFlags; - const nameKind = node.name.kind; - - // A VariableDeclaration with a binding pattern is ES6 syntax. - if (nameKind === SyntaxKind.ObjectBindingPattern || nameKind === SyntaxKind.ArrayBindingPattern) { - transformFlags |= TransformFlags.AssertES2015 | TransformFlags.ContainsBindingPattern; - } - - // Type annotations are TypeScript syntax. - if (node.type) { - transformFlags |= TransformFlags.AssertTypeScript; - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.NodeExcludes; - } - - function computeVariableStatement(node: VariableStatement, subtreeFlags: TransformFlags) { - let transformFlags: TransformFlags; - const modifierFlags = getModifierFlags(node); - const declarationListTransformFlags = node.declarationList.transformFlags; - - // An ambient declaration is TypeScript syntax. - if (modifierFlags & ModifierFlags.Ambient) { - transformFlags = TransformFlags.AssertTypeScript; - } - else { - transformFlags = subtreeFlags; - - // If a VariableStatement is exported, then it is either ES6 or TypeScript syntax. - if (modifierFlags & ModifierFlags.Export) { - transformFlags |= TransformFlags.AssertES2015 | TransformFlags.AssertTypeScript; - } - - if (declarationListTransformFlags & TransformFlags.ContainsBindingPattern) { - transformFlags |= TransformFlags.AssertES2015; - } - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.NodeExcludes; - } - - function computeLabeledStatement(node: LabeledStatement, subtreeFlags: TransformFlags) { - let transformFlags = subtreeFlags; - - // A labeled statement containing a block scoped binding *may* need to be transformed from ES6. - if (subtreeFlags & TransformFlags.ContainsBlockScopedBinding - && isIterationStatement(node, /*lookInLabeledStatements*/ true)) { - transformFlags |= TransformFlags.AssertES2015; - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.NodeExcludes; - } - - function computeImportEquals(node: ImportEqualsDeclaration, subtreeFlags: TransformFlags) { - let transformFlags = subtreeFlags; - - // An ImportEqualsDeclaration with a namespace reference is TypeScript. - if (!isExternalModuleImportEqualsDeclaration(node)) { - transformFlags |= TransformFlags.AssertTypeScript; - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.NodeExcludes; - } - - function computeExpressionStatement(node: ExpressionStatement, subtreeFlags: TransformFlags) { - let transformFlags = subtreeFlags; - - // If the expression of an expression statement is a destructuring assignment, - // then we treat the statement as ES6 so that we can indicate that we do not - // need to hold on to the right-hand side. - if (node.expression.transformFlags & TransformFlags.DestructuringAssignment) { - transformFlags |= TransformFlags.AssertES2015; - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.NodeExcludes; - } - - function computeModuleDeclaration(node: ModuleDeclaration, subtreeFlags: TransformFlags) { - let transformFlags = TransformFlags.AssertTypeScript; - const modifierFlags = getModifierFlags(node); - - if ((modifierFlags & ModifierFlags.Ambient) === 0) { - transformFlags |= subtreeFlags; - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.ModuleExcludes; - } - - function computeVariableDeclarationList(node: VariableDeclarationList, subtreeFlags: TransformFlags) { - let transformFlags = subtreeFlags | TransformFlags.ContainsHoistedDeclarationOrCompletion; - - if (subtreeFlags & TransformFlags.ContainsBindingPattern) { - transformFlags |= TransformFlags.AssertES2015; - } - - // If a VariableDeclarationList is `let` or `const`, then it is ES6 syntax. - if (node.flags & NodeFlags.BlockScoped) { - transformFlags |= TransformFlags.AssertES2015 | TransformFlags.ContainsBlockScopedBinding; - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.VariableDeclarationListExcludes; - } - - function computeOther(node: Node, kind: SyntaxKind, subtreeFlags: TransformFlags) { - // Mark transformations needed for each node - let transformFlags = subtreeFlags; - let excludeFlags = TransformFlags.NodeExcludes; - - switch (kind) { - case SyntaxKind.AsyncKeyword: - case SyntaxKind.AwaitExpression: - // async/await is ES2017 syntax - transformFlags |= TransformFlags.AssertES2017; - break; - - case SyntaxKind.PublicKeyword: - case SyntaxKind.PrivateKeyword: - case SyntaxKind.ProtectedKeyword: - case SyntaxKind.AbstractKeyword: - case SyntaxKind.DeclareKeyword: - case SyntaxKind.ConstKeyword: - case SyntaxKind.EnumDeclaration: - case SyntaxKind.EnumMember: - case SyntaxKind.TypeAssertionExpression: - case SyntaxKind.AsExpression: - case SyntaxKind.NonNullExpression: - case SyntaxKind.ReadonlyKeyword: - // These nodes are TypeScript syntax. - transformFlags |= TransformFlags.AssertTypeScript; - break; - - case SyntaxKind.JsxElement: - case SyntaxKind.JsxSelfClosingElement: - case SyntaxKind.JsxOpeningElement: - case SyntaxKind.JsxText: - case SyntaxKind.JsxClosingElement: - case SyntaxKind.JsxAttribute: - case SyntaxKind.JsxSpreadAttribute: - case SyntaxKind.JsxExpression: - // These nodes are Jsx syntax. - transformFlags |= TransformFlags.AssertJsx; - break; - - case SyntaxKind.ExportKeyword: - // This node is both ES6 and TypeScript syntax. - transformFlags |= TransformFlags.AssertES2015 | TransformFlags.AssertTypeScript; - break; - - case SyntaxKind.DefaultKeyword: - case SyntaxKind.NoSubstitutionTemplateLiteral: - case SyntaxKind.TemplateHead: - case SyntaxKind.TemplateMiddle: - case SyntaxKind.TemplateTail: - case SyntaxKind.TemplateExpression: - case SyntaxKind.TaggedTemplateExpression: - case SyntaxKind.ShorthandPropertyAssignment: - case SyntaxKind.ForOfStatement: - // These nodes are ES6 syntax. - transformFlags |= TransformFlags.AssertES2015; - break; - - case SyntaxKind.YieldExpression: - // This node is ES6 syntax. - transformFlags |= TransformFlags.AssertES2015 | TransformFlags.ContainsYield; - break; - - case SyntaxKind.AnyKeyword: - case SyntaxKind.NumberKeyword: - case SyntaxKind.NeverKeyword: - case SyntaxKind.StringKeyword: - case SyntaxKind.BooleanKeyword: - case SyntaxKind.SymbolKeyword: - case SyntaxKind.VoidKeyword: - case SyntaxKind.TypeParameter: - case SyntaxKind.PropertySignature: - case SyntaxKind.MethodSignature: - case SyntaxKind.CallSignature: - case SyntaxKind.ConstructSignature: - case SyntaxKind.IndexSignature: - case SyntaxKind.TypePredicate: - case SyntaxKind.TypeReference: - case SyntaxKind.FunctionType: - case SyntaxKind.ConstructorType: - case SyntaxKind.TypeQuery: - case SyntaxKind.TypeLiteral: - case SyntaxKind.ArrayType: - case SyntaxKind.TupleType: - case SyntaxKind.UnionType: - case SyntaxKind.IntersectionType: - case SyntaxKind.ParenthesizedType: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.TypeAliasDeclaration: - case SyntaxKind.ThisType: - case SyntaxKind.LiteralType: - // Types and signatures are TypeScript syntax, and exclude all other facts. - transformFlags = TransformFlags.AssertTypeScript; - excludeFlags = TransformFlags.TypeExcludes; - break; - - case SyntaxKind.ComputedPropertyName: - // Even though computed property names are ES6, we don't treat them as such. - // This is so that they can flow through PropertyName transforms unaffected. - // Instead, we mark the container as ES6, so that it can properly handle the transform. - transformFlags |= TransformFlags.ContainsComputedPropertyName; - if (subtreeFlags & TransformFlags.ContainsLexicalThis) { - // A computed method name like `[this.getName()](x: string) { ... }` needs to - // distinguish itself from the normal case of a method body containing `this`: - // `this` inside a method doesn't need to be rewritten (the method provides `this`), - // whereas `this` inside a computed name *might* need to be rewritten if the class/object - // is inside an arrow function: - // `_this = this; () => class K { [_this.getName()]() { ... } }` - // To make this distinction, use ContainsLexicalThisInComputedPropertyName - // instead of ContainsLexicalThis for computed property names - transformFlags |= TransformFlags.ContainsLexicalThisInComputedPropertyName; - } - break; - - case SyntaxKind.SpreadElementExpression: - // This node is ES6 syntax, but is handled by a containing node. - transformFlags |= TransformFlags.ContainsSpreadElementExpression; - break; - - case SyntaxKind.SuperKeyword: - // This node is ES6 syntax. - transformFlags |= TransformFlags.AssertES2015; - break; - - case SyntaxKind.ThisKeyword: - // Mark this node and its ancestors as containing a lexical `this` keyword. - transformFlags |= TransformFlags.ContainsLexicalThis; - break; - - case SyntaxKind.ObjectBindingPattern: - case SyntaxKind.ArrayBindingPattern: - // These nodes are ES6 syntax. - transformFlags |= TransformFlags.AssertES2015 | TransformFlags.ContainsBindingPattern; - break; - - case SyntaxKind.Decorator: - // This node is TypeScript syntax, and marks its container as also being TypeScript syntax. - transformFlags |= TransformFlags.AssertTypeScript | TransformFlags.ContainsDecorators; - break; - - case SyntaxKind.ObjectLiteralExpression: - excludeFlags = TransformFlags.ObjectLiteralExcludes; - if (subtreeFlags & TransformFlags.ContainsComputedPropertyName) { - // If an ObjectLiteralExpression contains a ComputedPropertyName, then it - // is an ES6 node. - transformFlags |= TransformFlags.AssertES2015; - } - - if (subtreeFlags & TransformFlags.ContainsLexicalThisInComputedPropertyName) { - // A computed property name containing `this` might need to be rewritten, - // so propagate the ContainsLexicalThis flag upward. - transformFlags |= TransformFlags.ContainsLexicalThis; - } - - break; - - case SyntaxKind.ArrayLiteralExpression: - case SyntaxKind.NewExpression: - excludeFlags = TransformFlags.ArrayLiteralOrCallOrNewExcludes; - if (subtreeFlags & TransformFlags.ContainsSpreadElementExpression) { - // If the this node contains a SpreadElementExpression, then it is an ES6 - // node. - transformFlags |= TransformFlags.AssertES2015; - } - - break; - - case SyntaxKind.DoStatement: - case SyntaxKind.WhileStatement: - case SyntaxKind.ForStatement: - case SyntaxKind.ForInStatement: - // A loop containing a block scoped binding *may* need to be transformed from ES6. - if (subtreeFlags & TransformFlags.ContainsBlockScopedBinding) { - transformFlags |= TransformFlags.AssertES2015; - } - - break; - - case SyntaxKind.SourceFile: - if (subtreeFlags & TransformFlags.ContainsCapturedLexicalThis) { - transformFlags |= TransformFlags.AssertES2015; - } - - break; - - case SyntaxKind.ReturnStatement: - case SyntaxKind.ContinueStatement: - case SyntaxKind.BreakStatement: - transformFlags |= TransformFlags.ContainsHoistedDeclarationOrCompletion; - break; - } - - node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~excludeFlags; - } -} From db76a9ca0720199852c39eef1c8956d5c55bacb7 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Sat, 15 Oct 2016 17:29:03 -0700 Subject: [PATCH 54/80] More tests --- .../transformsElideNullUndefinedType.js | 68 ++++++++++-- .../transformsElideNullUndefinedType.symbols | 101 ++++++++++++++--- .../transformsElideNullUndefinedType.types | 102 ++++++++++++++++-- .../transformsElideNullUndefinedType.ts | 36 ++++++- 4 files changed, 272 insertions(+), 35 deletions(-) diff --git a/tests/baselines/reference/transformsElideNullUndefinedType.js b/tests/baselines/reference/transformsElideNullUndefinedType.js index a5e27eee08..63bc77559c 100644 --- a/tests/baselines/reference/transformsElideNullUndefinedType.js +++ b/tests/baselines/reference/transformsElideNullUndefinedType.js @@ -15,21 +15,49 @@ var f5 = (): undefined => undefined; function f6(p0: null) { } function f7(p1: undefined) { } -class C { +var f8 = function (p2: null) { } +var f9 = function (p3: undefined) { } + +var f10 = (p4: null) => { } +var f11 = (p5: undefined) => { } + +class C1 { m0(): null { return null; } m1(): undefined { return undefined; } + m3(p6: null) { } + m4(p7: undefined) { } + get a0(): null { return null; } get a1(): undefined { return undefined; } + + set a2(p8: null) { } + set a3(p9: undefined) { } } -declare function fn(); +class C2 { constructor(p10: null) { } } +class C3 { constructor(p11: undefined) { } } +class C4 { + f1; + constructor(p12: null) { } +} + +class C5 { + f2; + constructor(p13: undefined) { } +} + +var C6 = class { constructor(p12: null) { } } +var C7 = class { constructor(p13: undefined) { } } + +declare function fn(); fn(); fn(); -new C(); -new C(); +declare class D {} +new D(); +new D(); //// [transformsElideNullUndefinedType.js] var v0; @@ -42,13 +70,39 @@ var f4 = () => null; var f5 = () => undefined; function f6(p0) { } function f7(p1) { } -class C { +var f8 = function (p2) { }; +var f9 = function (p3) { }; +var f10 = (p4) => { }; +var f11 = (p5) => { }; +class C1 { m0() { return null; } m1() { return undefined; } + m3(p6) { } + m4(p7) { } get a0() { return null; } get a1() { return undefined; } + set a2(p8) { } + set a3(p9) { } } +class C2 { + constructor(p10) { } +} +class C3 { + constructor(p11) { } +} +class C4 { + constructor(p12) { } +} +class C5 { + constructor(p13) { } +} +var C6 = class { + constructor(p12) { } +}; +var C7 = class { + constructor(p13) { } +}; fn(); fn(); -new C(); -new C(); +new D(); +new D(); diff --git a/tests/baselines/reference/transformsElideNullUndefinedType.symbols b/tests/baselines/reference/transformsElideNullUndefinedType.symbols index 0c9333d982..b651784a61 100644 --- a/tests/baselines/reference/transformsElideNullUndefinedType.symbols +++ b/tests/baselines/reference/transformsElideNullUndefinedType.symbols @@ -35,38 +35,109 @@ function f7(p1: undefined) { } >f7 : Symbol(f7, Decl(transformsElideNullUndefinedType.ts, 13, 25)) >p1 : Symbol(p1, Decl(transformsElideNullUndefinedType.ts, 14, 12)) -class C { ->C : Symbol(C, Decl(transformsElideNullUndefinedType.ts, 14, 30)) ->T : Symbol(T, Decl(transformsElideNullUndefinedType.ts, 16, 8)) +var f8 = function (p2: null) { } +>f8 : Symbol(f8, Decl(transformsElideNullUndefinedType.ts, 16, 3)) +>p2 : Symbol(p2, Decl(transformsElideNullUndefinedType.ts, 16, 19)) + +var f9 = function (p3: undefined) { } +>f9 : Symbol(f9, Decl(transformsElideNullUndefinedType.ts, 17, 3)) +>p3 : Symbol(p3, Decl(transformsElideNullUndefinedType.ts, 17, 19)) + +var f10 = (p4: null) => { } +>f10 : Symbol(f10, Decl(transformsElideNullUndefinedType.ts, 19, 3)) +>p4 : Symbol(p4, Decl(transformsElideNullUndefinedType.ts, 19, 11)) + +var f11 = (p5: undefined) => { } +>f11 : Symbol(f11, Decl(transformsElideNullUndefinedType.ts, 20, 3)) +>p5 : Symbol(p5, Decl(transformsElideNullUndefinedType.ts, 20, 11)) + +class C1 { +>C1 : Symbol(C1, Decl(transformsElideNullUndefinedType.ts, 20, 32)) m0(): null { return null; } ->m0 : Symbol(C.m0, Decl(transformsElideNullUndefinedType.ts, 16, 12)) +>m0 : Symbol(C1.m0, Decl(transformsElideNullUndefinedType.ts, 22, 10)) m1(): undefined { return undefined; } ->m1 : Symbol(C.m1, Decl(transformsElideNullUndefinedType.ts, 17, 31)) +>m1 : Symbol(C1.m1, Decl(transformsElideNullUndefinedType.ts, 23, 31)) >undefined : Symbol(undefined) + m3(p6: null) { } +>m3 : Symbol(C1.m3, Decl(transformsElideNullUndefinedType.ts, 24, 41)) +>p6 : Symbol(p6, Decl(transformsElideNullUndefinedType.ts, 26, 7)) + + m4(p7: undefined) { } +>m4 : Symbol(C1.m4, Decl(transformsElideNullUndefinedType.ts, 26, 20)) +>p7 : Symbol(p7, Decl(transformsElideNullUndefinedType.ts, 27, 7)) + get a0(): null { return null; } ->a0 : Symbol(C.a0, Decl(transformsElideNullUndefinedType.ts, 18, 41)) +>a0 : Symbol(C1.a0, Decl(transformsElideNullUndefinedType.ts, 27, 25)) get a1(): undefined { return undefined; } ->a1 : Symbol(C.a1, Decl(transformsElideNullUndefinedType.ts, 20, 35)) +>a1 : Symbol(C1.a1, Decl(transformsElideNullUndefinedType.ts, 29, 35)) >undefined : Symbol(undefined) + + set a2(p8: null) { } +>a2 : Symbol(C1.a2, Decl(transformsElideNullUndefinedType.ts, 30, 45)) +>p8 : Symbol(p8, Decl(transformsElideNullUndefinedType.ts, 32, 11)) + + set a3(p9: undefined) { } +>a3 : Symbol(C1.a3, Decl(transformsElideNullUndefinedType.ts, 32, 24)) +>p9 : Symbol(p9, Decl(transformsElideNullUndefinedType.ts, 33, 11)) } +class C2 { constructor(p10: null) { } } +>C2 : Symbol(C2, Decl(transformsElideNullUndefinedType.ts, 34, 1)) +>p10 : Symbol(p10, Decl(transformsElideNullUndefinedType.ts, 36, 23)) + +class C3 { constructor(p11: undefined) { } } +>C3 : Symbol(C3, Decl(transformsElideNullUndefinedType.ts, 36, 39)) +>p11 : Symbol(p11, Decl(transformsElideNullUndefinedType.ts, 37, 23)) + +class C4 { +>C4 : Symbol(C4, Decl(transformsElideNullUndefinedType.ts, 37, 44)) + + f1; +>f1 : Symbol(C4.f1, Decl(transformsElideNullUndefinedType.ts, 39, 10)) + + constructor(p12: null) { } +>p12 : Symbol(p12, Decl(transformsElideNullUndefinedType.ts, 41, 16)) +} + +class C5 { +>C5 : Symbol(C5, Decl(transformsElideNullUndefinedType.ts, 42, 1)) + + f2; +>f2 : Symbol(C5.f2, Decl(transformsElideNullUndefinedType.ts, 44, 10)) + + constructor(p13: undefined) { } +>p13 : Symbol(p13, Decl(transformsElideNullUndefinedType.ts, 46, 16)) +} + +var C6 = class { constructor(p12: null) { } } +>C6 : Symbol(C6, Decl(transformsElideNullUndefinedType.ts, 49, 3)) +>p12 : Symbol(p12, Decl(transformsElideNullUndefinedType.ts, 49, 29)) + +var C7 = class { constructor(p13: undefined) { } } +>C7 : Symbol(C7, Decl(transformsElideNullUndefinedType.ts, 50, 3)) +>p13 : Symbol(p13, Decl(transformsElideNullUndefinedType.ts, 50, 29)) + declare function fn(); ->fn : Symbol(fn, Decl(transformsElideNullUndefinedType.ts, 22, 1)) ->T : Symbol(T, Decl(transformsElideNullUndefinedType.ts, 24, 20)) +>fn : Symbol(fn, Decl(transformsElideNullUndefinedType.ts, 50, 50)) +>T : Symbol(T, Decl(transformsElideNullUndefinedType.ts, 52, 20)) fn(); ->fn : Symbol(fn, Decl(transformsElideNullUndefinedType.ts, 22, 1)) +>fn : Symbol(fn, Decl(transformsElideNullUndefinedType.ts, 50, 50)) fn(); ->fn : Symbol(fn, Decl(transformsElideNullUndefinedType.ts, 22, 1)) +>fn : Symbol(fn, Decl(transformsElideNullUndefinedType.ts, 50, 50)) -new C(); ->C : Symbol(C, Decl(transformsElideNullUndefinedType.ts, 14, 30)) +declare class D {} +>D : Symbol(D, Decl(transformsElideNullUndefinedType.ts, 54, 16)) +>T : Symbol(T, Decl(transformsElideNullUndefinedType.ts, 56, 16)) -new C(); ->C : Symbol(C, Decl(transformsElideNullUndefinedType.ts, 14, 30)) +new D(); +>D : Symbol(D, Decl(transformsElideNullUndefinedType.ts, 54, 16)) + +new D(); +>D : Symbol(D, Decl(transformsElideNullUndefinedType.ts, 54, 16)) diff --git a/tests/baselines/reference/transformsElideNullUndefinedType.types b/tests/baselines/reference/transformsElideNullUndefinedType.types index 66a73c8314..7f48d8a00e 100644 --- a/tests/baselines/reference/transformsElideNullUndefinedType.types +++ b/tests/baselines/reference/transformsElideNullUndefinedType.types @@ -47,9 +47,30 @@ function f7(p1: undefined) { } >f7 : (p1: undefined) => void >p1 : undefined -class C { ->C : C ->T : T +var f8 = function (p2: null) { } +>f8 : (p2: null) => void +>function (p2: null) { } : (p2: null) => void +>p2 : null +>null : null + +var f9 = function (p3: undefined) { } +>f9 : (p3: undefined) => void +>function (p3: undefined) { } : (p3: undefined) => void +>p3 : undefined + +var f10 = (p4: null) => { } +>f10 : (p4: null) => void +>(p4: null) => { } : (p4: null) => void +>p4 : null +>null : null + +var f11 = (p5: undefined) => { } +>f11 : (p5: undefined) => void +>(p5: undefined) => { } : (p5: undefined) => void +>p5 : undefined + +class C1 { +>C1 : C1 m0(): null { return null; } >m0 : () => null @@ -60,6 +81,15 @@ class C { >m1 : () => undefined >undefined : undefined + m3(p6: null) { } +>m3 : (p6: null) => void +>p6 : null +>null : null + + m4(p7: undefined) { } +>m4 : (p7: undefined) => void +>p7 : undefined + get a0(): null { return null; } >a0 : null >null : null @@ -68,8 +98,58 @@ class C { get a1(): undefined { return undefined; } >a1 : undefined >undefined : undefined + + set a2(p8: null) { } +>a2 : null +>p8 : null +>null : null + + set a3(p9: undefined) { } +>a3 : undefined +>p9 : undefined } +class C2 { constructor(p10: null) { } } +>C2 : C2 +>p10 : null +>null : null + +class C3 { constructor(p11: undefined) { } } +>C3 : C3 +>p11 : undefined + +class C4 { +>C4 : C4 + + f1; +>f1 : any + + constructor(p12: null) { } +>p12 : null +>null : null +} + +class C5 { +>C5 : C5 + + f2; +>f2 : any + + constructor(p13: undefined) { } +>p13 : undefined +} + +var C6 = class { constructor(p12: null) { } } +>C6 : typeof (Anonymous class) +>class { constructor(p12: null) { } } : typeof (Anonymous class) +>p12 : null +>null : null + +var C7 = class { constructor(p13: undefined) { } } +>C7 : typeof (Anonymous class) +>class { constructor(p13: undefined) { } } : typeof (Anonymous class) +>p13 : undefined + declare function fn(); >fn : () => any >T : T @@ -83,12 +163,16 @@ fn(); >fn() : any >fn : () => any -new C(); ->new C() : C ->C : typeof C +declare class D {} +>D : D +>T : T + +new D(); +>new D() : D +>D : typeof D >null : null -new C(); ->new C() : C ->C : typeof C +new D(); +>new D() : D +>D : typeof D diff --git a/tests/cases/compiler/transformsElideNullUndefinedType.ts b/tests/cases/compiler/transformsElideNullUndefinedType.ts index 244f2ea9c7..4a493a91d8 100644 --- a/tests/cases/compiler/transformsElideNullUndefinedType.ts +++ b/tests/cases/compiler/transformsElideNullUndefinedType.ts @@ -15,18 +15,46 @@ var f5 = (): undefined => undefined; function f6(p0: null) { } function f7(p1: undefined) { } -class C { +var f8 = function (p2: null) { } +var f9 = function (p3: undefined) { } + +var f10 = (p4: null) => { } +var f11 = (p5: undefined) => { } + +class C1 { m0(): null { return null; } m1(): undefined { return undefined; } + m3(p6: null) { } + m4(p7: undefined) { } + get a0(): null { return null; } get a1(): undefined { return undefined; } + + set a2(p8: null) { } + set a3(p9: undefined) { } } -declare function fn(); +class C2 { constructor(p10: null) { } } +class C3 { constructor(p11: undefined) { } } +class C4 { + f1; + constructor(p12: null) { } +} + +class C5 { + f2; + constructor(p13: undefined) { } +} + +var C6 = class { constructor(p12: null) { } } +var C7 = class { constructor(p13: undefined) { } } + +declare function fn(); fn(); fn(); -new C(); -new C(); \ No newline at end of file +declare class D {} +new D(); +new D(); \ No newline at end of file From 8094b2c5def5ed39e5a9ddc18bfd09bab731aa11 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 16 Oct 2016 17:28:45 -0700 Subject: [PATCH 55/80] Improve contextual typing of partially annotated signatures --- src/compiler/checker.ts | 68 +++++++++++++++++++++++++++++------------ 1 file changed, 48 insertions(+), 20 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 22ab44ee08..b3b6557c98 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3144,8 +3144,7 @@ namespace ts { // Use contextual parameter type if one is available let type: Type; if (declaration.symbol.name === "this") { - const thisParameter = getContextualThisParameter(func); - type = thisParameter ? getTypeOfSymbol(thisParameter) : undefined; + type = getContextualThisParameterType(func); } else { type = getContextuallyTypedParameterType(declaration); @@ -4789,9 +4788,6 @@ namespace ts { if (isJSConstructSignature) { minArgumentCount--; } - if (!thisParameter && isObjectLiteralMethod(declaration)) { - thisParameter = getContextualThisParameter(declaration); - } const classType = declaration.kind === SyntaxKind.Constructor ? getDeclaredTypeOfClassOrInterface(getMergedSymbol((declaration.parent).symbol)) @@ -6101,9 +6097,24 @@ namespace ts { } function isContextSensitiveFunctionLikeDeclaration(node: FunctionLikeDeclaration) { - const areAllParametersUntyped = !forEach(node.parameters, p => p.type); - const isNullaryArrow = node.kind === SyntaxKind.ArrowFunction && !node.parameters.length; - return !node.typeParameters && areAllParametersUntyped && !isNullaryArrow; + // Functions with type parameters are not context sensitive. + if (node.typeParameters) { + return false; + } + // Functions with any parameters that lack type annotations are context sensitive. + if (forEach(node.parameters, p => !p.type)) { + return true; + } + // For arrow functions we now know we're not context sensitive. + if (node.kind === SyntaxKind.ArrowFunction) { + return false; + } + // If the first parameter is not an explicit 'this' parameter, then the function has + // an implicit 'this' parameter which is subject to contextual typing. Otherwise we + // know that all parameters (including 'this') have type annotations and nothing is + // subject to contextual typing. + const parameter = firstOrUndefined(node.parameters); + return !(parameter && parameter.name.kind === SyntaxKind.Identifier && (parameter.name).text === "this"); } function isContextSensitiveFunctionOrObjectLiteralMethod(func: Node): func is FunctionExpression | ArrowFunction | MethodDeclaration { @@ -9629,7 +9640,7 @@ namespace ts { } } - const thisType = getThisTypeOfDeclaration(container); + let thisType = getThisTypeOfDeclaration(container) || getContextualThisParameterType(container); if (thisType) { return thisType; } @@ -9869,14 +9880,16 @@ namespace ts { } } - function getContextualThisParameter(func: FunctionLikeDeclaration): Symbol { + function getContextualThisParameterType(func: FunctionLikeDeclaration): Type { if (isContextSensitiveFunctionOrObjectLiteralMethod(func) && func.kind !== SyntaxKind.ArrowFunction) { const contextualSignature = getContextualSignature(func); if (contextualSignature) { - return contextualSignature.thisParameter; + const thisParameter = contextualSignature.thisParameter; + if (thisParameter) { + return getTypeOfSymbol(thisParameter); + } } } - return undefined; } @@ -12840,21 +12853,36 @@ namespace ts { function assignContextualParameterTypes(signature: Signature, context: Signature, mapper: TypeMapper) { const len = signature.parameters.length - (signature.hasRestParameter ? 1 : 0); - if (context.thisParameter) { - if (!signature.thisParameter) { - signature.thisParameter = createTransientSymbol(context.thisParameter, undefined); + if (isInferentialContext(mapper)) { + for (let i = 0; i < len; i++) { + const declaration = signature.parameters[i].valueDeclaration; + if (declaration.type) { + inferTypes(mapper.context, getTypeFromTypeNode(declaration.type), getTypeAtPosition(context, i)); + } + } + } + if (context.thisParameter) { + const parameter = signature.thisParameter; + if (!parameter || parameter.valueDeclaration && !(parameter.valueDeclaration).type) { + if (!parameter) { + signature.thisParameter = createTransientSymbol(context.thisParameter, undefined); + } + assignTypeToParameterAndFixTypeParameters(signature.thisParameter, getTypeOfSymbol(context.thisParameter), mapper); } - assignTypeToParameterAndFixTypeParameters(signature.thisParameter, getTypeOfSymbol(context.thisParameter), mapper); } for (let i = 0; i < len; i++) { const parameter = signature.parameters[i]; - const contextualParameterType = getTypeAtPosition(context, i); - assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType, mapper); + if (!(parameter.valueDeclaration).type) { + const contextualParameterType = getTypeAtPosition(context, i); + assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType, mapper); + } } if (signature.hasRestParameter && isRestParameterIndex(context, signature.parameters.length - 1)) { const parameter = lastOrUndefined(signature.parameters); - const contextualParameterType = getTypeOfSymbol(lastOrUndefined(context.parameters)); - assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType, mapper); + if (!(parameter.valueDeclaration).type) { + const contextualParameterType = getTypeOfSymbol(lastOrUndefined(context.parameters)); + assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType, mapper); + } } } From 808db07ce44d46574e88d15ba706bb79bdd160f3 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 16 Oct 2016 17:31:57 -0700 Subject: [PATCH 56/80] Accept new baselines --- tests/baselines/reference/thisTypeInFunctions.types | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/baselines/reference/thisTypeInFunctions.types b/tests/baselines/reference/thisTypeInFunctions.types index 44bf23ad50..a2aaba4cdd 100644 --- a/tests/baselines/reference/thisTypeInFunctions.types +++ b/tests/baselines/reference/thisTypeInFunctions.types @@ -453,7 +453,7 @@ let anyToSpecified: (this: { y: number }, x: number) => number = function(x: num >this : { y: number; } >y : number >x : number ->function(x: number): number { return x + 12; } : (x: number) => number +>function(x: number): number { return x + 12; } : (this: { y: number; }, x: number) => number >x : number >x + 12 : number >x : number From 6425f0ccfdbec7f7f189589cd8f49a829ef785a8 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 16 Oct 2016 17:37:37 -0700 Subject: [PATCH 57/80] Fix lint error --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b3b6557c98..db95eb9bc1 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9640,7 +9640,7 @@ namespace ts { } } - let thisType = getThisTypeOfDeclaration(container) || getContextualThisParameterType(container); + const thisType = getThisTypeOfDeclaration(container) || getContextualThisParameterType(container); if (thisType) { return thisType; } From ebba1c3d1a3c7d0a52a0531c2ec5edb9b2f94597 Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Sun, 16 Oct 2016 20:57:51 -0700 Subject: [PATCH 58/80] fix flow in finally blocks --- src/compiler/binder.ts | 36 ++++++++++++++----- tests/baselines/reference/flowInFinally1.js | 33 +++++++++++++++++ .../reference/flowInFinally1.symbols | 29 +++++++++++++++ .../baselines/reference/flowInFinally1.types | 34 ++++++++++++++++++ tests/cases/compiler/flowInFinally1.ts | 16 +++++++++ 5 files changed, 140 insertions(+), 8 deletions(-) create mode 100644 tests/baselines/reference/flowInFinally1.js create mode 100644 tests/baselines/reference/flowInFinally1.symbols create mode 100644 tests/baselines/reference/flowInFinally1.types create mode 100644 tests/cases/compiler/flowInFinally1.ts diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 4711d54e0b..31732bc833 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -984,24 +984,44 @@ namespace ts { } function bindTryStatement(node: TryStatement): void { - const postFinallyLabel = createBranchLabel(); + const preFinallyLabel = createBranchLabel(); const preTryFlow = currentFlow; // TODO: Every statement in try block is potentially an exit point! bind(node.tryBlock); - addAntecedent(postFinallyLabel, currentFlow); + addAntecedent(preFinallyLabel, currentFlow); + + const flowAfterTry = currentFlow; + let flowAfterCatch = unreachableFlow; + if (node.catchClause) { currentFlow = preTryFlow; bind(node.catchClause); - addAntecedent(postFinallyLabel, currentFlow); + addAntecedent(preFinallyLabel, currentFlow); + + flowAfterCatch = currentFlow; } if (node.finallyBlock) { - currentFlow = preTryFlow; + // in finally flow is combined from pre-try/flow from try/flow from catch + // pre-flow is necessary to make sure that finally is reachable even if finaly flows in both try and finally blocks are unreachable + addAntecedent(preFinallyLabel, preTryFlow); + currentFlow = finishFlowLabel(preFinallyLabel); bind(node.finallyBlock); + // if flow after finally is unreachable - keep it + // otherwise check if flows after try and after catch are unreachable + // if yes - convert current flow to unreachable + // i.e. + // try { return "1" } finally { console.log(1); } + // console.log(2); // this line should be unreachable even if flow falls out of finally block + if (!(currentFlow.flags & FlowFlags.Unreachable)) { + if ((flowAfterTry.flags & FlowFlags.Unreachable) && (flowAfterCatch.flags & FlowFlags.Unreachable)) { + currentFlow = flowAfterTry == reportedUnreachableFlow || flowAfterCatch === reportedUnreachableFlow + ? reportedUnreachableFlow + : unreachableFlow; + } + } } - // if try statement has finally block and flow after finally block is unreachable - keep it - // otherwise use whatever flow was accumulated at postFinallyLabel - if (!node.finallyBlock || !(currentFlow.flags & FlowFlags.Unreachable)) { - currentFlow = finishFlowLabel(postFinallyLabel); + else { + currentFlow = finishFlowLabel(preFinallyLabel); } } diff --git a/tests/baselines/reference/flowInFinally1.js b/tests/baselines/reference/flowInFinally1.js new file mode 100644 index 0000000000..b6bf494e83 --- /dev/null +++ b/tests/baselines/reference/flowInFinally1.js @@ -0,0 +1,33 @@ +//// [flowInFinally1.ts] + +class A { + constructor() { } + method() { } +} + +let a: A | null = null; + +try { + a = new A(); +} finally { + if (a) { + a.method(); + } +} + +//// [flowInFinally1.js] +var A = (function () { + function A() { + } + A.prototype.method = function () { }; + return A; +}()); +var a = null; +try { + a = new A(); +} +finally { + if (a) { + a.method(); + } +} diff --git a/tests/baselines/reference/flowInFinally1.symbols b/tests/baselines/reference/flowInFinally1.symbols new file mode 100644 index 0000000000..2ecedaee02 --- /dev/null +++ b/tests/baselines/reference/flowInFinally1.symbols @@ -0,0 +1,29 @@ +=== tests/cases/compiler/flowInFinally1.ts === + +class A { +>A : Symbol(A, Decl(flowInFinally1.ts, 0, 0)) + + constructor() { } + method() { } +>method : Symbol(A.method, Decl(flowInFinally1.ts, 2, 19)) +} + +let a: A | null = null; +>a : Symbol(a, Decl(flowInFinally1.ts, 6, 3)) +>A : Symbol(A, Decl(flowInFinally1.ts, 0, 0)) + +try { + a = new A(); +>a : Symbol(a, Decl(flowInFinally1.ts, 6, 3)) +>A : Symbol(A, Decl(flowInFinally1.ts, 0, 0)) + +} finally { + if (a) { +>a : Symbol(a, Decl(flowInFinally1.ts, 6, 3)) + + a.method(); +>a.method : Symbol(A.method, Decl(flowInFinally1.ts, 2, 19)) +>a : Symbol(a, Decl(flowInFinally1.ts, 6, 3)) +>method : Symbol(A.method, Decl(flowInFinally1.ts, 2, 19)) + } +} diff --git a/tests/baselines/reference/flowInFinally1.types b/tests/baselines/reference/flowInFinally1.types new file mode 100644 index 0000000000..c9cbab6dbd --- /dev/null +++ b/tests/baselines/reference/flowInFinally1.types @@ -0,0 +1,34 @@ +=== tests/cases/compiler/flowInFinally1.ts === + +class A { +>A : A + + constructor() { } + method() { } +>method : () => void +} + +let a: A | null = null; +>a : A | null +>A : A +>null : null +>null : null + +try { + a = new A(); +>a = new A() : A +>a : A | null +>new A() : A +>A : typeof A + +} finally { + if (a) { +>a : A | null + + a.method(); +>a.method() : void +>a.method : () => void +>a : A +>method : () => void + } +} diff --git a/tests/cases/compiler/flowInFinally1.ts b/tests/cases/compiler/flowInFinally1.ts new file mode 100644 index 0000000000..4ab2977e7d --- /dev/null +++ b/tests/cases/compiler/flowInFinally1.ts @@ -0,0 +1,16 @@ +// @strictNullChecks: true + +class A { + constructor() { } + method() { } +} + +let a: A | null = null; + +try { + a = new A(); +} finally { + if (a) { + a.method(); + } +} \ No newline at end of file From 8a2d16134d0001d5c0ce8f1b1df451f4a93af982 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Mon, 17 Oct 2016 06:09:19 -0700 Subject: [PATCH 59/80] Remove unnecessary assert --- src/server/scriptInfo.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/server/scriptInfo.ts b/src/server/scriptInfo.ts index 68dd59d2d3..2792b3e47a 100644 --- a/src/server/scriptInfo.ts +++ b/src/server/scriptInfo.ts @@ -84,11 +84,7 @@ namespace ts.server { } getDefaultProject() { - if (this.containingProjects.length === 0) { - return Errors.ThrowNoProject(); - } - Debug.assert(this.containingProjects.length !== 0); - return this.containingProjects[0]; + return this.containingProjects.length === 0 ? Errors.ThrowNoProject() : this.containingProjects[0]; } setFormatOptions(formatSettings: FormatCodeSettings): void { From df58df17f66f13d66d304bb4076849e07c4645f7 Mon Sep 17 00:00:00 2001 From: Herrington Darkholme Date: Mon, 17 Oct 2016 09:04:16 -0700 Subject: [PATCH 60/80] Add partially annotated function tests --- ...AnnotatedFunctionInferenceError.errors.txt | 27 ++++ ...artiallyAnnotatedFunctionInferenceError.js | 39 +++++ ...tatedFunctionInferenceWithTypeParameter.js | 85 +++++++++++ ...FunctionInferenceWithTypeParameter.symbols | 114 +++++++++++++++ ...edFunctionInferenceWithTypeParameter.types | 136 ++++++++++++++++++ ...llyAnnotatedFunctionWitoutTypeParameter.js | 12 ++ ...notatedFunctionWitoutTypeParameter.symbols | 19 +++ ...AnnotatedFunctionWitoutTypeParameter.types | 23 +++ ...artiallyAnnotatedFunctionInferenceError.ts | 14 ++ ...tatedFunctionInferenceWithTypeParameter.ts | 33 +++++ ...llyAnnotatedFunctionWitoutTypeParameter.ts | 7 + 11 files changed, 509 insertions(+) create mode 100644 tests/baselines/reference/partiallyAnnotatedFunctionInferenceError.errors.txt create mode 100644 tests/baselines/reference/partiallyAnnotatedFunctionInferenceError.js create mode 100644 tests/baselines/reference/partiallyAnnotatedFunctionInferenceWithTypeParameter.js create mode 100644 tests/baselines/reference/partiallyAnnotatedFunctionInferenceWithTypeParameter.symbols create mode 100644 tests/baselines/reference/partiallyAnnotatedFunctionInferenceWithTypeParameter.types create mode 100644 tests/baselines/reference/partiallyAnnotatedFunctionWitoutTypeParameter.js create mode 100644 tests/baselines/reference/partiallyAnnotatedFunctionWitoutTypeParameter.symbols create mode 100644 tests/baselines/reference/partiallyAnnotatedFunctionWitoutTypeParameter.types create mode 100644 tests/cases/conformance/types/contextualTypes/partiallyAnnotatedFunction/partiallyAnnotatedFunctionInferenceError.ts create mode 100644 tests/cases/conformance/types/contextualTypes/partiallyAnnotatedFunction/partiallyAnnotatedFunctionInferenceWithTypeParameter.ts create mode 100644 tests/cases/conformance/types/contextualTypes/partiallyAnnotatedFunction/partiallyAnnotatedFunctionWitoutTypeParameter.ts diff --git a/tests/baselines/reference/partiallyAnnotatedFunctionInferenceError.errors.txt b/tests/baselines/reference/partiallyAnnotatedFunctionInferenceError.errors.txt new file mode 100644 index 0000000000..a9fc9b68cf --- /dev/null +++ b/tests/baselines/reference/partiallyAnnotatedFunctionInferenceError.errors.txt @@ -0,0 +1,27 @@ +tests/cases/conformance/types/contextualTypes/partiallyAnnotatedFunction/partiallyAnnotatedFunctionInferenceError.ts(12,11): error TS2345: Argument of type '(t1: D, t2: D, t3: any) => void' is not assignable to parameter of type '(t: D, t1: D) => void'. +tests/cases/conformance/types/contextualTypes/partiallyAnnotatedFunction/partiallyAnnotatedFunctionInferenceError.ts(13,11): error TS2345: Argument of type '(t1: D, t2: D, t3: any) => void' is not assignable to parameter of type '(t: D, t1: D) => void'. +tests/cases/conformance/types/contextualTypes/partiallyAnnotatedFunction/partiallyAnnotatedFunctionInferenceError.ts(14,11): error TS2345: Argument of type '(t1: C, t2: C, t3: D) => void' is not assignable to parameter of type '(t: C, t1: C) => void'. + + +==== tests/cases/conformance/types/contextualTypes/partiallyAnnotatedFunction/partiallyAnnotatedFunctionInferenceError.ts (3 errors) ==== + class C { + test: string + } + + class D extends C { + test2: string + } + + declare function testError(a: (t: T, t1: T) => void): T + + // more args + testError((t1: D, t2, t3) => {}) + ~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '(t1: D, t2: D, t3: any) => void' is not assignable to parameter of type '(t: D, t1: D) => void'. + testError((t1, t2: D, t3) => {}) + ~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '(t1: D, t2: D, t3: any) => void' is not assignable to parameter of type '(t: D, t1: D) => void'. + testError((t1, t2, t3: D) => {}) + ~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '(t1: C, t2: C, t3: D) => void' is not assignable to parameter of type '(t: C, t1: C) => void'. + \ No newline at end of file diff --git a/tests/baselines/reference/partiallyAnnotatedFunctionInferenceError.js b/tests/baselines/reference/partiallyAnnotatedFunctionInferenceError.js new file mode 100644 index 0000000000..9702595fff --- /dev/null +++ b/tests/baselines/reference/partiallyAnnotatedFunctionInferenceError.js @@ -0,0 +1,39 @@ +//// [partiallyAnnotatedFunctionInferenceError.ts] +class C { + test: string +} + +class D extends C { + test2: string +} + +declare function testError(a: (t: T, t1: T) => void): T + +// more args +testError((t1: D, t2, t3) => {}) +testError((t1, t2: D, t3) => {}) +testError((t1, t2, t3: D) => {}) + + +//// [partiallyAnnotatedFunctionInferenceError.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var C = (function () { + function C() { + } + return C; +}()); +var D = (function (_super) { + __extends(D, _super); + function D() { + return _super.apply(this, arguments) || this; + } + return D; +}(C)); +// more args +testError(function (t1, t2, t3) { }); +testError(function (t1, t2, t3) { }); +testError(function (t1, t2, t3) { }); diff --git a/tests/baselines/reference/partiallyAnnotatedFunctionInferenceWithTypeParameter.js b/tests/baselines/reference/partiallyAnnotatedFunctionInferenceWithTypeParameter.js new file mode 100644 index 0000000000..d485fb11d7 --- /dev/null +++ b/tests/baselines/reference/partiallyAnnotatedFunctionInferenceWithTypeParameter.js @@ -0,0 +1,85 @@ +//// [partiallyAnnotatedFunctionInferenceWithTypeParameter.ts] +class C { + test: string +} + +class D extends C { + test2: string +} + +declare function test(a: (t: T, t1: T) => void): T + +declare function testRest(a: (t: T, t1: T, ...ts: T[]) => void): T + + +// exactly +test((t1: D, t2) => { t2.test2 }) +test((t1, t2: D) => { t2.test2 }) + +// zero arg +test(() => {}) + +// fewer args +test((t1: D) => {}) + +// rest arg +test((...ts: D[]) => {}) + +// source function has rest arg +testRest((t1: D) => {}) +testRest((t1, t2, t3) => {}) +testRest((t1: D, t2, t3) => {}) +testRest((t1, t2: D, t3) => {}) +testRest((t2: D, ...t3) => {}) +testRest((t2, ...t3: D[]) => {}) + + +//// [partiallyAnnotatedFunctionInferenceWithTypeParameter.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var C = (function () { + function C() { + } + return C; +}()); +var D = (function (_super) { + __extends(D, _super); + function D() { + return _super.apply(this, arguments) || this; + } + return D; +}(C)); +// exactly +test(function (t1, t2) { t2.test2; }); +test(function (t1, t2) { t2.test2; }); +// zero arg +test(function () { }); +// fewer args +test(function (t1) { }); +// rest arg +test(function () { + var ts = []; + for (var _i = 0; _i < arguments.length; _i++) { + ts[_i - 0] = arguments[_i]; + } +}); +// source function has rest arg +testRest(function (t1) { }); +testRest(function (t1, t2, t3) { }); +testRest(function (t1, t2, t3) { }); +testRest(function (t1, t2, t3) { }); +testRest(function (t2) { + var t3 = []; + for (var _i = 1; _i < arguments.length; _i++) { + t3[_i - 1] = arguments[_i]; + } +}); +testRest(function (t2) { + var t3 = []; + for (var _i = 1; _i < arguments.length; _i++) { + t3[_i - 1] = arguments[_i]; + } +}); diff --git a/tests/baselines/reference/partiallyAnnotatedFunctionInferenceWithTypeParameter.symbols b/tests/baselines/reference/partiallyAnnotatedFunctionInferenceWithTypeParameter.symbols new file mode 100644 index 0000000000..b3c66f8f8c --- /dev/null +++ b/tests/baselines/reference/partiallyAnnotatedFunctionInferenceWithTypeParameter.symbols @@ -0,0 +1,114 @@ +=== tests/cases/conformance/types/contextualTypes/partiallyAnnotatedFunction/partiallyAnnotatedFunctionInferenceWithTypeParameter.ts === +class C { +>C : Symbol(C, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 0, 0)) + + test: string +>test : Symbol(C.test, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 0, 9)) +} + +class D extends C { +>D : Symbol(D, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 2, 1)) +>C : Symbol(C, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 0, 0)) + + test2: string +>test2 : Symbol(D.test2, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 4, 19)) +} + +declare function test(a: (t: T, t1: T) => void): T +>test : Symbol(test, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 6, 1)) +>T : Symbol(T, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 8, 22)) +>C : Symbol(C, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 0, 0)) +>a : Symbol(a, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 8, 35)) +>t : Symbol(t, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 8, 39)) +>T : Symbol(T, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 8, 22)) +>t1 : Symbol(t1, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 8, 44)) +>T : Symbol(T, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 8, 22)) +>T : Symbol(T, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 8, 22)) + +declare function testRest(a: (t: T, t1: T, ...ts: T[]) => void): T +>testRest : Symbol(testRest, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 8, 63)) +>T : Symbol(T, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 10, 26)) +>C : Symbol(C, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 0, 0)) +>a : Symbol(a, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 10, 39)) +>t : Symbol(t, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 10, 43)) +>T : Symbol(T, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 10, 26)) +>t1 : Symbol(t1, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 10, 48)) +>T : Symbol(T, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 10, 26)) +>ts : Symbol(ts, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 10, 55)) +>T : Symbol(T, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 10, 26)) +>T : Symbol(T, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 10, 26)) + + +// exactly +test((t1: D, t2) => { t2.test2 }) +>test : Symbol(test, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 6, 1)) +>t1 : Symbol(t1, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 14, 6)) +>D : Symbol(D, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 2, 1)) +>t2 : Symbol(t2, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 14, 12)) +>t2.test2 : Symbol(D.test2, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 4, 19)) +>t2 : Symbol(t2, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 14, 12)) +>test2 : Symbol(D.test2, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 4, 19)) + +test((t1, t2: D) => { t2.test2 }) +>test : Symbol(test, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 6, 1)) +>t1 : Symbol(t1, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 15, 6)) +>t2 : Symbol(t2, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 15, 9)) +>D : Symbol(D, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 2, 1)) +>t2.test2 : Symbol(D.test2, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 4, 19)) +>t2 : Symbol(t2, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 15, 9)) +>test2 : Symbol(D.test2, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 4, 19)) + +// zero arg +test(() => {}) +>test : Symbol(test, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 6, 1)) + +// fewer args +test((t1: D) => {}) +>test : Symbol(test, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 6, 1)) +>t1 : Symbol(t1, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 21, 6)) +>D : Symbol(D, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 2, 1)) + +// rest arg +test((...ts: D[]) => {}) +>test : Symbol(test, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 6, 1)) +>ts : Symbol(ts, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 24, 6)) +>D : Symbol(D, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 2, 1)) + +// source function has rest arg +testRest((t1: D) => {}) +>testRest : Symbol(testRest, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 8, 63)) +>t1 : Symbol(t1, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 27, 10)) +>D : Symbol(D, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 2, 1)) + +testRest((t1, t2, t3) => {}) +>testRest : Symbol(testRest, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 8, 63)) +>t1 : Symbol(t1, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 28, 10)) +>t2 : Symbol(t2, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 28, 13)) +>t3 : Symbol(t3, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 28, 17)) + +testRest((t1: D, t2, t3) => {}) +>testRest : Symbol(testRest, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 8, 63)) +>t1 : Symbol(t1, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 29, 10)) +>D : Symbol(D, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 2, 1)) +>t2 : Symbol(t2, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 29, 16)) +>t3 : Symbol(t3, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 29, 20)) + +testRest((t1, t2: D, t3) => {}) +>testRest : Symbol(testRest, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 8, 63)) +>t1 : Symbol(t1, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 30, 10)) +>t2 : Symbol(t2, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 30, 13)) +>D : Symbol(D, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 2, 1)) +>t3 : Symbol(t3, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 30, 20)) + +testRest((t2: D, ...t3) => {}) +>testRest : Symbol(testRest, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 8, 63)) +>t2 : Symbol(t2, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 31, 10)) +>D : Symbol(D, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 2, 1)) +>t3 : Symbol(t3, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 31, 16)) + +testRest((t2, ...t3: D[]) => {}) +>testRest : Symbol(testRest, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 8, 63)) +>t2 : Symbol(t2, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 32, 10)) +>t3 : Symbol(t3, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 32, 13)) +>D : Symbol(D, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 2, 1)) + diff --git a/tests/baselines/reference/partiallyAnnotatedFunctionInferenceWithTypeParameter.types b/tests/baselines/reference/partiallyAnnotatedFunctionInferenceWithTypeParameter.types new file mode 100644 index 0000000000..c2113ae4d7 --- /dev/null +++ b/tests/baselines/reference/partiallyAnnotatedFunctionInferenceWithTypeParameter.types @@ -0,0 +1,136 @@ +=== tests/cases/conformance/types/contextualTypes/partiallyAnnotatedFunction/partiallyAnnotatedFunctionInferenceWithTypeParameter.ts === +class C { +>C : C + + test: string +>test : string +} + +class D extends C { +>D : D +>C : C + + test2: string +>test2 : string +} + +declare function test(a: (t: T, t1: T) => void): T +>test : (a: (t: T, t1: T) => void) => T +>T : T +>C : C +>a : (t: T, t1: T) => void +>t : T +>T : T +>t1 : T +>T : T +>T : T + +declare function testRest(a: (t: T, t1: T, ...ts: T[]) => void): T +>testRest : (a: (t: T, t1: T, ...ts: T[]) => void) => T +>T : T +>C : C +>a : (t: T, t1: T, ...ts: T[]) => void +>t : T +>T : T +>t1 : T +>T : T +>ts : T[] +>T : T +>T : T + + +// exactly +test((t1: D, t2) => { t2.test2 }) +>test((t1: D, t2) => { t2.test2 }) : D +>test : (a: (t: T, t1: T) => void) => T +>(t1: D, t2) => { t2.test2 } : (t1: D, t2: D) => void +>t1 : D +>D : D +>t2 : D +>t2.test2 : string +>t2 : D +>test2 : string + +test((t1, t2: D) => { t2.test2 }) +>test((t1, t2: D) => { t2.test2 }) : D +>test : (a: (t: T, t1: T) => void) => T +>(t1, t2: D) => { t2.test2 } : (t1: D, t2: D) => void +>t1 : D +>t2 : D +>D : D +>t2.test2 : string +>t2 : D +>test2 : string + +// zero arg +test(() => {}) +>test(() => {}) : C +>test : (a: (t: T, t1: T) => void) => T +>() => {} : () => void + +// fewer args +test((t1: D) => {}) +>test((t1: D) => {}) : D +>test : (a: (t: T, t1: T) => void) => T +>(t1: D) => {} : (t1: D) => void +>t1 : D +>D : D + +// rest arg +test((...ts: D[]) => {}) +>test((...ts: D[]) => {}) : D +>test : (a: (t: T, t1: T) => void) => T +>(...ts: D[]) => {} : (...ts: D[]) => void +>ts : D[] +>D : D + +// source function has rest arg +testRest((t1: D) => {}) +>testRest((t1: D) => {}) : D +>testRest : (a: (t: T, t1: T, ...ts: T[]) => void) => T +>(t1: D) => {} : (t1: D) => void +>t1 : D +>D : D + +testRest((t1, t2, t3) => {}) +>testRest((t1, t2, t3) => {}) : C +>testRest : (a: (t: T, t1: T, ...ts: T[]) => void) => T +>(t1, t2, t3) => {} : (t1: C, t2: C, t3: C) => void +>t1 : C +>t2 : C +>t3 : C + +testRest((t1: D, t2, t3) => {}) +>testRest((t1: D, t2, t3) => {}) : D +>testRest : (a: (t: T, t1: T, ...ts: T[]) => void) => T +>(t1: D, t2, t3) => {} : (t1: D, t2: D, t3: D) => void +>t1 : D +>D : D +>t2 : D +>t3 : D + +testRest((t1, t2: D, t3) => {}) +>testRest((t1, t2: D, t3) => {}) : D +>testRest : (a: (t: T, t1: T, ...ts: T[]) => void) => T +>(t1, t2: D, t3) => {} : (t1: D, t2: D, t3: D) => void +>t1 : D +>t2 : D +>D : D +>t3 : D + +testRest((t2: D, ...t3) => {}) +>testRest((t2: D, ...t3) => {}) : any +>testRest : (a: (t: T, t1: T, ...ts: T[]) => void) => T +>(t2: D, ...t3) => {} : (t2: D, ...t3: any[]) => void +>t2 : D +>D : D +>t3 : any[] + +testRest((t2, ...t3: D[]) => {}) +>testRest((t2, ...t3: D[]) => {}) : C +>testRest : (a: (t: T, t1: T, ...ts: T[]) => void) => T +>(t2, ...t3: D[]) => {} : (t2: C, ...t3: D[]) => void +>t2 : C +>t3 : D[] +>D : D + diff --git a/tests/baselines/reference/partiallyAnnotatedFunctionWitoutTypeParameter.js b/tests/baselines/reference/partiallyAnnotatedFunctionWitoutTypeParameter.js new file mode 100644 index 0000000000..8b81ff506f --- /dev/null +++ b/tests/baselines/reference/partiallyAnnotatedFunctionWitoutTypeParameter.js @@ -0,0 +1,12 @@ +//// [partiallyAnnotatedFunctionWitoutTypeParameter.ts] + +// simple case +declare function simple(f: (a: number, b: number) => void): {} + +simple((a: number, b) => {}) +simple((a, b: number) => {}) + + +//// [partiallyAnnotatedFunctionWitoutTypeParameter.js] +simple(function (a, b) { }); +simple(function (a, b) { }); diff --git a/tests/baselines/reference/partiallyAnnotatedFunctionWitoutTypeParameter.symbols b/tests/baselines/reference/partiallyAnnotatedFunctionWitoutTypeParameter.symbols new file mode 100644 index 0000000000..a7ed6b67d8 --- /dev/null +++ b/tests/baselines/reference/partiallyAnnotatedFunctionWitoutTypeParameter.symbols @@ -0,0 +1,19 @@ +=== tests/cases/conformance/types/contextualTypes/partiallyAnnotatedFunction/partiallyAnnotatedFunctionWitoutTypeParameter.ts === + +// simple case +declare function simple(f: (a: number, b: number) => void): {} +>simple : Symbol(simple, Decl(partiallyAnnotatedFunctionWitoutTypeParameter.ts, 0, 0)) +>f : Symbol(f, Decl(partiallyAnnotatedFunctionWitoutTypeParameter.ts, 2, 24)) +>a : Symbol(a, Decl(partiallyAnnotatedFunctionWitoutTypeParameter.ts, 2, 28)) +>b : Symbol(b, Decl(partiallyAnnotatedFunctionWitoutTypeParameter.ts, 2, 38)) + +simple((a: number, b) => {}) +>simple : Symbol(simple, Decl(partiallyAnnotatedFunctionWitoutTypeParameter.ts, 0, 0)) +>a : Symbol(a, Decl(partiallyAnnotatedFunctionWitoutTypeParameter.ts, 4, 8)) +>b : Symbol(b, Decl(partiallyAnnotatedFunctionWitoutTypeParameter.ts, 4, 18)) + +simple((a, b: number) => {}) +>simple : Symbol(simple, Decl(partiallyAnnotatedFunctionWitoutTypeParameter.ts, 0, 0)) +>a : Symbol(a, Decl(partiallyAnnotatedFunctionWitoutTypeParameter.ts, 5, 8)) +>b : Symbol(b, Decl(partiallyAnnotatedFunctionWitoutTypeParameter.ts, 5, 10)) + diff --git a/tests/baselines/reference/partiallyAnnotatedFunctionWitoutTypeParameter.types b/tests/baselines/reference/partiallyAnnotatedFunctionWitoutTypeParameter.types new file mode 100644 index 0000000000..f07cd5a892 --- /dev/null +++ b/tests/baselines/reference/partiallyAnnotatedFunctionWitoutTypeParameter.types @@ -0,0 +1,23 @@ +=== tests/cases/conformance/types/contextualTypes/partiallyAnnotatedFunction/partiallyAnnotatedFunctionWitoutTypeParameter.ts === + +// simple case +declare function simple(f: (a: number, b: number) => void): {} +>simple : (f: (a: number, b: number) => void) => {} +>f : (a: number, b: number) => void +>a : number +>b : number + +simple((a: number, b) => {}) +>simple((a: number, b) => {}) : {} +>simple : (f: (a: number, b: number) => void) => {} +>(a: number, b) => {} : (a: number, b: number) => void +>a : number +>b : number + +simple((a, b: number) => {}) +>simple((a, b: number) => {}) : {} +>simple : (f: (a: number, b: number) => void) => {} +>(a, b: number) => {} : (a: number, b: number) => void +>a : number +>b : number + diff --git a/tests/cases/conformance/types/contextualTypes/partiallyAnnotatedFunction/partiallyAnnotatedFunctionInferenceError.ts b/tests/cases/conformance/types/contextualTypes/partiallyAnnotatedFunction/partiallyAnnotatedFunctionInferenceError.ts new file mode 100644 index 0000000000..867b6526c1 --- /dev/null +++ b/tests/cases/conformance/types/contextualTypes/partiallyAnnotatedFunction/partiallyAnnotatedFunctionInferenceError.ts @@ -0,0 +1,14 @@ +class C { + test: string +} + +class D extends C { + test2: string +} + +declare function testError(a: (t: T, t1: T) => void): T + +// more args +testError((t1: D, t2, t3) => {}) +testError((t1, t2: D, t3) => {}) +testError((t1, t2, t3: D) => {}) diff --git a/tests/cases/conformance/types/contextualTypes/partiallyAnnotatedFunction/partiallyAnnotatedFunctionInferenceWithTypeParameter.ts b/tests/cases/conformance/types/contextualTypes/partiallyAnnotatedFunction/partiallyAnnotatedFunctionInferenceWithTypeParameter.ts new file mode 100644 index 0000000000..530d506f64 --- /dev/null +++ b/tests/cases/conformance/types/contextualTypes/partiallyAnnotatedFunction/partiallyAnnotatedFunctionInferenceWithTypeParameter.ts @@ -0,0 +1,33 @@ +class C { + test: string +} + +class D extends C { + test2: string +} + +declare function test(a: (t: T, t1: T) => void): T + +declare function testRest(a: (t: T, t1: T, ...ts: T[]) => void): T + + +// exactly +test((t1: D, t2) => { t2.test2 }) +test((t1, t2: D) => { t2.test2 }) + +// zero arg +test(() => {}) + +// fewer args +test((t1: D) => {}) + +// rest arg +test((...ts: D[]) => {}) + +// source function has rest arg +testRest((t1: D) => {}) +testRest((t1, t2, t3) => {}) +testRest((t1: D, t2, t3) => {}) +testRest((t1, t2: D, t3) => {}) +testRest((t2: D, ...t3) => {}) +testRest((t2, ...t3: D[]) => {}) diff --git a/tests/cases/conformance/types/contextualTypes/partiallyAnnotatedFunction/partiallyAnnotatedFunctionWitoutTypeParameter.ts b/tests/cases/conformance/types/contextualTypes/partiallyAnnotatedFunction/partiallyAnnotatedFunctionWitoutTypeParameter.ts new file mode 100644 index 0000000000..994df11e24 --- /dev/null +++ b/tests/cases/conformance/types/contextualTypes/partiallyAnnotatedFunction/partiallyAnnotatedFunctionWitoutTypeParameter.ts @@ -0,0 +1,7 @@ +// @noImplicitAny: true + +// simple case +declare function simple(f: (a: number, b: number) => void): {} + +simple((a: number, b) => {}) +simple((a, b: number) => {}) From 8aa56c1ccedb4070a8d6d8f3f703cd80b9841317 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Mon, 17 Oct 2016 09:12:15 -0700 Subject: [PATCH 61/80] Add fourslash test for contextually-typed `this` Regression test for #10972 --- tests/cases/fourslash/memberListOnContextualThis.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 tests/cases/fourslash/memberListOnContextualThis.ts diff --git a/tests/cases/fourslash/memberListOnContextualThis.ts b/tests/cases/fourslash/memberListOnContextualThis.ts new file mode 100644 index 0000000000..7eeb67dc62 --- /dev/null +++ b/tests/cases/fourslash/memberListOnContextualThis.ts @@ -0,0 +1,12 @@ +/// +////interface A { +//// a: string; +////} +////declare function ctx(callback: (this: A) => string): string; +////ctx(function () { return th/*1*/is./*2*/a }); + +goTo.marker('1'); +verify.quickInfoIs("this: A"); +goTo.marker('2'); +verify.memberListContains('a', '(property) A.a: string'); + From 6a59948ea125bc8c7d0205ef732f451a706bf68b Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Mon, 17 Oct 2016 09:46:26 -0700 Subject: [PATCH 62/80] Add lib-concatting newlines to jakefile as well --- Jakefile.js | 1 + 1 file changed, 1 insertion(+) diff --git a/Jakefile.js b/Jakefile.js index 64a8553ef3..18cafccd4e 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -355,6 +355,7 @@ function concatenateFiles(destinationFile, sourceFiles) { if (!fs.existsSync(sourceFiles[i])) { fail(sourceFiles[i] + " does not exist!"); } + fs.appendFileSync(temp, "\n\n"); fs.appendFileSync(temp, fs.readFileSync(sourceFiles[i])); } // Move the file to the final destination From 4c5a72831466c2738c81dfe3fa5634c11ae093a0 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Mon, 17 Oct 2016 10:15:13 -0700 Subject: [PATCH 63/80] Don't use ternary operator --- src/server/scriptInfo.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/server/scriptInfo.ts b/src/server/scriptInfo.ts index 2792b3e47a..7812792595 100644 --- a/src/server/scriptInfo.ts +++ b/src/server/scriptInfo.ts @@ -84,7 +84,10 @@ namespace ts.server { } getDefaultProject() { - return this.containingProjects.length === 0 ? Errors.ThrowNoProject() : this.containingProjects[0]; + if (this.containingProjects.length === 0) { + return Errors.ThrowNoProject(); + } + return this.containingProjects[0]; } setFormatOptions(formatSettings: FormatCodeSettings): void { From b71e8a21679d5c0b5020802b8851d109ec0d1a32 Mon Sep 17 00:00:00 2001 From: Jason Ramsay Date: Mon, 17 Oct 2016 13:11:13 -0700 Subject: [PATCH 64/80] Add isSemantic check to getDiagnosticsWorker --- src/server/session.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/server/session.ts b/src/server/session.ts index 3df6a1acb5..40110d94d5 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -389,9 +389,9 @@ namespace ts.server { }); } - private getDiagnosticsWorker(args: protocol.FileRequestArgs, selector: (project: Project, file: string) => Diagnostic[], includeLinePosition: boolean) { + private getDiagnosticsWorker(args: protocol.FileRequestArgs, isSemantic: boolean, selector: (project: Project, file: string) => Diagnostic[], includeLinePosition: boolean) { const { project, file } = this.getFileAndProject(args); - if (shouldSkipSematicCheck(project)) { + if (isSemantic && shouldSkipSematicCheck(project)) { return []; } const scriptInfo = project.getScriptInfoForNormalizedPath(file); @@ -492,11 +492,11 @@ namespace ts.server { } private getSyntacticDiagnosticsSync(args: protocol.SyntacticDiagnosticsSyncRequestArgs): protocol.Diagnostic[] | protocol.DiagnosticWithLinePosition[] { - return this.getDiagnosticsWorker(args, (project, file) => project.getLanguageService().getSyntacticDiagnostics(file), args.includeLinePosition); + return this.getDiagnosticsWorker(args, /*isSemantic*/ false, (project, file) => project.getLanguageService().getSyntacticDiagnostics(file), args.includeLinePosition); } private getSemanticDiagnosticsSync(args: protocol.SemanticDiagnosticsSyncRequestArgs): protocol.Diagnostic[] | protocol.DiagnosticWithLinePosition[] { - return this.getDiagnosticsWorker(args, (project, file) => project.getLanguageService().getSemanticDiagnostics(file), args.includeLinePosition); + return this.getDiagnosticsWorker(args, /*isSemantic*/ true, (project, file) => project.getLanguageService().getSemanticDiagnostics(file), args.includeLinePosition); } private getDocumentHighlights(args: protocol.DocumentHighlightsRequestArgs, simplifiedResult: boolean): protocol.DocumentHighlightsItem[] | DocumentHighlights[] { From 45253f85cf69f17daf401cc2b02cd8cb1c788b83 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Mon, 17 Oct 2016 14:00:49 -0700 Subject: [PATCH 65/80] Remove baseline-accept warning from CONTRIBUTING It's not longer true. You can baseline-accept after running just a few tests. --- CONTRIBUTING.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1c24202297..6dbb7e514a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -183,5 +183,3 @@ jake baseline-accept ``` to establish the new baselines as the desired behavior. This will change the files in `tests\baselines\reference`, which should be included as part of your commit. It's important to carefully validate changes in the baselines. - -**Note** that `baseline-accept` should only be run after a full test run! Accepting baselines after running a subset of tests will delete baseline files for the tests that didn't run. From 09b9ea5507b8b70d5a7c9e325e2d7126b17404d9 Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Mon, 17 Oct 2016 14:29:24 -0700 Subject: [PATCH 66/80] address PR feedback --- src/compiler/binder.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 31732bc833..086ec9dd92 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1002,7 +1002,7 @@ namespace ts { } if (node.finallyBlock) { // in finally flow is combined from pre-try/flow from try/flow from catch - // pre-flow is necessary to make sure that finally is reachable even if finaly flows in both try and finally blocks are unreachable + // pre-flow is necessary to make sure that finally is reachable even if finally flows in both try and finally blocks are unreachable addAntecedent(preFinallyLabel, preTryFlow); currentFlow = finishFlowLabel(preFinallyLabel); bind(node.finallyBlock); @@ -1014,7 +1014,7 @@ namespace ts { // console.log(2); // this line should be unreachable even if flow falls out of finally block if (!(currentFlow.flags & FlowFlags.Unreachable)) { if ((flowAfterTry.flags & FlowFlags.Unreachable) && (flowAfterCatch.flags & FlowFlags.Unreachable)) { - currentFlow = flowAfterTry == reportedUnreachableFlow || flowAfterCatch === reportedUnreachableFlow + currentFlow = flowAfterTry === reportedUnreachableFlow || flowAfterCatch === reportedUnreachableFlow ? reportedUnreachableFlow : unreachableFlow; } From af52b6314c553195474ba11d38b4b952ef2f15fa Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 17 Oct 2016 15:34:03 -0700 Subject: [PATCH 67/80] Address CR feedback --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index db95eb9bc1..41fc483f4e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6114,7 +6114,7 @@ namespace ts { // know that all parameters (including 'this') have type annotations and nothing is // subject to contextual typing. const parameter = firstOrUndefined(node.parameters); - return !(parameter && parameter.name.kind === SyntaxKind.Identifier && (parameter.name).text === "this"); + return !(parameter && parameterIsThisKeyword(parameter)); } function isContextSensitiveFunctionOrObjectLiteralMethod(func: Node): func is FunctionExpression | ArrowFunction | MethodDeclaration { From 05ebd1d5fb464405a7b7112b969d740fb3879b71 Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Mon, 17 Oct 2016 15:46:05 -0700 Subject: [PATCH 68/80] Merge pull request #11651 from Microsoft/vladima/literals-in-protocol switch enums in protocol to unions of literal types --- scripts/buildProtocol.ts | 69 +++++++++---- src/harness/unittests/session.ts | 69 ++++++++++--- src/server/editorServices.ts | 85 ++++++++++++++-- src/server/protocol.ts | 163 +++++++++++++++++++++++++++++-- src/server/session.ts | 28 ++---- 5 files changed, 346 insertions(+), 68 deletions(-) diff --git a/scripts/buildProtocol.ts b/scripts/buildProtocol.ts index 55ad086815..66f29f577d 100644 --- a/scripts/buildProtocol.ts +++ b/scripts/buildProtocol.ts @@ -10,6 +10,8 @@ function endsWith(s: string, suffix: string) { class DeclarationsWalker { private visitedTypes: ts.Type[] = []; private text = ""; + private removedTypes: ts.Type[] = []; + private constructor(private typeChecker: ts.TypeChecker, private protocolFile: ts.SourceFile) { } @@ -17,9 +19,18 @@ class DeclarationsWalker { let text = "declare namespace ts.server.protocol {\n"; var walker = new DeclarationsWalker(typeChecker, protocolFile); walker.visitTypeNodes(protocolFile); - return walker.text + text = walker.text ? `declare namespace ts.server.protocol {\n${walker.text}}` : ""; + if (walker.removedTypes) { + text += "\ndeclare namespace ts {\n"; + text += " // these types are empty stubs for types from services and should not be used directly\n" + for (const type of walker.removedTypes) { + text += ` export type ${type.symbol.name} = never;\n`; + } + text += "}" + } + return text; } private processType(type: ts.Type): void { @@ -41,19 +52,18 @@ class DeclarationsWalker { if (sourceFile === this.protocolFile || path.basename(sourceFile.fileName) === "lib.d.ts") { return; } - // splice declaration in final d.ts file - let text = decl.getFullText(); - if (decl.kind === ts.SyntaxKind.EnumDeclaration && !(decl.flags & ts.NodeFlags.Const)) { - // patch enum declaration to make them constan - const declStart = decl.getStart() - decl.getFullStart(); - const prefix = text.substring(0, declStart); - const suffix = text.substring(declStart + "enum".length, decl.getEnd() - decl.getFullStart()); - text = prefix + "const enum" + suffix; + if (decl.kind === ts.SyntaxKind.EnumDeclaration) { + this.removedTypes.push(type); + return; } - this.text += `${text}\n`; + else { + // splice declaration in final d.ts file + let text = decl.getFullText(); + this.text += `${text}\n`; + // recursively pull all dependencies into result dts file - // recursively pull all dependencies into result dts file - this.visitTypeNodes(decl); + this.visitTypeNodes(decl); + } } } } @@ -69,15 +79,37 @@ class DeclarationsWalker { case ts.SyntaxKind.Parameter: case ts.SyntaxKind.IndexSignature: if (((node.parent).type) === node) { - const type = this.typeChecker.getTypeAtLocation(node); - if (type && !(type.flags & ts.TypeFlags.TypeParameter)) { - this.processType(type); - } + this.processTypeOfNode(node); } break; + case ts.SyntaxKind.InterfaceDeclaration: + const heritageClauses = (node.parent).heritageClauses; + if (heritageClauses) { + if (heritageClauses[0].token !== ts.SyntaxKind.ExtendsKeyword) { + throw new Error(`Unexpected kind of heritage clause: ${ts.SyntaxKind[heritageClauses[0].kind]}`); + } + for (const type of heritageClauses[0].types) { + this.processTypeOfNode(type); + } + } + break; } } ts.forEachChild(node, n => this.visitTypeNodes(n)); + } + + private processTypeOfNode(node: ts.Node): void { + if (node.kind === ts.SyntaxKind.UnionType) { + for (const t of (node).types) { + this.processTypeOfNode(t); + } + } + else { + const type = this.typeChecker.getTypeAtLocation(node); + if (type && !(type.flags & (ts.TypeFlags.TypeParameter))) { + this.processType(type); + } + } } } @@ -128,9 +160,12 @@ function generateProtocolFile(protocolTs: string, typeScriptServicesDts: string) if (extraDeclarations) { protocolDts += extraDeclarations; } + protocolDts += "\nimport protocol = ts.server.protocol;"; + protocolDts += "\nexport = protocol;"; + protocolDts += "\nexport as namespace protocol;"; // do sanity check and try to compile generated text as standalone program const sanityCheckProgram = getProgramWithProtocolText(protocolDts, /*includeTypeScriptServices*/ false); - const diagnostics = [...program.getSyntacticDiagnostics(), ...program.getSemanticDiagnostics(), ...program.getGlobalDiagnostics()]; + const diagnostics = [...sanityCheckProgram.getSyntacticDiagnostics(), ...sanityCheckProgram.getSemanticDiagnostics(), ...sanityCheckProgram.getGlobalDiagnostics()]; if (diagnostics.length) { const flattenedDiagnostics = diagnostics.map(d => ts.flattenDiagnosticMessageText(d.messageText, "\n")).join("\n"); throw new Error(`Unexpected errors during sanity check: ${flattenedDiagnostics}`); diff --git a/src/harness/unittests/session.ts b/src/harness/unittests/session.ts index badbbaf526..9099f0a428 100644 --- a/src/harness/unittests/session.ts +++ b/src/harness/unittests/session.ts @@ -39,12 +39,18 @@ namespace ts.server { getLogFileName: (): string => undefined }; + class TestSession extends Session { + getProjectService() { + return this.projectService; + } + } + describe("the Session class", () => { - let session: Session; + let session: TestSession; let lastSent: protocol.Message; beforeEach(() => { - session = new Session(mockHost, nullCancellationToken, /*useOneInferredProject*/ false, /*typingsInstaller*/ undefined, Utils.byteLength, process.hrtime, mockLogger, /*canUseEvents*/ true); + session = new TestSession(mockHost, nullCancellationToken, /*useOneInferredProject*/ false, /*typingsInstaller*/ undefined, Utils.byteLength, process.hrtime, mockLogger, /*canUseEvents*/ true); session.send = (msg: protocol.Message) => { lastSent = msg; }; @@ -55,7 +61,7 @@ namespace ts.server { const req: protocol.FileRequest = { command: CommandNames.Open, seq: 0, - type: "command", + type: "request", arguments: { file: undefined } @@ -67,7 +73,7 @@ namespace ts.server { const req: protocol.Request = { command: "foobar", seq: 0, - type: "command" + type: "request" }; session.executeCommand(req); @@ -85,7 +91,7 @@ namespace ts.server { const req: protocol.ConfigureRequest = { command: CommandNames.Configure, seq: 0, - type: "command", + type: "request", arguments: { hostInfo: "unit test", formatOptions: { @@ -106,6 +112,47 @@ namespace ts.server { body: undefined }); }); + it ("should handle literal types in request", () => { + const configureRequest: protocol.ConfigureRequest = { + command: CommandNames.Configure, + seq: 0, + type: "request", + arguments: { + formatOptions: { + indentStyle: "Block" + } + } + }; + + session.onMessage(JSON.stringify(configureRequest)); + + assert.equal(session.getProjectService().getFormatCodeOptions().indentStyle, IndentStyle.Block); + + const setOptionsRequest: protocol.SetCompilerOptionsForInferredProjectsRequest = { + command: CommandNames.CompilerOptionsForInferredProjects, + seq: 1, + type: "request", + arguments: { + options: { + module: "System", + target: "ES5", + jsx: "React", + newLine: "Lf", + moduleResolution: "Node" + } + } + }; + session.onMessage(JSON.stringify(setOptionsRequest)); + assert.deepEqual( + session.getProjectService().getCompilerOptionsForInferredProjects(), + { + module: ModuleKind.System, + target: ScriptTarget.ES5, + jsx: JsxEmit.React, + newLine: NewLineKind.LineFeed, + moduleResolution: ModuleResolutionKind.NodeJs + }); + }); }); describe("onMessage", () => { @@ -118,7 +165,7 @@ namespace ts.server { const req: protocol.Request = { command: name, seq: i, - type: "command" + type: "request" }; i++; session.onMessage(JSON.stringify(req)); @@ -151,7 +198,7 @@ namespace ts.server { const req: protocol.ConfigureRequest = { command: CommandNames.Configure, seq: 0, - type: "command", + type: "request", arguments: { hostInfo: "unit test", formatOptions: { @@ -175,7 +222,7 @@ namespace ts.server { describe("send", () => { it("is an overrideable handle which sends protocol messages over the wire", () => { - const msg = { seq: 0, type: "none" }; + const msg: server.protocol.Request = { seq: 0, type: "request", command: "" }; const strmsg = JSON.stringify(msg); const len = 1 + Utils.byteLength(strmsg, "utf8"); const resultMsg = `Content-Length: ${len}\r\n\r\n${strmsg}\n`; @@ -203,7 +250,7 @@ namespace ts.server { expect(session.executeCommand({ command, seq: 0, - type: "command" + type: "request" })).to.deep.equal(result); }); it("throws when a duplicate handler is passed", () => { @@ -304,7 +351,7 @@ namespace ts.server { expect(session.executeCommand({ seq: 0, - type: "command", + type: "request", command: session.customHandler })).to.deep.equal({ response: undefined, @@ -405,7 +452,7 @@ namespace ts.server { this.seq++; this.server.enqueue({ seq: this.seq, - type: "command", + type: "request", command, arguments: args }); diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 54b257242f..6556aa0146 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -17,6 +17,68 @@ namespace ts.server { (event: ProjectServiceEvent): void; } + function prepareConvertersForEnumLikeCompilerOptions(commandLineOptions: CommandLineOption[]): Map> { + const map: Map> = createMap>(); + for (const option of commandLineOptions) { + if (typeof option.type === "object") { + const optionMap = >option.type; + // verify that map contains only numbers + for (const id in optionMap) { + Debug.assert(typeof optionMap[id] === "number"); + } + map[option.name] = optionMap; + } + } + return map; + } + + const compilerOptionConverters = prepareConvertersForEnumLikeCompilerOptions(optionDeclarations); + const indentStyle = createMap({ + "none": IndentStyle.None, + "block": IndentStyle.Block, + "smart": IndentStyle.Smart + }); + + export function convertFormatOptions(protocolOptions: protocol.FormatCodeSettings): FormatCodeSettings { + if (typeof protocolOptions.indentStyle === "string") { + protocolOptions.indentStyle = indentStyle[protocolOptions.indentStyle.toLowerCase()]; + Debug.assert(protocolOptions.indentStyle !== undefined); + } + return protocolOptions; + } + + export function convertCompilerOptions(protocolOptions: protocol.ExternalProjectCompilerOptions): CompilerOptions & protocol.CompileOnSaveMixin { + for (const id in compilerOptionConverters) { + const propertyValue = protocolOptions[id]; + if (typeof propertyValue === "string") { + const mappedValues = compilerOptionConverters[id]; + protocolOptions[id] = mappedValues[propertyValue.toLowerCase()]; + } + } + return protocolOptions; + } + + export function tryConvertScriptKindName(scriptKindName: protocol.ScriptKindName | ScriptKind): ScriptKind { + return typeof scriptKindName === "string" + ? convertScriptKindName(scriptKindName) + : scriptKindName; + } + + export function convertScriptKindName(scriptKindName: protocol.ScriptKindName) { + switch (scriptKindName) { + case "JS": + return ScriptKind.JS; + case "JSX": + return ScriptKind.JSX; + case "TS": + return ScriptKind.TS; + case "TSX": + return ScriptKind.TSX; + default: + return ScriptKind.Unknown; + } + } + /** * This helper function processes a list of projects and return the concatenated, sortd and deduplicated output of processing each project. */ @@ -63,7 +125,7 @@ namespace ts.server { const externalFilePropertyReader: FilePropertyReader = { getFileName: x => x.fileName, - getScriptKind: x => x.scriptKind, + getScriptKind: x => tryConvertScriptKindName(x.scriptKind), hasMixedContent: x => x.hasMixedContent }; @@ -214,6 +276,10 @@ namespace ts.server { this.ensureInferredProjectsUpToDate(); } + getCompilerOptionsForInferredProjects() { + return this.compilerOptionsForInferredProjects; + } + updateTypingsForProject(response: SetTypings | InvalidateCachedTypings): void { const project = this.findProject(response.projectName); if (!project) { @@ -231,10 +297,10 @@ namespace ts.server { } setCompilerOptionsForInferredProjects(projectCompilerOptions: protocol.ExternalProjectCompilerOptions): void { - this.compilerOptionsForInferredProjects = projectCompilerOptions; + this.compilerOptionsForInferredProjects = convertCompilerOptions(projectCompilerOptions); this.compileOnSaveForInferredProjects = projectCompilerOptions.compileOnSave; for (const proj of this.inferredProjects) { - proj.setCompilerOptions(projectCompilerOptions); + proj.setCompilerOptions(this.compilerOptionsForInferredProjects); proj.compileOnSaveEnabled = projectCompilerOptions.compileOnSave; } this.updateProjectGraphs(this.inferredProjects); @@ -744,12 +810,13 @@ namespace ts.server { } private createAndAddExternalProject(projectFileName: string, files: protocol.ExternalFile[], options: protocol.ExternalProjectCompilerOptions, typingOptions: TypingOptions) { + const compilerOptions = convertCompilerOptions(options); const project = new ExternalProject( projectFileName, this, this.documentRegistry, - options, - /*languageServiceEnabled*/ !this.exceededTotalSizeLimitForNonTsFiles(options, files, externalFilePropertyReader), + compilerOptions, + /*languageServiceEnabled*/ !this.exceededTotalSizeLimitForNonTsFiles(compilerOptions, files, externalFilePropertyReader), options.compileOnSave === undefined ? true : options.compileOnSave); this.addFilesToProjectAndUpdateGraph(project, files, externalFilePropertyReader, /*clientFileName*/ undefined, typingOptions, /*configFileErrors*/ undefined); @@ -1018,7 +1085,7 @@ namespace ts.server { if (args.file) { const info = this.getScriptInfoForNormalizedPath(toNormalizedPath(args.file)); if (info) { - info.setFormatOptions(args.formatOptions); + info.setFormatOptions(convertFormatOptions(args.formatOptions)); this.logger.info(`Host configuration update for file ${args.file}`); } } @@ -1028,7 +1095,7 @@ namespace ts.server { this.logger.info(`Host information ${args.hostInfo}`); } if (args.formatOptions) { - mergeMaps(this.hostConfiguration.formatCodeOptions, args.formatOptions); + mergeMaps(this.hostConfiguration.formatCodeOptions, convertFormatOptions(args.formatOptions)); this.logger.info("Format host information updated"); } } @@ -1142,7 +1209,7 @@ namespace ts.server { const scriptInfo = this.getScriptInfo(file.fileName); Debug.assert(!scriptInfo || !scriptInfo.isOpen); const normalizedPath = scriptInfo ? scriptInfo.fileName : toNormalizedPath(file.fileName); - this.openClientFileWithNormalizedPath(normalizedPath, file.content, file.scriptKind, file.hasMixedContent); + this.openClientFileWithNormalizedPath(normalizedPath, file.content, tryConvertScriptKindName(file.scriptKind), file.hasMixedContent); } } @@ -1235,7 +1302,7 @@ namespace ts.server { if (externalProject) { if (!tsConfigFiles) { // external project already exists and not config files were added - update the project and return; - this.updateNonInferredProject(externalProject, proj.rootFiles, externalFilePropertyReader, proj.options, proj.typingOptions, proj.options.compileOnSave, /*configFileErrors*/ undefined); + this.updateNonInferredProject(externalProject, proj.rootFiles, externalFilePropertyReader, convertCompilerOptions(proj.options), proj.typingOptions, proj.options.compileOnSave, /*configFileErrors*/ undefined); return; } // some config files were added to external project (that previously were not there) diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 80623f05ae..7da95e4957 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -109,7 +109,7 @@ namespace ts.server.protocol { /** * One of "request", "response", or "event" */ - type: string; + type: "request" | "response" | "event"; } /** @@ -833,7 +833,7 @@ namespace ts.server.protocol { /** * Script kind of the file */ - scriptKind?: ScriptKind; + scriptKind?: ScriptKindName | ts.ScriptKind; /** * Whether file has mixed content (i.e. .cshtml file that combines html markup with C#/JavaScript) */ @@ -866,20 +866,23 @@ namespace ts.server.protocol { typingOptions?: TypingOptions; } - /** - * For external projects, some of the project settings are sent together with - * compiler settings. - */ - export interface ExternalProjectCompilerOptions extends CompilerOptions { + export interface CompileOnSaveMixin { /** * If compile on save is enabled for the project */ compileOnSave?: boolean; } + /** + * For external projects, some of the project settings are sent together with + * compiler settings. + */ + export type ExternalProjectCompilerOptions = CompilerOptions & CompileOnSaveMixin; + /** * Contains information about current project version */ + /* @internal */ export interface ProjectVersionInfo { /** * Project name @@ -896,7 +899,7 @@ namespace ts.server.protocol { /** * Current set of compiler options for project */ - options: CompilerOptions; + options: ts.CompilerOptions; } /** @@ -920,6 +923,7 @@ namespace ts.server.protocol { * if changes is set - then this is the set of changes that should be applied to existing project * otherwise - assume that nothing is changed */ + /* @internal */ export interface ProjectFiles { /** * Information abount project verison @@ -938,6 +942,7 @@ namespace ts.server.protocol { /** * Combines project information with project level errors. */ + /* @internal */ export interface ProjectFilesWithDiagnostics extends ProjectFiles { /** * List of errors in project @@ -1012,9 +1017,11 @@ namespace ts.server.protocol { * Used to specify the script kind of the file explicitly. It could be one of the following: * "TS", "JS", "TSX", "JSX" */ - scriptKindName?: "TS" | "JS" | "TSX" | "JSX"; + scriptKindName?: ScriptKindName; } + export type ScriptKindName = "TS" | "JS" | "TSX" | "JSX"; + /** * Open request; value of command field is "open". Notify the * server that the client has file open. The server will not @@ -1109,6 +1116,7 @@ namespace ts.server.protocol { /** * Arguments to SynchronizeProjectListRequest */ + /* @internal */ export interface SynchronizeProjectListRequestArgs { /** * List of last known projects @@ -2056,4 +2064,141 @@ namespace ts.server.protocol { export interface NavTreeResponse extends Response { body?: NavigationTree; } + + export namespace IndentStyle { + export type None = "None"; + export type Block = "Block"; + export type Smart = "Smart"; + } + + export type IndentStyle = IndentStyle.None | IndentStyle.Block | IndentStyle.Smart; + + export interface EditorSettings { + baseIndentSize?: number; + indentSize?: number; + tabSize?: number; + newLineCharacter?: string; + convertTabsToSpaces?: boolean; + indentStyle?: IndentStyle | ts.IndentStyle; + } + + export interface FormatCodeSettings extends EditorSettings { + insertSpaceAfterCommaDelimiter?: boolean; + insertSpaceAfterSemicolonInForStatements?: boolean; + insertSpaceBeforeAndAfterBinaryOperators?: boolean; + insertSpaceAfterKeywordsInControlFlowStatements?: boolean; + insertSpaceAfterFunctionKeywordForAnonymousFunctions?: boolean; + insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis?: boolean; + insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets?: boolean; + insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces?: boolean; + insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces?: boolean; + placeOpenBraceOnNewLineForFunctions?: boolean; + placeOpenBraceOnNewLineForControlBlocks?: boolean; + } + + export interface CompilerOptions { + allowJs?: boolean; + allowSyntheticDefaultImports?: boolean; + allowUnreachableCode?: boolean; + allowUnusedLabels?: boolean; + baseUrl?: string; + charset?: string; + declaration?: boolean; + declarationDir?: string; + disableSizeLimit?: boolean; + emitBOM?: boolean; + emitDecoratorMetadata?: boolean; + experimentalDecorators?: boolean; + forceConsistentCasingInFileNames?: boolean; + inlineSourceMap?: boolean; + inlineSources?: boolean; + isolatedModules?: boolean; + jsx?: JsxEmit | ts.JsxEmit; + lib?: string[]; + locale?: string; + mapRoot?: string; + maxNodeModuleJsDepth?: number; + module?: ModuleKind | ts.ModuleKind; + moduleResolution?: ModuleResolutionKind | ts.ModuleResolutionKind; + newLine?: NewLineKind | ts.NewLineKind; + noEmit?: boolean; + noEmitHelpers?: boolean; + noEmitOnError?: boolean; + noErrorTruncation?: boolean; + noFallthroughCasesInSwitch?: boolean; + noImplicitAny?: boolean; + noImplicitReturns?: boolean; + noImplicitThis?: boolean; + noUnusedLocals?: boolean; + noUnusedParameters?: boolean; + noImplicitUseStrict?: boolean; + noLib?: boolean; + noResolve?: boolean; + out?: string; + outDir?: string; + outFile?: string; + paths?: MapLike; + preserveConstEnums?: boolean; + project?: string; + reactNamespace?: string; + removeComments?: boolean; + rootDir?: string; + rootDirs?: string[]; + skipLibCheck?: boolean; + skipDefaultLibCheck?: boolean; + sourceMap?: boolean; + sourceRoot?: string; + strictNullChecks?: boolean; + suppressExcessPropertyErrors?: boolean; + suppressImplicitAnyIndexErrors?: boolean; + target?: ScriptTarget | ts.ScriptTarget; + traceResolution?: boolean; + types?: string[]; + /** Paths used to used to compute primary types search locations */ + typeRoots?: string[]; + [option: string]: CompilerOptionsValue | undefined; + } + + export namespace JsxEmit { + export type None = "None"; + export type Preserve = "Preserve"; + export type React = "React"; + } + + export type JsxEmit = JsxEmit.None | JsxEmit.Preserve | JsxEmit.React; + + export namespace ModuleKind { + export type None = "None"; + export type CommonJS = "CommonJS"; + export type AMD = "AMD"; + export type UMD = "UMD"; + export type System = "System"; + export type ES6 = "ES6"; + export type ES2015 = "ES2015"; + } + + export type ModuleKind = ModuleKind.None | ModuleKind.CommonJS | ModuleKind.AMD | ModuleKind.UMD | ModuleKind.System | ModuleKind.ES6 | ModuleKind.ES2015; + + export namespace ModuleResolutionKind { + export type Classic = "Classic"; + export type Node = "Node"; + } + + export type ModuleResolutionKind = ModuleResolutionKind.Classic | ModuleResolutionKind.Node; + + export namespace NewLineKind { + export type Crlf = "Crlf"; + export type Lf = "Lf"; + } + + export type NewLineKind = NewLineKind.Crlf | NewLineKind.Lf; + + export namespace ScriptTarget { + export type ES3 = "ES3"; + export type ES5 = "ES5"; + export type ES6 = "ES6"; + export type ES2015 = "ES2015"; + } + + export type ScriptTarget = ScriptTarget.ES3 | ScriptTarget.ES5 | ScriptTarget.ES6 | ScriptTarget.ES2015; } diff --git a/src/server/session.ts b/src/server/session.ts index 3df6a1acb5..bf179c9077 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -807,7 +807,7 @@ namespace ts.server { private getIndentation(args: protocol.IndentationRequestArgs) { const { file, project } = this.getFileAndProjectWithoutRefreshingInferredProjects(args); const position = this.getPosition(args, project.getScriptInfoForNormalizedPath(file)); - const options = args.options || this.projectService.getFormatCodeOptions(file); + const options = args.options ? convertFormatOptions(args.options) : this.projectService.getFormatCodeOptions(file); const indentation = project.getLanguageService(/*ensureSynchronized*/ false).getIndentationAtPosition(file, position, options); return { position, indentation }; } @@ -874,19 +874,19 @@ namespace ts.server { private getFormattingEditsForRangeFull(args: protocol.FormatRequestArgs) { const { file, project } = this.getFileAndProjectWithoutRefreshingInferredProjects(args); - const options = args.options || this.projectService.getFormatCodeOptions(file); + const options = args.options ? convertFormatOptions(args.options) : this.projectService.getFormatCodeOptions(file); return project.getLanguageService(/*ensureSynchronized*/ false).getFormattingEditsForRange(file, args.position, args.endPosition, options); } private getFormattingEditsForDocumentFull(args: protocol.FormatRequestArgs) { const { file, project } = this.getFileAndProjectWithoutRefreshingInferredProjects(args); - const options = args.options || this.projectService.getFormatCodeOptions(file); + const options = args.options ? convertFormatOptions(args.options) : this.projectService.getFormatCodeOptions(file); return project.getLanguageService(/*ensureSynchronized*/ false).getFormattingEditsForDocument(file, options); } private getFormattingEditsAfterKeystrokeFull(args: protocol.FormatOnKeyRequestArgs) { const { file, project } = this.getFileAndProjectWithoutRefreshingInferredProjects(args); - const options = args.options || this.projectService.getFormatCodeOptions(file); + const options = args.options ? convertFormatOptions(args.options) : this.projectService.getFormatCodeOptions(file); return project.getLanguageService(/*ensureSynchronized*/ false).getFormattingEditsAfterKeystroke(file, args.position, args.key, options); } @@ -1426,24 +1426,8 @@ namespace ts.server { [CommandNames.RenameInfoFull]: (request: protocol.FileLocationRequest) => { return this.requiredResponse(this.getRenameInfo(request.arguments)); }, - [CommandNames.Open]: (request: protocol.Request) => { - const openArgs = request.arguments; - let scriptKind: ScriptKind; - switch (openArgs.scriptKindName) { - case "TS": - scriptKind = ScriptKind.TS; - break; - case "JS": - scriptKind = ScriptKind.JS; - break; - case "TSX": - scriptKind = ScriptKind.TSX; - break; - case "JSX": - scriptKind = ScriptKind.JSX; - break; - } - this.openClientFile(toNormalizedPath(openArgs.file), openArgs.fileContent, scriptKind); + [CommandNames.Open]: (request: protocol.OpenRequest) => { + this.openClientFile(toNormalizedPath(request.arguments.file), request.arguments.fileContent, convertScriptKindName(request.arguments.scriptKindName)); return this.notRequired(); }, [CommandNames.Quickinfo]: (request: protocol.QuickInfoRequest) => { From 722e72339209470858dde59a08e31d8a9a598ab8 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Mon, 17 Oct 2016 15:47:33 -0700 Subject: [PATCH 69/80] Include the correct file by default (#11685) --- src/compiler/utilities.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 7d4a144407..952a320525 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -4172,7 +4172,7 @@ namespace ts { case ScriptTarget.ES2016: return "lib.es2016.d.ts"; case ScriptTarget.ES2015: - return "lib.es2015.d.ts"; + return "lib.es6.d.ts"; default: return "lib.d.ts"; From 28899f386011353aeee3ccb17accab03a927f444 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Mon, 17 Oct 2016 16:08:00 -0700 Subject: [PATCH 70/80] Update the resolveName symbol flags for 'require' resolution --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1354002a29..7ac93d2e31 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12538,7 +12538,7 @@ namespace ts { if (isInJavaScriptFile(node) && isRequireCall(node, /*checkArgumentIsStringLiteral*/true) && // Make sure require is not a local function - !resolveName(node.expression, (node.expression).text, SymbolFlags.Value | SymbolFlags.ExportValue, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined)) { + !resolveName(node.expression, (node.expression).text, SymbolFlags.Value, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined)) { return resolveExternalModuleTypeByLiteral(node.arguments[0]); } From deb344907733d37822bb8e2f56b16f55d64c7c6c Mon Sep 17 00:00:00 2001 From: Jason Ramsay Date: Mon, 17 Oct 2016 14:50:03 -0700 Subject: [PATCH 71/80] Add getSyntacticDiagnostics unit test --- src/server/client.ts | 28 +++++++++++-------- .../getJavaScriptSyntacticDiagnostics01.ts | 23 +++++++++++++++ 2 files changed, 40 insertions(+), 11 deletions(-) create mode 100644 tests/cases/fourslash/server/getJavaScriptSyntacticDiagnostics01.ts diff --git a/src/server/client.ts b/src/server/client.ts index b0bc2c5dac..6d8ef419a7 100644 --- a/src/server/client.ts +++ b/src/server/client.ts @@ -424,33 +424,39 @@ namespace ts.server { } getSyntacticDiagnostics(fileName: string): Diagnostic[] { - const args: protocol.SyntacticDiagnosticsSyncRequestArgs = { file: fileName }; + const args: protocol.SyntacticDiagnosticsSyncRequestArgs = { file: fileName, includeLinePosition: true }; const request = this.processRequest(CommandNames.SyntacticDiagnosticsSync, args); const response = this.processResponse(request); - return (response.body).map(entry => this.convertDiagnostic(entry, fileName)); + return (response.body).map(entry => this.convertDiagnostic(entry, fileName)); } getSemanticDiagnostics(fileName: string): Diagnostic[] { - const args: protocol.SemanticDiagnosticsSyncRequestArgs = { file: fileName }; + const args: protocol.SemanticDiagnosticsSyncRequestArgs = { file: fileName, includeLinePosition: true }; const request = this.processRequest(CommandNames.SemanticDiagnosticsSync, args); const response = this.processResponse(request); - return (response.body).map(entry => this.convertDiagnostic(entry, fileName)); + return (response.body).map(entry => this.convertDiagnostic(entry, fileName)); } - convertDiagnostic(entry: protocol.Diagnostic, fileName: string): Diagnostic { - const start = this.lineOffsetToPosition(fileName, entry.start); - const end = this.lineOffsetToPosition(fileName, entry.end); + convertDiagnostic(entry: protocol.DiagnosticWithLinePosition, fileName: string): Diagnostic { + let category: DiagnosticCategory; + for (const id in DiagnosticCategory) { + if (typeof id === "string" && entry.category === id.toLowerCase()) { + category = (DiagnosticCategory)[id]; + } + } + + Debug.assert(category !== undefined, "convertDiagnostic: category should not be undefined"); return { file: undefined, - start: start, - length: end - start, - messageText: entry.text, - category: undefined, + start: entry.start, + length: entry.length, + messageText: entry.message, + category: category, code: entry.code }; } diff --git a/tests/cases/fourslash/server/getJavaScriptSyntacticDiagnostics01.ts b/tests/cases/fourslash/server/getJavaScriptSyntacticDiagnostics01.ts new file mode 100644 index 0000000000..0aa88ebd90 --- /dev/null +++ b/tests/cases/fourslash/server/getJavaScriptSyntacticDiagnostics01.ts @@ -0,0 +1,23 @@ +/// + +// @allowJs: true +// @Filename: a.js +//// var ===; + +verify.getSyntacticDiagnostics(`[ + { + "message": "Variable declaration expected.", + "start": 4, + "length": 3, + "category": "error", + "code": 1134 + }, + { + "message": "Expression expected.", + "start": 7, + "length": 1, + "category": "error", + "code": 1109 + } +]`); +verify.getSemanticDiagnostics(`[]`); \ No newline at end of file From 121f51e5523a6bcc6ac6d3790f4cd7fee68ac2ab Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Mon, 17 Oct 2016 23:15:22 -0700 Subject: [PATCH 72/80] Merge pull request #11694 from Microsoft/vladima/reload-tmp allow reload from temp files --- .../unittests/tsserverProjectSystem.ts | 62 ++++++++++++++++++- src/server/project.ts | 4 +- src/server/scriptInfo.ts | 4 +- src/server/session.ts | 3 +- 4 files changed, 66 insertions(+), 7 deletions(-) diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 9d086e4549..c3962c7749 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -170,11 +170,18 @@ namespace ts.projectSystem { return host; } + class TestSession extends server.Session { + getProjectService() { + return this.projectService; + } + }; + export function createSession(host: server.ServerHost, typingsInstaller?: server.ITypingsInstaller, projectServiceEventHandler?: server.ProjectServiceEventHandler) { if (typingsInstaller === undefined) { typingsInstaller = new TestTypingsInstaller("/a/data/", /*throttleLimit*/5, host); } - return new server.Session(host, nullCancellationToken, /*useSingleInferredProject*/ false, typingsInstaller, Utils.byteLength, process.hrtime, nullLogger, /*canUseEvents*/ projectServiceEventHandler !== undefined, projectServiceEventHandler); + + return new TestSession(host, nullCancellationToken, /*useSingleInferredProject*/ false, typingsInstaller, Utils.byteLength, process.hrtime, nullLogger, /*canUseEvents*/ projectServiceEventHandler !== undefined, projectServiceEventHandler); } export interface CreateProjectServiceParameters { @@ -515,11 +522,13 @@ namespace ts.projectSystem { this.reloadFS(filesOrFolders); } + write(s: string) { + } + readonly readFile = (s: string) => (this.fs.get(this.toPath(s))).content; readonly resolvePath = (s: string) => s; readonly getExecutingFilePath = () => this.executingFilePath; readonly getCurrentDirectory = () => this.currentDirectory; - readonly write = (s: string) => notImplemented(); readonly exit = () => notImplemented(); readonly getEnvironmentVariable = (v: string) => notImplemented(); } @@ -2420,4 +2429,53 @@ namespace ts.projectSystem { assert.isTrue(inferredProject.containsFile(file1.path)); }); }); + + describe("reload", () => { + it("should work with temp file", () => { + const f1 = { + path: "/a/b/app.ts", + content: "let x = 1" + }; + const tmp = { + path: "/a/b/app.tmp", + content: "const y = 42" + }; + const host = createServerHost([f1, tmp]); + const session = createSession(host); + + // send open request + session.executeCommand({ + type: "request", + command: "open", + seq: 1, + arguments: { file: f1.path } + }); + + // reload from tmp file + session.executeCommand({ + type: "request", + command: "reload", + seq: 2, + arguments: { file: f1.path, tmpfile: tmp.path } + }); + + // verify content + const projectServiice = session.getProjectService(); + const snap1 = projectServiice.getScriptInfo(f1.path).snap(); + assert.equal(snap1.getText(0, snap1.getLength()), tmp.content, "content should be equal to the content of temp file"); + + // reload from original file file + session.executeCommand({ + type: "request", + command: "reload", + seq: 2, + arguments: { file: f1.path } + }); + + // verify content + const snap2 = projectServiice.getScriptInfo(f1.path).snap(); + assert.equal(snap2.getText(0, snap2.getLength()), f1.content, "content should be equal to the content of original file"); + + }); + }); } \ No newline at end of file diff --git a/src/server/project.ts b/src/server/project.ts index a355d75f94..dd8902e83d 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -437,11 +437,11 @@ namespace ts.server { } } - reloadScript(filename: NormalizedPath): boolean { + reloadScript(filename: NormalizedPath, tempFileName?: NormalizedPath): boolean { const script = this.projectService.getScriptInfoForNormalizedPath(filename); if (script) { Debug.assert(script.isAttached(this)); - script.reloadFromFile(); + script.reloadFromFile(tempFileName); return true; } return false; diff --git a/src/server/scriptInfo.ts b/src/server/scriptInfo.ts index 7812792595..84649863a7 100644 --- a/src/server/scriptInfo.ts +++ b/src/server/scriptInfo.ts @@ -125,12 +125,12 @@ namespace ts.server { this.host.writeFile(fileName, snap.getText(0, snap.getLength())); } - reloadFromFile() { + reloadFromFile(tempFileName?: NormalizedPath) { if (this.hasMixedContent) { this.reload(""); } else { - this.svc.reloadFromFile(this.fileName); + this.svc.reloadFromFile(tempFileName || this.fileName); this.markContainingProjectsAsDirty(); } } diff --git a/src/server/session.ts b/src/server/session.ts index f029dc4a5d..3bf4acd248 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -1076,11 +1076,12 @@ namespace ts.server { private reload(args: protocol.ReloadRequestArgs, reqSeq: number) { const file = toNormalizedPath(args.file); + const tempFileName = args.tmpfile && toNormalizedPath(args.tmpfile); const project = this.projectService.getDefaultProjectForFile(file, /*refreshInferredProjects*/ true); if (project) { this.changeSeq++; // make sure no changes happen before this one is finished - if (project.reloadScript(file)) { + if (project.reloadScript(file, tempFileName)) { this.output(undefined, CommandNames.Reload, reqSeq); } } From de876bdfc96d942115ab22aef8b6130c210eaee3 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Tue, 18 Oct 2016 07:34:48 -0700 Subject: [PATCH 73/80] Use an ES5 target --- Jakefile.js | 2 ++ src/compiler/tsconfig.json | 3 ++- src/harness/tsconfig.json | 3 ++- src/server/cancellationToken/tsconfig.json | 3 ++- src/server/tsconfig.json | 3 ++- src/server/tsconfig.library.json | 3 ++- src/server/typingsInstaller/tsconfig.json | 3 ++- src/services/tsconfig.json | 3 ++- 8 files changed, 16 insertions(+), 7 deletions(-) diff --git a/Jakefile.js b/Jakefile.js index 6592347b59..301dc574eb 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -448,6 +448,8 @@ function compileFile(outFile, sources, prereqs, prefixes, useBuiltCompiler, opts options += " --stripInternal"; } + options += " --target es5"; + var cmd = host + " " + compilerPath + " " + options + " "; cmd = cmd + sources.join(" "); console.log(cmd + "\n"); diff --git a/src/compiler/tsconfig.json b/src/compiler/tsconfig.json index 92a3ea3855..65ba20f18d 100644 --- a/src/compiler/tsconfig.json +++ b/src/compiler/tsconfig.json @@ -8,7 +8,8 @@ "outFile": "../../built/local/tsc.js", "sourceMap": true, "declaration": true, - "stripInternal": true + "stripInternal": true, + "target": "es5" }, "files": [ "core.ts", diff --git a/src/harness/tsconfig.json b/src/harness/tsconfig.json index bbc1a49a0f..d0f500e27a 100644 --- a/src/harness/tsconfig.json +++ b/src/harness/tsconfig.json @@ -10,7 +10,8 @@ "stripInternal": true, "types": [ "node", "mocha", "chai" - ] + ], + "target": "es5" }, "files": [ "../compiler/core.ts", diff --git a/src/server/cancellationToken/tsconfig.json b/src/server/cancellationToken/tsconfig.json index 1245fc34fd..bcfe5ddb46 100644 --- a/src/server/cancellationToken/tsconfig.json +++ b/src/server/cancellationToken/tsconfig.json @@ -10,7 +10,8 @@ "stripInternal": true, "types": [ "node" - ] + ], + "target": "es5" }, "files": [ "cancellationToken.ts" diff --git a/src/server/tsconfig.json b/src/server/tsconfig.json index 9f907446c0..5308abb0c8 100644 --- a/src/server/tsconfig.json +++ b/src/server/tsconfig.json @@ -10,7 +10,8 @@ "stripInternal": true, "types": [ "node" - ] + ], + "target": "es5" }, "files": [ "../services/shims.ts", diff --git a/src/server/tsconfig.library.json b/src/server/tsconfig.library.json index a450b591a7..a287a77fed 100644 --- a/src/server/tsconfig.library.json +++ b/src/server/tsconfig.library.json @@ -7,7 +7,8 @@ "sourceMap": true, "stripInternal": true, "declaration": true, - "types": [] + "types": [], + "target": "es5" }, "files": [ "../services/shims.ts", diff --git a/src/server/typingsInstaller/tsconfig.json b/src/server/typingsInstaller/tsconfig.json index fc4b896f26..58805081de 100644 --- a/src/server/typingsInstaller/tsconfig.json +++ b/src/server/typingsInstaller/tsconfig.json @@ -10,7 +10,8 @@ "stripInternal": true, "types": [ "node" - ] + ], + "target": "es5" }, "files": [ "../types.d.ts", diff --git a/src/services/tsconfig.json b/src/services/tsconfig.json index a3482a63c3..4e130c7dfb 100644 --- a/src/services/tsconfig.json +++ b/src/services/tsconfig.json @@ -9,7 +9,8 @@ "sourceMap": true, "stripInternal": true, "noResolve": false, - "declaration": true + "declaration": true, + "target": "es5" }, "files": [ "../compiler/core.ts", From 64e8221a4498179cd90ea91a9e5ceacd14bafa6d Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Tue, 18 Oct 2016 08:18:01 -0700 Subject: [PATCH 74/80] Use single `concat` call instead of repeated calls --- src/compiler/program.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 50e53ab948..06e9f6f30f 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -766,7 +766,7 @@ namespace ts { const fileProcessingDiagnosticsInFile = fileProcessingDiagnostics.getDiagnostics(sourceFile.fileName); const programDiagnosticsInFile = programDiagnostics.getDiagnostics(sourceFile.fileName); - return bindDiagnostics.concat(checkDiagnostics).concat(fileProcessingDiagnosticsInFile).concat(programDiagnosticsInFile); + return bindDiagnostics.concat(checkDiagnostics, fileProcessingDiagnosticsInFile, programDiagnosticsInFile); }); } From 1f7f67de17879bb70825d8c5955e3b7c036ace10 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Tue, 18 Oct 2016 08:09:56 -0700 Subject: [PATCH 75/80] Type arguments to formatStringFromArgs as strings instead of implicitly stringifying --- src/compiler/checker.ts | 16 +++++++++------- src/compiler/commandLineParser.ts | 5 +---- src/compiler/core.ts | 6 +++--- src/compiler/utilities.ts | 2 +- src/harness/unittests/commandLineParsing.ts | 16 ++++++++-------- .../convertCompilerOptionsFromJson.ts | 18 +++++++++--------- ...ions module-kind is out-of-range.errors.txt | 4 ++-- ...ns target-script is out-of-range.errors.txt | 4 ++-- 8 files changed, 35 insertions(+), 36 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d3f15f2367..0fee5611c6 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -368,7 +368,7 @@ namespace ts { return emitResolver; } - function error(location: Node, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): void { + function error(location: Node, message: DiagnosticMessage, arg0?: string, arg1?: string, arg2?: string): void { const diagnostic = location ? createDiagnosticForNode(location, message, arg0, arg1, arg2) : createCompilerDiagnostic(message, arg0, arg1, arg2); @@ -3004,7 +3004,8 @@ namespace ts { : elementType; if (!type) { if (isTupleType(parentType)) { - error(declaration, Diagnostics.Tuple_type_0_with_length_1_cannot_be_assigned_to_tuple_with_length_2, typeToString(parentType), getTypeReferenceArity(parentType), pattern.elements.length); + error(declaration, Diagnostics.Tuple_type_0_with_length_1_cannot_be_assigned_to_tuple_with_length_2, + typeToString(parentType), getTypeReferenceArity(parentType).toString(), pattern.elements.length.toString()); } else { error(declaration, Diagnostics.Type_0_has_no_property_1, typeToString(parentType), propName); @@ -5103,7 +5104,7 @@ namespace ts { const typeParameters = type.localTypeParameters; if (typeParameters) { if (!node.typeArguments || node.typeArguments.length !== typeParameters.length) { - error(node, Diagnostics.Generic_type_0_requires_1_type_argument_s, typeToString(type, /*enclosingDeclaration*/ undefined, TypeFormatFlags.WriteArrayAsGenericType), typeParameters.length); + error(node, Diagnostics.Generic_type_0_requires_1_type_argument_s, typeToString(type, /*enclosingDeclaration*/ undefined, TypeFormatFlags.WriteArrayAsGenericType), typeParameters.length.toString()); return unknownType; } // In a type reference, the outer type parameters of the referenced class or interface are automatically @@ -5127,7 +5128,7 @@ namespace ts { const typeParameters = links.typeParameters; if (typeParameters) { if (!node.typeArguments || node.typeArguments.length !== typeParameters.length) { - error(node, Diagnostics.Generic_type_0_requires_1_type_argument_s, symbolToString(symbol), typeParameters.length); + error(node, Diagnostics.Generic_type_0_requires_1_type_argument_s, symbolToString(symbol), typeParameters.length.toString()); return unknownType; } const typeArguments = map(node.typeArguments, getTypeFromTypeNodeNoAlias); @@ -5270,7 +5271,7 @@ namespace ts { return arity ? emptyGenericType : emptyObjectType; } if (((type).typeParameters ? (type).typeParameters.length : 0) !== arity) { - error(getTypeDeclaration(symbol), Diagnostics.Global_type_0_must_have_1_type_parameter_s, symbol.name, arity); + error(getTypeDeclaration(symbol), Diagnostics.Global_type_0_must_have_1_type_parameter_s, symbol.name, arity.toString()); return arity ? emptyGenericType : emptyObjectType; } return type; @@ -8537,7 +8538,7 @@ namespace ts { // An evolving array type tracks the element types that have so far been seen in an // 'x.push(value)' or 'x[n] = value' operation along the control flow graph. Evolving // array types are ultimately converted into manifest array types (using getFinalArrayType) - // and never escape the getFlowTypeOfReference function. + // and never escape the getFlowTypeOfReference function. function createEvolvingArrayType(elementType: Type): AnonymousType { const result = createObjectType(TypeFlags.Anonymous); result.elementType = elementType; @@ -13630,7 +13631,8 @@ namespace ts { // such as NodeCheckFlags.LexicalThis on "this"expression. checkExpression(element); if (isTupleType(sourceType)) { - error(element, Diagnostics.Tuple_type_0_with_length_1_cannot_be_assigned_to_tuple_with_length_2, typeToString(sourceType), getTypeReferenceArity(sourceType), elements.length); + error(element, Diagnostics.Tuple_type_0_with_length_1_cannot_be_assigned_to_tuple_with_length_2, + typeToString(sourceType), getTypeReferenceArity(sourceType).toString(), elements.length.toString()); } else { error(element, Diagnostics.Type_0_has_no_property_1, typeToString(sourceType), propName); diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index d5207e4ce9..d6c7dad0e8 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -515,10 +515,7 @@ namespace ts { /* @internal */ export function createCompilerDiagnosticForInvalidCustomType(opt: CommandLineOptionOfCustomType): Diagnostic { - const namesOfType: string[] = []; - for (const key in opt.type) { - namesOfType.push(` '${key}'`); - } + const namesOfType = Object.keys(opt.type).map(key => `'${key}'`).join(", "); return createCompilerDiagnostic(Diagnostics.Argument_for_0_option_must_be_Colon_1, `--${opt.name}`, namesOfType); } diff --git a/src/compiler/core.ts b/src/compiler/core.ts index befa30b600..fd0724db31 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -940,7 +940,7 @@ namespace ts { } } - function formatStringFromArgs(text: string, args: { [index: number]: any; }, baseIndex?: number): string { + function formatStringFromArgs(text: string, args: { [index: number]: string; }, baseIndex?: number): string { baseIndex = baseIndex || 0; return text.replace(/{(\d+)}/g, (match, index?) => args[+index + baseIndex]); @@ -952,7 +952,7 @@ namespace ts { return localizedDiagnosticMessages && localizedDiagnosticMessages[message.key] || message.message; } - export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage, ...args: any[]): Diagnostic; + export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage, ...args: string[]): Diagnostic; export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage): Diagnostic { const end = start + length; @@ -992,7 +992,7 @@ namespace ts { return text; } - export function createCompilerDiagnostic(message: DiagnosticMessage, ...args: any[]): Diagnostic; + export function createCompilerDiagnostic(message: DiagnosticMessage, ...args: string[]): Diagnostic; export function createCompilerDiagnostic(message: DiagnosticMessage): Diagnostic { let text = getLocaleSpecificMessage(message); diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 952a320525..dfdfae9c25 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -503,7 +503,7 @@ namespace ts { return getFullWidth(name) === 0 ? "(Missing)" : getTextOfNode(name); } - export function createDiagnosticForNode(node: Node, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): Diagnostic { + export function createDiagnosticForNode(node: Node, message: DiagnosticMessage, arg0?: string, arg1?: string, arg2?: string): Diagnostic { const sourceFile = getSourceFileOfNode(node); const span = getErrorSpanForNode(sourceFile, node); return createFileDiagnostic(sourceFile, span.start, span.length, message, arg0, arg1, arg2); diff --git a/src/harness/unittests/commandLineParsing.ts b/src/harness/unittests/commandLineParsing.ts index cd9bf88df6..67bc1e9b79 100644 --- a/src/harness/unittests/commandLineParsing.ts +++ b/src/harness/unittests/commandLineParsing.ts @@ -60,7 +60,7 @@ namespace ts { assertParseResult(["--lib", "es5,invalidOption", "0.ts"], { errors: [{ - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'", category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, @@ -87,7 +87,7 @@ namespace ts { start: undefined, length: undefined, }, { - messageText: "Argument for '--jsx' option must be: 'preserve', 'react'", + messageText: "Argument for '--jsx' option must be: 'preserve', 'react'", category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, @@ -113,7 +113,7 @@ namespace ts { start: undefined, length: undefined, }, { - messageText: "Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015'", + messageText: "Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015'", category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, @@ -139,7 +139,7 @@ namespace ts { start: undefined, length: undefined, }, { - messageText: "Argument for '--newLine' option must be: 'crlf', 'lf'", + messageText: "Argument for '--newLine' option must be: 'crlf', 'lf'", category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, @@ -165,7 +165,7 @@ namespace ts { start: undefined, length: undefined, }, { - messageText: "Argument for '--target' option must be: 'es3', 'es5', 'es6', 'es2015', 'es2016', 'es2017'", + messageText: "Argument for '--target' option must be: 'es3', 'es5', 'es6', 'es2015', 'es2016', 'es2017'", category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, @@ -191,7 +191,7 @@ namespace ts { start: undefined, length: undefined, }, { - messageText: "Argument for '--moduleResolution' option must be: 'node', 'classic'", + messageText: "Argument for '--moduleResolution' option must be: 'node', 'classic'", category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, @@ -263,7 +263,7 @@ namespace ts { assertParseResult(["--lib", "es5,", "es7", "0.ts"], { errors: [{ - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'", category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, @@ -283,7 +283,7 @@ namespace ts { assertParseResult(["--lib", "es5, ", "es7", "0.ts"], { errors: [{ - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'", category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, diff --git a/src/harness/unittests/convertCompilerOptionsFromJson.ts b/src/harness/unittests/convertCompilerOptionsFromJson.ts index a2174c17e4..2942675f0a 100644 --- a/src/harness/unittests/convertCompilerOptionsFromJson.ts +++ b/src/harness/unittests/convertCompilerOptionsFromJson.ts @@ -94,7 +94,7 @@ namespace ts { file: undefined, start: 0, length: 0, - messageText: "Argument for '--jsx' option must be: 'preserve', 'react'", + messageText: "Argument for '--jsx' option must be: 'preserve', 'react'", code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] @@ -122,7 +122,7 @@ namespace ts { file: undefined, start: 0, length: 0, - messageText: "Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015'", + messageText: "Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015'", code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] @@ -150,7 +150,7 @@ namespace ts { file: undefined, start: 0, length: 0, - messageText: "Argument for '--newLine' option must be: 'crlf', 'lf'", + messageText: "Argument for '--newLine' option must be: 'crlf', 'lf'", code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] @@ -176,7 +176,7 @@ namespace ts { file: undefined, start: 0, length: 0, - messageText: "Argument for '--target' option must be: 'es3', 'es5', 'es6', 'es2015', 'es2016', 'es2017'", + messageText: "Argument for '--target' option must be: 'es3', 'es5', 'es6', 'es2015', 'es2016', 'es2017'", code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] @@ -202,7 +202,7 @@ namespace ts { file: undefined, start: 0, length: 0, - messageText: "Argument for '--moduleResolution' option must be: 'node', 'classic'", + messageText: "Argument for '--moduleResolution' option must be: 'node', 'classic'", code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] @@ -233,7 +233,7 @@ namespace ts { file: undefined, start: 0, length: 0, - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'", code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] @@ -264,7 +264,7 @@ namespace ts { file: undefined, start: 0, length: 0, - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'", code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] @@ -295,7 +295,7 @@ namespace ts { file: undefined, start: 0, length: 0, - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'", code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] @@ -326,7 +326,7 @@ namespace ts { file: undefined, start: 0, length: 0, - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'", code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] diff --git a/tests/baselines/reference/transpile/Report an error when compiler-options module-kind is out-of-range.errors.txt b/tests/baselines/reference/transpile/Report an error when compiler-options module-kind is out-of-range.errors.txt index d7d6eb6930..7778f6c23c 100644 --- a/tests/baselines/reference/transpile/Report an error when compiler-options module-kind is out-of-range.errors.txt +++ b/tests/baselines/reference/transpile/Report an error when compiler-options module-kind is out-of-range.errors.txt @@ -1,6 +1,6 @@ -error TS6046: Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015' +error TS6046: Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015' -!!! error TS6046: Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015' +!!! error TS6046: Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015' ==== file.ts (0 errors) ==== \ No newline at end of file diff --git a/tests/baselines/reference/transpile/Report an error when compiler-options target-script is out-of-range.errors.txt b/tests/baselines/reference/transpile/Report an error when compiler-options target-script is out-of-range.errors.txt index d7d6eb6930..7778f6c23c 100644 --- a/tests/baselines/reference/transpile/Report an error when compiler-options target-script is out-of-range.errors.txt +++ b/tests/baselines/reference/transpile/Report an error when compiler-options target-script is out-of-range.errors.txt @@ -1,6 +1,6 @@ -error TS6046: Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015' +error TS6046: Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015' -!!! error TS6046: Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015' +!!! error TS6046: Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015' ==== file.ts (0 errors) ==== \ No newline at end of file From ff17eeda8f3487fb1a1659beb4bb233efcbc08d3 Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Tue, 18 Oct 2016 11:35:22 -0700 Subject: [PATCH 76/80] check heritage clause for the presence of entry with Extends keyword (#11711) --- src/compiler/transformers/ts.ts | 2 +- tests/baselines/reference/classExpressions.js | 20 ++++++++++++++++++ .../reference/classExpressions.symbols | 19 +++++++++++++++++ .../reference/classExpressions.types | 21 +++++++++++++++++++ tests/cases/compiler/classExpressions.ts | 8 +++++++ 5 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/classExpressions.js create mode 100644 tests/baselines/reference/classExpressions.symbols create mode 100644 tests/baselines/reference/classExpressions.types create mode 100644 tests/cases/compiler/classExpressions.ts diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 1d930c3c21..a1190efee1 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -795,7 +795,7 @@ namespace ts { function visitClassExpression(node: ClassExpression): Expression { const staticProperties = getInitializedProperties(node, /*isStatic*/ true); const heritageClauses = visitNodes(node.heritageClauses, visitor, isHeritageClause); - const members = transformClassMembers(node, heritageClauses !== undefined); + const members = transformClassMembers(node, some(heritageClauses, c => c.token === SyntaxKind.ExtendsKeyword)); const classExpression = setOriginalNode( createClassExpression( diff --git a/tests/baselines/reference/classExpressions.js b/tests/baselines/reference/classExpressions.js new file mode 100644 index 0000000000..3932fa5045 --- /dev/null +++ b/tests/baselines/reference/classExpressions.js @@ -0,0 +1,20 @@ +//// [classExpressions.ts] +interface A {} +let x = class B implements A { + prop: number; + onStart(): void { + } + func = () => { + } +}; + +//// [classExpressions.js] +var x = (function () { + function B() { + this.func = function () { + }; + } + B.prototype.onStart = function () { + }; + return B; +}()); diff --git a/tests/baselines/reference/classExpressions.symbols b/tests/baselines/reference/classExpressions.symbols new file mode 100644 index 0000000000..038b1b8111 --- /dev/null +++ b/tests/baselines/reference/classExpressions.symbols @@ -0,0 +1,19 @@ +=== tests/cases/compiler/classExpressions.ts === +interface A {} +>A : Symbol(A, Decl(classExpressions.ts, 0, 0)) + +let x = class B implements A { +>x : Symbol(x, Decl(classExpressions.ts, 1, 3)) +>B : Symbol(B, Decl(classExpressions.ts, 1, 7)) +>A : Symbol(A, Decl(classExpressions.ts, 0, 0)) + + prop: number; +>prop : Symbol(B.prop, Decl(classExpressions.ts, 1, 30)) + + onStart(): void { +>onStart : Symbol(B.onStart, Decl(classExpressions.ts, 2, 17)) + } + func = () => { +>func : Symbol(B.func, Decl(classExpressions.ts, 4, 5)) + } +}; diff --git a/tests/baselines/reference/classExpressions.types b/tests/baselines/reference/classExpressions.types new file mode 100644 index 0000000000..3fcff32c4a --- /dev/null +++ b/tests/baselines/reference/classExpressions.types @@ -0,0 +1,21 @@ +=== tests/cases/compiler/classExpressions.ts === +interface A {} +>A : A + +let x = class B implements A { +>x : typeof B +>class B implements A { prop: number; onStart(): void { } func = () => { }} : typeof B +>B : typeof B +>A : A + + prop: number; +>prop : number + + onStart(): void { +>onStart : () => void + } + func = () => { +>func : () => void +>() => { } : () => void + } +}; diff --git a/tests/cases/compiler/classExpressions.ts b/tests/cases/compiler/classExpressions.ts new file mode 100644 index 0000000000..fc7ce37646 --- /dev/null +++ b/tests/cases/compiler/classExpressions.ts @@ -0,0 +1,8 @@ +interface A {} +let x = class B implements A { + prop: number; + onStart(): void { + } + func = () => { + } +}; \ No newline at end of file From 8dc9523fb0530bc5d35743e3250d3a4f0a67ce8d Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Tue, 18 Oct 2016 11:53:27 -0700 Subject: [PATCH 77/80] Allow number too --- src/compiler/checker.ts | 14 ++++++-------- src/compiler/core.ts | 4 ++-- src/compiler/utilities.ts | 2 +- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0fee5611c6..3708ea3582 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -368,7 +368,7 @@ namespace ts { return emitResolver; } - function error(location: Node, message: DiagnosticMessage, arg0?: string, arg1?: string, arg2?: string): void { + function error(location: Node, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number): void { const diagnostic = location ? createDiagnosticForNode(location, message, arg0, arg1, arg2) : createCompilerDiagnostic(message, arg0, arg1, arg2); @@ -3004,8 +3004,7 @@ namespace ts { : elementType; if (!type) { if (isTupleType(parentType)) { - error(declaration, Diagnostics.Tuple_type_0_with_length_1_cannot_be_assigned_to_tuple_with_length_2, - typeToString(parentType), getTypeReferenceArity(parentType).toString(), pattern.elements.length.toString()); + error(declaration, Diagnostics.Tuple_type_0_with_length_1_cannot_be_assigned_to_tuple_with_length_2, typeToString(parentType), getTypeReferenceArity(parentType), pattern.elements.length); } else { error(declaration, Diagnostics.Type_0_has_no_property_1, typeToString(parentType), propName); @@ -5104,7 +5103,7 @@ namespace ts { const typeParameters = type.localTypeParameters; if (typeParameters) { if (!node.typeArguments || node.typeArguments.length !== typeParameters.length) { - error(node, Diagnostics.Generic_type_0_requires_1_type_argument_s, typeToString(type, /*enclosingDeclaration*/ undefined, TypeFormatFlags.WriteArrayAsGenericType), typeParameters.length.toString()); + error(node, Diagnostics.Generic_type_0_requires_1_type_argument_s, typeToString(type, /*enclosingDeclaration*/ undefined, TypeFormatFlags.WriteArrayAsGenericType), typeParameters.length); return unknownType; } // In a type reference, the outer type parameters of the referenced class or interface are automatically @@ -5128,7 +5127,7 @@ namespace ts { const typeParameters = links.typeParameters; if (typeParameters) { if (!node.typeArguments || node.typeArguments.length !== typeParameters.length) { - error(node, Diagnostics.Generic_type_0_requires_1_type_argument_s, symbolToString(symbol), typeParameters.length.toString()); + error(node, Diagnostics.Generic_type_0_requires_1_type_argument_s, symbolToString(symbol), typeParameters.length); return unknownType; } const typeArguments = map(node.typeArguments, getTypeFromTypeNodeNoAlias); @@ -5271,7 +5270,7 @@ namespace ts { return arity ? emptyGenericType : emptyObjectType; } if (((type).typeParameters ? (type).typeParameters.length : 0) !== arity) { - error(getTypeDeclaration(symbol), Diagnostics.Global_type_0_must_have_1_type_parameter_s, symbol.name, arity.toString()); + error(getTypeDeclaration(symbol), Diagnostics.Global_type_0_must_have_1_type_parameter_s, symbol.name, arity); return arity ? emptyGenericType : emptyObjectType; } return type; @@ -13631,8 +13630,7 @@ namespace ts { // such as NodeCheckFlags.LexicalThis on "this"expression. checkExpression(element); if (isTupleType(sourceType)) { - error(element, Diagnostics.Tuple_type_0_with_length_1_cannot_be_assigned_to_tuple_with_length_2, - typeToString(sourceType), getTypeReferenceArity(sourceType).toString(), elements.length.toString()); + error(element, Diagnostics.Tuple_type_0_with_length_1_cannot_be_assigned_to_tuple_with_length_2, typeToString(sourceType), getTypeReferenceArity(sourceType), elements.length); } else { error(element, Diagnostics.Type_0_has_no_property_1, typeToString(sourceType), propName); diff --git a/src/compiler/core.ts b/src/compiler/core.ts index fd0724db31..b41f382bad 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -952,7 +952,7 @@ namespace ts { return localizedDiagnosticMessages && localizedDiagnosticMessages[message.key] || message.message; } - export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage, ...args: string[]): Diagnostic; + export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage, ...args: (string | number)[]): Diagnostic; export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage): Diagnostic { const end = start + length; @@ -992,7 +992,7 @@ namespace ts { return text; } - export function createCompilerDiagnostic(message: DiagnosticMessage, ...args: string[]): Diagnostic; + export function createCompilerDiagnostic(message: DiagnosticMessage, ...args: (string | number)[]): Diagnostic; export function createCompilerDiagnostic(message: DiagnosticMessage): Diagnostic { let text = getLocaleSpecificMessage(message); diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index dfdfae9c25..efdac40c28 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -503,7 +503,7 @@ namespace ts { return getFullWidth(name) === 0 ? "(Missing)" : getTextOfNode(name); } - export function createDiagnosticForNode(node: Node, message: DiagnosticMessage, arg0?: string, arg1?: string, arg2?: string): Diagnostic { + export function createDiagnosticForNode(node: Node, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number): Diagnostic { const sourceFile = getSourceFileOfNode(node); const span = getErrorSpanForNode(sourceFile, node); return createFileDiagnostic(sourceFile, span.start, span.length, message, arg0, arg1, arg2); From 7685e6af157d28dd6647def5de33c653efd37a17 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Mon, 10 Oct 2016 13:06:58 -0700 Subject: [PATCH 78/80] Forbid unused locals/parameters in compiler --- src/compiler/checker.ts | 49 ++++++++++------------ src/compiler/comments.ts | 10 ++--- src/compiler/core.ts | 17 ++++---- src/compiler/declarationEmitter.ts | 14 +++---- src/compiler/emitter.ts | 26 ++++++------ src/compiler/moduleNameResolver.ts | 2 +- src/compiler/parser.ts | 14 +++---- src/compiler/performance.ts | 2 +- src/compiler/program.ts | 49 +++++++++++----------- src/compiler/scanner.ts | 2 +- src/compiler/sys.ts | 12 ++---- src/compiler/transformer.ts | 2 +- src/compiler/transformers/destructuring.ts | 12 ++---- src/compiler/transformers/es2015.ts | 27 ++++++------ src/compiler/transformers/generators.ts | 6 +-- src/compiler/transformers/module/es2015.ts | 8 +--- src/compiler/transformers/module/module.ts | 1 - src/compiler/transformers/module/system.ts | 4 +- src/compiler/transformers/ts.ts | 25 +++++------ src/compiler/tsc.ts | 8 ++-- src/compiler/tsconfig.json | 4 +- src/compiler/utilities.ts | 4 +- src/compiler/visitor.ts | 6 +-- src/services/shims.ts | 4 +- 24 files changed, 142 insertions(+), 166 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3708ea3582..f24f72491b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1054,7 +1054,7 @@ namespace ts { if (node.moduleReference.kind === SyntaxKind.ExternalModuleReference) { return resolveExternalModuleSymbol(resolveExternalModuleName(node, getExternalModuleImportEqualsDeclarationExpression(node))); } - return getSymbolOfPartOfRightHandSideOfImportEquals(node.moduleReference, node); + return getSymbolOfPartOfRightHandSideOfImportEquals(node.moduleReference); } function getTargetOfImportClause(node: ImportClause): Symbol { @@ -1267,7 +1267,7 @@ namespace ts { } // This function is only for imports with entity names - function getSymbolOfPartOfRightHandSideOfImportEquals(entityName: EntityName, importDeclaration: ImportEqualsDeclaration, dontResolveAlias?: boolean): Symbol { + function getSymbolOfPartOfRightHandSideOfImportEquals(entityName: EntityName, dontResolveAlias?: boolean): Symbol { // There are three things we might try to look for. In the following examples, // the search term is enclosed in |...|: // @@ -2583,7 +2583,7 @@ namespace ts { } } - function buildDisplayForTypeArgumentsAndDelimiters(typeParameters: TypeParameter[], mapper: TypeMapper, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) { + function buildDisplayForTypeArgumentsAndDelimiters(typeParameters: TypeParameter[], mapper: TypeMapper, writer: SymbolWriter, enclosingDeclaration?: Node) { if (typeParameters && typeParameters.length) { writePunctuation(writer, SyntaxKind.LessThanToken); let flags = TypeFormatFlags.InFirstTypeArgument; @@ -4795,7 +4795,7 @@ namespace ts { const typeParameters = classType ? classType.localTypeParameters : declaration.typeParameters ? getTypeParametersFromDeclaration(declaration.typeParameters) : getTypeParametersFromJSDocTemplate(declaration); - const returnType = getSignatureReturnTypeFromDeclaration(declaration, minArgumentCount, isJSConstructSignature, classType); + const returnType = getSignatureReturnTypeFromDeclaration(declaration, isJSConstructSignature, classType); const typePredicate = declaration.type && declaration.type.kind === SyntaxKind.TypePredicate ? createTypePredicateFromTypePredicateNode(declaration.type as TypePredicateNode) : undefined; @@ -4805,7 +4805,7 @@ namespace ts { return links.resolvedSignature; } - function getSignatureReturnTypeFromDeclaration(declaration: SignatureDeclaration, minArgumentCount: number, isJSConstructSignature: boolean, classType: Type) { + function getSignatureReturnTypeFromDeclaration(declaration: SignatureDeclaration, isJSConstructSignature: boolean, classType: Type) { if (isJSConstructSignature) { return getTypeFromTypeNode(declaration.parameters[0].type); } @@ -5170,10 +5170,7 @@ namespace ts { return undefined; } - function resolveTypeReferenceName( - node: TypeReferenceNode | ExpressionWithTypeArguments | JSDocTypeReference, - typeReferenceName: EntityNameExpression | EntityName) { - + function resolveTypeReferenceName(typeReferenceName: EntityNameExpression | EntityName) { if (!typeReferenceName) { return unknownSymbol; } @@ -5211,7 +5208,7 @@ namespace ts { let type: Type; if (node.kind === SyntaxKind.JSDocTypeReference) { const typeReferenceName = getTypeReferenceName(node); - symbol = resolveTypeReferenceName(node, typeReferenceName); + symbol = resolveTypeReferenceName(typeReferenceName); type = getTypeReferenceType(node, symbol); } else { @@ -6673,8 +6670,8 @@ namespace ts { } if (source.flags & TypeFlags.Union && target.flags & TypeFlags.Union || source.flags & TypeFlags.Intersection && target.flags & TypeFlags.Intersection) { - if (result = eachTypeRelatedToSomeType(source, target, /*reportErrors*/ false)) { - if (result &= eachTypeRelatedToSomeType(target, source, /*reportErrors*/ false)) { + if (result = eachTypeRelatedToSomeType(source, target)) { + if (result &= eachTypeRelatedToSomeType(target, source)) { return result; } } @@ -6735,7 +6732,7 @@ namespace ts { return false; } - function eachTypeRelatedToSomeType(source: UnionOrIntersectionType, target: UnionOrIntersectionType, reportErrors: boolean): Ternary { + function eachTypeRelatedToSomeType(source: UnionOrIntersectionType, target: UnionOrIntersectionType): Ternary { let result = Ternary.True; const sourceTypes = source.types; for (const sourceType of sourceTypes) { @@ -11772,7 +11769,7 @@ namespace ts { // If the effective argument is 'undefined', then it is an argument that is present but is synthetic. if (arg === undefined || arg.kind !== SyntaxKind.OmittedExpression) { const paramType = getTypeAtPosition(signature, i); - let argType = getEffectiveArgumentType(node, i, arg); + let argType = getEffectiveArgumentType(node, i); // If the effective argument type is 'undefined', there is no synthetic type // for the argument. In that case, we should check the argument. @@ -11858,7 +11855,7 @@ namespace ts { if (arg === undefined || arg.kind !== SyntaxKind.OmittedExpression) { // Check spread elements against rest type (from arity check we know spread argument corresponds to a rest parameter) const paramType = getTypeAtPosition(signature, i); - let argType = getEffectiveArgumentType(node, i, arg); + let argType = getEffectiveArgumentType(node, i); // If the effective argument type is 'undefined', there is no synthetic type // for the argument. In that case, we should check the argument. @@ -12151,7 +12148,7 @@ namespace ts { /** * Gets the effective argument type for an argument in a call expression. */ - function getEffectiveArgumentType(node: CallLikeExpression, argIndex: number, arg: Expression): Type { + function getEffectiveArgumentType(node: CallLikeExpression, argIndex: number): Type { // Decorators provide special arguments, a tagged template expression provides // a special first argument, and string literals get string literal types // unless we're reporting errors @@ -13556,15 +13553,15 @@ namespace ts { return booleanType; } - function checkObjectLiteralAssignment(node: ObjectLiteralExpression, sourceType: Type, contextualMapper?: TypeMapper): Type { + function checkObjectLiteralAssignment(node: ObjectLiteralExpression, sourceType: Type): Type { const properties = node.properties; for (const p of properties) { - checkObjectLiteralDestructuringPropertyAssignment(sourceType, p, contextualMapper); + checkObjectLiteralDestructuringPropertyAssignment(sourceType, p); } return sourceType; } - function checkObjectLiteralDestructuringPropertyAssignment(objectLiteralType: Type, property: ObjectLiteralElementLike, contextualMapper?: TypeMapper) { + function checkObjectLiteralDestructuringPropertyAssignment(objectLiteralType: Type, property: ObjectLiteralElementLike) { if (property.kind === SyntaxKind.PropertyAssignment || property.kind === SyntaxKind.ShorthandPropertyAssignment) { const name = (property).name; if (name.kind === SyntaxKind.ComputedPropertyName) { @@ -13679,7 +13676,7 @@ namespace ts { target = (target).left; } if (target.kind === SyntaxKind.ObjectLiteralExpression) { - return checkObjectLiteralAssignment(target, sourceType, contextualMapper); + return checkObjectLiteralAssignment(target, sourceType); } if (target.kind === SyntaxKind.ArrayLiteralExpression) { return checkArrayLiteralAssignment(target, sourceType, contextualMapper); @@ -18588,7 +18585,7 @@ namespace ts { // Since we already checked for ExportAssignment, this really could only be an Import const importEqualsDeclaration = getAncestor(entityName, SyntaxKind.ImportEqualsDeclaration); Debug.assert(importEqualsDeclaration !== undefined); - return getSymbolOfPartOfRightHandSideOfImportEquals(entityName, importEqualsDeclaration, /*dontResolveAlias*/ true); + return getSymbolOfPartOfRightHandSideOfImportEquals(entityName, /*dontResolveAlias*/ true); } if (isRightSideOfQualifiedNameOrPropertyAccess(entityName)) { @@ -19971,7 +19968,7 @@ namespace ts { } } - function checkGrammarTypeParameterList(node: FunctionLikeDeclaration, typeParameters: NodeArray, file: SourceFile): boolean { + function checkGrammarTypeParameterList(typeParameters: NodeArray, file: SourceFile): boolean { if (checkGrammarForDisallowedTrailingComma(typeParameters)) { return true; } @@ -20022,7 +20019,7 @@ namespace ts { function checkGrammarFunctionLikeDeclaration(node: FunctionLikeDeclaration): boolean { // Prevent cascading error by short-circuit const file = getSourceFileOfNode(node); - return checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarTypeParameterList(node, node.typeParameters, file) || + return checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarTypeParameterList(node.typeParameters, file) || checkGrammarParameterList(node.parameters) || checkGrammarArrowFunction(node, file); } @@ -20208,7 +20205,7 @@ namespace ts { } } - function checkGrammarForInvalidQuestionMark(node: Declaration, questionToken: Node, message: DiagnosticMessage): boolean { + function checkGrammarForInvalidQuestionMark(questionToken: Node, message: DiagnosticMessage): boolean { if (questionToken) { return grammarErrorOnNode(questionToken, message); } @@ -20254,7 +20251,7 @@ namespace ts { let currentKind: number; if (prop.kind === SyntaxKind.PropertyAssignment || prop.kind === SyntaxKind.ShorthandPropertyAssignment) { // Grammar checking for computedPropertyName and shorthandPropertyAssignment - checkGrammarForInvalidQuestionMark(prop, (prop).questionToken, Diagnostics.An_object_member_cannot_be_declared_optional); + checkGrammarForInvalidQuestionMark((prop).questionToken, Diagnostics.An_object_member_cannot_be_declared_optional); if (name.kind === SyntaxKind.NumericLiteral) { checkGrammarNumericLiteral(name); } @@ -20438,7 +20435,7 @@ namespace ts { } if (node.parent.kind === SyntaxKind.ObjectLiteralExpression) { - if (checkGrammarForInvalidQuestionMark(node, node.questionToken, Diagnostics.An_object_member_cannot_be_declared_optional)) { + if (checkGrammarForInvalidQuestionMark(node.questionToken, Diagnostics.An_object_member_cannot_be_declared_optional)) { return true; } else if (node.body === undefined) { diff --git a/src/compiler/comments.ts b/src/compiler/comments.ts index 116a8e849a..c2cf49eeb6 100644 --- a/src/compiler/comments.ts +++ b/src/compiler/comments.ts @@ -182,13 +182,13 @@ namespace ts { } } - function emitTripleSlashLeadingComment(commentPos: number, commentEnd: number, kind: SyntaxKind, hasTrailingNewLine: boolean, rangePos: number) { + function emitTripleSlashLeadingComment(commentPos: number, commentEnd: number, _kind: SyntaxKind, hasTrailingNewLine: boolean, rangePos: number) { if (isTripleSlashComment(commentPos, commentEnd)) { - emitLeadingComment(commentPos, commentEnd, kind, hasTrailingNewLine, rangePos); + emitLeadingComment(commentPos, commentEnd, _kind, hasTrailingNewLine, rangePos); } } - function emitLeadingComment(commentPos: number, commentEnd: number, kind: SyntaxKind, hasTrailingNewLine: boolean, rangePos: number) { + function emitLeadingComment(commentPos: number, commentEnd: number, _kind: SyntaxKind, hasTrailingNewLine: boolean, rangePos: number) { if (!hasWrittenComment) { emitNewLineBeforeLeadingCommentOfPosition(currentLineMap, writer, rangePos, commentPos); hasWrittenComment = true; @@ -211,7 +211,7 @@ namespace ts { forEachTrailingCommentToEmit(pos, emitTrailingComment); } - function emitTrailingComment(commentPos: number, commentEnd: number, kind: SyntaxKind, hasTrailingNewLine: boolean) { + function emitTrailingComment(commentPos: number, commentEnd: number, _kind: SyntaxKind, hasTrailingNewLine: boolean) { // trailing comments are emitted at space/*trailing comment1 */space/*trailing comment2*/ if (!writer.isAtStartOfLine()) { writer.write(" "); @@ -242,7 +242,7 @@ namespace ts { } } - function emitTrailingCommentOfPosition(commentPos: number, commentEnd: number, kind: SyntaxKind, hasTrailingNewLine: boolean) { + function emitTrailingCommentOfPosition(commentPos: number, commentEnd: number, _kind: SyntaxKind, hasTrailingNewLine: boolean) { // trailing comments of a position are emitted at /*trailing comment1 */space/*trailing comment*/space emitPos(commentPos); diff --git a/src/compiler/core.ts b/src/compiler/core.ts index b41f382bad..05efc6db90 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -903,7 +903,7 @@ namespace ts { return t => compose(a(t)); } else { - return t => u => u; + return _t => u => u; } } @@ -943,7 +943,7 @@ namespace ts { function formatStringFromArgs(text: string, args: { [index: number]: string; }, baseIndex?: number): string { baseIndex = baseIndex || 0; - return text.replace(/{(\d+)}/g, (match, index?) => args[+index + baseIndex]); + return text.replace(/{(\d+)}/g, (_match, index?) => args[+index + baseIndex]); } export let localizedDiagnosticMessages: Map = undefined; @@ -982,7 +982,7 @@ namespace ts { } /* internal */ - export function formatMessage(dummy: any, message: DiagnosticMessage): string { + export function formatMessage(_dummy: any, message: DiagnosticMessage): string { let text = getLocaleSpecificMessage(message); if (arguments.length > 2) { @@ -1623,7 +1623,7 @@ namespace ts { basePaths: string[]; } - export function getFileMatcherPatterns(path: string, extensions: string[], excludes: string[], includes: string[], useCaseSensitiveFileNames: boolean, currentDirectory: string): FileMatcherPatterns { + export function getFileMatcherPatterns(path: string, excludes: string[], includes: string[], useCaseSensitiveFileNames: boolean, currentDirectory: string): FileMatcherPatterns { path = normalizePath(path); currentDirectory = normalizePath(currentDirectory); const absolutePath = combinePaths(currentDirectory, path); @@ -1640,7 +1640,7 @@ namespace ts { path = normalizePath(path); currentDirectory = normalizePath(currentDirectory); - const patterns = getFileMatcherPatterns(path, extensions, excludes, includes, useCaseSensitiveFileNames, currentDirectory); + const patterns = getFileMatcherPatterns(path, excludes, includes, useCaseSensitiveFileNames, currentDirectory); const regexFlag = useCaseSensitiveFileNames ? "" : "i"; const includeFileRegex = patterns.includeFilePattern && new RegExp(patterns.includeFilePattern, regexFlag); @@ -1874,11 +1874,11 @@ namespace ts { this.declarations = undefined; } - function Type(this: Type, checker: TypeChecker, flags: TypeFlags) { + function Type(this: Type, _checker: TypeChecker, flags: TypeFlags) { this.flags = flags; } - function Signature(checker: TypeChecker) { + function Signature() { } function Node(this: Node, kind: SyntaxKind, pos: number, end: number) { @@ -1911,9 +1911,6 @@ namespace ts { } export namespace Debug { - declare var process: any; - declare var require: any; - export let currentAssertionLevel = AssertionLevel.None; export function shouldAssert(level: AssertionLevel): boolean { diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 8bcce86c31..27751a1dfc 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -63,7 +63,7 @@ namespace ts { let isCurrentFileExternalModule: boolean; let reportedDeclarationError = false; let errorNameNode: DeclarationName; - const emitJsDocComments = compilerOptions.removeComments ? function (declaration: Node) { } : writeJsDocComments; + const emitJsDocComments = compilerOptions.removeComments ? () => {} : writeJsDocComments; const emit = compilerOptions.stripInternal ? stripInternal : emitNode; let noDeclare: boolean; @@ -580,7 +580,7 @@ namespace ts { writeAsynchronousModuleElements(nodes); } - function getDefaultExportAccessibilityDiagnostic(diagnostic: SymbolAccessibilityResult): SymbolAccessibilityDiagnostic { + function getDefaultExportAccessibilityDiagnostic(): SymbolAccessibilityDiagnostic { return { diagnosticMessage: Diagnostics.Default_export_of_the_module_has_or_is_using_private_name_0, errorNode: node @@ -710,7 +710,7 @@ namespace ts { } writer.writeLine(); - function getImportEntityNameVisibilityError(symbolAccessibilityResult: SymbolAccessibilityResult): SymbolAccessibilityDiagnostic { + function getImportEntityNameVisibilityError(): SymbolAccessibilityDiagnostic { return { diagnosticMessage: Diagnostics.Import_declaration_0_is_using_private_name_1, errorNode: node, @@ -888,7 +888,7 @@ namespace ts { writeLine(); enclosingDeclaration = prevEnclosingDeclaration; - function getTypeAliasDeclarationVisibilityError(symbolAccessibilityResult: SymbolAccessibilityResult): SymbolAccessibilityDiagnostic { + function getTypeAliasDeclarationVisibilityError(): SymbolAccessibilityDiagnostic { return { diagnosticMessage: Diagnostics.Exported_type_alias_0_has_or_is_using_private_name_1, errorNode: node.type, @@ -955,7 +955,7 @@ namespace ts { } } - function getTypeParameterConstraintVisibilityError(symbolAccessibilityResult: SymbolAccessibilityResult): SymbolAccessibilityDiagnostic { + function getTypeParameterConstraintVisibilityError(): SymbolAccessibilityDiagnostic { // Type parameter constraints are named by user so we should always be able to name it let diagnosticMessage: DiagnosticMessage; switch (node.parent.kind) { @@ -1029,7 +1029,7 @@ namespace ts { resolver.writeBaseConstructorTypeOfClass(enclosingDeclaration, enclosingDeclaration, TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.UseTypeAliasValue, writer); } - function getHeritageClauseVisibilityError(symbolAccessibilityResult: SymbolAccessibilityResult): SymbolAccessibilityDiagnostic { + function getHeritageClauseVisibilityError(): SymbolAccessibilityDiagnostic { let diagnosticMessage: DiagnosticMessage; // Heritage clause is written by user so it can always be named if (node.parent.parent.kind === SyntaxKind.ClassDeclaration) { @@ -1743,7 +1743,7 @@ namespace ts { } return addedBundledEmitReference; - function getDeclFileName(emitFileNames: EmitFileNames, sourceFiles: SourceFile[], isBundledEmit: boolean) { + function getDeclFileName(emitFileNames: EmitFileNames, _sourceFiles: SourceFile[], isBundledEmit: boolean) { // Dont add reference path to this file if it is a bundled emit and caller asked not emit bundled file path if (isBundledEmit && !addBundledFileReference) { return; diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 16f7e5a1c8..bf540f6a0c 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -14,7 +14,7 @@ namespace ts { } const id = (s: SourceFile) => s; - const nullTransformers: Transformer[] = [ctx => id]; + const nullTransformers: Transformer[] = [_ctx => id]; // targetSourceFile is when users only want one file in entire project to be emitted. This is used in compileOnSave feature export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFile: SourceFile, emitOnlyDtsFiles?: boolean): EmitResult { @@ -593,7 +593,7 @@ const _super = (function (geti, seti) { case SyntaxKind.ExpressionWithTypeArguments: return emitExpressionWithTypeArguments(node); case SyntaxKind.ThisType: - return emitThisType(node); + return emitThisType(); case SyntaxKind.LiteralType: return emitLiteralType(node); @@ -609,7 +609,7 @@ const _super = (function (geti, seti) { case SyntaxKind.TemplateSpan: return emitTemplateSpan(node); case SyntaxKind.SemicolonClassElement: - return emitSemicolonClassElement(node); + return emitSemicolonClassElement(); // Statements case SyntaxKind.Block: @@ -617,7 +617,7 @@ const _super = (function (geti, seti) { case SyntaxKind.VariableStatement: return emitVariableStatement(node); case SyntaxKind.EmptyStatement: - return emitEmptyStatement(node); + return emitEmptyStatement(); case SyntaxKind.ExpressionStatement: return emitExpressionStatement(node); case SyntaxKind.IfStatement: @@ -1014,7 +1014,7 @@ const _super = (function (geti, seti) { write(";"); } - function emitSemicolonClassElement(node: SemicolonClassElement) { + function emitSemicolonClassElement() { write(";"); } @@ -1084,7 +1084,7 @@ const _super = (function (geti, seti) { write(")"); } - function emitThisType(node: ThisTypeNode) { + function emitThisType() { write("this"); } @@ -1397,7 +1397,7 @@ const _super = (function (geti, seti) { // Statements // - function emitBlock(node: Block, format?: ListFormat) { + function emitBlock(node: Block) { if (isSingleLineEmptyBlock(node)) { writeToken(SyntaxKind.OpenBraceToken, node.pos, /*contextNode*/ node); write(" "); @@ -1425,7 +1425,7 @@ const _super = (function (geti, seti) { write(";"); } - function emitEmptyStatement(node: EmptyStatement) { + function emitEmptyStatement() { write(";"); } @@ -1623,13 +1623,13 @@ const _super = (function (geti, seti) { if (getEmitFlags(node) & EmitFlags.ReuseTempVariableScope) { emitSignatureHead(node); - emitBlockFunctionBody(node, body); + emitBlockFunctionBody(body); } else { const savedTempFlags = tempFlags; tempFlags = 0; emitSignatureHead(node); - emitBlockFunctionBody(node, body); + emitBlockFunctionBody(body); tempFlags = savedTempFlags; } @@ -1656,7 +1656,7 @@ const _super = (function (geti, seti) { emitWithPrefix(": ", node.type); } - function shouldEmitBlockFunctionBodyOnSingleLine(parentNode: Node, body: Block) { + function shouldEmitBlockFunctionBodyOnSingleLine(body: Block) { // We must emit a function body as a single-line body in the following case: // * The body has NodeEmitFlags.SingleLine specified. @@ -1694,12 +1694,12 @@ const _super = (function (geti, seti) { return true; } - function emitBlockFunctionBody(parentNode: Node, body: Block) { + function emitBlockFunctionBody(body: Block) { write(" {"); increaseIndent(); emitBodyWithDetachedComments(body, body.statements, - shouldEmitBlockFunctionBodyOnSingleLine(parentNode, body) + shouldEmitBlockFunctionBodyOnSingleLine(body) ? emitBlockFunctionBodyOnSingleLine : emitBlockFunctionBodyWorker); diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index 4ebdc59e6d..ba1f849755 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -5,7 +5,7 @@ namespace ts { /* @internal */ export function trace(host: ModuleResolutionHost, message: DiagnosticMessage, ...args: any[]): void; - export function trace(host: ModuleResolutionHost, message: DiagnosticMessage): void { + export function trace(host: ModuleResolutionHost, _message: DiagnosticMessage): void { host.trace(formatMessage.apply(undefined, arguments)); } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 62ae61e4cb..5481dc657b 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -575,7 +575,7 @@ namespace ts { export function parseSourceFile(fileName: string, _sourceText: string, languageVersion: ScriptTarget, _syntaxCursor: IncrementalParser.SyntaxCursor, setParentNodes?: boolean, scriptKind?: ScriptKind): SourceFile { scriptKind = ensureScriptKind(fileName, scriptKind); - initializeState(fileName, _sourceText, languageVersion, _syntaxCursor, scriptKind); + initializeState(_sourceText, languageVersion, _syntaxCursor, scriptKind); const result = parseSourceFileWorker(fileName, languageVersion, setParentNodes, scriptKind); @@ -589,7 +589,7 @@ namespace ts { return scriptKind === ScriptKind.TSX || scriptKind === ScriptKind.JSX || scriptKind === ScriptKind.JS ? LanguageVariant.JSX : LanguageVariant.Standard; } - function initializeState(fileName: string, _sourceText: string, languageVersion: ScriptTarget, _syntaxCursor: IncrementalParser.SyntaxCursor, scriptKind: ScriptKind) { + function initializeState(_sourceText: string, languageVersion: ScriptTarget, _syntaxCursor: IncrementalParser.SyntaxCursor, scriptKind: ScriptKind) { NodeConstructor = objectAllocator.getNodeConstructor(); TokenConstructor = objectAllocator.getTokenConstructor(); IdentifierConstructor = objectAllocator.getIdentifierConstructor(); @@ -5259,7 +5259,7 @@ namespace ts { parseExpected(SyntaxKind.ClassKeyword); node.name = parseNameOfClassDeclarationOrExpression(); node.typeParameters = parseTypeParameters(); - node.heritageClauses = parseHeritageClauses(/*isClassHeritageClause*/ true); + node.heritageClauses = parseHeritageClauses(); if (parseExpected(SyntaxKind.OpenBraceToken)) { // ClassTail[Yield,Await] : (Modified) See 14.5 @@ -5289,7 +5289,7 @@ namespace ts { return token() === SyntaxKind.ImplementsKeyword && lookAhead(nextTokenIsIdentifierOrKeyword); } - function parseHeritageClauses(isClassHeritageClause: boolean): NodeArray { + function parseHeritageClauses(): NodeArray { // ClassTail[Yield,Await] : (Modified) See 14.5 // ClassHeritage[?Yield,?Await]opt { ClassBody[?Yield,?Await]opt } @@ -5337,7 +5337,7 @@ namespace ts { parseExpected(SyntaxKind.InterfaceKeyword); node.name = parseIdentifier(); node.typeParameters = parseTypeParameters(); - node.heritageClauses = parseHeritageClauses(/*isClassHeritageClause*/ false); + node.heritageClauses = parseHeritageClauses(); node.members = parseObjectTypeMembers(); return addJSDocComment(finishNode(node)); } @@ -5817,7 +5817,7 @@ namespace ts { } export function parseJSDocTypeExpressionForTests(content: string, start: number, length: number) { - initializeState("file.js", content, ScriptTarget.Latest, /*_syntaxCursor:*/ undefined, ScriptKind.JS); + initializeState(content, ScriptTarget.Latest, /*_syntaxCursor:*/ undefined, ScriptKind.JS); sourceFile = createSourceFile("file.js", ScriptTarget.Latest, ScriptKind.JS); scanner.setText(content, start, length); currentToken = scanner.scan(); @@ -6134,7 +6134,7 @@ namespace ts { } export function parseIsolatedJSDocComment(content: string, start: number, length: number) { - initializeState("file.js", content, ScriptTarget.Latest, /*_syntaxCursor:*/ undefined, ScriptKind.JS); + initializeState(content, ScriptTarget.Latest, /*_syntaxCursor:*/ undefined, ScriptKind.JS); sourceFile = { languageVariant: LanguageVariant.Standard, text: content }; const jsDoc = parseJSDocCommentWorker(start, length); const diagnostics = parseDiagnostics; diff --git a/src/compiler/performance.ts b/src/compiler/performance.ts index e8f064e81c..a48eb117e2 100644 --- a/src/compiler/performance.ts +++ b/src/compiler/performance.ts @@ -12,7 +12,7 @@ namespace ts.performance { const profilerEvent = typeof onProfilerEvent === "function" && onProfilerEvent.profiler === true ? onProfilerEvent - : (markName: string) => { }; + : (_markName: string) => { }; let enabled = false; let profilerStart = 0; diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 06e9f6f30f..b34791b719 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -724,7 +724,7 @@ namespace ts { } } - function getSyntacticDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] { + function getSyntacticDiagnosticsForFile(sourceFile: SourceFile): Diagnostic[] { return sourceFile.parseDiagnostics; } @@ -761,7 +761,7 @@ namespace ts { // Instead, we just report errors for using TypeScript-only constructs from within a // JavaScript file. const checkDiagnostics = isSourceFileJavaScript(sourceFile) ? - getJavaScriptSemanticDiagnosticsForFile(sourceFile, cancellationToken) : + getJavaScriptSemanticDiagnosticsForFile(sourceFile) : typeChecker.getDiagnostics(sourceFile, cancellationToken); const fileProcessingDiagnosticsInFile = fileProcessingDiagnostics.getDiagnostics(sourceFile.fileName); const programDiagnosticsInFile = programDiagnostics.getDiagnostics(sourceFile.fileName); @@ -770,7 +770,7 @@ namespace ts { }); } - function getJavaScriptSemanticDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] { + function getJavaScriptSemanticDiagnosticsForFile(sourceFile: SourceFile): Diagnostic[] { return runWithCancellationToken(() => { const diagnostics: Diagnostic[] = []; walk(sourceFile); @@ -977,7 +977,7 @@ namespace ts { } function processRootFile(fileName: string, isDefaultLib: boolean) { - processSourceFile(normalizePath(fileName), isDefaultLib, /*isReference*/ true); + processSourceFile(normalizePath(fileName), isDefaultLib); } function fileReferenceIsEqualTo(a: FileReference, b: FileReference): boolean { @@ -1088,7 +1088,7 @@ namespace ts { /** * 'isReference' indicates whether the file was brought in via a reference directive (rather than an import declaration) */ - function processSourceFile(fileName: string, isDefaultLib: boolean, isReference: boolean, refFile?: SourceFile, refPos?: number, refEnd?: number) { + function processSourceFile(fileName: string, isDefaultLib: boolean, refFile?: SourceFile, refPos?: number, refEnd?: number) { let diagnosticArgument: string[]; let diagnostic: DiagnosticMessage; if (hasExtension(fileName)) { @@ -1096,7 +1096,7 @@ namespace ts { diagnostic = Diagnostics.File_0_has_unsupported_extension_The_only_supported_extensions_are_1; diagnosticArgument = [fileName, "'" + supportedExtensions.join("', '") + "'"]; } - else if (!findSourceFile(fileName, toPath(fileName, currentDirectory, getCanonicalFileName), isDefaultLib, isReference, refFile, refPos, refEnd)) { + else if (!findSourceFile(fileName, toPath(fileName, currentDirectory, getCanonicalFileName), isDefaultLib, refFile, refPos, refEnd)) { diagnostic = Diagnostics.File_0_not_found; diagnosticArgument = [fileName]; } @@ -1106,13 +1106,13 @@ namespace ts { } } else { - const nonTsFile: SourceFile = options.allowNonTsExtensions && findSourceFile(fileName, toPath(fileName, currentDirectory, getCanonicalFileName), isDefaultLib, isReference, refFile, refPos, refEnd); + const nonTsFile: SourceFile = options.allowNonTsExtensions && findSourceFile(fileName, toPath(fileName, currentDirectory, getCanonicalFileName), isDefaultLib, refFile, refPos, refEnd); if (!nonTsFile) { if (options.allowNonTsExtensions) { diagnostic = Diagnostics.File_0_not_found; diagnosticArgument = [fileName]; } - else if (!forEach(supportedExtensions, extension => findSourceFile(fileName + extension, toPath(fileName + extension, currentDirectory, getCanonicalFileName), isDefaultLib, isReference, refFile, refPos, refEnd))) { + else if (!forEach(supportedExtensions, extension => findSourceFile(fileName + extension, toPath(fileName + extension, currentDirectory, getCanonicalFileName), isDefaultLib, refFile, refPos, refEnd))) { diagnostic = Diagnostics.File_0_not_found; fileName += ".ts"; diagnosticArgument = [fileName]; @@ -1141,7 +1141,7 @@ namespace ts { } // Get source file from normalized fileName - function findSourceFile(fileName: string, path: Path, isDefaultLib: boolean, isReference: boolean, refFile?: SourceFile, refPos?: number, refEnd?: number): SourceFile { + function findSourceFile(fileName: string, path: Path, isDefaultLib: boolean, refFile?: SourceFile, refPos?: number, refEnd?: number): SourceFile { if (filesByName.contains(path)) { const file = filesByName.get(path); // try to check if we've already seen this file but with a different casing in path @@ -1155,18 +1155,18 @@ namespace ts { if (file && sourceFilesFoundSearchingNodeModules[file.path] && currentNodeModulesDepth == 0) { sourceFilesFoundSearchingNodeModules[file.path] = false; if (!options.noResolve) { - processReferencedFiles(file, getDirectoryPath(fileName), isDefaultLib); + processReferencedFiles(file, isDefaultLib); processTypeReferenceDirectives(file); } modulesWithElidedImports[file.path] = false; - processImportedModules(file, getDirectoryPath(fileName)); + processImportedModules(file); } // See if we need to reprocess the imports due to prior skipped imports else if (file && modulesWithElidedImports[file.path]) { if (currentNodeModulesDepth < maxNodeModulesJsDepth) { modulesWithElidedImports[file.path] = false; - processImportedModules(file, getDirectoryPath(fileName)); + processImportedModules(file); } } @@ -1202,14 +1202,13 @@ namespace ts { skipDefaultLib = skipDefaultLib || file.hasNoDefaultLib; - const basePath = getDirectoryPath(fileName); if (!options.noResolve) { - processReferencedFiles(file, basePath, isDefaultLib); + processReferencedFiles(file, isDefaultLib); processTypeReferenceDirectives(file); } // always process imported modules to record module name resolutions - processImportedModules(file, basePath); + processImportedModules(file); if (isDefaultLib) { files.unshift(file); @@ -1222,10 +1221,10 @@ namespace ts { return file; } - function processReferencedFiles(file: SourceFile, basePath: string, isDefaultLib: boolean) { + function processReferencedFiles(file: SourceFile, isDefaultLib: boolean) { forEach(file.referencedFiles, ref => { const referencedFileName = resolveTripleslashReference(ref.fileName, file.fileName); - processSourceFile(referencedFileName, isDefaultLib, /*isReference*/ true, file, ref.pos, ref.end); + processSourceFile(referencedFileName, isDefaultLib, file, ref.pos, ref.end); }); } @@ -1256,7 +1255,7 @@ namespace ts { if (resolvedTypeReferenceDirective) { if (resolvedTypeReferenceDirective.primary) { // resolved from the primary path - processSourceFile(resolvedTypeReferenceDirective.resolvedFileName, /*isDefaultLib*/ false, /*isReference*/ true, refFile, refPos, refEnd); + processSourceFile(resolvedTypeReferenceDirective.resolvedFileName, /*isDefaultLib*/ false, refFile, refPos, refEnd); } else { // If we already resolved to this file, it must have been a secondary reference. Check file contents @@ -1276,7 +1275,7 @@ namespace ts { } else { // First resolution of this library - processSourceFile(resolvedTypeReferenceDirective.resolvedFileName, /*isDefaultLib*/ false, /*isReference*/ true, refFile, refPos, refEnd); + processSourceFile(resolvedTypeReferenceDirective.resolvedFileName, /*isDefaultLib*/ false, refFile, refPos, refEnd); } } } @@ -1302,7 +1301,7 @@ namespace ts { return host.getCanonicalFileName(fileName); } - function processImportedModules(file: SourceFile, basePath: string) { + function processImportedModules(file: SourceFile) { collectExternalModuleReferences(file); if (file.imports.length || file.moduleAugmentations.length) { file.resolvedModules = createMap(); @@ -1333,7 +1332,7 @@ namespace ts { else if (shouldAddFile) { findSourceFile(resolution.resolvedFileName, toPath(resolution.resolvedFileName, currentDirectory, getCanonicalFileName), - /*isDefaultLib*/ false, /*isReference*/ false, + /*isDefaultLib*/ false, file, skipTrivia(file.text, file.imports[i].pos), file.imports[i].end); @@ -1541,7 +1540,7 @@ namespace ts { if (!options.noEmit && !options.suppressOutputPathCheck) { const emitHost = getEmitHost(); const emitFilesSeen = createFileMap(!host.useCaseSensitiveFileNames() ? key => key.toLocaleLowerCase() : undefined); - forEachExpectedEmitFile(emitHost, (emitFileNames, sourceFiles, isBundledEmit) => { + forEachExpectedEmitFile(emitHost, (emitFileNames) => { verifyEmitFilePath(emitFileNames.jsFilePath, emitFilesSeen); verifyEmitFilePath(emitFileNames.declarationFilePath, emitFilesSeen); }); @@ -1553,13 +1552,13 @@ namespace ts { const emitFilePath = toPath(emitFileName, currentDirectory, getCanonicalFileName); // Report error if the output overwrites input file if (filesByName.contains(emitFilePath)) { - createEmitBlockingDiagnostics(emitFileName, emitFilePath, Diagnostics.Cannot_write_file_0_because_it_would_overwrite_input_file); + createEmitBlockingDiagnostics(emitFileName, Diagnostics.Cannot_write_file_0_because_it_would_overwrite_input_file); } // Report error if multiple files write into same file if (emitFilesSeen.contains(emitFilePath)) { // Already seen the same emit file - report error - createEmitBlockingDiagnostics(emitFileName, emitFilePath, Diagnostics.Cannot_write_file_0_because_it_would_be_overwritten_by_multiple_input_files); + createEmitBlockingDiagnostics(emitFileName, Diagnostics.Cannot_write_file_0_because_it_would_be_overwritten_by_multiple_input_files); } else { emitFilesSeen.set(emitFilePath, true); @@ -1568,7 +1567,7 @@ namespace ts { } } - function createEmitBlockingDiagnostics(emitFileName: string, emitFilePath: Path, message: DiagnosticMessage) { + function createEmitBlockingDiagnostics(emitFileName: string, message: DiagnosticMessage) { hasEmitBlockingDiagnostics.set(toPath(emitFileName, currentDirectory, getCanonicalFileName), true); programDiagnostics.add(createCompilerDiagnostic(message, emitFileName)); } diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index b79106766d..ab76c7ffa1 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -723,7 +723,7 @@ namespace ts { return iterateCommentRanges(/*reduce*/ true, text, pos, /*trailing*/ true, cb, state, initial); } - function appendCommentRange(pos: number, end: number, kind: SyntaxKind, hasTrailingNewLine: boolean, state: any, comments: CommentRange[]) { + function appendCommentRange(pos: number, end: number, kind: SyntaxKind, hasTrailingNewLine: boolean, _state: any, comments: CommentRange[]) { if (!comments) { comments = []; } diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts index 1efa1e2b01..bb945824b4 100644 --- a/src/compiler/sys.ts +++ b/src/compiler/sys.ts @@ -46,13 +46,9 @@ namespace ts { } declare var require: any; - declare var module: any; declare var process: any; declare var global: any; declare var __filename: string; - declare var Buffer: { - new (str: string, encoding?: string): any; - }; declare class Enumerator { public atEnd(): boolean; @@ -324,7 +320,7 @@ namespace ts { const platform: string = _os.platform(); const useCaseSensitiveFileNames = isFileSystemCaseSensitive(); - function readFile(fileName: string, encoding?: string): string { + function readFile(fileName: string, _encoding?: string): string { if (!fileExists(fileName)) { return undefined; } @@ -576,7 +572,7 @@ namespace ts { args: ChakraHost.args, useCaseSensitiveFileNames: !!ChakraHost.useCaseSensitiveFileNames, write: ChakraHost.echo, - readFile(path: string, encoding?: string) { + readFile(path: string, _encoding?: string) { // encoding is automatically handled by the implementation in ChakraHost return ChakraHost.readFile(path); }, @@ -595,9 +591,9 @@ namespace ts { getExecutingFilePath: () => ChakraHost.executingFile, getCurrentDirectory: () => ChakraHost.currentDirectory, getDirectories: ChakraHost.getDirectories, - getEnvironmentVariable: ChakraHost.getEnvironmentVariable || ((name: string) => ""), + getEnvironmentVariable: ChakraHost.getEnvironmentVariable || ((_name: string) => ""), readDirectory: (path: string, extensions?: string[], excludes?: string[], includes?: string[]) => { - const pattern = getFileMatcherPatterns(path, extensions, excludes, includes, !!ChakraHost.useCaseSensitiveFileNames, ChakraHost.currentDirectory); + const pattern = getFileMatcherPatterns(path, excludes, includes, !!ChakraHost.useCaseSensitiveFileNames, ChakraHost.currentDirectory); return ChakraHost.readDirectory(path, extensions, pattern.basePaths, pattern.excludePattern, pattern.includeFilePattern, pattern.includeDirectoryPattern); }, exit: ChakraHost.quit, diff --git a/src/compiler/transformer.ts b/src/compiler/transformer.ts index e1e83a6b85..b27c8f6e79 100644 --- a/src/compiler/transformer.ts +++ b/src/compiler/transformer.ts @@ -165,7 +165,7 @@ namespace ts { hoistFunctionDeclaration, startLexicalEnvironment, endLexicalEnvironment, - onSubstituteNode: (emitContext, node) => node, + onSubstituteNode: (_emitContext, node) => node, enableSubstitution, isSubstitutionEnabled, onEmitNode: (node, emitContext, emitCallback) => emitCallback(node, emitContext), diff --git a/src/compiler/transformers/destructuring.ts b/src/compiler/transformers/destructuring.ts index c7219866df..3eaa1b764a 100644 --- a/src/compiler/transformers/destructuring.ts +++ b/src/compiler/transformers/destructuring.ts @@ -51,7 +51,7 @@ namespace ts { location = value; } - flattenDestructuring(context, node, value, location, emitAssignment, emitTempVariableAssignment, visitor); + flattenDestructuring(node, value, location, emitAssignment, emitTempVariableAssignment, visitor); if (needsValue) { expressions.push(value); @@ -87,13 +87,12 @@ namespace ts { * @param visitor An optional visitor to use to visit expressions. */ export function flattenParameterDestructuring( - context: TransformationContext, node: ParameterDeclaration, value: Expression, visitor?: (node: Node) => VisitResult) { const declarations: VariableDeclaration[] = []; - flattenDestructuring(context, node, value, node, emitAssignment, emitTempVariableAssignment, visitor); + flattenDestructuring(node, value, node, emitAssignment, emitTempVariableAssignment, visitor); return declarations; @@ -123,7 +122,6 @@ namespace ts { * @param visitor An optional visitor to use to visit expressions. */ export function flattenVariableDestructuring( - context: TransformationContext, node: VariableDeclaration, value?: Expression, visitor?: (node: Node) => VisitResult, @@ -131,7 +129,7 @@ namespace ts { const declarations: VariableDeclaration[] = []; let pendingAssignments: Expression[]; - flattenDestructuring(context, node, value, node, emitAssignment, emitTempVariableAssignment, visitor); + flattenDestructuring(node, value, node, emitAssignment, emitTempVariableAssignment, visitor); return declarations; @@ -180,7 +178,6 @@ namespace ts { * @param visitor An optional visitor to use to visit expressions. */ export function flattenVariableDestructuringToExpression( - context: TransformationContext, node: VariableDeclaration, recordTempVariable: (name: Identifier) => void, nameSubstitution?: (name: Identifier) => Expression, @@ -188,7 +185,7 @@ namespace ts { const pendingAssignments: Expression[] = []; - flattenDestructuring(context, node, /*value*/ undefined, node, emitAssignment, emitTempVariableAssignment, visitor); + flattenDestructuring(node, /*value*/ undefined, node, emitAssignment, emitTempVariableAssignment, visitor); const expression = inlineExpressions(pendingAssignments); aggregateTransformFlags(expression); @@ -219,7 +216,6 @@ namespace ts { } function flattenDestructuring( - context: TransformationContext, root: VariableDeclaration | ParameterDeclaration | BindingElement | BinaryExpression, value: Expression, location: TextRange, diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index bb2e8ac2aa..9972f339c1 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -396,7 +396,7 @@ namespace ts { return visitYieldExpression(node); case SyntaxKind.SuperKeyword: - return visitSuperKeyword(node); + return visitSuperKeyword(); case SyntaxKind.YieldExpression: // `yield` will be handled by a generators transform. @@ -1118,7 +1118,7 @@ namespace ts { createVariableStatement( /*modifiers*/ undefined, createVariableDeclarationList( - flattenParameterDestructuring(context, parameter, temp, visitor) + flattenParameterDestructuring(parameter, temp, visitor) ) ), EmitFlags.CustomPrologue @@ -1690,7 +1690,7 @@ namespace ts { if (decl.initializer) { let assignment: Expression; if (isBindingPattern(decl.name)) { - assignment = flattenVariableDestructuringToExpression(context, decl, hoistVariableDeclaration, /*nameSubstitution*/ undefined, visitor); + assignment = flattenVariableDestructuringToExpression(decl, hoistVariableDeclaration, /*nameSubstitution*/ undefined, visitor); } else { assignment = createBinary(decl.name, SyntaxKind.EqualsToken, visitNode(decl.initializer, visitor, isExpression)); @@ -1843,7 +1843,7 @@ namespace ts { if (isBindingPattern(node.name)) { const recordTempVariablesInLine = !enclosingVariableStatement || !hasModifier(enclosingVariableStatement, ModifierFlags.Export); - return flattenVariableDestructuring(context, node, /*value*/ undefined, visitor, + return flattenVariableDestructuring(node, /*value*/ undefined, visitor, recordTempVariablesInLine ? undefined : hoistVariableDeclaration); } @@ -1946,7 +1946,6 @@ namespace ts { // This works whether the declaration is a var, let, or const. // It will use rhsIterationValue _a[_i] as the initializer. const declarations = flattenVariableDestructuring( - context, firstOriginalDeclaration, createElementAccess(rhsReference, counter), visitor @@ -2539,15 +2538,15 @@ namespace ts { break; case SyntaxKind.PropertyAssignment: - expressions.push(transformPropertyAssignmentToExpression(node, property, receiver, node.multiLine)); + expressions.push(transformPropertyAssignmentToExpression(property, receiver, node.multiLine)); break; case SyntaxKind.ShorthandPropertyAssignment: - expressions.push(transformShorthandPropertyAssignmentToExpression(node, property, receiver, node.multiLine)); + expressions.push(transformShorthandPropertyAssignmentToExpression(property, receiver, node.multiLine)); break; case SyntaxKind.MethodDeclaration: - expressions.push(transformObjectLiteralMethodDeclarationToExpression(node, property, receiver, node.multiLine)); + expressions.push(transformObjectLiteralMethodDeclarationToExpression(property, receiver, node.multiLine)); break; default: @@ -2564,7 +2563,7 @@ namespace ts { * @param property The PropertyAssignment node. * @param receiver The receiver for the assignment. */ - function transformPropertyAssignmentToExpression(node: ObjectLiteralExpression, property: PropertyAssignment, receiver: Expression, startsOnNewLine: boolean) { + function transformPropertyAssignmentToExpression(property: PropertyAssignment, receiver: Expression, startsOnNewLine: boolean) { const expression = createAssignment( createMemberAccessForPropertyName( receiver, @@ -2586,7 +2585,7 @@ namespace ts { * @param property The ShorthandPropertyAssignment node. * @param receiver The receiver for the assignment. */ - function transformShorthandPropertyAssignmentToExpression(node: ObjectLiteralExpression, property: ShorthandPropertyAssignment, receiver: Expression, startsOnNewLine: boolean) { + function transformShorthandPropertyAssignmentToExpression(property: ShorthandPropertyAssignment, receiver: Expression, startsOnNewLine: boolean) { const expression = createAssignment( createMemberAccessForPropertyName( receiver, @@ -2608,7 +2607,7 @@ namespace ts { * @param method The MethodDeclaration node. * @param receiver The receiver for the assignment. */ - function transformObjectLiteralMethodDeclarationToExpression(node: ObjectLiteralExpression, method: MethodDeclaration, receiver: Expression, startsOnNewLine: boolean) { + function transformObjectLiteralMethodDeclarationToExpression(method: MethodDeclaration, receiver: Expression, startsOnNewLine: boolean) { const expression = createAssignment( createMemberAccessForPropertyName( receiver, @@ -2798,7 +2797,7 @@ namespace ts { // expressions into an array literal. const numElements = elements.length; const segments = flatten( - spanMap(elements, partitionSpreadElement, (partition, visitPartition, start, end) => + spanMap(elements, partitionSpreadElement, (partition, visitPartition, _start, end) => visitPartition(partition, multiLine, hasTrailingComma && end === numElements) ) ); @@ -2820,7 +2819,7 @@ namespace ts { : visitSpanOfNonSpreadElements; } - function visitSpanOfSpreadElements(chunk: Expression[], multiLine: boolean, hasTrailingComma: boolean): VisitResult { + function visitSpanOfSpreadElements(chunk: Expression[]): VisitResult { return map(chunk, visitExpressionOfSpreadElement); } @@ -3009,7 +3008,7 @@ namespace ts { /** * Visits the `super` keyword */ - function visitSuperKeyword(node: PrimaryExpression): LeftHandSideExpression { + function visitSuperKeyword(): LeftHandSideExpression { return enclosingNonAsyncFunctionBody && isClassElement(enclosingNonAsyncFunctionBody) && !hasModifier(enclosingNonAsyncFunctionBody, ModifierFlags.Static) diff --git a/src/compiler/transformers/generators.ts b/src/compiler/transformers/generators.ts index aaf9014c5c..200e5ec729 100644 --- a/src/compiler/transformers/generators.ts +++ b/src/compiler/transformers/generators.ts @@ -956,7 +956,7 @@ namespace ts { * @param elements The elements to visit. * @param multiLine Whether array literals created should be emitted on multiple lines. */ - function visitElements(elements: NodeArray, multiLine: boolean) { + function visitElements(elements: NodeArray, _multiLine?: boolean) { // [source] // ar = [1, yield, 2]; // @@ -1102,7 +1102,7 @@ namespace ts { createFunctionApply( cacheExpression(visitNode(target, visitor, isLeftHandSideExpression)), thisArg, - visitElements(node.arguments, /*multiLine*/ false), + visitElements(node.arguments), /*location*/ node ), node @@ -1131,7 +1131,7 @@ namespace ts { createFunctionApply( cacheExpression(visitNode(target, visitor, isExpression)), thisArg, - visitElements(node.arguments, /*multiLine*/ false) + visitElements(node.arguments) ), /*typeArguments*/ undefined, [], diff --git a/src/compiler/transformers/module/es2015.ts b/src/compiler/transformers/module/es2015.ts index 23fb444b6f..93aa108617 100644 --- a/src/compiler/transformers/module/es2015.ts +++ b/src/compiler/transformers/module/es2015.ts @@ -22,7 +22,8 @@ namespace ts { function visitor(node: Node): VisitResult { switch (node.kind) { case SyntaxKind.ImportEqualsDeclaration: - return visitImportEqualsDeclaration(node); + // Elide `import=` as it is not legal with --module ES6 + return undefined; case SyntaxKind.ExportAssignment: return visitExportAssignment(node); } @@ -30,11 +31,6 @@ namespace ts { return node; } - function visitImportEqualsDeclaration(node: ImportEqualsDeclaration): VisitResult { - // Elide `import=` as it is not legal with --module ES6 - return undefined; - } - function visitExportAssignment(node: ExportAssignment): VisitResult { // Elide `export=` as it is not legal with --module ES6 return node.isExportEquals ? undefined : node; diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index 1cca7a2177..1f56670c93 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -680,7 +680,6 @@ namespace ts { const name = node.name; if (isBindingPattern(name)) { return flattenVariableDestructuringToExpression( - context, node, hoistVariableDeclaration, getModuleMemberName, diff --git a/src/compiler/transformers/module/system.ts b/src/compiler/transformers/module/system.ts index 775d8fc34f..61f2d5c050 100644 --- a/src/compiler/transformers/module/system.ts +++ b/src/compiler/transformers/module/system.ts @@ -646,7 +646,7 @@ namespace ts { } else { // If the variable has a BindingPattern, flatten the variable into multiple assignment expressions. - return flattenVariableDestructuringToExpression(context, node, hoistVariableDeclaration); + return flattenVariableDestructuringToExpression(node, hoistVariableDeclaration); } } @@ -795,7 +795,7 @@ namespace ts { const name = firstDeclaration.name; return isIdentifier(name) ? name - : flattenVariableDestructuringToExpression(context, firstDeclaration, hoistVariableDeclaration); + : flattenVariableDestructuringToExpression(firstDeclaration, hoistVariableDeclaration); } /** diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index a1190efee1..925869da38 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -580,7 +580,7 @@ namespace ts { // HasLexicalDeclaration (N) : Determines if the argument identifier has a binding in this environment record that was created using // a lexical declaration such as a LexicalDeclaration or a ClassDeclaration. if (staticProperties.length) { - addInitializedPropertyStatements(statements, node, staticProperties, getLocalName(node, /*noSourceMaps*/ true)); + addInitializedPropertyStatements(statements, staticProperties, getLocalName(node, /*noSourceMaps*/ true)); } // Write any decorators of the node. @@ -822,7 +822,7 @@ namespace ts { // the body of a class with static initializers. setEmitFlags(classExpression, EmitFlags.Indented | getEmitFlags(classExpression)); expressions.push(startOnNewLine(createAssignment(temp, classExpression))); - addRange(expressions, generateInitializedPropertyExpressions(node, staticProperties, temp)); + addRange(expressions, generateInitializedPropertyExpressions(staticProperties, temp)); expressions.push(startOnNewLine(temp)); return inlineExpressions(expressions); } @@ -868,7 +868,7 @@ namespace ts { } const parameters = transformConstructorParameters(constructor); - const body = transformConstructorBody(node, constructor, hasExtendsClause, parameters); + const body = transformConstructorBody(node, constructor, hasExtendsClause); // constructor(${parameters}) { // ${body} @@ -922,9 +922,8 @@ namespace ts { * @param node The current class. * @param constructor The current class constructor. * @param hasExtendsClause A value indicating whether the class has an extends clause. - * @param parameters The transformed parameters for the constructor. */ - function transformConstructorBody(node: ClassExpression | ClassDeclaration, constructor: ConstructorDeclaration, hasExtendsClause: boolean, parameters: ParameterDeclaration[]) { + function transformConstructorBody(node: ClassExpression | ClassDeclaration, constructor: ConstructorDeclaration, hasExtendsClause: boolean) { const statements: Statement[] = []; let indexOfFirstStatement = 0; @@ -976,7 +975,7 @@ namespace ts { // } // const properties = getInitializedProperties(node, /*isStatic*/ false); - addInitializedPropertyStatements(statements, node, properties, createThis()); + addInitializedPropertyStatements(statements, properties, createThis()); if (constructor) { // The class already had a constructor, so we should add the existing statements, skipping the initial super call. @@ -1116,13 +1115,12 @@ namespace ts { /** * Generates assignment statements for property initializers. * - * @param node The class node. * @param properties An array of property declarations to transform. * @param receiver The receiver on which each property should be assigned. */ - function addInitializedPropertyStatements(statements: Statement[], node: ClassExpression | ClassDeclaration, properties: PropertyDeclaration[], receiver: LeftHandSideExpression) { + function addInitializedPropertyStatements(statements: Statement[], properties: PropertyDeclaration[], receiver: LeftHandSideExpression) { for (const property of properties) { - const statement = createStatement(transformInitializedProperty(node, property, receiver)); + const statement = createStatement(transformInitializedProperty(property, receiver)); setSourceMapRange(statement, moveRangePastModifiers(property)); setCommentRange(statement, property); statements.push(statement); @@ -1132,14 +1130,13 @@ namespace ts { /** * Generates assignment expressions for property initializers. * - * @param node The class node. * @param properties An array of property declarations to transform. * @param receiver The receiver on which each property should be assigned. */ - function generateInitializedPropertyExpressions(node: ClassExpression | ClassDeclaration, properties: PropertyDeclaration[], receiver: LeftHandSideExpression) { + function generateInitializedPropertyExpressions(properties: PropertyDeclaration[], receiver: LeftHandSideExpression) { const expressions: Expression[] = []; for (const property of properties) { - const expression = transformInitializedProperty(node, property, receiver); + const expression = transformInitializedProperty(property, receiver); expression.startsOnNewLine = true; setSourceMapRange(expression, moveRangePastModifiers(property)); setCommentRange(expression, property); @@ -1152,11 +1149,10 @@ namespace ts { /** * Transforms a property initializer into an assignment statement. * - * @param node The class containing the property. * @param property The property declaration. * @param receiver The object receiving the property assignment. */ - function transformInitializedProperty(node: ClassExpression | ClassDeclaration, property: PropertyDeclaration, receiver: LeftHandSideExpression) { + function transformInitializedProperty(property: PropertyDeclaration, receiver: LeftHandSideExpression) { const propertyName = visitPropertyNameOfClassElement(property); const initializer = visitNode(property.initializer, visitor, isExpression); const memberAccess = createMemberAccessForPropertyName(receiver, propertyName, /*location*/ propertyName); @@ -2423,7 +2419,6 @@ namespace ts { const name = node.name; if (isBindingPattern(name)) { return flattenVariableDestructuringToExpression( - context, node, hoistVariableDeclaration, getNamespaceMemberNameWithSourceMapsAndWithoutComments, diff --git a/src/compiler/tsc.ts b/src/compiler/tsc.ts index b39c017384..aa277c9b50 100644 --- a/src/compiler/tsc.ts +++ b/src/compiler/tsc.ts @@ -29,7 +29,7 @@ namespace ts { } } - function reportEmittedFiles(files: string[], host: CompilerHost): void { + function reportEmittedFiles(files: string[]): void { if (!files || files.length == 0) { return; } @@ -111,7 +111,7 @@ namespace ts { return count; } - function getDiagnosticText(message: DiagnosticMessage, ...args: any[]): string { + function getDiagnosticText(_message: DiagnosticMessage, ..._args: any[]): string { const diagnostic = createCompilerDiagnostic.apply(undefined, arguments); return diagnostic.messageText; } @@ -456,7 +456,7 @@ namespace ts { const sourceFile = hostGetSourceFile(fileName, languageVersion, onError); if (sourceFile && isWatchSet(compilerOptions) && sys.watchFile) { // Attach a file watcher - sourceFile.fileWatcher = sys.watchFile(sourceFile.fileName, (fileName: string, removed?: boolean) => sourceFileChanged(sourceFile, removed)); + sourceFile.fileWatcher = sys.watchFile(sourceFile.fileName, (_fileName: string, removed?: boolean) => sourceFileChanged(sourceFile, removed)); } return sourceFile; } @@ -617,7 +617,7 @@ namespace ts { reportDiagnostics(sortAndDeduplicateDiagnostics(diagnostics), compilerHost); - reportEmittedFiles(emitOutput.emittedFiles, compilerHost); + reportEmittedFiles(emitOutput.emittedFiles); if (emitOutput.emitSkipped && diagnostics.length > 0) { // If the emitter didn't emit anything, then pass that value along. diff --git a/src/compiler/tsconfig.json b/src/compiler/tsconfig.json index 65ba20f18d..a6c03d1b68 100644 --- a/src/compiler/tsconfig.json +++ b/src/compiler/tsconfig.json @@ -9,7 +9,9 @@ "sourceMap": true, "declaration": true, "stripInternal": true, - "target": "es5" + "target": "es5", + "noUnusedLocals": true, + "noUnusedParameters": true }, "files": [ "core.ts", diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index efdac40c28..55374a1cd7 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -2566,7 +2566,7 @@ namespace ts { const options = host.getCompilerOptions(); // Emit on each source file if (options.outFile || options.out) { - onBundledEmit(host, sourceFiles); + onBundledEmit(sourceFiles); } else { for (const sourceFile of sourceFiles) { @@ -2599,7 +2599,7 @@ namespace ts { action(jsFilePath, sourceMapFilePath, declarationFilePath, [sourceFile], /*isBundledEmit*/ false); } - function onBundledEmit(host: EmitHost, sourceFiles: SourceFile[]) { + function onBundledEmit(sourceFiles: SourceFile[]) { if (sourceFiles.length) { const jsFilePath = options.outFile || options.out; const sourceMapFilePath = getSourceMapFilePath(jsFilePath, options); diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index 8dca78fec9..5c152c88e4 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -1331,18 +1331,18 @@ namespace ts { export namespace Debug { export const failNotOptional = shouldAssert(AssertionLevel.Normal) ? (message?: string) => assert(false, message || "Node not optional.") - : (message?: string) => {}; + : () => {}; export const failBadSyntaxKind = shouldAssert(AssertionLevel.Normal) ? (node: Node, message?: string) => assert(false, message || "Unexpected node.", () => `Node ${formatSyntaxKind(node.kind)} was unexpected.`) - : (node: Node, message?: string) => {}; + : () => {}; export const assertNode = shouldAssert(AssertionLevel.Normal) ? (node: Node, test: (node: Node) => boolean, message?: string) => assert( test === undefined || test(node), message || "Unexpected node.", () => `Node ${formatSyntaxKind(node.kind)} did not pass test '${getFunctionName(test)}'.`) - : (node: Node, test: (node: Node) => boolean, message?: string) => {}; + : () => {}; function getFunctionName(func: Function) { if (typeof func !== "function") { diff --git a/src/services/shims.ts b/src/services/shims.ts index 7ed1786640..571f009d86 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -444,7 +444,7 @@ namespace ts { } public readDirectory(path: string, extensions?: string[], exclude?: string[], include?: string[], depth?: number): string[] { - const pattern = getFileMatcherPatterns(path, extensions, exclude, include, + const pattern = getFileMatcherPatterns(path, exclude, include, this.shimHost.useCaseSensitiveFileNames(), this.shimHost.getCurrentDirectory()); return JSON.parse(this.shimHost.readDirectory( path, @@ -509,7 +509,7 @@ namespace ts { // Wrap the API changes for 2.0 release. This try/catch // should be removed once TypeScript 2.0 has shipped. try { - const pattern = getFileMatcherPatterns(rootDir, extensions, exclude, include, + const pattern = getFileMatcherPatterns(rootDir, exclude, include, this.shimHost.useCaseSensitiveFileNames(), this.shimHost.getCurrentDirectory()); return JSON.parse(this.shimHost.readDirectory( rootDir, From dba03377b816123149046030b869baa70ae35291 Mon Sep 17 00:00:00 2001 From: Jason Ramsay Date: Tue, 18 Oct 2016 14:04:21 -0700 Subject: [PATCH 79/80] Adding JSXExpression check for isGlobalCompletion and associated tests --- src/services/completions.ts | 1 + .../fourslash/completionListIsGlobalCompletion.ts | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/services/completions.ts b/src/services/completions.ts index cd4d64b3b0..3b76fdc8c3 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -1082,6 +1082,7 @@ namespace ts.Completions { isGlobalCompletion = scopeNode.kind === SyntaxKind.SourceFile || scopeNode.kind === SyntaxKind.TemplateExpression || + scopeNode.kind === SyntaxKind.JsxExpression || isStatement(scopeNode); } diff --git a/tests/cases/fourslash/completionListIsGlobalCompletion.ts b/tests/cases/fourslash/completionListIsGlobalCompletion.ts index 3961f4fada..a1fadc6bb1 100644 --- a/tests/cases/fourslash/completionListIsGlobalCompletion.ts +++ b/tests/cases/fourslash/completionListIsGlobalCompletion.ts @@ -33,6 +33,7 @@ ////const y =
; // no globals in jsx attribute found ////const z =
; // no globals in jsx attribute with syntax error ////const x = `/*14*/ ${/*15*/}`; // globals only in template expression +////var user = ; // globals only in JSX expression (but not in JSX expression strings) goTo.marker("1"); verify.completionListIsGlobal(false); goTo.marker("2"); @@ -62,4 +63,12 @@ verify.completionListIsGlobal(false); goTo.marker("14"); verify.completionListIsGlobal(false); goTo.marker("15"); -verify.completionListIsGlobal(true); \ No newline at end of file +verify.completionListIsGlobal(true); +goTo.marker("16"); +verify.completionListIsGlobal(false); +goTo.marker("17"); +verify.completionListIsGlobal(false); +goTo.marker("18"); +verify.completionListIsGlobal(true); +goTo.marker("19"); +verify.completionListIsGlobal(false); \ No newline at end of file From f11dbc1ad160dde5209d06dd552f5d73cd832bac Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Wed, 19 Oct 2016 06:26:50 -0700 Subject: [PATCH 80/80] Respond to PR feedback --- src/compiler/comments.ts | 4 ++-- src/compiler/core.ts | 2 +- src/compiler/emitter.ts | 2 +- src/compiler/moduleNameResolver.ts | 2 +- src/compiler/parser.ts | 4 ++-- src/compiler/sys.ts | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/compiler/comments.ts b/src/compiler/comments.ts index c2cf49eeb6..cd96981c09 100644 --- a/src/compiler/comments.ts +++ b/src/compiler/comments.ts @@ -182,9 +182,9 @@ namespace ts { } } - function emitTripleSlashLeadingComment(commentPos: number, commentEnd: number, _kind: SyntaxKind, hasTrailingNewLine: boolean, rangePos: number) { + function emitTripleSlashLeadingComment(commentPos: number, commentEnd: number, kind: SyntaxKind, hasTrailingNewLine: boolean, rangePos: number) { if (isTripleSlashComment(commentPos, commentEnd)) { - emitLeadingComment(commentPos, commentEnd, _kind, hasTrailingNewLine, rangePos); + emitLeadingComment(commentPos, commentEnd, kind, hasTrailingNewLine, rangePos); } } diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 05efc6db90..2f77b3040b 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -903,7 +903,7 @@ namespace ts { return t => compose(a(t)); } else { - return _t => u => u; + return _ => u => u; } } diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index bf540f6a0c..1051c9adca 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -14,7 +14,7 @@ namespace ts { } const id = (s: SourceFile) => s; - const nullTransformers: Transformer[] = [_ctx => id]; + const nullTransformers: Transformer[] = [_ => id]; // targetSourceFile is when users only want one file in entire project to be emitted. This is used in compileOnSave feature export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFile: SourceFile, emitOnlyDtsFiles?: boolean): EmitResult { diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index ba1f849755..3fa54f127e 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -5,7 +5,7 @@ namespace ts { /* @internal */ export function trace(host: ModuleResolutionHost, message: DiagnosticMessage, ...args: any[]): void; - export function trace(host: ModuleResolutionHost, _message: DiagnosticMessage): void { + export function trace(host: ModuleResolutionHost): void { host.trace(formatMessage.apply(undefined, arguments)); } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 5481dc657b..8cdbf956d4 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -572,10 +572,10 @@ namespace ts { // attached to the EOF token. let parseErrorBeforeNextFinishedNode = false; - export function parseSourceFile(fileName: string, _sourceText: string, languageVersion: ScriptTarget, _syntaxCursor: IncrementalParser.SyntaxCursor, setParentNodes?: boolean, scriptKind?: ScriptKind): SourceFile { + export function parseSourceFile(fileName: string, sourceText: string, languageVersion: ScriptTarget, syntaxCursor: IncrementalParser.SyntaxCursor, setParentNodes?: boolean, scriptKind?: ScriptKind): SourceFile { scriptKind = ensureScriptKind(fileName, scriptKind); - initializeState(_sourceText, languageVersion, _syntaxCursor, scriptKind); + initializeState(sourceText, languageVersion, syntaxCursor, scriptKind); const result = parseSourceFileWorker(fileName, languageVersion, setParentNodes, scriptKind); diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts index bb945824b4..585fb60df3 100644 --- a/src/compiler/sys.ts +++ b/src/compiler/sys.ts @@ -591,7 +591,7 @@ namespace ts { getExecutingFilePath: () => ChakraHost.executingFile, getCurrentDirectory: () => ChakraHost.currentDirectory, getDirectories: ChakraHost.getDirectories, - getEnvironmentVariable: ChakraHost.getEnvironmentVariable || ((_name: string) => ""), + getEnvironmentVariable: ChakraHost.getEnvironmentVariable || (() => ""), readDirectory: (path: string, extensions?: string[], excludes?: string[], includes?: string[]) => { const pattern = getFileMatcherPatterns(path, excludes, includes, !!ChakraHost.useCaseSensitiveFileNames, ChakraHost.currentDirectory); return ChakraHost.readDirectory(path, extensions, pattern.basePaths, pattern.excludePattern, pattern.includeFilePattern, pattern.includeDirectoryPattern);